How do I fix this error “Error: An API error occurred: not_allowed_token_type” on Slack?

Recently, I’ve creating Slack bot with Javascript. And then I got an error that is token type, which is given in team.accessLogs() funcntion is not allowed. Detailed error is below:

Error: An API error occurred: not_allowed_token_type
    at platformErrorFromResult (/bot-todo/node_modules/@slack/bolt/node_modules/@slack/web-api/dist/errors.js:56:33)
    at WebClient.apiCall (/bot-todo/node_modules/@slack/bolt/node_modules/@slack/web-api/dist/WebClient.js:181:56)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async getIPAddress (file:///bot-todo/program-test.js:18:27) {       
  code: 'slack_webapi_platform_error',
  data: { ok: false, error: 'not_allowed_token_type', response_metadata: {} }
}

Code:

"use strict";

import bolt from "@slack/bolt";
import chalk from "chalk";
import dotenv from "dotenv";
dotenv.config();

import fs from "node:fs";
import readline from "readline";
const rs = fs.createReadStream("./meaning-data.csv");
const rl = readline.createInterface({ input: rs });

const app = new bolt.App({
  token: process.env.SLACK_BOT_TOKEN,
  appToken: process.env.SLACK_APP_TOKEN,
  socketMode: true,
  logLevel: "debug",
});

async function getIPAddress(n, page) {
  const userInformation = await app.client.team.accessLogs({
    token: "xoxb-5515557116866-5558641076690-dzK2Qk3c1HcaOx2OI0wlD8SU",
    before: 1701620221,
    count: n,
    page: page,
    limit: 1,
    team_id: "T05F5GD3ERG",
  });

  console.log(chalk.blue(userInformation));
}

getIPAddress("1", "12");

Up until now, I tried:

  • Test whether this token is valid or not with auth.test api
  • Given “admin” scope to the user scope to use accessLogs() function
    admin user scope

Webcam virtual background BodyPix problems on iPhone

I’m working on a webapp that use the webcam to replace the user background as a virtual background, the problem is it isnt working on ipphone. I have found a lot of documentation and info on how to do it with TensorFlow and BodyPix, I achieved the goal really fast but when I tested on iPhone it doesn’t work, so I went and look for tutorials and test several tutorials about this, using different methods. No one of them work properly on iPhone.

I also found BodyPix demos that do work in iPhone (using segmentation masks) so I’m confused about why the issue come when is used to replace the background. I cant find any info. Maybe i do not know how or where to search

Here is one of the bests codes I found, i saved it on a CodePen, This works on PC, Mac, Android, but when I try on iPhone it just wont work.

https://codepen.io/monclee/pen/gOqQNRR

// Initialize variables
        let isVirtual = false;

        // DOM elements
        const videoContainer = document.getElementById('videoContainer');
        const videoElement = document.getElementById('videoElement');
        const canvasElement = document.getElementById('backgroundCanvas');
        const backgroundImage = document.getElementById('yourBackgroundImage');
        const ctx = canvasElement.getContext('2d');
        const startButton = document.getElementById('startButton');
        const stopButton = document.getElementById('stopButton');
        const errorText = document.getElementById('errorText');

         // MobileNetV1 or ResNet50
        const BodyPixModel = 'MobileNetV1';

        async function startWebCamStream() {
            try {
                // Start the webcam stream
                const stream = await navigator.mediaDevices.getUserMedia({ video: true });
                videoElement.srcObject = stream;

                // Wait for the video to play
                await videoElement.play();
            } catch (error) {
                displayError(error)
            }
        }

        // Function to start the virtual background
        async function startVirtualBackground() {
            try {
                // Set canvas dimensions to match video dimensions
                canvasElement.width = videoElement.videoWidth;
                canvasElement.height = videoElement.videoHeight;

                // Load the BodyPix model: 
                let net = null;

                switch (BodyPixModel) {
                    case 'MobileNetV1':
                        /*
                            This is a lightweight architecture that is suitable for real-time applications and has lower computational requirements. 
                            It provides good performance for most use cases.
                        */
                        net = await bodyPix.load({
                            architecture: 'MobileNetV1',
                            outputStride: 16, // Output stride (16 or 32). 16 is faster, 32 is more accurate.
                            multiplier: 0.75, // The model's depth multiplier. Options: 0.50, 0.75, or 1.0.
                            quantBytes: 2, // The number of bytes to use for quantization (4 or 2).
                        });
                        break;
                    case 'ResNet50':
                        /*
                            This is a deeper and more accurate architecture compared to MobileNetV1. 
                            It may provide better segmentation accuracy, but it requires more computational resources and can be slower.
                        */
                        net = await bodyPix.load({
                            architecture: 'ResNet50',
                            outputStride: 16, // Output stride (16 or 32). 16 is faster, 32 is more accurate.
                            quantBytes: 4, // The number of bytes to use for quantization (4 or 2).
                        });
                        break;
                    default:
                        break;
                }

                // Start the virtual background loop
                isVirtual = true;
                videoElement.hidden = true;
                canvasElement.hidden = false;
                display(canvasElement, 'block');

                // Show the stop button and hide the start button
                startButton.style.display = 'none';
                stopButton.style.display = 'block';

                async function updateCanvas() {
                    if (isVirtual) {
                        // 1. Segmentation Calculation
                        const segmentation = await net.segmentPerson(videoElement, {
                            flipHorizontal: false, // Whether to flip the input video horizontally
                            internalResolution: 'medium', // The resolution for internal processing (options: 'low', 'medium', 'high')
                            segmentationThreshold: 0.7, // Segmentation confidence threshold (0.0 - 1.0)
                            maxDetections: 10, // Maximum number of detections to return
                            scoreThreshold: 0.2, // Confidence score threshold for detections (0.0 - 1.0)
                            nmsRadius: 20, // Non-Maximum Suppression (NMS) radius for de-duplication
                            minKeypointScore: 0.3, // Minimum keypoint detection score (0.0 - 1.0)
                            refineSteps: 10, // Number of refinement steps for segmentation
                        });

                        // 2. Creating a Background Mask
                        const background = { r: 0, g: 0, b: 0, a: 0 };
                        const mask = bodyPix.toMask(segmentation, background, { r: 0, g: 0, b: 0, a: 255 });

                        if (mask) {
                            ctx.putImageData(mask, 0, 0);
                            ctx.globalCompositeOperation = 'source-in';

                            // 3. Drawing the Background
                            if (backgroundImage.complete) {
                                ctx.drawImage(backgroundImage, 0, 0, canvasElement.width, canvasElement.height);
                            } else {
                                // If the image is not loaded yet, wait for it to load and then draw
                                backgroundImage.onload = () => {
                                    ctx.drawImage(backgroundImage, 0, 0, canvasElement.width, canvasElement.height);
                                };
                            }

                            // Draw the mask (segmentation)
                            ctx.globalCompositeOperation = 'destination-over';
                            ctx.drawImage(videoElement, 0, 0, canvasElement.width, canvasElement.height);
                            ctx.globalCompositeOperation = 'source-over';

                            // Add a delay to control the frame rate (adjust as needed) less CPU intensive
                            // await new Promise((resolve) => setTimeout(resolve, 100));

                            // Continue updating the canvas
                            requestAnimationFrame(updateCanvas);
                        }
                    }
                }
                // Start update canvas
                updateCanvas();
            } catch (error) {
                stopVirtualBackground();
                displayError(error);
            }
        }

        // Function to stop the virtual background
        function stopVirtualBackground() {
            isVirtual = false;
            videoElement.hidden = false;
            canvasElement.hidden = true;
            display(canvasElement, 'none');

            // Hide the stop button and show the start button
            startButton.style.display = 'block';
            stopButton.style.display = 'none';
        }

        // Helper function to set the display style of an element
        function display(element, style) {
            element.style.display = style;
        }

        // Helper function to display errors
        function displayError(error){
            console.error(error);
            // Display error message in the <p> element
            errorText.textContent = 'An error occurred: ' + error.message;
        }

        // Add click event listeners to the buttons
        startButton.addEventListener('click', startVirtualBackground);
        stopButton.addEventListener('click', stopVirtualBackground);

        // Start video stream
        startWebCamStream();

As far as I can see there are no errors, also I have tried Chrome and Safari in the iPhone, but is not working at all.

Is this error documented and I haven’t found it? Can anyone point me on the right direction, thanks in advance.

Send and email with several dates in body of message

I am trying to get a script to automatically send emails to the Manager when the auditor has not completed an audit despite 2 previous email reminders. Here is my script:

//Email to Manager for incomplete Internal Audit Register Review
function sendManagerInternalAuditRegisterEmails() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName("Internal Audit Register").activate();
  var lastRow = sheet.getLastRow();
  var message = spreadsheet.getSheetByName("Email Alerts").getRange(17,1).getValue(); //Cell A17

  for (var i = 3;i<=lastRow;i++){ //From row 3 to the last row

    var emailAddress = sheet.getRange(i, 12).getValue(); //Column L
    var firstName = sheet.getRange(i, 11).getValue(); //Column K
    var managerName = sheet.getRange(i, 13).getValue(); //Column M
    var todaysDate = sheet.getRange(1, 14).getValue(); //Cell N1
    var date = sheet.getRange(i, 7).getValue(); //Column G - date added to spreadsheet
    var date2 = sheet.getRange(i, 15).getValue(); //Column O - date of first email reminder
    var date3 = sheet.getRange(i, 16).getValue(); //Column P - date of second email reminder
    var formattedDate = Utilities.formatDate(date, "GMT+1300", "dd MMMMM yyyy")
    var formattedDate2 = Utilities.formatDate(date2, "GMT+1300", "dd MMMMM yyyy")
    var formattedDate3 = Utilities.formatDate(date3, "GMT+1300", "dd MMMMM yyyy")
    var type = sheet.getRange(i, 1).getValue(); //Column A
    var id = sheet.getRange(i, 2).getValue(); //Column B
    var title = sheet.getRange(i, 3).getValue(); //Column C
    var reason = sheet.getRange(i, 4).getValue(); //Column D
    var messageBody = message.replace("{Name}",firstName). replace("{Manager}",managerName).replace("{Type}",type).replace("{ID}",id).replace("{Title}",title).replace("{Reason}",reason).replace("{Date}",formattedDate).replace("{Date2}",formattedDate2).replace("{Date3}",formattedDate3);
    var subject = "Incomplete Internal Audit Review Task"; 
    var sendDate = sheet.getRange(i, 17).getValue(); //Column Q - date of email to Manager advising that the Auditor is still yet to complete the audit
    var sheetDate = new Date(sendDate);
    Sdate=Utilities.formatDate(todaysDate,"GMT+1300","dd MMMM yyyy")
    SsheetDate=Utilities.formatDate(sheetDate,"GMT+1300", "dd MMMM yyyy")
    
    
    if (Sdate == SsheetDate){
      var subject = "Reminder - Internal Audit Review Task";
      MailApp.sendEmail(emailAddress, subject, messageBody);
      
    }    
  }
}

There are 3 dates:

  • date = the date the required audit task was added to the spreadsheet.
    This date appears in the body of the email message.
  • date2 = the date of the first reminder email sent to the Auditor as it had not been
    completed. There is a separate script for the first email. This date
    is in the script above to inform the Manager of the date the previous
    email had been sent to the Auditor. See the body of the email message
    template below.
  • date3 = the date of the second reminder email sent to the Auditor as it had not been completed. There is a separate script for the second email. This date is in the script above to
    inform the manager of the date the previous email was sent to the auditor. See the body of the email message template below.
  • sendDate = the date to send the email to the Auditor’s Manager.

I keep getting the following message at date2 and date3:

Exception: The parameters (String,String,String) don't match the method signature for Utilities.formatDate.

sendManagerInternalAuditRegisterEmails

Email Message Template

Would appreciate your help.

Make an iframe as light-weight and restricted/secure as possible?

In the context of using a local server only (for desktop), I’m trying to accept user input to allow for HTML/CSS/JS to render their extended notes stored in a local database and displayed using srcdoc. The iframe should never be able to load content from any source other than requesting it from the local url.

It’s not hard to just get it to work but I’m not sure how to make it as secure as possible and to use as little memory as possible since it is somewhat limited in its functionality. By secure, I mean if one user attempts to use the “shared notes” from another, I wouldn’t want those notes to be able to load anything externally.

Thus far, I’ve used sandbox="allow-scripts allow-modal". Is there anything else that should/could be done?

In terms of memory usage, I looked at web components and, although they are written of in terms of “encapsulating functionality” and sometimes refer to scripts/methods as being private, they don’t seem to truly separate the JS code of the component from the parent JS code and don’t appear to be flexible in terms of the user frequently changing the content as it is built. But there is also a warning about an iframe potentially using a lot of resources, such as at MDN. Is there anything that can be done to keep that to a minimum when everything is only local and same-origin?

This is all coded in plain JS, no frameworks.

Thank you.

How do I make the output of the openai api response that gets displayed more comprehensible rather than it just being a paragraph?

I am doing a personal project where a user enters specifications to generate a workout. I used jQuery’s $.ajax function to send a POST request to the OpenAI API endpoint. However, the output of the AI onto the user interface is in paragraph form which is annoying to read and understand. How do I have the output on the user interface look more readable and easy to take in?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WorkoutWizard</title>
    <link rel="stylesheet" href="style.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="main.js" defer></script>
    <script src="https://kit.fontawesome.com/91ced6fe6d.js" crossorigin="anonymous"></script>

</head>
<body>
    <header>
        <div class="title-container">
            <i class="fa-solid fa-hat-wizard"></i>
            <div class="title">WorkoutWizard</div>
        </div>
    </header>
    <div class="main">
        <div class="main-card">
            <div class="settings">
                <form>
                    <div class="name spec">
                        <label>Name:</label>     
                        <input type="text" id="user-name" name="user-name">
                    </div>

                    <div class="level spec">
                        <label>Current Fitness Level:</label>
                        <ul class="level-options">
                            <li>
                                <input type="radio" name="level" id="radio">
                                <label>Beginner</label>
                            </li>
                            <li>
                                <input type="radio" name="level" id="radio">
                                <label>Intermediate</label>
                            </li>
                            <li>
                                <input type="radio" name="level" id="radio">
                                <label>Advanced</label>
                            </li>
                        </ul>
                    </div>

                    <div class="duration spec">
                        <label for="workoutDuration">Workout Duration (minutes):</label>
                        <input type="number" id="workoutDuration" name="workoutDuration" min="10" max="120" required>
                    </div>

                    <div class="muscles spec">
                        <label>Targeted Muscles (1-2):</label>
                        <ul>
                            <li>
                                <input type="checkbox" id="muscleChest" name="muscles" value="chest">
                                <label for="muscleChest">Chest</label>
                            </li>

                            <li>
                                <input type="checkbox" id="muscleBack" name="muscles" value="back">
                                <label for="muscleBack">Back</label>
                            </li>

                            <li>
                                <input type="checkbox" id="muscleShoulders" name="muscles" value="shoulders">
                                <label for="muscleShoulders">Shoulders</label>    
                            </li>

                            <li>
                                <input type="checkbox" id="muscleArms" name="muscles" value="arms">
                                <label for="muscleArms">Arms</label>    
                            </li>

                            <li>
                                <input type="checkbox" id="muscleGlutes" name="muscles" value="glutes">
                                <label for="muscleGlutes">Glutes</label>    
                            </li>

                            <li>
                                <input type="checkbox" id="muscleLegs" name="muscles" value="legs">
                                <label for="muscleLegs">Legs</label>    
                            </li>

                            <li>
                                <input type="checkbox" id="muscleAbs" name="muscles" value="abs">
                                <label for="muscleAbs">Abdominals</label>    
                            </li>

                            <li>
                                <input type="checkbox" id="muscleLowerBack" name="muscles" value="lowerBack">
                                <label for="muscleLowerBack">Lower Back</label>  
                            </li>

                            <li>
                                <input type="checkbox" id="muscleCardio" name="muscles" value="muscleCardio">
                                <label for="muscleCardio">Cardio</label>    
                            </li>
                        </ul>
                    </div>

                    <div class="exercise spec">
                        <label for="exercise">Exercise Type:</label>
                        <select id="exercise" name="exercise" required>
                            <option value="" disabled selected>Select Exercise Type</option>
                          <option value="strength">Strength</option>
                          <option value="hypertrophy">Hypertrophy</option>
                          <option value="functional">Functional</option>
                          <option value="hiit">High-intensity interval training (HIIT)</option>
                        </select>
                    </div>

                    <div class="button">
                        <a href="#" class="btn41-43 btn-43">
                            Generate Workout
                        </a>
                    </div>
                </form>
            </div>
            <div class="message">
                <div id="loadingAnimation" class="loading-animation"></div>
                <div class="message-content" id="generatedWorkout"></div>
            </div>
        </div>
    </div>
</body>
</html>
@import url('https://fonts.googleapis.com/css2?family=Ubuntu&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&family=Saira+Extra+Condensed:wght@800&display=swap');

* {
    padding: 0;
    margin: 0;
    outline: none;
    border: none;
    box-sizing: border-box;
}

.main {
    height: 85vh;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: white;
    margin-top: -20px;
}

.main-card {
    display: flex;
    justify-content: space-between;
    width: 80%;
    height: 90%;
    background-color: #ff5252;
    border-radius: 20px;
    border: 10px solid  #ff7b7b;
}

.settings {
    height: 100%;
    width: 400px;
    background-color: #ff0000;
    border-radius: 2.5px 0 0 2.5px;
    padding: 15px;
}

form {
    font-family: 'Ubuntu', sans-serif;
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    height: 100%;
}

.level {
    display: flex;
}


.level ul {
    list-style: none;
    margin-left: 20px;
}

.muscles {
    display: flex;
}

.muscles ul {
    list-style: none;
    margin-left: 20px;
}

.spec {
    color: white;
}

.spec input {
    border-radius: 2.5px;
}

.btn41-43 {
    padding: 10px 25px;
    font-family: "Roboto", sans-serif;
    font-weight: 500;
    background: transparent;
    outline: none !important;
    cursor: pointer;
    transition: all 0.3s ease;
    position: relative;
    display: inline-block;
  }
  
  .btn-43 {
    border: 2px solid rgb(255, 255, 255);
    z-index: 1;
    color: white;
    text-decoration: none;
    font-family: 'Ubuntu', sans-serif;
  }
  
  .btn-43:after {
    position: absolute;
    content: "";
    width: 100%;
    height: 0;
    top: 0;
    left: 0;
    z-index: -1;
    background: rgb(255, 255, 255);
    transition: all 0.3s ease;
  }
  
  .btn-43:hover {
    color: rgb(0, 0, 0);
  }
  
  .btn-43:hover:after {
    top: auto;
    bottom: 0;
    height: 100%;
  }

.message {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    width: 65%;
}

.message-content {
    width: 100%;
    height: 90%;
    margin-right: 25px;
    margin-left: 25px;
    font-family: 'Ubuntu', sans-serif;
    line-height: 25px;
}

.loading-animation {
    border: 16px solid #f3f3f3; /* Light grey */
    border-top: 16px solid #3498db; /* Blue */
    border-radius: 50%;
    width: 80px;
    height: 80px;
    animation: spin 1s linear infinite;
    position: absolute;
    top: 50%;
    left: 60%;
    transform: translate(-50%, -50%);
    display: none; /* Initially hide the loading animation */
}

@keyframes spin {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(360deg); }
}

.title-container {
    display: flex;
    width: 100%;
    height: 15vh;
    align-items: center;
    justify-content: center;
    font-size: 4rem;
    background-color: white;
    font-family: 'Saira Extra Condensed', sans-serif;
    color: #ff0000;
}
document.addEventListener('DOMContentLoaded', function () {
    document.addEventListener('DOMContentLoaded', function () {
        var checkboxes = document.querySelectorAll('input[name="muscles"]');
        
        checkboxes.forEach(function (checkbox) {
          checkbox.addEventListener('change', function () {
            var checkedCheckboxes = document.querySelectorAll('input[name="muscles"]:checked');
            
            if (checkedCheckboxes.length > 2) {
              this.checked = false; // Prevent checking more than 2 checkboxes
            }
            
            if (checkedCheckboxes.length < 1) {
              this.checked = true; // Ensure at least 1 checkbox is checked
            }
          });
        });
    });

    // Add an event listener to the "Generate Workout" button
    document.querySelector('.btn41-43').addEventListener('click', function (event) {
        event.preventDefault(); // Prevent the default form submission behavior

        showLoadingAnimation();
        
        // Gather user inputs
        var userName = document.getElementById('user-name').value;
        var fitnessLevel = document.querySelector('input[name="level"]:checked').value;
        var workoutDuration = document.getElementById('workoutDuration').value;
        var selectedMuscles = Array.from(document.querySelectorAll('input[name="muscles"]:checked')).map(checkbox => checkbox.value);
        var exerciseType = document.getElementById('exercise').value;

        // Construct the message object
        var message = {
            "role": "user",
            "content": `Generate a workout routine for ${userName} with fitness level ${fitnessLevel}, targeting ${selectedMuscles.join(', ')} muscles, lasting ${workoutDuration} minutes, and focusing on ${exerciseType} exercises. (Keep response to about 100 words max)`
        };

        // Send request to OpenAI API
        $.ajax({
            url: "https://api.openai.com/v1/chat/completions",
            type: "POST",
            contentType: "application/json",
            data: JSON.stringify({
                "model": "gpt-3.5-turbo",
                "messages": [message],
                "temperature": 0.7
            }),
            beforeSend: function (xhr) {
                xhr.setRequestHeader('Authorization', 'Bearer API-KEY');
            },
            success: function (result) {
                console.log(result);
                // Handle the result as needed (e.g., update the UI with the generated workout)
                hideLoadingAnimation();
                displayGeneratedWorkout(result.choices[0].message.content);
            },
            error: function (error) {
                hideLoadingAnimation();
                console.error(error);
            }
        });
    });

    function showLoadingAnimation() {
        // Show the loading animation
        var loadingAnimationElement = document.getElementById('loadingAnimation');
        loadingAnimationElement.style.display = 'block';
    }

    function hideLoadingAnimation() {
        // Hide the loading animation
        var loadingAnimationElement = document.getElementById('loadingAnimation');
        loadingAnimationElement.style.display = 'none';
    }

    function displayGeneratedWorkout(workoutContent) {
        // Clear the previous workout content
        var generatedWorkoutElement = document.getElementById('generatedWorkout');
        generatedWorkoutElement.innerHTML = '';

        // Update the content of the element with the new generated workout
        generatedWorkoutElement.innerHTML = `<p>${workoutContent}</p>`;
    }
});

I guess I wanted the output to be a list of the workouts for the routine. Something like how chatGPT would output it.

JavaScript object values change when being read [duplicate]

I have a d3 simulation defined as follows:

this.simulation = d3
    .forceSimulation(
        Object.entries(this.vertices()).map(([k, v]) => ({
            vertex: [k, v],
            x: v.ref().position().x,
            y: v.ref().position().y,
        })) as TNodeDatum[]
    )
    .force("charge", d3.forceManyBody().strength(-this.repelForce()))
    .force(
    "link",
    d3
        .forceLink(this.links)
        .distance(this.linkDistance())
    )
    .force("center", d3.forceCenter().strength(this.centerForce()))

I then attempt to pull out the node positions like:

this.simNodes = this.simulation.nodes();

for (let i = 0; i < this.simNodes.length; ++i) {
    console.log(this.simNodes);
    console.log(i);
    console.log(this.simNodes[i]);
}

Which yields the following console output:

JavaScript console output depicting the object value changing depending on whether it is being indexed into

I do not understand how this is possible. If I console.log(this.simNodes) I can expand them and see all of the proper coordinates, but the second that I try to pull out one of the numbers, say this.simNodes[0].x I receive 0 no matter what.

I have tried JSON.stringifying the nodes, but it results in a circular definition so this is not possible. I have tried doing a .map(...) on the array of nodes, this is also not able to get the correct number. I cannot think of any other ways of doing this.

EDIT: This question has been linked as a solution. It is not a solution. The linked question refers to a disparity between how different browsers console.log Objects—my problem here is that the Object itself alters its values when trying to retrieve them.

How to set img src by method

I have an iframe and im exists some images that need to be loaded from outside of the iframe as base64.

now I am able to loop throw all images and load them by accesing the iframe and then setting the src.

but as the images maybe big, it take time which i do not want.

is there a way to do it as below for example

for (let img of [...iframeDoc.querySelectorAll("img")]) {
              img.src = async(e)=> await load(e)
}

I am aware that the code above is not valid and simple trying to show what i need

How can I get my canvas and Math.random() positions work together well?

I know, the title was very vague. I have this problem. I have a canvas with a width and a height. But when I am making “x” and “y” positions for these circles and rectangles, they don’t exactly end up where I need them to. They will be off of the canvas.

Note: I think the answer is how I do my Math.random(). I might be making the ranges of what I want incorrectly.

Note: I haven’t finished the code. I have barely started the rectangles and am still working on the “stop” and “start” buttons. The circles part (x and y positions) is what I need help with.

Javascript:

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
const canvasWidth = 1024;
const canvasHeight = 576;

const circleCounter = document.querySelector('#circle-counter');
const rectangleCounter = document.querySelector('#rectangle-counter');

const start = document.querySelector('#start');
const stop = document.querySelector('#stop');

let rectCount = 0;
let circCount = 0;

function draw() {
    let circleId = setInterval(drawCircle, 500);
    //let rectangleId = setInterval(drawRectangle, 1000);
}

function drawCircle() {
    //Creates a random hex code
    let randomColor = Math.floor(Math.random() * 16777215).toString(16);
    let color = "#" + randomColor;
    
    let radius = Math.round(Math.random() * 15 + 15);
    let diameter = 2 * radius;

    let centerX = Math.round(Math.random() * ((canvasWidth - diameter) - (0 + diameter)) + diameter);
    let centerY = Math.round(Math.random() * ((canvasHeight - diameter) - (0 + diameter)) + diameter);

    ctx.beginPath();
    ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
    ctx.fillStyle = color;
    ctx.fill();
    ctx.lineWidth = 1;
    ctx.strokeStyle = "black";
    ctx.stroke();

    circCount++;
    circleCounter.innerHTML = circCount;
}

function drawRectangle() {
    let randomColor = Math.floor(Math.random() * 16777215).toString(16);
    let color = "#" + randomColor;

    let rectangleWidth = Math.round(Math.random() * 15 + 15);
    let rectangleHeight = Math.round(Math.random() * 15 + 15);

    let cornerX = Math.round(Math.random() * (canvasWidth - 2 * rectangleWidth) + rectangleWidth);
    let cornerY = Math.round(Math.random() * (canvasHeight - 2 * rectangleHeight) + rectangleHeight);
}

function reset() {
    let confirmationStatement = confirm("Are you sure you want to reset?");

    if (confirmationStatement) {
        location.reload();
    }
}

HTML:

<!DOCTYPE html>
<html lang="en">

<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible">
        <meta name="viewport", content="width=device-width, initial-scale=1.0">
        <meta name="author" content="Christian Davis">
        <link rel="stylesheet" href="styles.css">

        <title>Paint Splatter</title>
    </head>

    <body>
        <div class="buttons">
            <button id="start" onclick="draw()">Start</button>
            <button id="stop">Stop</button>
            <button id="reset" onclick="reset()">Reset</button>
        </div>

        <div class="counter-display">
            <h2>Total Circles: <span id="circle-counter"></span></h2>
            <h2>Total Rectangles: <span id="rectangle-counter"></span></h2>
        </div>

        <canvas id="canvas"></canvas>

        <script src="app.js"></script>
    </body>
</html>

I am attempting to make a bunch of circles and rectangles appear onto a canvas at random positions with random colors and sizes. I am also trying to keep count of how many circles and rectangles there are.

TypeError: Cannot set properties of undefined (setting ‘firstName’) [closed]

I have an initial object like this…

const info = { 
    data: {
        person: {
            firstName: "",
        },
    },
};

When trying to set the name like

info.data.person.firstName = "asdfasdf";

It’s throwing Cannot set properties of undefined (setting ‘firstName’) at column 26.

I’ve checked for spelling errors or typos over and over and I’m still not seeing anything wrong with it. I understand that if ‘person’ came back undefined it would be completely valid, but I’m still not seeing the problem.

What am I missing here?

Make images appear on a website when clicked

I’ve made some motivational badges that I would love to put on my website for my followers. I’d like a way for the badges to appear initially with reduced opacity, and then on click have full opacity. A bit like the one pictured Badges. Some badges are faded out and some not. The faded out ones have not been activated. What would be the best way for this?

javascript-Chart.js v4.4.0 How to update additional data?

It seems like you’re managing multiple charts by dividing items in a single dataset.
However, you’re encountering errors whenever new data is added.

            let category = [];
            let h2s = [];
            let co = [];
            let co2 = [];
            let ch4 = [];
            let no2 = [];
            let so2 = [];

            for (let row of result) {
                h2s.push(row.h2s);
                co.push(row.co);
                co2.push(row.co2);
                ch4.push(row.ch4);
                no2.push(row.no2);
                so2.push(row.so2);
                const time = moment(row.updateDate).format('HH:mm:ss');
                category.push(time);
            }

            let h2sData = {
                labels  : category,
                datasets: [{
                    label      : 'H2S',
                    data       : h2s,
                    borderColor: 'rgba(255, 99, 132, 1)',
                }]
            };

            let coData = {
                labels  : category,
                datasets: [{
                    label      : 'CO',
                    data       : co,
                    borderColor: 'rgba(255, 255, 132, 1)',
                }]
            };

            let no2Data = {
                labels  : category,
                datasets: [{
                    label      : 'NO2',
                    data       : no2,
                    borderColor: 'rgba(255, 155, 132, 1)',
                }]
            };

            let ch4Data = {
                labels  : category,
                datasets: [{
                    label      : 'CH4',
                    data       : ch4,
                    borderColor: 'rgba(255, 255, 255, 1)',
                }]
            };

            let co2Data = {
                labels  : category,
                datasets: [{
                    label      : 'CO2',
                    data       : co2,
                    borderColor: 'rgba(255, 155, 132, 1)',
                }]
            };

            let so2Data = {
                labels  : category,
                datasets: [{
                    label      : 'SO2',
                    data       : so2,
                    borderColor: 'rgba(255, 155, 132, 1)',
                }]
            };

            initializeGraph('graph1', h2sData);
            initializeGraph('graph2', coData);
            initializeGraph('graph3', co2Data);
            initializeGraph('graph4', ch4Data);
            initializeGraph('graph5', no2Data);
            initializeGraph('graph6', so2Data);

    function initializeGraph(containerId, data) {
        let ctx = $(`#${containerId}`).get(0).getContext('2d');
        let chartInstance = new Chart(ctx, {
            type: 'line',
            data: data,
        });
        chart.push(chartInstance);
    }

function addChartData(label, newData) {
      const time = moment(label).format('HH:mm:ss');
        const gas = ['H2S', 'CO', 'CO2', 'CH4', 'NO2', 'SO2'];

        for (let i = 0; i < 6; i++) {
            chart[i].data.labels.push(time);
            console.log(chart[i].data.labels)
            chart[i].data.datasets[0].data.push(newData[gas[i]]);
            chart[i].update();
        }

}

It seems like the bug is occurring in the last function, addChartData, where a new label is being added each time an update is performed.

enter image description here

It seems that even when using chart.update(), it’s causing errors.(TypeError: chart.update is not a function) …. ;;

Chrome extension for sending WhatsApp messages with name

I’m trying to create a chrome extension for sending messages. I just want to add my name above the messages.

The problem is that I don’t know how to send my name that comes from the variable (nomeAtendente).

I would be very grateful for any help, as I’ve been searching for how to do this on the internet for a few days now and haven’t found anything.

enter image description here

const interval = setInterval(() => {
    const menu = document.querySelector("#app > div > div > div._2Ts6i._3RGKj > header > div._604FD > div > span > span");
    const content = document.querySelector("#app > div > div > div._2Ts6i._2xAQV");

    if (menu && content) {
        clearInterval(interval);

        const btnMenu = document.createElement("button");
        btnMenu.innerHTML = "7C";
        btnMenu.classList.add("btnMenu7Carros");
        menu.appendChild(btnMenu);



        const divLateralHTML = `
            Nome do atendente: <br>
            <input type="text" id="nomeAtendente">

            <br><br>
            <button id="buttonSalvar" name="button" class="">Salvar</button>
        `;
        content.insertAdjacentHTML('afterend', `<div id="divLateral" style="display: none;">${divLateralHTML}</div>`);


        //Abre e fecha o menu.
        const divLateral = document.getElementById("divLateral");
        let divLateralVisivel = false;
        btnMenu.addEventListener("click", function () {
            divLateralVisivel = !divLateralVisivel;
            divLateral.style.display = divLateralVisivel ? "block" : "none";
        });


        //Salva os dados
        const buttonSalvar = document.getElementById("buttonSalvar");
        buttonSalvar.addEventListener("click", function () {
            localStorage.setItem("nomeAtendente", document.getElementById("nomeAtendente").value);
            alert("Salvo com sucesso!")
        });
        // Obtém o valor do localStorage e define no input
        document.getElementById("nomeAtendente").value = localStorage.getItem('nomeAtendente') || "";



        const nomeAtendente = localStorage.getItem("nomeAtendente");





        document.addEventListener("keydown", function (e) {
            handleEvent(e);
        });

        document.addEventListener("keyup", function (e) {
            handleEvent(e);
        });

        document.addEventListener("keypress", function (e) {
            handleEvent(e);
        });

        function handleEvent(e) {
            const elemento = document.querySelector("#main > footer > div._2lSWV._3cjY2.copyable-area > div > span:nth-child(2) > div > div._1VZX7 > div._3Uu1_ > div > div > p > span");

            if (elemento !== null) {
                mensagemOriginal = elemento.textContent.trim();
                localStorage.setItem("mensagemOriginal", mensagemOriginal);
                //console.log("Original: " + mensagemOriginal);
            }


            if (e.key === "Enter" || e.code === "Enter") {
                mensagemOriginal = localStorage.getItem('mensagemOriginal') || ""
                const novaMensagem = `*[${nomeAtendente}]*n${mensagemOriginal}`;
                console.log(novaMensagem);


                var elementoRemover = document.querySelector("#main > footer > div._2lSWV._3cjY2.copyable-area > div > span:nth-child(2) > div > div._1VZX7 > div._3Uu1_ > div > div.lhggkp7q.qq0sjtgm.jxacihee.c3x5l3r8.b9fczbqn.t35qvd06.m62443ks.rkxvyd19.c5h0bzs2.bze30y65.kao4egtt.kh4n4d4z.tt14wmjx");
                if (elementoRemover) {
                    elementoRemover.parentNode.removeChild(elementoRemover);
                }

                // Selecione o elemento com a classe "selectable-text" e classe "copyable-text"
                var elementoModificar = document.querySelector("#main > footer > div._2lSWV._3cjY2.copyable-area > div > span:nth-child(2) > div > div._1VZX7 > div._3Uu1_ > div > div > p");
                if (elementoModificar) {
                    elementoModificar.innerHTML = elementoModificar.innerHTML.replace(/<br>/g, '');
                
                    elementoModificar.innerHTML += `<span class="selectable-text copyable-text" data-lexical-text="true">${novaMensagem}</span>`;
                }



                localStorage.setItem("mensagemOriginal", "");
            }
        }


    }
}, 1000);

Poblem with images uploading, take a long time to upload to the database

I have a form on my website that allows users to upload four images to it in order to use these images for specific purposes. My problem is that the form takes a very long time when the user presses the submit button, which makes the user experience bad, knowing that I use the GD extension to compress images in PHP. In simpler terms, when the user uploads images to the form and clicks the submit button, the form takes about a minute or two to take it to the next page

            <div class="main-img-container">
            <p class="uplod-main-img-text">Upload main image<span style="color:red"> *</span></p>
            <label for="main-img" id="main-img-label"
                <div id="main-img-view">
                    <img src="icons/uploadimgicon.png" id="icon-img">
                </div>
            </label>
        </div>
        <div class="multiple-imgs-container">
            <p class="uplod-three-imgs-text">Upload three more images<span style="color:red"> *</span></p>
            <label for="multiple-imgs" id="multiple-imgs-label">
                <input type="file" class="multiple-imgs" id="multiple-imgs" name="multiple-imgs[]" accept="image/*"
                    multiple hidden>
                <div id="multiple-imgs-view">
                    <img src="icons/uploadimgicon.png" id="icon-img">
                </div>
            </label>
        </div>

Is there a solution such as making the process of compressing images and uploading them to the database in the background without the user knowing and without making him wait on the same page? For example, when the user clicks on the submit button, he goes directly to the next page of the website without waiting for the process of compressing and uploading images to database to complete
Thank you all

buggy animation on chrome of https://codepen.io/paulnoble/details/PwOxOY [closed]

I’m encountering an intermittent issue with the animation of a field representation on the link i have put in the title. i am trying to make something like it. The field animation occasionally exhibits glitches or erratic behavior upon page load, happening only once or twice with each load cycle.

The animation involves complex 3D transformations and CSS animations to simulate a football field. Despite attempted optimizations in CSS and some adjustments in the JavaScript code, the glitch persists sporadically.

The glitches primarily occur during the initial load, impacting the smoothness of the field animation. While I’ve tried simplifying the animations and optimizing the performance, the issue remains inconsistent.

I’m seeking advice or suggestions on how to troubleshoot and resolve this intermittent rendering glitch in the field animation. Any insights or approaches to debug and stabilize the animation on load would be greatly appreciated.

  • tried checking if its a css issue but all changes done didnt resolve this issue
  • tried to change stuff in velocity js but didnt resolve this issue

Thank you in advance for any guidance or expertise in addressing this issue!

How to check if two sets of radio button is selected and output results onto website?

    function checkradio() {

        var sizeSelect = document.getElementsByName("size");
        var colorSelect = document.getElementsByName("colors");
        var quantityCheck = document.getElementById("quantity");


        var sizeSelected = false;
        var colorSelected = false;

        for (var i = 0, len = sizeSelect.length; i < len; i++) {
            if (sizeSelect[i].checked === true) {
                sizeSelected = true;         
            }
        }

        for (var j = 0, len2 = colorSelect.length; j < len2; j++) {
            if (colorSelect[j].checked === true) {
                colorSelected = true;         
            }
        }



        if (colorSelected === true && sizeSelected  === true && quantityCheck > 0){
            var productname = document.getElementById("pname");
            var sentence = " has been added to your basket";
            document.getElementById("result").innerHTML = productname.concat(temp);
            }
            else{
                var incorrect = "You need to select your style, size  and quantity for this product to add to the cart";
                document.getElementById("result").innerHTML = incorrect;

            }
      
    }

    </script>

Checking if two sets of radio button both have had answer selected as well as quantity>0 however everytime the output for this not being met is being outputted. Im not sure why