(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.length == v2.fields.length
          && 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;
          }
        }
        return true;
      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 "pad4":
      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) {
            if (field.type !== "$out") {
              push(INDENT.repeat(indent + 1));
            }
            thunks.push(helper(field, indent + 1, /* topLevelObject = */ false));
            if (field.type !== "$out") {
              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 (const 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 (row >= rowLengths.length || 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 (const 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. Occasionally 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, config, 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, config);
    }
    if ("fields" in node) {
      return {...copyNode(node), fields: node.fields.map(f => self(f, config))};
    }
    // 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, config) {
  return doLowering(tree, config, 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, config) {
  return doLowering(tree, config, 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, config) {
  return doLowering(tree, config, 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, config) {
  return doLowering(tree, config, 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, config) {
  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, config, 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) {
          if (config.v2Enabled) {
            return {
              type: "$pointer",
              value: "absent",
              note: node.note,
            };
          }
          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 payload = lowerBytes(lower6(lower5(node.fields[0], config), config), config);
        const bytes = countTotalBytes(payload);
        disableAddLowered = false;
        const handles = countPresentHandles(node.fields[0]);
        if (config.v2Enabled) {
          const lastField = payload.fields[payload.fields.length - 1]
          if (bytes === 8 && lastField.padding && lastField.size >= 4) {
            return {
              type: "struct",
              fields: [
                {
                  ...copyNode(node),
                  type: "pad4",
                  note: "Pad inlined envelope value to 4 bytes"
                },
                {type: "int", signed: "u", width: 16,
                 orig: handles.toString(), value: handles,
                note: `Envelope: ${handles} handle${plural(handles)}`},
                {type: "int", signed: "u", width: 16, orig: "1", value: 1,
                 note: "Envelope flags: inlined representation"},
              ],
              note: node.note,
            };
          }
          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: 16, orig: handles.toString(), value: handles,
               note: `Envelope: ${handles} handle${plural(handles)}`},
              {type: "int", signed: "u", width: 16, orig: "0", value: 0,
               note: "Envelope flags: out-of-line representation"},
              {type: "$out", fields: node.fields,
               note: "Envelope: out-of-line data"},
            ],
            note: node.note,
          };
        }
        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: arrays and boxes. Assumes earlier lowerings are done.
function lower6(tree, config) {
  return doLowering(tree, config, 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, config) {
  // object can be "primary", "secondary", "pad4", 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 "pad4": {
        return lower(node.fields[0], "pad4");
      }
      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 === "pad4") {
          padToAlign(4, pad => `${pad} byte${plural(pad)} tail padding for `
            + `object inlined in envelope`);
        } else 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, config) {
  const lowerings = [
    lower1, lower2, lower3, lower4, lower5, lower6, lowerBytes
  ];
  for (let i = from - 1; i < to; i++) {
    tree = lowerings[i](tree, config);
  }
  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 $outputV2Control = document.getElementById("OutputV2Control");
  const $outputV2Checkbox = document.getElementById("OutputV2Checkbox");
  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 (const 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;
      $outputV2Control.hidden = true;
    } else {
      $debugButton.classList.remove("button--active");
      $outputSlider.max = LAST_OUTPUT_MODE;
      $outputV2Control.hidden = false;
    }
    // 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;

    const config = {
      v2Enabled: $outputV2Checkbox.checked,
    };

    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, config);
        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]);
    $outputV2Checkbox.checked = true;
    // 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();
  };
  // Update the output view whenever the v2 checkox changes.
  $outputV2Checkbox.oninput = () => {
    if (restoreInProgress) {
      return;
    }
    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
