Updated all bookmarklets to just be functions and we can use utils/bookmarkletMaker.js to generate the bookmarklets in the console for now.

This commit is contained in:
Greg Jacobs
2024-06-12 13:04:47 -04:00
parent 3f25aef4f2
commit e2c5035011
26 changed files with 587 additions and 380 deletions

View File

@@ -0,0 +1,12 @@
/**
* Opens the API documentation for a given project API.
*
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*
* @param {string} projectAPI - The project API to open the documentation for.
*/
const projectAPI = prompt("Please enter the project API:");
if (projectAPI) {
window.open(`https://api.qa.services.mdgapp.net/${projectAPI}/v1/docs`, "_blank").focus();
}

View File

@@ -2,17 +2,17 @@
* Opens the DAG Task details page(s) based on user input.
* If user provides a comma-separated list of DAG Task numbers, it opens each task's details page in a new tab.
* If user does not provide any input, it opens the default DAG Tasks page in a new tab.
*
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*/
javascript:(function() {
let answers = prompt("Enter the DAG Task #s, separated by commas");
const splitAnswers = answers ? answers.split(",") : false;
let url = "https://dag.tools.mdgapp.net/Tasks/Tasks.asp";
if (splitAnswers) {
splitAnswers.forEach(answer => {
let moidUrl = "https://dag.tools.mdgapp.net/Tasks/TaskDetail.asp?Cmd=Details&TaskID=" + answer.trim();
window.open(moidUrl, '_blank');
});
} else {
window.open(url, '_blank').focus();
}
})();
let answers = prompt("Enter the DAG Task #s, separated by commas");
const splitAnswers = answers ? answers.split(",") : false;
let url = "https://dag.tools.mdgapp.net/Tasks/Tasks.asp";
if (splitAnswers) {
splitAnswers.forEach(answer => {
let moidUrl = "https://dag.tools.mdgapp.net/Tasks/TaskDetail.asp?Cmd=Details&TaskID=" + answer.trim();
window.open(moidUrl, '_blank');
});
} else {
window.open(url, '_blank').focus();
}

View File

@@ -9,13 +9,13 @@
* 4. Copies the decoded string to the clipboard.
*
* Note: This function uses the Clipboard API which might not be fully supported in all browsers.
*
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*/
javascript:(function() {
let answer = prompt("Enter the HashID");
let decodedStr = decodeURIComponent(answer);
alert(decodedStr);
let answer = prompt("Enter the HashID");
let decodedStr = decodeURIComponent(answer);
alert(decodedStr);
navigator.clipboard.writeText(decodedStr)
.then(() => console.log('Decoded string copied to clipboard'))
.catch(err => console.error('Error in copying decoded string to clipboard: ', err));
})();
navigator.clipboard.writeText(decodedStr)
.then(() => console.log('Decoded string copied to clipboard'))
.catch(err => console.error('Error in copying decoded string to clipboard: ', err));

View File

@@ -10,17 +10,16 @@
* 5. Opens the URL in a new browser tab and brings focus to it.
*
* Note: This function is wrapped in a self-invoking function `(function() {...})();` which means it will automatically execute as soon as it is defined.
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*/
javascript:(function() {
let answers = prompt("Enter the JIRA Tickets, separated by commas");
const splitAnswers = answers ? answers.split(",") : false;
let url = "https://fincentric.atlassian.net/jira/software/c/projects/DIP/boards/513";
if (splitAnswers) {
splitAnswers.forEach(answer => {
let moidUrl = "https://fincentric.atlassian.net/browse/" + answer.trim();
window.open(moidUrl, '_blank');
});
} else {
window.open(url, '_blank').focus();
}
})();
let answers = prompt("Enter the JIRA Tickets, separated by commas");
const splitAnswers = answers ? answers.split(",") : false;
let url = "https://fincentric.atlassian.net/jira/software/c/projects/DIP/boards/513";
if (splitAnswers) {
splitAnswers.forEach(answer => {
let moidUrl = "https://fincentric.atlassian.net/browse/" + answer.trim();
window.open(moidUrl, '_blank');
});
} else {
window.open(url, '_blank').focus();
}

View File

@@ -10,17 +10,16 @@
* 5. Opens each URL in a new browser tab and brings focus to the last opened tab.
*
* Note: This function is wrapped in a self-invoking function `(function() {...})();` which means it will automatically execute as soon as it is defined.
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*/
javascript:(function() {
let answers = prompt("Enter the MOID #s, separated by commas");
const splitAnswers = answers ? answers.split(",") : false;
let url = "https://jira.ihsmarkit.com/secure/Dashboard.jspa?selectPageId=63222";
if (splitAnswers) {
splitAnswers.forEach(answer => {
let moidUrl = "https://jira.ihsmarkit.com/browse/MOID-" + answer.trim();
window.open(moidUrl, '_blank');
});
} else {
window.open(url, '_blank').focus();
}
})();
let answers = prompt("Enter the MOID #s, separated by commas");
const splitAnswers = answers ? answers.split(",") : false;
let url = "https://jira.ihsmarkit.com/secure/Dashboard.jspa?selectPageId=63222";
if (splitAnswers) {
splitAnswers.forEach(answer => {
let moidUrl = "https://jira.ihsmarkit.com/browse/MOID-" + answer.trim();
window.open(moidUrl, '_blank');
});
} else {
window.open(url, '_blank').focus();
}

View File

@@ -0,0 +1,19 @@
function jsToMsDate(jsdate) {
const ms = Date.UTC(
jsdate.getFullYear(),
jsdate.getMonth(),
jsdate.getDate(),
jsdate.getHours(),
jsdate.getMinutes(),
jsdate.getSeconds(),
jsdate.getMilliseconds()
);
const off = jsdate.getTimezoneOffset();
return (ms - off * 60 * 1000) / 86400000 + 25569;
}
const date = prompt("Enter date");
if (date) {
const parsedDate = new Date(date);
alert(jsToMsDate(parsedDate));
}

View File

@@ -0,0 +1,11 @@
function msToJsDate(msdate) {
const jscriptDateObj = new Date((msdate - 25569) * 86400000);
const timezoneOffset = jscriptDateObj.getTimezoneOffset();
jscriptDateObj.setTime((msdate - 25569 + timezoneOffset / (60 * 24)) * 86400000);
return jscriptDateObj;
}
const date = prompt("Enter MSDate");
if (date) {
alert(msToJsDate(date));
}

View File

@@ -0,0 +1,40 @@
function setFlag(flag, state) {
function setFlagSub(url, flag, state) {
if (!url.includes(flag)) {
url += (url.includes('?') ? '&' : '?');
url += `..${flag}..=${state}`;
} else {
const re = new RegExp(`\\.\\.${flag}\\.\\.=[^&]*`);
url = url.replace(re, `..${flag}..=${state}`);
}
return url;
}
function toggleParameter(ad, type, val) {
type = `..${type}..`;
const regex = new RegExp(`[?|&]${type}=(on|off)&?`);
const match = ad.match(regex);
if (match) {
ad = ad.replace(`${type}=${match[1]}`, `${type}=${val || (match[1] === 'on' ? 'off' : 'on')}`);
} else {
ad += (ad.includes('?') ? '&' : '?') + `${type}=${val || 'on'}`;
}
return ad;
}
const dependencies = {
debugchartsrv: ['showdebuginfo'],
scriptscachedebug: ['scriptscache']
};
let url = window.location.href.replace(/#.*/, '');
if (dependencies[flag] && state !== 'off') {
for (const dependency of dependencies[flag]) {
url = toggleParameter(url, dependency, 'on');
}
}
url = toggleParameter(url, flag, state || null);
window.location.href = url;
}
setFlag('showdebuginfo');

View File

@@ -3,94 +3,94 @@
* It retrieves the feature flags from the session storage, creates checkboxes for each flag,
* and saves the updated flags back to the session storage when the user clicks the save button.
* The modal dialog is appended to the document body and can be closed by clicking the save button.
*
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*/
javascript:(function() {
let data = sessionStorage.getItem('rbc_di_session');
let parsedData = JSON.parse(data);
let features = parsedData.features || {};
let data = sessionStorage.getItem('rbc_di_session');
let parsedData = JSON.parse(data);
let features = parsedData.features || {};
let modal = document.createElement('div');
modal.style.position = 'fixed';
modal.style.top = '50%';
modal.style.left = '50%';
modal.style.transform = 'translate(-50%, -50%)';
modal.style.backgroundColor = 'white';
modal.style.padding = '20px';
modal.style.border = '1px solid black';
modal.style.zIndex = '999';
modal.style.display = 'flex';
modal.style.flexWrap = 'wrap';
let modal = document.createElement('div');
modal.style.position = 'fixed';
modal.style.top = '50%';
modal.style.left = '50%';
modal.style.transform = 'translate(-50%, -50%)';
modal.style.backgroundColor = 'white';
modal.style.padding = '20px';
modal.style.border = '1px solid black';
modal.style.zIndex = '999';
modal.style.display = 'flex';
modal.style.flexWrap = 'wrap';
for (let key in features) {
if (features.hasOwnProperty(key) && typeof features[key] === 'boolean') {
let checkboxContainer = document.createElement('div');
checkboxContainer.style.width = '50%';
for (let key in features) {
if (features.hasOwnProperty(key) && typeof features[key] === 'boolean') {
let checkboxContainer = document.createElement('div');
checkboxContainer.style.width = '50%';
let checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = key;
checkbox.checked = features[key];
let checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = key;
checkbox.checked = features[key];
let label = document.createElement('label');
label.htmlFor = key;
label.innerText = key;
let label = document.createElement('label');
label.htmlFor = key;
label.innerText = key;
checkboxContainer.appendChild(checkbox);
checkboxContainer.appendChild(label);
modal.appendChild(checkboxContainer);
}
}
checkboxContainer.appendChild(checkbox);
checkboxContainer.appendChild(label);
modal.appendChild(checkboxContainer);
}
}
let saveButton = document.createElement('button');
saveButton.innerText = 'Save';
saveButton.addEventListener('click', function() {
const checkboxes = modal.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach(function(checkbox) {
features[checkbox.id] = checkbox.checked;
});
parsedData.features = features;
sessionStorage.setItem('rbc_di_session', JSON.stringify(parsedData));
location.reload();
});
let saveButton = document.createElement('button');
saveButton.innerText = 'Save';
saveButton.addEventListener('click', function() {
const checkboxes = modal.querySelectorAll('input[type="checkbox"]');
checkboxes.forEach(function(checkbox) {
features[checkbox.id] = checkbox.checked;
});
parsedData.features = features;
sessionStorage.setItem('rbc_di_session', JSON.stringify(parsedData));
location.reload();
});
let closeButton = document.createElement('button');
closeButton.innerText = 'X';
closeButton.style.position = 'absolute';
closeButton.style.right = '10px';
closeButton.style.top = '10px';
closeButton.addEventListener('click', function() {
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
let closeButton = document.createElement('button');
closeButton.innerText = 'X';
closeButton.style.position = 'absolute';
closeButton.style.right = '10px';
closeButton.style.top = '10px';
closeButton.addEventListener('click', function() {
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
let cancelButton = document.createElement('button');
cancelButton.innerText = 'Cancel';
cancelButton.addEventListener('click', function() {
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
let cancelButton = document.createElement('button');
cancelButton.innerText = 'Cancel';
cancelButton.addEventListener('click', function() {
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
let buttonContainer = document.createElement('div');
buttonContainer.style.width = '100%';
buttonContainer.style.display = 'flex';
buttonContainer.style.justifyContent = 'center';
buttonContainer.style.marginTop = '20px';
let buttonContainer = document.createElement('div');
buttonContainer.style.width = '100%';
buttonContainer.style.display = 'flex';
buttonContainer.style.justifyContent = 'center';
buttonContainer.style.marginTop = '20px';
buttonContainer.appendChild(saveButton);
buttonContainer.appendChild(cancelButton);
buttonContainer.appendChild(saveButton);
buttonContainer.appendChild(cancelButton);
modal.appendChild(closeButton);
modal.appendChild(buttonContainer);
modal.appendChild(closeButton);
modal.appendChild(buttonContainer);
let overlay = document.createElement('div');
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
overlay.style.zIndex = '998';
let overlay = document.createElement('div');
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
overlay.style.zIndex = '998';
document.body.appendChild(overlay);
document.body.appendChild(modal);
})();
document.body.appendChild(overlay);
document.body.appendChild(modal);

View File

@@ -3,21 +3,21 @@
* Deletes the 'fnc-rbc-session' property from the session storage if it exists.
* If the property exists, it prompts the user for confirmation before deleting.
* If the property does not exist, it displays an alert message.
*
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*/
javascript: (function () {
const rbcSession = sessionStorage.getItem('fnc-rbc-session');
if (rbcSession) {
const sessionValue = JSON.parse(rbcSession);
let properties = '';
for (const key in sessionValue) {
properties += `${key}: ${sessionValue[key]}\n`;
}
const confirmDelete = confirm(`The properties in 'fnc-rbc-session' are:\n\n${properties}\nDo you want to delete 'fnc-rbc-session'?`);
if (confirmDelete) {
sessionStorage.removeItem('fnc-rbc-session');
location.reload();
}
} else {
alert("'fnc-rbc-session' does not exist in session storage.");
const rbcSession = sessionStorage.getItem('fnc-rbc-session');
if (rbcSession) {
const sessionValue = JSON.parse(rbcSession);
let properties = '';
for (const key in sessionValue) {
properties += `${key}: ${sessionValue[key]}\n`;
}
})();
const confirmDelete = confirm(`The properties in 'fnc-rbc-session' are:\n\n${properties}\nDo you want to delete 'fnc-rbc-session'?`);
if (confirmDelete) {
sessionStorage.removeItem('fnc-rbc-session');
location.reload();
}
} else {
alert("'fnc-rbc-session' does not exist in session storage.");
}

View File

@@ -4,26 +4,26 @@
* Prompts the user to enter the environment and language in the format 'prod|ste,en|fr'.
* If the input is valid, it opens the corresponding URL in a new tab.
* If the input is invalid, it logs an error message to the console.
*
* Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*/
javascript: (function () {
const answer = prompt("Please enter the env and language in the format 'prod|ste,en|fr':");
const [env, language] = answer.split(",");
switch (env) {
case "prod":
if (language === "fr") {
window.open("https://www1.royalbank.com/french/netaction/sgnf.html", "_blank").focus();
} else {
window.open("https://www1.royalbank.com/english/netaction/sgne.html", "_blank").focus();
}
break;
case "ste":
if (language === "fr") {
window.open("https://www1.steroyalbank.com/french/netaction/sgnf.html", "_blank").focus();
} else {
window.open("https://www1.steroyalbank.com/english/netaction/sgne.html", "_blank").focus();
}
break;
default:
console.log("Invalid input");
}
})();
const answer = prompt("Please enter the env and language in the format 'prod|ste,en|fr':");
const [env, language] = answer.split(/,|\s/);
switch (env) {
case "prod":
if (language === "fr") {
window.open("https://www1.royalbank.com/french/netaction/sgnf.html", "_blank").focus();
} else {
window.open("https://www1.royalbank.com/english/netaction/sgne.html", "_blank").focus();
}
break;
case "ste":
if (language === "fr") {
window.open("https://www1.steroyalbank.com/french/netaction/sgnf.html", "_blank").focus();
} else {
window.open("https://www1.steroyalbank.com/english/netaction/sgne.html", "_blank").focus();
}
break;
default:
console.log("Invalid input");
}

View File

@@ -6,43 +6,43 @@ and sets the value of the input field to each security in the array.
It then triggers events to simulate user input and key presses to add the security to the watchlist.
The process repeats for each security in the array with a delay of 2.5 seconds between each iteration.
The code is executed when the bookmarklet is clicked on the web page.
Requires the use of utils/bookmarkletMaker.js to generate the bookmarklet.
*/
javascript: (function () {
const newSecurities = [
'AMX',
'VNORP',
'AMBKP',
'CSU.DB',
'NFLX',
'ICFSSUSN',
'ICRP',
'LDSVF',
'AMTPQ',
'DSHKP',
'AITRR',
'URW',
'AP.UN',
'PVF.WT'
];
function populateWatchlist() {
const foundInputs = document.querySelectorAll('.rbc-typeahead-search-input');
const input = foundInputs && foundInputs.length > 1 ? foundInputs[1] : null;
if (input) {
let index = 0;
const interval = setInterval(() => {
if (index >= newSecurities.length) {
clearInterval(interval);
return;
}
input.value = newSecurities[index];
input.dispatchEvent(new Event('input', { bubbles: true }));
input.dispatchEvent(new Event('change', { bubbles: true }));
setTimeout(() => {
input.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 }));
}, 1000);
index++;
}, 2500);
}
const newSecurities = [
'AMX',
'VNORP',
'AMBKP',
'CSU.DB',
'NFLX',
'ICFSSUSN',
'ICRP',
'LDSVF',
'AMTPQ',
'DSHKP',
'AITRR',
'URW',
'AP.UN',
'PVF.WT'
];
function populateWatchlist() {
const foundInputs = document.querySelectorAll('.rbc-typeahead-search-input');
const input = foundInputs && foundInputs.length > 1 ? foundInputs[1] : null;
if (input) {
let index = 0;
const interval = setInterval(() => {
if (index >= newSecurities.length) {
clearInterval(interval);
return;
}
input.value = newSecurities[index];
input.dispatchEvent(new Event('input', { bubbles: true }));
input.dispatchEvent(new Event('change', { bubbles: true }));
setTimeout(() => {
input.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 13 }));
}, 1000);
index++;
}, 2500);
}
populateWatchlist();
})();
}
populateWatchlist();

View File

@@ -1,91 +1,89 @@
javascript:(function() {
const urls = {
JIRAMetricsDashboard: "https://fincentric.atlassian.net/jira/dashboards/14019/",
JIRABoard: "https://fincentric.atlassian.net/jira/software/c/projects/DIP/boards/513",
MOIDDashboard: "https://jira.ihsmarkit.com/secure/Dashboard.jspa?selectPageId=63222",
DIUserLoginsConfluencePage: "https://confluence.ihsmarkit.com/pages/viewpage.action?spaceKey=MOD&title=DI+User+Logins#direct-investing--686175318",
WEUserAdmin: "https://intranet.tools.mdgapp.net/P/PTC1/UserAdmin"
};
const urls = {
JIRAMetricsDashboard: "https://fincentric.atlassian.net/jira/dashboards/14019/",
JIRABoard: "https://fincentric.atlassian.net/jira/software/c/projects/DIP/boards/513",
MOIDDashboard: "https://jira.ihsmarkit.com/secure/Dashboard.jspa?selectPageId=63222",
DIUserLoginsConfluencePage: "https://confluence.ihsmarkit.com/pages/viewpage.action?spaceKey=MOD&title=DI+User+Logins#direct-investing--686175318",
WEUserAdmin: "https://intranet.tools.mdgapp.net/P/PTC1/UserAdmin"
};
let modal = document.createElement('div');
modal.style.position = 'fixed';
modal.style.top = '50%';
modal.style.left = '50%';
modal.style.transform = 'translate(-50%, -50%)';
modal.style.backgroundColor = 'white';
modal.style.padding = '20px';
modal.style.border = '1px solid black';
modal.style.zIndex = '999';
modal.style.display = 'flex';
modal.style.flexWrap = 'wrap';
Object.keys(urls).forEach(key => {
let checkboxContainer = document.createElement('div');
checkboxContainer.style.width = '50%';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = key;
checkbox.name = key;
checkbox.value = urls[key];
let modal = document.createElement('div');
modal.style.position = 'fixed';
modal.style.top = '50%';
modal.style.left = '50%';
modal.style.transform = 'translate(-50%, -50%)';
modal.style.backgroundColor = 'white';
modal.style.padding = '20px';
modal.style.border = '1px solid black';
modal.style.zIndex = '999';
modal.style.display = 'flex';
modal.style.flexWrap = 'wrap';
const label = document.createElement('label');
label.htmlFor = key;
label.innerText = key.split(/(?=[A-Z][a-z])/).join(' ');
checkboxContainer.appendChild(checkbox);
checkboxContainer.appendChild(label);
modal.appendChild(checkboxContainer);
});
Object.keys(urls).forEach(key => {
let checkboxContainer = document.createElement('div');
checkboxContainer.style.width = '50%';
const startButton = document.createElement('button');
startButton.innerText = 'Start';
startButton.addEventListener('click', () => {
const selectedUrls = Array.from(modal.querySelectorAll('input[type="checkbox"]:checked')).map(checkbox => checkbox.value);
selectedUrls.forEach(url => window.open(url, '_blank'));
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = key;
checkbox.name = key;
checkbox.value = urls[key];
const label = document.createElement('label');
label.htmlFor = key;
label.innerText = key.split(/(?=[A-Z][a-z])/).join(' ');
checkboxContainer.appendChild(checkbox);
checkboxContainer.appendChild(label);
modal.appendChild(checkboxContainer);
});
const startButton = document.createElement('button');
startButton.innerText = 'Start';
startButton.addEventListener('click', () => {
const selectedUrls = Array.from(modal.querySelectorAll('input[type="checkbox"]:checked')).map(checkbox => checkbox.value);
selectedUrls.forEach(url => window.open(url, '_blank'));
let closeButton = document.createElement('button');
closeButton.innerText = 'X';
closeButton.style.position = 'absolute';
closeButton.style.right = '10px';
closeButton.style.top = '10px';
closeButton.addEventListener('click', function() {
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
});
let closeButton = document.createElement('button');
closeButton.innerText = 'X';
closeButton.style.position = 'absolute';
closeButton.style.right = '10px';
closeButton.style.top = '10px';
closeButton.addEventListener('click', function() {
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
let cancelButton = document.createElement('button');
cancelButton.innerText = 'Cancel';
cancelButton.addEventListener('click', function() {
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
let cancelButton = document.createElement('button');
cancelButton.innerText = 'Cancel';
cancelButton.addEventListener('click', function() {
document.body.removeChild(modal);
document.body.removeChild(overlay);
});
let buttonContainer = document.createElement('div');
buttonContainer.style.width = '100%';
buttonContainer.style.display = 'flex';
buttonContainer.style.justifyContent = 'center';
buttonContainer.style.marginTop = '20px';
let buttonContainer = document.createElement('div');
buttonContainer.style.width = '100%';
buttonContainer.style.display = 'flex';
buttonContainer.style.justifyContent = 'center';
buttonContainer.style.marginTop = '20px';
buttonContainer.appendChild(startButton);
buttonContainer.appendChild(cancelButton);
buttonContainer.appendChild(startButton);
buttonContainer.appendChild(cancelButton);
modal.appendChild(closeButton);
modal.appendChild(buttonContainer);
modal.appendChild(closeButton);
modal.appendChild(buttonContainer);
let overlay = document.createElement('div');
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
overlay.style.zIndex = '998';
let overlay = document.createElement('div');
overlay.style.position = 'fixed';
overlay.style.top = '0';
overlay.style.left = '0';
overlay.style.width = '100%';
overlay.style.height = '100%';
overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.5)';
overlay.style.zIndex = '998';
document.body.appendChild(overlay);
document.body.appendChild(modal);
})();
document.body.appendChild(overlay);
document.body.appendChild(modal);