Open links with pop-up window

I have those links:

<div class="linksblock">
<a link href="www.google.com/1">link 1</a>
<a link href="www.google.com/2">link 2</a>
<a link href="www.google.com/3">link 3</a>
<a link href="www.google.com/4">link 4</a>
<a link href="www.google.com/5">link 5</a>
</div>

I would like to open these links in a pop-up window.
It’s important to note that I can’t modify the links, so I can’t add “onclick” or anything else. So I want to make all links in “linksblock” open in a pop-up window.

I tried this code, but it doesn’t work:

$(".linksblock a").on("click", function() {
  var share_link = $(this).prop('href');
  console.log(share_link);
window.open(share_link, "_blank", "toolbar=yes,scrollbars=yes,resizable=yes,top=500,left=500,width=400,height=400");

});

How to create a reuseable controlled Select field using MUI and React Hook Form?

I’m creating a reusable Select input component using Material UI (MUI) and react-hook-form. I want the component to:

Be fully controlled using react-hook-form’s Controller.

Accept dynamic options passed via props.

Support labels, placeholders, and custom menu styling.

Show validation errors from the form schema.

Here’s the current implementation:

import { JSX } from "@emotion/react/jsx-dev-runtime";
import {
  Select,
  FormLabel,
  FormHelperText,
  FormControl,
  MenuItem,
} from "@mui/material";
import { Controller, useFormContext } from "react-hook-form";

export function RHFCustomSelect({
  name,
  options,
  outerLabel,
  styleMenu,
  placeholder,
  fullWidth = true,
  ...others
}: any): JSX.Element {
  const { control } = useFormContext();

  const menuProps: any = {
    PaperProps: {
      sx: {
        marginTop: "10px",
      },
    },
  };

  return (
    <Controller
      control={control}
      name={name}
      render={({ field, fieldState: { error } }) => (
        <FormControl error={Boolean(error)} fullWidth={fullWidth}>
          {outerLabel && (
            <FormLabel sx={{ pb: "0.6rem" }}>{outerLabel}</FormLabel>
          )}
          <Select
            displayEmpty
            MenuProps={menuProps}
            inputRef={field.ref}
            {...field}
            {...others}
          >
            <MenuItem disabled value="" sx={{ display: "none" }}>
              <em style={{ fontStyle: "normal" }}>{placeholder ?? "Select"}</em>
            </MenuItem>
            {options?.map(({ id, label, value }: any) => (
              <MenuItem
                value={value}
                key={id}
                sx={{ fontSize: "1.5rem", ...styleMenu }}
              >
                {label}
              </MenuItem>
            ))}
          </Select>
          {Boolean(error) && <FormHelperText>{error?.message}</FormHelperText>}
        </FormControl>
      )}
    />
  );
}

How to achieve sticky behavior in CSS to the top or to the bottom

My website has a left sidebar containing tools related to the currently displayed screen. Currently it does not stick, so if you want to make any changes, you need to scroll all the way to the top.

The natural way of solving this issue is making the sidebar sticky, but it may happen that its height will be greater than the height of screen. So I’d like to achieve the following behavior:

  • If height of the container is less than screen, it should stick to the top.
  • If height of the container is greater than screen, it should show at the top, then scroll along with page content until its bottom is visible and then stick to its bottom.

Can such behavior be achieved with pure CSS or do I need to involve some Javascript? I’m using TailwindCSS if it helps anyhow.


Edit: Sample code.

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
  </head>
  <body>
    <div class="flex flex-row space-x-4 m-4">
        <div class="w-50 bg-zinc-200">
            <div class="h-500 bg-red-400/50 w-full">
                Sidebar
            </div>
        </div>
        
        <div class="grow bg-zinc-400">
            <div class="h-1000 bg-green-400/50 w-full">
                Content
            </div>
        </div>
    </div>
  </body>
</html>

When the red rectangle on the left is higher than the screen, it should stick to the bottom. If it is smaller than the screen (adjust with h-* CSS class, e.g. h-20), then it should stick to the top.

Animations not rendering on mobile platforms

I have created a portfolio website using React js with Node js on VScode to showcase my skillset with a terminal typewriter animation. Everything works perfectly fine on laptop/pc browsers, but when I tried accessing my website on mobile it doesnt show any of the animations even when I switch to desktop website on my android device still no animations playing.

My react js code –>

import './App.css';
import React, { use, useState } from 'react';
import Windowz from './RoomWindow';
import Table from './Tables';
import Footer from './Footer';
import Contents from './ScreenContent';


function App() {
  
    return (
            <div className="App">
            <Windowz />

            <Contents />

            <Table />
            <Footer />
            </div>
        );
}

export default App;

The CSS part –>

/* TABLE ------------------------------------------------ */
svg {
  margin-left: 0;
  width: 100%;
  position: relative;
  border-radius: 3%;
  }


a {
  font-size: 1.5em;
}
footer {
  font-size: 1.3em;
}
/* TABLE------------------------------------------------ */


/* TERMINAL WINDOW ------------------------------------------------ */

/* CONTENT ----------------------------------- */

#fake__Screen:-ms-fullscreen p {
  visibility: visible;
  font-size: 2.0em;
  overflow: auto;
}
#fake__Screen:fullscreen {
  font-size: 2.0em;
  width: 100vw;
  height: 100vh;
  overflow: auto;
}

span {
  color: #fff;
  font-family: monospace;
  text-align: left;
  font-size: 1.5em;
  display: inline-flex;
}
a {
  color: #fff;
  font-family: monospace;
  text-align: left;
}
.codeHead {
  color: rgb(0, 229, 255);
  font-family: monospace;
  text-align: left;
  font-size: 1.5em;
  display: inline-flex;
}

.typewriter {
  width: fit-content;
  color: #fff;
  font-family: monospace;
  overflow: hidden; /* Ensures the content is not revealed until the animation */
  border-right: .7em solid rgb(0, 229, 255); /* The typwriter cursor */
  white-space: nowrap; /* Keeps the content on a single line */
  margin: -10 auto; /* Gives that scrolling effect as the typing happens */
  letter-spacing: .15em; /* Adjust as needed */
  -webkit-animation: 
    typing 3.5s steps(30, end),
    blink-caret .5s step-end infinite;
  animation: 
    typing 3.5s steps(30, end),
    blink-caret .9s step-end infinite;
}
.typewriter1 {
  width: fit-content;
  color: #fff;
  font-family: monospace;
  overflow: hidden; /* Ensures the content is not revealed until the animation */
  border-right: .7em solid rgb(0, 229, 255); /* The typwriter cursor */
  white-space: nowrap; /* Keeps the content on a single line */
  margin: -10 auto; /* Gives that scrolling effect as the typing happens */
  letter-spacing: .15em; /* Adjust as needed */
  -webkit-animation: 
    typing 1s steps(60, end),
    blink-caret .5s step-end infinite;
  animation: 
    typing 1s steps(60, end),
    blink-caret .9s step-end infinite;
}
.bio:hover {
  color: rgb(0, 229, 255);
}
.work:hover {
  color: rgb(0, 229, 255);
}
.projects:hover {
  color: rgb(0, 229, 255);
}
/* The typing effect */
@-webkit-keyframes typing {
  from { width: 0 }
  to { width: 40% }
}
@keyframes typing {
  from { width: 0 }
  to { width: 40% }
}
/* The typewriter cursor effect */
@-webkit-keyframes blink-caret {
  from, to { border-color: transparent }
  50% { border-color: rgb(0, 238, 255) }
}
@keyframes blink-caret {
  from, to { border-color: transparent }
  50% { border-color: rgb(0, 208, 255) }
}

#id {
  overflow-y:auto;
}
/* CONTENT ----------------------------------- */

body {
  background-color: rgb(84, 96, 97);
  padding: 10px;
  margin-bottom: 0;
  padding-bottom: 0;
  }
  
  .fakeButtons {
  height: 10px;
  width: 10px;
  border-radius: 50%;
  border: 1px solid #000;
  position: relative;
  top: 6px;
  left: 6px;
  background-color: #ff3b47;
  border-color: #9d252b;
  display: inline-block;
  }
  
  .fakeMinimize {
  left: 11px;
  background-color: #ffc100;
  border-color: #9d802c;
  }
  
  .fakeZoom {
  left: 16px;
  background-color: #00d742;
  border-color: #049931;
  }
  
  .fakeMenu {
  max-width: 748px;
  box-sizing: border-box;
  height: 25px;
  background-color: #bbb;
  margin: 0 auto;
  border-top-right-radius: 5px;
  border-top-left-radius: 5px;
  text-align: left;
  }
  
  .fakeScreen {
  background-color: #151515;
  box-sizing: border-box;
  max-width: 748px;
  height: 467.50px;
  margin: 0 auto;
  padding: 20px;
  overflow: auto;
  border-bottom-left-radius: 5px;
  border-bottom-right-radius: 5px;
  
  }
  
  p {
  position: relative;
  left: 22%;
  margin-left: -8.5em;
  text-align: left;
  font-size: 2.5em;
  font-family: monospace;
  white-space: normal;
  overflow: hidden;
  width: 0;
  }
  
  .hide {
    display: none;
  }

  /* TERMINAL WINDOW ------------------------------------------------ */

  /* LAPTOP SYLE */

html {
  font-size: 62.5%;
  }
  
  .container {
  margin-top: 70px;
  }
  
  .laptop {
  position: relative;
  margin: auto;
  max-width: 80rem;
  
  .laptop__screen {
    position: relative;
    z-index: 1;
    padding: 3%;
    border-radius: 2rem;
    background: #ecf1f7;
    background-image: linear-gradient(to bottom, #333, #111);
    box-shadow: 0 .1rem 0 #cfcfcf;
    border: 2px solid #ccc;
    
    -webkit-box-shadow:0px 0px 105px 30px rgba(119,171,156,0.55);
    -moz-box-shadow: 0px 0px 105px 30px rgba(119,171,156,0.55);
    box-shadow: 0px 0px 105px 30px rgba(119,171,156,0.55);

  
    img {
      display: block;
      max-width: 100%;
      height: auto;
      aspect-ratio: attr(width) / attr(height);
      background: #000;
    }

  }
  
  .laptop__bottom {
    position: relative;
    z-index: 1;
    margin-right: -7%;
    margin-left: -7%;
    height: .7rem;
    background: #e9eff5;
    background-image: linear-gradient(to right, #d2dde9 0%, #f9fcff 15%, #e5ebf2 40%, #e5ebf2 60%, #f9fcff 85%, #d2dde9 100%);
    
    &::before {
      display: block;
      margin: 0 auto;
      width: 20%;
      height: .7rem;
      border-radius: 0 0 .2rem .2rem;
      background: #f6f9fc;
      background-image: linear-gradient(to right, #c3cfdb 0%, #f6f9fc 10%, #f6f9fc 90%, #c3cfdb 100%);
      content: " ";
    }
  }
  
  .laptop__under {
    position: absolute;
    top: 100%;
    left: 25%;
    display: block;
    width: 50%;
    height: 1.5rem;
    background: #e2e8f0;
    background-image: linear-gradient(to bottom, #e2e8f0, #bec7d1);
  
    &::after, &::before {
      position: absolute;
      top: 0%;
      right: 100%;
      bottom: 0;
      display: block;
      width: 50%;
      border-bottom-left-radius: 100%;
      background: inherit;
      content: " ";
    }
  
    &::after {
      right: auto;
      left: 100%;
      border-bottom-right-radius: 100%;
      border-bottom-left-radius: 0;
    }
  }
  
  .laptop__shadow {
    position: absolute;
    right: -10%;
    bottom: -2.5rem;
    left: -10%;
    z-index: 0;
    height: 2rem;
    background: radial-gradient(ellipse closest-side,#000,transparent);
    opacity: 0.5;
  }
  }
  svg {
  margin-left: 0;
  width: 100%;
  position: relative;
  }
  .bg {
  width: 100%;
  height: 100%;
  border-radius: 2px;
  background: url(https://i.imgur.com/g2aFOGP.png) no-repeat fixed;
  -webkit-background-size: cover;
  -moz-background-size: cover;
  -o-background-size: cover;
  background-size: cover;
  box-shadow: inset 1px 1px 0px rgba(255, 255, 255, 0.3), inset 0px 0px 10px rgba(255, 255, 255, 0.2), 0px 1px 2px rgba(0, 0, 0, 0.3), -5px 5px 15px rgba(0, 0, 0, 0.3);
  width: 85vw;
  height: 100vh;
  position: fixed;
  top: 2%;
  left: 7%;
  max-height: 600px;
  overflow: hidden;
  }

/* LAPTOP SYLE 000000000000000000000000000000000000000000000000*/

/* CLOUDS SYLE 000000000000000000000000000000000000000000000000*/

/* KEYFRAMES */

@-webkit-keyframes animateCloud {
  0% {
      margin-left: -1000px;
  }
  100% {
      margin-left: 100%;
  }
}

@-moz-keyframes animateCloud {
  0% {
      margin-left: -1000px;
  }
  100% {
      margin-left: 100%;
  }
}

@keyframes animateCloud {
  0% {
      margin-left: -1000px;
  }
  100% {
      margin-left: 100%;
  }
}

/* ANIMATIONS */

.x1 {
-webkit-animation: animateCloud 35s linear infinite;
-moz-animation: animateCloud 35s linear infinite;
animation: animateCloud 35s linear infinite;

-webkit-transform: scale(0.65);
-moz-transform: scale(0.65);
transform: scale(0.65);
}

.x2 {
-webkit-animation: animateCloud 20s linear infinite;
-moz-animation: animateCloud 20s linear infinite;
animation: animateCloud 20s linear infinite;

-webkit-transform: scale(0.3);
-moz-transform: scale(0.3);
transform: scale(0.3);
}

.x3 {
-webkit-animation: animateCloud 30s linear infinite;
-moz-animation: animateCloud 30s linear infinite;
animation: animateCloud 30s linear infinite;

-webkit-transform: scale(0.5);
-moz-transform: scale(0.5);
transform: scale(0.5);
}

.x4 {
-webkit-animation: animateCloud 18s linear infinite;
-moz-animation: animateCloud 18s linear infinite;
animation: animateCloud 18s linear infinite;

-webkit-transform: scale(0.4);
-moz-transform: scale(0.4);
transform: scale(0.4);
}

.x5 {
-webkit-animation: animateCloud 25s linear infinite;
-moz-animation: animateCloud 25s linear infinite;
animation: animateCloud 25s linear infinite;

-webkit-transform: scale(0.55);
-moz-transform: scale(0.55);
transform: scale(0.55);
}

/* OBJECTS */

.cloud {
background: #fff;
background: -moz-linear-gradient(top,  #fff 5%, #f1f1f1 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(5%,#fff), color-stop(100%,#f1f1f1));
background: -webkit-linear-gradient(top,  #fff 5%,#f1f1f1 100%);
background: -o-linear-gradient(top,  #fff 5%,#f1f1f1 100%);
background: -ms-linear-gradient(top,  #fff 5%,#f1f1f1 100%);
background: linear-gradient(top,  #fff 5%,#f1f1f1 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#fff', endColorstr='#f1f1f1',GradientType=0 );

-webkit-border-radius: 100px;
-moz-border-radius: 100px;
border-radius: 100px;

-webkit-box-shadow: 0 8px 5px rgba(0, 0, 0, 0.1);
-moz-box-shadow: 0 8px 5px rgba(0, 0, 0, 0.1);
box-shadow: 0 8px 5px rgba(0, 0, 0, 0.1);

height: 120px;
position: relative;
width: 350px;
}

.cloud:after, .cloud:before {
  background: #fff;
content: '';
position: absolute;
z-indeX: -1;
}

.cloud:after {
-webkit-border-radius: 100px;
-moz-border-radius: 100px;
border-radius: 100px;

height: 100px;
left: 50px;
top: -50px;
width: 100px;
}

.cloud:before {
-webkit-border-radius: 200px;
-moz-border-radius: 200px;
border-radius: 200px;

width: 180px;
height: 180px;
right: 50px;
top: -90px;
}

/* CLOUDS SYLE 000000000000000000000000000000000000000000000000*/

    /* SUNRISE - SUNSET END ------------------------------------------- */


    @keyframes sunrise {
      from {
        transform: rotate(-45deg);
      }
      
      to {
        transform: rotate(315deg);
      }
      }
      
      @keyframes moonrise {
      from {
        transform: rotate(0deg);
      }
      
      to {
        transform: rotate(180deg);
      }
      }
      
      @keyframes dawn {
      0% {
        opacity: 0;
      }
      10% {
        opacity: 1;
      }
      60% {
        opacity: 0;
      }
      }
      
      @keyframes noon {
      0% {
        opacity: 0;
      }
      50% {
        opacity: 1;
      }
      75% {
        opacity: 0;
      }
      }
      
      @keyframes dusk {
      0% {
        opacity: 0;
      }
      50% {
        opacity: 0;
      }
      70% {
        opacity: 1;
      }
      90% {
        opacity: 0;
      }
      }
      
      @keyframes midnight {
      0% {
        opacity: 1;
      }
      25% {
        opacity: 0;
      }
      50% {
        opacity: 0;
      }
      80% {
        opacity: 1;
      }
      }
      
      body {
      --animation-speed: 1200s;
      background-color: #63689b;
      
      }
      
      body.pause {
      --animation-speed: 0;
      }
      
      .sky {
      width: 85vw;
      height: 100vh;
      position: fixed;
      top: 2%;
      left: 7%;
      max-height: 600px;
      overflow: hidden;
      }
      
      .sky__phase {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;
      transition: opacity 0.2s;
      }
      
      .sky__dawn {
      background: linear-gradient(
        0deg,
        rgba(254, 215, 102, 1) 0%,
        rgba(205, 237, 246, 1) 100%
      );
      animation: linear dawn infinite var(--animation-speed);
      }
      
      .sky__noon {
      background: linear-gradient(
        0deg,
        rgba(205, 237, 246, 1) 0%,
        rgba(36, 123, 160, 1) 100%
      );
      animation: linear noon infinite var(--animation-speed);
      }
      
      .sky__dusk {
      background: linear-gradient(
        0deg,
        rgba(255, 32, 110, 1) 0%,
        rgba(10, 0, 94, 1) 100%
      );
      animation: linear dusk infinite var(--animation-speed);
      }
      
      .sky__midnight {
      background: linear-gradient(
        0deg,
        rgba(2, 0, 20, 1) 0%,
        rgba(10, 0, 94, 1) 100%
      );
      animation: linear midnight infinite var(--animation-speed);
      }
      
      .orbit {
      position: relative;
      width: 500px;
      height: 500px;
      margin: 200px auto;
      transform: rotate(-45deg);
      animation: linear sunrise infinite var(--animation-speed);
      }
      
      @media (min-width: 768px) {
      .sky {
        max-height: 600px;
      }
      .orbit {
        width: 700px;
        height: 700px;
        margin: 150px auto;
      }
      }
      
      @media (min-width: 940px) {
      .orbit {
        width: 800px;
        height: 800px;
      }
      }
      
      @media (min-width: 1200px) {
      body {
        --animation-speed: 1204s;
      }
      .orbit {
        width: 1000px;
        height: 1000px;
        margin: 200px auto;
      }
      }
      
      @media (min-width: 1500px) {
      body {
        --animation-speed: 1206s;
      }
      .orbit {
        width: 1300px;
        height: 1300px;
      }
      }
      
      .sun {
      position: absolute;
      top: -40px;
      left: -40px;
      width: 80px;
      height: 80px;
      background-color: rgb(254, 215, 102);
      border-radius: 50%;
      box-shadow: 0 0 14px 14px rgba(254, 215, 102, 0.2);
      }
      
      .moon {
      position: absolute;
      bottom: -40px;
      right: -40px;
      width: 80px;
      height: 80px;
      border-radius: 50%;
      background-color: #ebf3fe;
      box-shadow: inset -40px 0px 0px #d8e8f7, inset 20px 0px 0px #ffffff, inset -50px 0px 0px 20px #e2eefa, 0px 0px 0px 20px  rgba(255, 255, 255, 0.05), 0px 0px 0px 40px  rgba(255, 255, 255, 0.025), 0px 0px 0px 60px  rgba(255, 255, 255, 0.0125);
      transition: all 0.2s ease-in;
      }
      .moon:after {
      content: "";
      width: 13px;
      height: 13px;
      border-radius: 50%;
      background-color: #d8e8f7;
      position: absolute;
      top: 20%;
      left: 20%;
      box-shadow: 40px -20px 0px -10px #d8e8f7, 40px 10px 0px -15px #d8e8f7;
      }
      
      #sky__stars > div {
      width: 3px;
      height: 3px;
      background-color: #fff;
      border-radius: 50%;
      position: absolute;
      }
      
      #toggle-animation {
      position: fixed;
      bottom: 1em;
      right: 1em;
      text-transform: uppercase;
      background-color: rgb(2, 0, 20);
      color: #fff;
      border: 0;
      padding: 0.5em 1em;
      letter-spacing: 0.5px;
      }
      
      #toggle-animation:hover {
      background-color: rgb(61, 0, 21);
      cursor: pointer;
      }
      
      .paused {
      display: none;
      }
      
      .pause .paused {
      display: block;
      }
      
      .pause .playing {
      display: none;
      }
      

    /* SUNRISE - SUNSET END ------------------------------------------- */

The room window jsx code –>

import './App.css';
import React, { useState } from 'react';

function Windowz() {
    //////////////////////////////////////////////////////
    const starsArray = [];
    const stars = 40;
    let x,y = 0;

    // Generate stars randomly using absolute position
    for (let i = 0; i < stars; i++) {
        x = Math.floor(Math.random() * 100 + 1) + "%";
        y = Math.floor(Math.random() * 100 + 1) + "%";
        starsArray.push(x);
        starsArray.push(y);
    }
    //////////////////////////////////////////////////////

    return (
        <div className="bg">
        <div className="x1">
                <div className="cloud"></div>
            </div>

            <div className="x2">
                <div className="cloud"></div>
            </div>

            <div className="x3">
                <div className="cloud"></div>
            </div>

            <div className="x4">
                <div className="cloud"></div>
            </div>

            <div className="x5">
                <div className="cloud"></div>
            </div>
            <div className="sky">
            <div className="sky__phase sky__dawn"></div>
            <div className="sky__phase sky__noon"></div>
            <div className="sky__phase sky__dusk"></div>
            <div className="sky__phase sky__midnight">
                <div id="sky__stars">{starsArray.map((element,index) => {
                    return(<div key={index} style={{ position: "relative", top: element, left: element }}></div>);
                })}</div>
            </div>
        
            <div className="orbit">
                <div className="sun"></div>
                <div className="moon"></div>
            </div>
            
        </div>
        </div>
    );
}

export default Windowz;

How to automatically trigger an Action Chain in the background?

I have developed a Visual Builder Application that includes an Action Chain responsible for processing invoice-related logic. This Action Chain is currently triggered manually by a button click on the UI and performs the following actions:

Retrieves invoice data from Oracle Fusion

Sends the data to an external REST API

Handles request signing, response handling, and error checking

Writes the result back to custom fields in Fusion

Now, I would like to automate this process and have the Action Chain run in the background without user interaction, ideally on a scheduled basis.

My questions:
Is there a supported way to run an Action Chain programmatically in the background (without UI interaction)?

Can I expose the Action Chain via a custom REST endpoint and trigger it from an ESS job or another scheduled process in Fusion?

Any advice or examples would be appreciated!

Thanks!

Flutter Web js and main app communication

I have a problem with communication between flutter App and InAppWebView (for IOS/Android it works). When i build it as web it doesn’t work. Any suggestions what i did wrong or how i can get it works? Thanks in advance.

Please give me some good advice how to solve it of any other options how to make that alive.
Here is my code sample.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';

Future main() async {
  WidgetsFlutterBinding.ensureInitialized();

  runApp(const MaterialApp(home: MyApp()));
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<MyApp> createState() => _MyAppState();
}

var js = "console.log('Hello from JavaScript!');";
var js2 = "changeBackgroundColor();";

class _MyAppState extends State<MyApp> {
  final GlobalKey webViewKey = GlobalKey();

  InAppWebViewController? webViewController;
  InAppWebViewSettings settings = InAppWebViewSettings(
      isInspectable: true,
      mediaPlaybackRequiresUserGesture: false,
      allowsInlineMediaPlayback: true,
      iframeAllow: "camera; microphone",
      iframeAllowFullscreen: true);

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: const Text("Official InAppWebView website")),
        body: SafeArea(
            child: Column(children: <Widget>[
          SizedBox(
            height: 100,
          ),
          Expanded(
            child: Stack(
              children: [
                InAppWebView(
                  key: webViewKey,
                  initialUrlRequest: URLRequest(
                    url: WebUri("https://jspagesample.web.app"),
                  ),
                  initialSettings: settings,
                  onWebViewCreated: (controller) {
                    webViewController = controller;
                    debugPrint("onWebViewCreated");
                  },
                  onLoadStart: (controller, url) {
                    debugPrint("onLoadStart");
                  },
                  onPermissionRequest: (controller, request) async {
                    return PermissionResponse(
                        resources: request.resources,
                        action: PermissionResponseAction.GRANT);
                  },
                  onLoadStop: (controller, url) async {
                    debugPrint("onLoadStop");
                  },
                  onReceivedError: (controller, request, error) {},
                  onConsoleMessage: (controller, consoleMessage) {
                    debugPrint(consoleMessage.message);
                  },
                ),
              ],
            ),
          ),
          ButtonBar(
            alignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                child: Text("Run JS 1"),
                onPressed: () async {
                  debugPrint("JS Result: Before");
                  if (webViewController == null) {
                    debugPrint("webViewController is null");
                    return;
                  }
                  await webViewController!.evaluateJavascript(source: js);
                  debugPrint("JS Result: After");
                },
              ),
              ElevatedButton(
                child: Text("Run JS 2"),
                onPressed: () async {
                  debugPrint("JS 2 Result: Before");
                  await webViewController!
                      .evaluateJavascript(source: js2)
                      .then((value) {
                    debugPrint("JS Result: $value");
                  });
                  debugPrint("JS 2 Result: After");
                },
              ),
            ],
          ),
        ])));
  }
}

TypeError: User.findOne.mockResolvedValue is not a function when using jest.mock() with Mongoose model in Jest tests

I’m encountering the error TypeError: User.findOne.mockResolvedValue is not a function while trying to mock the Mongoose findOne method in my Jest tests. The issue occurs even though I have properly mocked the User model using jest.mock() and set up mock implementations for its methods.
Here’s my setup:

I am using ES modules with import and export in my code.

I am mocking a Mongoose model, specifically the findOne and create methods in the User.js model, to simulate the behavior of the database during tests.

I am running tests with Jest, and using the supertest package to send HTTP requests to my application.

Inside models/mocks/User.js:

const findOne = jest.fn();
const create = jest.fn();

export default {findOne, create};

Inside jest.config.js:

export default {
    testEnvironment: 'node',
    transform: {},
    moduleNameMapper: {
        '^(\.{1,2}/.*)\.js$': '$1',
    },
};

Inside auth.test.js:

import {jest} from '@jest/globals';
import request from 'supertest';
import app from '../app.js';
jest.mock('../models/User.js');
import User from '../models/User.js';
import bcrypt from "bcrypt";

let dummyUser;

beforeAll(async () => {
    dummyUser = {
        _id: 'fakeid123',
        username: 'mockuser',
        email: '[email protected]',
        password: await bcrypt.hash('password123!', 10)
    };
})




describe('Auth tanpa DB (mock)', ()=>{
    it('register user successfully', async ()=>{
        console.log(User.findOne);
        User.findOne.mockResolvedValue(null);
        User.create.mockResolvedValue(dummyUser);
        
        const res = await request(app)
            .post('/api/auth/register')
            .send({
                username: dummyUser.username,
                email: dummyUser.email,
                password: 'password123!'
            });
        expect(res.status).toBe(201);
        expect(res.body).toHaveProperty('message');
    })
    
    it('login user successfully', async ()=>{
        User.findOne.mockResolvedValue(dummyUser);
        
        const res = await request(app)
            .post('/api/auth/login')
            .send({
                email: dummyUser.email,
                password: 'password123',
            });
        expect(res.status).toBe(200);
        expect(res.body).toHaveProperty('token');
    })
})

and the this is the error:

 FAIL  tests/auth.test.js
  ● Console
                                                                                                                                                                         
    console.log
      [Function: findOne]

      at Object.<anonymous> (tests/auth.test.js:26:11)

  ● Auth tanpa DB (mock) › register user successfully
                                                                                                                                                                         
    TypeError: User.findOne.mockResolvedValue is not a function

      25 |      it('register user successfully', async ()=>{
      26 |              console.log(User.findOne);
    > 27 |              User.findOne.mockResolvedValue(null);
         |                           ^
      28 |              User.create.mockResolvedValue(dummyUser);
      29 | 
      30 |              const res = await request(app)

      at Object.<anonymous> (tests/auth.test.js:27:16)

  ● Auth tanpa DB (mock) › login user successfully

    TypeError: User.findOne.mockResolvedValue is not a function

      40 |
      41 |      it('login user successfully', async ()=>{
    > 42 |              User.findOne.mockResolvedValue(dummyUser);
         |                           ^
      43 | 
      44 |              const res = await request(app)
      45 |                      .post('/api/auth/login')

      at Object.<anonymous> (tests/auth.test.js:42:16)

How to manually sign a transaction using Hedera Javascript SDK?

I’m trying to use a Hardware Security Module (HSM) to manually sign a Hedera transaction, but the Hedera JavaScript SDK requires me to pass my private key to the SDK for signing. Since my private key cannot leave the HSM and I can only use the HSM to sign transactions, I’m not sure how to proceed. Could someone please let me know how to do this? I couldn’t find any example code.

The flow I need to follow is:

  1. Create a transaction

  2. Serialize the transaction into transaction bytes

  3. Pass the transaction bytes to the HSM for signing

  4. Deserialize the signed transaction bytes back into a transaction object

  5. Submit the signed transaction to the network

How can I optimize three.js the rendering of a gltf model? I tried 4 ways, but the result is the same

I’m trying to find a way to optimize three.js . I have a gltf tree model with 2144 triangles. I am adding 1000 trees to the scene in different ways.

  1. I clone the tree in a simple loop. 2. I use InstancedMesh. 3. Using BatchedMesh 4. Clone instance tree in Blender and load all tree. All four methods give the same number of fps. I also tried 100 pieces, 1000 pieces and 5000 pieces of trees. I also tried WebGPURenderer and WebGLRenderer. The result is always about the same. Is there any way to speed up the rendering of gltf models, or is it already maximally optimized when loading into three.js . Thanks!

Issues with `setRulesChannel` and `setPublicUpdatesChannel` Not Updating Guild Object in Discord Library im creating

I’m developing a custom Discord JavaScript library, and I am encountering an issue when trying to update the rulesChannelId and publicUpdatesChannelId fields of a Guild object using the setRulesChannel and setPublicUpdatesChannel methods. These methods seem to execute without errors, but after the update, the Guild object remains unchanged as if the values were not updated at all.

This is my Guild.js file

'use strict';

const GuildMemberManager = require("../Managers/GuildMemberManager");
const GuildChannelManager = require("../Managers/GuildChannelManager");
const RoleManager = require("../Managers/RoleManager");
const PresenceManager = require("../Managers/PresenceManager");
const VoiceStateManager = require("../Managers/VoiceStateManager");
const StageInstanceManager = require("../Managers/StageInstanceManager");
const GuildInviteManager = require("../Managers/GuildInviteManager");
const GuildScheduledEventManager = require("../Managers/GuildScheduledEventManager");
const AutoModerationRuleManager = require("../Managers/AutoModerationRuleManager");
const GuildEmojiManager = require("../Managers/GuildEmojiManager");
const GuildStickerManager = require("../Managers/GuildStickerManager");
const Rest = require("../Rest");
const fetch = require("node-fetch")

class Guild {
    constructor(data, client) {
        Object.defineProperty(this, 'client', {
            value: client,
            enumerable: false,
            writable: false,
        });
        this.id = data.id;
        this.name = data.name;
        this.icon = data.icon ?? null;
        this.features = data.features ?? [];
        // put GuildApplicationCommandManager heres
        this.members = new GuildMemberManager(this, data.members ?? []);
        this.channels = new GuildChannelManager(this, data.channels ?? []);
        // put GuildBanManager here
        this.roles = new RoleManager(this, this.client);
        this.presences = new PresenceManager(this, data.presences ?? []);
        this.voiceStates = new VoiceStateManager(this, data.voice_states ?? []);
        this.stageInstances = new StageInstanceManager(this, data.stage_instances ?? []);
        this.invites = new GuildInviteManager(this, data.invites ?? []);
        this.scheduledEvents = new GuildScheduledEventManager(this, data.scheduled_events ?? []);
        this.autoModerationRules = new AutoModerationRuleManager(this, data.auto_moderation_rules ?? []);
        // put vailable: here
        // put shardId: here
        this.splash = data.splash ?? null;
        this.banner = data.banner ?? null;
        this.description = data.description ?? null;
        this.verificationLevel = data.verification_level ?? 0;
        this.vanityURLCode = data.vanity_url_code ?? null;
        // put nsfw level here
        this.premiumSubscriptionCount = data.premium_subscription_count ?? 0;
        // put discovery splash here
        this.memberCount = data.memberCount ?? 0;
        // put larger here
        // put premium progress bar here
        this.afkTimeout = data.afk_timeout ?? 0;
        this.afkChannelId = data.afk_channel_id ?? null;
        this.systemChannelId = data.system_channel_id ?? null;
        this.premiumTier = data.premium_tier ?? 0;
        this.widgetEnabled = data.widget_enabled ?? false;
        this.widgetChannelId = data.widget_channel_id ?? null;
        this.explicitContentFilter = data.explicit_content_filter ?? 0;
        this.mfaLevel = data.mfa_level ?? 0;
        this.joinedTimestamp = data.joined_timestamp ?? null;
        this.defaultMessageNotifications = data.default_message_notifications ?? 0;
        // put SystemChannelFlagsBitField here
        this.maximumMembers = data.maximum_members ?? 500000;
        this.maximumPresences = data.maximum_presences ?? null;
        this.maxVideoChannelUsers = data.max_video_channel_users ?? 0;
        this.maxStageVideoChannelUsers = data.max_stage_video_channel_users ?? 0;
        this.approximateMemberCount = data.approximate_member_count ?? 0;
        this.approximatePresenceCount = data.approximate_presence_count ?? 0;
        this.vanityURLUses = data.vanity_url_uses ?? 0;
        this.rulesChannelId = data.rules_channel_id ?? null;
        this.publicUpdatesChannelId = data.public_updates_channel_id ?? null;
        this.preferredLocale = data.preferred_locale ?? 'en-US';
        // put safetyAlertsChannelId here
        this.ownerId = data.owner_id ?? null;
        this.emojis = new GuildEmojiManager(this, data.emojis ?? []);
        this.stickers = new GuildStickerManager(this, data.stickers ?? []);
    }

    /**
     * Edits the guild using PATCH.
     *
     * Available options to update:
     * - `name` *(string)*: The new name of the guild.
     * - `afkChannelId` *(string|null)*: The ID of the voice channel where AFK users are moved.
     * - `afkTimeout` *(number)*: The AFK timeout in seconds.
     * - `systemChannelId` *(string|null)*: The ID of the system channel.
     * - `systemChannelFlags` *(number)*: System channel flags (bitfield).
     * - `verificationLevel` *(number)*: The verification level (0–4).
     * - `explicitContentFilter` *(number)*: The explicit content filter level (0–2).
     * - `defaultMessageNotifications` *(number)*: Default message notification level (0–1).
     * - `icon` *(string|null)*: A data URI or base64 string of the guild icon. `null` to remove.
     * - `splash` *(string|null)*: A data URI or base64 string of the guild splash image. `null` to remove.
     * - `discoverySplash` *(string|null)*: A data URI or base64 string for the guild’s discovery splash. `null` to remove.
     * - `banner` *(string|null)*: A data URI or base64 string of the guild banner. `null` to remove.
     * - `rulesChannelId` *(string|null)*: The ID of the rules channel.
     * - `publicUpdatesChannelId` *(string|null)*: The ID of the public updates channel.
     * - `preferredLocale` *(string)*: The preferred locale (e.g., "en-US").
     * - `description` *(string|null)*: The description for the guild (shown in server discovery).
     * 
     * @param {Object} options - The guild settings to update.
     * @param {string} [options.name]
     * @param {string|null} [options.afkChannelId]
     * @param {number} [options.afkTimeout]
     * @param {string|null} [options.systemChannelId]
     * @param {number} [options.systemChannelFlags]
     * @param {number} [options.verificationLevel]
     * @param {number} [options.explicitContentFilter]
     * @param {number} [options.defaultMessageNotifications]
     * @param {string|null} [options.icon]
     * @param {string|null} [options.splash]
     * @param {string|null} [options.discoverySplash]
     * @param {string|null} [options.banner]
     * @param {string|null} [options.rulesChannelId]
     * @param {string|null} [options.publicUpdatesChannelId]
     * @param {string} [options.preferredLocale]
     * @param {string|null} [options.description]
     * 
     * @returns {Promise<Guild>} The updated Guild instance.
     */

    async edit(options) {
        const validProperties = [
            'name',
            'afkChannelId',
            'afkTimeout',
            'systemChannelId',
            'systemChannelFlags',
            'verificationLevel',
            'explicitContentFilter',
            'defaultMessageNotifications',
            'icon',
            'splash',
            'discoverySplash',
            'banner',
            'rulesChannelId',
            'publicUpdatesChannelId',
            'preferredLocale',
            'description'
        ];

        for (const key in options) {
            if (!validProperties.includes(key)) {
                throw new Error(`Invalid property: ${key}`);
            }
        }

        const requestData = {
            name: 'name' in options ? options.name : this.name,
            afk_channel_id: 'afkChannelId' in options ? options.afkChannelId : this.afkChannelId,
            afk_timeout: 'afkTimeout' in options ? options.afkTimeout : this.afkTimeout,
            system_channel_id: 'systemChannelId' in options ? options.systemChannelId : this.systemChannelId,
            system_channel_flags: 'systemChannelFlags' in options ? options.systemChannelFlags : this.systemChannelFlags,
            verification_level: 'verificationLevel' in options ? options.verificationLevel : this.verificationLevel,
            explicit_content_filter: 'explicitContentFilter' in options ? options.explicitContentFilter : this.explicitContentFilter,
            default_message_notifications: 'defaultMessageNotifications' in options ? options.defaultMessageNotifications : this.defaultMessageNotifications,
            icon: 'icon' in options ? options.icon : this.icon,
            splash: 'splash' in options ? options.splash : this.splash,
            discovery_splash: 'discoverySplash' in options ? options.discoverySplash : this.discoverySplash,
            banner: 'banner' in options ? options.banner : this.banner,
            rules_channel_id: 'rulesChannelId' in options ? options.rulesChannelId : this.rulesChannelId,
            public_updates_channel_id: 'publicUpdatesChannelId' in options ? options.publicUpdatesChannelId : this.publicUpdatesChannelId,
            preferred_locale: 'preferredLocale' in options ? options.preferredLocale : this.preferredLocale,
            description: 'description' in options ? options.description : this.description
        };


        const updatedData = await Rest.patch(this.client.token, `/guilds/${this.id}`, requestData);

        Object.assign(this, {
            name: updatedData.name,
            afkChannelId: updatedData.afk_channel_id,
            afkTimeout: updatedData.afk_timeout,
            systemChannelId: updatedData.system_channel_id,
            systemChannelFlags: updatedData.system_channel_flags,
            verificationLevel: updatedData.verification_level,
            explicitContentFilter: updatedData.explicit_content_filter,
            defaultMessageNotifications: updatedData.default_message_notifications,
            icon: updatedData.icon,
            splash: updatedData.splash,
            discoverySplash: updatedData.discovery_splash,
            banner: updatedData.banner,
            rulesChannelId: updatedData.rules_channel_id,
            publicUpdatesChannelId: updatedData.public_updates_channel_id,
            preferredLocale: updatedData.preferred_locale,
            description: updatedData.description
        });

        return this;
    }

    async setName(name) {
        if (typeof name !== 'string' || name.length < 1 || name.length > 100) {
            throw new Error("Name must be a string between 1 and 100 characters.");
        }

        return await this.edit({ name });
    }

    async setAFKChannel(channel) {
        const channelId = typeof channel === 'string' ? channel : channel?.id;

        if (!channelId || typeof channelId !== 'string') {
            throw new Error("[Vunsh]");
        }

        const fullChannel = await this.channels.fetch(channelId);

        if (!fullChannel || fullChannel.type !== 2) {
            throw new Error("AFK channel must be a voice channel.");
        }

        return await this.edit({ afkChannelId: channelId });
    }

    async setAFKTimeout(timeout) {
        const validTimeouts = [60, 300, 900, 1800, 3600];
        if (!validTimeouts.includes(timeout)) {
            throw new Error("Timeout must be one of the following values in seconds: 60, 300, 900, 1800, or 3600.");
        }

        const updatedData = await Rest.patch(this.client.token, `/guilds/${this.id}`, {
            afk_timeout: timeout
        });

        Object.assign(this, {
            afkTimeout: updatedData.afk_timeout
        });

        return this;
    }

    async setIcon(icon) {
        if (icon !== null && typeof icon !== 'string') {
            throw new Error("Icon must be a string (data URI, URL) or null to remove it.");
        }

        if (icon === null) {
            return await this.edit({ icon: null });
        }

        if (icon.startsWith('http')) {
            try {
                const res = await fetch(icon);
                if (!res.ok) throw new Error(`Failed to fetch image from URL: ${res.statusText}`);
                const contentType = res.headers.get('content-type');
                const buffer = await res.buffer();
                const base64 = buffer.toString('base64');
                icon = `data:${contentType};base64,${base64}`;
            } catch (err) {
                throw new Error(`Failed to process image URL: ${err.message}`);
            }
        }

        return await this.edit({ icon });
    }

    async setBanner(banner) {
        if (banner !== null && typeof banner !== 'string') {
            throw new Error("Banner must be a string (data URI, URL) or null to remove it.");
        }

        if (banner === null) {
            return await this.edit({ banner: null });
        }

        if (banner.startsWith('http')) {
            try {
                const res = await fetch(banner);
                if (!res.ok) throw new Error(`Failed to fetch image from URL: ${res.statusText}`);
                const contentType = res.headers.get('content-type');
                const buffer = await res.buffer();
                const base64 = buffer.toString('base64');
                banner = `data:${contentType};base64,${base64}`;
            } catch (err) {
                throw new Error(`Failed to process banner image URL: ${err.message}`);
            }
        }

        return await this.edit({ banner });
    }

    async setSplash(splash) {
        if (splash !== null && typeof splash !== 'string') {
            throw new Error("Splash must be a string (data URI, URL) or null to remove it.");
        }

        if (splash === null) {
            return await this.edit({ splash: null });
        }

        if (splash.startsWith('http')) {
            try {
                const res = await fetch(splash);
                if (!res.ok) throw new Error(`Failed to fetch splash image from URL: ${res.statusText}`);
                const contentType = res.headers.get('content-type');
                const buffer = await res.buffer();
                const base64 = buffer.toString('base64');
                splash = `data:${contentType};base64,${base64}`;
            } catch (err) {
                throw new Error(`Failed to process splash image URL: ${err.message}`);
            }
        }

        return await this.edit({ splash });
    }

    async setDiscoverySplash(splash) {
        if (splash !== null && typeof splash !== 'string') {
            throw new Error("Discovery splash must be a string (data URI, URL) or null to remove it.");
        }

        if (splash === null) {
            return await this.edit({ discovery_splash: null });
        }

        if (splash.startsWith('http')) {
            try {
                const res = await fetch(splash);
                if (!res.ok) throw new Error(`Failed to fetch discovery splash image from URL: ${res.statusText}`);
                const contentType = res.headers.get('content-type');
                const buffer = await res.buffer();
                const base64 = buffer.toString('base64');
                splash = `data:${contentType};base64,${base64}`;
            } catch (err) {
                throw new Error(`Failed to process discovery splash image URL: ${err.message}`);
            }
        }

        return await this.edit({ discovery_splash: splash });
    }

    async setSystemChannel(channel) {
        let channelId = null;

        if (typeof channel === 'string') {
            channelId = channel;
        } else if (typeof channel === 'object' && channel !== null && 'id' in channel) {
            channelId = channel.id;
        } else if (channel !== null) {
            throw new Error("Channel must be a string (channel ID), an object with an 'id' property, or null.");
        }

        return await this.edit({ systemChannelId: channelId });
    }

    async setSystemChannelFlags(flags) {
        if (typeof flags !== 'number') {
            throw new Error("Flags must be a number representing a bitfield.");
        }

        return await this.edit({ systemChannelFlags: flags });
    }

    async setPublicUpdatesChannel(channel) {
        const channelId = typeof channel === 'string' ? channel : channel?.id;

        if (!channelId || typeof channelId !== 'string') {
            throw new Error("Invalid channel provided. Must be a string ID or a channel object with an ID.");
        }

        const fullChannel = await this.channels.fetch(channelId);
        if (!fullChannel) {
            throw new Error("Channel not found in this guild.");
        }

        return await this.edit({ publicUpdatesChannelId: channelId });
    }

    async setRulesChannel(channel) {
        const channelId = typeof channel === 'string' ? channel : channel?.id;
    
        if (!channelId || typeof channelId !== 'string') {
            throw new Error("Invalid channel ID.");
        }
    
        const fullChannel = await this.channels.fetch(channelId);
    
        if (!fullChannel || ![0, 5].includes(fullChannel.type)) {
            throw new Error("Rules channel must be a text or announcement channel.");
        }
    
        return await this.edit({ rulesChannelId: channelId });
    }
}

module.exports = Guild;

This is my Rest.js file

/**
 * A utility class for making HTTP requests to the Discord API.
 */
module.exports = class Rest {
    /**
     * Makes a GET request to the Discord API.
     * 
     * @param {string} authorization - The bot token.
     * @param {string} endpoint - The API endpoint to send the GET request to (e.g., `/guilds/{guildId}`).
     * @returns {Promise<Object>} A promise that resolves to the parsed JSON response from the API.
     * @throws {Error} Throws an error if the API request fails or returns an invalid response.
     * @private
     */
    static async get(authorization, endpoint) {
        const response = await fetch(`https://discord.com/api/v10${endpoint}`, {
            method: 'GET',
            headers: {
                'Authorization': `Bot ${authorization}`,
                'Content-Type': 'application/json'
            }
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        return await response.json();
    }

    /**
     * Makes a PATCH request to the Discord API.
     * 
     * @param {string} authorization - The bot token.
     * @param {string} endpoint - The API endpoint to send the PATCH request to (e.g., `/guilds/{guildId}`).
     * @param {Object} data - The JSON body data to send with the PATCH request.
     * @returns {Promise<Object>} A promise that resolves to the parsed JSON response from the API.
     * @throws {Error} Throws an error if the API request fails or returns an invalid response.
     * @private
     */
    static async patch(authorization, endpoint, data) {
        const response = await fetch(`https://discord.com/api/v10${endpoint}`, {
            method: 'PATCH',
            headers: {
                'Authorization': `Bot ${authorization}`,
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        return await response.json();
    }
};

Shift data associated with an array’s index based on filter data

I have an array of any values, as well as data associated with each value.
This data is stored as Record<string,FooData> where the key is generated using the index within the array.

However, I am struggling to implement a correct solution for shifting the meta back to their correct place after the array has been filtered.

An example scenario:
[ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ]

The array is then filtered outside of my function. The old array is unknown, all that remains is the following data:

  • The new array is [ 'a', 'b', 'd', 'e', 'h', 'i', 'j' ]. Remember that it’s unknown[] and not sorted.
  • The indeces of the removed elements from before the filter. In this case, it would be [ 2, 5, 6 ] (corresponding to [ 'c', 'f', 'g' ])
  • The length of the array before it was filtered. In this case 10

Knowing this information, how can I shift all records to their new location? ('h' moved from index 7 to 4)

I do not need to remove dangling data from the end of the array. All data in the record is from before the filter.

Reproducible Example

function getKey(i: number) {
   return `unknownProcess[${i}]`;
}

// Array before the filter
const originalArray = [ 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j' ]
// Associated data is the upper case variant of the letter
const associatedData: Record<string, string> = {}
originalArray.forEach((letter, i) => {
  associatedData[getPath(i)] = letter.toUpperCase();
});
// data[getKey(0)] === 'A'
// data[getKey(2)] === 'C'

// Array after filter
// [ 'a', 'b', 'd', 'e', 'h', 'i', 'j' ]
// data[getKey(0)] === 'A'
// data[getKey(2)] === 'C' // should be 'D' now
// data[getKey(4)] === 'E' // should be 'H' now

type FooData = any

// separate file, cannot access data above
function shiftDataFromFilter(filteredArray: unknown[], data: Record<string, FooData>, removedIndeces: number[], lengthBeforeFilter: number) {
  // to get data of index 0
  const fooData = data[getKey(0)];
}

how to solve valiadation in javascrpt?

I have found this type of error in my code
: Duplicate entry ” for key ‘new_serial_number’
: HHH000010: On release of batch it still contained JDBC statements
: /hardware/update (queryCount: 17)
: Exception occured. in validation when there is not required validation, still error is showing. using HTML,THYMleaf spring

                                        <label><span class="text-danger"><strong>* </strong></span>資産の種類:</label>
                                        <div class="form-inline">
                                            <label class="radio-inline">
                                                <input type="radio" value="true" id="machineTrue"
                                                        th:field="${hardwareForm.machine}"
                                                        th:checked="${hardwareForm.machine}" />マシン
                                            </label>
                                            <label class="radio-inline">
                                                <input type="radio" value="false" id="machineFalse"
                                                        th:field="${hardwareForm.machine}"
                                                        th:checked="${hardwareForm.machine}" />マシン以外
                                            </label>
                                        </div>
                                    </div></div>

                                


                                        <div class="form-group col-md-5">
                                            <label><span class="text-danger"><strong>* </strong></span>製造番号:
                                            </label>
                                            <input type="hidden" id="tmp_newSerialNumber"></input>
                                            <input class="form-control" th:field="*{newSerialNumber}"
                                                th:id="newSerialNumber"></input>
                                            <span class="error_frontSide" style="color: red;"></span>
                                            <span class="errorField" th:if="${#fields.hasErrors('newSerialNumber')}"
                                                th:errors="*{newSerialNumber}" style="color: red"></span>

                                        </div>  here number is depependant on マシン. i wnat to show マシン when number is clicked only, not for マシン以外,.

Backend development [closed]

I’m a systems engineering student in Mexico. I’m interested in backend engineering because of a project I need to develop. So, if anyone could give me advice or recommend tutorials so I can learn more about this and pursue it professionally, I’d be very grateful

I expect help from developers

Why is my CSS Grid code not working on my HTML form even though it should be working? What’s wrong with it?

Trying to implement CSS grids for this “Job Application” page for an assignment and I’ve been stuck for a good 3 hours trying to figure out what’s wrong with it even though I’ve followed like 5 different tutorials and I’ve followed their instructions and it’s not working.
here is the code

* {
  font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
}

body,
html,
h1,
h2 {
  padding: 0;
  margin: 0;
  box-sizing: border-box;
}

h1,
h2 {
  color: #46767E;
}

.job-title {
  background-color: #EBC4BB;
  padding: 12px;
  margin: 0;
}

h3 {
  padding-left: 20px;
}

/* Grid Boxes for Application */
fieldset {
  border: 0
}

.container {
  display: grid;
  grid-template-rows: repeat(6, auto);
  /* Changed to auto for flexibility */
  grid-template-columns: repeat(3, 1fr);
  /* Using fr units for better responsiveness */
  gap: 5px;
  padding: 5px;
  text-align: center;
}

.job-number {
  background-color: #EBC4BB;
  padding: 20px;
  border: solid #46767E;
  text-align: center;
  grid-row: 1 / 2;
  grid-column: 1 / 3;
}

.job-personalinfo {
  background-color: #EBC4BB;
  padding: 20px;
  border: solid #46767E;
  text-align: center;
  grid-row: 2 / 4;
  grid-column: 1 / 2;
}
<h1 id="page-title">Job Application Form</h1>
<hr>
<main>
  <div class="container">

    <form action="https://mercury.swin.edu.au/it000000/formtest.php" method="POST" enctype="multipart/form-data"> <!-- Action needs to handle submissions -->
      <div class="job-number">
        <label for="job-ref">Job Reference Number:</label>
        <select id="job-ref" name="job_ref" required>
          <option value="" disabled selected>Select your job reference</option>
          <option value="001">001-Front-End Developer</option>
          <option value="002">002-Back-End Developer</option>
          <option value="003">003-Full-Stack Developer</option>
          <option value="004">004-Web Designer</option>
          <option value="005">005-Data Analyst/option>
          <option value="006">006-UX/UI Designer</option>
          <option value="007">007-Software Engineer</option>
          <option value="008">008-Project Manager</option>
          <option value="009">009-Quality Assurance Tester</option>
          <option value="010">010-DevOps Engineer</option>
          <!-- Add more options as necessary -->
        </select>
      </div>

      <br><br>

      <div class="job-personalinfo">
        <fieldset>
          <h3>Personal information</h3>

          <label for="first-name">First Name:</label>
          <input type="text" id="first-name" name="first_name" maxlength="20" required placeholder="Luke">

          <label for="last-name">Last Name:</label>
          <input type="text" id="last-name" name="last_name" maxlength="20" required placeholder="Skywalker">

          <!-- <br><br> -->

          <label for="dob">Date of Birth:</label>
          <input type="date" id="dob" name="dob" required>
          <p>Gender</p>
          <input type="radio" id="male" name="gender" value="male" required>
          <label for="male">Male</label>
          <input type="radio" id="female" name="gender" value="female">
          <label for="female">Female</label>
          <input type="radio" id="other" name="gender" value="other">
          <label for="other">Other</label>
        </fieldset>
      </div>
      <br>

      <br>

      <div class="job-address">
        <fieldset>
          <legend>Address</legend>

          <label for="address">Street Address:</label>
          <input type="text" id="address" name="address" maxlength="40" required>

          <label for="suburb">Suburb/Town:</label>
          <input type="text" id="suburb" name="suburb" maxlength="40" required>

          <label for="state">State:</label>
          <select id="state" name="state" required>
            <option value="" disabled selected>Select your state</option>
            <option value="VIC">VIC</option>
            <option value="NSW">NSW</option>
            <option value="QLD">QLD</option>
            <option value="NT">NT</option>
            <option value="WA">WA</option>
            <option value="SA">SA</option>
            <option value="TAS">TAS</option>
            <option value="ACT">ACT</option>
          </select>

          <label for="postcode">Postcode:</label>
          <input type="text" id="postcode" name="postcode" pattern="[0-9]{4}"  maxlength="4" required title="Exactly 4 digits.">
        </fieldset>
      </div>

      <br>

      <fieldset>
        <legend>Contact information</legend>

        <label for="email">Email Address:</label>
        <input type="email" id="email" name="email" required placeholder="[email protected]">

        <label for="phone">Phone Number:</label>
        <input type="tel" id="phone" name="phone" pattern="[0-9 ]{8,12}" required title="8 to 12 digits or spaces." placeholder="(000) 000-0000">
      </fieldset>

      <br>

      <fieldset>
        <legend>Required Technical Skills:</legend>
        <label for="skill1">HTML/CSS</label>
        <input type="checkbox" id="skill2" name="technical_skills" value="skill2">
        <label for="skill2">JavaScript</label>
        <input type="checkbox" id="skill3" name="technical_skills" value="skill3">
        <label for="skill3">Node.js</label>
        <label for="skill1">Python</label>
        <input type="checkbox" id="skill1" name="technical_skills" value="skill1">
        <label for="skill1">SQL</label>
        <label for="skill1">Version Control (Git)</label>
        <label for="skill1">Graphic Design (Adobe XD, Figma)</label>
        <!-- Add more skills as necessary -->
      </fieldset>

      <br>

      <fieldset>
        <legend>Other skills</legend>
        <textarea id="other-skills" name="other_skills" rows="4" placeholder="Please list any other skills you may have..."></textarea>
      </fieldset>

      <br>

      <button type="submit">Submit Application</button>
      <button type="reset">Re-do application</button>
    </form>

  </div>
</main>

here is what it currently looks like vs what im aiming for

here is what it currently looks like vs what im aiming for

I’d really appreciate any help I can get. I have no idea how to do this since this is my first time using grid.