/////////////////////////////////////////
// Functions to keep after refactoring //
/////////////////////////////////////////


var syncKetcherLock = 0;
var ignoreKetcherUpdates = 0
var ignoreTextFieldUpdates = 0
// The SMILES generated by Ketcher might look different than the one inserted
// however we need this for internal comparison to check whether the SMILES taken
// from the TextInput generates the same smiles.
var SMILES = "";

// FIXME: marked for removal
// function syncTextInputToKetcher(textInputId, ketcherId) {
//     var ketcher = getKetcher(ketcherId);
//     var textInputSMILES = $('#' + textInputId).val();

//     data = {
//         "struct": textInputSMILES,
//         "output_format": "chemical/x-mdl-molfile",
//         "options": {
//             "smart-layout": true,
//             "ignore-stereochemistry-errors": true,
//             "mass-skip-error-on-pseudoatoms": false,
//             "gross-formula-add-rsites": true
//         }
//     }

//     ketcher.server.layout(data).then(
//         function(response) {
//             if(response.struct != '') {
//                 console.log("Writing " + textInputSMILES + " to Ketcher");
//                 ketcher.setMolecule(textInputSMILES);

//                 // Wait for ketcher to accept the change and set global SMILES
//                 setTimeout(function() {
//                     SMILES = ketcher.getSmiles();
//                 }, 250);
//             }
//         }
//     ).catch(
//         function(res) {
//             console.log("Promise failed" + res);
//         }
//     );
// }

// FIXME: marked for removal
// function syncKetcherToTextInput(ketcherId, textInputId) {
//     // Obtain values
//     var ketcher = getKetcher(ketcherId);
//     // Get the SMILES of the molecule currently drawn in Ketcher
//     var tempKetcherSMILES;
//     try {
//         tempKetcherSMILES = ketcher.getSmiles();
//     } catch(err) {
//         console.log(err);
//         return;
//     }

//     // compare to SMILES from global scope
//     if(SMILES == tempKetcherSMILES) {
//         // There was no change originating from TextInput
//         return
//     } else {
//         SMILES = tempKetcherSMILES;
//         $("#" + textInputId).val(SMILES);
//     }
// }

// FIXME: marked for removal
// function syncKetcherAndTextInput(origin, ketcherId, textInputId) {
//     // check if function is "locked"
//     if(origin == 'ketcher') {
//         // Early exit - no op
//         if (ignoreKetcherUpdates == 1) {
//             return;
//         }
//         // Lock updates triggered by textInput
//         ignoreTextFieldUpdates = 1;

//         // Do the sync
//         syncKetcherToTextInput(ketcherId, textInputId);

//         ignoreTextFieldUpdates = 0;
//     } else {
//         // Early exit - no op
//         if(ignoreTextFieldUpdates == 1) {
//             return;
//         }
//         ignoreKetcherUpdates = 1;

//         // Do the sync
//         syncTextInputToKetcher(textInputId, ketcherId);

//         ignoreKetcherUpdates = 0;
//     }
// }

// Returns the ketcher object usually located in an iframe
function getKetcher(idToUse){
    if (idToUse === undefined) {
        console.log("getKetcher() called without id!");
        idToUse = 'ifKetcher';
    }
    var ketcherFrame = document.getElementById(idToUse);

    if ('contentDocument' in ketcherFrame) {
        return ketcherFrame.contentWindow.ketcher;
    } else { // IE7
        return document.frames[idToUse].window.ketcher;
    }
}

// FIXME: marked for removal
// function enterKeyPressed(event){
//     // 13 means return/enter
//     if (event.which == 13 || event.keyCode == 13) {
//         return false;
//     }
//     return true
// };

// FIXME: marked for removal
// Function to attach an RSS feed available at feedUrl and attaches it to attachElement
// async function loadRSSFeed(attachElement, feedUrl) {
//     try {
//         const response = await fetch(feedUrl, {
//             headers: {
//                 'Accept': 'application/rss+xml'
//             }
//         });
//         const text = await response.text();
//         const parser = new DOMParser();
//         const data = parser.parseFromString(text, 'application/xml');

//         const items = data.querySelectorAll('item');
//         items.forEach(item => {
//             const link = item.querySelector('link')?.textContent || '';
//             const title = item.querySelector('title')?.textContent || '';
//             const pubDate = item.querySelector('pubDate')?.textContent || '';
//             const description = item.querySelector('description')?.textContent || '';

//             document.getElementById(attachElement).innerHTML +=
//                 '<li class="list-group-item">' +
//                 '<h4 class="list-group-item-heading">' +
//                 '<a target="blank" href="' + link + '">' +
//                 title +
//                 '</a></h4><h6>' +
//                 pubDate +
//                 '</h6><p>' +
//                 description +
//                 '</p></li>';
//         });
//     } catch (error) {
//         console.error('Error loading RSS feed:', error);
//     }
// }

// FIXME: marked for removal
// function hasValue(id) {
//     var element = document.getElementById(id);
//     if(element.value === ""
//         || element.value === undefined
//         || element.value === null
//         || element.value === "undefined"){
//         return false;
//     }
//     return true;
// }

// FIXME: marked for removal
// async function beforePredict(){
//     // TODO make it a parameter
//     if(!hasValue("smilesinput")) {
//         return;
//     }

//     const smilesInput = document.getElementById('smilesinput');
//     const encodedSMILES = encodeURIComponent(smilesInput.value);
//     // TODO Fix via templating to set host
//     const url = "/pathway?rootNode="+ encodedSMILES;

//     try {
//         const response = await fetch(url);
//         const result = await response.json();

//         // If something is found the returned dict contains the key "pathway" if not it contains "object"
//         if(result.pathway){
//             // TODO set as param
//             attachObjectsAsList("foundPathways", result.pathway);
//         } else {
//             document.getElementById("index-form").submit();
//         }
//     } catch (error) {
//         console.error('Error in beforePredict:', error);
//     }
// }

// FIXME: marked for removal
// function attachObjectsAsList(elementId, objects){
//     var content ='<ul class="list-group">';
//     var foundone = false;

//     for (var obj in objects) {
//         if(objects[obj].reviewStatus == "reviewed"){
//             content += '<a class="list-group-item" href="' + objects[obj].id + '">';
//             content += objects[obj].name;
//             content += '</a>';
//             foundone = true;
//         }
//     }

//     content += '</ul>';
//     console.log(foundone);
//     if(foundone){
//         document.getElementById("foundPathways").innerHTML += content;
//         // Show the modal using native dialog API
//         const modal = document.getElementById("foundMatching");
//         if (modal && modal.showModal) {
//             modal.showModal();
//         }
//     } else {
//         document.getElementById("index-form").submit();
//     }
// }

// FIXME: marked for removal
// class Setting {
//   constructor(nameInputId, selectedPackagesId, relativeReasoningSelectId, cutoffInputId, evaluationTypeSelectId,
//               availableTSSelectId, formsId, tableId, summaryTableId) {
//     this.nameInputId = nameInputId;
//     this.selectedPackagesId = selectedPackagesId;
//     this.relativeReasoningSelectId = relativeReasoningSelectId;
//     this.cutoffInputId = cutoffInputId;
//     this.evaluationTypeSelectId = evaluationTypeSelectId;
//     this.availableTSSelectId = availableTSSelectId;
//     this.formsId = formsId;
//     this.tableId = tableId;
//     this.summaryTableId = summaryTableId;

//     // General settings
//     this.name = null;
//     this.selectedPackages = [];

//     // Relative Reasoning related
//     this.selectedRelativeReasoning = null;
//     this.cutoff = null;
//     this.evaluationType = null;

//     // parameters such as { "lowPH": 7, "highPH": 8 }
//     this.tsParams = {};
//   }

// FIXME: marked for removal
//   extractName() {
//     var tempName = $('#' + this.nameInputId).val()
//     if (tempName == '') {
//         console.log("Name was empty...");
//         return;
//     }
//     this.name = tempName;
//   }

//   extractSelectedPackages() {
//     var selPacks = $("#" + this.selectedPackagesId + " :selected");
//     var ref = this;
//     ref.selectedPackages = [];
//     selPacks.each(function () {
//       var obj = {}
//       obj['id'] = this.value;
//       obj['name'] = this.text;
//       ref.selectedPackages.push(obj);
//     });
//   }

//   extractRelativeReasoning() {
//     var tempRR = $('#' + this.relativeReasoningSelectId + " :selected").val()
//     if (tempRR == '') {
//         console.log("RR was empty...");
//         return;
//     }
//     var obj = {}
//     obj['id'] = $('#' + this.relativeReasoningSelectId + " :selected").val()
//     obj['name'] = $('#' + this.relativeReasoningSelectId + " :selected").text()
//     this.selectedRelativeReasoning = obj;
//   }

//   extractCutoff() {
//     var tempCutoff = $('#' + this.cutoffInputId).val()
//     if (tempCutoff == '') {
//         console.log("Cutoff was empty...");
//         return;
//     }
//     this.cutoff = tempCutoff;
//   }

//   extractEvaluationType() {
//     var tempEvaluationType = $('#' + this.evaluationTypeSelectId).val()
//     if (tempEvaluationType == '') {
//         console.log("EvaluationType was empty...");
//         return;
//     }
//     this.evaluationType = tempEvaluationType;
//   }

//   addTruncator() {
//     // triggered by "Add"
//     // will extract values and afterwards updates table + summary
//     var type = $("#" + this.availableTSSelectId + " :selected").val();
//     var text = $("#" + this.availableTSSelectId + " :selected").text();
//     var form = $("#" + type + "_form > :input")

//     // flag to check whether at least one input had a valid value
//     var addedValue = false;

//     // reference being used in each
//     var ref = this;

//     form.each(function() {
//         if(this.value == "" || this.value === "undefined"){
//             console.log(this);
//             console.log("Skipping " + this.name);
//         } else {
//             var obj = {}
//             obj[this.name] = this.value;
//             obj['text'] = text;
//             ref.tsParams[type] = obj
//         }
//     });

//     this.updateTable();
//     this.updateSummaryTable();
//   }

//   removeTruncator(rowId) {
//     var summary = rowId.startsWith("sum") ? true : false;
//     // plain key
//     var key = rowId.replace(summary ? "sum" : "trunc", "").replace("row", "");

//     console.log("Removing " + key);

//     // remove the rows
//     $("#trunc"+ key + "row").remove();
//     if($("#sum"+ key + "row").length > 0) {
//         $("#sum"+ key + "row").remove();
//     }

//     delete this.tsParams[key];
//   }

//   updateTable() {
//     // remove all children
//     $('#'+this.tableId + "Body").empty()

//     var innerHTML = "<tr>" +
//                       "<td>Name</td>" +
//                       "<td>Value</td>" +
//                       "<td width='10%'>Action</td>" +
//                     "</tr>";

//     for (var x in this.tsParams) {
//       var val = "";
//       for (var y in this.tsParams[x]){
//         if (y == 'text') {
//             continue;
//         }
//         val += this.tsParams[x][y]

//       }
//       innerHTML += "<tr id='trunc" + x + "row'>" +
//                      "<td>" + this.tsParams[x]['text'] + "</td>" +
//                      "<td>" + val + "</td>" +
//                      "<td width='10%'>"+
//                        "<button type='button' id='" + x + "button' class='form-control' onclick='s.removeTruncator(\"trunc" + x + "row\")'>Remove</button>" +
//                      "</td>" +
//                    "</tr>";
//     }

//     $('#'+this.tableId + "Body").append(innerHTML);
//   }

//   packageRows() {
//     var res = '';
//     for(var p in this.selectedPackages) {
//         var obj = this.selectedPackages[p];
//         res += "<tr>" +
//                  "<td>Package</td>" +
//                  "<td>" + obj['name'] + "</td>" +
//                  "<td width='10%'>" +
//                    // "<button type='button' id='relativereasoningbutton' class='form-control' onclick='s.removeTruncator(\"Relative Reasoning\")'>Remove</button>" +
//                  "</td>" +
//                "</tr>";
//     }
//     return res;
//   }

//   modelRow() {
//     if(this.selectedRelativeReasoning == null) {
//       return '';
//     }
//     return "<tr>" +
//              "<td>Relative Reasoning</td>" +
//              "<td>" + this.selectedRelativeReasoning['name'] + " " + (this.evaluationType == "singleGen" ? "SG" : "MG") + " with t=" + this.cutoff + " </td>" +
//              "<td width='10%'>" +
//                // "<button type='button' id='relativereasoningbutton' class='form-control' onclick='s.removeTruncator(\"Relative Reasoning\")'>Remove</button>" +
//              "</td>" +
//            "</tr>";
//   }

//   updateSummaryTable() {
//     // remove all children
//     $('#'+this.summaryTableId + "Body").empty()

//     var innerHTML = "<tr>" +
//                       "<td>Name</td>" +
//                       "<td>Value</td>" +
//                       "<td width='10%'>Action</td>" +
//                     "</tr>";

//     innerHTML += this.packageRows();
//     innerHTML += this.modelRow();

//     // var innerHTML = ''
//     for (var x in this.tsParams) {
//       var val = "";
//       for (var y in this.tsParams[x]){
//         if (y == 'text') {
//             continue;
//         }
//         val += this.tsParams[x][y]

//       }
//       innerHTML += "<tr id='sum" + x + "row'>" +
//                      "<td>" + this.tsParams[x]['text'] + "</td>" +
//                      "<td>" + val + "</td>" +
//                      "<td width='10%'>"+
//                        "<button type='button' id='" + x + "button' class='form-control' onclick='s.removeTruncator(\"sum" + x + "row\")'>Remove</button>" +
//                      "</td>" +
//                    "</tr>";
//     }

//     $('#'+this.summaryTableId + "Body").append(innerHTML);
//   }


// }

// TODO

function queryResultToTable(appendId, result) {
    const container = document.getElementById(appendId);
    container.innerHTML = '';
    var table = '<table class="table">' +
                   '<thead class="thead-dark">' +
                     '<tr>';

    var header = '';
    for (var r in result['result']) {
        var keys = Object.keys(result['result'][r]);
        for (var k in keys) {
            header += '<th>' + keys[k] + '</th>';
        }
        break;
    }

    table += header;
    table += '</tr>';
    table += '</thead>';
    table += '<tbody>';

    var body = '';
    for (var r in result['result']) {
        body += '<tr>';
        for (var k in result['result'][r]) {
            body += '<td>' + result['result'][r][k] + '</td>';
        }
        body += '</tr>';
    }

    table += body;
    table += '</tbody>';
    table += '</table>';

    container.innerHTML = table;
}

function showLoadingSpinner(attachOb) {
    // Benzene ring spinner - hexagon with rotating double bonds
    const spinnerHtml = `<div class="loading-spinner">
        <svg viewBox="0 0 58 66">
            <!-- Outer hexagon (static) -->
            <path class="hexagon" d="M1 49v-32l28-16 28 16v32l-28 16z" fill="none" stroke="currentColor"/>
            <!-- Inner double bonds (rotating) -->
            <g class="double-bonds">
                <path d="M52.7 19.5 L29 6" fill="none" stroke="currentColor"/>
                <path d="M29 60 L52.7 46.5" fill="none" stroke="currentColor"/>
                <path d="M5.5 19.5 v27" fill="none" stroke="currentColor"/>
            </g>
        </svg>
    </div>`;

    // Handle both ID selectors and DOM elements
    let element;
    if (typeof attachOb === 'string') {
        element = attachOb.startsWith('#')
            ? document.querySelector(attachOb)
            : document.getElementById(attachOb);
    } else {
        element = attachOb;
    }

    if (element) {
        element.innerHTML = spinnerHtml;
    }
}

// Keep old function name for backwards compatibility
function makeLoadingGif(attachOb) {
    showLoadingSpinner(attachOb);
}

// FIXME: marked for removal
// function cleanIdName(idName) {
//     return idName.replace(/[ \-()]/g, "")
// }

// FIXME: marked for removal
// function makeAccordionHead(accordionId, accordionTitle, reviewStatus) {
//     return "<div class='panel-group' id='" + accordionId + "'>"
//             + "<div class='panel panel-default'>"
//             + "<div class='panel-heading' id='headingPanel' style='font-size:2rem;height: 46px'>"
//             + accordionTitle + reviewStatus
//             + "</div><div id='descDiv'></div>"
//             + "</div>";
// }

// FIXME: marked for removal
// function makeAccordionPanel(accordionId, panelName, panelContent, collapsed, id) {
//     if(panelContent == "" || panelContent == "no description") {
//         return "";
//     }
//     if(collapsed == true) {
//         collapsed = "in";
//     } else {
//         collapsed = "";
//     }
//     var panelId =  typeof id === "undefined" ? cleanIdName(panelName) : id;
//     return "<div class='panel panel-default panel-heading list-group-item' style='background-color:silver'>"
//     + "<h4 class='panel-title'>"
//     + "<a id=" + panelId + "Link" + " data-toggle='collapse' data-parent='#" + accordionId + "' href='#" + panelId + "'>"
//     + panelName
//     + "</a>"
//     + "</h4>"
//     + "</div>"
//     + "<div id='" + panelId + "' class='panel-collapse collapse " + collapsed + "'>"
//     + "<div class='panel-body list-group-item' id='"+panelId+"Content'>"
//     + panelContent
//     + "</div>"
//     + "</div>";
// }

// FIXME: marked for removal
// async function fillPRCurve(modelUri, onclick){
//     if (modelUri == '') {
//         return;
//     }

//     // clear div
//     const plotDiv = document.getElementById('plotDiv');
//     plotDiv.innerHTML = '';

//     // for the time being add animation
//     makeLoadingGif('#plotDiv');

//     try {
//         const response = await fetch(modelUri + "?prcurve");
//         const result = await response.json();

//         // remove loading gif
//         plotDiv.innerHTML = '';

//         // check if model is in a proper state
//         if(result.hasOwnProperty('error')){
//             var content = '<div>'+result.error+' \nYou can check the model <a href="' + modelUri + '">here</a>. </div>';
//             plotDiv.innerHTML += content;
//             return
//         }

//         var chartPanel = '<div id="chart" class="panel-group"></div>';
//         plotDiv.innerHTML += chartPanel;

//         // Labels
//         var x = ['Recall'];
//         var y = ['Precision'];
//         var thres = ['threshold'];

//         // Compare function for the given array
//         function compare(a, b) {
//             if (a.threshold < b.threshold)
//                 return -1;
//             else if (a.threshold > b.threshold)
//                 return 1;
//             else
//                 return 0;
//         }

//         // gets the index for a certain value
//         function getIndexForValue(data, val, val_name) {
//             for(var idx in data) {
//                 if(data[idx][val_name] == val) {
//                     return idx;
//                 }
//             }
//             return -1;
//         }

//         var data = result.prdata;
//         var dataLength = Object.keys(data).length;
//         data.sort(compare);

//         // collect data in 3 individual arrays
//         for (var idx in data) {
//             var d = data[idx];
//             x.push(d.recall);
//             y.push(d.precision);
//             thres.push(d.threshold);
//         }

//         // generate the actual chart with values collected above
//         var chart = c3.generate({
//             bindto: '#chart',
//             data: {
//                 onclick: function (d, e) {
//                     var idx = d.index;
//                     var thresh = data[dataLength-idx-1].threshold;

//                     onclick(thresh)

//                 },
//                 x: 'Recall',
//                 y: 'Precision',
//                 columns: [
//                     x,
//                     y,
//                     //thres
//                 ]
//             },
//             size: {
//                 height: 400, // TODO: Make variable to current modal width
//                 width: 480
//             },
//             axis: {
//                 x: {
//                     max: 1,
//                     min: 0,
//                     label: 'Recall',
//                     padding: 0,
//                     tick: {
//                         fit: true,
//                         values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
//                     }
//                 },
//                 y: {
//                     max: 1,
//                     min: 0,
//                     label: 'Precision',
//                     padding: 0,
//                     tick: {
//                         fit: true,
//                         values: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
//                     }
//                 }
//             },
//             point: {
//                 r: 4
//             },
//             tooltip: {
//                 format: {
//                     title: function (recall) {
//                         idx = getIndexForValue(data, recall, "recall");
//                         if(idx != -1) {
//                             return "Threshold: " + data[idx].threshold;
//                         }
//                         return "";
//                     },
//                     value: function (precision, ratio, id) {
//                         return undefined;
//                     }
//                 }
//             },
//             zoom: {
//                 enabled: true
//             }
//         });

//     } catch (error) {
//         console.error('Error loading PR curve:', error);
//         const plotDiv = document.getElementById('plotDiv');
//         plotDiv.innerHTML = '<div>Error loading PR curve data.</div>';
//     }
// }


function handleAssessmentResponse(depict_url, data) {
    var inside_app_domain = "<p class='mb-2'>This compound is " + (data["assessment"]["inside_app_domain"] ? "inside" : "outside") + " the Applicability Domain derived from the chemical (PCA) space constructed using the training data.</p>";
    var functionalGroupsImgSrc = null;
    var reactivityCentersImgSrc = null;

    if (data['assessment']['node'] !== undefined) {
        functionalGroupsImgSrc = "<img width='400' src='" + data['assessment']['node']['image'] + "&highlight=true'>";
        reactivityCentersImgSrc = "<img width='400' src='" + data['assessment']['node']['image'] + "&highlightReactivity=true'>"
    } else {
        functionalGroupsImgSrc = "<img width='400' src=\"" + depict_url + "?smiles=" + encodeURIComponent(data['assessment']['smiles']) + "\">";
        reactivityCentersImgSrc = "<img width='400' src=\"" + depict_url + "?smiles=" + encodeURIComponent(data['assessment']['smiles']) + "\">"
    }

    tpl = `<div class="collapse collapse-arrow bg-base-200">
                <input type="checkbox" checked />
                <div class="collapse-title text-xl font-medium">Functional Groups Covered by Model</div>
                <div class="collapse-content">
                    ${inside_app_domain}
                    <div class="flex justify-center my-4">
                        ${functionalGroupsImgSrc}
                    </div>
                </div>
            </div>

            <div class="collapse collapse-arrow bg-base-200 mt-2">
                <input type="checkbox" checked />
                <div class="collapse-title text-xl font-medium">Reactivity Centers</div>
                <div class="collapse-content">
                    <div class="flex justify-center my-4">
                        ${reactivityCentersImgSrc}
                    </div>
                </div>
            </div>`

    var transformations = '';

    for (t in data['assessment']['transformations']) {
        transObj = data['assessment']['transformations'][t];
        var neighbors = '';
        for (n in transObj['neighbors']) {
            neighObj = transObj['neighbors'][n];
            var neighImg = "<img width='100%' src='" + transObj['rule']['url'] + "?smiles=" + encodeURIComponent(neighObj['smiles']) + "'>";

            var pwLinksHtml = '';
            if (neighObj['related_pathways'] && Object.keys(neighObj['related_pathways']).length > 0) {
                pwLinksHtml = '<ul class="menu bg-base-100 rounded-box w-full">';
                for (pw in neighObj['related_pathways']) {
                    var pwObj = neighObj['related_pathways'][pw];
                    pwLinksHtml += `<li><a href="${pwObj['url']}" class="link link-primary">${pwObj['name']}</a></li>`;
                }
                pwLinksHtml += '</ul>';
            }

            var expPathways = '';
            if (pwLinksHtml !== '') {
                expPathways = `
                    <div class="collapse collapse-arrow bg-base-200 mt-2">
                        <input type="checkbox" />
                        <div class="collapse-title font-medium">Experimental Pathways</div>
                        <div class="collapse-content">
                            ${pwLinksHtml}
                        </div>
                    </div>
                `;
            }

            neighbors += `
                    <div class="collapse collapse-arrow bg-base-100 mt-2">
                        <input type="checkbox" />
                        <div class="collapse-title text-lg font-medium">Analog Transformation on ${neighObj['name']}</div>
                        <div class="collapse-content">
                            <ul class="menu bg-base-100 rounded-box w-full">
                                <li><a href="${neighObj['url']}" class="link link-primary">${neighObj['name']}</a></li>
                                <li>Predicted probability: ${neighObj['probability'].toFixed(2)}</li>
                            </ul>
                            ${expPathways}
                            <div class="flex justify-center my-4">
                                ${neighImg}
                            </div>
                        </div>
                    </div>
                    `
        }

        var panelName = null;
        var objLinkUrl = null;
        var objLinkText = null;
        if (transObj['is_predicted']) {
            panelName = `Predicted Transformation by ${transObj['rule']['name']}`;
            for (e in transObj['edges']) {
                objLinkUrl = transObj['edges'][e]['url'];
                objLinkText = transObj['edges'][e]['name'];
                break;
            }
        } else {
            panelName = `Potential Transformation by applying ${transObj['rule']['name']}`;
            objLinkUrl = transObj['rule']['url'];
            objLinkText = transObj['rule']['name'];
        }

        var transImg = "<img width='100%' src='" + transObj['rule']['url'] + "?smiles=" + encodeURIComponent(data['assessment']['smiles']) + "'>";

        var transformation = `
                    <div class="collapse collapse-arrow bg-base-200 mt-2">
                        <input type="checkbox" />
                        <div class="collapse-title text-xl font-medium">${panelName}</div>
                        <div class="collapse-content">
                            <ul class="menu bg-base-100 rounded-box w-full">
                                <li><a href="${objLinkUrl}" class="link link-primary">${objLinkText}</a></li>
                                <li>Predicted probability: ${transObj['probability'].toFixed(2)}</li>
                                <li>This rule has triggered ${transObj['times_triggered']} times in the training set</li>
                                <li>Reliability: ${transObj['reliability'].toFixed(2)} (${(transObj['reliability'] > data['ad_params']['reliability_threshold'] ? "&gt;" : "&lt;")} Reliability Threshold of ${data['ad_params']['reliability_threshold']})</li>
                                <li>Local Compatibility: ${transObj['local_compatibility'].toFixed(2)} (${(transObj['local_compatibility'] > data['ad_params']['local_compatibility_threshold'] ? "&gt;" : "&lt;")} Local Compatibility Threshold of ${data['ad_params']['local_compatibility_threshold']})</li>
                            </ul>
                            <div class="flex justify-center my-4">
                                ${transImg}
                            </div>
                            ${neighbors}
                        </div>
                    </div>
                `
        transformations += transformation;
    }

    res = tpl + transformations;

    document.getElementById('appDomainAssessmentResultTable').innerHTML += res;

}
