Error while connecting to MongoDB atlas , My IP is whitelisted and added 0.0.0.0 too

enter image description hereI am new to the backend and is learning it currently, I am facing a error. Here is the error

ERROR: mongodb+srv://dhruv:[email protected]/videotube MongooseServerSelectionError: Could not connect to any servers in your MongoDB Atlas cluster. One common reason is that you’re trying to access the database from an IP that isn’t whitelisted. Make sure your current IP address is on your Atlas cluster’s IP whitelist: https://www.mongodb.com/docs/atlas/security-whitelist/
at _handleConnectionErrors (C:UsersdhruvOneDriveDocumentsWeb dev pracBackend DevProfessional Backend setupnode_modulesmongooselibconnection.js:1110:11)
at NativeConnection.openUri (C:UsersdhruvOneDriveDocumentsWeb dev pracBackend DevProfessional Backend setupnode_modulesmongooselibconnection.js:1041:11)
at async connectDb (file:///C:/Users/dhruv/OneDrive/Documents/Web%20dev%20prac/Backend%20Dev/Professional%20Backend%20setup/src/db/index.js:8:31) {
reason: TopologyDescription {
type: ‘ReplicaSetNoPrimary’,
servers: Map(3) {
‘dhruvdeepchakravorty-shard-00-00.t7pt2.mongodb.net:27017’ => [ServerDescription],
‘dhruvdeepchakravorty-shard-00-02.t7pt2.mongodb.net:27017’ => [ServerDescription],
‘dhruvdeepchakravorty-shard-00-01.t7pt2.mongodb.net:27017’ => [ServerDescription]
},
stale: false,
compatible: true,
heartbeatFrequencyMS: 10000,
localThresholdMS: 15,
setName: ‘atlas-z5wloi-shard-0’,
maxElectionId: null,
maxSetVersion: null,
commonWireVersion: 0,
logicalSessionTimeoutMinutes: null
},
code: undefined
}

import mongoose from "mongoose";
import { db_Name } from "../constants.js";


const connectDb= async()=>{
   
  try {
    const connectionInstance= await mongoose.connect(`${process.env.MONGODB_URI}/${db_Name}`)
    console.log(`n DB connected at host : ${connectionInstance.connection.host}`)
  } catch (error) {
    console.error(`ERROR: ${process.env.MONGODB_URI}/${db_Name}`,error);
    process.exit(1);
  }
}
import connectDb from "./db/index.js";
import dotenv from "dotenv";
dotenv.config({ path: './.env' });

connectDb();


My code is correct (I think so), how can i solve this ?
Please check photos for the code

  1. Was trying to connect to mongoDB atlas.
  2. my Ip is Whitelisted and i have also added 0.0.0.0/0 too in network access

Chrome extension using Drive API returns incomplete search

I’m working on a Chrome Extension with the Drive API v3. My OAuth, API key and client_id are working fine. I’m having trouble fetching any data.

I used this as a starting point and it works fine for the People API. I modified the oauth.js code to this:

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
  chrome.identity.getAuthToken({interactive: true}, function(token) {
  let init = {
    method: 'GET',
    async: true,
    headers: {
      Authorization: 'Bearer ' + token,
      'Content-Type': 'application/json'
    },
    'contentType': 'json'
  };
  fetch(
    //'https://www.googleapis.com/drive/v3/files?mimeType!='application/vnd.google-apps.folder'',
    //'https://www.googleapis.com/drive/v3/files?q=name%20contains%20'Yamaha'',
    //'https://www.googleapis.com/drive/v3/files?name='Spices'',
    'https://www.googleapis.com/drive/v3/files?q='0Bxl5Z50oMH4MX2E0UXdhQUdUbGs'',
    init)
    .then((response) => response.json())
    .then(response => {
      console.log(JSON.stringify(response))
      console.log("Done stringify");
      console.log(response);
      console.log("Done response");
      
    })
   });
  });
 };

The commented lines are attempts at different fetch syntaxes.

For each of these attempts, I do not get any console errors but instead I get the following:

Console

What is the missing piece? Ideally, I’d like to get all the files/folders, their ids and names!

dataTables fixedColumn part is not working

I am using DataTables version 1.10.18 and attempting to freeze the first column in the table. I have included the fixedColumns.js and the corresponding CSS files; however, the FixedColumns functionality is not working as expected. Upon checking the resources in the debug tools, both fixedColumns.js and CSS files appear to have been loaded successfully.

Please refer the below image
enter image description here.

import {LightningElement,api} from 'lwc';
import dataTableResource from '@salesforce/resourceUrl/DataTableDemo';
import JqueryResource from '@salesforce/resourceUrl/jquery331';
import {
    loadScript,
    loadStyle
} from 'lightning/platformResourceLoader';
import {
    ShowToastEvent
} from 'lightning/platformShowToastEvent';
// import toast message event .

// import apex class and it's methods.
import getAccounts from '@salesforce/apex/LWCExampleController.getAccounts';


export default class SampleTable1 extends LightningElement {
    accounts = [];
    error;
    @api recordId;
    async connectedCallback() {
        await this.fetchAccoutns();

        Promise.all([
            loadScript(this, JqueryResource),
            loadScript(this, dataTableResource + '/DataTables-1.10.18/media/js/jquery.dataTables.min.js'),
            loadScript(this, dataTableResource + '/DataTables-1.10.18/extensions/FixedColumns/js/dataTables.fixedColumns.min.js'),
            loadScript(this, dataTableResource + '/DataTables-1.10.18/extensions/FixedColumns/js/fixedColumns.dataTables.js'),
            loadStyle(this, dataTableResource + '/DataTables-1.10.18/media/css/jquery.dataTables.min.css'),
            loadStyle(this, dataTableResource + '/DataTables-1.10.18/extensions/FixedColumns/css/fixedColumns.dataTables.css'),
        ]).then(() => {
            console.log('script loaded sucessfully');

            const table = this.template.querySelector('.tableClass');
            const columnNames = ['Spend Category', 'Spend Sub Category', 'Line Item Description', 'Calculation Description', 'NGO and ILP Discussion','Q1','Q2','Q3','Q4'];
            let tableHeaders = '<thead> <tr>';
            columnNames.forEach(header => {
                tableHeaders += '<th>' + header + '</th>';
            });
            tableHeaders += '</tr></thead>';
            table.innerHTML = tableHeaders;

            let jqTable = $(table).DataTable({
                fixedColumns: {
                    leftColumns: 1 // Fix the first column
                }
            });
            $('div.dataTables_filter input').addClass('slds-input');
            $('div.dataTables_filter input').css("marginBottom", "10px");

            this.accounts.forEach(rec => {
                let tableRows = [];
                //tableRows.push('<a href="/lightning/r/Account/' + rec.Id + '/view">' + rec.Name + '</a>');
                tableRows.push(rec.Spend_Category_T__c != undefined ? rec.Spend_Category_T__c : '');
                tableRows.push(rec.Spend_Sub_Category_T__c != undefined ? rec.Spend_Sub_Category_T__c : '');
                tableRows.push(rec.Line_Item_Description__c != undefined ? rec.Line_Item_Description__c : '');
                tableRows.push(rec.Calculation_Description__c != undefined ? rec.Calculation_Description__c : '');
                tableRows.push(rec.NGO_and_ILP_Discussion__c != undefined ? rec.NGO_and_ILP_Discussion__c : '');
                tableRows.push(rec.Q1__c != undefined ? rec.Q1__c : '');
                tableRows.push(rec.Q2__c != undefined ? rec.Q2__c : '');
                tableRows.push(rec.Q3__c != undefined ? rec.Q3__c : '');
                tableRows.push(rec.Q4__c != undefined ? rec.Q4__c : '');
                jqTable.row.add(tableRows);
            });
            jqTable.draw();

        }).catch(error => {
            this.error = error;
            console.log('error in loaded script',this.error)
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error!!',
                    message: JSON.stringify(error),
                    variant: 'error',
                }),
            );
        });
    }

    async fetchAccoutns() {
        await getAccounts()
            .then(data => {
                if (data) {
                    this.accounts = data;
                }
            })
            .catch(error => {
                this.error = error;
                this.accounts = undefined;
                this.error = 'Unknown error';
                if (Array.isArray(error.body)) {
                    this.error = error.body.map(e => e.message).join(', ');
                } else if (typeof error.body.message === 'string') {
                    this.error = error.body.message;
                }
                this.dispatchEvent(
                    new ShowToastEvent({
                        title: 'Error!!',
                        message: error,
                        variant: 'error',
                    }),
                );
            });
    }

}

How to delete saved passwords in Chrome for my website using a Chrome extension?

I’m developing a Chrome extension and I want to delete any saved passwords in Chrome’s password manager that are associated with my website. My goal is to ensure that no credentials for my website are stored in the browser.

I understand that Chrome extensions have access to the chrome.storage API for managing their own data, but I couldn’t find any way to access or delete saved passwords in Chrome’s password manager.

Here’s what I’ve tried so far:

chrome.storage.sync.get(null, function(items) {
  for (var key in items) {
    if (items.hasOwnProperty(key)) {
      var url = extractUrlFromKey(key);
      if (url === 'www.example.com') {
        chrome.storage.sync.remove(key, function() {
          console.log('Şifre silindi.');
        });
      }
    }
  }
});

In a .net 6 MVC site I’m using cropper.js to crop photos. It works on my local machine, but not on my server (IIS 10)

I’m using cropper.js in an MVC .net 6 app.

It works on my local machine but not on IIS.

_Layout.cshtml:

@using Microsoft.AspNetCore.Identity
@using Memayo.ViewModels
@using Microsoft.AspNetCore.Http
@using System.Security.Claims
@inject SignInManager<AppUser> SignInManager
@inject UserManager<AppUser> UserManager
@inject IHttpContextAccessor HttpContextAccessor
@{
    var userId = HttpContextAccessor.HttpContext.User.FindFirstValue(ClaimTypes.NameIdentifier);
    var user = userId != null ? await UserManager.FindByIdAsync(userId) : null;
    var avatarUrl = user?.Avatar != null ? $"/images/uploads/small/{user.Avatar}" : "/images/default-avatar.png";
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>@ViewData["Title"] - Memayo</title>
    <link rel="stylesheet" href="~/bootstrap/css/bootstrap.min.css" />
    <link rel="stylesheet" href="~/css/site.css" />
    <link href="~/css/memayo.css" rel="stylesheet" />

@*     <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-eval';"> *@

@*     <link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.css" rel="stylesheet" /> *@    
 <link href="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.6.2/cropper.min.css" rel="stylesheet" />
</head>
<body>
    <header>
        <nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
            <div class="container">
                <a class="nav-linkxx xxtext-dark" asp-controller="Home" asp-action="Index">
                    <img class="memayologo" src="~/images/logo.png" />
                </a>

                <button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
                        aria-expanded="false" aria-label="Toggle navigation">
                    <span class="navbar-toggler-icon"></span>
                </button>

                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
                    <ul class="navbar-nav flex-grow-1">
                        @if (SignInManager.IsSignedIn(User))
                        {
                            @if (User.IsInRole("admin"))
                            {
                                <li class="nav-item">
                                    <a class="nav-link text-lightx text-danger" asp-area="venus" asp-controller="AHome" asp-action="Index">Admin Area</a>
                                </li>
                            }
                            else
                            {
                                <li class="nav-item">
                                    <a class="nav-link" asp-controller="Yarn" asp-action="Index">Yarn</a>
                                </li>
                                <li class="nav-item">
                                    <a class="nav-link" asp-controller="Question" asp-action="Index">Chapters</a>
                                </li>
                                <li class="nav-item">
                                    <a class="nav-link" asp-controller="Photo" asp-action="Index">Photos</a>
                                </li>
                                <li class="nav-item">
                                    <a class="nav-link" asp-controller="YourQuestion" asp-action="Index">My Q&A</a>
                                </li>
                                <li class="nav-item dropdown">
                                    <a class="nav-link dropdown-toggle" data-bs-toggle="dropdown" href="#" role="button" aria-expanded="false">Friends</a>
                                    <ul class="dropdown-menu">
                                        <li><a class="dropdown-item" asp-controller="Friend" asp-action="Index">Friends List</a></li>
                                        <li><a class="dropdown-item" asp-controller="Friend" asp-action="Requests">Friend Requests</a></li>
                                        <li><a class="dropdown-item" asp-controller="Friend" asp-action="Search">Search for Friends</a></li>
                                    </ul>
                                </li>
                            }
                        }
                    </ul>

                    <ul class="navbar-nav">
                        @if (SignInManager.IsSignedIn(User))
                        {
                            <li class="nav-item dropdown">
                                <a class="nav-link d-flex align-items-center gap-2" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                                    <div class="rounded-circle overflow-hidden" style="width: 38px; height: 38px;">
                                        @if (user?.Avatar != null)
                                        {
                                            <img src="@avatarUrl" alt="User Avatar" class="w-100 h-100 object-fit-cover" />
                                        }
                                        else
                                        {
                                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128" class="w-100 h-100">
                                                <circle cx="64" cy="64" r="64" fill="#E2E8F0" />
                                                <path d="M64 36c7.732 0 14 6.268 14 14s-6.268 14-14 14-14-6.268-14-14 6.268-14 14-14zM64 70c18.778 0 34 8.222 34 20v8c0 2-2 2-2 2H32s-2 0-2-2v-8c0-11.778 15.222-20 34-20z" fill="#94A3B8" />
                                            </svg>
                                        }
                                    </div>
                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-chevron-down" viewBox="0 0 16 16">
                                        <path fill-rule="evenodd" d="M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z" />
                                    </svg>
                                </a>
                                <ul class="dropdown-menu dropdown-menu-end">
                                    <li><a class="dropdown-item" asp-controller="MyProfile" asp-action="Profile">Profile</a></li>
                                    <li><a class="dropdown-item" asp-controller="MyProfile" asp-action="Avatar">Avatar</a></li>
                                    <li><hr class="dropdown-divider"></li>
                                    <li><a class="dropdown-item" asp-controller="account" asp-action="Logout">Logout</a></li>
                                </ul>
                            </li>
                        }
                        else
                        {
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-controller="account" asp-action="Register">Register</a>
                            </li>
                            <li class="nav-item">
                                <a class="nav-link text-dark" asp-controller="account" asp-action="Login">Login</a>
                            </li>
                        }
                    </ul>
                </div>
            </div>
        </nav>
    </header>
    <div class="container">
        <main role="main" class="pb-3">
            <partial name="_MessagePartial" />
            @RenderBody()
        </main>
    </div>

    <footer class="border-top footer text-muted">
        <div class="container">
            <partial name="_VersionPartial" />
            <a asp-controller="Home" asp-action="Privacy">Privacy</a> |
            <a asp-controller="Home" asp-action="Terms">Terms</a>
        </div>
    </footer>
    <script src="~/js/jquery/dist/jquery.min.js"></script>
    <script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
    <script src="~/bootstrap/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/cropperjs/1.5.12/cropper.min.js"></script>
    @await RenderSectionAsync("Scripts", required: false)
</body>
</html>

Controller:

using CSharpAwsSesServiceHelper.EmailService;
using Memayo.Models;
using Memayo.ViewModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using System.Security.Claims;
using Microsoft.AspNetCore.Authentication;
using System.Collections.Generic;
using Microsoft.Extensions.Hosting;
using Memayo.Repositories;
using Microsoft.AspNetCore.Http;
using System.IO;
using System.Linq;
using System;

using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.Processing;

namespace Memayo.Controllers
{
    [Authorize(Roles = "user")]
    public class MyProfileController : Controller
    {
        private readonly ILogger<MyProfileController> _logger;
        private IWebHostEnvironment _env;
        private SignInManager<AppUser> _signManager;
        private UserManager<AppUser> _userManager;
        private readonly IEmailService _emailService;
        private readonly IUserRepository _userRepository;
        private readonly IHttpContextAccessor _httpContextAccessor;

        private string userId => _httpContextAccessor.HttpContext.User.FindFirst(ClaimTypes.NameIdentifier).Value;

        public MyProfileController(ILogger<MyProfileController> logger, IWebHostEnvironment env,
            UserManager<AppUser> userManager, SignInManager<AppUser> signManager,
            IEmailService emailService, IUserRepository userRepository,
            IHttpContextAccessor httpContextAccessor)
        {
            _logger = logger;
            _env = env;
            _userManager = userManager;
            _signManager = signManager;
            _emailService = emailService;
            _userRepository = userRepository;
            _httpContextAccessor = httpContextAccessor;
        }

        public IActionResult Index()
        {
            return View();
        }

        public async Task<IActionResult> Profile()
        {
            var user = await _userRepository.GetAsync(userId);
            return View(user);
        }

        [HttpPost]
        public async Task<IActionResult> Profile(User user)
        {
            await _userRepository.UpdateProfileAsync(user);
            TempData["message"] = "Profile Updated";
            return RedirectToAction("Index", "Home");
        }

        [Authorize(Roles = "user")]
        public async Task<IActionResult> Avatar()
        {
            var user = await _userRepository.GetAsync(userId);
            return View(user);
        }

        [HttpPost]
        [Authorize(Roles = "user")]
        public async Task<IActionResult> Avatar(IFormFile avatar)
        {
            try
            {
                if (avatar == null)
                {
                    _logger.LogError("Avatar is null");
                    return Json(new { success = false, error = "No file received" });
                }

                _logger.LogInformation($"Received file: {avatar.FileName}, Length: {avatar.Length}, ContentType: {avatar.ContentType}");

                if (avatar.Length == 0)
                {
                    TempData["messageError"] = "Please upload a valid image.";
                    return Json(new { success = false, error = "Empty file" });
                }

                // Check file type
                var allowedExtensions = new[] { ".png", ".jpg", ".jpeg" };
                var extension = Path.GetExtension(avatar.FileName).ToLower();
                if (!allowedExtensions.Contains(extension))
                {
                    TempData["messageError"] = "Only PNG and JPG images are allowed.";
                    return Json(new { success = false, error = "Invalid file type" });
                }

                // Delete old avatar if exists, get user
                var user = await _userRepository.GetAsync(userId);

                var uploadsDir = Path.Combine(_env.WebRootPath, "images", "uploads");
                var filename = $"{Guid.NewGuid()}{extension}";
                var oldAvatarPathLarge = Path.Combine(uploadsDir, "large", user.Avatar);
                var oldAvatarPathSmall = Path.Combine(uploadsDir, "small", user.Avatar);
                var newAvatarPathLarge = Path.Combine(uploadsDir, "large", filename);
                var newAvatarPathSmall = Path.Combine(uploadsDir, "small", filename);

                _logger.LogInformation($"Paths: New Large: {newAvatarPathLarge}, New Small: {newAvatarPathSmall}");

                // Delete old avatar if exists
                if (System.IO.File.Exists(oldAvatarPathLarge))
                {
                    try
                    {
                        System.IO.File.Delete(oldAvatarPathLarge);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"Error deleting old large avatar: {ex.Message}");
                    }
                }

                if (System.IO.File.Exists(oldAvatarPathSmall))
                {
                    try
                    {
                        System.IO.File.Delete(oldAvatarPathSmall);
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"Error deleting old small avatar: {ex.Message}");
                    }
                }

                // Resize the image
                using (var image = await Image.LoadAsync(avatar.OpenReadStream()))
                {
                    _logger.LogInformation("Image loaded successfully");

                    var maxWidthLarge = 1000;
                    var maxHeightLarge = 1000;
                    var maxWidthSmall = 200;
                    var maxHeightSmall = 200;

                    var largeImage = image.Clone(ctx => ctx.Resize(new ResizeOptions
                    {
                        Size = new SixLabors.ImageSharp.Size(maxWidthLarge, maxHeightLarge),
                        Mode = ResizeMode.Max
                    }));

                    var smallImage = image.Clone(ctx => ctx.Resize(new ResizeOptions
                    {
                        Size = new SixLabors.ImageSharp.Size(maxWidthSmall, maxHeightSmall),
                        Mode = ResizeMode.Max
                    }));

                    _logger.LogInformation("Images resized");

                    try
                    {
                        if (extension == ".png")
                        {
                            await largeImage.SaveAsync(newAvatarPathLarge, new PngEncoder());
                            await smallImage.SaveAsync(newAvatarPathSmall, new PngEncoder());
                        }
                        else
                        {
                            await largeImage.SaveAsync(newAvatarPathLarge, new JpegEncoder());
                            await smallImage.SaveAsync(newAvatarPathSmall, new JpegEncoder());
                        }
                        _logger.LogInformation("Images saved successfully");
                    }
                    catch (Exception ex)
                    {
                        _logger.LogError($"Error saving images: {ex.Message}nStack: {ex.StackTrace}");
                        throw;
                    }
                }

                // Update the user's avatar path in the database
                user.Avatar = filename;
                await _userRepository.UpdateAvatarAsync(user);
                _logger.LogInformation("Database updated successfully");

                TempData["message"] = "Avatar updated successfully.";
                return Json(new { success = true });
            }
            catch (Exception ex)
            {
                _logger.LogError($"Avatar upload error: {ex.Message}nStack: {ex.StackTrace}");
                return Json(new { success = false, error = ex.Message });
            }
        }
    }
}

View:

@model Memayo.Models.User
@{
    ViewData["Title"] = "Edit Avatar";
}
<h2>Edit Avatar</h2>
<div class="avatar-section">
    <h4>Current Avatar</h4>
    <div class="current-avatar">
        @if (!string.IsNullOrEmpty(Model.Avatar))
        {
            <img src="/images/uploads/large/@Model.Avatar" alt="User Avatar" class="rounded-circle" style="max-width: 200px; max-height: 200px;" />
        }
        else
        {
            <p>No avatar uploaded. Please upload an avatar.</p>
        }
    </div>
</div>
<hr />
<div class="upload-section">
    @if (TempData["message"] != null)
    {
        <div class="alert alert-success">@TempData["message"]</div>
    }
    @if (TempData["messageError"] != null)
    {
        <div class="alert alert-danger">@TempData["messageError"]</div>
    }
    <form id="avatarForm" method="post" enctype="multipart/form-data">
        <div class="form-group">
            <label for="avatar">Select New Avatar</label>
            <input type="file" class="form-control" id="avatar" name="avatar" accept=".jpg,.jpeg,.png" />
            <small class="form-text text-muted">Allowed: .jpg, .png</small>
        </div>
        <div class="form-group">
            <img id="preview" class="img-fluid" />
        </div>
        <button type="button" class="btn btn-primary" id="cropButton">Crop and Upload Avatar</button>
        <a asp-controller="Home" asp-action="Index" class="btn btn-secondary">Cancel</a>
    </form>
</div>

@section Scripts {
    <script type="module">
        // Initialize state
        const state = {
            cropper: null,
            uploadUrl: '@Url.Action("Avatar", "MyProfile")',
            redirectUrl: '@Url.Action("Index", "Home")',
        };

        // Configuration object for Cropper
        const cropperConfig = {
            aspectRatio: 1,
            viewMode: 1,
            autoCropArea: 1,
        };

        // Handle file input change
        function handleFileChange(event) {
            const image = document.getElementById('preview');
            const file = event.target.files[0];

            if (!file) return;

            const objectURL = URL.createObjectURL(file);
            image.src = objectURL;

            image.addEventListener('load', () => {
                if (state.cropper) {
                    state.cropper.destroy();
                }

                // Initialize the cropper with config object
                state.cropper = new Cropper(image, cropperConfig);
            }, { once: true }); // Use once: true to prevent memory leaks
        }

        // Handle crop and upload
        async function handleCropAndUpload() {
            if (!state.cropper) {
                alert('Please select an image to crop.');
                return;
            }

            try {
                const canvas = state.cropper.getCroppedCanvas({
                    width: 1000,
                    height: 1000
                });

                if (!canvas) {
                    throw new Error('Failed to generate canvas');
                }

                const blob = await new Promise((resolve) => {
                    canvas.toBlob(resolve, 'image/png', 0.9);
                });

                if (!blob) {
                    throw new Error('Failed to generate image blob');
                }

                const formData = new FormData();
                formData.append('avatar', new File([blob], 'avatar.png', {
                    type: 'image/png'
                }));

                const response = await fetch(state.uploadUrl, {
                    method: 'POST',
                    body: formData
                });

                const data = await response.json();

                if (data.success) {
                    window.location.href = state.redirectUrl;
                } else {
                    throw new Error(data.error || 'Upload failed');
                }
            } catch (error) {
                console.error('Upload error:', error);
                alert(`An error occurred: ${error.message}`);
            }
        }

        // Add event listeners
        document.getElementById('avatar').addEventListener('change', handleFileChange);
        document.getElementById('cropButton').addEventListener('click', handleCropAndUpload);
    </script>
}

I get this error in an alert:

Error uploading avatar: Value cannot be null. (Parameter ‘path3’)

I also get this error in browser tools

The Content Security Policy (CSP) prevents cross-site scripting
attacks by blocking inline execution of scripts and style sheets.

To solve this, move all inline scripts (e.g. onclick=[JS code]) and
styles into external files.

⚠️ Allowing inline execution comes at the risk of script injection via
injection of HTML script elements. If you absolutely must, you can
allow inline script and styles by:

adding unsafe-inline as a source to the CSP header adding the hash or
nonce of the inline script to your CSP header. 1 directive
Directive Element Source location Status
script-src-elem Avatar:119 blocked Learn more: Content Security
Policy – Inline Code

I’ve asked both Claude and Chat GPT 40 and o1. They suggested that I put this meta tag in but it didn’t help

and doing that that may cause security issues anyway.

I have a feeling it’s related to the unsafe CSP header but a google search revealed nothing.

How can I get this working on the server?

Thanks

Javascript get value from an object [duplicate]

I need to get the values from the propertyTwo from an javascript object and sum at the end.

Using Object.values i see the structure below :

console.log(Object.values(myObj));

[0]
propertyOne
[0]
propertyTwo
: 
"123456.25"
[1]
propertyOne
[0]
propertyTwo
: 
"78910.35"

I try to run this loop :

  Object.keys(myObj).forEach(key => {
            const value = myObj[key];
            console.log(`Key: ${key}, Value: ${value}`);
        });

But the result end with the Object keyword, how can i get access and sum each value from propertyTwo ?

Key: 0, Value: [object Object]

GraphViz Performance Improvements

I am using the quoted function below to render a ‘tech tree’ in a game I am making. It works but is pretty performance heavy when the tech tree grows. In my case it is taking up to 3 seconds to render, and it is called whenever the graph state changes which in my game can be every 10 seconds or so if the user is on that screen that shows it.

I am wondering if it would be beneficial to use a web worker, I have spent a few hours trying to set one up but I could use some tips on which libraries to use for this, and how to set it up using CDNs and ES6, as my project is a web app, not nodeJS.

If this would not be the solution needed to speed up these renders, any better libraries i can use? I already cache the render for when the state doesnt change and for example the user just switches to that screen, but if they are on that screen and it needs to change, I need to show that update.

Here is the function and what I pass in:

    export async function drawTechTree(techData, svgElement, renew) {
        const cachedTree = getRenderedTechTree();
        const container = document.querySelector(svgElement);
        container.innerHTML = '';
    
        const bgColor = getComputedStyle(container).getPropertyValue('--bg-color').trim();
        const textColor = getComputedStyle(container).getPropertyValue('--text-color').trim();
    
        const researchedBgColor = getComputedStyle(container).getPropertyValue('--text-color').trim();
        const researchedTextColor = getComputedStyle(container).getPropertyValue('--ready-text').trim();
    
        const researchedTechs = getTechUnlockedArray();
    
        const svgWidth = container.clientWidth || container.parentNode.clientWidth;
        const svgHeight = container.clientHeight || container.parentNode.clientHeight;
    
        if (cachedTree && !renew) {
            container.innerHTML = '';
            container.appendChild(cachedTree.cloneNode(true));
            setupTooltip(svgElement);
            return;
        }
    
        let graphDef = `digraph TechTree {
            graph [bgcolor="${bgColor}", size="${svgWidth / 72},${svgHeight / 72}!", size="10,7!", rankdir="TB"];
            node [
                color="${textColor}"
                style="filled,rounded",
                shape="box",
                fontname="Arial",
                fontsize=24,
                penwidth=4
                fixedsize=true,
                width=4.5,
                height=1.3
            ];
            edge [
                color="${textColor}",
                penwidth=2,
                arrowsize=1.2,
                fontname="Arial",
                fontsize=10
            ];
        `;
    
        let title = `<b>???</b><br/>???`;
    
        for (const [key, value] of Object.entries(techData)) {
            const isResearched = researchedTechs.includes(key);
            const nodeBgColor = isResearched ? researchedBgColor : bgColor;
            const nodeTextColor = isResearched ? researchedTextColor : textColor;
    
            const capitalisedTechName = capitaliseString(key);
            const separatedCapitalisedTechNames = capitalisedTechName.replace(/([a-z])([A-Z])/g, '$1 $2');
            const price = value.price;
            
    
            if (getUpcomingTechArray().includes(key) && !getRevealedTechArray().includes(key)) {
                title = `<b>???</b><br/>Price: ${price}`;
            } else {
                title = `<b>${separatedCapitalisedTechNames}</b><br/>Price: ${price}`;
            }
            graphDef += `${key} [label=<${title}> shape="box" style="rounded,filled" fontcolor="${nodeTextColor}" fillcolor="${nodeBgColor}" fontname="Arial"];n`;
        }
    
        for (const [key, value] of Object.entries(techData)) {
            const appearsAt = value.appearsAt || [];
            if (appearsAt.length > 1) {
                for (let i = 1; i < appearsAt.length; i++) {
                    const prereq = appearsAt[i];
                    if (prereq) {
                        graphDef += `${prereq} -> ${key};n`;
                    }
                }
            }
        }
    
        graphDef += "}";
    
        const graphviz = d3.select(svgElement)
            .graphviz()
            .zoom(false)
            .scale(0.8)
            .fit(false);  
    
        graphviz.renderDot(graphDef);
    
        setTimeout(() => {
            setupTooltip(svgElement);
            setRenderedTechTree(container);
        }, 50);
    }

I pass in:

export async function getTechTreeData(renew) {

    let techData = getResourceDataObject('techs');
    const unlockedTechs = getTechUnlockedArray();
    const upcomingTechs = getUpcomingTechArray();

    techData = Object.fromEntries(
        Object.entries(techData).filter(([key]) => 
            unlockedTechs.includes(key) || upcomingTechs.includes(key)
        )
    );

    await drawTechTree(techData, '#techTreeSvg', renew);
}

I have tried using a timer and consoling out the time taken for each part of the function, and the bottleneck is where it renders it, taking up to 3 seconds sometimes, so maybe I need a better solution, or help setting up a web worker, which is mentioned in the graphViz documentation but I cannot seem to get working in the CDN ES6 environment.

So open ended really, either help with this, or ideas for better libraries for my needs, which is to visualise my tech tree data which looks like below:

    techs: {
        knowledgeSharing: { appearsAt: [0, null, null], prereqs: [null], price: 150, idForRenderPosition: 10 },
        fusionTheory: { appearsAt: [500, "knowledgeSharing", ""], prereqs: ['Knowledge Sharing'], price: 750, idForRenderPosition: 20 },
        hydrogenFusion: { appearsAt: [1000, "fusionTheory", ""], prereqs: ['Fusion Theory'], price: 1150, idForRenderPosition: 30 },
        heliumFusion: { appearsAt: [2000, "hydrogenFusion", ""], prereqs: ['Hydrogen Fusion'], price: 2300, idForRenderPosition: 40 },
        carbonFusion: { appearsAt: [4100, "nobleGasCollection", ""], prereqs: ['Noble Gas Collection'], price: 4300, idForRenderPosition: 50 },
        basicPowerGeneration: { appearsAt: [3000, "heliumFusion", ""], prereqs: ['Helium Fusion'], price: 4200, idForRenderPosition: 51 },
        sodiumIonPowerStorage: { appearsAt: [5000, "basicPowerGeneration", ""], prereqs: ['Basic Power Generation'], price: 7000, idForRenderPosition: 52 }
    }

JavaScript – Is there an efficient way to check if an integer “k” is a linear combination of the values in an array of prime numbers?

I have an arbitrarily large integer k and an array of arbitrarily many positive prime numbers [p_1, p_2, ..., p_n]. Using JavaScript, I want to check if k can be expressed as a linear combination of the values of the array with nonnegative integer coefficients.

However, I haven’t been able to figure out a method for determining if any given k is a linear combination of the values in any given array.

The only answer to a similar question on this site doesn’t work because all the values in my arrays are prime numbers: their GCD is always 1, the remainder is always 0, and the return value of that answer’s expression is always True, even when it should be False.

As an example, if the array has the values [5, 7, 13], then k = 12 is a valid linear combination (1×5 + 1×7 + 0×13) while k = 16 is not.

Additionally, the code in the linked question and answer only checks for multiples less than or equal to the array values, and I want to be able to check numbers much bigger than that.

Is what I want possible to achieve?

How to properly document an express application with JSDoc

I need a quick help with JSDoc, I’m trying to document a node application running with express but I can find a way to declare it correctly for Intelisense. Below is a code snippet on what I’m trying to do and the issue.

const express = require('express');
// initializing the express application

const app = express();

/** 
 * Express application
 *
 * @public
 */
module.exports = app;

app.get('test');
app.use(anotherFunction());

What is happening for me is that neither the .get or .use (or any other method for the matter) are part of the express prototype

migrating from vue 2 to vue 3 vue-svgicon

I have to migrate an application that use vue2 (2.6.10) to the last version of vue 3; I’m also do not have many experince on frontend development;

I have create the project with

npm init vue@3

I have copied all src folder and public folder from the old project using vue2;

And with the commad:

npm install <package>

I have installed almost all dependency I have in package.json

{
  "name": "mybadge",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve --host 0.0.0.0 --port 80",
    "build": "vue-cli-service build",
    "svg": "rm -rf ./public/static/compiled-icons && vsvg -s ./src/assets/icons -t ./public/static/compiled-icons"
  },
  "dependencies": {
    "apexcharts": "^3.10.1",
    "axios": "^0.19.0",
    "core-js": "^2.6.5",
    "mini-toastr": "^0.8.1",
    "register-service-worker": "^1.6.2",
    "vue": "^2.6.10",
    "vue-apexcharts": "^1.5.1",
    "vue-axios": "^2.1.4",
    "vue-mini-toast": "^1.0.1",
    "vue-perfect-scrollbar": "^0.2.0",
    "vue-router": "^3.0.3",
    "vue-youtube": "^1.3.5",
    "vuetify": "^2.1.14"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^3.11.0",
    "@vue/cli-plugin-pwa": "^3.11.0",
    "@vue/cli-service": "^3.11.0",
    "material-design-icons-iconfont": "^5.0.1",
    "sass": "^1.17.4",
    "sass-loader": "^7.1.0",
    "vue-cli-plugin-vuetify": "^0.6.3",
    "vue-svgicon": "^3.2.6",
    "vue-template-compiler": "^2.6.10",
    "vuetify-loader": "^1.2.2"
  }
}

But no way to install vue-sgvicon!!!!

I try to install with the same command

npm install vue-svgicon --save

But I get

npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: [email protected]
npm error Found: [email protected]
npm error node_modules/vue
npm error   vue@"^3.5.13" from the root project
npm error
npm error Could not resolve dependency:
npm error peer vue@"^2.5.17" from [email protected]
npm error node_modules/vue-svgicon
npm error   vue-svgicon@"*" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error C:UsersvisAppDataLocalnpm-cache_logs2025-01-23T15_32_49_704Z-eresolve-report.txt
npm error A complete log of this run can be found in: C:UsersvisAppDataLocalnpm-cache_logs2025-01-23T15_32_49_704Z-debug-0.log

I have also used –force option, but no way to install vue-svgicon.

Scrolling function not working in mobile browsers

I created a website (www.techieafrohead.com) and facing an issue on testimonial cards horizontal scrolling. It is smoothly working in desktop browsers but when seen on samsung browsers(Chrome) or in any phone’s (android) browser , scrolling is not smooth or just not scrolling.

i tried making .card-wrapper class overflow-y to auto from hidden, but it creates a scrollbar on the right which makes it look odd because i’m expecting to do that through scroll button. Also, in javascript added a line to control the max scroll amount let scrollAmount = window.innerWidth < 768 ? 50 : 100; // Also finally tried btnScrollUp.addEventListener(‘click’, () => scrollVertically(1));
btnScrollUp.addEventListener(‘touchstart’, () => scrollVertically(1));
btnScrollDown.addEventListener(‘click’, () => scrollVertically(-1));
btnScrollDown.addEventListener(‘touchstart’, () => scrollVertically(-1));
….,but all my attempts failed.Let me know how can i fix this issue.

<div class="testimonial-container-right">
                    <div class="vertical-scroll">
                        <button class="btn-scroll" id="btn-scroll-up" onclick="scrollVertically(1)">
                            <i class="fas fa-chevron-up"></i>
                        </button>
                    </div>
                    <div class="card-wrapper">
                        <?php 
                            $testi_query = "SELECT * FROM testimonial WHERE status = 'verified' ORDER BY id DESC";
                            $testi_run = mysqli_query($conn, $testi_query);
                            if (mysqli_num_rows($testi_run) > 0) {
                                while ($row = mysqli_fetch_array($testi_run)) {
                                    $id = htmlspecialchars($row['id']);
                                    $name = htmlspecialchars($row['name']);
                                    $image = htmlspecialchars($row['profile_picture']);
                                    $review = htmlspecialchars($row['review']);
                                    $service = htmlspecialchars($row['service']);
                                    $country = htmlspecialchars($row['country']);
                                    $college = htmlspecialchars($row['college']);
                                    $rating = htmlspecialchars($row['rating_value']);
                        ?>
                                    <div class="card">
                                        <div class="testi-image">
                                            <img src="image/testimonial/<?php echo $image; ?>" alt="client-photo">
                                        </div>
                                        <div class="card__content">
                                            <span><i class="fas fa-quote-left"></i></span>
                                            <div class="card__details">
                                                <p class="card-text"><?php echo nl2br($review); ?></p>
                                                <button class="view-more-btn">View More</button><br>
                                                <div class="rating-stars_in_card">
                                                    <div class="grey-stars"></div>
                                                    <div class="filled-stars" style="width:<?php echo $rating * 20; ?>%"></div>
                                                </div>
                                                <h4>~ <?php echo $name; ?></h4>
                                                <h5><?php echo $country; 
                                                    if (!empty($college)) {
                                                        echo " ($college)"; 
                                                    }
                                                ?></h5>
                                                <h6><?php echo $service; ?></h6>
                                            </div>
                                        </div>
                                    </div>
                        <?php 
                                } // End of while loop
                            } else {
                                echo "<center><h2 style='color:var(--text-dark);'>No testimonial recorded!<h2></center>";
                            }
                        ?>
                    </div><!--card-wrapper-->
                    <div class="vertical-scroll">
                        <button class="btn-scroll" id="btn-scroll-down" onclick="scrollVertically(-1)">
                            <i class="fas fa-chevron-down"></i>
                        </button>
                    </div>
                </div><!--testimonial-container-right-->
//scrolling of testimonial cards
document.addEventListener('DOMContentLoaded', function () {
    const cardWrapper = document.querySelector('.card-wrapper');
    const btnScrollUp = document.getElementById('btn-scroll-up');
    const btnScrollDown = document.getElementById('btn-scroll-down');

    let scrollAmount = window.innerWidth < 768 ? 50 : 100; // Adjust scroll amount based on screen size

function scrollVertically(direction) {
    const scrollHeight = cardWrapper.scrollHeight;
    const clientHeight = cardWrapper.clientHeight;
    const currentScrollPosition = cardWrapper.scrollTop;

    // Scroll up
    if (direction === 1) {
        cardWrapper.scrollBy({
            top: -scrollAmount,
            behavior: 'smooth'
        });
    } 
    // Scroll down
    else {
        cardWrapper.scrollBy({
            top: scrollAmount,
            behavior: 'smooth'
        });
    }

    // Update button visibility after scrolling
    setTimeout(updateScrollButtons, 300); // Delay to allow for smooth scrolling
}

    function updateScrollButtons() {
        const currentScrollPosition = cardWrapper.scrollTop;
        const maxScrollHeight = cardWrapper.scrollHeight - cardWrapper.clientHeight;

        if (currentScrollPosition <= 0) {
            btnScrollUp.style.display = 'none'; // Hide up button
        } else {
            btnScrollUp.style.display = 'flex'; // Show up button
        }

        if (currentScrollPosition >= maxScrollHeight) {
            btnScrollDown.style.display = 'none'; // Hide down button
        } else {
            btnScrollDown.style.display = 'flex'; // Show down button
        }
    }

    // Initialize scroll button visibility
    updateScrollButtons();

    // Event listeners for buttons
    btnScrollUp.addEventListener('click', () => scrollVertically(1));
btnScrollUp.addEventListener('touchstart', () => scrollVertically(1));
btnScrollDown.addEventListener('click', () => scrollVertically(-1));
btnScrollDown.addEventListener('touchstart', () => scrollVertically(-1));

    // Add scroll event listener to update button visibility when scrolling manually
    cardWrapper.addEventListener('scroll', updateScrollButtons);

    // Add event listeners for "View More" buttons
    const viewMoreButtons = document.querySelectorAll('.view-more-btn');
    viewMoreButtons.forEach(button => {
    button.addEventListener('click', function () {
        const cardDetails = this.parentElement.querySelector('.card-text');
        cardDetails.classList.toggle('expanded'); // Toggle the expanded class
        
        // Scroll to the bottom of the card wrapper if expanding the last card
        if (this.closest('.card') === cardWrapper.lastElementChild) {
            cardWrapper.scrollTo({
                top: cardWrapper.scrollHeight, // Scroll to the bottom of the card wrapper
                behavior: 'smooth' // Smooth scroll
            });
        }

        this.textContent = cardDetails.classList.contains('expanded') ? 'View Less' : 'View More'; // Change button text

        // Update scroll button visibility
        updateScrollButtons();
    });
});
});
.testimonial-container-right{
    grid-area:testimonial-container-right;
    display:flex;
    flex-direction: column;
}
.vertical-scroll {
    display: flex;
    align-items: center;
    justify-content: center;
    position: relative; /* Change to relative for positioning */
}
.btn-scroll{
    font-size: 2rem;
    outline: none;
    border: none;
    color:var(--white);
    cursor: pointer;
    background: var(--primary-color);
    transition: .3s all ease;
}
#btn-scroll-up,
#btn-scroll-down {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    display: flex; /* Ensure it's displayed as a flex container */
    z-index: 1;
    padding: .5rem 1rem;
}
#btn-scroll-up{
    border-radius: 0 0 1rem 1rem;
    top:0;
}
#btn-scroll-down{
    border-radius: 1rem 1rem 0 0;
    bottom: 0;
}
.btn-scroll:hover,
.btn-scroll:focus{
    background-color: var(--secondary-color);
}
.card-wrapper {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-start;
    gap: 1rem;
    height: 650px;
    overflow-y: hidden;
    position: relative;
}
.card{
    padding:2rem;
    display:flex;
    flex-direction: row;
    align-items: flex-start;
    gap:1rem;
    background-color: var(--white);
    border-radius: 1rem;
    cursor:pointer;
    max-height: auto;
    border: 1px solid var(--secondary-color);
    -webkit-user-select: none; /* Safari */
    -ms-user-select: none; /* IE 10 and IE 11 */
    user-select: none; /* Standard syntax */  
    max-width: 650px;
    /*word-break: break-all;*/
}   
.testi-image{
    display: flex;
    align-items: center;
    justify-content: center;
}
.card img {
    width: 75px; /* Set a max width for the preview */
    height: 75px; /* Set a max height for the preview */
    border-radius:50%;
    border: 1px solid #eee;
    float: none;
    pointer-events: none;
}
.card__content{
    display: flex;
    gap:1rem;
    flex: 1;
    max-width: 100%;
}
.card__content span i{
    font-size: 2rem;
    color:var(--primary-color);
}
.card__details {
    flex-grow: 1; /* Allow it to grow */
    flex-shrink: 1; /* Allow it to shrink */
    min-width: 0; /* Avoid forcing unnecessary width */
    max-width: 100%; /* Prevent overflow beyond container */
    overflow: hidden;
}
.card__details p {
    max-width: 100%;
    font-size: 1rem;
    font-style: italic;
    font-weight: 400;
    color: var(--text-dark);
    margin-right: 1rem;
    margin-bottom: 1rem;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 3; /* Limit to 3 lines */
    -webkit-box-orient: vertical;
    transition: max-height 0.3s ease;
    max-height: 4.5em; /* Adjust based on line height */

}
.card__details p.expanded {
    -webkit-line-clamp: unset; /* Remove line limit */
    max-height: none; /* Allow full height */
}
.card__details h4{
    text-align: right;
    color:var(--primary-color);
    font-size: 1rem;
    font-weight: 500;
}
.card__details h5{
    text-align: right;
    color:var(--primary-color);
    font-size: .8rem;
    font-weight: 400;
    margin-bottom: .1rem;
}
.card__details h6{
    text-align: right;
    color:var(--text-light);
    font-size: .7rem;
    font-weight: 400;
    display: flex; /* Use flexbox for better alignment */
    align-items: center; /* Center align items vertically */
    justify-content: flex-end; /* Align content to the right */
    margin-top: 0;
    margin-bottom: 0;
}
.rating-stars_in_card{
    height: 30px;
    position: absolute;
    vertical-align: baseline;
    color: #b9b9b9;
    line-height: 10px;
    float: left;
    margin:1rem 0;
}
.card__details button{
    padding: .5rem 1rem;
    outline:none;
    border: none;
    border-radius: 5px;
    background: linear-gradient(
        to right,#ff226f,
        #fe6769);
    color: var(--white);
    font-size: .8rem;
    cursor: pointer;
}

Zooming relative to cursor only by element width

I have an element:

<div ref={scrollRef}>
  <div ref={containerRef} style={{ width: width * zoomCoef }}>
           
  </div>   
</div>

Where “width” is a constant and “zoomCoef” is a dynamic numerical value.
So when “zoomCoef” value changed, div shrink or expand. I want zoom to behave smooth and relative to cursor position.

To do it I have such calculations (written by chatGPT)

const zoomCallback = ({ prevZoom, newZoom, event }: { prevZoom: number, newZoom: number, event: WheelEvent }) => {
        const scrollDiv = scrollRef.current;
        const container = containerRef.current;
        if (!scrollDiv || !container) return;

        const rect = container.getBoundingClientRect();
        const scrollRect = scrollDiv.getBoundingClientRect();
        const zoomDif = newZoom / prevZoom;
        const cursorPositionOnView = event.clientX - scrollRect.left;
        const cursorX = event.clientX - rect.left;
        const newCursorX = cursorX * zoomDif;
        const newScrollLeft = newCursorX - cursorPositionOnView;
        const animationDuration = 400;
        const initialWidth = container.offsetWidth;
        const initialScrollLeft = scrollDiv.scrollLeft;
        const newWidth = container.offsetWidth * zoomDif;
        const startTime = performance.now();
        const animate = (currentTime: number) => {
            const elapsedTime = currentTime - startTime;
            const progress = Math.min(elapsedTime / animationDuration, 1);
            const interpolatedWidth = initialWidth + progress * (newWidth - initialWidth);
            const interpolatedScrollLeft = initialScrollLeft + progress * (newScrollLeft - initialScrollLeft);
            container.style.width = `${interpolatedWidth}px`;
            scrollDiv.scrollLeft = interpolatedScrollLeft;
            if (progress < 1) {
                requestAnimationFrame(animate);
            }
        };
        requestAnimationFrame(animate);
    };

I use it with animation styles:

 transition: 0.5s;
 transition: width 0.5 linear;

It kinda work, but very poor (jerks and drives back and forth).

How can I fix it to achieve smooth and precisious behavior?
The example of what I want to achieve can be found in browser devtools>performance>profile timeline, which can be scrolled in/out relative to a cursor position:
Example of such zooming

Why is this array broken? [duplicate]

I have a function getTeilnehmer(id) which gets some mail addresses from a Sharepoint list and returns them as array. Now I have this function:

async function signUp(id, userId) {
    let alleTeilnehmer = await getTeilnehmer(id);
    
    alleTeilnehmer.push('[email protected]');
    alleTeilnehmer.push('[email protected]');
    
    console.log(alleTeilnehmer);

    alleTeilnehmer.forEach( t => {
        console.log(t); 
    });
};

The output on the console is:

    > (2) ['[email protected]', '[email protected]']
        0: "[email protected]"
        1: "[email protected]"
        2: "[email protected]"
        3: "[email protected]"
        length: 4
      > [[Prototype]]: Array(0)

[email protected]
[email protected]

Why does forEach only log the pushed addresses and why only those adresses are shown in the first line of the output but when I expand this line there are the others that came from the function getTeilnehmer(id)?

From message event in ios web

I have an webapp that need an 6 digits code from text message, the input is the following

OTP example

the expected behaviour is the cursor go to the next input and copy the following number, this works in my browser, but in ios whith “from message” function, copy all number in first input

this is the code

const handlePaste = (e: React.ClipboardEvent<HTMLInputElement>) => {
    e.preventDefault()
    const matchNotOtpTypeValues =
      otpType === 'numeric' ? /[^0-9]/gi : /[^0-9a-zA-Z]/gi
    const pasteValue = e.clipboardData
      .getData('text')
      .replace(matchNotOtpTypeValues, '')

    if (
      pasteValue.length < 1 ||
      pasteValue.length > otpLength ||
      !checkOtp(pasteValue)
    )
      return
    const individualValues = pasteValue.split('')

    if (pasteValue.length === 1) {
      setOptValues({ ...otpValues, [e.currentTarget.name]: pasteValue })

      return
    }
    const newObj: Record<string, string> = { ...otpValues }

    individualValues.forEach((value, index) => {
      newObj[`${name}-${index}`] = value
    })
    setOptValues(newObj)
    const isComplete = pasteValue.length === otpLength

    setIsReadyToSubmit(isComplete)

    if (isComplete) {
      e.currentTarget.blur()
    } else {
      const nextInput = document.querySelector(
        `input[name=${name}-${pasteValue.length}]`
      ) as HTMLInputElement | null

      if (nextInput) {
        nextInput.focus()
      }
    }
  }

Is there a way to compare to values in two different array and create a new object?

First hello everyone, i will explain my problem and what i trigger to achive kind of to solve my issue.

I have to arrays that i need to compare, then create a new array of objects comparing the “group” id object, as you can see in my first array there is the array user which includes two objects , username Test-50 & Test-18, inside this objects they have groups array, which basically is necessary to compare with the second array.

First, i have two arrays:

the first one is:

   const user = [
      {
        username: "Test-50",
        group: [
          {
            id: 3127,
            name: "user default group",
          },
        ],
      },

      {
        username: "Test-18",
        group: [
          {
            id: 3069,
            name: "user default group",
          },
        ],
      },
    ];

My second array is:

Here we have the second array , here i need to compare the groups ids values from the first array with the actions scopes values to extract and use the localizedTexts.


    const actions = [
      {
        name: {
          localizedTexts: [
            {
              translation: "Enrichissement variété Google",
            },
          ],
        },
        scopes: [
          {
            group: {
              id: 3071,
              name: "Test-20",
            },
          },
          {
            group: {
              id: 3111,
              name: "Test-44",
            },
          },

          {
            group: {
              id: 3127,
              name: "Test-50",
            },
          },
        ],
      },
      {
        name: {
          localizedTexts: [
            {
              translation: "Filtre Hagberg",
            },
          ],
        },
        scopes: [
          {
            group: {
              id: 3127,
              name: "Test-50",
            },
          },
          {
            group: {
              id: 3069,
              name: "Test-18",
            },
          },
        ],
      },
    ];

My expected behaviour is :

    

expected result = [
      {
        username: "Test-50",
        group: [
          {
            id: 3127,
            name: "user default group",
          },
        ],

        actions: [
          {
            name: {
              localizedTexts: [
                {
                  translation: "Enrichissement variété Google",
                },
              ],
            },
          },

          {
            name: {
              localizedTexts: [
                {
                  translation: "Filtre Hagberg",
                },
              ],
            },
          },
        ],
      },

      {
        username: "Test-18",
        group: [
          {
            id: 3069,
            name: "user default group",
          },
        ],
        actions: [
          {
            name: {
              localizedTexts: [
                {
                  translation: "Filtre Hagberg",
                },
              ],
            },
          },
        ],
      },
    ];

I tried this function:

  const result = user.reduce((arr, e) => {
      arr.push(
        Object.assign(
          {},
          e,
          actions.find((x) =>
            x.scopes.find((w) => w.group?.id === e.groups[0]?.id)
          )
        )
      );
      return arr;
    }, []);

but the results it gives me is this one:

result = [

  {
    "username": "Test-50",
    "groups": [
      {
        "id": 3127,
        "name": "user default group"
      }
    ],
    "name": {
      "localizedTexts": [
        {
          "translation": "Enrichissement variété Google"
        }
      ]
    },
    "scopes": [
      {
        "group": {
          "id": 3071,
          "name": "Test-20"
        }
      },
      {
        "group": {
          "id": 3111,
          "name": "Test-44"
        }
      },
      {
        "group": {
          "id": 3127,
          "name": "Test-50"
        }
      }
    ]
  },
  {
    "username": "Test-18",
    "groups": [
      {
        "id": 3069,
        "name": "user default group"
      }
    ],
    "name": {
      "localizedTexts": [
        {
          "translation": "Filtre Hagberg"
        }
      ]
    },
    "scopes": [
      {
        "group": {
          "id": 3127,
          "name": "Test-50"
        }
      },
      {
        "group": {
          "id": 3069,
          "name": "Test-18"
        }
      }
    ]
  }
]

far away from what i need.

Thanks for your time.