GenFBDD / app /static.py
libokj's picture
Bug fixes
642d891
raw
history blame
21 kB
CSS = """
/* HTML: <div class="loader"></div> */
.loader {
width: 60px;
aspect-ratio: 1.154;
color: #25b09b;
display: grid;
animation: l38-0 6s infinite linear;
}
.loader:before,
.loader:after {
content: "";
grid-area: 1/1;
}
.loader:before {
clip-path: polygon(25% 0,75% 0,100% 50%,75% 100%,25% 100%,0 50%);
background: conic-gradient(from -30deg,#0000 60deg,currentColor 0);
}
.loader:after {
background: conic-gradient(from -30deg,currentColor 60deg,#0000 0);
animation: l38 0.5s infinite alternate;
}
@keyframes l38-0 {
0%,16.66% {transform: rotate(0deg)}
16.67%,33.33% {transform: rotate(60deg)}
33.34%,50% {transform: rotate(120deg)}
50.1%,66.66% {transform: rotate(180deg)}
66.67%,83.33% {transform: rotate(240deg)}
83.34%,100% {transform: rotate(300deg)}
}
@keyframes l38 {
100% {transform: translateY(-20px)}
}
.loader.first-frame {
animation: none; /* Stop the main animation */
}
.loader.first-frame:before {
transform: rotate(0deg); /* Explicitly set the rotation to the first frame */
}
.loader.first-frame:after {
animation: none; /* Stop the after animation */
transform: translateY(0px); /*reset the translate Y*/
}
.help-tip {
position: absolute;
display: inline-block;
top: 16px;
right: 0px;
text-align: center;
border-radius: 40%;
/* border: 2px solid darkred; background-color: #8B0000;*/
width: 24px;
height: 24px;
font-size: 16px;
line-height: 26px;
cursor: default;
transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
z-index: 100 !important;
}
.help-tip:hover {
cursor: pointer;
/*background-color: #ccc;*/
}
.help-tip:before {
content: '?';
font-weight: 700;
color: #8B0000;
z-index: 100 !important;
}
.help-tip p {
visibility: hidden;
opacity: 0;
text-align: left;
background-color: #EFDDE3;
padding: 20px;
width: 300px;
position: absolute;
border-radius: 4px;
right: -4px;
color: #494F5A;
font-size: 13px;
line-height: normal;
transform: scale(0.7);
transform-origin: 100% 0%;
transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
z-index: 100;
}
.help-tip:hover p {
cursor: default;
visibility: visible;
opacity: 1;
transform: scale(1.0);
}
.help-tip p:before {
position: absolute;
content: '';
width: 0;
height: 0;
border: 6px solid transparent;
border-bottom-color: #EFDDE3;
right: 10px;
top: -12px;
}
.help-tip p:after {
width: 100%;
height: 40px;
content: '';
position: absolute;
top: -5px;
left: 0;
z-index: 101;
}
.upload_button {
background-color: #008000;
}
.absolute {
position: absolute;
}
.example {
padding: 0;
background: none;
border: none;
text-decoration: underline;
box-shadow: none;
text-align: left !important;
display: inline-block !important;
}
footer {
visibility: hidden
}
.html-container {
padding: 0px;
}
.block .table-wrap {
width: 100% !important;
aspect-ratio: 1.618 / 1 !important;
height: auto !important;
}
.mol-container {
width: 100%;
aspect-ratio: 1.618 / 1;
}
.mol-container > canvas {
position: relative ! important;
}
.gr-btn-grp {
display: flex;
flex-wrap: wrap;
gap: var(--layout-gap);
width: var(--size-full);
position: relative
border-radius: 0
border-radius: var(--container-radius);
background: var(--background-fill-secondary);
padding: var(--size-2)
align-items: stretch
}
.gr-btn-grp > button {
flex: 1 1 0;
display: inline-flex;
justify-content: center;
align-items: center;
transition: var(--button-transition);
padding: var(--size-0-5) var(--size-2);
text-align: center;
border: var(--button-border-width) solid var(--button-secondary-border-color);
background: var(--button-secondary-background-fill);
color: var(--button-secondary-text-color);
box-shadow: var(--button-secondary-shadow)
border-radius: var(--button-large-radius);
padding: calc(var(--button-large-padding) - 1px);
font-family: monospace;
font-weight: var(--button-large-text-weight);
font-size: calc(var(--button-large-text-size) - 1px);
}
"""
IFRAME_TEMPLATE = """
<iframe style="width: 100%; aspect-ratio: {aspect_ratio}; overflow: visible; border: none;" scrolling="no"
frameborder="0" allow="display-capture; encrypted-media;"
sandbox="allow-modals allow-forms allow-scripts allow-same-origin allow-popups
allow-top-navigation-by-user-activation allow-downloads" srcdoc='{srcdoc}'></iframe>
"""
SETUP_JS = """
() => {
const scripts = [
"https://code.jquery.com/jquery-3.7.1.min.js",
"https://3dmol.org/build/3Dmol.js"
];
scripts.forEach((script) => {
const scriptElement = document.createElement("script");
scriptElement.src = script;
scriptElement.async = true;
document.head.appendChild(scriptElement);
});
viewerConfig = { backgroundColor: "white" };
ligandStyle = { stick: { colorscheme: "greenCarbon" } };
proteinStyle = { cartoon: { colorscheme: "Jmol" } };
pocketStyle = { clicksphere: { radius: 1.5 } };
pocketSurfaceStyle = { opacity: 0.854, color: "aquamarine" };
selectedElements = {
"atoms": [],
"ligand": {name: null, resn: null, chain: null, resi: null},
"pocket": {name: null, id: null}
}
}
"""
# function handleMessage(event) {
# if (event.data.name == "atom_selection") {
# console.log("New message: ", event.data)
# let atom = event.data.data["atom"];
# let add = event.data.data["add"];
# console.log("add: ", add, " atom: ", atom);
# window.selected_elements["atom_selection"][atom] = add;
# }
# if (event.data.name == "ligand_selection") {
# console.log("New message: ", event.data)
# let residue_info = event.data.data["residue"];
# let add = event.data.data["add"];
# residue = residue_info.resi + ":" + residue_info.resn + ":" + residue_info.chain;
# console.log("add: ", add, " residue: ", residue);
# window.selected_elements["ligand_selection"][residue] = add;
# }
# if (event.data.name == "pocket_selection") {
# let pocket = event.data.data["pocket"];
# console.log("add: ", add, " pocket: ", pocket);
# window.selected_elements["pocket_selection"][pocket] = add;
# }
# }
#
# window.addEventListener("message", handleMessage);
# console.log("Listener Added");
# console.log(window.selected_elements);
RETURN_LIGAND_SELECTION_JS = """
(prot_file, selected_ligand) => {
const selectedElements = window.selected_elements || {}; // Handle potential undefined
if ("ligand_selection" in selectedElements) {
ligandElements = selectedElements["ligand_selection"];
for (const [residue, add] of Object.entries(ligandElements)) {
if (add) {
selectedLigand = residue
console.log("Selecting ligand ", selectedLigand);
}
}
}
console.log("Finished parsing selection.");
window.selected_elements["ligand_selection"] = {}
return [prot_file, selectedLigand];
}
"""
RETURN_SELECTION = """
(selected_ligand, selected_pocket) => {
selectedAtoms = selectedElements.atoms;
selectedLigand = selectedElements.ligand.name;
console.log("Selected Ligand:", selectedLigand);
selectedPocket = selectedElements.pocket.name;
console.log("Selected Pocket:", selectedPocket);
return [selectedLigand, selectedPocket];
}
"""
RETURN_POCKET_SELECTION_JS = """
(prot_file, selected_pocket) => {
const selectedElements = window.selected_elements || {}; // Handle potential undefined
if ("pocket_selection" in selectedElements) {
pocketElements = selectedElements["pocket_selection"];
for (const [pocket, add] of Object.entries(pocketElements)) {
if (add) {
console.log("Selecting pocket ", pocket);
selected_pocket = pocket;
}
}
}
console.log("Finished parsing selection.");
window.selected_elements["pocket_selection"] = {}
return [prot_file, selected_pocket];
}
"""
RETURN_ATOM_SELECTION_JS = """
(input_file, selected_atoms) => {
let selectedAtoms = [];
if ("atom_selection" in selectedElements) {
atomElements = selectedElements["atom_selection"];
for (const [atom, add] of Object.entries(atomElements)) {
if (add) {
console.log("Adding atom ", atom);
selectedAtoms.push(String(atom));
}
}
}
const selectedAtomsString = selectedAtoms.join(",");
console.log("Finished parsing selection.");
window.selected_elements["atom_selection"] = {}
return [input_file, selectedAtomsString];
}
"""
CREATE_INPUT_MOL_VIEW = """
(mol_file, view_html) => {
try {
let viewer;
// Get element id of the view_html string with error handling
const idMatch = view_html.match(/id="(\w+)"/);
if (!idMatch || !idMatch[1]) {
console.error("Invalid view_html: No ID found.");
return; // Exit the function if no ID is found
}
const element_id = idMatch[1];
const element = document.getElementById(element_id);
if (!element.querySelector('canvas')) {
viewer = $3Dmol.createViewer(element, viewerConfig);
} else {
viewer = element.querySelector('canvas')._3dmol_viewer;
viewer.clear();
selectedElements = {
"atoms": [],
"ligand": {name: null, resn: null, chain: null, resi: null},
"pocket": {name: null, id: null}
}
}
if (mol_file == null) {
return;
}
$.get(mol_file.url, function(molContent) {
fmt = mol_file.path.split('.').pop();
model = viewer.addModel(molContent, fmt);
model.setStyle({ hetflag: false }, proteinStyle);
model.setStyle({ hetflag: true }, ligandStyle);
selectedLigand = selectedElements.ligand.name;
model.setClickable(
{ hetflag: true, byres: true },
true,
function (_atom, _viewer, _event, _container) {
let selectedLigand = selectedElements.ligand;
let currentLigand = { resn: _atom.resn, chain: _atom.chain, resi: _atom.resi };
currentLigand.name = currentLigand.resi + ":" + currentLigand.resn + ":" + currentLigand.chain;
if (selectedLigand.name == currentLigand.name) {
// Deselect ligand
_viewer.setStyle(
{ resn: currentLigand.resn, chain: currentLigand.chain, resi: currentLigand.resi },
ligandStyle
);
console.log("Deselected Ligand:", currentLigand);
selectedElements.ligand = {name: null, resn: null, chain: null, resi: null};
} else {
// Select ligand and deselect previous
if (selectedLigand.name) {
_viewer.setStyle(
{ resn: selectedLigand.resn, chain: selectedLigand.chain, resi: selectedLigand.resi },
ligandStyle
);
}
selectedElements.ligand = currentLigand;
_viewer.setStyle(
{ resn: currentLigand.resn, chain: currentLigand.chain, resi: currentLigand.resi },
{ stick: { color: "red", radius: "0.4"} }
);
console.log("Selected Ligand:", currentLigand);
}
_viewer.render();
}
);
viewer.zoomTo();
viewer.render();
}).fail(function(error) {
console.error("Error loading molecule:", error);
});
} catch (error) {
console.error("An error occurred:", error);
}
}
"""
UPDATE_MOL_VIEW = """
(mol_files, view_html) => {
try {
let viewer;
// Get element id of the view_html string with error handling
const idMatch = view_html.match(/id="(\w+)"/);
if (!idMatch || !idMatch[1]) {
console.error("Invalid view_html: No ID found.");
return; // Exit the function if no ID is found
}
const element_id = idMatch[1];
const element = document.getElementById(element_id);
if (element.querySelector('canvas')) {
viewer = element.querySelector('canvas')._3dmol_viewer;
for (let i = 1; i < viewer.models.length; i++) {
viewer.removeModel(i);
}
viewer.removeAllSurfaces();
} else {
console.error("Invalid view_html: No canvas found.");
return;
}
for (var mol_file of mol_files) {
// Get the file format
const fmt = mol_file.orig_name.split('.').pop();
const filename = mol_file.orig_name;
console.log("File:", mol_file.orig_name, "Format:", fmt); // Check values
$.get(mol_file.url, function(molContent) {
model = viewer.addModel(molContent, fmt);
if (fmt == "pqr") {
model.setStyle(pocketStyle);
surface = viewer.addSurface('VDW', pocketSurfaceStyle, {model: model}, {model: model});
const surface_id = surface.surfid;
const pocket_name = filename.replace("_vert.pqr", "");
model.setClickable(
{ byres: true },
true,
function (_atom, _viewer, _event, _container) {
let selectedPocket = selectedElements.pocket;
let currentPocket = { name: pocket_name, id: _atom.model, surface: surface_id };
if (currentPocket.name == selectedPocket.name) {
// Deselect pocket
// _viewer.setStyle({model: currentPocket.id}, pocketStyle);
_viewer.setSurfaceMaterialStyle(currentPocket.surface, pocketSurfaceStyle);
console.log("Deselected Pocket:", currentPocket);
selectedElements.pocket = {name: null, id: null};
} else {
// Select pocket and deselect previous
if (selectedPocket.name) {
console.log("Deselected Pocket:", selectedPocket);
//_viewer.setStyle({model: selectedPocket.id}, pocketStyle);
_viewer.setSurfaceMaterialStyle(selectedPocket.surface, pocketSurfaceStyle);
}
selectedElements.pocket = currentPocket;
//_viewer.setStyle({model: currentPocket.id}, {sphere: {color: "red", opacity: 0.944} });
_viewer.setSurfaceMaterialStyle(currentPocket.surface, { opacity: 0.944, color: "red" });
console.log("Selected Pocket:", currentPocket);
}
_viewer.render();
}
);
} else {
model.setStyle({ hetflag: false }, proteinStyle);
model.setStyle({ hetflag: true }, ligandStyle);
}
viewer.render();
}).fail(function(error) {
console.error("Error loading molecule:", error);
})
}
console.log("Rendering protein view.");
viewer.zoomTo();
viewer.render();
selectedElements = {
"atoms": [],
"ligand": {name: null, resn: null, chain: null, resi: null},
"pocket": {name: null, id: null}
}
} catch (error) {
console.error("An error occurred:", error);
}
}
"""
CREATE_OUTPUT_MOL_VIEW = """
(mol_file, view_html) => {
try {
let viewer;
const idMatch = view_html.match(/id="(\w+)"/);
if (!idMatch || !idMatch[1]) {
console.error("Invalid view_html: No ID found.");
return;
}
const element_id = idMatch[1];
const element = document.getElementById(element_id);
fmt = mol_file.path.split('.').pop();
$.get(mol_file.url, function(molContent) {
if (!element.querySelector('canvas')) {
viewer = $3Dmol.createViewer(element, viewerConfig);
} else {
viewer = element.querySelector('canvas')._3dmol_viewer;
viewer.clear();
}
model = viewer.addModel(molContent, fmt);
model.setStyle({ hetflag: false }, proteinStyle);
model.setStyle({ hetflag: true }, ligandStyle);
viewer.zoomTo();
viewer.render();
let container = element.parentElement.querySelector(".gr-btn-grp");
if (!container) {
container = document.createElement("div");
container.classList.add("gr-btn-grp");
element.parentElement.appendChild(container);
}
// Molecule Button
let toggleMoleculeButton = container.querySelector("#toggleMoleculeButton");
if (!toggleMoleculeButton) {
toggleMoleculeButton = document.createElement("button");
toggleMoleculeButton.id = "toggleMoleculeButton"; // Add an ID
toggleMoleculeButton.textContent = "Hide Generated Molecule";
let moleculeIsHidden = false;
toggleMoleculeButton.onclick = function() {
if (viewer.models.length === 2) {
moleculeIsHidden = !moleculeIsHidden;
viewer.addStyle({model: 1}, {stick: {hidden: moleculeIsHidden} });
toggleMoleculeButton.textContent = moleculeIsHidden ? "Show Generated Molecule" : "Hide Generated Molecule";
viewer.render();
}
};
container.appendChild(toggleMoleculeButton);
}
// Ligand Button
const ligandButtonId = "toggleLigandButton";
let toggleLigandButton = container.querySelector("#" + ligandButtonId);
// Check for ligands and existing button
const hasLigands = viewer.getAtomsFromSel({model: 0, hetflag : true}).length > 0;
if (hasLigands && !toggleLigandButton) {
// Create button if ligands exist and it doesn't exist yet
toggleLigandButton = document.createElement("button");
toggleLigandButton.id = ligandButtonId;
toggleLigandButton.textContent = "Hide Co-Crystallized Ligand";
let ligandIsHidden = false;
toggleLigandButton.onclick = function() {
ligandIsHidden = !ligandIsHidden;
viewer.addStyle({model: 0, hetflag: true}, {stick: {hidden: ligandIsHidden} });
toggleLigandButton.textContent = ligandIsHidden ? "Show Co-Crystallized Ligand" : "Hide Co-Crystallized Ligand";
viewer.render();
};
container.appendChild(toggleLigandButton);
} else if (!hasLigands && toggleLigandButton) {
// Remove button if no ligands exist and it already exists
container.removeChild(toggleLigandButton);
}
// Protein Button
let toggleProteinButton = container.querySelector("#toggleProteinButton");
if (!toggleProteinButton) {
toggleProteinButton = document.createElement("button");
toggleProteinButton.id = "toggleProteinButton";
toggleProteinButton.textContent = "Hide Target Protein";
let proteinIsHidden = false;
toggleProteinButton.onclick = function() {
proteinIsHidden = !proteinIsHidden;
viewer.addStyle({model: 0, hetflag: false}, {cartoon: {hidden: proteinIsHidden} });
toggleProteinButton.textContent = proteinIsHidden ? "Show Target Protein" : "Hide Target Protein";
viewer.render();
};
container.appendChild(toggleProteinButton);
}
}).fail(function(error) {
console.error("Error loading molecule:", error);
});
} catch (error) {
console.error("An error occurred:", error);
}
}
"""