How can I check if there are single quotes around a string in the command line?

I need to check if there are single quotes around a string and if not it will show an different message. Also we use Git Bash if that helps.

let pin = parseInt(process.argv[2], 10);
let functie = process.argv[3];
let dag = parseInt(process.argv[4], 10);

// for testing
console.log(pin);
console.log(functie);
console.log(dag);

if ((pin == 123752) && (functie == "'bestuur'" || "'administratief medewerker'") && (dag < 5)) {
    console.log(`Toegang verleend`);
} else if ((!(pin == 123752) || !(functie == "'bestuur'" || "'administratief medewerker'")) && (dag < 5)) {
    console.log(`Verkeerde pincode of je hebt niet de juiste rechten`);
} else {
    console.log(`Veiligheidsdiensten worden ingeschakeld`);
}

If I for example put this in Git Bash:

node script.js 123752 'bestuur' 1.

I get “toegang verleend” which is good but when I put this:

node script.js 123752 bestuur 1.

I should get “verkeerde pincode of je hebt niet de juiste rechten”. How can I change it so it checks if there are single quotes?

I tried changing the if statement but to no result.

Vue3 carousel doesn’t work smoothly when the iPhone is rotated

I use the vue3-carousel package in my vue project.(v0.3.1) https://www.npmjs.com/package/vue3-carousel

I implemented a simple carousel with the following code;

App.vue

<script setup lang="ts">
import { Carousel, Slide, Pagination } from 'vue3-carousel'
import 'vue3-carousel/dist/carousel.css'
</script>

<template>
  <div class="myContainer">
    <carousel :items-to-show="1">
      <slide v-for="slide in 10" :key="slide"> Slide index {{ slide }} </slide>

      <template #addons>
        <navigation />
        <pagination />
      </template>
    </carousel>
  </div>
</template>

<style scoped>
.myContainer {
  width: 90%;
  background-color: red;
  position: fixed;
  bottom: 0%;
}
</style>

index.html

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Vite App</title>
  </head>
  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.ts"></script>
  </body>
</html>

My error case is like the following;

1- I can use the carousel well in the portrait mode of my iPhone simulator the device

2- After I change the device orientation to portrait it doesn’t properly.

3- After the other orientation changes it still doesn’t work well.

I attached a demo video to the link

It seems about container fixed position but I don’t understand why fixed position couses and what this parameter breaks. Thanks.

AWS Cognito – Setting device as remembered does not suppress MFA challenge

I have 2 Cognito user-pools.

First one I have created on August 20, 2021. The following is the configuration:

{
    "UserPool": {
        "Id": "us-east-2_************",
        "Name": "dev-mobileapp-users",
        "Policies": {
            "PasswordPolicy": {
                "MinimumLength": 8,
                "RequireUppercase": true,
                "RequireLowercase": true,
                "RequireNumbers": true,
                "RequireSymbols": true,
                "TemporaryPasswordValidityDays": 7
            }
        },
        "DeletionProtection": "INACTIVE",
        "LambdaConfig": {
            "PreSignUp": "arn:aws:lambda:us-east-2:123456789009:function:dev-mobileapp-users-presignup-trigger"
        },
        "LastModifiedDate": "2024-02-16T11:13:49.777000+05:30",
        "CreationDate": "2021-08-20T10:59:47.932000+05:30",
        "SchemaAttributes": [
            {
                "Name": "sub",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": false,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "1",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "given_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "family_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "middle_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "nickname",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "preferred_username",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "profile",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "picture",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "website",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "email",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "email_verified",
                "AttributeDataType": "Boolean",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false
            },
            {
                "Name": "gender",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "birthdate",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "10",
                    "MaxLength": "10"
                }
            },
            {
                "Name": "zoneinfo",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "locale",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "phone_number",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "phone_number_verified",
                "AttributeDataType": "Boolean",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false
            },
            {
                "Name": "address",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "updated_at",
                "AttributeDataType": "Number",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "NumberAttributeConstraints": {
                    "MinValue": "0"
                }
            }
        ],
        "AutoVerifiedAttributes": [
            "email"
        ],
        "UsernameAttributes": [
            "email"
        ],
        "SmsVerificationMessage": "Your verification code is {####}. ",
        "EmailVerificationMessage": "Please enter this verification code to verify your identity:n{####}nnIf you did not make this request, please email [email protected],nThe Abc Team",
        "EmailVerificationSubject": "Your verification code",
        "VerificationMessageTemplate": {
            "SmsMessage": "Your verification code is {####}. ",
            "EmailMessage": "Please enter this verification code to verify your identity:n{####}nnIf you did not make this request, please email [email protected],nThe Abc Team",
            "EmailSubject": "Your verification code",
            "DefaultEmailOption": "CONFIRM_WITH_CODE"
        },
        "SmsAuthenticationMessage": "Your verification code is {####}. ",
        "UserAttributeUpdateSettings": {
            "AttributesRequireVerificationBeforeUpdate": []
        },
        "MfaConfiguration": "OPTIONAL",
        "DeviceConfiguration": {
            "ChallengeRequiredOnNewDevice": true,
            "DeviceOnlyRememberedOnUserPrompt": true
        },
        "EstimatedNumberOfUsers": 689,
        "EmailConfiguration": {
            "SourceArn": "arn:aws:ses:us-east-1:123456789009:identity/[email protected]",
            "EmailSendingAccount": "COGNITO_DEFAULT"
        },
        "SmsConfiguration": {
            "SnsCallerArn": "arn:aws:iam::123456789009:role/service-role/devmobileappusers-SMS-Role",
            "ExternalId": "8d37769d-08cd-44e7-987a-******************",
            "SnsRegion": "us-east-1"
        },
        "UserPoolTags": {},
        "Domain": "devmobileappusers",
        "AdminCreateUserConfig": {
            "AllowAdminCreateUserOnly": false,
            "UnusedAccountValidityDays": 7,
            "InviteMessageTemplate": {
                "SMSMessage": "Your username is {username} and temporary password is {####}. ",
                "EmailMessage": "Your username is {username} and temporary password is {####}. ",
                "EmailSubject": "Your temporary password"
            }
        },
        "UsernameConfiguration": {
            "CaseSensitive": false
        },
        "Arn": "arn:aws:cognito-idp:us-east-2:123456789009:userpool/us-east-2_*********",
        "AccountRecoverySetting": {
            "RecoveryMechanisms": [
                {
                    "Priority": 1,
                    "Name": "verified_email"
                }
            ]
        }
    }
}

Second one I have created on August 23, 2023. The following is the configuration:

{
    "UserPool": {
        "Id": "us-east-2_***********",
        "Name": "devint-mobileapp-users",
        "Policies": {
            "PasswordPolicy": {
                "MinimumLength": 8,
                "RequireUppercase": true,
                "RequireLowercase": true,
                "RequireNumbers": true,
                "RequireSymbols": true,
                "TemporaryPasswordValidityDays": 7
            }
        },
        "DeletionProtection": "ACTIVE",
        "LambdaConfig": {
            "PreSignUp": "arn:aws:lambda:us-east-2:123456789098:function:dev-mobileapp-users-presignup-trigger"
        },
        "LastModifiedDate": "2024-02-15T10:30:19.365000+05:30",
        "CreationDate": "2023-08-23T16:00:18.471000+05:30",
        "SchemaAttributes": [
            {
                "Name": "sub",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": false,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "1",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "given_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "family_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "middle_name",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "nickname",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "preferred_username",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "profile",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "picture",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "website",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "email",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "email_verified",
                "AttributeDataType": "Boolean",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false
            },
            {
                "Name": "gender",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "birthdate",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "10",
                    "MaxLength": "10"
                }
            },
            {
                "Name": "zoneinfo",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "locale",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "phone_number",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": true,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "phone_number_verified",
                "AttributeDataType": "Boolean",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false
            },
            {
                "Name": "address",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "0",
                    "MaxLength": "2048"
                }
            },
            {
                "Name": "updated_at",
                "AttributeDataType": "Number",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "NumberAttributeConstraints": {
                    "MinValue": "0"
                }
            },
            {
                "Name": "custom:internal-token",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "5"
                }
            },
            {
                "Name": "custom:user_token",
                "AttributeDataType": "String",
                "DeveloperOnlyAttribute": false,
                "Mutable": true,
                "Required": false,
                "StringAttributeConstraints": {
                    "MinLength": "1"
                }
            }
        ],
        "AutoVerifiedAttributes": [
            "email"
        ],
        "UsernameAttributes": [
            "email"
        ],
        "VerificationMessageTemplate": {
            "DefaultEmailOption": "CONFIRM_WITH_CODE"
        },
        "UserAttributeUpdateSettings": {
            "AttributesRequireVerificationBeforeUpdate": []
        },
        "MfaConfiguration": "OPTIONAL",
        "DeviceConfiguration": {
            "ChallengeRequiredOnNewDevice": true,
            "DeviceOnlyRememberedOnUserPrompt": true
        },
        "EstimatedNumberOfUsers": 577,
        "EmailConfiguration": {
            "SourceArn": "arn:aws:ses:us-east-2:123456789098:identity/[email protected]",
            "EmailSendingAccount": "COGNITO_DEFAULT"
        },
        "SmsConfiguration": {
            "SnsCallerArn": "arn:aws:iam::123456789098:role/service-role/stagingmobileappusers-SMS-Role",
            "ExternalId": "3f0cc307-d5dd-44be-96ff-************",
            "SnsRegion": "us-east-1"
        },
        "UserPoolTags": {},
        "Domain": "devint-appusers",
        "AdminCreateUserConfig": {
            "AllowAdminCreateUserOnly": false,
            "UnusedAccountValidityDays": 7
        },
        "UsernameConfiguration": {
            "CaseSensitive": false
        },
        "Arn": "arn:aws:cognito-idp:us-east-2:123456789098:userpool/us-east-2_********",
        "AccountRecoverySetting": {
            "RecoveryMechanisms": [
                {
                    "Priority": 1,
                    "Name": "verified_email"
                }
            ]
        }
    }
}

The following is the sample code for my MFA with SMS setup:

import Amplify, { Auth } from 'aws-amplify';

Amplify.configure({
  Auth: {
      region: 'us-east-2', 
      userPoolId: 'us-east-2_FSabCdeff', 
      userPoolWebClientId: '2lehdjcn73nnfmmjfnvgg53'
  }
});

var globalUser = null

async function signIn(event) {
  try {
    event.preventDefault();
    console.log('event::',event)
    const username = event.currentTarget.elements.usernameInput.value;
    const password = event.currentTarget.elements.passwordInput.value
      const user = await Auth.signIn(username, password);
      globalUser = user
      console.log('user: ', user);

  } catch (error) {
      console.log('error signing in', error);
  }
}

async function verify2FA(event) {
  try {
    event.preventDefault();
    const otpCode = event.currentTarget.elements.otpField.value;
    const loggedUser = await Auth.confirmSignIn( globalUser, otpCode, 'SMS_MFA' );
      console.log('user: ', loggedUser);
      const result = await Auth.rememberDevice();
      console.log('Remember:',result);
  } catch (error) {
      console.log('error verifying otp', error);
  }
}

function App() {
  return (
    <div className="App">
    ______________________________________________
    <h2>Sign in</h2>
    <form onSubmit={signIn}>
      <div>
        <label htmlFor="usernameInput">Username:</label>
        <input id="usernameInput" type="text" />
      </div>
      <div>
        <label htmlFor="passwordInput">Password:</label>
        <input id="passwordInput" type="text" />
      </div>
      <button type="submit">Submit</button>
    </form>
    ______________________________________________

    ______________________________________________
    <h2>MFA - SMS</h2>
    <form onSubmit={verify2FA}>
      <div>
        <label htmlFor="otpField">OTP:</label>
        <input id="otpField" type="text" />
      </div>
      <button type="submit">Submit</button>
    </form>
    ______________________________________________
    
    </div>
  );
}

export default App;

Remember device and suppress MFA for subsequent logins are working fine for dev-mobileapp-users user pool. But for the other user-pool, it is always prompting for MFA. When I compare the configurations, everything looks the same. I am not getting why this issue is happening. Is this some problem with Cognito or any configuration mismatch from my end. I don’t know.

But one point I have noticed is that, for dev-mobileapp-users in the Device tracking log section, I can see the device I used to login as Remembered = YES with a full Name of the device.

At the same time for the other user-pool, the Device tracking log section is showing my device as Remembered = YES, but Name is showing as empty (-).

I am wondering why the same code is behaving differently on 2 user-pools though the configurations are the same.

Any thoughts on this problem?

What is the best approach to deal with floating point issues when limiting the user input to 2 decimal places?

I am currently creating an application that allows users to input a weight and select their preferred unit, between kg and lbs. As of now, the database is written in Django and stores each user weight entry for a particular date as a string with 2 decimal points precision, such as,

weight_kg = models.DecimalField(max_digits=5, decimal_places=2, validators=[MinValueValidator(1)])

The problem I am facing is loss of data when changing between units. For example if a user chooses 165 with lbs as the unit, I will store this in my database as 74.84. When closing and reopening the page, it will fetch the data and attempt to restore it. Doing it, it will change 74.84kg to 164.99lbs. A loss of data, as we have no idea if the user chose 164.99lbs or it was a rounding error.

I was starting to think that I made a mistake choosing to store the weight as strings, however, the same problem will occur when using numbers. Such as,

let kg_to_lbs = 2.20462;
let lbs_to_kg = 0.453592;
((165 * lbs_to_kg) * kg_to_lbs) // 164.99....

Is their any best practices to prevent such issues?

Replicating CPU-Intensive Animation with HTML/CSS/JS

I’m attempting to replicate an animation similar to this one: https://imgur.com/8rAXdYL. However, I’m facing significant CPU performance issues, causing the browser to become unresponsive.

Here’s what I’ve tried so far:

Initially, I attempted to recreate the animation using HTML, CSS, and JavaScript, with a canvas element for the main animation. However, this approach proved to be too heavy on the CPU, resulting in poor performance.
I then experimented with duplicating the canvas to simulate a “tracking” motion, but this only exacerbated the performance issues.
Additionally, I’ve optimized my code by reducing unnecessary calculations and minimizing DOM manipulations, but the performance problems persist.
I’m seeking guidance on how to achieve a smoother animation experience without overburdening the CPU. Are there alternative approaches or techniques I could use to create this animation more efficiently? Could someone provide insights or suggestions on how to optimize the animation code for better performance?

Any help or advice would be greatly appreciated.

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <title>Animated Dots Inside Circle</title>


    <style>
        body {
            margin: 0;
            overflow: hidden;
        }

        canvas {
            position: absolute;
            border-radius: 50%;
        }
    </style>
</head>

<body>
    <!-- First Canvas container -->
    <canvas id="canvas"></canvas>
    <script>
        const canvas = document.getElementById('canvas');
        const ctx = canvas.getContext('2d');
        let width, height, radius;
        let particles = [];
        const numParticles = 600; // Increased number of particles for higher density
        const particleRadius = 1; // Particle radius
        const fadeOutThreshold = 20; // Threshold distance from edge for particles to start fading out

        // Function to center the canvas and update its size
        function centerCanvas() {
            width = window.innerWidth * 0.25; // Increased canvas width
            height = window.innerHeight * 0.5; // Increased canvas height
            radius = Math.min(width, height) / 2; // Circular boundary radius
            canvas.width = width;
            canvas.height = height;
            canvas.style.left = (window.innerWidth / 2 - width / 2) + 'px';
            canvas.style.top = (window.innerHeight / 2 - height / 2) + 'px';
        }

        // Call the centerCanvas function initially and on window resize
        centerCanvas();
        window.addEventListener('resize', centerCanvas);

        class Particle {
            constructor(x, y, color) {
                this.x = x;
                this.y = y;
                this.velocity = {
                    x: (Math.random() - 0.5) * 2,
                    y: (Math.random() - 0.5) * 2
                };
                this.color = color;
                this.opacity = 1; // Initial opacity
            }

            draw(context) {
                context.globalAlpha = this.opacity;
                context.beginPath();
                context.arc(this.x, this.y, particleRadius, 0, Math.PI * 2);
                context.fillStyle = this.color;
                context.fill();
                context.globalAlpha = 1;
            }

            update() {
                this.draw(ctx);

                this.x += this.velocity.x;
                this.y += this.velocity.y;

                // Keep particles within the canvas boundaries
                if (this.x < 0 || this.x > width || this.y < 0 || this.y > height) {
                    const distanceFromEdge = Math.min(this.x, width - this.x, this.y, height - this.y);
                    if (distanceFromEdge < fadeOutThreshold) {
                        this.opacity -= 0.01; // Reduce opacity when particles are close to the edge
                    }
                }

                if (this.opacity < 0) {
                    this.opacity = 0; // Ensure opacity doesn't go below 0
                }
            }
        }

        // Initialize particles with higher density
        function initializeParticles() {
            particles = [];
            const desiredNumParticles = 300; // Desired number of particles
            const particleGap = Math.sqrt((width * height) / desiredNumParticles); // Adjust particle gap based on desired number
            for (let x = 0; x < width; x += particleGap) {
                for (let y = 0; y < height; y += particleGap) {
                    const color = '#6A73AE';
                    particles.push(new Particle(x, y, color));
                }
            }
        }
        initializeParticles();

        // Function to continuously spawn new particles and remove faded-out particles
        function updateParticles() {
            particles.forEach((particle, index) => {
                if (particle.opacity <= 0) {
                    particles.splice(index, 1); // Remove faded-out particles
                }
            });

            while (particles.length < numParticles) {
                const x = Math.random() * (width - particleRadius * 2) + particleRadius;
                const y = Math.random() * (height - particleRadius * 2) + particleRadius;
                const color = '#6A73AE';
                particles.push(new Particle(x, y, color)); // Add new particles
            }
        }

        function animate() {
            requestAnimationFrame(animate);
            ctx.clearRect(0, 0, width, height);
            particles.forEach(particle => {
                particle.update();
            });
            updateParticles(); // Update particles array
        }

        animate();

        // Function to create a new canvas following the mouse, fade it out, and remove it
        function createFollowingCanvas(event) {
            const newCanvas = document.createElement('canvas');
            const newCtx = newCanvas.getContext('2d');
            const newCanvasSize = Math.min(width, height); // Size of the new canvas
            const fadeOutTime = 500; // Duration before fade-out
            const fadeOutInterval = 20; // Interval for opacity reduction, increased for smoother animation
            const mouseX = event.clientX;
            const mouseY = event.clientY;

            newCanvas.width = newCanvasSize;
            newCanvas.height = newCanvasSize;
            newCanvas.style.position = 'absolute';
            newCanvas.style.left = (mouseX - newCanvasSize / 2) + 'px';
            newCanvas.style.top = (mouseY - newCanvasSize / 2) + 'px';

            document.body.appendChild(newCanvas);

            return new Promise((resolve, reject) => {
                let opacity = 1;
                const fadeOutIntervalId = setInterval(() => {
                    newCtx.clearRect(0, 0, newCanvasSize, newCanvasSize);
                    particles.forEach(particle => {
                        particle.draw(newCtx); // Draw particles on the new canvas
                    });
                    opacity -= 1 / (fadeOutTime / fadeOutInterval);
                    // console.log('Opacity:', opacity); // Debug output
                    newCanvas.style.opacity = opacity; // Set opacity on the canvas element
                    if (opacity <= 0) {
                        clearInterval(fadeOutIntervalId);
                        document.body.removeChild(newCanvas); // Remove the canvas once faded out
                        console.log('Canvas removed');
                        resolve(); // Resolve the promise when fade-out is complete
                    }
                }, fadeOutInterval);
            });
        }

        // Event listener to create a new canvas following the mouse on mousemove
        const throttleDelay = 100; // Throttle delay in milliseconds
        let lastMouseMove = 0; // Variable to track the time of the last mousemove event

        // Throttle mousemove event to reduce the number of animation triggers
        $(window).on('mousemove', function (e) {
            const now = Date.now();
            if (now - lastMouseMove >= throttleDelay) {
                lastMouseMove = now;

                const mouseX = e.clientX - width / 2;
                const mouseY = e.clientY - height / 2;
                $('#canvas').css({ 'left': mouseX, 'top': mouseY });

                // Create a new canvas following the mouse with fade-out effect
                createFollowingCanvas(e)
                    .then(() => {
                        console.log('Fade-out complete');
                    })
                    .catch((error) => {
                        console.error('Error:', error);
                    });
            }
        });

    </script>
</body>

</html>```

js how to prevent hiding / catching errors

The problem is that some errors and warnings are not displayed in the console at all. Even banal syntax errors when you call a function on a non-existent variable. I have a suspicion that it is one of the included libs that affects the error output.
Fortunately, while I was writing this question I found a solution, but since there are no answers to this question at all:

  • perhaps there is a standard / an universal solution
  • for someone it will be useful what I found

Different return type based on parameter type?

I want to have an interface where I know the parameter is going to be 1 of a few different types (coming from a 3rd party library) and based on what type it is, the return type will change, with some types also being from a 3rd party library, or being a basic type like void or null.

Here is the simplest code to replicate my issue

type foo = {
  statusCode: number;
  body: string;
}
type fooReturn = string; // in reality, this could be a complex type

type bar = {
  results: [];
}
type barReturn = number; // in reality, this could be a complex type

interface foobar {
  myFunc<T extends (foo | bar)>(event: T): T extends foo ? fooReturn : barReturn;
}

class myClass implements foobar {
  // the below code errors
  myFunc(event: foo) { // we tell TS that the param is of type foo
    return 'hello' // so the return must be a string
  }
}

The error is

Property 'myFunc' in type 'myClass' is not assignable to the same property in base type 'foobar'.
  Type '(event: foo) => string' is not assignable to type '(event: T) => T extends foo ? string : number'.
    Types of parameters 'event' and 'event' are incompatible.
      Type 'T' is not assignable to type 'foo'.
        Type 'foo | bar' is not assignable to type 'foo'.
          Type 'bar' is missing the following properties from type 'foo': statusCode, body

How to set up Google Chrome Extension Native Messaging and sending parameters to native host properly?

I am developing a chrome extension and I need to implement a feature that allows to launch an .exe on button click AND pass user entered parameters to that .exe.

Feature details:
User selects file and clicks on a button -> button triggers prompt menu, getting input from user -> if user provides input extension launches .exe file, passing user entered input to .exe’s stdio stream -> .exe reads stdin and saves user entered input to txt file -> (optional) .exe sends success message to extension.

The problem is it does not work as expected and i have no idea what did i do wrong 🙁

Here is what i did and my results:

Button onClick logic:

content.js

    button.addEventListener('click', function() {
        allSelected = document.querySelectorAll('[aria-selected="true"]')
        console.log(allSelected.length)
        let allFIles = []
        allSelected.forEach(element => {
            // Get the parent element
            const parentElement = element.parentNode;
            
            // Check if the parent element has the data-id attribute
            if (parentElement && parentElement.hasAttribute('data-id')) {
                // Retrieve the value of the data-id attribute
                const dataIdValue = parentElement.getAttribute('data-id');
                console.log('Data ID value:', dataIdValue);
                allFIles.push(dataIdValue)
            } else {
                console.log('Parent element does not have a data-id attribute');
            }
        });
        const userInput = window.prompt(`You selected ${allFIles.length} files. Please, provide info on these files below.`, '');

        // Check if the user entered something
        if (userInput !== null) {
            // User clicked OK and entered some text
            console.log('User input:', userInput);
            allInfo = {"fileIds": allFIles, "newValues": userInput}
            chrome.runtime.sendMessage({ action: 'connectNative', data: allInfo});
        } else {
            // User clicked Cancel or closed the prompt dialog
            console.log('User canceled input.');
        }
    });

In my background.js file I tried using both chrome.runtime.connectNative+port.postMessage or chrome.runtime.sendNativeMessage. Trough a lot of trial and error I came up with this block of code that seems to work (to some extent):

background.js

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
  console.log('Message received:', request);

  if (request.action === 'connectNative') {

    console.log("try");
    let port = chrome.runtime.connectNative('com.google_drive.edit_description'); 

    port.postMessage({filesToEdit: request["data"]})
    port.onMessage.addListener(function(message) {
      console.log("Message from native messaging host:", message);

    });
  }
});

I created com.my_extension.new_feature folder in NativeMessagingHost and provided full path to native-apps/editInfo.json

editInfo.json

{
    "name": "com.my_extension.new_feature",
    "description": "My Application",
    "path": "new_feature.exe",
    "type": "stdio",
    "allowed_origins": ["chrome-extension://<passed my_extension's id>/"]
  }

I added nativeMessaging permissions to manifest.json. So far so good.
Then i created my .exe file from Python script (this is my primary programming language)

new_feature.py

import sys
import json
import logging

logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    datefmt='%d-%b-%y %H:%M:%S',
                    filename='new_feature.log',
                    filemode='a')


def main():
    logging.info("Started")

    input_data = sys.stdin.read()

    logging.info("Read stdin")
    logging.info(f"Input data: {input_data}")

    with open('output.txt', 'w') as f:
        f.write(input_data)

    logging.info("Wrote to file")
    send_message({"message": "Success"})



if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        logging.error(e)

It looks like everything should be fine now, but this is what happens:
On button click my new_feature.exe is triggered. It writes to .log file 15-Feb-24 18:51:34 - root - INFO - Started and then it does nothing! I tried setting setTimeout before port.postMessage in background.js (just in case there are some time-related problems)- nothing changed, same results. But while experimenting I noticed that when I reload extension from in chrome://extensions/ it seems to “release” this part of code input_data = sys.stdin.read(), and successfuly runs the rest of the code, writing to .log

15-Feb-24 18:58:10 - root - INFO - Read stdin
15-Feb-24 18:58:10 - root - INFO - Input data: 6  {"filesToEdit":{"fileIds":[<fileIds>],"newValues":"<newValues>"}}
15-Feb-24 18:58:10 - root - INFO - Wrote to file

I don`t understand why this is happening and this does not solve my problem – I am not going to reload extension every time I want to use this feature. I read a lot of different answers here as well as everywhere else, including asking chatGPT. Nothing seemed to work.

Then I accidentally didn’t comment the rest of the code when trying to send message from .exe to extension (why not…) AND IT WORKED. I have no idea why, here is the full code that reads stdin and writes to .log file with no problems:

new_feature.py

import sys
import json
import logging

logging.basicConfig(level=logging.INFO,
                    format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
                    datefmt='%d-%b-%y %H:%M:%S',
                    filename='edit_gd_description.log',
                    filemode='a')

def send_message(message):
    sys.stdout.write(json.dumps(message))
    sys.stdout.flush()


def main():
    logging.info("Started")

    send_message({"message": "Waiting for input"})

    input_data = sys.stdin.read()

    logging.info("Read stdin")
    logging.info(f"Input data: {input_data}")

    with open('output.txt', 'w') as f:
        f.write(input_data)

    logging.info("Wrote to file")
    send_message({"message": "Success"})



if __name__ == "__main__":
    try:
        main()
    except Exception as e:
        logging.error(e)

This logs Unchecked runtime.lastError: Error when communicating with the native messaging host. to background.js console, but the .exe works well, getting right input from stdin that extesion sends, and writing this input to .log and .txt.

I would like to know why is that happening, what did I do wrong? How can i make .exe send messages to extension?

Thank you for any help or ideas!

Failed to build wavemaker app using angular ui mode

I’m using Wavemaker to develop an app. For deployment, we use docker image, so I need to build the app using docker and then push the image. It works fine when I build the app using wm UI mode. But my build failed when I switched UI mode to angular.

I’m using Wavemaker 11.5.3. I use dockerfile from Wavemaker docs directly. This is the failed log
failed log

Also this is the dockerfile content

FROM maven:3.9.5-eclipse-temurin-11 as maven-java-node
ENV MAVEN_CONFIG=~/.m2
RUN mkdir -p /usr/local/content/node
WORKDIR /usr/local/content/node
ADD https://nodejs.org/dist/v18.16.1/node-v18.16.1-linux-x64.tar.gz .
RUN tar -xzf node-v18.16.1-linux-x64.tar.gz 
    && ln -s /usr/local/content/node/node-v18.16.1-linux-x64/bin/node /usr/local/bin/node 
    && ln -s /usr/local/content/node/node-v18.16.1-linux-x64/bin/npm /usr/local/bin/npm 
    && chown -R root:root /usr/local/content/node 
    && rm -fR node-v18.16.1-linux-x64.tar.gz

FROM maven-java-node as webapp-artifact
RUN mkdir -p /usr/local/content/app
ADD ./ /usr/local/content/app
WORKDIR /usr/local/content/app
ARG build_profile_name
ENV profile=${build_profile_name}
RUN  mvn clean install -P${profile}

FROM tomcat:9.0.83-jdk11-temurin
COPY --from=webapp-artifact /usr/local/content/app/target/*.war /usr/local/tomcat/webapps/

I have been searched all over the internet, but no luck

Thunderbird: messenger.messages.listAttachments returns empty array when using pgp

I am trying to use the paperless addon for thunderbird: https://github.com/Niach/paperless-thunderbird-extension

My mail account has a PGP key linked to it. When I click on an email, I can view the attachments without problems and they are listed correctly.

However, when the addon calls

let message = await messenger.messageDisplay.getDisplayedMessage(tabs[0].id);
const attachments = await messenger.messages.listAttachments(message.id);

an empty array is returned.

When using another account that is not using pgp, the attachments are returned as expected.

Does anyone have any experience with this issue? The only other answer I found is

https://stackoverflow.com/a/77610640/10843051, which does not answer the question why it does not work.

I am trying to display surcharge amount on Adyen payment screen

https://docs.adyen.com/online-payments/build-your-integration/?platform=Web&integration=Drop-in&version=5.55.1

I am using this javascript drop in component and I am trying to display additional surcharge amount on top of the transaction cost depending on which network the card uses (e.g 3% for Amex vs 1.5% for Mastercard) but I can’t seem to find a field on the drop in component that allows for this.

The closest I can find is:
‘secondaryAmount’ – Shows the payment amount in an additional currency on the Pay button. You must do the currency conversion and set the amount.
This object has:

  • currency: The three-character ISO currency code.
  • value: The amount of the transaction, in minor units.
  • currencyDisplay: Sets the currency formatting. Default: symbol.

Make an element ignore event listeners

Is there a way I can make an element, or group of elements, ignore event listeners without changing the event listener code? The event listener is in a library and I don’t want to muck around with the library code. I want to just put something in my own code that will stop the event listener firing when these particular elements are clicked.

What I am actually trying to do, is stop popups from disappearing when their relative markers are clicked on in a Leaflet map. I have autoClose and closeOnClick both set to false in the popups. I have a class for the markers and popups that I can use to access them.

How to improve my First Contentful Paint (FCP) and Largest Contentful Paint (LCP)

I’m struggling with my first WordPress website I bought over via Flippa.

The website used to generate thousands of visits. Since I took over, the performance has decreased and the Google Ranks went from 1 to 10+…

The main issue so far that I can see is the page speed performance

enter image description here

It takes 5.1s to load on mobile – which is a no-go for Google.
Here’s the page for example:
https://citydogslife.com/best-medium-sized-dog-breeds-for-apartment-living/

The main issues are the FCP & LCP:

enter image description here

However, I have no clue on how to fix those.
Clearly didn’t change anything on the files but PageSpeed recommends all these without concrete actions.

Is there anyone who has experience on how to fix the LCP and some of these other points?

Thanks!

Appreciate anyone’s help.

  1. I tried to remove Ezoic – the page speed increased slightly but not so much.

  2. I tried to re-upload the same website transfer files given by the seller twice but the speed still does not improve.

  3. I optimized all images on the website 3 times with different providers to ensure their sizes were not huge

Unable to add/display button

start button and stop button have similar properties which i have given to restart button.

I am new to JavaScript so kindly give me a detailed explanation.

      <button id="start-test" onclick="startTest()">Start Test</button>
      <button id="stop-test" onclick="displayResult()">Stop Test</button>
      <button id="restart-test" onclick="restartTest()">Restart Test</button>
//Restart Test
const restartTest = () => {
  // Reset variables
  mistakes = 0;
  timer = "";
  time = 60;
  
  // Reset UI
  userInput.disabled = false;
  userInput.value = "";
  document.getElementById("start-test").style.display = "block";
  document.getElementById("stop-test").style.display = "none";
  document.querySelector(".result").style.display = "none";
  document.getElementById("mistakes").innerText = "0";
  document.getElementById("timer").innerText = "60s";
  document.getElementById("wpm").innerText = "0 wpm";
  document.getElementById("accuracy").innerText = "0 %";

  
  renderNewQuote();
};

window.onload = () => {
  userInput.value = "";
  document.getElementById("start-test").style.display = "block";
  document.getElementById("stop-test").style.display = "none";
  document.getElementById("restart-test").style.display = "none"; // Hide restart button initially
  userInput.disabled = true;
  renderNewQuote();

  
  document.getElementById("restart-test").addEventListener("click", restartTest);
};

In the restart test section i am repeatedly facing same issue of not getting the Restart Button displayed.