increase height of popup by keeping top static

I want to increase height of popup from bottom side only while top remain static, but whenever I change from element then it increases height from both side.
Please any suggestion?
I want to change the popup’s height only from the bottom side keeping top side of popup constant while changing the from the element

HTML code

<div class='container__main'>
   <div class='popup__overlay'>
      <div>
        contents here...
    </div>

   </div>
</div

CSS

.container__main .popup__overlay {
    width: 1100px;
    min-height: 50%;
    max-width: 95%;
    background: rgb(190, 186, 186);
    position: absolute;
    top: 32%;
    left: 43%;
    transform: translate(-40% ,-50%);
    border-radius: 11px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.4);
    opacity: 0;
    visibility: hidden;
}

.container__main .popup__overlay.active{
    animation: slideDownAndFade 0.25s ease-in-out forwards;
}

@keyframes slideDownAndFade {
    0% {
        top: 32%;
        opacity: 0;
        visibility: hidden;
    }
    10% {
        top: 34%;
        opacity: 0.11;
    }
    20% {
        top: 35%;
        opacity: 0.15;
    }
    30% {
        top: 36%;
        opacity: 0.18;
    }
    40% {
        top: 37%;
        opacity: 0.2;
    }
    50% {
        top: 38%;
        opacity: 0.23;
    }
    60% {
        top: 39%;
        opacity: 0.27;
    }
    70% {
        top: 41%;
        opacity: 0.3;
    }
    80% {
        top: 43%;
        opacity: 0.35;
    }
    90% {
        top: 44%;
        opacity: 0.5;
    }
    100% {
        top: 45%;
        opacity: 1;
        visibility: visible;
        z-index: 1003;
    }
}

javascript

function myVisit() {
    var x = document.getElementById("add_site_type_vcls");
    var i = x.selectedIndex;

    // popupTopPosition = popOver.getBoundingClientRect().top;
    if (i == 1) {
        document.querySelector(".surf__by").style.display = 'flex';
        document.querySelector('.inp__single').style.display = 'block';
        // document.querySelector(".surf__by").style.opacity = '1';
        document.querySelector(".par__adv").style.display = 'none';
        document.querySelector(".any__clk").style.display = 'none';
        popOver.style.height = '630px';
        popOver.style.top = 35%;

    } else if (i == 2) {
        document.querySelector(".surf__by").style.display = 'none';
        document.querySelector('.inp__single').style.display = 'block';
        document.querySelector(".par__adv").style.display = 'flex';
        popOver.style.height = '740px';
        popOver.style.top = 40%;
    } else if (i == 3) {
        document.querySelector(".surf__by").style.display = 'none';
        document.querySelector('.inp__single').style.display = 'block';
        document.querySelector(".par__adv").style.display = 'none';
        document.querySelector(".any__clk").style.display = 'flex';
        popOver.style.height = '1325px';
        popOver.style.top = 35%;
    }
 }

Angular ngOnChanges Not Updating Component Variables When @Input() Changes

I have an Angular component that receives an @Input() property from a parent component. The parent component fetches data asynchronously (from an API), and when the data is set, ngOnChanges should update my local component variables.

However, my variables remain null even after the data is received and ngOnChanges is triggered.

import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';

@Component({
  selector: 'app-invoice',
  templateUrl: './invoice.component.html',
  styleUrls: ['./invoice.component.css']
})
export class InvoiceComponent implements OnChanges {
  invoiceId: string | null = null;

  @Input()
  invoiceData: any = null;

  ngOnChanges(changes: SimpleChanges): void {
    if (changes['invoiceData'] && changes['invoiceData'].currentValue) {
      this.invoiceId = this.invoiceData?.invoiceGenInfo?.invoice?.id;
      console.log("Updated invoiceData:", this.invoiceId); //this works
    }
  }

  onEdit(): void {
    console.log("Invoice Data in Edit:", this.invoiceId);
  }
}

Above is the angular component of the code. The console.log in the ngOnChange method does print the value after a few seconds since it’s asynchronous. But even after I see the console value when I trigger onEdit() with a click from a template the console logs as null.

How can I fix this? I need to update the template with the data from the invoiceData object after the API from the parent is completed.?

Thanks

How can I prevent Android downloads from failing?

I am using Cordova 12 to modify an existing Android application in order to try and make it compatible with Android API 34 (Android 14). The app must download thousands of small images before being usable, as the point of the app is to be used when totally offline. Therefore, linking directly to online images is not possible.

The problem is that some of the files will be saved to disk with a size of 0 byte. The specific files vary between runs. There is no error during the download or file saving process, ot at least the error callback is not triggered. I have tried adding a delay between file downloads, but it’s not clear if it helped or not.

Here is the FileUtility class, that is used for downloading and saving the files to disk

import ErrorLog from "./error-log.cls";
const { log } = ErrorLog;
const { logError } = ErrorLog;

export default class FileUtility {
    static DEFAULT_ERROR_MESSAGE = 'UNKNOWN_ERROR';
    static ErrorCodesStrings = {
        1: 'NOT_FOUND_ERR',
        2: 'SECURITY_ERR',
        3: 'ABORT_ERR',
        4: 'NOT_READABLE_ERR',
        5: 'ENCODING_ERR',
        6: 'NO_MODIFICATION_ALLOWED_ERR',
        7: 'INVALID_STATE_ERR',
        8: 'SYNTAX_ERR',
        9: 'INVALID_MODIFICATION_ERR',
        10: 'QUOTA_EXCEEDED_ERR',
        11: 'TYPE_MISMATCH_ERR',
        12: 'PATH_EXISTS_ERR',
    };

    constructor() {}

    static getErrorText(errorCode) {
        if(errorCode && Number.isInteger(errorCode) && errorCode > 1 && errorCode < 13) {
            return FileUtility.ErrorCodesStrings[errorCode] + ` (code ${errorCode})`;
        }

        return FileUtility.DEFAULT_ERROR_MESSAGE + ` (code ${errorCode})`;
    }

    static createDirectory(directoriesToCreate, callback, onError) {
        const directoriesChain = directoriesToCreate.trim('/').split('/');

        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, (fileSystem) => {
            const currentPathArray = [];
            let currentDirectoryCount = 0;
            directoriesChain.forEach(currentDirectory => {
                currentDirectoryCount++;
                currentPathArray.push(currentDirectory);
                fileSystem.root.getDirectory(currentPathArray.join('/'), { create: true }, (directoryEntry) => {
                    if(callback && currentDirectoryCount == directoriesChain.length) { callback(directoryEntry); }
                }, onError);
            });
        }, onError);
    }

    static createFile(filename, content, callback, onError) {
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, (fileSystem) => {
            fileSystem.root.getFile(filename, { create: true, exclusive: false }, (fileEntry) => {
                fileEntry.createWriter((fileWriter) => {
                    fileWriter.onwriteend = () => {
                        if (callback) { callback(fileEntry) };
                    };
                    fileWriter.onerror = (fileWriterError) => {
                        if (onError) {
                            onError(fileWriterError);
                        } else {
                            logError(`Could not create file ${filename}: ${FileUtility.getErrorText(fileWriterError.code)}.`);
                        }
                    };
                    fileWriter.write(content);
                });
            }, (fileCreationError) => {
                if (onError) {
                    onError(fileCreationError);
                } else {
                    logError(`Could not create ${filename}: ${FileUtility.getErrorText(fileCreationError.code)}.`);
                }
            });
        }, (fileSystemError) => {
            if (onError) {
                onError(fileSystemError);
            }else {
                logError(`downloadFile: Could not get the file system access required to create file ${filename}: ${FileUtility.getErrorText(fileSystemError.code)}.`);
            }
        });
    }

    static downloadFile(sourceURI, destinationPath, onComplete, onError) {
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, (fileSystem) => {
            fileSystem.root.getFile(destinationPath, { create: true, exclusive: false }, (dataFile) => {
                /* Using XMLHttpRequest gives the same end result.
                const fileRequest = new XMLHttpRequest();
                fileRequest.open("GET", encodeURI(sourceURI), true);
                fileRequest.responseType = 'blob';
                fileRequest.onload = (loadEvent) => {
                    const responseData = fileRequest.response;

                    if(responseData) {
                        dataFile.createWriter((fileWriter) => {
                            fileWriter.onwriteend = (fileWriteEvent) => {
                                log(`downloadFile: File ${dataFile.fullPath} was downloaded and saved.`);
                                if(onComplete) { onComplete(dataFile); }
                            };

                            fileWriter.onerror = (downloadError) => {
                                logError(`downloadFile: Could not download file ${sourceURI} to ${dataFile.fullPath}: ${FileUtility.getErrorText(downloadError.code)}.`);
                                if(onError) { onError(downloadError); }
                            };

                            fileWriter.write(responseData);
                        });
                    }
                };
                fileRequest.onerror = (downloadError) => {
                    logError(`downloadFile: Could not download file ${sourceURI} to ${dataFile.fullPath}: ${FileUtility.getErrorText(downloadError.code)}.`);
                    if(onError) { onError(downloadError); }
                }
                fileRequest.send(null);
                */
                fetch(encodeURI(sourceURI), {
                    method: "get",
                }).then(response => {
                    if(response.ok) {
                        response.blob().then((blobData) => {
                            dataFile.createWriter((fileWriter) => {
                                fileWriter.onwriteend = (fileWriteEvent) => {
                                    log(`downloadFile: File ${dataFile.fullPath} was downloaded and saved.`);
                                    if(onComplete) { onComplete(dataFile); }
                                };

                                fileWriter.onerror = (downloadError) => {
                                    logError(`downloadFile: Could not download file ${sourceURI} to ${dataFile.fullPath}: ${FileUtility.getErrorText(downloadError.code)}.`);
                                    if(onError) { onError(downloadError); }
                                };

                                fileWriter.write(blobData);
                            });
                        }).catch((responseError) => {
                            logError(`downloadFile: Could not download file ${sourceURI}: ${responseError.message}.`);
                        });
                    } else {
                        logError(`downloadFile: Could not download file ${sourceURI}: ${response.status}.`);
                    }
                }).catch(responseError => {
                    logError(`downloadFile: Could not download file ${sourceURI}: ${responseError.message}.`);
                });
            }, (fileCreationError) => {
                logError(`downloadFile: Could not create the file ${destinationPath}: ${FileUtility.getErrorText(fileCreationError.code)}.`);
                if(onError) { onError(fileCreationError); }
            });
        }, (fileSystemError) => {
            logError(`downloadFile: Could not get the file system access required to create file ${destinationPath}: ${FileUtility.getErrorText(fileSystemError.code)}.`);
            if(onError) { onError(fileSystemError); }
        });
    }

    static readTextFile(filePath, onRead, onError) {
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, (fileSystem) => {
            fileSystem.root.getFile(filePath, { create: true, exclusive: false }, (fileToRead) => {
                fileToRead.file((fileEntry) => {
                    const reader = new FileReader();
                    reader.onloadend = () => { if (onRead) onRead(reader.result); };
                    reader.readAsText(fileEntry);
                }, (fileReadError) => {
                    logError(`readTextFile: Could not read file ${filePath} (${JSON.stringify(fileReadError)}).`);
                    if(onError) { onError(fileReadError); }
                });
            });
        }, (fileReadError) => {
            logError(`readTextFile: Could not read file ${filePath} (${JSON.stringify(fileReadError)}).`);
            if(onError) { onError(fileReadError); }
        });
    }

    static deleteFile(filePath, onSuccess, onError) {
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, (fileSystem) => {
            fileSystem.root.getFile(filePath, { create: false, exclusive: false }, (fileToDelete) => {
                fileToDelete.remove((fileDeleted) => {
                    log(`The file ${filePath} was successfully deleted.`, ErrorLog.ERROR_LEVEL.WARNING);
                    if(onSuccess) { onSuccess(fileDeleted); }
                }, (fileDeletionError) => {
                    logError(`deleteFile: Could not deleted file ${filePath}: ${FileUtility.getErrorText(fileDeletionError.code)}).`);
                    if(onError) { onError(fileDeletionError); }
                });
            }, (fileGetError) => {
                logError(`deleteFile: Could not deleted file ${filePath}: ${FileUtility.getErrorText(fileGetError.code)}).`);
                if(onError) { onError(fileGetError); }
            });
        }, (fileSystemError) => {
            logError(`deleteFile: Could not deleted file ${filePath}: ${FileUtility.getErrorText(fileSystemError.code)}).`);
            if(onError) { onError(fileSystemError); }
        });
    }

    static readDirectory(directoryPath, onSuccess, onError) {
        window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, (fileSystem) => {
            fileSystem.root.getDirectory(directoryPath, { create: false, exclusive: false }, (directoryEntry) => {
                onSuccess(directoryEntry);
            }, (readDirectoryError) => {
                logError(`readDirectory: Could not read directory ${directoryPath}: ${FileUtility.getErrorText(readDirectoryError.code)}.`);
                if(onError) { onError(readDirectoryError); }
            })
        }, (fileSystemError) => {
            logError(`readDirectory: Could not get the file system access to read directory ${directoryPath}: ${FileUtility.getErrorText(fileSystemError.code)}.`);
            if(onError) { onError(fileSystemError); }
        });
    }
};

Here is the part of the code responsible for downloading the images:

/*
    this.listToDownload is an array of objects with the following structure:
        path: the remote path of the image on the server, which should also be used, after some tweaking, as a local path.
        state: the string "missing", "ok", "update" or "delete", in order to know what to do with the image.
        version: the version of the image, in order to check if that specific image must be downloaded or if it's already up to date.
*/

export default class ApplicationSynchronisation {
    [...]

    downloadNextElement() {
        if(this.nextToDownload) {
            // Display the progress percentage on the main window.
            this.onProgress(this._('updating'), parseFloat((1 - (this.listToDownload.length / this.listOriginalSize)).toFixed(4)));
            const action = this.nextToDownload.state != "delete" ? 'download' : 'delete';
            let path = this.nextToDownload.path.replace(/{lang}/gi, this.language);
            path = path.startsWith('./') ? path.substr(2) : path;
            path = path.lastIndexOf('|') != -1 ? path.substring(0, path.lastIndexOf('|')) : path;
            let localPath = path;

            if(localPath.endsWith('.json')) {
                localPath = localPath.replace(`/${this.language}/`, '/');
            }

            if(localPath.startsWith('dist/')) {
                localPath = localPath.substr(5);
            }

            if(this.listToDownload.length) {
                this.nextToDownload = this.listToDownload.pop();
            } else {
                delete this.nextToDownload;
            }

            if(action == 'download') {
                FileUtility.createDirectory(localPath.substring(0, localPath.lastIndexOf('/')), () => {
                    FileUtility.downloadFile(this.application.remoteUrl + path, localPath, () => this.downloadNextElement(), (downloadError) => {
                        logError(`Error while downloading file ${this.application.remoteUrl + path} to local path ${localPath}: ${FileUtility.getErrorText(downloadError.code)}.`);
                        setTimeout(() => this.downloadNextElement, 250);
                    });
                }, (directoryCreationError) => {
                    logError(`Could not create the following complete path: ${localPath.substring(0, localPath.lastIndexOf('/'))}: ${FileUtility.getErrorText(directoryCreationError.code)}`);
                    this.downloadNextElement();
                });
            } else {
                FileUtility.deleteFile(localPath, (() => this.downloadNextElement), (deleteError) => {
                    logError(`Error while deleting ${localPath}: ${FileUtility.getErrorText(deleteError.code)}.`);
                    this.downloadNextElement();
                });
            }
        } else {
            this.onComplete();
        }
    }

    onProgress(textToShow, percentCompletion) {
        log(`${textToShow} ${(percentCompletion * 100).toFixed(2)}%`);
        if(this.application.onSyncProgress) { this.application.onSyncProgress(textToShow, percentCompletion) };
    }

    onComplete() {
        if(! this.synchronised) {
            this.synchronised = true;
            log("App synchronised.");
            this.onProgress(this._('uptodate'), 1);
            // Process sync callback and switch to main app.
            [...]
        }
    }

    [...]
}

As mentioned in the code, I have tried using the fetch API or XMLHttpRequest. Both give the same result. Adding a delay (through setTimeout) seems to help, although I have not yet formerly calculated the percentage of files that are empty with different delays so I cannot say for sure.

How can I change the download process to ensure that all the files are properly downloaded? Should I just put back on the stack any file that is downloaded and that is 0 byte, even if don’t know exactly why it was saved as en empty file?

How to Fill the Area Between Two EMA Series in Lightweight Charts Using a Plugin?

I’m working with Lightweight-charts by TradingView and want to create a custom plugin that fills the area between two series of Exponential Moving Average.

I know that the Lightweigh-charts does not natively support area fills between two different lines, but I assume this could be done using a plugin.

My Goals:

Plot two EMA series (e.g., EMA 50 and EMA 60).

Fill the area between them with a transparent color with different coloring based on the position of one EMA relative to the other.

Ensure the fill dynamically updates as new data arrives.

Any help would be greatly appreciated.

I’m trying to navigate through the various sections of the documentation, but I’m not sure how to achieve this. I hope there’s already a solution rather than having to implement a plugin from scratch. But if that’s the case, I’m ready to give it a try.

AWS S3 Bucket upload via presigned request – 403 forbidden if filename contains unicode characters

I have just ran into a weird issue with S3 blocking requests (403 Forbidden, no response body) if the filename contains unicode characters.

Backend code that generates the presigned URL:

$userId = ...; // Irrelevant.
$filename = ...; // Comes from POST data.
$safeName = trim(preg_replace('/[^a-z0-9-_.]/i', '-', $filename), '-'); // AWS only allows specific characters in key.
$key = sprintf('user-documents/%s/%s', $userId, $safeName);

$metadata = [
    'type'     => 'USER_DOCUMENT',
    'userId'   => $userId,
    'filename' => $filename, // The raw one from POST.
];
$s3 = new S3Client([
    'region'      => getenv('AWS_REGION'),
    'version'     => 'latest',
    'credentials' => CredentialProvider::env(),
]);
$uploadUrl = $s3->createPresignedRequest(
    $s3->getCommand('PutObject', [
        'Bucket'   => getenv('AWS_BUCKET_USER_DATA'),
        'Key'      => $key,
        'Metadata' => $metadata,
    ]),
    '+1 hour',
)->getUri();

$response = [
    'uploadUrl' => $uploadUrl,
    'metadata'  => $metadata,
];

Frontend code that uploads the files to S3:

const file = fileInput.files[0];
const response = await getUploadUrl(file.name); // This is where the POST filename comes from.
await fetch(response.uploadUrl, {
    method: 'PUT',
    headers: {
        'x-amz-meta-type': response.metadata.type,
        'x-amz-meta-userid': response.metadata.userId,
        'x-amz-meta-filename': response.metadata.filename
    },
    body: file,
}).then(resp => {
    if (!resp.ok) {
        throw new Error('File upload failed: ' + resp.status + ' ' + resp.statusText)
    }
});

This code works completely fine if the filenames are in ASCII, but if a filename contains a unicode letter, e.g. ä, then the uploadUrl request gives me a 403 Forbidden response without a response body, turning debugging into guessing. I only tried changing ä into a because another StackOverflow question had some answers mentioning filename URL encoding, and that worked.

So the question is – what do I need to change in this code in order to not have this issue? I’m not even sure where the problem is, because uploadUrl contains the URL-encoded original filename, which AWS – presumably – decodes on their end (it’s a query parameter, of course it should be URL-decoded, it’s their own SDK that encodes it!), and metadata headers also contain the original filename (non-encoded).

aws/[email protected], if that changes anything.

Why does `Object()` constructor work when implementing `Function.call`?

I was trying to implement the Function.call without using call in any form. The idea was to create an object whose this is the value passed as thisArg to the call method. Initially Object.create(thisArg) came to mind, however that doesn’t really work since it only sets the prototype of the object to thisArg.
The answer basically boils down to using Object() constructor, and then setting the function with arguments as a ‘method’ on some key for that object.

Something along this lines:

 thisArg = thisArg || window;
 thisArg = Object(thisArg); 

 const methodSymbol = Symbol();
 thisArg[methodSymbol] = this; // this is the function on which call is executed.

My query is that I am a bit confused on the working of the Object constructor – it seems it sets the this of the object method to the value passed in the constructor, but there is some other malarkey in the spec/MDN docs that basically confuses me.
Is there a better explanation on why this works? any other way to implement the same? maybe this is some hacky JS workings that I am not aware of.

How to make looping scroll when scroll to top an

currently I’m create time-picker
like input tag of HTML :
with Radix-vue using Scroll-area component.

As you can see at input tag of html, the hour is from 01->12, when scroll to bottom of dropdown list, it appear 01->12 and 01, 02, 03. Anh whenever you scroll to top of dropdown list, it appear 11,12,01->12.
Like this image

I already search : radix vue cdn scroll area allow infinite scroll with loop element
but I don’t find any way to resolve my problem.

Here is my current code ( I’m using vue3 and tailwind css )

     <div class="flex h-[242px] justify-between gap-1 divide-x divide-gray-200">
        <ScrollArea id="scrollableHours" className="h-full w-1/2 overflow-y-hidden scroll-smooth" :type="`scroll`">
          <div v-for="hour in HOURS" :key="hour.label">
            <Button
              :variant="`unstyle`"
              :id="`h-${hour.label}`"
          
            >
              {{ hour.label }}
            </Button>
          </div>
        </ScrollArea>

        </div>

Send Firebase Cloud Messaging (FCM) notification with click_action

I’m having trouble getting the payload right for sending Firebase Cloud Messaging (FCM) notifications with click_action.

According to https://firebase.google.com/docs/reference/admin/node/firebase-admin.messaging.messaging.md#messagingsendeach, sendToDevice() is not supported anymore? So I am trying to use sendEach().

Previously, I was able to do this:

const tokens = [
  'token',
];
const payload = {
  notification: {
    title: 'Title',
    body: 'Body',
    icon: 'https://example.com/icon.png',
    click_action: 'https://example.com',
  },
}
await admin.messaging().sendToDevice(tokens, payload);

Now I am trying this:

const messages = [
  token: 'token',
  notification: {
    title: 'Title',
    body: 'Body',
    icon: 'https://example.com/icon.png',
    click_action: 'https://example.com',
  },
];
await admin.messaging().sendEach(messages);

Which gives me this error:

>    errorInfo: {
>      code: 'messaging/invalid-argument',
>      message: `Invalid JSON payload received. Unknown name "icon" at 'message.notification': Cannot find field.n` +
>        `Invalid JSON payload received. Unknown name "click_action" at 'message.notification': Cannot find field.`
>    },

I see on https://firebase.google.com/docs/reference/admin/node/firebase-admin.messaging.notification.md#notification_interface that icon should be imageUrl but there is no mention of click_action anymore.

How do I send a notification with click_action like I used to? Is there a different method that I am not seeing?

TomTom Maps React Cluster Count Missing Glyphs Style

I’m integrating TomTom Maps into a React application and using clustering to combine map points. However, I’m encountering the following error when trying to display cluster counts:

Error: layers.cluster-count.layout.text-field: use of "text-field" requires a style "glyphs"

This error occurs when I try to add a layer for displaying the cluster count using the text-field property. I believe the issue is related to missing glyphs (fonts) in the map style, but I’m not sure how to properly configure the map to include them.

Here’s my current implementation:

const mapInstance = useRef(null);
const markersOnMap = useRef({});

useEffect(() => {
  if (!mapElement.current) return;

  // Convert markers to GeoJSON format
  const geoJson = {
    type: "FeatureCollection",
    features: markers.map((marker, index) => ({
      type: "Feature",
      geometry: {
        type: "Point",
        coordinates: [marker.longitude, marker.latitude],
      },
      properties: {
        id: index + 1,
        name: marker.label || `Location ${index + 1}`,
      },
    })),
  };

  // Initialize map
  mapInstance.current = tt.map({
    key: process.env.TOMTOM_API_KEY,
    container: mapElement.current,
    center: center,
    zoom: zoom,
  });

  // Setup layers and sources
  const setupMapLayers = () => {
    // Add source for clustering
    if (mapInstance.current.getSource("point-source")) return;
    mapInstance.current.addSource("point-source", {
      type: "geojson",
      data: geoJson,
      cluster: true,
      clusterMaxZoom: 14,
      clusterRadius: 50,
    });

    // Add cluster circles layer
    mapInstance.current.addLayer({
      id: "clusters",
      type: "circle",
      source: "point-source",
      filter: ["has", "point_count"],
      paint: {
        "circle-color": [
          "step",
          ["get", "point_count"],
          "#EC619F", // Default color
          4, // Number of points threshold
          "#008D8D", // Color for clusters with 4+ points
          7, // Number of points threshold
          "#004B7F", // Color for clusters with 7+ points
        ],
        "circle-radius": [
          "step",
          ["get", "point_count"],
          15, // Default radius
          4, // Number of points threshold
          20, // Radius for clusters with 4+ points
          7, // Number of points threshold
          25, // Radius for clusters with 7+ points
        ],
        "circle-stroke-width": 1,
        "circle-stroke-color": "white",
        "circle-stroke-opacity": 1,
      },
    });

    // Add cluster count layer
    mapInstance.current.addLayer({
      id: "cluster-count",
      type: "symbol",
      source: "point-source",
      filter: ["has", "point_count"],
      layout: {
        "text-field": "{point_count_abbreviated}",
        "text-size": 16,
      },
      paint: {
        "text-color": "white",
      },
    });

I attempted to specify a map style that includes glyphs by adding the glyphs property to the map initialization, but I’m not sure if I’m doing it correctly.

Differentiate between different types of email recipients in inboxSdk

I am using InboxSdk and I wanted to know if there is any way to differentiate between different types of email recipients, i.e., to, Cc, Bcc

Currently using both methods of messageView getRecipientEmailAddresses() and getRecipientsFull(), I am only getting arrays of the recipients, which are unfiltered.

getRecipientEmailAddresses()


[
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]",
    "[email protected]"
]

getRecipientsFull()

[
    {
        "emailAddress": "[email protected]"
    },
    {
        "emailAddress": "[email protected]"
    },
    {
        "emailAddress": "[email protected]"
    },
    {
        "emailAddress": "[email protected]"
    },
    {
        "emailAddress": "[email protected]"
    },
    {
        "emailAddress": "[email protected]"
    }
]

Working with character classes in javascript [closed]

I have this regex variable which is const regex = /[0-9]e[0-9]/i , I want to replace [0-9] character classes with a shorthand character d, how do i replace it in javascript

// This is the original variable
const regex = /[0-9]e[0-9]/i;

//This is what I worked on
 const regex = /ded/i;

the problem is that my program is not running, I cant really locate where the bug is.

Smooth time-series visualization of COG GeoTIFFs in OpenLayers with WebGL without loading delays

I’m implementing a temporal visualization of water depth data using OpenLayers with COG (Cloud Optimized GeoTIFF) files (large). The user should be able to scroll horizontally to navigate through time, but I’m experiencing visible loading delays when switching between rasters.

// Simplified current implementation
const layer = new WebGLTileLayer({
  source: new GeoTIFF({
    sources: [{ url: initialUrl }],
    convertToRGB: true
  })
});

// On scroll event
function handleScroll(direction) {
  const newUrl = getUrlForTimeStep(currentIndex + direction);
  layer.getSource().setUrl(newUrl); // Causes visible loading delay
  currentIndex += direction;
}

What are best practices here? I’ve also tried to have active layers left and right of current time index, with opacity 0, with loaded sources. It works better, but I feel I’m missing the “right” way of solving this issue.

How to apply another lay-out e.g. ForceSupervisor?

I’d like to show a graph with a few nodes on my website. The code should directly work in the browser.

With

npm install sigma
npm install graphology
npm install graphology-library

the following code is working:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Title</title>
    <script type="text/javascript" src="node_modules/sigma/dist/sigma.min.js"></script>
    <script type="text/javascript" src="node_modules/graphology/dist/graphology.umd.min.js"></script>

    <!--<script type="text/javascript" src="node_modules/graphology-library/dist/graphology-library.min.js"></script>-->
    <!--<script type="module" src="node_modules/graphology-layout-force/worker.js"></script>-->
  </head>
  <body style="background: lightgrey">
    <div id="graph-container" style="position: absolute; top:0; left:0; width: 800px; height: 600px; background: white"></div>

    <script>
      const graph = new graphology.Graph();
      graph.addNode("1", { label: "1", x: 0, y: 0, size: 10, color: "blue" });
      graph.addNode("2", { label: "2", x: 1, y: 1, size: 20, color: "red" });
      graph.addEdge("1", "2", { size: 5, color: "purple" });

      // https://www.sigmajs.org/storybook/?path=/story/mouse-manipulations--story
      //const layout = new ForceSupervisor(graph, { isNodeFixed: (_, attr) => attr.highlighted });
      //layout.start();

      const sigma = new Sigma(graph, document.getElementById("graph-container"));
    </script>
  </body>
</html>

Now I’d like to have another layout (ForceSupervisor). How can I involve this layout? The commented out lines are throwing errors like

Uncaught ReferenceError: ForceSupervisor is not defined
Uncaught ReferenceError: require is not defined

Is it possible at all to reach this completely in the browser?