(function () {

// Indent used for formatting output.
const INDENT = "  ";

// Table of ASCII character names used for tooltips on strings.
const ASCII_NAMES = {
  0:   "NUL (null)",
  1:   "SOH (start of heading)",
  2:   "STX (start of text)",
  3:   "ETX (end of text)",
  4:   "EOT (end of transmission)",
  5:   "ENQ (enquiry)",
  6:   "ACK (acknowledge)",
  7:   "BEL (bell)",
  8:   "BS (backspace)",
  9:   "TAB (horizontal tab)",
  10:  "LF (NL line feed, new line)",
  11:  "VT (vertical tab)",
  12:  "FF (NP form feed, new page)",
  13:  "CR (carriage return)",
  14:  "SO (shift out)",
  15:  "SI (shift in)",
  16:  "DLE (data link escape)",
  17:  "DC1 (device control 1)",
  18:  "DC2 (device control 2)",
  19:  "DC3 (device control 3)",
  20:  "DC4 (device control 4)",
  21:  "NAK (negative acknowledge)",
  22:  "SYN (synchronous idle)",
  23:  "ETB (end of trans. block)",
  24:  "CAN (cancel)",
  25:  "EM (end of medium)",
  26:  "SUB (substitute)",
  27:  "ESC (escape)",
  28:  "FS (file separator)",
  29:  "GS (group separator)",
  30:  "RS (record separator)",
  31:  "US (unit separator)",
  32:  "SPACE",
  127: "DEL",
};

// =============================================================================
// ===== TOKENIZING ============================================================
// =============================================================================

// Tokenizes user input.
function tokenize(input) {
  const tokens = [];
  let currentToken = "";
  let mode = "normal";
  // True in "string" mode if the current character is escaped by a backslash.
  let escape = false;
  // Zero-based row and column of the current character. Col counts in bytes,
  // so a multibyte character will advance col by > 1.
  let row = 0, col = 0;
  // {row, col} of the start of the current token.
  let start = undefined;

  // Pushes a character onto the current token.
  function push(c) {
    currentToken += c;
  }

  // Undoes the last push.
  function unpush() {
    currentToken = currentToken.substring(0, currentToken.length - 1);
  }

  // Emits the current token.
  function emit() {
    if (currentToken !== "") {
      tokens.push({
        text: currentToken,
        // The row and col are 0-based. End row is inclusive, col exclusive.
        start: {row: start.row, col: start.col},
        end: {row, col},
      });
    }
    start = undefined;
    currentToken = "";
  }

  // Updates start to the current row and column, if not already set.
  function setStart(c) {
    if (c.trim() !== "" && start === undefined) {
      start = {row, col};
    }
  }

  // Increments row and col based on c.
  function incPos(c) {
    col += c.length;
    if (c === "\n") {
      row++;
      col = 0;
    }
  }

  for (const c of input) {
    setStart(c);
    if (mode === "normal") {
      switch (c.trim()) {
        case "#":
          mode = "comment";
          break;
        case "\"":
          emit();
          setStart(c);
          push(c);
          mode = "string";
          break;
        case ":": case "{": case "}": case ",":
          emit();
          setStart(c);
          push(c);
          incPos(c);
          emit();
          continue;
        case "":
          emit();
          break;
        default:
          push(c);
          break;
      }
    } else if (mode === "string") {
      if (c === "\n") {
        if (escape) {
          unpush();
        } else {
          push("\\n");
        }
      } else {
        push(c);
      }
      switch (c) {
        case "\\":
          escape = !escape;
          break;
        case "\"":
          if (!escape) {
            incPos(c);
            emit();
            mode = "normal";
            continue;
          }
          // fallthrough
        default:
          escape = false;
          break;
      }
    } else if (mode === "comment") {
      if (c === "\n") {
        mode = "normal";
      }
    }

    incPos(c);
  }

  emit();
  if (mode === "string") {
    throw {
      token: tokens[tokens.length-1],
      message: "unterminated string",
    };
  }
  return tokens;
}

// =============================================================================
// ===== PARSING ===============================================================
// =============================================================================

// Parses a list of tokens.
function parse(tokens) {
  let tokenIdx = 0;

  // Store previous int and float tokens so that the next one can be inferred to
  // have the same signedness and bit width.
  let prevInt = null;
  let prevFloat = null;

  // Consumes a single token. If the argument is provided, checks that the token
  // contains the given text and fails otherwise.
  function consume(text) {
    if (tokenIdx === tokens.length) {
      throw {token: tokens[tokenIdx-1], message: "unexpected end of input"};
    }
    const t = tokens[tokenIdx++];
    if (text !== undefined && t.text !== text) {
      throw {token: t, message: `expected ${JSON.stringify(text)}`};
    }
    return t;
  }

  // Returns true if the first token contains the given text.
  function peek(text) {
    if (tokenIdx === tokens.length) {
      throw {token: tokens[tokenIdx-1], message: "unexpected end of input"};
    }
    return tokens[tokenIdx].text === text;
  }

  // Returns true if v1 and v2 have compatible types.
  function sameType(v1, v2) {
    switch (v1.type) {
      case "null":
        return v1.type === v2.type || sameType(v2, v1);
      case "bool":
        return v1.type === v2.type;
      case "string":
      case "handle":
        return v1.type === v2.type || (v2.type === "null" && v2.kind === v1.type);
      case "int":
      case "float":
        return v1.type === v2.type && v1.width === v2.width;
      case "struct":
        return v1.type === v2.type
          && v1.fields.every((f, i) => sameType(f, v2.fields[i]));
      case "array":
        return v1.type === v2.type && v1.fields.length === v2.fields.length
          // Note: Only check first element even for array/vector since
          // validate() checks that all elements are the same.
          && sameType(v1.fields[0], v2.fields[0]);
      case "bits":
      case "enum":
        return v1.type === v2.type && sameType(v1.fields[0], v2.fields[0]);
      case "box":
        return v1.type === v2.type || (v2.type === "null" && v2.kind === "struct");
      case "vector":
        return (v1.type === v2.type
                && (v1.fields.length === 0 || v2.fields.length === 0
                  || sameType(v1.fields[0], v2.fields[0])))
          || (v2.type === "null" && v2.kind === v1.type);
      case "table":
        const map = {};
        for (const entry of v1.fields) {
          map[entry.ordinal] = entry.fields[0];
        }
        for (const entry of v2.fields) {
          const field1 = map[entry.ordinal];
          const field2 = entry.fields[0];
          if (field1 !== undefined && !sameType(field1, field2)) {
            return false;
          }
        }
      case "union":
        return v1.type === v2.type &&
          (v1.fields.length === 0 || v2.fields.length === 0
            || v1.fields[0].ordinal !== v2.fields[0].ordinal
            || sameType(v1.fields[0], v2.fields[0]));
      default:
        throw Error(`unexpected type: ${v1.type}`);
    }
  }

  // Validates a parsed FIDL value.
  function validate(value) {
    // Check number of fields.
    switch (value.type) {
      // Note: We COULD make bits{} mean 0, but we don't know the width. We
      // could infer from the last int, but that means sometimes bits{} is
      // allowed and sometimes not, which is confusing.
      case "bits":
      // Zero-length arrays are disallowed by fidlc.
      case "array":
        if (value.fields.length === 0) {
          throw {
            range: value.range,
            message: `${value.type} must have at least 1 field; got `
            + `${value.fields.length}`,
          };
        }
        break;
      case "box":
      case "enum":
      case "handle":
      case "union":
        if (value.fields.length !== 1) {
          throw {
            range: value.range,
            message: `${value.type} must have 1 field; got `
            + `${value.fields.length}`,
          };
        }
        break;
    }

    // Check underlying types.
    switch (value.type) {
      case "enum":
        if (value.fields[0].type !== "int") {
          const field = value.fields[0];
          throw {
            range: field.range,
            message: `${value.type} value must be an int, not ${field.type}`,
          };
        }
        break;
      case "bits":
        if (value.fields[0].type !== "int" || value.fields[0].signed !== "u") {
          const field = value.fields[0];
          throw {
            range: field.range,
            message: `${value.type} value must be a uint, not ${field.type}`,
          };
        }
        break;
      case "handle":
        if (value.fields[0].type !== "int" || value.fields[0].signed !== "u"
            || value.fields[0].width !== 32) {
          const field = value.fields[0];
          throw {
            range: field.range,
            message: `${value.type} value must be an uint32, not ${field.type}`,
          };
        }
        if (value.fields[0].value == 0) {
          const field = value.fields[0];
          throw {
            range: field.range,
            message: `${value.type} value must be nonzero; use "null handle" for null`,
          };
        }
        break;
      case "box":
        if (value.fields[0].type !== "struct") {
          throw {
            range: value.fields[0].range,
            message: `${value.fields[0].type} values cannot be boxed`,
          };
        }
        break;
    }

    // Check type homogeneity.
    switch (value.type) {
      case "vector":
      case "array":
      case "bits":
        if (value.fields.length > 0) {
          for (let i = 1; i < value.fields.length; i++) {
            if (value.fields[0].type !== value.fields[i].type) {
              throw {
                range: value.fields[i].range,
                message: `${value.type} element 0 (${value.fields[0].type}) `
                  + `and element ${i} (${value.fields[i].type}) have different `
                  + `types`,
              };
            }
            if (!sameType(value.fields[0], value.fields[i])) {
              throw {
                range: value.fields[i].range,
                message: `${value.type} element 0 (${value.fields[0].type}) `
                  + `and element ${i} (${value.fields[i].type}) have `
                  + `structurally different types`,
              };
            }
          }
        }
        break;
    }

    // Check children.
    if (value.fields !== undefined) {
      for (const field of value.fields) {
        validate(field);
      }
    }
  }

  // Consumes and parses a FIDL value.
  function parseValue() {
    const t = consume();
    const range = {first: t, last: t};
    if (/^"/.test(t.text)) {
      let value;
      try {
        value = JSON.parse(t.text);
      } catch (ex) {
        throw {token: t, message: "invalid string literal"};
      }
      return {type: "string", value, range};
    }
    if (/^-?(?:\d|\.)/.test(t.text)) {
      return parseNumber(t);
    }
    switch (t.text) {
      case "true":
        return {type: "bool", value: true, range};
      case "false":
        return {type: "bool", value: false, range};
      case "handle":
      case "bits":
      case "enum":
      case "struct":
      case "array":
      case "vector":
      case "box":
        return parseAgg(t, false);
      case "table":
      case "union":
        return parseAgg(t, true);
      case "null": {
        const t2 = consume();
        switch (t2.text) {
          case "handle": case "string": case "struct": case "union": case "vector":
            return {type: "null", kind: t2.text, range: {first: t, last: t2}};
          default:
            throw {token: t2, message: "expected one of: handle, string, struct, union, vector"};
        }
      }
    }
    throw {token: t, message: "invalid syntax"};
  }

  // Parses an already-consumed number token t.
  function parseNumber(t) {
    const range = {first: t, last: t};
    if (/\./.test(t.text) || (!/x/.test(t.text) && /[eEf]/.test(t.text))) {
      const match = t.text.match(/(.*)f(32|64)$/);
      let result;
      if (match) {
        result = {
          type: "float",
          width: parseInt(match[2]),
          orig: match[1],
          value: parseFloat(match[1]),
          range,
        };
      } else if (prevFloat) {
        result = {...prevFloat, orig: t.text, value: parseFloat(t.text), range};
      } else {
        throw {token: t, message: "float missing suffix (f32 or f64)"};
      }
      // Check both because parseFloat can ignore trailing garbage.
      if (isNaN(result.orig) || isNaN(result.value)) {
        throw {token: t, message: "invalid float"};
      }
      return prevFloat = result;
    }
    const match = t.text.match(/(.*)(u|i)(8|16|32|64)$/);
    let result;
    if (match) {
      result = {
        type: "int",
        signed: match[2],
        width: parseInt(match[3]),
        orig: match[1],
        range,
      };
    } else if (prevInt) {
      result = {...prevInt, orig: t.text, range};
    } else {
      throw {token: t, message: "int missing suffix (u8, i8, u16, i16, etc.)"};
    }
    try {
      result.value = BigInt(result.orig);
    } catch (ex) {
      throw {token: t, message: `invalid ${result.signed}int${result.width}`};
    }
    if (result.signed === "u") {
      if (result.value < 0) {
        throw {token: t, message: `uint${result.width} cannot be negative`}
      }
      if (result.value >= 2n ** BigInt(result.width)) {
        throw {token: t, message: `uint${result.width} out of range`}
      }
    } else {
      const limit = 2n ** BigInt(result.width - 1);
      if (result.value < -limit || result.value >= limit) {
        throw {token: t, message: `int${result.width} out of range`}
      }
    }
    return prevInt = result;
  }

  // Parses an aggregate structure whose keyword token (struct, table, etc.) has
  // already been consumed. If ordinals is true, parses ordinals before each
  // field and stores "$entry" nodes in the fields.
  function parseAgg(keyword, ordinals) {
    consume("{");
    const fields = [];
    while (!peek("}")) {
      if (ordinals) {
        const t = consume();
        const ordinal = parseInt(t.text, 10);
        // Check isNaN on both because parseInt can ignore trailing garbage.
        if (isNaN(t.text) || isNaN(ordinal)) {
          throw {token: t, message: "expected an integer ordinal"};
        }
        if (ordinal <= 0) {
          throw {token: t, message: "ordinals must be positive"};
        }
        consume(":");
        const value = parseValue();
        fields.push({
          // $entry is a special parse tree node that stores the ordinal. We use
          // dollar signs for special nodes that are not printed literally. In
          // the case of $entry, format() prints it with the colon syntax.
          type: "$entry",
          ordinal,
          fields: [value],
          range: {first: t, last: value.range.last},
        });
      } else {
        fields.push(parseValue());
      }
      if (!peek("}")) {
        consume(",");
      }
    }
    return {
      type: keyword.text,
      fields,
      range: {first: keyword, last: consume("}")},
    };
  }

  const value = parseValue();
  if (tokenIdx !== tokens.length) {
    throw {
      range: {first: tokens[tokenIdx], last: tokens[tokens.length-1]},
      message: "extraneous input",
    };
  }
  validate(value);
  return value;
}

// =============================================================================
// ===== FORMATTING ============================================================
// =============================================================================

// Formats a parse tree back to the input syntax. Also mutates the nodes, adding
// outputRange properties of the form {start: {row, col}, end: {row, col}}.
function format(tree) {
  let result = "";
  // Zero-based row and column of the current position in result. Col counts in
  // bytes, so a multibyte character will advance col by > 1.
  let row = 0, col = 0;
  // Keep track of secondary objects in order to number them in comments.
  let secondaryObjectNumber = 1;

  function push(text) {
    result += text;
    col += text.length;
  }
  function newline() {
    result += "\n";
    row++;
    col = 0;
  }
  function commentHeader(msg, first /* = false */) {
    if (!first) {
      newline();
      newline();
    }
    push(`# ${msg}`);
    newline();
  }

  // Returns true if node should be displayed in a one liner between braces.
  function isOneLiner(node) {
    switch (node.type) {
      case "bool":
      case "$pointer":
        return true;
      case "string":
        return node.value.length < 50;
      case "int":
      case "float":
        return node.orig.length < 50;
      case "$entry":
        return isOneLiner(node.fields[0]);
      case "struct":
        return isPointerAndOut(node);
      default:
        return false;
    }
  }

  // Returns true if node is a {$pointer, $out} struct lowered from a box.
  function isPointerAndOut(node) {
    return node.type === "struct" && node.fields.length === 2
      && node.fields[0].type === "$pointer"
      && node.fields[1].type === "$out";
  }

  // Returns true if the tree has any out-of-line blocks.
  function hasOutOfLine(node) {
    return node.type === "$out" || (node.fields && node.fields.some(hasOutOfLine));
  }

  // Helper function that keeps track of the current indentation level.
  function helper(node, indent, topLevelObject) {
    const start = {row, col};
    // The thunks in this function work the same as in formatBytes(). They might
    // be easier to understand in that function because it is shorter.
    const thunks = [];

    switch (node.type) {
      case "null":
        push(`null ${node.kind}`);
        break;
      case "$pointer":
        push(node.value);
        break;
      case "bool":
      case "string":
        push(JSON.stringify(node.value));
        break;
      case "int":
        push(node.orig + node.signed + node.width);
        break;
      case "float":
        push(node.orig + "f" + node.width);
        break;
      case "$entry":
        push(node.ordinal + ": ");
        helper(node.fields[0], indent);
        break;
      case "handle":
      case "bits":
      case "struct":
      case "array":
      case "vector":
      case "enum":
      case "envelope":
      case "box":
      case "table":
      case "union": {
        if (node.fields.length === 0) {
          push(node.type + " {}");
        } else if (node.fields.length === 1 && isOneLiner(node.fields[0])) {
          push(node.type + " { ");
          thunks.push(helper(node.fields[0], 0, /* topLevelObject = */ false));
          push(" }");
        } else if (isPointerAndOut(node)) {
          // Handle this specially because we don't want to wrap the "present"
          // in a struct. We just want to emit "present" and add the out-of-line
          // thunk to be emitting later.
          const pointer = node.fields[0];
          const out = node.fields[1];
          helper(pointer, indent, topLevelObject);
          thunks.push(helper(out, indent, topLevelObject));
        } else {
          push(node.type + " {");
          newline();
          for (const field of node.fields) {
            push(INDENT.repeat(indent + 1));
            thunks.push(helper(field, indent + 1, /* topLevelObject = */ false));
            push(",");
            newline();
          }
          push(INDENT.repeat(indent) + "}");
        }
        break;
      }
      case "$out":
        // Don't emit anything yet. Return a thunk that will emit the
        // out-of-line object after the inline portion is done.
        return function() {
          commentHeader(`Secondary object ${secondaryObjectNumber}`);
          secondaryObjectNumber++;
          helper(node.fields[0], 0, /* topLevelObject = */ true);
          const ranges = node.fields[0].outputRanges;
          node.outputRanges = ranges;
          return ranges;
        };
      default:
        throw Error(`unexpected type: ${node.type}`);
    }
    // outputRanges is a list to allow for multiple noncontiguous regions.
    // This is used for bytes (inline and out-of-line). For format(), there
    // is always only 1 output range per node.
    node.outputRanges = [{start, end: {row, col}}];

    const flushOutOfLine = () => {
      let combined = [];
      for (thunk of thunks) {
        const ranges = thunk();
        if (ranges !== undefined) {
          node.outputRanges.push(...ranges);
          combined.push(...ranges);
        }
      }
      return combined;
    };
    if (topLevelObject) {
      flushOutOfLine();
      return function() {}
    }
    return flushOutOfLine;
  }

  if (hasOutOfLine(tree)) {
    commentHeader("Primary object", /* first = */ true);
  }
  helper(tree, 0, /* topLevelObject = */ true);
  return result;
}

// Format the bytes tree as hex bytes.
function formatBytes(tree) {
  let result = "";
  let row = 0, col = 0, byteIndex = 0;
  const rowLengths = [];

  function emitByte(byte) {
    result += byte.toString(16).padStart(2, "0");
    col += 2;
    // NOTE: Keep this (8) in sync with output editor gutter renderer, which
    // replaces line numbers with offsets 0, 8, 16, etc.
    if (byteIndex % 8 == 7) {
      result += "\n";
      rowLengths.push(col);
      col = 0;
      row++;
    } else {
      result += " ";
      col++;
    }
    byteIndex++;
  }

  // Get the position just before pos, to avoid including whitespace in ranges.
  function justBefore({row, col}) {
    if (col > 0) {
      return {row, col: col - 1};
    }
    return {row: row - 1, col: rowLengths[row - 1]};
  }

  // Get the position just after pos, to avoid including whitespace in ranges.
  function justAfter({row, col}) {
    if (col < rowLengths[row]) {
      return {row, col: col + 1};
    }
    return {row: row + 1, col: 0};
  }

  // Executes f on all padding nodes below node in DFS order.
  function foreachInlinePadding(node, f) {
    switch (node.type) {
      case "bytes":
        if (node.padding) {
          f(node);
        }
        break;
      case "inline":
        for (const field of node.fields) {
          foreachInlinePadding(field, f);
        }
        break;
    }
  }

  function helper(node, topLevelObject) {
    const start = {row, col};
    switch (node.type) {
      case "bytes":
        node.bytes.forEach(emitByte);
        node.outputRanges = [{start, end: justBefore({row, col})}];
        return function() {}
      case "inline":
        const thunks = node.fields.map(f => helper(f, false));
        node.outputRanges = [{start, end: justBefore({row, col})}];
        // Remove padding regions from the node's ouput ranges, so that we never
        // highlight padding.
        foreachInlinePadding(node, paddingNode => {
          const lastRange = node.outputRanges[node.outputRanges.length-1];
          const {start: padStart, end: padEnd} = paddingNode.outputRanges[0];
          const oldEnd = lastRange.end;
          lastRange.end = justBefore(padStart);
          node.outputRanges.push({start: justAfter(padEnd), end: oldEnd});
        });
        const flushOutOfLine = () => {
          let combined = [];
          for (thunk of thunks) {
            const ranges = thunk();
            if (ranges !== undefined) {
              node.outputRanges.push(...ranges);
              combined.push(...ranges);
            }
          }
          return combined;
        };
        if (topLevelObject) {
          flushOutOfLine();
          return function() {}
        }
        return flushOutOfLine;
      case "secondary":
        // For secondary objects, don't encode anything yet. Instead, return a
        // thunk to be executed after the inline portion of the last object has
        // been fully encoded.
        return function() {
          helper(node.fields[0], /* topLevelObject = */ true);
          const ranges = node.fields[0].outputRanges;
          node.outputRanges = ranges;
          return ranges;
        };
      default:
        throw Error(`unexpected type in formatBytes: ${node.type}`);
    }
  }

  helper(tree, /* topLevelObject = */ true);
  return result;
}

// =============================================================================
// ===== LOWERING ==============================================================
// =============================================================================

// Global flag to disable adding "lowered" fields. This is an ugly hack.
let disableAddLowered = false;

// Adds lowered to node's list of lowered nodes, creating the list if necessary.
// Also adds links in the reverse direction.
function addLowered(node, lowered) {
  if (disableAddLowered) {
    return;
  }
  if (node.lowered === undefined) {
    node.lowered = [];
  }
  node.lowered.push(lowered);
  // If there is already a loweredFrom, overwrite it. Usually this is when a
  // lowering stage copies a whole node (including its loweredFrom) field, and
  // then calls addLowered. Ocassionally there genuinely are multiple things it
  // was loweredFrom, like bits/enums -- the whole structure and the value
  // inside all lower the same output. In these cases letting the last
  // addLowered call win works -- it will be the largest structure, the whole
  // bits/enum, which is what we want for reverse highlighting (otherwise if the
  // bits has multiple fields, it will only highlight one of them).
  lowered.loweredFrom = node;
}

// Creates a note/tooltip, incorporating an old one if present.
function addNote(oldNode, additional) {
  return oldNode.note === undefined
    ? additional : `${oldNode.note}\n\n${additional}`;
}

// Creates a note/tooltip, but does not replace an existing one.
function provideNote(oldNode, newNote) {
  return oldNode.note === undefined
    ? newNote : oldNode.note;
}

// Helper functions for English messages.
function plural(n) { return n === 1 ? "" : "s"; }
function article(n) { return n == 8 ? "an" : "a"; }

// Copies a tree node, omitting metadata that should not be copied.
function copyNode(node) {
  return {
    ...node,
    lowered: undefined,
    loweredFrom: undefined,
  };
}

// Helper combinator for lowering.
function doLowering(tree, self, helper) {
  function augmentedHelper(node) {
    const result = helper(node);
    if (result !== undefined) {
      // Reapply self. A proper lowering should not get into infinite recursion.
      return self(result);
    }
    if ("fields" in node) {
      return {...copyNode(node), fields: node.fields.map(self)};
    }
    // Very important that this copies the node rather than returning the same
    // object. Otherwise highlighting gets into infinite recursion.
    return {...copyNode(node)};
  }
  const lowered = augmentedHelper(tree);
  addLowered(tree, lowered);
  return lowered;
}

// Lowering stage 1: tables and unions.
function lower1(tree) {
  return doLowering(tree, lower1, node => {
    switch (node.type) {
      case "table": {
        if (node.fields.length === 0) {
          return {
            type: "vector",
            fields: [],
            note: addNote(node,
              `Empty table lowers to an empty vector`),
          };
        }
        const maxOrdinal =
          node.fields.map(f => f.ordinal).reduce((a, b) => Math.max(a, b));
        const ordinalToEntry = {};
        for (const field of node.fields) {
          ordinalToEntry[field.ordinal] = field;
        }
        const fields = [];
        for (let i = 1; i <= maxOrdinal; i++) {
          const entry = ordinalToEntry[i];
          if (entry === undefined) {
            const empty = {
              type: "envelope",
              fields: [],
              note: `Empty envelope for omitted table field #${i}`,
            };
            fields.push(empty);
          } else {
            const present = {
              type: "envelope",
              fields: [entry.fields[0]],
              note: `Envelope for table field #${i}`,
            };
            fields.push(present);
            addLowered(entry, present);
          }
        }
        return {
          type: "vector",
          fields,
          note: addNote(node, `Table lowers to a vector of envelopes`),
        };
      }
      case "null": {
        if (node.kind !== "union") {
          break;
        }
        return {
          type: "struct",
          fields: [
            {
              type: "int", signed: "u", width: 64,
              orig: "0", value: 0,
              note: "Zero ordinal for null union",
            },
            {
              type: "envelope",
              fields: [],
              note: "Empty envelope for null union",
            }
          ],
          note: addNote(node,
            `Null union lowers to ordinal 0 and an empty envelope`),
        };
      }
      case "union": {
        const entry = node.fields[0];
        const ordinal = entry.ordinal;
        const envelope = {
          type: "envelope",
          fields: [entry.fields[0]],
          note: `Envelope wrapping union variant #${ordinal}`,
        };
        addLowered(entry, envelope);
        return {
          type: "struct",
          fields: [
            {
              type: "int", signed: "u", width: 64,
              orig: ordinal.toString(), value: ordinal,
              note: `Union ordinal specifying variant #${ordinal}`,
            },
            envelope,
          ],
          note: addNote(node,
            `Union lowers to an ordinal (${ordinal}) and envelope`),
        };
      }
    }
  });
}

// Lowering stage 2: bits and enums. Assumes earlier lowerings are done.
function lower2(tree) {
  return doLowering(tree, lower2, node => {
    switch (node.type) {
      case "bits": {
        const type = (node.fields[0].signed === "u" ? "uint" : "int")
          + node.fields[0].width.toString();
        const value = node.fields.map(f => f.value).reduce((a, b) => a | b);
        const orig = value == 0 ? "0" : "0x" + value.toString(16);
        let valueStr = orig;
        if (node.fields.length > 1) {
          valueStr = node.fields.map(f => "0x" + f.value.toString(16)).join(" | ") + ` = ${orig}`;
        }
        const result = {
          ...copyNode(node.fields[0]),
          orig,
          value,
          note: addNote(node, `Bits ${valueStr} : ${type}`),
        };
        for (const field of node.fields) {
          addLowered(field, result);
        }
        return result;
      }
      case "enum": {
        const type = (node.fields[0].signed === "u" ? "uint" : "int")
          + node.fields[0].width.toString();
        const result = {
          ...copyNode(node.fields[0]),
          note: addNote(node,
            `Enum ${node.fields[0].value} : ${type}`),
        };
        addLowered(node.fields[0], result);
        return result;
      }
    }
  });
}

// Lowering stage 3: strings. Assumes earlier lowerings are done.
function lower3(tree) {
  return doLowering(tree, lower3, node => {
    switch (node.type) {
      case "null": {
        if (node.kind !== "string") {
          break;
        }
        return {
          type: "null",
          kind: "vector",
          note: addNote(node, `Null string lowers to a null vector`),
        };
      }
      case "string": {
        const fields = [];
        const u8 = (byte, extra) => ({
          type: "int", signed: "u", width: 8,
          orig: "0x" + byte.toString(16), value: byte,
          ...extra,
        });
        // Iterate over Unicode characters.
        for (const char of node.value) {
          // Trick to convert to UTF-8: https://stackoverflow.com/a/18729536
          const utf8 = unescape(encodeURIComponent(char));
          if (utf8.length === 1) {
            const byte = utf8.charCodeAt(0);
            const note = `Character: ${ASCII_NAMES[byte] || String.fromCharCode(byte)}`;
            fields.push(u8(byte, {note}));
          } else {
            for (let i = 0; i < utf8.length; i++) {
              fields.push(u8(utf8.charCodeAt(i), {
                note: `Character: ${char} (byte ${i+1} of ${utf8.length})`,
              }));
            }
          }
        }
        let displayStr;
        if (node.value.length > 100) {
          displayStr = JSON.stringify(node.value.substring(0, 100) + "…")
            + " (truncated)";
        } else {
          displayStr = JSON.stringify(node.value);
        }
        return {
          type: "vector",
          fields,
          note: addNote(node, `String ${displayStr}`),
        }
      }
    }
  });
}

// Lowering stage 4: vectors. Assumes earlier lowerings are done.
function lower4(tree) {
  return doLowering(tree, lower4, node => {
    switch (node.type) {
      case "null": {
        if (node.kind !== "vector") {
          break;
        }
        return {
          type: "struct",
          fields: [
            {
              type: "int", signed: "u", width: 64,
              orig: "0", value: 0,
              note: `Vector length: 0 elements (null vector)`,
            },
            {
              type: "$pointer",
              value: "absent",
              note: `ABSENT pointer for null vector`,
            },
          ],
          note: addNote(node,
            `Null vector lowers to length 0 and ABSENT pointer`),
        };
      }
      case "vector": {
        const len = node.fields.length;
        const lengthNode = {
          type: "int", signed: "u", width: 64,
          orig: len.toString(), value: len,
          note: `Vector length: ${len} elements`,
        };
        if (len === 0) {
          return {
            type: "struct",
            fields: [
              lengthNode,
              {
                type: "$pointer",
                value: "present",
                note: `Pointer to empty vector's out-of-line array; PRESENT `
                  + `even though there is no array, to distinguish from null vectors`,
              },
            ],
            note: addNote(node,
              `Vector lowers to a length (${len}) and an out-of-line array`),
          };
        }
        return {
          type: "struct",
          fields: [
            lengthNode,
            {
              type: "box",
              fields: [{
                type: "array",
                fields: node.fields,
                note: `Vector's out-of-line array`,
              }],
              note: `Pointer to vector's out-of-line array`,
            },
          ],
          note: addNote(node,
            `Vector lowers to a length (${len}) and an out-of-line array`),
        };
      }
    }
  });
}

// Lowering stage 5: handles and envelopes. Assumes earlier lowerings are done.
function lower5(tree) {
  function countPresentHandles(node) {
    if (node.type === "handle") {
      return 1;
    }
    if (node.fields !== undefined) {
      let sum = 0;
      for (const f of node.fields) {
        sum += countPresentHandles(f);
      }
      return sum;
    }
    return 0;
  }

  return doLowering(tree, lower5, node => {
    switch (node.type) {
      case "null": {
        if (node.kind !== "handle") {
          break;
        }
        return {
          type: "int", signed: "u", width: 32, orig: "0", value: 0,
          note: addNote(node, `Null handle`),
        };
      }
      case "handle": {
        const result = {
          ...copyNode(node.fields[0]),
          type: "int", signed: "u", width: 32, orig: "0xffffffff", value: 0xffffffff,
          note: addNote(node, `Pointer to handle ${node.fields[0].value} (stored out-of-band in the handle vector)`),
        };
        addLowered(node.fields[0], result);
        return result;
      }
      case "envelope": {
        if (node.fields.length === 0) {
          return {
            type: "struct",
            fields: [
              {type: "int", signed: "u", width: 32, orig: "0", value: 0,
               note: "Empty envelope: 0 bytes"},
              {type: "int", signed: "u", width: 32, orig: "0", value: 0,
               note: "Empty envelope: 0 handles"},
              {type: "$pointer", value: "absent",
               note: "ABSENT pointer for empty envelope"},
            ],
            note: node.note,
          };
        }
        disableAddLowered = true;
        const bytes = countTotalBytes(lowerBytes(lower6(lower5(node.fields[0]))));
        disableAddLowered = false;
        const handles = countPresentHandles(node.fields[0]);
        return {
          type: "struct",
          fields: [
            {type: "int", signed: "u", width: 32, orig: bytes.toString(), value: bytes,
             note: `Envelope: ${bytes} byte${plural(bytes)}`},
            {type: "int", signed: "u", width: 32, orig: handles.toString(), value: handles,
             note: `Envelope: ${handles} handle${plural(handles)}`},
            {type: "box", fields: node.fields,
             note: "Pointer to the envelope's out-of-line data"},
          ],
          note: node.note,
        };
      }
    }
  });
}

// Lowering stage 6: boxes. Assumes earlier lowerings are done.
function lower6(tree) {
  return doLowering(tree, lower6, node => {
    switch (node.type) {
      case "null": {
        if (node.kind !== "struct") {
          break;
        }
        return {
          type: "$pointer",
          value: "absent",
          note: addNote(node, `ABSENT pointer for null struct`),
        };
      }
      case "array": {
        return {
          ...copyNode(node),
          type: "struct",
          note: addNote(node, `Array lowers to a struct where all fields have `
            + `the same type`),
        };
      }
      case "box": {
        return {
          type: "struct",
          fields: [
            {
              type: "$pointer",
              value: "present",
              note: provideNote(node, `Pointer to out-of-line struct`),
            },
            {
              type: "$out",
              fields: node.fields,
            }
          ],
        };
      }
    }
  });
}

// Final lowering stage, to bytes. Assumes all earlier lowerings are done.
function lowerBytes(tree) {
  // object can be "primary", "secondary", or false.
  function lower(tree, object) {
    const lowered = helper(tree, object);
    addLowered(tree, lowered);
    return lowered;
  }

  function helper(node, object) {
    if (object && node.type !== "struct") {
      // Instead of handling the 8-byte padding in every branch, we just handle
      // it in the struct case, and wrap other things in structs.
      node = {type: "struct", fields: [node]};
    }
    switch (node.type) {
      case "int": {
        const signed = node.signed === "i";
        const type = signed ? `int${node.width}` : `uint${node.width}`;
        const arrayType = signed
        ? {8: Int8Array, 16: Int16Array, 32: Int32Array, 64: BigInt64Array}[node.width]
        : {8: Uint8Array, 16: Uint16Array, 32: Uint32Array, 64: BigUint64Array}[node.width];
        const value = node.width === 64 ? BigInt(node.value) : Number(node.value);
        const size = node.width / 8;
        return {
          type: "bytes",
          bytes: new Uint8Array(arrayType.of(value).buffer),
          size,
          align: size,
          note: provideNote(node, `${node.value} : ${type}`),
        };
      }
      case "float": {
        const type = `float${node.width}`;
        const single = node.width === 32;
        const arrayType = single ? Float32Array : Float64Array;
        const size = node.width / 8;
        return {
          type: "bytes",
          bytes: new Uint8Array(arrayType.of(node.value).buffer),
          size,
          align: size,
          note: provideNote(node, `${node.value} : ${type}`),
        };
      }
      case "bool": {
        const value = node.value ? 1 : 0;
        return {
          type: "bytes",
          bytes: Uint8Array.of(value),
          size: 1,
          align: 1,
          note: provideNote(node, `${node.value} : bool`),
        };
      }
      case "$pointer": {
        let bytes;
        switch (node.value) {
          case "absent":
            bytes = Uint8Array.of(0, 0, 0, 0, 0, 0, 0, 0);
            break;
          case "present":
            bytes = Uint8Array.of(0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
            break;
          default:
            throw new Error(`invalid $pointer value: ${node.value}`);
        }
        return {
          type: "bytes",
          bytes,
          size: 8,
          align: 8,
          note: node.note,
        };
      }
      case "$out": {
        return {
          type: "secondary",
          fields: [lower(node.fields[0], "secondary")],
        };
      }
      case "struct": {
        const fields = [];
        let size = 0, align = 0;

        // Helper to add padding.
        function padToAlign(desiredAlign, message) {
          align = Math.max(align, desiredAlign);
          if (size % desiredAlign === 0) {
            return;
          }
          const pad = desiredAlign - size % desiredAlign;
          fields.push({
            type: "bytes",
            bytes: new Uint8Array(pad),
            size: pad,
            align: 1,
            padding: true,
            note: message(pad),
          });
          size += pad;
        }

        if (node.fields.length === 0) {
          size = 1;
          align = 1;
          fields.push({
            type: "bytes",
            bytes: Uint8Array.of(0),
            size,
            align,
            note: `An empty struct encodes to the byte 0x00.`,
          });
        }
        for (const originalField of node.fields) {
          const f = lower(originalField, false);
          if (f.type === "secondary") {
            fields.push(f);
          } else {
            padToAlign(f.align, pad => `${pad} byte${plural(pad)} padding `
              + `to align next field to ${article(f.align)} ${f.align}-byte boundary`);
            // Note: We used to flatten nested inline fields here, but not
            // anymore. Instead, functions like formatBytes() and
            // countTotalBytes() were rewritten to allow for nested inlines.
            fields.push(f);
            size += f.size;
          }
        }
        padToAlign(align, pad => `${pad} byte${plural(pad)} tail padding for `
          + `struct's ${pad}-byte alignment`);
        if (object) {
          padToAlign(8, pad => `${pad} byte${plural(pad)} tail padding for `
            + `${object} object ${align}-byte alignment`);
        }
        return {
          type: "inline",
          size,
          align,
          fields,
        }
      }
    }
    throw Error(`Unexpected type in lowerBytes: ${node.type}`);
  }

  return lower(tree, "primary");
}

// Calculates the total number of bytes that tree (returned by lowerBytes) will
// serialize to. This is distinct from tree.size, which is only the inline size
// (i.e. the size of the primary object).
function countTotalBytes(tree) {
  let size = 0;
  function visit(node, topLevelObject) {
    switch (node.type) {
      case "bytes":
        // Do nothing: size is already rolled up into parent "inline" node.
        break;
      case "inline":
        if (topLevelObject) {
          size += node.size;
        }
        for (const field of node.fields) {
          visit(field, /* topLevelObject = */ false);
        }
        break;
      case "secondary":
        visit(node.fields[0], /* topLevelObject = */ true);
        break;
      default:
        throw Error(`Unexpected type in countTotalBytes: ${node.type}`);
    }
  }

  visit(tree, /* topLevelObject = */ true);
  return size;
}

// Applies lowering functions from...to inclusive.
// 7 means lowerBytes.
function lowerFromTo(tree, from, to) {
  const lowerings = [
    lower1, lower2, lower3, lower4, lower5, lower6, lowerBytes
  ];
  for (let i = from - 1; i < to; i++) {
    tree = lowerings[i](tree);
  }
  return tree;
}

// =============================================================================
// ===== ACE CUSTOMIZATION =====================================================
// =============================================================================

// Custom highlighting for Ace editor.
ace.define("ace/mode/fidlviz",
    ["require", "exports", "ace/lib/oop", "ace/mode/text", "ace/mode/fidlviz_highlight_rules",
    "ace/mode/behaviour/cstyle", "ace/mode/folding/cstyle", "ace/mode/matching_brace_outdent"],
    (require, exports) => {
  const oop = require("ace/lib/oop");
  const TextMode = require("ace/mode/text").Mode;
  const FidlvizHighlightRules = require("ace/mode/fidlviz_highlight_rules").FidlvizHighlightRules;
  const MatchingBraceOutdent = require("ace/mode/matching_brace_outdent").MatchingBraceOutdent;
  const CstyleBehaviour = require("ace/mode/behaviour/cstyle").CstyleBehaviour;
  const CstyleFoldMode = require("ace/mode/folding/cstyle").FoldMode;
  const FidlvizMode = function FidlvizMode() {
    this.$id = "ace/mode/fidlviz";
    this.HighlightRules = FidlvizHighlightRules;
    this.$outdent = new MatchingBraceOutdent();
    this.$behaviour = new CstyleBehaviour();
    this.foldingRules = new CstyleFoldMode();
    this.lineCommentStart = "#";
    // Adapted from:
    // https://fuchsia.googlesource.com/fidlbolt/+/refs/heads/master/frontend/src/ace-modes.js#102
    this.getNextLineIndent = (state, line, tab) => {
      let indent = line.match(/^\s*/)[0];
      const tokens = this.getTokenizer().getLineTokens(line, state).tokens;
      if (tokens.length && tokens[tokens.length - 1].type === "comment") {
        return indent;
      }
      if (state === "start") {
        const match = line.match(/^.*\{\s*$/);
        if (match) {
          indent += tab;
        }
      }
      return indent;
    }
    this.checkOutdent = (state, line, input) => {
      return this.$outdent.checkOutdent(line, input);
    }
    this.autoOutdent = (state, doc, row) => {
      this.$outdent.autoOutdent(doc, row);
    }
  };
  oop.inherits(FidlvizMode, TextMode);
  exports.Mode = FidlvizMode;
});
ace.define("ace/mode/fidlviz_highlight_rules",
    ["require", "exports", "ace/lib/oop", "ace/mode/text_highlight_rules"],
    (require, exports) => {
  const oop = require("ace/lib/oop");
  const TextHighlightRules = require("ace/mode/text_highlight_rules").TextHighlightRules;
  const FidlvizHighlightRules = function FidlvizHighlightRules() {
    this.$rules = {
      start: [
        {
          token: "comment",
          regex: "#.*$",
        },
      ],
    };
  };
  oop.inherits(FidlvizHighlightRules, TextHighlightRules);
  exports.FidlvizHighlightRules = FidlvizHighlightRules;
});

// Custom theme for Ace editor.
ace.define("ace/theme/fidlviz_light", ["require", "exports", "ace/lib/dom"], (require, exports) => {
  exports.isDark = false;
  exports.cssClass = "ace-fl";
  exports.cssText = `
.ace-fl {
  background: #fff;
  color: #111;
}
.ace-fl .ace_gutter {
  background: #eee;
  color: #666;
}
.ace-fl .ace_comment {
  color: #777;
}
.ace-fl .ace_selection {
  background: #d0d0d0;
}
.ace-fl .ace_gutter-active-line {
  background: #e0e0e0;
}
.ace-fl .ace_active-line {
  background: rgba(0, 0, 0, 0.07);
}
  `;
  exports.$id = "ace/theme/fidlviz_light";
  const dom = require("ace/lib/dom");
  dom.importCssString(exports.cssText, exports.cssClass);
});
ace.define("ace/theme/fidlviz_dark", ["require", "exports", "ace/lib/dom"], (require, exports) => {
  exports.isDark = false;
  exports.cssClass = "ace-fd";
  exports.cssText = `
.ace-fd {
  background: #303030;
  color: #eee;
}
.ace-fd .ace_gutter {
  background: #404040;
  color: #aaa;
}
.ace-fd .ace_comment {
  color: #b0b0b0;
}
.ace-fd .ace_selection {
  background: #777;
}
.ace-fd .ace_gutter-active-line {
  background: #505050;
}
.ace-fd .ace_active-line {
  background: rgba(255, 255, 255, 0.07);
}
  `;
  exports.$id = "ace/theme/fidlviz_dark";
  const dom = require("ace/lib/dom");
  dom.importCssString(exports.cssText, exports.cssClass);
});

// =============================================================================
// ===== DEFAULT INPUT =========================================================
// =============================================================================

// Input shown when the user has nothing saved (or after clicking Reset).
const DEFAULT_INPUT = `\
struct {
  # Integers
  0u8, -1i8, 2u16, 3u32, 4u64,

  # Other bases
  0b1010u8, 0xffu8, 0o755u16,

  # Floats
  1.2f32, 1e-8f64,

  # Booleans
  true, false,

  # Strings
  "Hello 🌎\\u0021",
  null string, "",

  # Handles
  null handle, handle { 0xBEEFu32 },

  # Arrays and vectors
  array { 12u8, 223, 0xff }, # all u8
  vector { 1.0f64, 2., .3 }, # all f64
  null vector, vector {},

  # Bits and enums
  bits { 1, 2, 4 }, enum { 42 },

  # Structs
  struct {}, struct { 1u64 },
  null struct, box { struct { 42 } },

  # Tables
  table {}, table { 1: true, 3: false },

  # Unions
  null union, union { 7: "hi" },
}
`;

// =============================================================================
// ===== MAIN UI CODE ==========================================================
// =============================================================================

// Main function called after the window loads.
function main() {
  // ---------------------------------------------------------------------------
  // ----- ACE CONFIG ----------------------------------------------------------
  // ---------------------------------------------------------------------------

  const inputConfig = {
    mode: "ace/mode/fidlviz",
    theme: getTheme(window.matchMedia
      && window.matchMedia("(prefers-color-scheme: dark)").matches),
    fontSize: 14,
    readOnly: false,
    tabSize: 2,
    useSoftTabs: true,
    indentedSoftWrap: false,
    scrollPastEnd: 1,
    showGutter: true,
    showLineNumbers: true,
    showPrintMargin: false,
  };
  const outputConfig = {
    ...inputConfig,
    readOnly: true,
    highlightActiveLine: false,
  };

  // ---------------------------------------------------------------------------
  // ----- DOM ELEMENTS --------------------------------------------------------
  // ---------------------------------------------------------------------------

  const $inputEditor = ace.edit("InputEditor", inputConfig);
  const $outputEditor = ace.edit("OutputEditor", outputConfig);
  const $outputSlider = document.getElementById("OutputSlider");
  const $outputTitle = document.getElementById("OutputTitle");
  const $outputTooltip = document.getElementById("OutputTooltip");
  const $resetButton = document.getElementById("ResetButton");
  const $debugButton = document.getElementById("DebugButton");
  const $layoutButton = document.getElementById("LayoutButton");
  const $helpButton = document.getElementById("HelpButton");
  const $helpModal = document.getElementById("HelpModal");
  const $helpModalContent = document.getElementById("HelpModalContent");
  const $container = document.getElementById("Container");
  const $inputPart = document.getElementById("InputPart");
  const $splitContainer = document.getElementById("SplitContainer");
  const $splitter = document.getElementById("Splitter");

  for (editor of [$inputEditor, $outputEditor]) {
    // We use Ctrl-[ and Ctrl-] to move the slider.
    editor.commands.removeCommand('blockindent');
    editor.commands.removeCommand('blockoutdent');
  }

  // ---------------------------------------------------------------------------
  // ----- DARK MODE -----------------------------------------------------------
  // ---------------------------------------------------------------------------

  // Gets the Ace theme depending on whether dark mode is enabled.
  function getTheme(darkMode) {
    return darkMode ? "ace/theme/fidlviz_dark" : "ace/theme/fidlviz_light";
  }
  if (window.matchMedia) {
    window.matchMedia("(prefers-color-scheme: dark)").addListener(e => {
      const theme = getTheme(e.matches);
      $inputEditor.setTheme(theme);
      $outputEditor.setTheme(theme);
    });
  }

  // ---------------------------------------------------------------------------
  // ----- UI HELPERS ----------------------------------------------------------
  // ---------------------------------------------------------------------------

  // Vertical (left & right) or Horizontal (top & bottom).
  let editorSplitOrientation;

  function setEditorSplitOrientation(orientation) {
    function toggle(o) {
      return o === "vertical" ? "horizontal" : "vertical";
    }
    if (orientation === "toggle") {
      orientation = toggle(editorSplitOrientation);
    }
    editorSplitOrientation = orientation;
    const other = toggle(orientation);
    $splitter.classList.remove(`split-splitter--${other}`);
    $splitter.classList.add(`split-splitter--${orientation}`);
    $splitContainer.classList.remove(`split-container--${other}`);
    $splitContainer.classList.add(`split-container--${orientation}`);
    resizeEditors(editorSplitPosition);
    window.localStorage.editorSplitOrientation = orientation;
  }

  // Keep in sync with the output slider in index.html.
  const LAST_DEBUG_OUTPUT_MODE = "3";
  const LAST_OUTPUT_MODE = "8";

  // In Debug mode, the output shows tokens or parse trees.
  let debugEnabled;
  let outputModeWhenDebugIs;
  function setDebugEnabled(enabled, restoring) {
    debugEnabled = !!enabled;
    if (debugEnabled) {
      $debugButton.classList.add("button--active");
      $outputSlider.max = LAST_DEBUG_OUTPUT_MODE;
    } else {
      $debugButton.classList.remove("button--active");
      $outputSlider.max = LAST_OUTPUT_MODE;
    }
    // Skip this at very beginning when called from restore().
    if (restoring === undefined) {
      setOuputMode(outputModeWhenDebugIs[debugEnabled]);
    }
    window.localStorage.debugEnabled = debugEnabled;
  }

  // Show byte offsets instead of line numbers when viewing bytes.
  let currentOutputMode = undefined;
  $outputEditor.session.gutterRenderer =  {
    getWidth: function(_session, lastLineNumber, config) {
      // Note: lastLineNumber is a value returned by getText(), so it has
      // already been multiplied by 8 if necessary.
      return lastLineNumber.toString().length * config.characterWidth;
    },
    getText: function(_session, row) {
      if (currentOutputMode === LAST_OUTPUT_MODE && !state.error) {
        return row * 8;
      }
      return (row + 1).toString();
    }
  };

  // Updates output slider and title, but not the editors.
  function setOuputMode(mode) {
    $outputSlider.value = mode;
    $outputTitle.innerHTML = getTitle(mode);
    outputModeWhenDebugIs[debugEnabled] = mode;
    window.localStorage.outputModeWhenDebugIs = JSON.stringify(outputModeWhenDebugIs);
    // Do a full update whenever the line number format needs to change.
    if ((currentOutputMode === LAST_OUTPUT_MODE) !== (mode === LAST_OUTPUT_MODE)) {
      $outputEditor.renderer.updateFull();
    }
    currentOutputMode = mode;
  }

  // Number from 0 to 1 (0.5 means split halfway).
  let editorSplitPosition;

  // Applies styling to resize the editors to a split defined by the position
  // from 0 to 1 (0.5 means each editor takes up half the space).
  function resizeEditors(position) {
    // 4px is half the splitter thickness, 8px.
    $inputPart.style.flexBasis = `calc(${position * 100}% - 4px)`;
    if (editorSplitOrientation === "vertical") {
      $inputPart.style.maxWidth = `calc(100% - 8px)`;
      $inputPart.style.maxHeight = "none";
    } else {
      $inputPart.style.maxHeight = `calc(100% - 8px)`;
      $inputPart.style.maxWidth = "none";
    }
    editorSplitPosition = position;
    window.localStorage.editorPosition = JSON.stringify(position);
    // Let Ace editors know their parent has resized.
    $inputEditor.resize();
    $outputEditor.resize();
  }

  // Converts a mode (slider value) to a title.
  function getTitle(mode) {
    if (debugEnabled) {
      switch (mode) {
        case "1":
          return "Tokens";
        case "2":
          return "Annotated Tokens";
        case "3":
          return "Parse tree";
      }
    }
    switch (mode) {
      case "1":
        return "Format";
      case "2":
        return "[1] Lower tables & unions";
      case "3":
        return "[2] Lower bits & enums";
      case "4":
        return "[3] Lower strings";
      case "5":
        return "[4] Lower vectors";
      case "6":
        return "[5] Lower handles & envelopes";
      case "7":
        return "[6] Lower arrays & boxes";
      case "8":
        return "Bytes";
    }
  }

  // ---------------------------------------------------------------------------
  // ----- UTILITIES --------------------------------------------------------------
  // ---------------------------------------------------------------------------

  // Converts an object to a pretty-printed JSON string.
  function stringify(obj) {
    return JSON.stringify(
      obj,
      (_key, value) => typeof value === "bigint" ? value.toString() : value,
      INDENT
    );
  };

  // Wraps text to the given maximum width, preserving existing newlines.
  // https://fuchsia.googlesource.com/fidlbolt/+/refs/heads/master/frontend/src/util.ts#16
  function wordWrap(text, width) {
    function wrap(line) {
      const words = line.split(' ');
      let lineLength = 0;
      const withNewlines = words.map(w => {
        lineLength += w.length + 1;
        if (lineLength > width) {
          lineLength = w.length;
          return '\n' + w;
        }
        return w;
      });
      return withNewlines.join(' ');
    }
    const lines = text.split('\n');
    return lines.map(wrap).join('\n');
  }

  // Returns true if r1 and r2 represent the same output editor range.
  function outputRangesEqual(r1, r2) {
    return r1.start.row === r2.start.row
      && r1.start.col === r2.start.col
      && r1.end.row === r2.end.row
      && r1.end.col === r2.end.col;
  }

  // ---------------------------------------------------------------------------
  // ----- MAIN UI UPDATES -----------------------------------------------------
  // ---------------------------------------------------------------------------

  // State retained between updates.
  let state = {
    // True if there is an error (which we are displaying in the output).
    error: false,
    // Keep track of markers in order to remove them later.
    errorMarker: undefined,
    inputMarkers: [],
    outputMarkers: [],
    underlineMarkers: {"has-tooltip": [], "has-tooltip-active": []},
    // Parse tree and final output tree.
    tree: undefined,
    outputTree: undefined,
    // Highlighting and tooltip state.
    highlightState: {lastBestNode: undefined, lastOnFirst: undefined},
    tooltipState: {lastBestNode: undefined, lastDocPos: undefined},
  };

  // Flag to avoid trigerring cursor events when writing output.
  let updateOutputInProgress = false;

  // Updates the output given input text.
  function update() {
    const outputMode = $outputSlider.value;
    const previouslyHadError = state.error;

    function getOutput(input) {
      $inputEditor.session.clearAnnotations();
      state.error = false;
      if (state.errorMarker !== undefined) {
        $inputEditor.session.removeMarker(state.errorMarker);
        state.errorMarker = undefined;
      }
      clearHighlights();
      clearTooltip();
      clearUnderlines();
      state.tree = undefined;
      state.outputTree = undefined;
      try {
        const tokens = tokenize(input);
        const tree = parse(tokens);
        state.tree = tree;
        if (debugEnabled) {
          switch (outputMode) {
            case "1":
              return stringify(tokens.map(t => t.text));
            case "2":
              return stringify(tokens);
            case "3":
              return stringify(tree);
          }
        }
        const outputTree = lowerFromTo(state.tree, 1, outputMode - 1);
        state.outputTree = outputTree;
        return outputMode === LAST_OUTPUT_MODE ? formatBytes(outputTree) : format(outputTree);
      } catch (ex) {
        state.error = true;
        let start, end, message;
        if (ex.message !== undefined) {
          if (ex.token !== undefined) {
            start = ex.token.start;
            end = ex.token.end;
            message = `${JSON.stringify(ex.token.text)}: ${ex.message}`;
          } else if (ex.range !== undefined) {
            start = ex.range.first.start;
            end = ex.range.last.end;
            message = ex.message;
          } else {
            message = ex.message;
          }
        } else {
          message = ex;
        }

        if (start && end) {
          state.errorMarker = $inputEditor.session.addMarker(
            new ace.Range(start.row, start.col, end.row, end.col),
            "input-error",
            "text",
          );
          $inputEditor.session.setAnnotations([{
            row: start.row,
            column: start.col,
            type: "error",
            text: wordWrap(message, 66),
          }]);
          return `ERROR at ${start.row+1}:${start.col+1}: ${message}`;
        }
        return `ERROR: ${message}`;
      }
    }

    const input = $inputEditor.getValue();
    const output = getOutput(input);
    updateOutputInProgress = true;
    $outputEditor.session.setValue(output);
    updateOutputInProgress = false;
    // We need to rehighlight now that the output is changed. Even though the
    // user might have had output-cursor-driven highlighting, we can't maintain
    // that because the output could be completely different now. So highlight
    // from the input cursor position.
    highlight("input");
    // The underlines are useless for bytes -- every byte would get underlined.
    // Instead, we only underline for the active (hovered) node.
    if (outputMode !== LAST_OUTPUT_MODE) {
      underlineTooltipRegions(
        state.outputTree, /* skipWhitespace = */ true, "has-tooltip");
    }
    // If we go between error/non-error in the byte output mode, update the
    // renderer since the line numbers have changed (non-error bytes mode uses
    // line numbers 0, 8, 16, etc.).
    if (outputMode === LAST_OUTPUT_MODE && (state.error !== previouslyHadError)) {
      $outputEditor.renderer.updateFull();
    }
    // Enable output editor wrapping only when showing errors, to ensure they
    // are always fully visible.
    $outputEditor.session.setUseWrapMode(state.error);
  }

  // Clears all input and output highlights.
  function clearHighlights() {
    for (const marker of state.inputMarkers) {
      $inputEditor.session.removeMarker(marker);
    }
    for (const marker of state.outputMarkers) {
      $outputEditor.session.removeMarker(marker);
    }
    state.inputMarkers = [];
    state.outputMarkers = [];
  }

  // Highlights input and output editors. Also underlines output regions that
  // have tooltips.
  function highlight(cursorFrom /* : "input" | "output" */) {
    if (state.tree === undefined) {
      return;
    }

    function le(p1, p2) {
      return p1.row < p2.row || (p1.row === p2.row && p1.col <= p2.col);
    }

    let bestNode;
    let inputPos;
    if (cursorFrom === "input") {
      const cursor = $inputEditor.getCursorPosition();
      const pos = {row: cursor.row, col: cursor.column};
      inputPos = pos;

      let bestStart = {row: -Infinity, col: -Infinity};
      function visit(node) {
        const start = node.range.first.start;
        const end = node.range.last.end;
        if (le(start, pos) && le(pos, end) && le(bestStart, start)) {
          bestNode = node;
          bestStart = start;
        }
        if (node.fields !== undefined) {
          for (const field of node.fields) {
            visit(field);
          }
        }
      }
      visit(state.tree);
    } else if (cursorFrom === "output") {
      if (state.outputTree === undefined) {
        return;
      }
      const cursor = $outputEditor.getCursorPosition();
      const pos = {row: cursor.row, col: cursor.column};
      let node = findClosestOutputNode(pos, /* hasInputSource = */true);
      if (!node) {
        return;
      }
      // Walk back to find the input node.
      while (node.loweredFrom !== undefined) {
        node = node.loweredFrom;
      }
      if (node.range === undefined) {
        throw Error("loweredFrom chain did not lead to input node with range");
      }
      bestNode = node;
    } else {
      throw Error(`unexpected cursorFrom: ${cursorFrom}`);
    }

    if (bestNode === undefined) {
      state.highlightState.lastBestNode = undefined;
      state.highlightState.lastOnFirst = undefined;
      clearHighlights();
      return;
    }
    const onFirst = inputPos === undefined ||
      le(bestNode.range.first.start, inputPos) && le(inputPos, bestNode.range.first.end);
    if (bestNode === state.highlightState.lastBestNode && onFirst === state.highlightState.lastOnFirst) {
      return;
    }
    state.highlightState.lastBestNode = bestNode;
    state.highlightState.lastOnFirst = onFirst;

    clearHighlights();
    const nodes =
      onFirst || bestNode.fields === undefined || bestNode.fields.length === 0
      ? [bestNode] : bestNode.fields;
    // List of lists of output ranges. Element i corresponds to nodes[i].
    const outputRangesForNode = [];
    // Keep track of whether all nodes map to the same output range. If so,
    // we'll give them the same color to avoid confusion. This is the case when
    // highlighting all bits members after they've been lowered to 1 integer.
    let outputsCoincide = true;

    // Populate outputRangesForNode and calculate outputsCoincide.
    for (const node of nodes) {
      // outputRanges: [{start, end}] positions.
      // Position: {row, col} zero-based.
      let outputRanges = [];
      function explore(node) {
        if (node.lowered) {
          for (const lowered of node.lowered) {
            explore(lowered);
          }
        } else if (node.outputRanges !== undefined) {
          outputRanges.push(...node.outputRanges);
        }
      }
      explore(node);
      outputRangesForNode.push(outputRanges);
      if (outputsCoincide
        && (outputRanges.length !== 1 || !outputRangesEqual(outputRanges[0], outputRangesForNode[0][0]))) {
        outputsCoincide = false;
      }
    }

    // Add highlight markers.
    for (let i = 0; i < nodes.length; i++) {
      // Range: {first, last} tokens.
      // Token: {start, end} positions.
      // Position: {row, col} zero-based.
      const range = nodes[i].range;
      // NOTE: Keep 9 in sync with the number of highlight classes in style.css.
      const highlightClass = outputsCoincide ? "highlight-1" : `highlight-${i%9+1}`;
      state.inputMarkers.push($inputEditor.session.addMarker(
        new ace.Range(
          range.first.start.row,
          range.first.start.col,
          range.last.end.row,
          range.last.end.col,
        ),
        highlightClass,
        "text",
        false, // behind the text, not in front
      ));

      for (const {start, end} of outputRangesForNode[i]) {
        state.outputMarkers.push($outputEditor.session.addMarker(
          new ace.Range(
            start.row,
            start.col,
            end.row,
            end.col,
          ),
          highlightClass,
          "text",
          false, // behind the text, not in front
        ));
      }
    }
  }

  // Clears underline markers in the output.
  function clearUnderlines(cssClass) {
    if (cssClass === undefined) {
      clearUnderlines("has-tooltip");
      clearUnderlines("has-tooltip-active");
      return;
    }
    for (const marker of state.underlineMarkers[cssClass]) {
      $outputEditor.session.removeMarker(marker);
    }
    state.underlineMarkers[cssClass] = [];
  }

  // Underlines regions of the output that have tooltips.
  function underlineTooltipRegions(startingOutputNode, skipWhitespace, cssClass) {
    clearUnderlines(cssClass);
    if (state.outputTree === undefined) {
      return;
    }
    // Comparison operators for {row, col} ranges (col exclusive).
    function le(p1, p2) {
      return p1.row < p2.row || (p1.row === p2.row && p1.col <= p2.col);
    }
    function lt(p1, p2) {
      return !(p1.row === p2.row && p1.col === p2.col) && le(p1, p2);
    }

    // Subtract a list of [{start, end}] from range: {start, end}.
    function subtract(range, others, p) {
      let result = [{...range}];
      for (const other of others) {
        const newResult = [];
        for (const r of result) {
          if (lt(other.start, r.end) && lt(r.start, other.end)) {
            if (le(other.start, r.start) && lt(other.end, r.end)) {
              newResult.push({start: other.end, end: r.end});
            } else if (lt(r.start, other.start) && lt(other.end, r.end)) {
              newResult.push({start: r.start, end: other.start});
              newResult.push({start: other.end, end: r.end});
            } else if (lt(r.start, other.start) && le(r.end, other.end)) {
              newResult.push({start: r.start, end: other.start});
            } else {
            }
          } else {
            newResult.push(r);
          }
        }
        result = newResult;
      }
      return result;
    }

    // Returns a list of ranges that have notes/tooltips (if wantNote is true)
    // or that do *not* (if wantNote is false).
    function getTooltipRanges(node, wantNote) {
      const children = node.fields === undefined ? [] : node.fields;
      const haveNote = node.note !== undefined;
      if (wantNote === haveNote) {
        const opposite = getTooltipRanges(node, !wantNote);
        return node.outputRanges.flatMap(r => subtract(r, opposite));
      }
      return children.flatMap(n => getTooltipRanges(n, wantNote));
    }

    // Get whitespace (or other tokens we don't want to underline).
    const whitespaceRanges = [];
    if (skipWhitespace) {
      let row = 0, col = 0;
      let whitespaceStart = undefined;
      let inWhitespace = false;
      for (const ch of $outputEditor.getValue()) {
        if (!inWhitespace && (ch.trim() === "" || ch === "," || ch === "{" || ch === "}")) {
          inWhitespace = true;
          whitespaceStart = {row, col};
        } else if (inWhitespace && !(ch.trim() === "" || ch === "," || ch === "{" || ch === "}")) {
          whitespaceRanges.push({start: whitespaceStart, end: {row, col}});
          inWhitespace = false;
          whitespaceStart = undefined;
        }
        col++;
        if (ch === "\n") {
          row++;
          col = 0;
        }
      }
      if (whitespaceStart !== undefined) {
        whitespaceRanges.push({start: whitespaceStart, end: {row, col}});
      }
    }

    for (const fullRange of getTooltipRanges(startingOutputNode, true)) {
      for (const range of
            skipWhitespace ? subtract(fullRange, whitespaceRanges) : [fullRange]) {
        state.underlineMarkers[cssClass].push($outputEditor.session.addMarker(
          new ace.Range(
            range.start.row,
            range.start.col,
            range.end.row,
            range.end.col,
          ),
          cssClass,
          "text",
          true, // in front of the text, not behind
        ));
      }
    }
  }

  // Clears the tooltip in the output editor.
  function clearTooltip() {
    $outputTooltip.hidden = true;
    $outputTooltip.innerHTML = "";
    state.tooltipState.lastBestNode = undefined;
    // Remove the active underline since it's no longer active.
    clearUnderlines("has-tooltip-active");
  }

  // Finds the output node closest to pos.
  function findClosestOutputNode(pos, hasInputSource) {
    function le(p1, p2) {
      return p1.row < p2.row || (p1.row === p2.row && p1.col <= p2.col);
    }

    // Returns true if node can be traced back to an input node, with a range
    // specifying the input's location in the input editor.
    function searchForInput(node) {
      while (node !== undefined) {
        if (node.range !== undefined) {
          return true;
        }
        node = node.loweredFrom;
      }
      return false;
    }

    let bestNode;
    let bestStart = {row: -Infinity, col: -Infinity};
    function visit(node) {
      for (const {start, end} of node.outputRanges) {
        if (le(start, pos) && le(pos, end) && le(bestStart, start)
            && (!hasInputSource || searchForInput(node))) {
          bestNode = node;
          bestStart = start;
        }
      }
      if (node.fields !== undefined) {
        for (const field of node.fields) {
          visit(field);
        }
      }
    }

    visit(state.outputTree);
    return bestNode;
  }

  // Shows tooltips based on the cursor position in the output editor.
  function updateTooltip(docPos, pixelPos) {
    if (state.outputTree === undefined) {
      return;
    }

    if (docPos === state.tooltipState.lastDocPos) {
      $outputTooltip.style.left = `${pixelPos.pageX}px`;
      $outputTooltip.style.top = `${pixelPos.pageY}px`;
      return;
    }
    state.tooltipState.lastDocPos = docPos;

    const pos = {row: docPos.row, col: docPos.column};
    const bestNode = findClosestOutputNode(pos, /* hasInputSource = */ false);

    if (bestNode === undefined || bestNode.note === undefined) {
      clearTooltip();
      return;
    }
    if (bestNode === state.tooltipState.lastBestNode) {
      $outputTooltip.style.left = `${pixelPos.pageX}px`;
      $outputTooltip.style.top = `${pixelPos.pageY}px`;
      return;
    }
    state.tooltipState.lastBestNode = bestNode;

    $outputTooltip.style.left = `${pixelPos.pageX}px`;
    $outputTooltip.style.top = `${pixelPos.pageY}px`;
    $outputTooltip.innerHTML = wordWrap(bestNode.note, 66);
    $outputTooltip.hidden = false;

    // In bytes mode, we don't underline the things that can be hovered over
    // (in update()) because *everything* can be hovered. Instead, we show an
    // underline for the current tooltip to show the extent of it. In other
    // modes, we also show a more distinct underline for the active one.
    underlineTooltipRegions(
      bestNode,
      /* skipWhitespace = */ $outputSlider.value !== LAST_OUTPUT_MODE,
      "has-tooltip-active");
  }

  // ---------------------------------------------------------------------------
  // ----- RESTORE -------------------------------------------------------------
  // ---------------------------------------------------------------------------

  // Used to avoid firing events while restoring (either in the beginning or
  // when the Reset button is clicked).
  let restoreInProgress;

  // Restores the site from localStorage.
  function restore() {
    restoreInProgress = true;
    if (window.localStorage.editorPosition) {
      editorSplitPosition = JSON.parse(window.localStorage.editorPosition);
    } else {
      editorSplitPosition = 0.5;
    }
    // This will also call resizeEditors.
    setEditorSplitOrientation(window.localStorage.editorSplitOrientation || "vertical");
    if (window.localStorage.debugEnabled) {
      setDebugEnabled(JSON.parse(window.localStorage.debugEnabled), "restoring");
    } else {
      setDebugEnabled(false, "restoring");
    }
    if (window.localStorage.outputModeWhenDebugIs) {
      outputModeWhenDebugIs = JSON.parse(window.localStorage.outputModeWhenDebugIs);
    } else {
      outputModeWhenDebugIs = {false: $outputSlider.max, true: $outputSlider.min};
    }
    setOuputMode(outputModeWhenDebugIs[debugEnabled]);
    // Hidden at first to avoid a flash from default 50% editor split to the
    // restored value. This also applies for the output slider (Debug or not
    // Debug can cause flash). So we just hide the whole container till ready.
    $container.hidden = false;
    let input = window.localStorage.input;
    if (!input || input.trim() === "") {
      input = DEFAULT_INPUT;
    }
    $inputEditor.session.setValue(input);
    // Move the cursor to the open brace so that we get the rainbow highlights.
    // Note: still do this even if we restored from localStorage, but it was
    // unchanged from the default.
    if (input === DEFAULT_INPUT) {
      $inputEditor.moveCursorTo(0, 8);
    }
    update();
    restoreInProgress = false;
  }

  // ---------------------------------------------------------------------------
  // ----- EVENTS --------------------------------------------------------------
  // ---------------------------------------------------------------------------

  // Update and save whenever the input changes.
  $inputEditor.on("change", () => {
    if (restoreInProgress) {
      return;
    }
    update();
    window.localStorage.input = $inputEditor.getValue();
  });

  // Re-highlight whenever the cursor moves. But not when selecting text.
  $inputEditor.session.getSelection().on("changeCursor", () => {
    if (restoreInProgress) {
      return;
    }
    if ($inputEditor.session.getSelection().isEmpty()) {
      highlight("input");
    }
  });
  $outputEditor.session.getSelection().on("changeCursor", () => {
    if (restoreInProgress || updateOutputInProgress) {
      return;
    }
    if ($outputEditor.session.getSelection().isEmpty()) {
      highlight("output");
    }
  });

  // Update the output view whenever the slider changes.
  $outputSlider.oninput = () => {
    if (restoreInProgress) {
      return;
    }
    setOuputMode($outputSlider.value);
    update();
  };
  // Also allow moving the slider using Ctrl-[ and Ctrl-].
  document.addEventListener("keydown", (e) => {
    let delta;
    if (e.ctrlKey && e.key === "[") {
      delta = -1;
    } else if (e.ctrlKey && e.key === "]") {
      delta = 1;
    } else {
      return;
    }
    const newValue = (parseInt($outputSlider.value) + delta).toString();
    if (newValue < $outputSlider.min || newValue > $outputSlider.max) {
      return;
    }
    $outputSlider.value = newValue;
    setOuputMode(newValue);
    update();
  });

  // Update output tooltip when the cursor moves.
  $outputEditor.on("mousemove", e => {
    const docPos = e.getDocumentPosition();
    if (!docPos || !$outputEditor.session.getSelection().isEmpty()) {
      clearTooltip();
      return;
    }
    const screenPos = $outputEditor.session.documentToScreenPosition(docPos);
    if (
        // Avoid tooltip persisting when moving into the blank space to the right.
        $outputEditor.session.getScreenLastRowColumn(screenPos.row) === screenPos.column
        // Avoid weird flicker when moving past top edge of window.
        || (docPos.row === 0 && docPos.column === 0 && screenPos.row === 0 && screenPos.column === 0)) {
      clearTooltip();
      return;
    }
    const pixelPos = $outputEditor.renderer.textToScreenCoordinates(docPos);
    pixelPos.pageX += 10;

    // Removing this because large tooltips at the bottom cause a scrollbar
    // on the entire document, jerking the page when the tooltip appears.
    // It can still happen with large tooltips, but it's alleviated by the fact
    // that I enabled scrollPastEnd on the editors.
    //
    // EDIT: uncommenting it again because I have made body overflow: hidden
    // so that problem is gone. On bytes it's nice to have the tooltip below
    // to not obstruct the rest of the line.
    pixelPos.pageY += $outputEditor.renderer.lineHeight + 2;

    updateTooltip(docPos, pixelPos);
  });

  document.getElementById("OutputEditor").addEventListener("mouseleave", () => {
    clearTooltip();
  });

  // Allow the editor splitter to be dragged.
  let draggingSplitter = false;
  $splitter.addEventListener("mousedown", () => draggingSplitter = true);
  document.addEventListener("mouseup", () => draggingSplitter = false);
  document.addEventListener("mousemove", (e) => {
    if (!draggingSplitter) {
      return;
    }
    const rect = $container.getBoundingClientRect();
    // NOTE: Keep the number below in sync with style.css.
    const position = editorSplitOrientation === "vertical"
      ? (e.pageX - rect.x) / rect.width
      : (e.pageY - rect.y) / rect.height;
    const clamped = Math.max(0, Math.min(1, position));
    resizeEditors(clamped);
  });

  // Toggle Debug mode when the Debug button is clicked.
  $debugButton.onclick = () => {
    setDebugEnabled(!debugEnabled);
    update();
  };

  $layoutButton.onclick = () => setEditorSplitOrientation("toggle");

  function exitModalKeyListener(e) {
    if (e.key === "Enter" || e.key === "Escape") {
      // Without preventDefault, pressing Enter would hide the window and then
      // immediately show it again because it presses the Help button again (if
      // it's still in focus).
      e.preventDefault();
      hideHelpModal();
    }
  }
  function showHelpModal() {
    $helpModal.hidden = false;
    document.addEventListener("keydown", exitModalKeyListener);
  }
  function hideHelpModal() {
    $helpModal.hidden = true;
    document.removeEventListener("keydown", exitModalKeyListener);
  }

  // Open the help window on clicking the Help button. It also functions as a
  // toggle so that if you press space while it's still in focus, it will close
  // the help window.
  $helpButton.onclick = () => {
    if ($helpModal.hidden) {
      showHelpModal();
    } else {
      hideHelpModal();
    }
  };
  // Click outside the modal to hid eit. But use stopPropagation to prevent
  // clicks on the modal content itself from closing it.
  $helpModal.onclick = hideHelpModal;
  $helpModalContent.onclick = (e) => e.stopPropagation();

  // Reset all data to the defaults on clicking the Reset buton.
  $resetButton.onclick = () => {
    window.localStorage.clear();
    restore();
  };

  restore();
};

window.onload = () => {
  // Load ace/mode/json first. Running main() eventually results in setting an
  // editor mode to ace/mode/fidlviz. This imports some resources that are not
  // exposed as separate files by the CDN, like ace/mode/behaviour/cstyle. By
  // first loading ace/mode/json, these common resources get populated in Ace's
  // internal map, so it won't attempt and fail to load them from the CDN.
  ace.config.loadModule("ace/mode/json", () => {
    main();
  });
};

})(); // end IIFE
