let counter = 0
/**  
 * an object to keep track of the query diagram of the page used to handle the dynamic query generation 
 */
let DIAGRAMS = {}
/** an object to keep track of the query dictionaty of the page used to handle the dynamic query generation */
let DATA_DICTIONARY_STATE = {}
const DOWNLOAD_QUERY_RESULTS = false
const PAGE_URL = new URL(window.location)
const DEVELOPMENT_MODE = PAGE_URL.host.includes("localhost") || PAGE_URL.host.includes("127.0.0.1")
const PRODUCTION_MODE = !DEVELOPMENT_MODE
//const apps_script = {}
const post_list = {} // a direct link from the pageid to the entry in TOC.json
const menu_list = {} //  a direct link from the menu label to the entry in TOC.json
const ASSESSMENT_SUBMISSION_DETAILS={}// used to accumlate grading reports and to know when we can submit the stduent's work

const sequence = {}
const section_map = {}
const sequence_array = []
let CURRENT_PAGE_ID //id of the currently loaded page
const DIAGRAM_NOTE_TIMEOUTS=[]// used for cancelling a note display if the user does not wait for a second
let SQLITE_DB// a refrernece the the sqlite db
let SQLITE// a refrernece the the sqlite engine
let book_config = null
let menu = null

function download_text_file2(filename, text) {
  //console.log(filename)
  const element = document.createElement('a');
  element.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
  element.setAttribute('download', filename);

  element.style.display = 'none';
  document.body.appendChild(element);

  element.click();

  document.body.removeChild(element);
}



function Uint8ToString(u8a) {
  var CHUNK_SZ = 0x8000;
  var c = [];
  for (var i = 0; i < u8a.length; i += CHUNK_SZ) {
    c.push(String.fromCharCode.apply(null, u8a.subarray(i, i + CHUNK_SZ)));
  }
  return c.join("");
}
// Usage
//var u8 = new Uint8Array([65, 66, 67, 68]);
//var b64encoded = btoa(Uint8ToString(u8));


function sqlite_export() {
  const data = SQLITE_DB.export();
  //const buffer = Buffer.from(data);
  download_text_file2("art.sqlite", btoa(Uint8ToString(data)))

}


function get_query_log_form_id() {
  // returns the query log id set by the user
  return "1FAIpQLSeurcMcJX-_ak4SYla1wJ-qCBKNsm4_hVIa6lHHdIjuKl2dzQ"
}



function set_gas_token(token) {
  // sets the token into local(or session) storage
  BookStorage.gasToken(token);
}
function get_gas_token() {
  // gets the token into local(or session) storage
  try{
    return BookStorage.gasToken();
  }catch{
    return "";
  }
  
}


  





function server_save(params){
  // saves a value to the server object store, if it is configured

}

function set_dw_token(token) {
  // sets the token into local(or session) storage
  //localStorage.setItem("dwToken", token)
  BookStorage.dwToken(token)
}



function get_book_db_type() {

  // returns one of book, sqlite, data.world, oracle

  //console.log("at get_book_db_type", BookStorage.dbType())
  return BookStorage.dbType()

}

function set_config_value(name, value, save_to_cookie) {
  // sets a value in the book_config object, and the cookie of this book
  if (!book_config) {
    load_config()
  }
  book_config[name] = {
    value: value,
    save: save_to_cookie
  }

  if (save_to_cookie) {
    book_config_cor_cookie[name] = value
  }

  if (save_to_cookie) {
    save_config_to_cookie()
  }


}
function save_config_to_cookie() {
  // writes the properties in book_config to the cookie, if they are marked for saving
  const cookie_data = {}
  for (const [key, value] of Object.entries(book_config)) {
    if (value.save === true) {
      cookie_data[key] = value
    }
  }
  set_cookie("book_config", btoa(JSON.stringify(cookie_data)), 366)
}
function get_config_value(name) {
  // gets a value in the book_config object, which may read the cookie of the same name
  if (!book_config) {
    load_config()
  }
  if (book_config[name]) {
    return book_config[name].value
  }

}
function load_config() {
  //reads the config cookie into a local, global variable
  const cookie_data = get_cookie("book_config")
  if (!cookie_data) {
    book_config = {}
  } else {
    book_config = JSON.parse(atob(cookie_data))
  }
}
function clear_config() {
  // wipes out the config info and clears the cookie
  book_config = undefined
  set_cookie("book_config", btoa(JSON.stringify({})), 366)
}

function genPassword(pwLength = 16) {
  const structure = [[0, 52], [0, 26], [26, 26], [52, 10]]
  const chars = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789").split("")
  const password = [letter(0)]
  for (var i = 0; i <= pwLength; i++)
    password.push(letter(Math.floor(Math.random() * 4)))
  password[Math.floor(Math.random() * pwLength - 1) + 2] = "_"
  return password.join("")+"a1A"
  function letter(index) {
    return chars[structure[index][0] + Math.floor(Math.random() * structure[index][1])]
  }
}

function add_message(text) {
  const p = document.createElement("p")
  p.className = "console"
  p.appendChild(document.createTextNode(text))
  tag("script-message").appendChild(p);
  p.scrollIntoView(false)
  return p
}

function get_url(page_id, suffix) {
  const appendix = suffix || ""
  if (PRODUCTION_MODE) {
    return `${PAGE_URL.protocol}//${PAGE_URL.host}/2022/02/${page_id}${appendix}.html`
  } else {
    return `blog/posts/${page_id}${appendix}`
  }
}
function add_console_dot() { // used tp show progress when loading oracle data
  const console_lines = document.querySelectorAll(".console")
  const last_line = console_lines[console_lines.length - 1]
  if (last_line.style.paddingBottom === "1rem") { return }
  last_line.appendChild(document.createTextNode("."))
  setTimeout(add_console_dot, 2000);
}
async function configure_book_db(admin_username, admin_password, oracle_url) {
  // run the scripts needed to do book data on student's DB
  let username = admin_username
  let password = admin_password

  const scripts= await get_post_json(get_url("oracle-config-index"))
  //console.log("scripts", scripts)
  
  const pw = genPassword()
  //console.log("password====>", pw)
  let errors = 0
  let p = add_message("Configuring Oracle. This will take a few minutes.")
  p = add_message(" ")
  p = add_message("Clearing old sessions..")
  p.style.paddingTop = "1rem"


  // terminate inactive sessions
  let user_statements = await run_oracle_script({ 
    sql:`SELECT 'ALTER SYSTEM KILL SESSION '''||sid||','||serial#||''' IMMEDIATE;' as statement FROM v$session 
    where status='INACTIVE';` , 
    username: username, 
    password: password, 
    url:oracle_url.split("/ords/")[0] + "/ords/" + username.toLowerCase() + "/_/sql"
  })
  add_console_dot()
  const kill_sessions_script=[]
  for(const item of user_statements.items[0].resultSet.items){
    kill_sessions_script.push(item.statement)
    //console.log(item)
  }
  //console.log("kill_sessions_script", kill_sessions_script.join(""))
  await run_oracle_script({ 
    sql:kill_sessions_script.join("") , 
    username: username, 
    password: password, 
    url:oracle_url.split("/ords/")[0] + "/ords/" + username.toLowerCase() + "/_/sql"
  })

  p.appendChild(document.createTextNode("Done."))

  let script_number = 0
  for (const script of scripts) {
    script_number++
    let oracle_script = await get_post_content(get_url(script.file))
    if (script.type === "pl-sql") {
      oracle_script = oracle_script.split('USER_Pa55w0rd').join(pw)
    }

    if(script.user)(username=script.user)


    p = add_message(script.text)
    if (script_number === 1) {
      add_console_dot()
    }

    let error_count = 0

    if(script.type === "csv") {
    //}else if(script.type === "csv") {
      username=script.user
      //console.log(oracle_script)
      let url_appendix=""
      const package={ 
        data: oracle_script,
        username: script.user,
        password: pw,
        table:script.table,
        urlbase: oracle_url.split("/ords/")[0] + "/ords/" 
        //"https://gac20d8680a12b9-tpdb.adb.us-sanjose-1.oraclecloudapps.com/ords/"
      }
      if(script.dateFormat){
        package.urlAppendix="&dateFormat="+script.dateFormat
      }
      const json_response = await oracle_csv(package)
      if (json_response.status!=="success") {
        error_count++
        console.error(data?.message)
        p.appendChild(document.createTextNode("Error."))
        p = add_message(data?.message + "\n*** Script halted. ***")
        p.style.color = "red"
        p.style.paddingBottom = "1rem"
        errors++
        return "error"
      }
  

    }else{
      const json = await run_oracle_script({ 
        sql: oracle_script, 
        username: username, 
        password: password, 
        url:oracle_url.split("/ords/")[0] + "/ords/" + username.toLowerCase() + "/_/sql"
      })
      for (const stmt of json.items) {
        if (stmt.errorCode) {
          error_count++
          console.error(stmt)
          p.appendChild(document.createTextNode("Error."))
          p = add_message(stmt.errorDetails + "\n*** Script halted. ***")
          p.style.color = "red"
          p.style.paddingBottom = "1rem"
          errors++
          return "error"
        }
      }
  
    }


    if (error_count === 0) {
      p.appendChild(document.createTextNode("Done."))
    }
   // only the first script runs with admin permissions, switch to newly created users
   password=pw// set the password to the newly created password.  It is is the password for all new accounts

  }
  // all scripts processed without error
  // set the connection for the script stuent user
  p = add_message("Saving connection information...")
  //console.log("saving connection-----")
  const response = await save_connection({ 
    name: "SQL-Book Queries", 
    username: "BOOK_USER", 
    password: pw, 
    description: "Account used for executing queries at SQL-Book.blogspot.com" ,
    url:oracle_url.split("/ords/")[0] + "/ords/book_user/_/sql",
    id:"sql_book_connection",
    protect:true
  })
  console.warn("saved connection", response)
  p.appendChild(document.createTextNode("Done."))

  p = add_message("Eanbling remote connection for user...")
  p.appendChild(document.createTextNode("Done."))

  p = add_message("-----------------------")
  p = add_message("Configuration Complete.")
  p.style.paddingBottom = "1rem"

  return "done"

}



async function run_fixed_query(button, data_url) {
  // just gets a saved data block from a web post
  // post that hold data must be created in january 2000

  if (button.innerHTML === `hourglass_empty`) { return }
  let query_box = button

  while (query_box.className !== `query-editor`) {
    //console.log(`query_box`, query_box)
    query_box = query_box.parentNode
  }

  const error_message = query_box.querySelector(`.error-message`);
  const query_result = query_box.querySelector(`.query-result`);
  const result = query_box.querySelector(`.result-wrapper`);
  const edit = query_box.getElementsByTagName("code")[0]
  const sql = edit.value

  button.innerHTML = `hourglass_empty`
  button.classList.add(`blink`)
  try {
    const data = await get_post_content(get_url(data_url, "-data"))
    result.innerHTML = data
    query_result.style.display = "block"
    error_message.style.display = "none"
    button.innerHTML = "play_circle"
    button.classList.remove(`blink`)

  } catch (e) {
    error_message.innerHTML = e.message
    query_result.style.display = "none"
    error_message.style.display = "block"

  }

}

function toggle_elements_of_class(checkbox, visibility, class_name) {
  if (checkbox.tagName = "input") {
    let visibility = "none"
    if (checkbox.checked) { visibility = "" }
    get_query_controls(checkbox).query_box.querySelectorAll("." + checkbox.parentNode.getAttribute("name")).forEach((elem) => {
      elem.style.display = visibility
    });
  } else {
    //in this case, checkbox is really the query box
    checkbok.querySelectorAll("." + class_name).forEach((elem) => {
      elem.style.display = visibility
    });

  }
}

function header_clicked(el, dictionary_block_id) {
  const query_editor = document.getElementById(dictionary_block_id).parentElement
  if (query_editor) {
    const sql_editor = query_editor.getElementsByTagName("textarea")[0]
    sql_editor.value = el.innerText
    sql_editor.parentElement.update(sql_editor.value)
    //console.log(sql_editor)
  } else {
    throw 'dictionary block unavaliable'
  }
}


function get_query_controls(element) {
  // returns the structure of the query result block given any element in the block
  const controls = {
    query_box: element,
    tools: {}
  }

  // find the top-level container
  while (controls.query_box.className !== `query-editor`) {
    controls.query_box = controls.query_box.parentNode
  }

  // find the button that runs the query
  const spans = controls.query_box.getElementsByTagName("SPAN")
  for (let x = 0; x < spans.length; x++) {
    if (spans[x].onclick && spans[x].onclick.toString().includes("run_query(")) {
      controls.button = spans[x]
      break
    }
  }
  controls.text_before_query = controls.query_box.querySelector(`.text-before-query`);
  controls.text_after_query = controls.query_box.querySelector(`.text-after-query`);
  controls.query_diagram = controls.query_box.querySelector(`.query-diagram`);
  controls.note = controls.query_box.querySelector(`.task-text`);
  controls.settings = controls.query_box.querySelector(`.query-settings`);
  controls.error_message = controls.query_box.querySelector(`.error-message`);
  controls.query_result = controls.query_box.querySelector(`.query-result`);
  controls.edit = controls.query_box.getElementsByTagName("code-input")[0]
  controls.tools.line_numbers = controls.query_box.querySelector('span[name="result-line-number"]')
  controls.tools.sql = controls.query_box.querySelector('span[name="result-sql"]')
  //console.log("at get_query_controls",controls)
  return controls
}


async function get_query_block(params) {
  // const sql=params.sql  ||"select * from dual"
  // const connection = params.connection
  // const schema = params.schema
  // const owner = params.owner
  let diagram_settings = params.diagram_settings
  if(!diagram_settings){diagram_settings=params.diagram}
  let height = params.query_box_height
  let engine = params.engine || BookStorage.dbType()
  
  let pre_block = ""
  let post_block = ""
  let diagram_block = ""
  let diagram_button = ""
  let add_button = ""
  let settings_button = ""
  let note_button=""
  let note_block=""
  let settings_block=""
  let editor_button=get_button("edit_note","Open in Query Editor","open_in_query_editor")

  if (params.note){// notes are from editors or assignments
    note_block = `<div class="task-text" contenteditable="true" style="margin-top: 0px; display: ${params.note?"block":"none"};">${params.note}</div>`
  }

  if(params.kind){// settings are only available in the query editor or tutorial
    engine = params.engine
    note_button=get_button("description","Show Note","show_query_note")
    editor_button=""
    if(!params.note){
      note_block = `<div class="task-text" contenteditable="${params.kind==='editor'}" style="margin-top: 0px; display: ${params.note?"block":"none"};">"Enter any notes here."</div>`
    }

    if(params.kind==="editor"){
      pre_block=`<div contenteditable="${params.kind==='editor'}" class="text-before-query" style="margin-top: 0px; background-color:white; padding:0 .5rem .25rem .5rem;">${params.textBeforeQuery===undefined?"":params.textBeforeQuery}</div>`
      post_block=`<div contenteditable="${params.kind==='editor'}" class="text-after-query" style="margin-top: 0px; background-color:white; padding:.25rem .5rem .25rem .5rem;">${params.textAfterQuery===undefined?"":params.textAfterQuery}</div>`
    }else if(params.kind==="tutorial"){
      pre_block=`<div contenteditable="${params.kind==='editor'}" class="text-before-query" style="margin-top: 0px; background-color:white; padding:0 .5rem .25rem .5rem; display: ${params.textBeforeQuery?"block":"none"};">${params.textBeforeQuery}</div>`
      post_block=`<div contenteditable="${params.kind==='editor'}" class="text-after-query" style="margin-top: 0px; background-color:white; padding:.25rem .5rem .25rem .5rem; display: ${params.textAfterQuery?"block":"none"};">${params.textAfterQuery}</div>`
    }

    settings_button=get_button("settings","Show Settings","show_settings")
    settings_block=`<div class="query-settings" style="margin-top: 0px; display: none; margin: 1rem 0">
    <table align="center">
    
    <tr><td>
    Diagram:
    </td><td>
    <input name="diagram" type="text" size="20" placeholder="Name or URL" value="${params.diagram||""}">
    </td><td><span onclick="message({title:'Database Diagram',message:'Name of diagram from this book or a url to an image of a database diagram.  To see Diagram, save and refresh page.', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>
    
    <tr><td>
    File Name:
    </td><td>
    <input name="filename" type="text" size="20" placeholder="Name of file when downloaded" value="${params.filename||"query_"+params.script_number}">.csv
    </td><td><span onclick="message({title:'Table Name',message:'When you execute this script, any query that retruns a records set will have the option to download the result.  This is the name that will be used when downloadin any file.', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>
    
    <tr><td>
    Database Engnie:
    </td><td>
    <select name="engine" onchange="select_engine(this)">
      <option value="sqlite"${engine==="sqlite"?" selected":""}>SQLite</option>
      <option value="dataworld"${engine==="dataworld"?" selected":""}>data.world</option>
      <option value="oracle"${engine==="oracle"?" selected":""}>Oracle Autonomous Database</option>
    </select>
    </td><td><span onclick="message({title:'Database Engine',message:'The database engine used to execute this script.  Oracle is only valid when the current &quot;<a href=&quot;/?user-profile&quot;>authentication Method</a>&quot; is &quot;Your own authentication server&quot; or &quot;This book'+String.fromCharCode(27)+'s authentication server&quot;', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    <tr class="oracle engine" style="display:${engine==='oracle'?'':'none'}"><td>
    Schema:
    </td><td>
    <input name="schema" type="text" size="20" placeholder="Database Schema" value="${params.schema||""}">
    </td><td><span onclick="message({title:'Connection',message:'Optional. The name of the user that owns the tables you want to query.  If omitted, the schema of the authenticated user will be the default schema.', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    <tr class="oracle engine" style="display:${engine==='oracle'?'':'none'}"><td>
    Connection:
    </td><td>
    <input name="connection" type="text" size="20" placeholder="Connection Name" value="${params.connection||""}">
    </td><td><span onclick="message({title:'Connection',message:'The name of the connection to use to connect to your Oracle Autonomous Database.  Optional if supplying the Oracle URL, User Name, and Password.', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    <tr class="oracle engine" style="display:${engine==='oracle'?'':'none'}"><td>
    Oracle URL:
    </td><td>
    <input name="url" type="text" size="20" placeholder="User REST URL" value="${params.url||""}">
    </td><td><span onclick="message({title:'Connection',message:'The REST URL of a user on your Oracle Autnonmous Databse.  Optional if a connection name is supplied.', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    <tr class="oracle engine" style="display:${engine==='oracle'?'':'none'}"><td>
    User Name:
    </td><td>
    <input name="username" type="text" size="20" placeholder="Oracle User Name" value="${params.username||""}">
    </td><td><span onclick="message({title:'Connection',message:'The username of a user on your Oracle Autnonmous Databse.  Optional if a connection name is supplied.', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    <tr class="oracle engine" style="display:${engine==='oracle'?'':'none'}"><td>
    Password:
    </td><td>
    <input name="password" type="password" size="20" placeholder="Oracle User Password" value="${params.password||""}"><span title="Show Password" style="margin-left:3px" onclick="toggle_prior_password(this)" class="material-symbols-outlined button inline-icon" title="Show Password">visibility</span>
    </td><td><span onclick="message({title:'Connection',message:'The password of a user on your Oracle Autnonmous Databse.  Optional if a connection name is supplied.', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    <tr class="dataworld engine"  style="display:${engine==='dataworld'?'':'none'}"><td>
    Owner:
    </td><td>
    <input name="owner" type="text" size="20" placeholder="Owner Name" value="${params.owner||""}">
    </td><td><span onclick="message({title:'Connection',message:'The name of the data.world user that owns the tables you want to query', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    <tr class="dataworld engine" style="display:${engine==='dataworld'?'':'none'}"><td>
    Dataset:
    </td><td>
    <input name="dataset" type="text" size="20" placeholder="Dataset Name" value="${params.dataset||""}">
    </td><td><span onclick="message({title:'Connection',message:'The name of the dataset that holds the tables you want to query', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    <tr class="sqlite engine" style="display:${engine==='sqlite'?'':'none'}"><td>
    Database Name:
    </td><td>
    <input name="databaseName" type="text" size="20" placeholder="Database Name" value="${params.databaseName||""}">
    </td><td><span onclick="message({title:'Connection',message:'The name of this book'+String.fromCharCode(39)+'s database that holds the tables you want to query.', seconds:10})" class="material-symbols-outlined button inline-icon">help</span>                
    </td></tr>

    </table>
      <div style="text-align:center;margin-top:1rem">
        <button onclick="delete_query(this)">
          Delete
          <span class="material-symbols-outlined" style="vertical-align:middle">
            delete
          </span>
        </button>
      </div>
    </div>`
    add_button=get_button("add_circle","Duplicate Script","duplicate_script")
  }

  if(params.kind==="tutorial"){
    add_button=""
    settings_button=""
  }

  if (diagram_settings) {
    const diagram = diagram_settings.split("|")
    if (diagram.length === 1) { diagram.push("none") }
    if (diagram[1] === "visible") { diagram[1] === "block" }
    diagram_block = `<div class="query-diagram" style="zoom:100%; display:${diagram[1]}" data-diagram-page="${diagram[0]}"></div>`
    diagram_button = get_button("account_tree","Show Diagram","show_diagram")
  }

  // height
  if (!height) { height = params.sql.split("\n").length }
  if (height < 3) {
    height = 3
  } else if (height > 30) {
    height = 30
  }
  
  
return `<div class="query-editor">${pre_block}${diagram_block}${note_block}${settings_block}
  <code-input lang="sql" data-connection="${params.connection}" data-owner="${params.owner}" data-schema="${params.schema}" data-tablename="${params.fileame}" class="rows-${height}"  value="${params.sql}" ></code-input>
  <div class="button-box">      
    <div class="divTableRow">
      <div class="divTableCell">
        <span name="result-line-number" style="display:none"><input type="checkbox" checked onclick="toggle_elements_of_class(this)">&nbsp;Line&nbsp;Numbers </span>
        <span name="result-sql" style="display:none"><input type="checkbox" checked onclick="toggle_elements_of_class(this)">&nbsp;SQL</span>
      </div>
      <div class="divTableCell" style="text-align: right">${add_button}${settings_button}${note_button}${editor_button}${diagram_button}${get_button("play_circle","Run this query","run_query")}
      </div>
    </div>
  </div>
  <div class="query-result"/>
  </div>
  ${post_block}
  </div>
`

function get_button(icon_name, title, function_name){
    return `<span onclick="${function_name}(this)" title="${title}" class="material-symbols-outlined button" style=";vertical-align:middle;margin-left:3px"><span class="material-symbols-outlined">${icon_name}</span></span>`
  }
}

function select_engine(elem){
  //console.log("elem",elem, elem.value)
  const controls = get_query_controls(elem)
  for(const div of controls.settings.querySelectorAll(".engine")){
    div.style.display="none"
  }
  for(const div of controls.settings.querySelectorAll("." + elem.value)){
    div.style.display=""
  }
  //console.log("settings",controls.settings)
  //console.log("controls",controls)
}

function script_from_query_controls(controls){
  // returns an object analogous to one script from the query editor object structure
  console.log("controls", controls)
  const script={}

  if(controls.settings){
    // making script from an editor
    for(input of controls.settings.getElementsByTagName("input")){
      script[input.name] = input.value
    }
    for(select of controls.settings.getElementsByTagName("select")){
      script[select.name] = select.value
    }
    script.note = controls.note.innerHTML
    script.textAfterQuery = controls.text_after_query.innerHTML
    script.textBeforeQuery = controls.text_before_query.innerHTML
  }else{
    // making script from a simple query interface
    script.sql=controls.edit.value
    script.diagram=controls.query_diagram.dataset.diagramPage
    script.connection=controls.edit.dataset.connection
    script.owner=controls.edit.dataset.owner
    script.schema=controls.edit.dataset.schema
    script.dataset=script.schema
    script.databaseName=script.schema
    script.filename=controls.edit.dataset.tablename
    if(controls.note){
      script.note=controls.note.innerHTML
    }else{
      script.note='Copied From "' + sequence[CURRENT_PAGE_ID].label + '"'
    }
    script.engine = BookStorage.dbType()


  }
  //console.log("inputs", script)
  script.sql = controls.edit.value
  return script
}

function open_in_query_editor(button){
  const controls = get_query_controls(button)
  //console.log("Controls",controls)
  const script=script_from_query_controls(controls)
  //console.log("script",script)
  sessionStorage.setItem("open_query_in_editor", JSON.stringify(script))
  load_page("query_editor")
}

async function delete_query(button) {
  let elem = button
  while (elem.className !== 'query-editor') {
    elem = elem.parentNode
  }
  elem.remove()
}

async function save_editor(button) {
  // save's the query editor work to bookstorage
  BookStorage.queryEditor(get_query_editor_data(button))
}


function toggle_prior_password(eye_ball){
  // finds the input that immediately preceeds the eyeball icon and toggles it between text and password, 
  
  let elem=eye_ball
  while (elem.tagName.toLowerCase() !== 'input') {
    elem = elem.previousSibling
  }
  if(elem.type==="text"){
    elem.type="password"
    eye_ball.innerHTML="visibility"
    eye_ball.title="Show Password"
  }else{
    elem.type="text"
    eye_ball.innerHTML="visibility_off"
    eye_ball.title="Hide Password"
  }
}

async function import_editor(data) {

  let query_editor_data
  try{
    query_editor_data = JSON.parse(data)
  }catch(e){
    message({
      message: "Unable to import the file.  It does not appear to be in the correct format.",
      title: "Bad File Format",
      seconds: 8,
      kind:"error",
      show: true
    })
    return
  }


  if(query_editor_data.title && query_editor_data.text && query_editor_data.scripts){

    const button_label="Yes, replace existing queries."
    const button = await ui_message_box(
        "Importing an existing query editor file will replace all existing queries? ",
        "Are you sure?",
        [button_label, "Oops, I changed my mind."]
    )

    if(button===button_label){
      console.log("ready to import")
      console.log(data)
      BookStorage.queryEditor(query_editor_data)
      window.location.reload()
    }

  }else{
    message({
      message: "Unable to import the file.  It does not appear to be in the correct format.",
      title: "Bad File Format",
      seconds: 8,
      kind:"error",
      show: true
    })

  }


}


async function get_editor(button_pressed) {
  // loads an editor from a url
    const url = await ui_input_box(
        "Enter the URL of the query set you want to load.",
        "Load Query Set",
        "",
        "https://...",
        ["OK"]       
    )
    if(url && url.length>8){
      try{
      response = await fetch(url)
      BookStorage.queryEditor(await response.json())
      window.location.reload()
      }catch(e){
        ;console.log("response")
        message({
          message: "Unable to import the file.  It does not appear to be in the correct format.",
          title: "Bad File Format",
          seconds: 8,
          kind:"error",
          show: true
        })
      }
    }
}


async function load_tutorial(select_obj) {
  if(select_obj.value<0){
  // loads an editor from a url
    const url = await ui_input_box(
        'Enter the URL of the tutorial or the tutorial set you want to load or <span onclick="tag(`input-box-input`).value=`tutorials`" class="span-link"> get the code for the default tutorials.</span>',
        "Load Tutorials",
        "",
        "https://...",
        ["OK"]       
    )

    if(url && url.length>5){
      try{
        let tutorials_data
        
        if(url.toLowerCase().startsWith("http")){
          let response = await fetch(url)
          tutorials_data = await response.json()
        }else{
          tutorials_data = await get_post_json(get_url(url))
        }

        console.log("tutorials_data",tutorials_data)
        //debugger
        // checking for format of tutorial set      
        console.log("tutorials_data.tutorials",tutorials_data.tutorials)
        console.log("tutorials_data.currentTutorial",tutorials_data.currentTutorial)
        if(tutorials_data.tutorials!==undefined && tutorials_data.currentTutorial!==undefined){
        
          // looks like a tutorial set
        }else if(tutorials_data.title!==undefined && tutorials_data.text!==undefined && tutorials_data.pages!==undefined){
          // looks like a dingle tutorial, use it to build a set
        
          tutorials_data={
            "currentTutorial":0,  
              "tutorials":[
              { "title":tutorials_data.title,
                "text":tutorials_data.text,
                "url":url
          }]}
        }else{
          throw new Error('File format not recognized.');
        }


        for(let t=0;t<tutorials_data.tutorials.length;t++){// set the default page on each tutorial
          tutorials_data.tutorials[t].currentPage=0
        }
        console.log("tutorials_data",tutorials_data)
        BookStorage.tutorials(tutorials_data)
        tutorials()
      }catch(e){
        message({
          message: "Unable to import the file.  It does not appear to be in the correct format.",
          title: "Bad File Format",
          seconds: 8,
          kind:"error",
          show: true
        })
      }
    }else{
      //cancelled
      tag("select-tutorial").value=BookStorage.tutorials().currentTutorial
    }
  }else{
    // chosing an existing one
    const tutorial_data=BookStorage.tutorials()
    tutorial_data.currentTutorial=select_obj.value
    BookStorage.tutorials(tutorial_data)
    tutorials()

  }
}






function get_query_editor_data(button){
  //builds the object of a query editor for saving or export
  const query_editor_data={
    title: tag("editor-title").innerHTML,
    text:tag("editor-text").innerHTML,
    scripts:[]
  }

  let elem = button
  while (elem.className !== 'content-panel') {
    elem = elem.parentNode
  }

  for (const editor of elem.querySelectorAll(".query-editor")) {
    //console.log("editor",editor)
    query_editor_data.scripts.push(script_from_query_controls(get_query_controls(editor)))
  }
  
  return query_editor_data

}



function export_editor(button_pressed){
  // exports all queries from advanced query editor and downloads them
  const query_editor_data= get_query_editor_data(button_pressed)
  download_text_file(JSON.stringify(query_editor_data,null,2), query_editor_data.title.replace(/[^a-z0-9]/gi, '_') + ".json")
  message({
    message: "Your file has been exported.",
    title: "File Downloaded",
    seconds: 8,
    show: true
  })
}







async function duplicate_script(button) {
  // const controls = get_query_controls(button)
  //console.log (controls,"controls")
  // const script = script_from_query_controls(get_query_controls(button))
  //console.log("script", script)
  // const html=await get_query_block(script)
  //console.log (html)
  let elem = button
  while (elem.className !== 'query-editor') {
    elem = elem.parentNode
  }
  //console.log(elem)
  const new_editor=ui_div("query-editor")
  new_editor.innerHTML = elem.innerHTML
  //new_editor.style.marginTop="1rem"
  elem.after(new_editor)

}
function show_diagram(button) {
  const controls = get_query_controls(button)
  if (controls.query_diagram.style.display === "none") {
    controls.query_diagram.style.display = "block"
  } else {
    controls.query_diagram.style.display = "none"
  }
}
function show_settings(button) {
  const controls = get_query_controls(button)
  if (controls.settings.style.display === "none") {
    controls.settings.style.display = "block"
  } else {
    controls.settings.style.display = "none"
  }
}

function show_query_note(button) {
  const controls = get_query_controls(button)
  if (controls.note.style.display === "none") {
    controls.note.style.display = "block"
  } else {
    controls.note.style.display = "none"
  }
}


function gas_to_book_storage(data, deployment_id){
  // takes a connect response from google apps script and writes to bookstorage
  for(const [key,value] of Object.entries(data.bookStorage.property)){
    //console.log(key, value.value)
    if(!BookStorage.exists(key)){BookStorage.addItem(key)}
    try{
      BookStorage[key](JSON.parse(value.value))
    }catch(e){
      //console.log("gas_to_book_storage Error", e)
    }
  }
  
  BookStorage.deploymentId(deployment_id)
  BookStorage.gasToken(data.token)
  fill_server_configuration()
}

/**
 * makes a request to a google app script entpoint
 * this could be built out to use a differnt end point for paying customers
 * so they can run the book in a browser without setting up a google sheet
 * or apps script deployment endpoint
 */
async function server_post(payload, raw_url) {
  //console.log("raw url", raw_url)

  if(BookStorage.loginType()==="gas" || raw_url){
    return await frelayServerPost(payload, raw_url)
  }else if(BookStorage.loginType()==="paid"){
    return await paylayServerPost(payload)
  }else{
    // no other bookstorage.logintype requires sending data to the backend.
    return {status: "success", msg: "did not make post to server."}
  }
}

async function frelayServerPost(payload, raw_url){
  let url = raw_url
  if (!url) {
    url = get_gas_endpoint()
    if (!url) {
      // the student's google apps script is not known
      return null
    }

  }

  payload.token = get_gas_token()
  if(DEVELOPMENT_MODE){
  ;console.log("frelay server_post payload", payload)
  }
  
  let reply
  try{
    reply = await fetch(url, {
      method: `POST`,
      body: JSON.stringify(payload),
    })
  }catch(e){
    //console.log("reply error",e.message)
    return JSON.stringify({status:"error",message:e.message})
  }

  const text = await reply.text()
  try {
    return JSON.parse(text)
  } catch (e) {
    return {response: text}
  }

}

async function paylayServerPost(payload){
  console.log("calling paylay's server post")
  const client = await PaylayClient.init()
  return await client.server_post(payload)
}

async function oracle_csv(params) {
  // runs an oracle script against the endpoint stored in the cookie


  const payload = params
  payload.mode=`import-data-oracle`

  return await server_post(payload)
}



async function run_oracle_script(params) {
  // runs an oracle script using frelay or paylay

  
  const payload = { mode: `run-oracle-script`, sql: params.sql}
  // execute an oracle query
  if (params.url) { payload.url = params.url }
  if (params.connection) { payload.connection = params.connection }
  if (params.username) { payload.username = params.username }
  if (params.password) { payload.password = params.password }

  return await server_post(payload)
}

function display_query_result(controls, result_json) {
  const result_wrapper = document.createElement('div');
  result_wrapper.className = "result-wrapper"
  controls.query_result.appendChild(result_wrapper)
  const sql_statement = `<div style="width: 100%" ><pre class="result-sql">${result_json.statementText}</pre></div>`

  //console.log(result_json);

  if (result_json.errorMessage) {
    show_error(controls, result_json.errorMessage, sql_statement)
    return
  }
  if (result_json.errorDetails) {
    if (result_json.errorDetails === 'unknown') {
      show_error(controls, result_json.response.join("\n"))
    } else {
      show_error(controls, result_json.errorDetails)
    }

    return
  }

  if (result_json.resultSet) {
    // record set
    const table = [`<table onclick="show_query_cell(event)" class="qtable" data-tablename="${controls.edit.dataset.tablename}"><thead><tr><th class="result-line-number">&nbsp;</th>`]
    const columns = result_json.resultSet.metadata
    for (const col of result_json.resultSet.metadata) {
      //columns.push({name:col.jsonColumnName, datatype:col.columnTypeName})
      table.push(`<th>${col.columnName}</th>`)
    }
    table.push(`</tr></thead><tbody>`)
    let line_number = 0
    //console.log(`columns`,columns)
    for (const row of result_json.resultSet.items) {
      const tr = [`<tr><td class="result-line-number">${++line_number}</td>`]
      for (col of columns) {
        if (row[col.jsonColumnName]) {
          let val = row[col.jsonColumnName]
          let css_class = ""
          switch (col.columnTypeName) {
            case "DATE":
              val = row[col.jsonColumnName].replace("T", " ").replace("Z", "");
              break
            case "NUMBER":
              if (col.scale > 0) {
                val = row[col.jsonColumnName].toFixed(col.scale)
              }
              css_class = ' class="numeric"'
              break
            default:
          }
          tr.push(`<td${css_class}>${val}</td>`)
        } else {
          tr.push(`<td class="null"></td>`)
        }
      }
      tr.push(`</tr>`)
      table.push(tr.join(``))
    }
    //console.log("data table name",controls.edit.dataset.tablename)
    table.push(`</tr></tbody></table><div class="tool-footer"><span title="Expand" onclick="expand_result(this)" class="material-symbols-outlined button">expand</span><span title="Download CSV" onclick="tableToCSV(this)" class="material-symbols-outlined button">download</span></div>`)
    //console.log(table.join(``))
    result_wrapper.innerHTML = sql_statement + table.join(``)
    return
  }

  if (["session-control", "ddl", "dml", "sqlplus", "sqlite-message"].includes(result_json.statementType)) {
    //result_wrapper.style.width="100%"
    let output = result_json.response
    if (!Array.isArray(output)) {
      output = [output]
    }
    result_wrapper.innerHTML = `${sql_statement}<div class="response-message">${output.join("\n")}</div>`
    return
  }



  result_wrapper.innerHTML = `${sql_statement}<div class="response-message">Unrecognized response:<br>${JSON.stringify(result_json, null, 2)}</div>`

}


function expand_result(button){
  // make a query result the height of the viewport
  let elem = button
  while (elem.className !== 'result-wrapper') {
    elem = elem.parentNode
  }
  //console.log(elem)
  if(elem.style.maxHeight){
    elem.style.maxHeight = null
  }else{
    elem.style.maxHeight= window.innerHeight+"px"
  }
  elem.scrollIntoView({ behavior: 'smooth' })
  
}



/**
 * runs an runs a query appropriately based on the book configuration
 * @param {HTMLElement} element 
 * @param paramOverrides 
 * @returns 
 */
async function run_query(element, paramOverrides) {
  let params
  const controls = get_query_controls(element)
  try {
    //console.log("contorls--->", controls)
    if (paramOverrides) {
      params = paramOverrides
    } else if (element) {
      element.id = Date.now()

      //  if we are currently running, don't do anything
      if (controls.button.innerHTML === `hourglass_empty`) { return }

      // show that we are currently running a query
      controls.button.innerHTML = `hourglass_empty`
      controls.button.classList.add(`blink`)
      controls.query_result.innerHTML = ""


      for (const tool of Object.values(controls.tools)) {
        tool.style.display = "none"
      }

      params = {
        engine: get_book_db_type(),
        query: controls.edit.value,
        connection: controls.edit.dataset.connection,
        schema: controls.edit.dataset.schema,
        owner: controls.edit.dataset.owner,
        tablename: controls.edit.dataset.tablename,
        timestamp: element.id
      }

      // overrides if working from query editor
      if(controls.settings){
        //console.log("controls", controls)
        params.engine=controls.settings.querySelector("select[name='engine']").value
      }
        



      // }

      //console.log("query execution params", params)

      //log query if configured
      if (get_from_book_storage("courseCode")) {
        //build the obejct to submit
        payload = {
          submissionType: "logQuery",
          studentId: get_from_book_storage("studentId", ""),
          firstName: get_from_book_storage("studentFirstName", ""),
          lastName: get_from_book_storage("studentLastName", ""),
          email: get_from_book_storage("studentEmail", ""),
          page: window.location.href,
          source: params.tablename,
          query: params.query
        }



        const response = await submit_backend_package(payload)


        if (response.status === "failure") {
          message({
            message: response.message,
            title: "Log Error",
            kind: "error",
            seconds: 8,
          })
          return
        }

      }


    } else {
      throw 'cannot run query without an HTML Element or override params'
    }

    let response

    //console.log("---> params.engine", params, controls)
    switch (params.engine) {
      case "oracle": //================================================================
        if(BookStorage.loginType()!=="paid" && BookStorage.loginType()!=="gas"){
          //Trying to execute an oracle query with no backend, probably from query editor
          
          message({
            message: "To execute a query using Oracle, your authentication method must be either \"Your Own Authentication Server\" or \"This Book's Authentication Server\".  Go to <a href=\"/?user-profile\">Settings</a> and make the appropriate choice under \"Authentication Method\".",
            title: "Not configured for Oracle",
            kind: "error",
            seconds: 8,
          show: true
          })
          controls.button.innerHTML = "play_circle"
          controls.button.classList.remove(`blink`)
          return
        }  

        response = await run_db_query(params)
        if (!response) {
          return// the query must have been processed through the internal channel, it will get rendered later
        }
        if (DOWNLOAD_QUERY_RESULTS) { download_text_file(JSON.stringify(response), params.tablename + "-data") }

        //console.log("oracle_params", params)


        break
      case "dataworld": //============================================================

      if(controls.settings){
        // running from editor
        params.owner=controls.settings.querySelector("input[name='owner']").value
        params.schema=controls.settings.querySelector("input[name='dataset']").value
      }  

        try {
          params.token = BookStorage.dwToken()//BookStorage.dwToken()
          //console.log("BookStorage.dwToken()", BookStorage.dwToken())
        } catch (e) {
          message({
            message: "You are trying to execute a query using data.world, but you have not set you data.world read/write token.  Go to Settings and chose \" data.world\" under \"Database Engine Configuration\" to set the token.",
            title: "Token Missing",
            kind: "error",
            seconds: 8,
          show: true
          })

          throw e
        }
        response = await run_db_query(params)



        break
      case "sqlite": //================================================================
      if(controls.settings){
        // running from editor
        params.schema=controls.settings.querySelector("input[name='databaseName']").value
      }  
        response = await run_db_query(params)


        break
      default: //Book ======================================================================
        //console.log("---> executing book query")
        // book  
        response = await JSON.parse(await get_post_content(get_url(controls.edit.dataset.tablename, "-data")))


    } //===============================================================================

    process_query_response(response, element.id)

  } catch (e) {
    console.error(e)
    const result_wrapper = document.createElement('div');
    result_wrapper.className = "result-wrapper"
    const error_msg = e instanceof ShowableError ? e.message : "Unable to execute query"
    controls.query_result.replaceChildren(ui_div("m3",
      ui_div("feedback-pane m3",
        ui_div("feedback-header-error", "There Was a Problem"),
        ui_div("feedback-body error-message", error_msg)
      ),
    ))

    controls.button.innerHTML = "play_circle"
    controls.button.classList.remove(`blink`)
  }
}


function process_query_response(response, timestamp) {
  //takes a response formatted like Oracle's query response and displays it

  //console.log("RESPONSE---", response, timestamp)
  controls = get_query_controls(tag(timestamp))


  if (response.error === "html") {
    show_error(controls, response.message)
    controls.button.innerHTML = "play_circle"
    controls.button.classList.remove(`blink`)
    return
  }

  let query_count = 0
  let sql_with_results = 0
  // display results
  for (let x = 0; x < response.items.length; x++) {
    const item = response.items[x]
    if (!item.statementText.includes("/*hIdE-Me*/")) {
      // suppress the oracle statement to set the schema
      display_query_result(controls, item)
      query_count++
      if (item.resultSet) { sql_with_results++ }
    }
  }




  // post-query formatting
  //set visibility for query box  
  //console.log("script_result", response)
  if (query_count > 1) {
    // There are multiple visible queries
    controls.tools.sql.style.display = "inline"
  } else {
    // there are not multiple queries, hide show sql tool
    controls.tools.sql.style.display = "none"
    controls.tools.sql.firstElementChild.checked = false
  }
  toggle_elements_of_class(controls.tools.sql.firstElementChild)

  if (sql_with_results === 0) {
    controls.tools.line_numbers.style.display = "none"
  } else {
    controls.tools.line_numbers.style.display = "inline"
    toggle_elements_of_class(controls.tools.line_numbers.firstElementChild)
  }


  controls.button.innerHTML = "play_circle"
  controls.button.classList.remove(`blink`)
}

function show_error(controls, message, sql_statement) {// adds the strucrue and displays an error for the query box
  const result_wrapper = document.createElement('div');
  result_wrapper.className = "result-wrapper"
  controls.query_result.appendChild(result_wrapper)

  //result_wrapper.style.width="100%"
  result_wrapper.innerHTML = `${sql_statement}<div class="error-message">${message}</div>`

}


async function save_connection(params) {
  // records the deployment ID and gets the connections available on that deployment  
  // const build_number = gas_end_point.split("/")[5]
  const payload = {
    mode : 'property',
    action : 'set',
    key : 'oracle_connections',
    dataArray : [params]
  }
  try {
    return await server_post(payload)
  } catch (e) {
    tag("error").style.display = "block"
    tag("error").innerHTML = e.message
  }
}


function popstate(event) {
  //console.log(`popstate`,event)
  load_page(event.state, true)
}

async function assessment_configuration(button) {
  //console.log("at assessment_configuration")

  let elem = button
  while (elem.className !== 'submit-bar') {
    elem = elem.parentNode
  }
  const data = JSON.parse(atob(elem.dataset.info))
  //console.log("data", data)
  //console.log("elem", elem)

  const msg = message({
    message: "Password must contain at least one Capital letter",
    title: "User Error",
    kind: "error",
    seconds: 4
  })

}

async function process_assessment(button, page_id, update_interface = true) {
  if (button.innerHTML.includes("hourglass_empty")) { return }


  // remove any feedback that may be present from a prior grading 
  for(const block of document.body.querySelectorAll(".feedback")){
    block.remove()
  }
  
  
  if (update_interface) {
     button.dataset.text = btoa(button_waiting(button, "saving"))
  }
  await save_assessment(button, false)

  const assessment_data = await get_post_json(get_url(page_id))

  //console.log("assessment_data",assessment_data)

  button_waiting(button, "Evaluating")
  
  await gradeStudentSQLs(assessment_data) // grade submissions or just get student work as appropraite
    .catch(()=> update_interface && (button.innerHTML = atob(button.dataset.text)))
  

  if(!assessment_data.scoreVisibility || assessment_data.scoreVisibility.length===0){
    // we are doing no grading, just submit the student's work
    button_waiting(button, "Submitting")
    await submit_assessment(button)
    // if there is scoreVisibilit for student or instrutor, gradeStudentSQLs will submit when complete
  }


  if (update_interface) {
    button.innerHTML = atob(button.dataset.text)
  }
}

async function submit_assessment(update_interface = true ) {
  const button=tag("submit-button")
  //console.log("at submit assessment")
  // data validation
  const data = get_user_data_object(tag("form-div"))
  const summary = object_data(data)
  //console.log("summary", summary)
  if (summary.defined !== summary.count) {
    message({
      message: "All items in submission are required.",
      title: "Submision Error",
      kind: "error",
      seconds: 8,
    })
    return
  }



  let elem = button
  while (elem.className !== 'submit-bar') {
    elem = elem.parentNode
  }


  //0    1     2       3         4         5     6  7   8   9   10  11  12  13  14  15
  //id	 name	 studid	 studname	 lastname	 email q1 q2	q3	q4	q5	q6	q7	q8	q9	q10	 
  //const field_names = ["entry.231650436", "entry.447670095", "entry.1896149029", "entry.523829530", "entry.1253890597", "entry.488240833", "entry.330043579", "entry.1292541365", "entry.441070121", "entry.1614256690", "entry.1369668819", "entry.411795143", "entry.1077827313", "entry.382602208", "entry.904079664", "entry.501564656"]
  

  // const field_values = []

  // field_values.push(encodeURIComponent(tag("form-div").dataset.assessment_id))
  // field_values.push(encodeURIComponent(tag("form-div").dataset.assessment_name))
  // field_values.push(encodeURIComponent(data.student_id))
  // field_values.push(encodeURIComponent(data.first_name))
  // field_values.push(encodeURIComponent(data.last_name))
  // field_values.push(encodeURIComponent(data.email))

  // // find the queryboxes and pull out the data
  // const answers = document.getElementsByTagName("code-input")
  // let unanswered = ""

  // for (let x = 0; x < answers.length; x++) {
  //   if (answers[x].innerText.trim().length === 0) {
  //     unanswered++
  //     field_values.push(encodeURIComponent("Left blank by student"))
  //   } else {
  //     field_values.push(encodeURIComponent(answers[x].innerText))
  //   }
  // }

  // if (unanswered) {
  //   //console.log("student did not answer all the questions.")
  // }

  // for (let x = 0; x < 16; x++) {
  //   field_values[x] = field_names[x] + "=" + field_values[x]
  // }


  // from: roadsql form named freceiver  1Q8gdNFC6E9uARxPouRTn08sIX_tNUct7fQedJzZdDcI
  // each cell in google sheets can only hold 50,000 characters, so the fields are to allow us to
  // handle submissions up to 500k

  ASSESSMENT_SUBMISSION_DETAILS.studentId=data.student_id
  ASSESSMENT_SUBMISSION_DETAILS.firstName=data.first_name
  ASSESSMENT_SUBMISSION_DETAILS.lastName=data.last_name
  ASSESSMENT_SUBMISSION_DETAILS.email=data.email
  ASSESSMENT_SUBMISSION_DETAILS.submissionType="assessment"

  ASSESSMENT_SUBMISSION_DETAILS.assessmentName=document.getElementsByTagName("h1")[0].innerHTML

  

  const response = await submit_backend_package(ASSESSMENT_SUBMISSION_DETAILS)


  if (response.status === "failure") {
    message({
      message: response.message,
      title: "Submision Error",
      kind: "error",
      seconds: 8,
    })
    return
  } else {
    message({
      message: "Your work has been submitted",
      title: "Success",
      seconds: 3,
    })
  }

  button.innerHTML = atob(button.dataset.text)
}


async function submit_backend_package(payload){
  // sends information to a google form, needs to be gereralized for paid backend
  const url = `https://docs.google.com/forms/u/0/d/e/${get_from_book_storage("courseCode")}/formResponse`
  const reply = await fetch(url, {
    method: `POST`,
    mode: 'no-cors',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'//;charset=UTF-8'
    },
    body: build_google_form_payload(payload)
  })
  return await reply.text()
}


function build_google_form_payload(payload_object){
  //takes an object and returns the body necessary to submit to the form processor
  const field_ids=[333028646,1323973366,275531788,1122039756,344552657,827802822,904289242,2102328485,1822900509,1808139614]
  // split base 64 data into 50k blocks
  const payload = btoa(JSON.stringify(payload_object)).match(/.{1,50000}/g) ?? [];
  
  for(let x=0; x<payload.length; x++){
    const segment = payload[x]
    payload[x] = "entry." + field_ids[x] + "=" + encodeURIComponent(segment)
  }
  return payload.join("&")
}

async function gradeStudentSQLs(assessment_data) {
  const student_sqls = userCodeOnPage()
  ASSESSMENT_SUBMISSION_DETAILS.tasks=[]
  ASSESSMENT_SUBMISSION_DETAILS.tasksComplete=0
  ASSESSMENT_SUBMISSION_DETAILS.graded=false


  // set up grading report
  for (let index = 0; index < assessment_data.tasks.length; index++) {
    const task = assessment_data.tasks[index]
    ASSESSMENT_SUBMISSION_DETAILS.tasks.push({answer:student_sqls[index]})
  }

  if (assessment_data.scoreVisibility.length===0){
    // not graded for student or professor
    // all we need is the sudent's answers, and we have them now
    return
  }

  //console.log("assessment_data",assessment_data)

  const blocks=document.body.querySelectorAll(".query-editor")
  //const div = tag("student_grade_results")
  //div.innerHTML = ''

  // close all query results
  for(result_div of document.body.querySelectorAll(".query-result")){
    result_div.innerHTML=""
  }

  for (let index = 0; index < assessment_data.tasks.length; index++) {
    const task = assessment_data.tasks[index]
    const student_sql = student_sqls[index]
    const graderUpdateDiv = tag("grader_updates")
    // const gradeResultdiv = document.createElement('div')
    // div.append(gradeResultdiv)
    const updateGraderDivContents = e => {
      //console.log("at updateGraderDivContents", e.detail.message)
      graderUpdateDiv.style.duplay="block"
      graderUpdateDiv.innerText = e.detail.message
    }
    //console.log("about to make grade")
    const grader = QueryGrader.new(get_book_db_type(), assessment_data)
    document.addEventListener(grader.eventName, updateGraderDivContents)
    //gradeResultdiv.innerHTML =
    //  `<b>Results for problem ${index + 1}: </b> <span class='i'>${task.text}</span> <br>`
    const resultDiv = document.createElement('div')
    resultDiv.className="feedback"
    resultDiv.innerHTML = '<div class="center"><span class="material-symbols-outlined blink" style="vertical-align:middle">hourglass_empty</span></div>'
    //gradeResultdiv.append(resultDiv)
    blocks[index].append(resultDiv)

    grader.grade_query(
      task.key,
      remove_comments_from_query(student_sql),
      task.required_terms,
    ).then(grade => {

      //console.log("grade", grade)
      let header_div='<div class="feedback-pane"><div class="feedback-header">Full Credit</div>'

      let points_earned=task.points
      let feedback_text
      //console.log("grade", grade)
      const grade_percent = grade.full_percent || grade.percent
      if(grade.full_credit){
        feedback_text = pick_one(['Great job','Outstanding','Oh, you are good','Good show','Nice work','Excellent job','Magnificent','Give yourself a pat on the back','Nicely done','Awesome','Fabulous work','Your are superb'])+"."
      }else if(grade_percent){
        const rci = grade.complexity_index
        const final_percent = Math.round((rci *grade_percent)*100)/100
        // const final_percent = Math.round((rci + ((1-rci) *grade_percent))*100)/100
        //console.log("final grade",final_percent, rci)
        header_div='<div class="feedback-header" style="background-color:Goldenrod">Partial Credit</div>'
        points_earned = Math.round(task.points * final_percent*100)/100

        //console.log("---"," grade.full_percent", grade.full_percent)
        //console.log("---","grade.percent",grade.percent)

        feedback_text=`That's ${Math.round(final_percent*10000)/100}% <br>${grade.feedback}`
      }else{
        points_earned=0
        precent_earned=0
        header_div='<div class="feedback-header" style="background-color:DarkRed">Incorrect</div>'
        if(student_sql.trim().length>0){
          feedback_text = grade.feedback
        }else{
          feedback_text = "It appears that you did not enter a solution"
        }
      }

      //document.removeEventListener(grader.eventName, updateGraderDivContents)
      resultDiv.innerHTML = `<div class="feedback-pane">${header_div}<div style="padding:0.5rem 1rem">
      Possible: ${task.points}<br>
      Earned: ${points_earned}<br>
      ${feedback_text}
      </div></div>
      `
      updateGraderDivContents({ detail: { message: "Grading complete" } })
      update_grading_progress(index, {
        possible:task.points,
        earned:points_earned,
        feedback:feedback_text,
        answer:student_sql
      })
    }).catch(err=>{
      console.error(err)
      let msg = "We were unable to grade the query. This is probably because of a network error. There may also be a problem with your code. Please review your code and try again."
      if (err instanceof ShowableError) {
        msg = err.message
      }
      resultDiv.replaceChildren(
        ui_feedback_pane(
          "Something went wrong!", 
          msg, 
          true
        )
      )
    })
  }
}

function update_grading_progress(task_index, task_report){
  // used to tell when all queries have completed grading
  ASSESSMENT_SUBMISSION_DETAILS.tasksComplete++
  ASSESSMENT_SUBMISSION_DETAILS.tasks[task_index]=task_report
  //console.log("----------------update_grading_progress------------------------")
  //console.log("complete",ASSESSMENT_SUBMISSION_DETAILS.tasksComplete)
  //console.log("total",ASSESSMENT_SUBMISSION_DETAILS.tasks.length)
  //console.log("report", task_report)
  let total_possible = 0
  let total_earned = 0
  if(ASSESSMENT_SUBMISSION_DETAILS.tasksComplete===ASSESSMENT_SUBMISSION_DETAILS.tasks.length){
    for(const task of ASSESSMENT_SUBMISSION_DETAILS.tasks){
      total_possible+=task.possible
      total_earned+=task.earned
    }
    ASSESSMENT_SUBMISSION_DETAILS.graded=true
    ASSESSMENT_SUBMISSION_DETAILS.points_possible=total_possible
    ASSESSMENT_SUBMISSION_DETAILS.points_earned=total_earned
    ASSESSMENT_SUBMISSION_DETAILS.score=Math.round((total_earned/total_possible)*10000)/100
    //console.log(ASSESSMENT_SUBMISSION_DETAILS)
    submit_assessment()
  }
  
}

function pick_one(choices){
  //returns a random entry from an array
  return choices[Math.floor(Math.random() * choices.length)]
}

function button_waiting(button, text, icon = "hourglass_empty") {
  const old_value = button.innerHTML
  button.innerHTML = `${text} <span class="material-symbols-outlined blink" style="vertical-align:middle">${icon}</span>`
  return old_value
}

/**
 * @returns {[SQLText]} Array of users queries
 */
function userCodeOnPage() {
  const answers = document.getElementsByTagName("code-input")
  const work = []
  for (let x = 0; x < answers.length; x++) {
    work.push(answers[x].innerText)
  }
  return work
}

async function save_assessment(button, update_interface = true) {
  // save's a student's work to bookstorage


  //if (button.innerHTML.includes("hourglass_empty") && update_interface) { return }

  //const data = get_user_data_object(tag("form-div"))
  const answers = document.getElementsByTagName("code-input")
  const work = []

  for (let x = 0; x < answers.length; x++) {
    work.push(answers[x].innerText)
  }
  //console.log("data",work)
  const assignment_id=string_to_token(BookStorage.currentPage())
  if(!BookStorage.exists(assignment_id)){BookStorage.addItem(assignment_id)}
  BookStorage[assignment_id](work)


  return
}


function string_to_token(data){
  // accepts an arbitrary string and returns a string that is a valid variable name, replacing all special characers with the underscore
  const data_array = data.split("")
  for(let x=0;x<data_array.length;x++){
    if((data_array[x].charCodeAt(0)>47 && data_array[x].charCodeAt(0)<58) || data_array[x].toUpperCase() !== data_array[x].toLowerCase()){
	   data_array[x]=data_array[x].toLowerCase()		
    }else{
      data_array[x]="_"
    }
  } 
  if(data_array[0].charCodeAt(0)>47 && data_array[0].charCodeAt(0)<58){
    data_array.unshift("_")
  }
  return data_array.join("")
}

function get_user_data_object(elem) {
  //builds an object from all input elements in a containing elem

  const data = {}
  for (const input of elem.getElementsByTagName("input")) {
    data[input.id.split("-").join("_")] = input.value
  }
  return data
}

function object_data(object) {
  // returns the number of top-level keys in an object and the number of those which are defined
  const data = {
    count: 0,
    defined: 0
  }
  for (const value of Object.values(object)) {
    data.count++
    if (value !== undefined && value.trim() !== '') {
      data.defined++
    }
  }
  return data
}


async function load_assessment(page_id) {

  const panel = show_panel(section_map[page_id])

  //document.getElementById(`page-body`).innerHTML = ` <div style='text-align:center'><span id='loading-message'>Loading Assessment</span>
  panel.innerHTML = ` <div style='text-align:center'><span id='loading-message'>Loading Assessment</span>
  <span class='material-symbols-outlined blink' style='vertical-align:middle;'>
    hourglass_empty
  </span>
</div>`


  let ass_obj = await get_post_content(get_url(page_id), post_list[page_id].format)
  //console.log("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
  //console.log(ass_obj)
  if (!ass_obj.schema) { ass_obj.schema = "" }
  if (!ass_obj.diagram) { ass_obj.diagram = "" }
  if (!ass_obj.height) { ass_obj.height = 10 }
  ass_obj.title = post_list[page_id].label
  const ass_html = [`<h1 id="select-practice">${ass_obj.title}</h1>`]
  ass_html.push(`<p>${ass_obj.text}</p>`)


  // look for earlier saved work 
  const assignment_id=string_to_token(page_id)
  if(!BookStorage.exists(assignment_id)){BookStorage.addItem(assignment_id)}
  const saved_work = get_from_book_storage(assignment_id)
  if (saved_work) {
    // set the start property to the student's saved work
    for (let x = 0; x < saved_work.length; x++) {
      ass_obj.tasks[x].start = saved_work[x]
    }
  }

  let task_num = 0
  for (const task of ass_obj.tasks) {
    task_num++
    //console.log(task_num, task)
    const sql = task.start || ""
    const connection = task.connection || ass_obj.connection
    const schema = task.schema || ass_obj.schema
    const owner = task.owner || ass_obj.owner
    const diagram = task.diagram || ass_obj.diagram
    const height = task.height || ass_obj.height
    //console.log("schema", schema)
    //ass_html.push(`<div class="task-text">${task.text}</div>`)
    ass_html.push(await get_query_block({
      sql: sql,
      connection : connection,
      schema : schema,
      note:task.text,
      owner : owner,
      filename : `result-${task_num}`,
      diagram_settings : diagram,
      query_box_height :height 
      }))
  }

  // place the submission footer
  ass_html.push(`<div id="submit-div" class="submit-bar">

    <button onclick="save_assessment(this)">
      Save 
      <span class="material-symbols-outlined"  style="vertical-align:middle">
        save
      </span>
    </button>

    <button id="submit-button" onclick="process_assessment(this, '${page_id}')">
      Submit 
      <span class="material-symbols-outlined"  style="vertical-align:middle">
        send
      </span>
    </button>

  </div>
  <div id="form-div" data-assessment_id="${page_id}" data-assessment_name="${ass_obj.title}" class="form-bar" style="display:none">
    <div style="width:400px;display:inline-block">
      <div style="text-align:center; background-color:#0F52BA; color:white; font-weight:bold;">
        Submision Data
      </div>
      <div class="form-page">
        <table>
          <tr>
            <td onclick="toggle_next_row(this)" style="cursor:pointer">
              Student&nbsp;ID:
            </td><td>
              <input type="text" id="student-id">
            </td></tr><tr style="display:none"><td></td><td>
              This is your identifier at school.  Your instructor uses this to give you credit for your work.
            </td>
          </tr>

          <tr>
            <td onclick="toggle_next_row(this)" style="cursor:pointer">
              First&nbsp;Name:
            </td><td>
              <input type="text" id="first-name">
            </td></tr><tr style="display:none"><td></td><td>
              This is your given name.  It's probabaly what your friends call you.
            </td>
          </tr>

          <tr>
            <td onclick="toggle_next_row(this)" style="cursor:pointer">
              Last&nbsp;Name:
            </td><td>
              <input type="text" id="last-name">
            </td></tr><tr style="display:none"><td></td><td>
              This is your family name.  
            </td>
          </tr>

          <tr>
            <td onclick="toggle_next_row(this)" style="cursor:pointer">
              Email:
            </td><td>
              <input type="text" id="email">
            </td></tr><tr style="display:none"><td></td><td>
              This will make it easy for your instructor to contact you about your submission.
            </td>
          </tr>

          <tr>
            <td onclick="toggle_next_row(this)" style="cursor:pointer">
              Class&nbsp;Key:
            </td><td>
              <input type="text" id="class-key" size="38">
            </td></tr><tr style="display:none"><td></td><td>
              This is a code issued by your instructor.  It's what allows your instructor receive to your submission.
            </td>
          </tr>
        </table>
      </div>
    </div>
  </div>
  <div id="student_grade_results" style="display:none"></div>
  <div id="grader_updates"  style="display:none"></div
  `)

  //document.getElementById(`page-body`).innerHTML=ass_html.join(``)
  panel.innerHTML = ass_html.join(``)
  try{
  codeInput.registerTemplate('code-input', codeInput.templates.prism(Prism, [new codeInput.plugins.Indent()]));
  }catch(e){
    console.error(e)
  }
  get_diagrams()

  creds={
    assignmentName: ass_obj.title,
    assignment_id: page_id,
    id:get_from_book_storage("studentId",""),
    firstName:get_from_book_storage("studentFirstName",""),
    lastName:get_from_book_storage("studentLastName",""),
    email:get_from_book_storage("studentEmail",""),
    key:get_from_book_storage("courseCode","")
  }
   //console.log("creds", creds)
  
  tag("student-id").value = creds.id
  tag("first-name").value = creds.firstName
  tag("last-name").value = creds.lastName
  tag("email").value = creds.email
  tag("class-key").value = creds.key

  if (!(creds.id && creds.firstName && creds.lastName && creds.email && creds.key)) {
    tag("form-div").style.display = "block"
  }
}



async function query_editor(page_id) {

  const panel = show_panel(section_map[page_id])

  //document.getElementById(`page-body`).innerHTML = ` <div style='text-align:center'><span id='loading-message'>Loading Assessment</span>


  let query_editor_data = get_from_book_storage("queryEditor",null)

  if(query_editor_data===null){
    //console.log("getting default")
    panel.innerHTML = ` <div style='text-align:center'><span id='loading-message'>Loading Assessment</span>
      <span class='material-symbols-outlined blink' style='vertical-align:middle;'>
        hourglass_empty
      </span>
      </div>`
    query_editor_data = await get_post_content(get_url("query-editor"),"json")
  }

  const new_query=sessionStorage.getItem("open_query_in_editor")
  if(new_query){
    // now that we  have the new query script, we need to remove it from session storage
    // it's only there to handle the refresh from some page to the query editor
    sessionStorage.removeItem("open_query_in_editor")
    query_editor_data.scripts.unshift(JSON.parse(new_query))
  }



  //query_editor_data.title = post_list[page_id].label
  const ass_html = [`<h1 contenteditable id="editor-title">${query_editor_data.title}</h1>`]
  ass_html.push(`<p contenteditable id="editor-text">${query_editor_data.text}</p>`)



  let script_num = 0
  for (const script of query_editor_data.scripts) {
    script_num++
    if(!script.tablename){
      script.tablename = `result-${script_num}`
    }
    script.kind="editor"
    ass_html.push(await get_query_block(script))
  }

  // place the submission footer
  ass_html.push(`<div id="submit-div" class="submit-bar">
    <button onclick="get_editor(this)">
      From Web
      <span class="material-symbols-outlined"  style="vertical-align:middle">
      language
      </span>
    </button>

    <button onclick="export_editor(this)">
      Export
      <span class="material-symbols-outlined"  style="vertical-align:middle">
      download
      </span>
    </button>

    <input id="uploadInput" type="file" style="display:none;">
    <button onclick="tag('uploadInput').click()">
      Import
      <span class="material-symbols-outlined"  style="vertical-align:middle">
      publish
      </span>
    </button>

    <button onclick="save_editor(this)">
      Save 
      <span class="material-symbols-outlined"  style="vertical-align:middle">
        save
      </span>
    </button>

  `)

  //document.getElementById(`page-body`).innerHTML=ass_html.join(``)
  panel.innerHTML = ass_html.join(``)



  tag('uploadInput').addEventListener('change', function() {
    const fr=new FileReader();
    fr.onload=function(){import_editor(fr.result)}
    fr.readAsText(this.files[0]);
})

  codeInput.registerTemplate('code-input', codeInput.templates.prism(Prism, [new codeInput.plugins.Indent()]));
  
  get_diagrams()
}


async function tutorials(page_id) {
  if(!page_id){page_id="tutorials"}
  const panel = show_panel(section_map[page_id])

  //document.getElementById(`page-body`).innerHTML = ` <div style='text-align:center'><span id='loading-message'>Loading Assessment</span>
  panel.innerHTML = ` <div style='text-align:center'><span id='loading-message'>Loading Assessment</span>
  <span class='material-symbols-outlined blink' style='vertical-align:middle;'>
    hourglass_empty
  </span>
</div>`

  let tutorials_data = get_from_book_storage("tutorials",null)

  if(!tutorials_data){
    //console.log("getting default")
    tutorials_data = await get_post_content(get_url("tutorials"),"json")

    for(let t=0;t<tutorials_data.tutorials.length;t++){// set the default page on each tutorial
      tutorials_data.tutorials[t].currentPage=0
    }
    BookStorage.tutorials(tutorials_data)
  }
  
  // now we have either the default tutorial set, or the users's set

  // get the current tutorial
  console.log("tutorials_data",tutorials_data)
  const url = tutorials_data.tutorials[tutorials_data.currentTutorial].url
  
  let tutorial
  if(url.toLowerCase().startsWith("http")){
    const response = await fetch(url)
    tutorial = await response.json()
  }else{    
    tutorial = await get_post_json(get_url(url))      
  }

  console.log("tutorial",tutorial)

  

  //tutorials_data.title = post_list[page_id].label
  const ass_html = [`<div id="tutorial" style="display:none">${btoa(JSON.stringify(tutorial))}</div><div id="tutorial-page">`]
  ass_html.push(`<div style="padding:.5rem;background-color:#0F52BA;text-align:center"><select onchange="load_tutorial(this)" id="select-tutorial" style="border:none;font-size:1.5rem;font-weight:bold;background-color:#0F52BA;color:whitesmoke;text-align:center">`)
  for(let t=0;t<tutorials_data.tutorials.length;t++){
    const one_tutorial = tutorials_data.tutorials[t]
    let selected=""
    console.log(t,tutorials_data.currentTutorial )
    if(t==tutorials_data.currentTutorial){
      selected=" selected"
    }
    ass_html.push(`<option value="${t}"${selected}>${one_tutorial.title}</option>`)
  }
  ass_html.push(`<option value="-1">Load Tutorials</option>`)
  ass_html.push(`</select></div><div id="tutorial-text">${tutorial.text}</div><div id="tutorial-page-content"></div>`)


  // place the submission footer
  ass_html.push(`<div id="submit-div" class="submit-bar">
    <table style="width:100%"><td><td style="text-align:left">
    <button id="tutorial-prior" onclick="render_tutorial_page('prior')">
      <span class="material-symbols-outlined"  style="vertical-align:middle">
        skip_previous
      </span>
      Prior Tutorial Page
    </button>
    </td><td style="text-align:right">
    <button id="tutorial-next" onclick="render_tutorial_page('next')">
      Next Tutorial Page
      <span class="material-symbols-outlined"  style="vertical-align:middle">
        skip_next
      </span>
    </button>
    </td></tr></table>
  `)
  
  //document.getElementById(`page-body`).innerHTML=ass_html.join(``)
  panel.innerHTML = ass_html.join(``)

  await render_tutorial_page()

  codeInput.registerTemplate('code-input', codeInput.templates.prism(Prism, [new codeInput.plugins.Indent()]));
  get_diagrams()
}
async function render_tutorial_page(page="current"){
  //renders one page of a tutorial.  page can be "current", "prior", "next", or a page index

  const tutorial        = JSON.parse(atob(tag("tutorial").innerHTML))  
  const tutorial_data   = BookStorage.tutorials()
  const tutorial_number = tutorial_data.currentTutorial
  let   page_number     = tutorial_data.tutorials[tutorial_number].currentPage
  const last_page       = tutorial.pages.length-1

  switch(page){
    case "next":
      page_number++
      break
    case "prior":
      page_number--
      break  
    case "current":
      break  
    default:
      page_number=parseInt(page)
      // assume we have a page number to show  
  }

  tag("tutorial-next").style.display=""
  tag("tutorial-prior").style.display=""

  if(page_number>=last_page){
    page_number=last_page
    tag("tutorial-next").style.display="none"
  }else if(page_number<=0){
    page_number=0
    tag("tutorial-prior").style.display="none"
  }
  
  if(page_number===0){
    tag("tutorial-text").style.display="block"
  }else{
    tag("tutorial-text").style.display="none"
  }

  tutorial_data.tutorials[tutorial_number].currentPage = page_number
  BookStorage.tutorials(tutorial_data)



  const tutorial_page=tutorial.pages[page_number]
  const html=[]
  //html.push(`${tutorial_page.title}`)
  html.push(`<select onchange=render_tutorial_page(this.value) style="border:none;font-size:1.5rem;font-weight:bold;margin-top:1rem">`)
  for(let p=0;p<tutorial.pages.length;p++){
    const page = tutorial.pages[p]
    console.log(page)
    html.push(`<option value="${p}"${p===page_number?" selected":""}>${page.title}</option>`)  

  }
  html.push(`</select>`)
  html.push(`<p>${tutorial_page.text}</p>`)
  let script_num = 0
  for (const script of tutorial_page.scripts) {
    script_num++
    if(!script.tablename){
      script.tablename = `result-${script_num}`
    }
    script.editor=true
    script.kind="tutorial"
    html.push(await get_query_block(script))
  }
 tag("tutorial-page-content").innerHTML=html.join("")
}




function get_from_book_storage(attribute, alternate=""){
  //gets a value from book storage or it's alternate
  try{
    return BookStorage[attribute]()
  }catch(e){
    return alternate
  }
}

function toggle_next_row(clicked_elem) {
  // toggles the visibility of next row of a table.  used for showing field help in a form
  let elem = clicked_elem
  while (elem.tagName !== 'TR') {
    elem = elem.parentNode
  }
  elem = elem.nextElementSibling
  if (elem.style.display === "none") {
    elem.style.display = ""
  } else {
    elem.style.display = "none"
  }
}

function remember_diagram(diagram) {
  DIAGRAMS[diagram.id] = {
    history: [],
    history_position: 0,
    query: { select: [], from: [], tables: [] },
    sql: diagram.parentNode.getElementsByTagName("textarea")[0],
  }
}

// /**
//  * resets the data dictioanry state for the given ID
//  * @param {string} id the ID from the data dictionary block / div
//  */
// function reset_data_dictionary_state(id) {
//   DIAGRAMS[id] = {
//     history: [],
//     history_position: 0,
//     query: { select: [], from: [], tables: [] },
//     sql: document.getElementById(id).parentElement.getElementsByTagName("textarea")[0],
//   }
// }

async function get_diagrams() {
  // fetch the diagrams async
  DIAGRAMS = {}
  for (const diagram of document.querySelectorAll(".query-diagram")) {
    const response = await resource_manager.get_post_content(get_url(diagram.dataset.diagramPage, "-diagram"))
    diagram.id = uuid()
    diagram.innerHTML = response.split("image-map").join("map-" + diagram.id)
    remember_diagram(diagram)

    for (let link of diagram.getElementsByTagName("area")) {
      link.addEventListener("click",amend_sql_click)
      link.addEventListener("mouseenter", show_note)
      link.addEventListener("mouseleave", clear_notes)
    }
  }
  // // fetch data dictionary
  // for (const dictionary_block of document.querySelectorAll(".query-dictionary")) {
  //   const dict_data = await resource_manager.get_post_content(get_url(dictionary_block.dataset.dictionaryPage, "-dictionary"), "json")
  //   dictionary_block.id = uuid()
  //   for (const table of dict_data.tables) {
  //     const card = ui_card(ui_card_head(table.name, table.description), ...table.feilds.map(feild => {
  //       const header = ui_header(feild.name)
  //       header.onclick = function () {
  //         amend_sql(undefined, id, title)
  //       }
  //       const content = ui_content(feild.description)
  //       return ui_card_body_item(header, content)
  //     }))
  //     card.classList.add("ui-min-width", "ui-max-width")
  //     dictionary_block.append(ui_inline_block(card))
  //   }
  //   remember_diagram(dictionary_block)
  // }
}


function clear_notes(event){
  //console.log("at clear notes")
  const area = event.target
  //clear a note from teh schema diagra and cancel any timeouts that have not been processed
  for(const one_timeout of DIAGRAM_NOTE_TIMEOUTS){
    clearTimeout(one_timeout)
  }
  DIAGRAM_NOTE_TIMEOUTS.length=0

  let elem=area
  while(elem.className!=="query-diagram"){
    elem=elem.parentNode
  }

  for(const note of document.querySelectorAll(".schema-note")){
    note.remove()
  }

}


function show_note(event){
  // show a note on on the db schema diagram
  
  const area = event.target
  DIAGRAM_NOTE_TIMEOUTS.push(setTimeout((area) => {
    //console.log("event",event)
    const margin=10
    const coords = area.coords.split(",")
    // //console.log("coords",coords)
    // for(let x=0;x< coords.length;x++){
    //   coords[x] = coords[x]
    // }
    // //console.log("coords2",coords)
    let elem=area
    while(elem.className!=="query-diagram"){
      elem=elem.parentNode
    }

    //console.log("query-diagram", elem)
    const image = elem.getElementsByTagName("img")[0]
    let rect = getCoords(image)
    // //console.log("rect", rect)
  
    const doc_center = document.body.clientWidth/2

    let left
    let left2
    let top
    let classname="right"
     
    if(area.dataset.kind==="table"){
      left = rect.left + parseInt(coords[2])
      left2 = rect.left + parseInt(coords[0])
      top = rect.top+parseInt(coords[1])-5 
      if(Math.abs(doc_center-left) > Math.abs(doc_center-left2)){
         // place callout to right
         left=left2 - 216
         classname="left"
      }else{
        // place callout to left
        left=left+margin
      }  
    }else{
      //relationship
      //console.log("event.pageX",event.pageX)
      //left=rect.left+event.offsetX +0
      left=event.pageX+25
      top=Math.round(rect.top+event.offsetY) -25
      if(left > doc_center){
        left=left - 250
        classname="left"
      }
    }

    //console.log("left",left, doc_center)
    //console.log("top",top, typeof top)

    const note = document.createElement(`div`)
    note.innerHTML = `<div class="schema-note-title">${area.dataset.heading}</div><div class="schema-note-body">${area.dataset.note}</div>`
    note.className = "schema-note callout " + classname
    note.style.position = "absolute"
    note.style.top = top + "px"
    note.style.left = left + "px"
    note.style.width="200px"
    note.style.zIndex=10
    document.body.appendChild(note)
  }, "1000",area))
}

function getCoords(elem) {
  // get coords of elem WRT document
  let box = elem.getBoundingClientRect();
  return {
    top: box.top + window.pageYOffset,
    right: box.right + window.pageXOffset,
    bottom: box.bottom + window.pageYOffset,
    left: box.left + window.pageXOffset
  };
}

// --------------- Automatic Querr Writing Refactored -----------------------

/**
 * 
 * @param {string} title 
 * @param {HTMLTextAreaElement} sql_editor 
 */
function amend_sql_v2(title, sql_editor) {
  const history = []

  // check to see if the query is empty, if so, we are resetting the query
  if (sql_editor.value.trim().length === 0) {
    history = []

  }
}

//--------------End of Automatic Querr Writing Refactored--------------------

function amend_sql_click(event){
  // used to get data from event and pass to amend sql
  //console.log("event",event)

  amend_sql(event)
}

// functions for automatic query writing===================
function amend_sql(area_or_event, _id, title) {
  let area=area_or_event
  let evt=""
  if(area.ctrlKey!==undefined){
    // an event was passed in
    evt=area
    area=evt.target
  }

  //console.log("area",typeof area)

  const diagram = area?.parentNode?.parentNode || null
  const id = diagram?.id || _id
  let fragment = area?.dataset.title || title

  //console.log(area, id)

  // check to see if the query is empty, if so, we are resetting the query
  if (DIAGRAMS[id].sql.value.trim().length === 0) {
    //reset the query
    DIAGRAMS[id].history = []
    DIAGRAMS[id].history_position = 0
    DIAGRAMS[id].query = { select: [], from: [], tables: [] }
  }

  if (!(DIAGRAMS[id].sql.value.trim() === get_local_sql(id))) {
    // insert the item a the appropriate place in the edited query
    if(area.dataset.kind==="table"){
      if(!evt.ctrlKey){
        // only insert tablename if ctrl key is down
        fragment = fragment.split(".")[1]
      }
      if(evt.shiftKey){
        // prepend a space an a comma if shift key isdown
        fragment = ", "+fragment
      }

    }
    DIAGRAMS[id].sql.setRangeText(fragment, DIAGRAMS[id].sql.selectionStart, DIAGRAMS[id].sql.selectionEnd, 'select');
    const pos = DIAGRAMS[id].sql.selectionStart + fragment.length
    DIAGRAMS[id].sql.setSelectionRange(pos, pos);

    sync_query_text(id)
    DIAGRAMS[id].sql.focus()
    return
  }

  // we are in full build mode
  let msg = ""
  if (fragment.indexOf(".") === -1) {
    // we have a table only
    msg = add_field(id, fragment, "*")
    if (msg) {
      message({
        message: msg,
        title: "Problem Building SQL",
        seconds: 4,
        kind: "error",
        show: true
      })
    return
    }
  } else if (fragment.indexOf(" JOIN ") === -1) {
    // we have a dot in in the title and no join, it must be a field
    //console.log("trying to add a field")
    msg = add_field(id, fragment.split(".")[0], fragment.split(".")[1])
    if (msg) {
      message({
        message: msg,
        title: "Problem Building SQL",
        seconds: 4,
        kind: "error",
        show: true
      })
    return
    }

  } else {
    // atom is a link
    // find the talbes in the link
    let temp = fragment.replace(" JOIN ", " ").split(" ")
    let match_count = 0
    let table_to_add
    const table1 = temp[0]
    const table2 = temp[1]

    if (DIAGRAMS[id].query.tables.length === 0) {
      // query is empty, configure from scratch
      msg = add_field(id, table1, "*")
      if (msg) {
        message({
          message: msg,
          title: "Problem Building SQL",
          seconds: 4,
          kind: "error",
          show: true
        })
        return
      }
      // now get ready to add the join clause
      let frag = fragment.split(" ON ")[1]
      //console.log("frag",frag)
      // push the rest into the next entry
      DIAGRAMS[id].query.from.push("  JOIN  " + table2 + "\n    ON  " + frag)
      DIAGRAMS[id].query.tables.push(table2)

    } else {
      //there is already a table in the query.  need to check to see if atom join makes sense
      for (const tname of DIAGRAMS[id].query.tables) {
        if (tname === table1) {
          match_count++
          //console.log(tname, "is already in the query")
          table_to_add = table2
        }
        if (tname === table2) {
          match_count++
          //console.log(tname, "is already in the query")
          table_to_add = table1
        }
      }
      //console.log("table_to_add",table_to_add)
      if (match_count === 0) {
        message({
          message: 'Neither "' + table1 + '" nor "' + table2 + '" is already in the query, so we cannot add the selected join.',
          title: "Problem Building SQL",
          seconds: 4,
          kind: "error",
          show: true
        })

        
      } else if (match_count === 1) {
        //console.log("ready to add", fragment)
        DIAGRAMS[id].query.from.push("  JOIN  " + table_to_add + "\n    ON  " + fragment.split(" ON ")[1].replace(/ AND /g, '\n    AND '))
        DIAGRAMS[id].query.tables.push(table_to_add)
      } else {
        message({
          message: 'Both "' + table1 + '" and "' + table2 + '" are already in the query, so we cannot add the selected join.',
          title: "Problem Building SQL",
          seconds: 4,
          kind: "error",
          show: true
        })

      }
    }
  }

  // you always wanted to be able to change history, now you can
  if (DIAGRAMS[id].history_position < DIAGRAMS[id].history.length - 1) { DIAGRAMS[id].history.splice(DIAGRAMS[id].history_position + 1) }   // get rid of old history     

  if (JSON.stringify(DIAGRAMS[id].query) !== DIAGRAMS[id].history[DIAGRAMS[id].history.length - 1]) {
    DIAGRAMS[id].history.push(JSON.stringify(DIAGRAMS[id].query))
    DIAGRAMS[id].history_position = DIAGRAMS[id].history.length - 1
  }

  write_query(id)

  return false;
}
function get_local_sql(id) {
  let local_sql = "SELECT  "
  //console.log("query",query)
  // write out the query
  for (let x = 0; x < DIAGRAMS[id].query.select.length; x++) {
    if (x > 0) { local_sql += "\n        ," }
    if (DIAGRAMS[id].query.select[x].indexOf(".") === -1) {
      local_sql += DIAGRAMS[id].query.select[x]  // there is no prefix, show the whole thing.   should only happen when value is "*"
    } else if (DIAGRAMS[id].query.tables.length === 1) {
      local_sql += DIAGRAMS[id].query.select[x].split(".")[1]// there is only one table, no need to prefix
    } else {
      local_sql += DIAGRAMS[id].query.select[x]// multiple tables, let's add prefixes
    }
  }
  for (let x = 0; x < DIAGRAMS[id].query.from.length; x++) {
    local_sql += "\n"
    if (x === 0) { local_sql += "FROM    " }
    local_sql += DIAGRAMS[id].query.from[x]
  }

  if (local_sql.trim() == "SELECT") {
    return ""
  }
  return local_sql
}

function write_query(id) {
  DIAGRAMS[id].sql.value = get_local_sql(id)
  sync_query_text(id)
}

function sync_query_text(id) {
  if (DIAGRAMS[id].sql.scrollHeight > DIAGRAMS[id].sql.clientHeight) {
    DIAGRAMS[id].sql.parentElement.style.height = DIAGRAMS[id].sql.scrollHeight + "px"
  }
  DIAGRAMS[id].sql.parentElement.update(DIAGRAMS[id].sql.value); DIAGRAMS[id].sql.parentElement.sync_scroll();
}

function clear_sql(id) {
  DIAGRAMS[id].sql.value = ""
  DIAGRAMS[id].query.select = []
  DIAGRAMS[id].query.from = []
  DIAGRAMS[id].query.tables = []
}

function add_field(id, table, field) {
  //console.log("table",table)
  //console.log("field",field)
  if (DIAGRAMS[id].query.select.indexOf(table + "." + field) > -1) { return }
  if (DIAGRAMS[id].query.tables.length === 0) {
    //query is empty, just build the query
    DIAGRAMS[id].query.select.push(table + "." + field)
    DIAGRAMS[id].query.tables.push(table)
    DIAGRAMS[id].query.from.push(table)
    return
  } else if (DIAGRAMS[id].query.tables.indexOf(table) === -1) {
    // query already has some data and the table specified is nit in the list of tables, can't add field
    return "Cannot add table to query.  Try clicking ON a link instead."
  } else if (field === "*") {
    // we already have 
    return "Cannot add table to query.  Try clicking ON a field instead."
  } else if (DIAGRAMS[id].query.select.length === 1 && DIAGRAMS[id].query.select[0] === "*") {
    // there is currently only one field, and it is start.  neex to replace
    DIAGRAMS[id].query.select[0] = table + "." + field
  } else {
    // must have been a field in one of the tables in the query
    //if we already have a *, get shod of it
    if (DIAGRAMS[id].query.select.length === 1 && DIAGRAMS[id].query.select[0].substr(DIAGRAMS[id].query.select[0].length - 2, 2) === ".*") { DIAGRAMS[id].query.select.shift() }
    DIAGRAMS[id].query.select.push(table + "." + field)
  }
}








// end of functions for automatic query writing===================


function set_prior_next_link(page_id) {
  // set up all four navigation buttons
  // page_id is the current page being displayed
  let next_id
  let prior_id
  if(post_list[page_id] && post_list[page_id].hidden){
    // this is a hidden page, supress TOC, forward, next
    //console.log(post_list[page_id])
    //tag("toc").style.display="none"
    //tag("prior-next").style.display="none"
  }else{
    //tag("toc").style.display=""
    //tag("prior-next").style.display=""
    // this is a regular page, show it all
    if (page_id.match(/^contents-[0-9]+$/)) {
      //this is a section contents menu
      const menu_number = page_id.split("-")[1]
      next_id = menu[menu_number].menu[0].page
      prior_id = menu[menu_number - 1].menu[menu[menu_number - 1].menu.length - 1].page
    } else {
      // this is a regular page
      next_id = sequence[page_id]?.next
      prior_id = sequence[page_id]?.prior
    }


    // build the forward / next buttons
    if (next_id) {
      document.getElementById(`next-page`).innerHTML = `<span class='page-link' data-nav_id="${page_id}" data-move="next" onclick="navigate(event)"><span id='navigate-next-label'></span><span class='material-symbols-outlined button inline-icon'>arrow_forward</span></span>`
      //console.log("setting next button event")
      const button = tag("next-button")
      button.addEventListener("click", navigate, false);
      button.dataset.nav_id = page_id
      button.dataset.move = "next"
    } else {
      document.getElementById(`next-page`).innerHTML = ``
    }

    if (prior_id) {
      document.getElementById(`go-back-div`).innerHTML = `<span class='page-link' data-nav_id="${page_id}" data-move="prior" onclick="navigate(event)"><span class='material-symbols-outlined button inline-icon'>arrow_back</span><span id='navigate-prior-label'></span></span>`
      const button = tag("prior-button")
      button.addEventListener("click", navigate, false);
      button.dataset.nav_id = page_id
      button.dataset.move = "prior"
    } else {
      document.getElementById(`go-back-div`).innerHTML = ``
    }
  }

}

function navigate(event) {
  // make sure we scoll up to the top of the page, since the user is going to look at a new page
  window. scrollTo(0,0)
  //navigate to the next page based on the current page
  //console.log("navigate===========",JSON.stringify(event.target.dataset))
  let target=event.target
  while(!target.dataset.move){
    target=target.parentNode
  }

  const new_page_id = get_prior_next_page(target.dataset.nav_id,target.dataset.move).id
  //console.log("just got new page id", new_page_id)
  load_page(new_page_id)
}

function get_prior_next_page(page_id, prior_next){
  // takes a page_id and returns the prior or next based on the current conditional 
  //console.log("get_prior_next_page",page_id, prior_next)
  const current_db = BookStorage.dbType()
  let new_page_id=page_id
  let x = 0
  while(true){
    if(x++>100){return {}}
    new_page_id = sequence[new_page_id][prior_next]
    if(!new_page_id){
      // reached the end
      return {}
    }
    if(sequence[new_page_id].conditional){
      // the page is conditional, check if it should be shown
      //console.log("conditional",sequence[new_page_id].conditional)
      if(sequence[new_page_id].conditional.includes(current_db)){
        return {id:new_page_id,label:sequence[new_page_id].label}
      }
    }else{
      // the page is unconditional, show it
      //console.log("new page id",new_page_id)
      return {id:new_page_id,label:sequence[new_page_id].label}
    }
  }
}

function show_panel(label) {
  if(menu_list[label].hidden){
    tag("toc").style.display="none"
    tag("prior-next").style.display="none"
  }else{
    tag("toc").style.display=""
    tag("prior-next").style.display=""
  }

  const id = label_to_id(label)
  // show the panel
  for (const elem of document.querySelectorAll(".content-panel")) {
    elem.style.display = "none"
  }
  // highlight the the menu
  for (let i = 0; i < menu.length; i++) {
    if(tag(`menu-${i}`)){
      tag(`menu-${i}`).classList.remove("active")
    }
  }
  if(tag(`menu-${tag(id).dataset.menuNumber}`)){
    tag(`menu-${tag(id).dataset.menuNumber}`).classList.add("active")
  }

  tag(id).style.display = "block"
  return tag(id)
}

async function load_page(page_id, replace = false) {
  //console.log("page_id", page_id)
  //console.log("sequence", sequence)
  //console.log("section_map", section_map)
  //console.log("label_map", label_map)
  hide_toc()
  if (!page_id || page_id === "contents-0") {
    page_id = "introduction"
  }

  
  set_current_page(page_id)


  if (!replace) {
    history.pushState(page_id, ``, `/?${page_id}`)
  }

  
  set_prior_next_link(page_id)

  //console.log("at load page", page_id)
  //highlight_menu(section_map[page_id])
  //console.log("pageid", page_id)
  const panel = show_panel(section_map[page_id])
  panel.dataset.pageId = page_id

  // check to see if we are showing a section contents page
  if (page_id.match(/^contents-[0-9]+$/)) {
    //const page_body=document.getElementById(`page-body`)
    panel.innerHTML = document.getElementById("contents_" + page_id.split("-")[1]).outerHTML
    configure_book()
    return
  }


  // //console.log("page_id", page_id)
  // //console.log("sequence", sequence)
  // //console.log("label_map", label_map)

  if (post_list[page_id]?.type === "assessment") {
    // this is an assessment, treat it totally differently from regular posts
    load_assessment(page_id)
    configure_book()
    return
  }else if (post_list[page_id]?.type === "javascript") {
    // This page is loaded by running JS
    
    window[page_id](page_id);

    configure_book()
    return
  }


  //console.log(`page_id`,page_id)

  //separate js from html in post body
  const begin_script_tag = String.fromCharCode(60, 115, 99, 114, 105, 112, 116, 62)
  const end_script_tag = String.fromCharCode(60, 47, 115, 99, 114, 105, 112, 116, 62)
  const post_javascript = []
  const post_html = []
  //console.log(get_url(page_id),page_id, post_list)
  //console.log("post_list[page_id].format",post_list[page_id].format)

  let post_content
  // check to see if we are showing a section contents page
  //console.log("checking for a section contents page", page_id)
  if (page_id.match(/^contents-[0-9]+$/)) {
    //console.log("loading a section contents page")
    //const page_body=document.getElementById(`page-body`)
    if (panel.innerHTML.length = 0) {
      post_content = document.getElementById("contents_" + page_id.split("-")[1]).outerHTML
    } else {
      configure_book()
      return
    }
  } else {
    post_content = await get_post_content(get_url(page_id), post_list[page_id].format)
    //console.log("post_content",post_content)
  }

  const post_array = post_content.split(end_script_tag)

  for (const block of post_array) {
    if (block.includes(begin_script_tag)) {
      //this block has a script
      const segment = block.split(begin_script_tag)
      if (segment.length === 1) {
        // no html here
        post_javascript.push(segment[0])
      } else {
        // this segment has both HTML and JS
        post_html.push(segment[0])
        post_javascript.push(segment[1])

      }
    } else {
      // this block does not have a script
      post_html.push(block)
    }
  }

  //console.log("HTML", post_html)

  // render the html of the post 
  //document.getElementById(`page-body`).innerHTML=post_html.join(``)
  panel.innerHTML = post_html.join(``)

  // only display the tags that should be shown based on how the book is configured
  configure_book()
  
  // run the JS of the post
  if (post_javascript.length > 0) {
    const newScript = document.createElement(`script`)
    newScript.innerHTML = post_javascript.join(``)
    document.getElementsByTagName(`head`)[0].appendChild(newScript)
  }


  // if(get_cookie(`deployment_id`)){
  // we are configured to run oracle queries, highlihgt the query block
  codeInput.registerTemplate('code-input', codeInput.templates.prism(Prism, [new codeInput.plugins.Indent()]));
  // disable query editing if we are in book mode
  //console.log("get_book_db_type()", get_book_db_type())
  if (get_book_db_type() === 'book') {
    for (const textarea of document.querySelectorAll(".editor")) {
      textarea.style.display = "none"
    }
  }
  // }else{
  //   // we are not configured to run real queries, highlight the simulated ones
  //   Prism.highlightAll()
  // }
  get_diagrams()



}
function strip_trailing_div(content) {
  //console.log(`at strip trailing div.  Content:`,content, content.length)
  if (!content.includes(`<div`)) { return content }
  const post = content.split(`\n`)
  while (!post.pop().includes(`<div`)) { }
  return post.join(`\n`)
}

async function get_post_json(url) {
  // from the post, we get a div at the end of our post 
  const post = await get_post_content(url)
  console.log("-------------------",url,"---------------------")
  console.log(post)
  return JSON.parse(post)
}


async function get_post_content(url, format) {
  const response = await fetch(url)
  let post_body = await response.text();
  //console.log ("post_body",post_body)

  if (PRODUCTION_MODE) {// in production, the JS in base 64 encoded
    const parser = new DOMParser();
    const doc = parser.parseFromString(post_body, `text/html`);
    post_body = strip_trailing_div(doc.querySelector(`.post-body`).innerHTML)
  }
  

  //console.log("format",format)
  if (format === `markdown`) {
    //pre-process for any query statements
    let body = decodeHtml(post_body).split('---[SQL]---')
    //console.log("body",body)
    if (body.length === 1) {
      body=body[0]
    }else{
      // we had at least one query
      for (let x = 0; x < body.length - 2; x = x + 3) {
        let query_params = body[x + 1].trim().split("\n")
        for (let i = 0; i < query_params.length; i++) {
          const param = query_params[i].split(":")
          param[0] = '"' + param[0].trim() + '"'
          param[1] = '"' + param[1].trim() + '"'
          query_params[i] = param.join(":")
        }
        query_params = JSON.parse("{" + query_params.join(",") + "}")
        const sql = body[x + 2].trim().split("\n\n").join("\n<line break in a QuErY>")
        let query_block = await get_query_block({
          sql: sql,
          connection : query_params.connection,
          schema : query_params.schema,
          owner : query_params.owner,
          filename : query_params.result,
          diagram_settings : query_params.diagram,
          query_box_height : query_params.height
          })
        body[x + 1] = "\n" + query_block
        body[x + 2] = "\n"
      }
    }

    //pre-process AI blocks
    if(Array.isArray(body)===true){
      body = body.join("").split('---[AI]---')
    }else{
      body = body.split('---[AI]---')
    }
    //body = body.join("").split('---[AI]---')
    if (body.length === 1) {
      body=body[0]
    }else{
      // we had at least one AI block
      for (let x = 0; x < body.length - 1; x = x + 2) {
        const ai_blocks=[]
        const ai_source = JSON.parse(body[x+1])
        for(const ai_exchange of ai_source){
          ai_blocks.push(get_ai_block(ai_exchange))
        }
        body[x+1] = ai_blocks.join("")
        
      }
    }

    //pre-process sidebars

    if(Array.isArray(body)===true){
      body = body.join("").split('---[SIDEBAR]---')
    }else{
      body = body.split('---[SIDEBAR]---')
    }
    //body = body.join("").split('---[SIDEBAR]---')
    if (body.length === 1) {
      body=body[0]
    }else{
      // we had at least one sidebar
      for (let x = 0; x < body.length - 1; x = x + 2) {
        console.log(body[x+1])
        const sidebar=JSON.parse("{" + body[x+1] +"}")
        body[x+1] = `<div class="sidebar">
        <div class="sidebar title ${sidebar.type}"><table><tr><td style="width:100%">${sidebar.title}</td><td style="text-align: right;">${sidebar.type.charAt(0).toUpperCase()
          + sidebar.type.slice(1)}</td></tr></table></div>
        <div class="sidebar body">${sidebar.text}</div></div>
    `
        
      }
    }

    //pre-process figures

    if(Array.isArray(body)===true){
      body = body.join("").split('---[FIGURE]---')
    }else{
      body = body.split('---[FIGURE]---')
    }
    // body = body.join("").split('---[FIGURE]---')
    if (body.length === 1) {
      body=body[0]
    }else{
        // we had at least one image
      let figure_number=1
      const figures=[]
      for (let x = 0; x < body.length - 1; x = x + 2) {
        console.log(body[x+1])
        const figure=JSON.parse("{" + body[x+1] +"}")
        body[x+1] = `<div class="figure-container"><div class="figure">
        <div class="figure body"><img src="${figure.url}" title="${figure.altText}"></div>
        <div class="figure title">Figure ${figure_number}:&nbsp; ${figure.title}</div>
    </div></div>`
        figures.push(figure.id)  
        figure_number++
      }
      body=body.join("")
      // now replace the figure numbers
      for(let x=0;x<figures.length;x++){
        body=body.split(`---[${figures[x]}]---`).join(`Figure ${x+1}`)
      } 
    }


    const ai_name_regex = /\^ai_name\^/g;
    const db_name_regex = /\^db_name\^/g;
    return marked.parse(body)
      .split("<line break in a QuErY>")
      .join("\n")
      .replace(ai_name_regex, '<span class="conditional gpt">ChatGPT</span><span class="conditional bard">Bard</span><span class="conditional bing">Bing Chat</span>')
      .replace(db_name_regex, '<span class="conditional sqlite">SQLite</span><span class="conditional oracle">Oracle</span><span class="conditional dataworld">data.world</span>')

  } else if (format === `json`) {
    return JSON.parse(post_body)
  } else {
    return post_body
  }

}

function get_ai_block(ai){
  console.log("ai",ai)
  let post_block = ai.posttext
  let pre_block = ai.pretext  
  // height
  let height = ai.responseHeight
  if (!height) { height = ai.response.split("\n").length }
  if (height < 3) {
    height = 3
  } else if (height > 30) {
    height = 30
  }
  return `<div style="width:90%;background-color:#CFD4D2;color:#384440;margin:auto;padding:1rem 0;margin-top:1rem;margin-bottom:1rem;border-radius:5px">
  <div style="width:90%;margin:auto; border: 2px solid #6F7975;border-radius: 10px;background-color:#EFF1F0;margin-bottom:1rem;padding:.2rem .5rem;filter: drop-shadow(4px 4px 4px #7D7F7E);"><table><tr><td style="width:100%">${ai.prompt}</td><td style="vertical-align:bottom;"><span class="material-symbols-outlined" style="vertical-align: middle">send</span></td></tr></table></div>
  <div style="width:95%;margin:auto;">${pre_block}
  <code-input lang="sql" class="rows-${height}" value="${ai.response}" style="margin: 1rem 0; "></code-input>
  ${post_block}
  </div></div>
`


}

function get_attribute(tag, attribute_name, delimiter = '"') {
  //accepts a tag and an attribute name and retrens the attriute's value
  const splitted = tag.split(attribute_name)
  if (splitted.length === 1) { return null }
  return splitted[1].split(delimiter)[1].split(delimiter)[0]
}


function build_section_map(section_map, menu, level = 0, toc, top_level_menu) {
  //section map is an object to map name of pages to thier sections so se can highlight a section when a page is direct-loaded  
  let menu_number = 0
  //console.log("menu in build section map", menu)
  const menu_condition_list=[]
  for (let m=0;m<menu.length;m++) {
    // build conditional display classnames
    const entry = menu[m]
    let conditional_display_classes = ""
    let condition_list=["ALL"]
    if (entry.conditional) {
      conditional_display_classes = "conditional " + entry.conditional
      condition_list = entry.conditional.split(" ")
    }

    // add the conditions to the menu's conditions
    for(const condition of condition_list){
      if(!menu_condition_list.includes(condition)){
        menu_condition_list.push(condition)
      }
    }
    if (entry.page) {
      section_map[entry.page] = top_level_menu
      const sequence_object={label:entry.label,id:entry.page}
      if (entry.conditional){
        sequence_object["conditional"]=entry.conditional
      }
      sequence_array.push(sequence_object)

      if(!entry.hidden){
        toc.push(`<div class="page-link ${conditional_display_classes}" onclick="load_page('${entry.page}');hide_toc()" id="${entry.page}" style="padding-left:${level}rem">${entry.label}</div>`)
      }  
      //label_map[entry.page] = entry.label
      post_list[entry.page] = entry

    } else if (entry.menu) {
  
      if (level === 0) { top_level_menu = entry.label }
      section_map["contents-" + menu_number] = top_level_menu
      //label_map["contents-" + menu_number] = entry.label + " Contents"
      const sequence_object={label:entry.label + " Contents", id:"contents-" + menu_number}

      sequence_array.push(sequence_object)
      //console.log("menu", entry.label, level)
      if(!entry.hidden){
        toc.push("</div>")
        toc.push(`<div id="contents_${menu_number++}">`)
        toc.push(`<div CONDITIONAL_CLAUSE style="padding-left:${level}rem;font-size:1.5rem;font-weight:bold;border-bottom:2px solid black">${entry.label}</div>`)
      }
      menu_list[entry.label] = entry
      const mc_list = build_section_map(section_map, entry.menu, level + 1, toc, top_level_menu)
      if(mc_list.length>0 && !mc_list.includes("ALL")){
        // if any of the sub entires of this menu had conditionals, put them on the menu
        menu[m].conditional=mc_list.join(" ")
        sequence_object["conditional"]=menu[m].conditional
        for(let x=toc.length-1;x>-1;x--){
          //console.log("x",x)
          if(toc[x].includes("CONDITIONAL_CLAUSE")){
            toc[x]=toc[x].replace("CONDITIONAL_CLAUSE",`class="conditional ${menu[m].conditional}"`)
            break
          }
        }
      }else{
        //clear conditional cluase entry
        for(let x=toc.length-1;x>-1;x--){
          if(toc[x].includes("CONDITIONAL_CLAUSE")){
            toc[x]=toc[x].replace(" CONDITIONAL_CLAUSE "," ")
            break
          }
        }
      }
      if(!entry.hidden){
        //console.log("last toc entry", toc)
      }
      
    }
  }
  return menu_condition_list
}


async function load_css_from_blog_post(url) {
  // gets css that is stored in a post and load it
  const css = document.createElement(`style`)
  css.innerHTML = await get_post_content(url)
  document.getElementsByTagName(`head`)[0].appendChild(css)
}


/** 
 * gets js that is stored as a base-64 encoded stirng (if fethed in production) 
 * in a post and loads it to the <header> tag.
 * If the tag already exsists, then it will override the js tag with the content of the file. 
 * @param {string} file_name the name of the file we want to get. It gets converted into 
 * a URL.
 */
async function load_js_from_blog_post(file_name) {
  const url = get_url(file_name)

  let source = await get_post_content(url)
  if (PRODUCTION_MODE) { source = atob(source) }

  let js = document.getElementById(file_name)


  if (!js) {
    js = document.createElement(`script`)
    js.setAttribute("id", file_name)
    const type_attr = source.match(/@type=["'](.*)['"]@/)
    if (type_attr) {
      js.setAttribute("type", type_attr[1])
    }
    js.async = false;
    document.getElementsByTagName(`head`)[0].appendChild(js)
  }
  js.addEventListener('load', function() {
    console.log("hi hi hi");
  });


  js.innerHTML = source

}

function get_params(query_string) {
  if (!query_string) {
    query_string = PAGE_URL.search
  }
  const url_params_array = query_string.split("?").join("").split("&")
  const url_params = {}

  for (let x = 0; x < url_params_array.length; x++) {
    // returns the params from the url as an object
    const temp = url_params_array[x].split("=")
    url_params[decodeURI(temp[0])] = decodeURI(temp[1])
  }
  return url_params
}

async function start_me_up() {//==================================================================


  //console.log("calling initialize_sqlite_engine")
  initialize_sqlite_engine()

  document.body.innerHTML = `<div id="message-center"></div>` + document.getElementById(`page-container`).outerHTML
  addEventListener(`popstate`, popstate);

  // read the configuration from the cookie
  load_config()
  await Promise.all([
    load_js_from_blog_post("code-input-js"),
    load_js_from_blog_post("ui-js"),
    load_js_from_blog_post("auto-storage-js"),
  ])
  await Promise.all([
    load_js_from_blog_post("error-js"),
    load_js_from_blog_post("subscriptions-js"),
    load_js_from_blog_post("paylay-js"),
    load_js_from_blog_post("indent-js"),
    load_js_from_blog_post("secret-keeper-js"),
    load_js_from_blog_post("authenticate-js"),
    

    // loading Database Processors
    load_js_from_blog_post("database-js"),

    // loading grader scripts
    load_js_from_blog_post("grader-query-js"),
    load_js_from_blog_post("grader-query-parts-js"),
    load_js_from_blog_post("js-sql-parser-js"),

    load_css_from_blog_post(get_url("book-css")),
    load_css_from_blog_post(get_url("prism-css")),
    load_css_from_blog_post(get_url("sql-book-css")),
    load_css_from_blog_post(get_url("query-css")),
    load_css_from_blog_post(get_url("code-input-css")),
  ])

  

  menu = await get_post_content(get_url("toc-json"), `json`)
  

  const toc = []
  build_section_map(section_map, menu, 0, toc)
  toc.push(toc.shift())
  //console.log("section_map",section_map)
  //console.log("toc",toc)
  //console.log(`menu_data`,menu)
  //console.log(`prost_format`,post_list)


  //console.log("BookStorage.loginType",BookStorage.loginType())
  //console.log("BookStorage_canary",BookStorage.canary())
  //console.log("BookStorage_token",BookStorage.token())
  //console.log("BookStorage.loggedIn",BookStorage.loggedIn())

  // build prior next info
  for (let x = 0; x < sequence_array.length; x++) {
    //console.log(x,sequence_array[x])
    if (sequence[sequence_array[x].id] === undefined) { sequence[sequence_array[x].id] = {} }
    sequence[sequence_array[x].id].label=sequence_array[x].label
    if(sequence_array[x].conditional){
      sequence[sequence_array[x].id].conditional = sequence_array[x].conditional
    }

    if (x > 0) { sequence[sequence_array[x].id].prior = sequence_array[x - 1].id }
    if (x < sequence_array.length - 1) { sequence[sequence_array[x].id].next = sequence_array[x + 1].id }
  }

  document.getElementById("contents").innerHTML = toc.join(``)
  //console.log(`sequence`,sequence)
  const html = []
  // top menu bar
  let class_clause = `class='active' `
  for (let x = 0; x < menu.length; x++) {
    if (x === 0) {
      tag("page-body").id = label_to_id(menu[x].label)
    } else {
      // we will leave the original body div for the first element of the menu and generate others
      const div = document.createElement("div")
      div.className = "content-panel"
      div.dataset.menuNumber = x
      div.style.display = "none"
      div.id = label_to_id(menu[x].label)
      tag("panels").append(div)
    }
    const menu_item = menu[x]
    if(!menu_item.hidden){
      let class_clause=""
      if(menu_item.conditional){
        //console.log("menu_item",menu_item)
        class_clause = ` class='conditional ${menu_item.conditional}'`
      }
      //console.log("class_clause",class_clause)
      html.push(`<a ${class_clause} id='menu-${x}' onclick='load_menu(${x})'${class_clause}> ${menu_item.label}</a>`)
    }
  }
  document.getElementById(`menu`).innerHTML = html.join(``)
  //console.log("document.getElementById(`menu`).innerHTML",document.getElementById(`menu`).innerHTML)

  // check to see if we are loged in
  if(!BookStorage.loggedIn()){
    //console.log("we are NOT logged in", BookStorage.loginType())
    let login_result
    switch(BookStorage.loginType()){
      case "local":
        //console.log("found local")
        login_result = await login_local()
        //console.log("login_result",login_result)
        if(login_result==="success"){
          // we have a valid login 
          message({
            message:"You are now logged in to this computer.",
            title:"Authentication Method Changed",
            seconds:8,
            show:true
          })
  
        }else if(login_result==="no login"){
          BookStorage.reset()
        }
        break
      case "gas":
        
        login_result = await login_gas()
        //console.log("login_result",login_result)
        if(login_result.status==="success"){
          // we have a valid login 
          message({
            message:"You are now logged in using your own authentication server.",
            title:"Authentication Method Changed",
            seconds:8,
            show:true
          })
  
        }else if(login_result==="no login"){
          BookStorage.reset()
        }
        break
      case "paid":
        break
      default: // loginType is none    
    }
  }


  let query_string = window.location.href.split(`?`)[1]
  if (!query_string) { query_string = get_from_book_storage("currentPage","introduction" ) }
  if (!query_string) { query_string = ""}
  if (!query_string.includes("=")) {
    query_string = "page=" + query_string
  }
  const url_params = get_params(query_string)
  let page = url_params.page
  //console.log("Current page",page)
  if(page==="undefined"){page="introduction"}
  //console.log("Current page2",page)

  // remove introduction contents
  //delete sequence["contents-0"]
  //delete sequence.introduction.prior
  
  // decide what to do when the page is loaded
  //console.log("about to decide what to do with the page"
  if (page === `m=0`) {
    load_page(menu[0].menu[0].page)
    //document.body.style.zoom = `200%`
    //document.getElementById(`contents`).style.zoom = `50%`
  } else if (page) {
    load_page(page, true)
  } else if (window.location.href.slice(-5) === `.html`) {
    // handle the navive link to a blog page
    //console.log(window.location.href.split(`/`).pop())
    load_page(window.location.href.split(`/`).pop().split(".")[0])
  } else {
    load_page(menu[0].menu[0].page)
  }



  set_book_label()
  configure_book()  

  

}



//==============================================================================================

function label_to_id(label) {
  return "panel-" + label.toLowerCase().split(" ").join("-").split(".").join("-")
}

function set_current_page(page_id){
  CURRENT_PAGE_ID=page_id
  BookStorage.currentPage(page_id)
}

function load_menu(menu_number) {
  
  //console.log(menu[menu_number],"---------------------------",menu)
  const panel = show_panel(menu[menu_number].label)
  if (panel.innerHTML.length === 0) {
    // no page has been loaded on this tab, load the index
    const page_id = "contents-" + menu_number
    load_page(page_id)
  } else {
    const page_id = panel.dataset.pageId
    history.pushState(page_id, ``, `/?${page_id}`)
    set_current_page(page_id)
    configure_book()
    //console.log("just loaded panel with data already on it")
  }
  
}

// function highlight_menu(menu_label){
//   if (!menu_label){return}
//   let menu_number
//   //console.log("menu", menu)
//   for(let i=0;i < menu.length;i++){
//     document.getElementById(`menu-${i}`).className=``
//     if(menu[i].label===menu_label){menu_number=i}
//   }
//   //console.log("menu_label",menu_label)
//   //console.log("menu_number=>",menu_number)
//   document.getElementById(`menu-${menu_number}`).className=`active`
// }

function proper_case(str) {
  'use strict'
  var smallWords = /^(a|an|and|as|at|but|by|en|for|if|in|nor|of|on|or|per|the|to|v.?|vs.?|via)$/i
  var alphanumericPattern = /([A-Za-z0-9\u00C0-\u00FF])/
  var wordSeparators = /([ :&#8211;&#8212;-])/

  return str.split(wordSeparators)
    .map(function (current, index, array) {
      if (
        /* Check for small words */
        current.search(smallWords) > -1 &&
        /* Skip first and last word */
        index !== 0 &&
        index !== array.length - 1 &&
        /* Ignore title end and subtitle start */
        array[index - 3] !== ':' &&
        array[index + 1] !== ':' &&
        /* Ignore small words that start a hyphenated phrase */
        (array[index + 1] !== '-' ||
          (array[index - 1] === '-' && array[index + 1] === '-'))
      ) {
        return current.toLowerCase()
      }

      /* Ignore intentional capitalization */
      if (current.substr(1).search(/[A-Z]|\../) > -1) {
        return current
      }

      /* Ignore URLs */
      if (array[index + 1] === ':' && array[index + 2] !== '') {
        return current
      }

      /* Capitalize the first letter */
      return current.replace(alphanumericPattern, function (match) {
        return match.toUpperCase()
      })
    })
    .join('')
}

function param(name, url = window.location.href) {
  name = name.replace(/[\[\]]/g, '\\$&');
  var regex = new RegExp(`[?&]${name}(=([^&#]*)|&|#|$)`),
    results = regex.exec(url);
  if (!results) return null;
  if (!results[2]) return '';
  return decodeURIComponent(results[2].replace(/\+/g, ` `));
}

function copy_to_clipboard(elem) {
  var range = document.createRange();
  range.selectNode(elem);
  window.getSelection().removeAllRanges(); // clear current selection
  window.getSelection().addRange(range); // to select text
  document.execCommand("copy");
  window.getSelection().removeAllRanges();// to deselect
}

function toggle_code() {
  //console.log(header)
  // no longer using was what is passed in
  const icon = tag("toc-button")
  const code_div = tag("contents")
  if (code_div.style.display === `none`) {
    code_div.style.display = `block`
    icon.innerHTML = `expand_less`
  } else {
    code_div.style.display = `none`
    icon.innerHTML = `expand_more`
  }
}

function hide_toc() {
  // hides the table of contents
  //console.log("at hide_toc")
  tag("contents").style.display = `none`
  tag("toc-button").innerHTML = `expand_more`


}



function decodeHtml(html) {
  var txt = document.createElement("textarea");
  txt.innerHTML = html;
  return txt.value;
}


function tag(id) {
  return document.getElementById(id)
}



function set_cookie(name, value, days) {//used to update cookie information
  var expires = ``;
  if (days) {
    var date = new Date();
    date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
    expires = `; expires=` + date.toUTCString();
  }
  document.cookie = name + `=` + (value || ``) + expires + `; path=/`;
}

function get_cookie(name) {//used to retrieve cookie by name
  var nameEQ = name + `=`;
  var ca = document.cookie.split(`;`);
  for (var i = 0; i < ca.length; i++) {
    var c = ca[i];
    while (c.charAt(0) == ` `) c = c.substring(1, c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
  }
  return null;
}

function erase_cookie(name) {//used to delete a cookie by name
  set_cookie(name, `deleted`, -2)
}



function get_gas_endpoint(optional_gas_token) {
  //console.log("at get_gas_endpoint",BookStorage)
  let gas_end_point
  try {
    if(optional_gas_token){
      gas_end_point = optional_gas_token
    }else{
      gas_end_point = BookStorage.deploymentId()
    }
    //console.log("gas_end_point",gas_end_point)
  } catch (e) {
    message({
      message: `You attempted to execute a query using the Oracle Autonomous Database.  To do this, you must implement a Google Sheet and record the deployment ID in this book.  See <a href="/?engine-configuration">Book Configuration</a> for more details.`,
      title: "Not Fully Configured",
      seconds: 8,
      kind: "error",
      show: true
    })
    throw (e)
  }

  if (!gas_end_point) {
    return null
  }

  if (!gas_end_point.startsWith(`https://`)) {
    gas_end_point = `https://script.google.com/macros/s/${gas_end_point}/exec`
  }
  return gas_end_point
}


function tableToCSV(button) {
  // find the table of the button that was clicked
  let elem = button
  while (true) {
    elem = elem.parentNode
    if (elem.querySelector(".qtable")) {
      elem = elem.querySelector(".qtable")
      break
    }
  }

  // Variable to store the final csv data
  const rows = elem.rows
  const csv_data = [];
  for (var i = 0; i < rows.length - 1; i++) {
    const cols = rows[i].querySelectorAll('td,th');
    const csvrow = [];
    for (var j = 1; j < cols.length; j++) {
      let data = cols[j].innerHTML
      if (data.includes('"')) { data = data.split('"').join('""') }
      if (data.includes('"') || data.includes('\n') || data.includes(',')) {
        csvrow.push('"' + data + '"');
      } else {
        csvrow.push(data);
      }

    }
    csv_data.push(csvrow.join(","));
  }
  CSVFile = new Blob([csv_data.join('\n')], { type: "text/csv" });

  // Create to temporary link to initiate download process
  var temp_link = document.createElement('a');

  // Download csv file
  temp_link.download = `${elem.dataset.tablename}.csv`;
  var url = window.URL.createObjectURL(CSVFile);
  temp_link.href = url;

  // This link should not be displayed
  temp_link.style.display = "none";
  document.body.appendChild(temp_link);

  // Automatically click the link to trigger download
  temp_link.click();
  document.body.removeChild(temp_link);
}



function download_text_file(text, filename) {
  var blob = new Blob([text], { type: "text/plain" });
  var url = window.URL.createObjectURL(blob);
  var a = document.createElement("a");
  a.href = url;
  a.download = filename;
  a.click();
}

function test_dialog(resolve_callback) {



  const body = `To execute a query using data.world, you must provide the <a href="https://data.world/settings/advanced" target="_blank">Read/Write token</a> from your account.<table style="margin-top:1rem"><tr><td>Read/Write token</td><td><input type="text" id="dwTokenEntry"></td></tr></table>`
  const title = "Token Needed"
  // const buttons=`<button onclick="set_dw_token(tag('dwTokenEntry').value); tag('overlay').remove()">OK</button>`
  const buttons = ui_button("", "Ok")
  buttons.onclick = () => {
    resolve_callback(tag('dwTokenEntry').value)
    close_dialog()
  }


  // setTimeout(()=>{
  //console.log("about to resolve the promise!!!!!!!!!!!!", resolve_callback)
  //   resolve_callback()
  // }, 3000)

  show_dialog({
    title: title,
    body: body,
    buttons: buttons,
    style: "max-width:500px",
  })
}



function close_dialog(){
  tag('overlay').remove()
}


function show_dialog(params){

  const overlay = ui_div()
  overlay.id = "overlay"
  overlay.className = "overlay"
  overlay.innerHTML = `<div class="modal-page"><div class="modal"  style="${params.style}"><div class="modal-title"><table><tr><td style="width:100%">${params.title}</td><td><span onclick="tag('overlay').remove()" class="material-symbols-outlined button inline-icon">close</span></td></tr></table></div><div class="modal-content">
  ${params.body}
  </div><div class="modal-footer" id="modal-footer"></div>
  </div></div>
  `

  document.body.append(overlay)
  tag("modal-footer").append(params.buttons)

}

function message(params) {
  // shows a message to the user
  //returns a reference to the message created
  // Example params{
  //     message:"Password must contain at least one Capital letter",
  //     title:"User Error",
  //     kind:"error",
  //     seconds:4,
  //     show:true
  // }
  if (params.show === false) {
    return
  }

  if (!params.title) { params.title = "Message" }
  if (!params.seconds) { params.seconds = 0 }


  let message_class = "msg-head"
  if (params.kind === "error") {
    message_class += " error"
    if (params.title === "Message") {
      params.title = "Error"
    }
  } else if (params.kind === "info") {
    message_class += " info"
  }
  const msg = document.createElement("div")
  msg.addEventListener("mouseenter", (event) => {
    event.target.dataset.permanent=true
  });
  msg.className = "message"
  msg.innerHTML = `
  <div class="${message_class}">
    ${params.title}
    <div class="msg-ctrl">
    <span onclick="close_message(this)" style="font-weight:bold" class="material-symbols-outlined button">close</span>
    </div>
  </div>
  <div class="msg-body">
  ${params.message}
  </div>`
  if (params.seconds > 0) {
    setTimeout(function () { if (!msg.dataset.permanent) { msg.remove() } }, params.seconds * 1000)
  }
  tag("message-center").appendChild(msg)
  return msg

}

function close_message(button) {
  let elem = button
  while (elem.className !== "message") {
    elem = elem.parentNode
  }
  elem.remove()
}

function get_oracle_link(url, kind = "login", raw_user_name) {
  //url is requreed an is an oracle login or a rest end point connection--Anything that like the following (up to the .com) https://gac2XxXxXxXx12b9-tpdb.adb.us-sanjose-1.oraclecloudapps.com/ords/book_user/_/sql
  // kind is login(default)  or sql to indicate what kind of link to make
  // raw_user_name is the user to build it for.  If not supplied, it will try to read it from URL

  const parts = url.split("oraclecloudapps.com")
  const link = [parts[0] + "oraclecloudapps.com", "ords"]
  let user_name = raw_user_name
  if (!user_name) {
    parts = parts[1].split("/")
    if (parts.length > 1) {
      user_name = parts[1]
    } else {
      user_name = "book_user"
    }
  }
  link.push(user_name)
  if (kind === "login") {
    link.push("_sdw/")
  } else if (kind === "sql") {
    link.push("_")
    link.push("sql")
  } else {
    // if it's not login or sql, just append what ever it is
    link.push(kind)
  }
  return link.join("/")
}

function configure_book() {
  // hides all conditional elements that do not include get_book_db_type() as a class
  for (const one_tag of document.querySelectorAll(".conditional")) {
    one_tag.style.display = "none"
  }

  for (const one_tag of document.querySelectorAll("." + get_book_db_type())) {
    one_tag.style.display = ""
  }
  for (const one_tag of document.querySelectorAll("." + BookStorage.aiType())) {
    one_tag.style.display = ""
  }

  //adjust prior and next links
  //console.log("current page id",CURRENT_PAGE_ID )
  const next_label=get_prior_next_page(CURRENT_PAGE_ID, "next")
  //console.log("next_label",next_label)
  if(tag("navigate-prior-label")){
    // profile page does not have navigation buttons
    tag("navigate-prior-label").innerHTML=get_prior_next_page(CURRENT_PAGE_ID, "prior").label
    if ( tag("navigate-next-label")){
      tag("navigate-next-label").innerHTML=next_label.label
    }
  }

}





function set_book_label(text = "Table of Contents:") {
  const version = {
    "book": "SQL Standard",
    "sqlite": "SQLite",
    "dataworld": "data.world",
    "oracle": "Oracle",
  }
  //debugger
  tag("top-info").innerHTML = text + " " + version[get_book_db_type()]

}



async function load_sqlite_db(schema) {

  SQLITE_DB = new SQLITE.Database();

  const response = await get_post_content(get_url("sqlite-" + schema))
  //console.log("size of sqlite script", response.length)
  const data = response.split("\r").join("")
  for (const line of data.split("\n")) {
    if (line.trim().length > 0) {
      //console.log("line", line)        
      SQLITE_DB.run(line)
    }
  }

  SQLITE_DB.run("create table schema_name(name);")
  SQLITE_DB.run(`insert into schema_name values('${schema}');`)

}


function initialize_sqlite_engine() {
  // it takes a couple of seconds for initSqlJs to be available after the call to load the library.
  // this function keeps trying to load if it fails.
  try {
    initSqlJs({ locateFile: filename => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.wasm` }).then(function (SQL) {
      SQLITE = SQL
    });

  } catch (e) {
    //console.log("in catch, trying to initialize sqllite", e.message)
    setTimeout(function () { initialize_sqlite_engine() }, 1000);
  }

}

function split_queries(data) {// returns an array of sql queries split by semicolon.  Ignores semicolons in quotes and
  const q = data.split("")
  try {
    for (let x = 0; x < q.length; x++) {
      if (q[x] === "'") while (q[++x] !== "'") { }
      else if (q[x] === '"') while (q[++x] !== '"') { }
      else if (q[x] === '`') while (q[++x] !== '`') { }
      else if (q[x] + q[x + 1] === '--') while (q[x] !== '\n' && x < q.length) { x++ }
      else if (q[x] + q[x + 1] === '/*') { x = x + 2; while (q[x] + q[x + 1] !== '*/') { x++ } }
      else if (q[x] === ';') q[x] = String.fromCharCode(30, 31, 7, 8, 9)
    }
  } catch (e) {
    // ending when we run past the end of string
  }
  return (q.join("").split(String.fromCharCode(30, 31, 7, 8, 9)))
}

function remove_comments_from_query(query){
  const q = query.split("")
  for (let x = 0; x < q.length; x++) {
    // --- ignore anything in quotes ---
    if (q[x] === "'") while (q[++x] !== "'") { }
    else if (q[x] === '"') while (q[++x] !== '"') { }
    else if (q[x] === '`') while (q[++x] !== '`') { }
    // --- ah, we found a real comment ---
    else if (q[x] + q[x + 1] === '--') {
      while (q[x] !== '\n' && x < q.length) { 
        q[x] = ''
        x++ 
      }
    }
    else if (q[x] + q[x + 1] === '/*') { 
      while (q[x] + q[x + 1] !== '*/') {
        q[x] = ''
        x++ 
      } 

      q[x] = ''
      q[x+1] = ''
      x = x + 2; 
    }
  }
  return q.join("")
}



async function run_db_query(params) {
  // params:
  //     engine:  (if not supplied, reads from bookSettings)
  //         one of: oracle,sqlite,book,data.world

  //     oracle:
  //         endpoint: the google_apps_script (or other) endpoint to relay the query

  //         connection: the identifer to username, password, url from endpoint
  //                OR
  //         username: the dataser username
  //         password: the password for username
  //         url:      the oracle connection url      

  //         query: the script to execute on oracle
  //         schema: (optional) an oracle schema name for accessing tables wihout prefix

  //     sqlite:
  //         schema: name of sqlite data file (minus "sqlite-" prefix)
  //         query:    the script to execute on sqlite

  //     dataworld: 
  //         schema:   dataset name
  //         owner:    owner of dataset
  //         query:    the script to execute on data,world
  //         token:    the users read-write token from data.world

  //     book:
  //         tablename:  the name of the dataset, minus the "results-" prefix

  if (!params.engine) { params.engine = BookStorage.dbType() }

  // log the query
  log_query(params)

  //console.log("ad rnd_db_query, params=", params)

  let script_result
  switch (params.engine) {
    case "oracle":
      //console.log("---> executing oracle query")
      const sql = []
      if (params.schema) {
        sql.push(`ALTER SESSION /*hIdE-Me*/ SET CURRENT_SCHEMA = ${params.schema};\n`)
      }

      sql.push(params.query)
      const payload = {
        sql: sql.join(""),
      }

      if (params.connection){
        payload.connection = params.connection 
      }else{
        if (params.username) { payload.username = params.username }
        if (params.password) { payload.password = params.password }
        if (params.url) { payload.connection = params.url }
      }
      if (params.timestamp) { payload.timestamp = params.timestamp }
      // let endpoint = params.endpoint
      // if (!endpoint) { endpoint = get_gas_endpoint() }
      // if (endpoint.startsWith("https://script.google.com")) {
      //   payload.build_number = endpoint.split("/")[5],
          payload.mode = "run-oracle-script"
      // }
      //console.warn(payload,endpoint)
      const data = await server_post(payload)
      // check to see if we got html back, if so display it
      if (data.response?.substring(0, 15) === "<!DOCTYPE html>") {
        return { error: "html", message: data.response }
      }
      return data
    case "sqlite"://=================================================
      //check to see if we have the right schema
      let stmt

      //console.log("SQLITE_DB", SQLITE_DB)
      try {
        if (SQLITE_DB === undefined) {
          //console.log("about to load")
          await load_sqlite_db(params.schema)
          //console.log("just loaded sqlite schema", params.schema)
        }

        stmt = SQLITE_DB.prepare("select * from schema_name");
      } catch (e) {
        if (e.message === "memory access out of bounds") {
          message({
            message: "It appears that your computer does not have enough available memory to load this dataset.",
            title: "Data Loading Error",
            kind: "error",
            seconds: 8,
          })
        } else {
          message({
            message: e.message,
            title: "Data Loading Error",
            kind: "error",
            seconds: 8,
          })
        }
      }


      stmt.getAsObject();
      stmt.step()
      const row = stmt.getAsObject();
      if (row.name !== params.schema) {
        // the correct schema is not loaded, load it up
        //console.log("loading sqlite schema", params.schema)
        await load_sqlite_db(params.schema)
      }

      //console.log("schema is loaded-----")
      script_result = { items: [] }
      let statementId = 0
      for (const query of split_queries(params.query)) {
        statementId++
        try {
          const sql = query.trim()
          if (sql.length > 0) {
            //console.log("--4")
            const stmt = SQLITE_DB.prepare(sql);
            stmt.getAsObject();
            const item = format_sqlite_results(stmt, sql)
            item.statementId = statementId
            script_result.items.push(item)
          }
        } catch (e) {
          script_result.items.push({
            statementId: statementId,
            statementText: query.trim(),
            errorMessage: e.message
          })
        }
      }

      return script_result



      break
    case "dataworld":
      //console.log("at run_db_query", params)
      // params.schema="cookbook"  
      // params.query="select * from nutrition"  
      script_result = { items: [] }
      let stmtId = 0
      for (const query of split_queries(params.query)) {
        stmtId++
        try {
          const sql = query.trim()
          if (sql.length > 0) {
            //console.log("dwq", sql)

            const url = `https://api.data.world/v0/sql/${params.owner}/${params.schema}`
            const options = {
              headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Bearer ' + params.token,
              },
              'method': 'POST',
              'body': JSON.stringify({
                "query": sql,
                "includeTableSchema": true,
                "queryRunToken": uuid()
              })
            }
            let response
            try {
              response = await fetch(url, options)
            } catch (e) {
              ;console.log("http errpr", e)
            }

            if (response?.ok) {
              //console.log("response",response) 
              const data = await response.json()
              //console.log(data)
              const item = format_dw_results(data, sql)
              //console.log("item in run dw",item)
              item.statementId = stmtId
              script_result.items.push(item)
            } else {
              const data = await response.text()
              //console.log("err msg", data)
              const item = {
                statementId: stmtId,
                statementType: "query",
                statementText: sql,
                errorMessage: data,
                response: [],
                result: 0
              }
              script_result.items.push(item)
            }
          }
        } catch (e) {
          ;console.log("error", e)
          script_result.items.push({
            statementId: stmtId,
            statementText: query.trim(),
            errorMessage: e.message
          })
        }
      }
      //console.log("script_result", script_result)
      return script_result


      break
    default: //book

  }

}





function format_dw_results(data, sql) {
  const item = {
    statementType: "query",
    statementText: sql,
    resultSet: {
    }
  }
  item.resultSet.metadata = data.shift().fields
  item.resultSet.items = data
  //console.log("item", item)
  // adjust field properites
  for (let x = 0; x < item.resultSet.metadata.length; x++) {
    //console.log("field",item.resultSet.metadata[x])
    item.resultSet.metadata[x].columnName = item.resultSet.metadata[x].name.toUpperCase()
    item.resultSet.metadata[x].scale = 0
    item.resultSet.metadata[x].precision = 0
    item.resultSet.metadata[x].columnTypeName = "NUMBER"
    item.resultSet.metadata[x].jsonColumnName = item.resultSet.metadata[x].name
    // make specific adjustments
    switch (item.resultSet.metadata[x].type) {
      case "string":
        item.resultSet.metadata[x].columnTypeName = "VARCHAR2"
        break
      case "Number":
      case "integer":
        item.resultSet.metadata[x].precision = 38
        break
    }
    //remove extras
    delete item.resultSet.metadata[x].rdftype
    delete item.resultSet.metadata[x].type
    delete item.resultSet.metadata[x].name

  }

  //console.log("item", item)

  if (item.resultSet && item.resultSet.items.length === 0) {
    item.response = ["No records returned."]
    item.statementType = "sqlite-message"
    delete item.resultSet


  }
  return item


}


function format_sqlite_results(stmt, sql) {
  const item = {
    statementType: "query",
    statementText: sql,
    resultSet: {
      metadata: [],
      items: []
    }
  }
  const columns = {}
  while (stmt.step()) { //
    const row = stmt.getAsObject();
    for (const [name, val] of Object.entries(row)) {
      if (!columns[name]) {
        item.resultSet.metadata.push(name)
        columns[name] = {
          columnName: name.toUpperCase(),
          jsonColumnName: name,
          columnTypeName: "NUMBER",
          precision: 0,
          scale: 0
        }
        if (columns[name].columnTypeName === "NUMBER") {
          // we have not yet found any non-numeric values
          if (isNaN(val)) {
            //console.log("val", val)
            columns[name].columnTypeName = "VARCHAR2"
            //console.log(name, columns[name])
          } else if (val === null) {
            // skip if null
          } else {
            num_struct = val.toString().split(".")
            if (num_struct.length === 1) { num_struct.push("") }
            if (num_struct[0].length > columns[name].precision) {
              columns[name].precision = num_struct[0].length
            }
            if (num_struct[1].length > columns[name].scale) {
              columns[name].scale = num_struct[1].length
            }
          }
        }
      }
    }
    item.resultSet.items.push(row)
  }
  for (let x = 0; x < item.resultSet.metadata.length; x++) {
    // replace the name of the column with the column object
    // //console.log("column", item.resultSet.metadata[x],columns[item.resultSet.metadata[x]])
    item.resultSet.metadata[x] = columns[item.resultSet.metadata[x]]
  }
  if (item.resultSet && item.resultSet.items.length === 0) {
    item.response = ["No records returned."]
    item.statementType = "sqlite-message"
    delete item.resultSet


  }
  return item
}




function uuid() {
  var u = '', m = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx', i = 0, rb = Math.random() * 0xffffffff | 0;
  while (i++ < 36) {
    var c = m[i - 1], r = rb & 0xf, v = c == 'x' ? r : (r & 0x3 | 0x8);
    u += (c == '-' || c == '4') ? c : v.toString(16); rb = i % 8 == 0 ? Math.random() * 0xffffffff | 0 : rb >> 4
  }
  return u
}

function log_query(params) {// saves query execution to students google form
  //console.log("params at log query",params.query)
  //console.log("params at log query",params.schema)
  const query_log_form_id = get_query_log_form_id()
  if (!query_log_form_id) { return }

  const field_names = ["entry.1205869118", "entry.902126040", "entry.1903789170", "entry.545177327", "entry.1371350672", "entry.1167983881"]
  const field_values = []

  field_values.push(encodeURIComponent(params.engine))
  field_values.push(encodeURIComponent(params.connection))
  field_values.push(encodeURIComponent(window.location.search))
  field_values.push(encodeURIComponent(params.schema))
  field_values.push(encodeURIComponent(params.owner))
  field_values.push(encodeURIComponent(params.query))

  for (let x = 0; x < field_names.length; x++) {
    field_values[x] = field_names[x] + "=" + field_values[x]
  }

  //console.log("field_values.join()",field_values.join("&"))

  const url = `https://docs.google.com/forms/u/0/d/e/${query_log_form_id}/formResponse`
  fetch(url, {
    method: `POST`,
    mode: 'no-cors',
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'//;charset=UTF-8'
    },
    body: field_values.join("&")
  }).then((response) => response.text())
    .then((data) => {;console.log(data)});

}



/**
 * Manages resources by only downloading the content from the url 
 * if it has not been cached. 
 */
const resource_manager = {
  cache: {},
  /**
   * gets the content from the URL and chaches it. if we already have it, then we just return the value
   * without making the request to the url. The url is used as the unique ID. 
   * @param url the url that we get the content from
   * @returns 
   */
  async get_post_content(url, format) {
    // const resources = BookStorage.resources.data() // get our current resources
    const resources = this.cache
    if (resources[url] === undefined) {
      const content = await get_post_content(url, format)
      resources[url] = content // update current resources with new url
      // BookStorage.resources.data(resources) // save into local storage
      this.cache = resources
    }
    return resources[url]
  },
}

function show_hourglass(element, show) {
  //replaces the innerhtml of element with a blinking hourglass and remembers what the html used to be
  // or restores the original content if show = "restore"
  // returns false of element is already showing hourglass
  const hourglass = `<span class="material-symbols-outlined blink" style="vertical-align:middle">hourglass_empty</span>`


  if (show === 'restore') {
    element.innerHTML = atob(element.dataset.original_content)
  } else if (element.innerHTML === hourglass) {
    return false
  } else {
    element.dataset.original_content = btoa(element.innerHTML)
    element.innerHTML = hourglass
  }

  return true

}

async function set_server_property(params) {
  // sets or gets a propert on the google backend.  Can be modified to work with other backends when we have them
  // params needs:
  //   "key" property with with name of the data object to be read or modified
  //   "dataArray" prperty that has whatever value you want to store.  If you
  //               pass an id, as part of an array entry, it will overwrite
  //               an existing entry with the same id 
  // example data array
  // [{name:"admin connection",
  // username:"admin", 
  // password:"delphi.12345", 
  // url:"https://cloud.oracleapps.com/yada/yada", 
  // protect:true,
  // id:"b8e226bb-4393-40e6-b957-460826e3f652" 
  // }]

  return await server_post({
    "mode": "property",
    "action": "set",
    "key": params.key,
    "dataArray": params.dataArray,
  })

}

async function get_server_property(params) {
  // sets or gets a propert on the google backend.  Can be modified to work with other backends when we have them
  // params needs:
  //   "key" property with with name of the data object to be read or modified
  //   "ids" property with an array of hte ids you want retrieve,  omit to get all

  return await server_post({
    "mode": "property",
    "action": "get",
    "key": params.key,
    "ids": params.ids,
  })

}

async function test_get_server_props() {
  const response = await server_property({
    action: "get",
    key: "oracle_connections",
    ids: ["sql_book_connection"]
  })
  //console.log(response)
}


async function get_student_data_values() {
  let data = await get_server_property({
    action: "get",
    key: "data",
    ids: ["student_data"]
  })

  if (data.status === "failure") {
    data = {}
  } else {
    data = data.property.student_data.obj
  }
  simple_add("studentId")
  simple_add("firstName")
  simple_add("lastName")
  simple_add("email")
  simple_add("classKey")
  simple_add("dwToken")

  //console.log("data", data)

  tag("data-object").innerHTML = btoa(JSON.stringify(data))

  function simple_add(id) {// just calls the next two function with only an id
    add_if_missing(id)
    val_to_form(id)
  }

  function val_to_form(tag_id, data_id) {//read value from data in push to form, replace with tagid
    if (!data_id) { data_id = tag_id }
    tag(tag_id).value = data[data_id]
    data[data_id] = tag_id

  }
  function add_if_missing(id, value = "") {
    if (data[id] === undefined) {
      data[id] = value
    }
  }

}

async function signUserInModal() {
  //console.log("user sing in modal")
  try {
    return await new Promise((resolve, reject) => {
      const overlay = ui_div("overlay")
      overlay.id = "overlay"

      const modal_x = ui_span("material-symbols-outlined button inline-icon", "close")
      modal_x.onclick = () => {
        overlay.remove()
        reject("user abort")
      }
      const modal_title = ui_div("modal-title", "Signup", modal_x)

      const modal_content = ui_div("modal-content p3",
        ui_auth_form(resolve, reject)
      )

      const modal_footer = ui_div("modal-footer", "foot")
      const modal = ui_div("modal", modal_title, modal_content, modal_footer)
      const modal_page = ui_div("modal-page", modal)

      overlay.append(modal_page)
      document.body.append(overlay)
    })
  } catch (error) {
    // auth failed!
    console.error("auth has failed, or user gave up")
    throw error
  }
}

function show_query_cell(evt){
  // shows all contents of a cell in a query if the cell's text is too wide to be displayed by default
  const cell=evt.target
  //console.log("cell", cell.tagName)
  switch(cell.tagName){
    case "TD":
      if(cell.style.whiteSpace==="normal"){
        cell.style.whiteSpace="nowrap"
      }else{
        if (cell.offsetWidth < cell.scrollWidth){
          cell.style.whiteSpace="normal"
        }
      }
      break  
    case "TH":
      // TO DO:  figure out queryseletor nth column to make this work
      if(evt.offsetX<cell.offsetWidth*.25){
        //console.log("need to shrink column")
      }else if(evt.offsetX>cell.offsetWidth*.75){
        //console.log("need to grow column")
      }
      break  
    }

}

function user_menu(icon){
  // loads the user login page
  //console.log(icon)
  load_page("user-profile")
}



function show_user_menu(evt) {
  // shows the user menu in the upper right corner
  const rect = tag("panels").getBoundingClientRect()
  
  const menu = document.createElement("div")
  menu.id="menu-overlay"
  menu.className = "overlay-menu"
  
  let logout_display="none"
  let clear_data_display="block"

  if(BookStorage.loggedIn() && BookStorage.loginType()!=="none"){
    logout_display="block"
    clear_data_display="none"
  }

  menu.innerHTML = `
  <div class="user-menu" style="margin-top:${tag('menu').clientHeight}px; margin-left:${rect.right-200}px">
    <div class="user-menu-item" onclick="abandon_machine()" style="display:${clear_data_display}">Clear All Data</div>
    <div class="user-menu-item" onclick="BookStorage.logout()" style="display:${logout_display}">Log out</div>
    <div class="user-menu-item" onclick="load_page('user-profile')">Settings</div>
  </div>`
  
  
  tag("panels").appendChild(menu)
 
  tag('menu-overlay').addEventListener('click', function (event) {
    tag('menu-overlay').remove()
  });

}





function save_course_data(){
  // does saces the stduent data
  message({
    message: "yep, we need to figure out how to save coruse data.  It's on the list",
    title: "Not yet implemented",
    seconds: 8,
    kind: "error",
    show: true
  })
}

function ncrypt(data, key){
  // uses sjcl to encrypt a string
  if(data===null){return null}
  if(key){
    return JSON.parse(sjcl.encrypt(key,data,{"iv":"5zm0Jejo259XOOjbEDSpOA==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"0szHqYwXgcY="})).ct
  }else{
    return data
  }
}

function dcrypt(data, key){
  // decrypts a string that was encrypted with ncrypt 
  if(data===null){return null}
  if(key){
    try{
      return sjcl.decrypt(key,JSON.stringify({"iv":"5zm0Jejo259XOOjbEDSpOA==","v":1,"iter":10000,"ks":128,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"0szHqYwXgcY=","ct":data}))
      }catch(e){
        return("failed")
      }
  }else{
    return data
  }

}



function bookstorage_to_object(stringify=false){
  //returns all values in bookStorage as an object or json string
  const obj={}
  for(const key of BookStorage.getKeys()){
    try{
    obj[key] = BookStorage[key]()
    }catch(e){
      if(e.name!=="AutoStorageNullValueError"){
        throw e
      }
    }
  }
  if(stringify){
    return JSON.stringify(obj)
  }else{
    return obj
  }
  
}

function object_to_bookstorage(object_or_json_string){
  //loads an object or json string into book strorage.  object_or_json_string is produced by bookstorage_to_object
  const obj=(
    typeof object_or_json_string === "string"
    ?
    JSON.parse(object_or_json_string)
    :
    object_or_json_string
  )
  for(const [key,val] of Object.entries(obj)){
    BookStorage[key](val)
  }
  
}


// function backend_connection(){
//  // returns "gas", "paid" or null depending on whcih connection is active
//   let connection=null 
//   let gas_token=null
//   try{
//     connection=BookStorage.currentBackend()
//     gasToken=BookStorage.gasToken()

//   }catch(e){
//     // it means there was no current backend
//     ;console.log(e.message)
//     return null
//   }

//   if(connection==="gas" && gasToken){
//     return "gas"
//   }else if(connection==="paid"){
//     // not really tested or implement yet
//     return "paid"
//   }
// }


function get_data_from_element(element, input_ids_to_exclude=[]){
  // get's the values and names of all input tags in the element
  // written for pulling data from user-profile, but should work anywhere
  const key_value_pair_object={}
  for(const input of element.getElementsByTagName("input")){
    const var_name = id_to_variable_name(input.id)
    if(!input_ids_to_exclude.includes(input_ids_to_exclude)){
      key_value_pair_object[var_name]=input.value
    }
  }
  return key_value_pair_object
}

function get_id_map_from_element(element, input_ids_to_exclude=[]){
  // retrns a map of ids of the inputs in element
  // {studentId:"student-id",studentFirstName:"student-first-name"}
  const key_value_pair_object={}
  for(const input of element.getElementsByTagName("input")){
    const var_name = id_to_variable_name(input.id)
    if(!input_ids_to_exclude.includes(input_ids_to_exclude)){
      key_value_pair_object[var_name]=input.id
    }
  }
  return key_value_pair_object
}

function id_to_variable_name(id) {
  //takes a compound-object-id and returns compoundObjectId
  //console.log(id, id.length)
  if(id){
  s = id.split('-')
  .map(w => w[0].toUpperCase() + w.substring(1).toLowerCase())
  .join('')
  return s[0].toLowerCase() + s.slice(1)
  }
}

function close_message(element_clicked){
  // closes a message in the messagecenter.  Call this from the click even inside a message to close it.
  //console.log(element_clicked)
  let elem = element_clicked
  while (elem.className !== 'message') {
    elem = elem.parentNode
  }
  elem.remove()

}


function debug(on_off_blank){
  // a debugging function.  put debug() somewhere in your code
  // it stays dormant until you execute debug("on") , then it will
  //take you to break mode.  execute debug("off"), to make dormant

  switch(on_off_blank){
    case 1:
    case "on":
      window.stop_for_debug=true
      return "The debugger will now be invoked by debug() statements in your code"
    case 0:
    case "off":
      window.stop_for_debug=false
      return "The debugger is now dormant"
    default:
      if(window.stop_for_debug){
        debugger
      }
  }
}

/**
 * ensures the user is signed in. Will throw an empty error if the user does not sign in. 
 * @returns {Promise<FirebaseUser?>} undefined
 */
async function getUser(showModal=true) {
  //console.log("getting user")
  const auth = firebase.auth.getAuth();
  return await new Promise((resolve) => {
      const overlay = ui_modal("Please Sign In", ui_auth_form(), resolve)
      firebase.auth.onAuthStateChanged(auth, async (user) => {
          if (!user) {
            if (showModal) {
              document.body.append(overlay)
            }else{
              resolve(null)
            }
          } else {
              overlay.remove()
              resolve(user)
          }
      })
  })
}

/**
 * tells us if the user is logged in. 
 * @returns {boolean} true if the object is not null
 */
function userIsLoggedIn(){
  return firebase.auth.getAuth().currentUser ? true : false
}

/**
* gets the size on bytes of a given string
* @param {string }str string to get size in bytes from
* @returns number of bytes in the string
*/
function byteSize(str) {
  return new Blob([str]).size;
}

/**
 * Returns a promise you can use to wait for a spesific amount of time.
 * @param {number} sec number of seconds to wait
 * @returns 
 */
function wait(sec){
  return new Promise((resolve) => {
    setTimeout(resolve, sec*1000)
  })
}

function debounce(func, timeout = 300) {
  let timer
  return (...args) => {
    clearTimeout(timer)
    timer = setTimeout(() => { func(...args) }, timeout)
  }
}