OSM Buildings viewer.remove() and viewer.destroy() not working propperly

Kinda newbie at programming so please bear withe me…

So I am trying to dynamically add and remove objects from the OSMBuildings 3dviewer using Java Script.

Short explaination:
I tried using the .remove() method to no avail… then found the .destroy() method but it also didnt work (In almost all scenarios that i tested i get 0 errors/a completely silent fail and everything just continues without removing the object)

Then after that tried to use the .destroy method + clearing the html div to clear the whole map and just reload all objects except the one that i want to remove but the map starts flashing red when i create a new one (probably because the old one is not cleared completely).

Detailed explaination/rant:
The “documentation” (https://osmbuildings.org/documentation/viewer/api) mentions the .remove() method which doesnt seem to be working no matter what i try (i tried viewer.remove(object itself), i tried using viewer.remove(‘id’ of object), i tried object.remove() etc etc). I even went through the source code just to find:

remove(object) {
   if (object.destroy) {
       object.destroy()
   }
}

i then tried the object.destroy method which also did NOTHING… I didnt even get any error message in any of these tests except for object.remove().

after that i tried to use a rather unsatisfying workaround (as described in the seconnd half of my short explaination) by clearing the div and destroying the map and creating a new one without the object that i want to remove. But that just makes the new map flash red and glitch… I then tried to just delete the div and create a new div with the same name but then OSMBuildings does not seem to find the div at all (my guess since the error message is not really helpful) despite the div definitely existing….

Any advice is highly appreciated.

I am working with Html, JS, and CSS on windows 11 pro using Chrome and Opera to test my page.

i tried too many things to go into detail on all of them but ill attach my current attempt at removing an object.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>3D Map with OSM Buildings</title>
  
  <link href="https://cdn.osmbuildings.org/4.1.1/OSMBuildings.css" rel="stylesheet">
  <script src="https://cdn.osmbuildings.org/4.1.1/OSMBuildings.js"></script>

  <style>
    body {
      margin: 0;
      padding: 0;
    }
  </style>
</head>
<body>

  <div id="map3D" style="width: 950px; height: 450px;"></div>

  <script>
    var map = new OSMBuildings({
      container: 'map3D',
      position: { latitude: 53.111212, longitude: 8.857276 }, 
      zoom: 16,
      minZoom: 13,
      maxZoom: 19,
      attribution: '© Data <a href="https://openstreetmap.org/copyright/">OpenStreetMap</a> © Map <a href="https://osmbuildings.org/copyright/">OSM Buildings</a>'
    });

    map.addMapTiles('https://tile-a.openstreetmap.fr/hot/{z}/{x}/{y}.png');
    map.addGeoJSONTiles('https://{s}.data.osmbuildings.org/0.2/59fcc2e8/tile/{z}/{x}/{y}.json');

  </script>
  <script>

    //var for custom building
    var buildings = [];
    let lon = 53.111;
    let lat = 8.857;
    droneSize = 2;
    let lat1 = lat + 0.00005;
    let lon1 = lon + 0.00005;
    let lat2 = lat + 0.00005;
    let lon2 = lon - 0.00005;
    let lat3 = lat - 0.00005;
    let lon3 = lon - 0.00005;
    let lat4 = lat - 0.00005;
    let lon4 = lon + 0.00005;

    let customBuilding = {
      "type": "FeatureCollection",
      "features": [
        {
          "type": "Feature",
          "properties": {
            "height": 15,
            "minHeight": 11,
            "color": "#cc0000"
          },
          "geometry": {
            "type": "Polygon",
            "coordinates": [[
              [lat1, lon1],
              [lat2, lon2],
              [lat3, lon3],
              [lat4, lon4],
              [lat1, lon1]
            ]]
          }
        }
      ]
    };

    //add custom building and store object in buildings array
    buildings.push(map.addGeoJSON(customBuilding, { id: '1' }));
    //remove custom buildings that are in array from map
    for(const building of buildings) {
      console.log(building);
      //different tries to remove building from map
      map.remove(building);
      map.remove({id: '1'});
      map.remove('1');
      map.remove(1);
      building.destroy();
    }
  </script>

</body>
</html>

I have written the jsp,js and servlet for my program but the data is not passed from js to servlet. Below are the code snippet

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>New User Sign Up</title>
    <!-- Bootstrap CSS CDN -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" />
    <link rel="stylesheet" href="loginNewUserSignUp.css" />
</head>
<body>
    <div class="signup-container">
        <div class="signup-header">NEW USER SIGN UP DETAILS</div>
        <form id="signupForm" novalidate>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="userName" class="label-field col-4">Enter User Name</label>
                <input type="text" id="userName" name="userName" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="userId" class="label-field col-4">Enter User ID</label>
                <input type="text" id="userId" name="userId" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="password" class="label-field col-4">Enter User Password</label>
                <input type="password" id="password" name="password" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span><br>
                
            </div>
            <span class="password-msg">(Atleast one Capital Letter, One Number and One Special Character should be in Password)</span>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="confirmPassword" class="label-field col-4">Confirm User Password</label>
                <input type="password" id="confirmPassword" name="confirmPassword" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="email" class="label-field col-4">Enter User Email ID</label>
                <input type="email" id="email" name="email" autocomplete="off" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="mobile" class="label-field col-4">Enter User Mobile No.</label>
                <input type="text" id="mobile" name="mobile" autocomplete="off" maxlength="10" class="input-field col-7" />
                <span class="asterisk">*</span>
            </div>
            <div class="form-row d-flex align-items-center mb-2">
                <label for="address" class="label-field col-4">Enter User Address</label>
                <textarea id="address" name="address" class="input-field col-7" rows="4" wrap="soft"></textarea>
                <span class="asterisk">*</span>
            </div>
            <div class="button-row d-flex justify-content-center mt-3">
                <button type="submit" class="submit-btn">SUBMIT</button>
                <button type="reset" id="resetBtn" class="reset-btn">RESET</button>
                <button type="button" id="closeBtn" class="close-btn">CLOSE</button>
            </div>
        </form>
    </div>

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

My js file code is —

// 
// Disable right-click on the page
document.addEventListener('contextmenu', event => event.preventDefault());

// Disable tab key and enable enter key to move focus
document.addEventListener('keydown', function(event) {
    if (event.key === 'Tab') {
        event.preventDefault();
    }
    if (event.key === 'Enter') {
        const formElements = Array.from(document.querySelectorAll('#signupForm input, #signupForm textarea'));
        const index = formElements.indexOf(document.activeElement);
        if (index > -1 && index < formElements.length - 1) {
            formElements[index + 1].focus();
            event.preventDefault();
        }
    }
});

const form = document.getElementById('signupForm');

function showError(input, message) {
    alert(message);
    input.focus();
}

function validateNotBlank(input, fieldName) {
    if (!input.value.trim()) {
        showError(input, `The field cannot be Blank: ${fieldName}`);
        return false;
    }
    return true;
}

function validatePassword(input) {
    const value = input.value;
    const hasCapital = /[A-Z]/.test(value);
    const hasNumber = /[0-9]/.test(value);
    const hasSpecial = /[!@#$%^&*(),.?":{}|<>]/.test(value);
    if (!hasCapital || !hasNumber || !hasSpecial) {
        showError(input, "Password must contain at least one Capital Letter, One Number and One Special Character.");
        return false;
    }
    return true;
}

function validateConfirmPassword(passwordInput, confirmInput) {
    if (passwordInput.value !== confirmInput.value) {
        alert("The Password and Confirm Password are not same.");
        confirmInput.focus();
        return false;
    }
    return true;
}

function validateEmail(input) {
    const emailRegex = /^[^s@]+@[^s@]+.[^s@]+$/;
    if (!emailRegex.test(input.value.trim())) {
        showError(input, "Enter valid Email ID");
        return false;
    }
    return true;
}

function validateMobile(input) {
    const mobileRegex = /^[0-9]{10}$/;
    if (!mobileRegex.test(input.value.trim())) {
        showError(input, "Enter a valid Mobile Number");
        return false;
    }
    return true;
}

function validateAddress(input) {
    const words = input.value.trim().split(/s+/).filter(word => word.length > 0);
    if (words.length === 0 || words.length > 4500) {
        showError(input, "Please enter proper Address not more than 4500 words.");
        return false;
    }
    return true;
}

form.addEventListener('submit', function(event) {
    event.preventDefault();
alert("Entering Data");
    const userName = document.getElementById('userName');
    const userId = document.getElementById('userId');
    const password = document.getElementById('password');
    const confirmPassword = document.getElementById('confirmPassword');
    const email = document.getElementById('email');
    const mobile = document.getElementById('mobile');
    const address = document.getElementById('address');

    if (!validateNotBlank(userName, 'User Name')) return;
        if (!validateNotBlank(userId, 'User ID')) return;
        if (!validateNotBlank(password, 'Password')) return;
        if (!validatePassword(password)) return;
        if (!validateNotBlank(confirmPassword, 'Confirm Password')) return;
        if (!validateConfirmPassword(password, confirmPassword)) return;
        if (!validateNotBlank(email, 'Email')) return;
        if (!validateEmail(email)) return;
        if (!validateNotBlank(mobile, 'Mobile')) return;
        if (!validateMobile(mobile)) return;
        if (!validateNotBlank(address, 'Address')) return;
        if (!validateAddress(address)) return;
        alert("Entering Transfer");
        const servletUrl = 'http://localhost:8081/MyTransactionDetails/Servlets/loginNewUserData';
    // Send data to servlet
    fetch(servletUrl, {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            userName: userName.value,
            userId: userId.value,
            password: password.value,
            confirmPassword:confirmPassword.value,
            email: email.value,
            mobile: mobile.value,
            address: address.value
        })
        
    })
    
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            alert('Data entered successfully');
            // Clear form
            form.reset();
            // Focus on userName
            userName.focus();
        } else {
            alert('Error: ' + data.message);
        }
    })
    .catch(error => {
        console.error('Error:', error);
        alert('An error occurred during sign up.');
    });
});

My servlet code is as shown below

package Servlets;

import java.io.IOException;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONObject;



import java.sql.ResultSet;
import java.sql.SQLException;
import jakarta.servlet.*;


@WebServlet("/loginNewUserData")
public class loginNewUserData extends HttpServlet {
    private static final long serialVersionUID = 1L;

    // Database connection details
    private static final String DB_URL = "jdbc:mysql://localhost:3306/mytransactiondetails";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "Devi@27032009";

    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // CORS headers
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        
        response.setContentType("application/json");
        PrintWriter out = response.getWriter();

        StringBuilder sb = new StringBuilder();
        String line;
        try (BufferedReader reader = request.getReader()) {
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
        }
        String requestBody = sb.toString();

        JSONObject jsonRequest = new JSONObject(requestBody);
        String userName = jsonRequest.getString("userName");
        String userId = jsonRequest.getString("userId");
        String password = jsonRequest.getString("password");
        String confirmpwd=jsonRequest.getString("confirmPassword");
        String email = jsonRequest.getString("email");
        String mobile = jsonRequest.getString("mobile");
        String address = jsonRequest.getString("address");

        JSONObject jsonResponse = new JSONObject();

        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection conn =null;
            conn=DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
            
            String newUserIDNo = null,sqlSearchID;
            sqlSearchID="select count(qr_New_User_ID) as totalID from qr_new_user_details";
            PreparedStatement pstmt= conn.prepareStatement(sqlSearchID);
            ResultSet rs=pstmt.executeQuery();
            while (rs.next())
            {
                newUserIDNo=rs.getString("totalID");
                newUserIDNo=newUserIDNo+1;
            }
            
            Date CurDate=new Date();
            SimpleDateFormat sdf=new SimpleDateFormat("dd/mm/yyyy");
            String getCurDate=sdf.format(CurDate);

            String sql = "INSERT INTO qr_new_user_details (qr_New_User_ID, qr_New_User_Name, qr_New_UID, qr_New_UPWD, qr_New_UCPWD, qr_New_User_Email,qr_New_User_Mobile,"
                    + "qr_New_User_Address,qr_New_User_Status,qr_New_User_Create_Date) VALUES (?, ?, ?, ?, ?, ?,?,?,?,?)";
            java.sql.PreparedStatement stmt = conn.prepareStatement(sql);
            stmt.setString(1, newUserIDNo);
            stmt.setString(2, userName);
            stmt.setString(3, userId);
            stmt.setString(4, password);
            stmt.setString(5, confirmpwd);
            stmt.setString(6, email);
            stmt.setString(7, mobile);
            stmt.setString(8, address);
            stmt.setString(9, "Active");
            stmt.setString(10, getCurDate);
            
            int rowsAffected = stmt.executeUpdate();

            if (rowsAffected > 0) {
                jsonResponse.put("success", true);
                jsonResponse.put("message", "Data entered successfully");
            } else {
                jsonResponse.put("success", false);
                jsonResponse.put("message", "Failed to insert data");
            }

            stmt.close();
            conn.close();
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
            jsonResponse.put("success", false);
            jsonResponse.put("message", "Database error: " + e.getMessage());
        }

        out.print(jsonResponse.toString());
        out.flush();
    }
    
    protected void doOptions(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // Handle CORS preflight
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type");
        response.setStatus(HttpServletResponse.SC_OK);
    }
}

<———————————————————->
The above is the code which I wrote for new user details to be entered in the jsp file and validated in js file. After validation the data should be transferred fron js file to the servlet. I am using eclipse ide for the coding. The issue is that the data is not transferred from js file to the servlet.

Google Sign In popup not showing (only showing in FireFox)

I am trying to implement Google Sign In on my page. I am following this documentation.

Here is my code:

function loginWithGoogle() {
  if (!otherUtils.notNullEmptyOrUndefined(cookieUtils.getAuthToken())) {
    google.accounts.id.initialize({
      client_id: "xxxxxx",
      callback: (response) => handleCredentialResponse(response),
      ux_mode: "popup",
    });
    google.accounts.id.prompt();
  }
}

NOTE: Don’t mind the if(...) part – the code goes through it, I checked.

And here is HTML part:

<template>
  <div class="options-container">
    <div id="google-login-button">
      <button @click="loginWithGoogle">google</button>
    </div>
  </div>
</template>

I am using Nuxt 4 btw.

I have a problem where the popup that should appear doesn’t show on Brave, Chrome and Opera. It only shows on Firefox.

enter image description here

What can be the problem?

PhpWord generates paragraph breaks in addhtml

I am using PHPWord from within PHP to generate a word docment. I do use addHtml to transform some Mysql text containing multiple lines into a Word paragraph.

My input text contains:

<pre>
Lorem ipsum dolor sit amet, 
&lt;span style="font_weight:bold"&gt;consectetur adipiscing elit.&lt;/span&gt;
Quisque pretium mi a risus interdum, eu mollis nulla viverra. 
</pre>

Each line is separated with a carriage return (n). I tried to process the lines one by one (adding a n for each line, or use the complete text, result is the same.
Whatever I use (nl2br or str_replace) to transform the n into &lt;br /&gt; before handling addHtml generates:

Meaning a double paragraph separator instead of a single line separator.

How can this be solved? Or is this a known issue?

Best way to implement User Progress and Tracking their Progress? [closed]

I have a website where there are many users. There are some training involved. When users first start using the website (newbies).

I would like to lock or hide certain parts of the website or simply grey out the buttons UNTIL user has done the training module for that section before using that feature.

What is the best way to implment this type of structure?

There is not just a few sections. Also users may skip a module and do a different learning module first and do it in different order. So there is not ordered level number.

E.g. User might do learning Module A, B, C, E and F, M and O

So I would like to unlock / unhide features A B C, E and F. M and O feature. But for example Feature D would be greyed out or not available to them.

Also would it affect page load speed if I am checking all the time making a call to the database if they user has done the module or not? Would I user another field to store a true or false boolean?

I don’t wanna have a large table with heaps and heaps of fields just to store true or false 🙁 or this is industty standard?

Summary of Challenges:
There could be a large number of learning modules.
I wanna only unlock that part of the website after they have done the module.
By the end majority of all users would have done all the learning modules in the end.
I don’t want the website to be very slow for page load speed checking this for regular users.

What’s the best way to go about it? Or should I just have a level number. Where their level is the highest module that they have completed that doesn’t skip a module. e.g. Module A, B, C, E and F, M and O So even thou they have completed higher modules their level is only level 3 since they only completed A B and C?

I haven’t tried anything. I only began thinking about this design and thinking about the problem.

I would like to get insight on how profressional programmers would tackle this problem.

What database structure would you use?

What is the correct context to consume a RabbitMQ broker within the PHP/laravel ecosystem?

Well, to give you some context. We have a system that captures telemetry data in real time. The broker we hire sends telemetry data in real time from the device they place inside our cars. This operation has been running for two years, but we’ve been trying to troubleshoot and improve it for two years.

It turns out that after fixing numerous flaws, we started comparing what leaves their broker with what arrives at our database. We noticed that some packets simply don’t arrive, either in the data lake (raw message) or in the processed database. So we added more logs and started investigating. I noticed recurring Queue Error: Broken Pipe Or Closed Connection errors. But at the same time, when we see this error and go to the database, packets still arrive, so the consumer doesn’t crash and stop acquiring packets, losing that one. We set no_ack to true because we use the consumer in the Laravel schedule, running with cron 8x daily. And setting no_ack to false would trigger a race condition for the packet that ended up giving an error.

I’d like to know what’s the best context for the consumer? Should it run in the supervisor, with auto-restart policies and running 100% in the background?

    $schedule->command('pad:cron')->weekdays()->daily();
    
            $schedule->command('x:consumir')->cron('00 04 * * *');
            $schedule->command('x:consumir')->cron('00 07 * * *');
            $schedule->command('x:consumir')->cron('00 10 * * *');
            $schedule->command('x:consumir')->cron('01 12 * * *');
            $schedule->command('x:consumir')->cron('0 15 * * *');
            $schedule->command('x:consumir')->cron('0 17 * * *');
            $schedule->command('x:consumir')->cron('00 20 * * *');
            $schedule->command('x:consumir')->cron('00 00 * * *');

if run command on server – px aux | grep “x:consumir”

1195277  0.0  0.0   7124  3200 ?        S    00:00   0:00 sh -c '/usr/bin/php' 'artisan' x:consumir > '/dev/null' 2>&1
1195278  0.5  0.4 277348 66736 ?        S    00:00   3:56 /usr/bin/php artisan x:consumir
1199299  0.0  0.0   7124  3328 ?        S    04:00   0:00 sh -c '/usr/bin/php' 'artisan' x:consumir > '/dev/null' 2>&1
1199300  0.7  0.4 277352 67100 ?        S    04:00   3:38 /usr/bin/php artisan x:consumir
1203839  0.0  0.0   7124  3328 ?        S    10:00   0:00 sh -c '/usr/bin/php' 'artisan' x:consumir > '/dev/null' 2>&1
1203840  1.2  0.4 277360 66964 ?        S    10:00   1:45 /usr/bin/php artisan x:consumir
1310719  0.0  0.0   7124  3328 ?        S    12:01   0:00 sh -c '/usr/bin/php' 'artisan' x:consumir > '/dev/null' 2>&1
1310720  0.9  0.4 277360 64436 ?        S    12:01   0:11 /usr/bin/php artisan x:consumir
1332376  0.0  0.0   6436  2432 pts/1    S+   12:21   0:00 grep --color=auto x:consumir

And this is the method to create the consumer:

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle(){
        try{
            $connection = new AMQPStreamConnection('xxx.xxx.xxx', xxxx, env('user_rabbit'), env('password_rabbit'),'/', env('parameter1_rabbit'), 'AMQPLAIN', null, 'en_US', 3.0, 30.0, null, false, 60, 0);
            $channel = $connection->channel();

            echo " [*] Waiting for messages. To exit press CTRL+Cn";

            $callback = function ($msg) {
                
                $retorno = json_decode($msg->body);
                //dd($retorno);
        
                $this->processar($retorno);
                
            };

            $channel->basic_consume(env('user_rabbit'), '', false, true, false, false, $callback);
            //consumer_tag =
            //no_local=
            //no_ack = this is true
            //exclusive =
            //nowait =

            while ($channel->is_consuming()) {
                $channel->wait();
            }

            $channel->close();
            //$connection->close();
            return true;
        }catch(Throwable $e){
            Log::debug('QUEUE ERROR: ' . $e->getMessage());
            Log::debug($e->getTrace());
            return true;
            //dd("parar2");
        }
    }

What do you say? Where else can I look? I must say the accuracy of the data is about 80%. But we need to get to at least 95%.

How can I split a full webpage screenshot into separate UI blocks (PHP library or API)? [closed]

Does anyone know tools that can take a full-page website screenshot and automatically split it into logical UI blocks (hero, header, cards, footer, etc.) and return each block as a separate image segment?

Ideally I’m looking for either:

  • a PHP library I can run on my server, or
  • an online service with an API (paid is fine)

image explanation

I did some research but, unfortunately, couldn’t find any suitable tools.

Changing Delimeter of Multiple Items Returned by a osascript/javascript File Select Dialog

I have a little zsh script I’m coding to run on MacOS. Been a bash/shell scripter for 25+ years, so it hasn’t been all bad. Part of its function is to have the user select a file (or files) from a dialog using this little bit of osascript/javascript:

IMAGES="$(osascript -l JavaScript -e 'a=Application.currentApplication();a.includeStandardAdditions=true;a.chooseFile({withPrompt:"Select Image(s)",multipleSelectionsAllowed:"true"}).toString()')"

The selected files (three in this example) get dumped into the $IMAGES variable with a comma between each of them.

/Users/anderson/Pictures/1890-1899/1898/5-3-1898 John Gansemer & Lena Gansemer (nee Koltes).jpg,/Users/anderson/Pictures/1890-1899/1898/1898 Hans, Mary Anderson Wedding Photo 600dpi.jpg,/Users/anderson/Pictures/1890-1899/1898/1898 Hans. Mary Anderson Wedding Photo.jpg

Is there a way to get the delimiter to be something else (a pipe or something similar) that is less likely to show up in file or folder names that I am grabbing?

I’ve found references across the interwebs to the following the toString with a “.join” function, but I can’t get the syntax right and/or might be barking up the wrong tree anyway.

Thanks,

Bill

Injecting invisible metadata to gmail emails fails for certain gmail account [closed]

I have a chrome extension which appends some base64 metadata to gmail emails before sending them (and keeps the base64 metadata invisible for the user).
This is done through InboxSDK, and works as a charm for every but single account.
Only the emails sent from this account, get base64 metadata stripped off.
It doesn’t appear neither when message is opened in inbox nor sent emails.

I tried following ways of injecting it:

1)
<div style='display:none!important; mso-hide:all; max-height:0; overflow:hidden; font-size:1px; line-height:1px;' class='spx-meta'>${base64Metadata}</div>

2)
<img src="https://yourdomain.com/pixel.gif?policy=${base64Metadata}" width="1" height="1" style="display:none;" alt="">

3)
<span style="color:#ffffff;font-size:1px;">${base64Metadata}</span>

Each of these work on other accounts, but this one sanitizes it for some reason and completely removes it.
Any proven way to send data in email this way?

javascript function force round up the decimal [duplicate]

I looking for java-script function that will force round up the decimal.

for example value = 12.23123 will round to 12.24 .

toFixed() not return the value I want .
I want something like math.ceil but not round up to nearest numeric but to nearest decimal

for example 5.561 , when round 2 decimal will return 5.57 not 5.56

How to preview an image before uploading it? [duplicate]

I’m trying to let users preview an image before uploading it to the server.
I have an HTML , and I want to show a small preview of the selected image right after the user selects it.

I tried using FileReader, but I’m not sure if I’m doing it correctly.
The image is not displaying, or sometimes I get an empty preview.

Here’s my code below. Can someone tell me what I’m doing wrong or how to properly preview an image before upload using JavaScript?

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Image Preview Before Upload</title>
</head>
<body>
  <h2>Upload and Preview Image</h2>
  <input type="file" id="imageInput" accept="image/*">
  <br><br>
  <img id="preview" src="" alt="Image Preview" width="200" style="display:none;">

  <script>
    const imageInput = document.getElementById('imageInput');
    const preview = document.getElementById('preview');

    imageInput.addEventListener('change', function(event) {
      const file = event.target.files[0];
      if (file) {
        const reader = new FileReader();
        reader.onload = function(e) {
          preview.src = e.target.result;
          preview.style.display = 'block';
        }
        reader.readAsDataURL(file);
      }
    });
  </script>
</body>
</html>`

Injecting invisible metadata to gmail emails fails for certain gmail account

I have a chrome extension which appends some base64 metadata to gmail emails before sending them (and keeps the base64 metadata invisible for the user).
This is done through InboxSDK, and works as a charm for every but single account.
Only the emails sent from this account, get base64 metadata stripped off.
It doesn’t appear neither when message is opened in inbox nor sent emails.

I tried following ways of injecting it:

1)
<div style='display:none!important; mso-hide:all; max-height:0; overflow:hidden; font-size:1px; line-height:1px;' class='spx-meta'>${base64Metadata}</div>

2)
<img src="https://yourdomain.com/pixel.gif?policy=${base64Metadata}" width="1" height="1" style="display:none;" alt="">

3)
<span style="color:#ffffff;font-size:1px;">${base64Metadata}</span>

Each of these work on other accounts, but this one sanitizes it for some reason and completely removes it.
Any proven way to send data in email this way?

eBay Subscribe to itemSold notification with RESTful API

I am trying to subscribe to several eBay notifications (itemSold, fixedPriceTransactionEnd, etc.). The users backend server should be informed about every sale. So far I got stuck between the two APIs and tons of documentation but have not seen any other example than MARKETPLACE_ACCOUNT_DELETION. When I call getTopics I only get this along with ESP_test_APP topic. How can I subscribe to the aforementioned topics?

There is a similar unanswered question using the old API here. I am trying to use this SDK. I think they use the ebay api definitions.