/*
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
if you want to view the source, please visit the github repository of this plugin
*/

var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __markAsModule = (target) => __defProp(target, "__esModule", { value: true });
var __commonJS = (cb, mod) => function __require() {
  return mod || (0, cb[Object.keys(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
  __markAsModule(target);
  for (var name in all)
    __defProp(target, name, { get: all[name], enumerable: true });
};
var __reExport = (target, module2, desc) => {
  if (module2 && typeof module2 === "object" || typeof module2 === "function") {
    for (let key of __getOwnPropNames(module2))
      if (!__hasOwnProp.call(target, key) && key !== "default")
        __defProp(target, key, { get: () => module2[key], enumerable: !(desc = __getOwnPropDesc(module2, key)) || desc.enumerable });
  }
  return target;
};
var __toModule = (module2) => {
  return __reExport(__markAsModule(__defProp(module2 != null ? __create(__getProtoOf(module2)) : {}, "default", module2 && module2.__esModule && "default" in module2 ? { get: () => module2.default, enumerable: true } : { value: module2, enumerable: true })), module2);
};
var __async = (__this, __arguments, generator) => {
  return new Promise((resolve, reject) => {
    var fulfilled = (value) => {
      try {
        step(generator.next(value));
      } catch (e) {
        reject(e);
      }
    };
    var rejected = (value) => {
      try {
        step(generator.throw(value));
      } catch (e) {
        reject(e);
      }
    };
    var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
    step((generator = generator.apply(__this, __arguments)).next());
  });
};

// node_modules/node-webvtt/lib/parser.js
var require_parser = __commonJS({
  "node_modules/node-webvtt/lib/parser.js"(exports, module2) {
    "use strict";
    function ParserError(message, error) {
      this.message = message;
      this.error = error;
    }
    ParserError.prototype = Object.create(Error.prototype);
    var TIMESTAMP_REGEXP = /([0-9]{1,2})?:?([0-9]{2}):([0-9]{2}\.[0-9]{2,3})/;
    function parse2(input, options) {
      if (!options) {
        options = {};
      }
      const { meta = false, strict = true } = options;
      if (typeof input !== "string") {
        throw new ParserError("Input must be a string");
      }
      input = input.trim();
      input = input.replace(/\r\n/g, "\n");
      input = input.replace(/\r/g, "\n");
      const parts = input.split("\n\n");
      const header = parts.shift();
      if (!header.startsWith("WEBVTT")) {
        throw new ParserError('Must start with "WEBVTT"');
      }
      const headerParts = header.split("\n");
      const headerComments = headerParts[0].replace("WEBVTT", "");
      if (headerComments.length > 0 && (headerComments[0] !== " " && headerComments[0] !== "	")) {
        throw new ParserError("Header comment must start with space or tab");
      }
      if (parts.length === 0 && headerParts.length === 1) {
        return { valid: true, strict, cues: [], errors: [] };
      }
      if (!meta && headerParts.length > 1 && headerParts[1] !== "") {
        throw new ParserError("Missing blank line after signature");
      }
      const { cues, errors } = parseCues(parts, strict);
      if (strict && errors.length > 0) {
        throw errors[0];
      }
      const headerMeta = meta ? parseMeta(headerParts) : null;
      const result = { valid: errors.length === 0, strict, cues, errors };
      if (meta) {
        result.meta = headerMeta;
      }
      return result;
    }
    function parseMeta(headerParts) {
      const meta = {};
      headerParts.slice(1).forEach((header) => {
        const splitIdx = header.indexOf(":");
        const key = header.slice(0, splitIdx).trim();
        const value = header.slice(splitIdx + 1).trim();
        meta[key] = value;
      });
      return Object.keys(meta).length > 0 ? meta : null;
    }
    function parseCues(cues, strict) {
      const errors = [];
      const parsedCues = cues.map((cue, i) => {
        try {
          return parseCue(cue, i, strict);
        } catch (e) {
          errors.push(e);
          return null;
        }
      }).filter(Boolean);
      return {
        cues: parsedCues,
        errors
      };
    }
    function parseCue(cue, i, strict) {
      let identifier = "";
      let start = 0;
      let end = 0.01;
      let text = "";
      let styles = "";
      const lines = cue.split("\n").filter(Boolean);
      if (lines.length > 0 && lines[0].trim().startsWith("NOTE")) {
        return null;
      }
      if (lines.length === 1 && !lines[0].includes("-->")) {
        throw new ParserError(`Cue identifier cannot be standalone (cue #${i})`);
      }
      if (lines.length > 1 && !(lines[0].includes("-->") || lines[1].includes("-->"))) {
        const msg = `Cue identifier needs to be followed by timestamp (cue #${i})`;
        throw new ParserError(msg);
      }
      if (lines.length > 1 && lines[1].includes("-->")) {
        identifier = lines.shift();
      }
      const times = typeof lines[0] === "string" && lines[0].split(" --> ");
      if (times.length !== 2 || !validTimestamp(times[0]) || !validTimestamp(times[1])) {
        throw new ParserError(`Invalid cue timestamp (cue #${i})`);
      }
      start = parseTimestamp(times[0]);
      end = parseTimestamp(times[1]);
      if (strict) {
        if (start > end) {
          throw new ParserError(`Start timestamp greater than end (cue #${i})`);
        }
        if (end <= start) {
          throw new ParserError(`End must be greater than start (cue #${i})`);
        }
      }
      if (!strict && end < start) {
        throw new ParserError(`End must be greater or equal to start when not strict (cue #${i})`);
      }
      styles = times[1].replace(TIMESTAMP_REGEXP, "").trim();
      lines.shift();
      text = lines.join("\n");
      if (!text) {
        return false;
      }
      return { identifier, start, end, text, styles };
    }
    function validTimestamp(timestamp) {
      return TIMESTAMP_REGEXP.test(timestamp);
    }
    function parseTimestamp(timestamp) {
      const matches = timestamp.match(TIMESTAMP_REGEXP);
      let secs = parseFloat(matches[1] || 0) * 60 * 60;
      secs += parseFloat(matches[2]) * 60;
      secs += parseFloat(matches[3]);
      return secs;
    }
    module2.exports = { ParserError, parse: parse2 };
  }
});

// node_modules/node-webvtt/lib/compiler.js
var require_compiler = __commonJS({
  "node_modules/node-webvtt/lib/compiler.js"(exports, module2) {
    "use strict";
    function CompilerError(message, error) {
      this.message = message;
      this.error = error;
    }
    CompilerError.prototype = Object.create(Error.prototype);
    function compile(input) {
      if (!input) {
        throw new CompilerError("Input must be non-null");
      }
      if (typeof input !== "object") {
        throw new CompilerError("Input must be an object");
      }
      if (Array.isArray(input)) {
        throw new CompilerError("Input cannot be array");
      }
      if (!input.valid) {
        throw new CompilerError("Input must be valid");
      }
      let output = "WEBVTT\n";
      if (input.meta) {
        if (typeof input.meta !== "object" || Array.isArray(input.meta)) {
          throw new CompilerError("Metadata must be an object");
        }
        Object.entries(input.meta).forEach((i) => {
          if (typeof i[1] !== "string") {
            throw new CompilerError(`Metadata value for "${i[0]}" must be string`);
          }
          output += `${i[0]}: ${i[1]}
`;
        });
      }
      let lastTime = null;
      input.cues.forEach((cue, index) => {
        if (lastTime && lastTime > cue.start) {
          throw new CompilerError(`Cue number ${index} is not in chronological order`);
        }
        lastTime = cue.start;
        output += "\n";
        output += compileCue(cue);
        output += "\n";
      });
      return output;
    }
    function compileCue(cue) {
      if (typeof cue !== "object") {
        throw new CompilerError("Cue malformed: not of type object");
      }
      if (typeof cue.identifier !== "string" && typeof cue.identifier !== "number" && cue.identifier !== null) {
        throw new CompilerError(`Cue malformed: identifier value is not a string.
    ${JSON.stringify(cue)}`);
      }
      if (isNaN(cue.start)) {
        throw new CompilerError(`Cue malformed: null start value.
    ${JSON.stringify(cue)}`);
      }
      if (isNaN(cue.end)) {
        throw new CompilerError(`Cue malformed: null end value.
    ${JSON.stringify(cue)}`);
      }
      if (cue.start >= cue.end) {
        throw new CompilerError(`Cue malformed: start timestamp greater than end
    ${JSON.stringify(cue)}`);
      }
      if (typeof cue.text !== "string") {
        throw new CompilerError(`Cue malformed: null text value.
    ${JSON.stringify(cue)}`);
      }
      if (typeof cue.styles !== "string") {
        throw new CompilerError(`Cue malformed: null styles value.
    ${JSON.stringify(cue)}`);
      }
      let output = "";
      if (cue.identifier.length > 0) {
        output += `${cue.identifier}
`;
      }
      const startTimestamp = convertTimestamp(cue.start);
      const endTimestamp = convertTimestamp(cue.end);
      output += `${startTimestamp} --> ${endTimestamp}`;
      output += cue.styles ? ` ${cue.styles}` : "";
      output += `
${cue.text}`;
      return output;
    }
    function convertTimestamp(time) {
      const hours = pad(calculateHours(time), 2);
      const minutes = pad(calculateMinutes(time), 2);
      const seconds = pad(calculateSeconds(time), 2);
      const milliseconds = pad(calculateMs(time), 3);
      return `${hours}:${minutes}:${seconds}.${milliseconds}`;
    }
    function pad(num, zeroes) {
      let output = `${num}`;
      while (output.length < zeroes) {
        output = `0${output}`;
      }
      return output;
    }
    function calculateHours(time) {
      return Math.floor(time / 60 / 60);
    }
    function calculateMinutes(time) {
      return Math.floor(time / 60) % 60;
    }
    function calculateSeconds(time) {
      return Math.floor(time % 60);
    }
    function calculateMs(time) {
      return Math.floor((time % 1).toFixed(4) * 1e3);
    }
    module2.exports = { CompilerError, compile };
  }
});

// node_modules/node-webvtt/lib/segmenter.js
var require_segmenter = __commonJS({
  "node_modules/node-webvtt/lib/segmenter.js"(exports, module2) {
    "use strict";
    var parse2 = require_parser().parse;
    function segment(input, segmentLength) {
      segmentLength = segmentLength || 10;
      const parsed = parse2(input);
      const segments = [];
      let cues = [];
      let queuedCue = null;
      let currentSegmentDuration = 0;
      let totalSegmentsDuration = 0;
      parsed.cues.forEach((cue, i) => {
        const firstCue = i === 0;
        const lastCue = i === parsed.cues.length - 1;
        const start = cue.start;
        const end = cue.end;
        const nextStart = lastCue ? Infinity : parsed.cues[i + 1].start;
        const cueLength = firstCue ? end : end - start;
        const silence = firstCue ? 0 : start - parsed.cues[i - 1].end;
        currentSegmentDuration = currentSegmentDuration + cueLength + silence;
        debug("------------");
        debug(`Cue #${i}, segment #${segments.length + 1}`);
        debug(`Start ${start}`);
        debug(`End ${end}`);
        debug(`Length ${cueLength}`);
        debug(`Total segment duration = ${totalSegmentsDuration}`);
        debug(`Current segment duration = ${currentSegmentDuration}`);
        debug(`Start of next = ${nextStart}`);
        if (queuedCue) {
          cues.push(queuedCue);
          currentSegmentDuration += queuedCue.end - totalSegmentsDuration;
          queuedCue = null;
        }
        cues.push(cue);
        let shouldQueue = nextStart - end < segmentLength && silence < segmentLength && currentSegmentDuration > segmentLength;
        if (shouldSegment(totalSegmentsDuration, segmentLength, nextStart, silence)) {
          const duration = segmentDuration(lastCue, end, segmentLength, currentSegmentDuration, totalSegmentsDuration);
          segments.push({ duration, cues });
          totalSegmentsDuration += duration;
          currentSegmentDuration = 0;
          cues = [];
        } else {
          shouldQueue = false;
        }
        if (shouldQueue) {
          queuedCue = cue;
        }
      });
      return segments;
    }
    function shouldSegment(total, length, nextStart, silence) {
      const x = alignToSegmentLength(silence, length);
      const nextCueIsInNextSegment = silence <= length || x + total < nextStart;
      return nextCueIsInNextSegment && nextStart - total >= length;
    }
    function segmentDuration(lastCue, end, length, currentSegment, totalSegments) {
      let duration = length;
      if (currentSegment > length) {
        duration = alignToSegmentLength(currentSegment - length, length);
      }
      if (lastCue) {
        duration = parseFloat((end - totalSegments).toFixed(2));
      } else {
        duration = Math.round(duration);
      }
      return duration;
    }
    function alignToSegmentLength(n, segmentLength) {
      n += segmentLength - n % segmentLength;
      return n;
    }
    var debugging = false;
    function debug(m) {
      if (debugging) {
        console.log(m);
      }
    }
    module2.exports = { segment };
  }
});

// node_modules/node-webvtt/lib/hls.js
var require_hls = __commonJS({
  "node_modules/node-webvtt/lib/hls.js"(exports, module2) {
    "use strict";
    var segment = require_segmenter().segment;
    function hlsSegment(input, segmentLength, startOffset) {
      if (typeof startOffset === "undefined") {
        startOffset = "900000";
      }
      const segments = segment(input, segmentLength);
      const result = [];
      segments.forEach((seg, i) => {
        const content = `WEBVTT
X-TIMESTAMP-MAP=MPEGTS:${startOffset},LOCAL:00:00:00.000

${printableCues(seg.cues)}
`;
        const filename = generateSegmentFilename(i);
        result.push({ filename, content });
      });
      return result;
    }
    function hlsSegmentPlaylist(input, segmentLength) {
      const segmented = segment(input, segmentLength);
      const printable = printableSegments(segmented);
      const longestSegment = Math.round(findLongestSegment(segmented));
      const template = `#EXTM3U
#EXT-X-TARGETDURATION:${longestSegment}
#EXT-X-VERSION:3
#EXT-X-MEDIA-SEQUENCE:0
#EXT-X-PLAYLIST-TYPE:VOD
${printable}
#EXT-X-ENDLIST
`;
      return template;
    }
    function pad(num, n) {
      const padding = "0".repeat(Math.max(0, n - num.toString().length));
      return `${padding}${num}`;
    }
    function generateSegmentFilename(index) {
      return `${index}.vtt`;
    }
    function printableSegments(segments) {
      const result = [];
      segments.forEach((seg, i) => {
        result.push(`#EXTINF:${seg.duration.toFixed(5)},
${generateSegmentFilename(i)}`);
      });
      return result.join("\n");
    }
    function findLongestSegment(segments) {
      let max = 0;
      segments.forEach((seg) => {
        if (seg.duration > max) {
          max = seg.duration;
        }
      });
      return max;
    }
    function printableCues(cues) {
      const result = [];
      cues.forEach((cue) => {
        result.push(printableCue(cue));
      });
      return result.join("\n\n");
    }
    function printableCue(cue) {
      const printable = [];
      if (cue.identifier) {
        printable.push(cue.identifier);
      }
      const start = printableTimestamp(cue.start);
      const end = printableTimestamp(cue.end);
      const styles = cue.styles ? `${cue.styles}` : "";
      printable.push(`${start} --> ${end} ${styles}`);
      printable.push(cue.text);
      return printable.join("\n");
    }
    function printableTimestamp(timestamp) {
      const ms = (timestamp % 1).toFixed(3);
      timestamp = Math.round(timestamp - ms);
      const hours = Math.floor(timestamp / 3600);
      const mins = Math.floor((timestamp - hours * 3600) / 60);
      const secs = timestamp - hours * 3600 - mins * 60;
      const hourString = `${pad(hours, 2)}:`;
      return `${hourString}${pad(mins, 2)}:${pad(secs, 2)}.${pad(ms * 1e3, 3)}`;
    }
    module2.exports = { hlsSegment, hlsSegmentPlaylist };
  }
});

// node_modules/node-webvtt/index.js
var require_node_webvtt = __commonJS({
  "node_modules/node-webvtt/index.js"(exports, module2) {
    "use strict";
    var parse2 = require_parser().parse;
    var compile = require_compiler().compile;
    var segment = require_segmenter().segment;
    var hls = require_hls();
    module2.exports = { parse: parse2, compile, segment, hls };
  }
});

// main.ts
__export(exports, {
  default: () => ChatViewPlugin
});
var import_obsidian = __toModule(require("obsidian"));
var webvtt = __toModule(require_node_webvtt());
var KEYMAP = { ">": "right", "<": "left", "^": "center" };
var CONFIGS = {
  "header": ["h2", "h3", "h4", "h5", "h6"],
  "mw": ["50", "55", "60", "65", "70", "75", "80", "85", "90"],
  "mode": ["default", "minimal"]
};
var COLORS = [
  "red",
  "orange",
  "yellow",
  "green",
  "blue",
  "purple",
  "grey",
  "brown",
  "indigo",
  "teal",
  "pink",
  "slate",
  "wood"
];
var _ChatPatterns = class {
};
var ChatPatterns = _ChatPatterns;
ChatPatterns.message = /(^>|<|\^)/;
ChatPatterns.delimiter = /.../;
ChatPatterns.comment = /^#/;
ChatPatterns.colors = /\[(.*?)\]/;
ChatPatterns.format = /{(.*?)}/;
ChatPatterns.joined = RegExp([_ChatPatterns.message, _ChatPatterns.delimiter, _ChatPatterns.colors, _ChatPatterns.comment, _ChatPatterns.format].map((pattern) => pattern.source).join("|"));
ChatPatterns.voice = /<v\s+([^>]+)>([^<]+)<\/v>/;
var ChatViewPlugin = class extends import_obsidian.Plugin {
  onload() {
    return __async(this, null, function* () {
      this.registerMarkdownCodeBlockProcessor("chat-webvtt", (source, el, _) => {
        const vtt = webvtt.parse(source, { meta: true });
        const messages = [];
        const self = vtt.meta && "Self" in vtt.meta ? vtt.meta.Self : void 0;
        const selves = self ? self.split(",").map((val) => val.trim()) : void 0;
        const formatConfigs = new Map();
        const maxWidth = vtt.meta && "MaxWidth" in vtt.meta ? vtt.meta.MaxWidth : void 0;
        const headerConfig = vtt.meta && "Header" in vtt.meta ? vtt.meta.Header : void 0;
        const modeConfig = vtt.meta && "Mode" in vtt.meta ? vtt.meta.Mode : void 0;
        if (CONFIGS["mw"].contains(maxWidth))
          formatConfigs.set("mw", maxWidth);
        if (CONFIGS["header"].contains(headerConfig))
          formatConfigs.set("header", headerConfig);
        if (CONFIGS["mode"].contains(modeConfig))
          formatConfigs.set("mode", modeConfig);
        console.log(formatConfigs);
        for (let index = 0; index < vtt.cues.length; index++) {
          const cue = vtt.cues[index];
          const start = (0, import_obsidian.moment)(Math.round(cue.start * 1e3)).format("HH:mm:ss.SSS");
          const end = (0, import_obsidian.moment)(Math.round(cue.end * 1e3)).format("HH:mm:ss.SSS");
          if (ChatPatterns.voice.test(cue.text)) {
            const matches = cue.text.match(ChatPatterns.voice);
            messages.push({ header: matches[1], body: matches[2], subtext: `${start} to ${end}` });
          } else {
            messages.push({ header: "", body: cue.text, subtext: `${start} to ${end}` });
          }
        }
        const headers = messages.map((message) => message.header);
        const uniqueHeaders = new Set(headers);
        uniqueHeaders.delete("");
        console.log(messages);
        console.log(uniqueHeaders);
        const colorConfigs = new Map();
        Array.from(uniqueHeaders).forEach((h, i) => colorConfigs.set(h, COLORS[i % COLORS.length]));
        console.log(colorConfigs);
        messages.forEach((message, index, arr) => {
          const prevHeader = index > 0 ? arr[index - 1].header : "";
          const align = selves && selves.contains(message.header) ? "right" : "left";
          const continued = message.header === prevHeader;
          this.createChatBubble(continued ? "" : message.header, prevHeader, message.body, message.subtext, align, el, continued, colorConfigs, formatConfigs);
        });
      });
      this.registerMarkdownCodeBlockProcessor("chat", (source, el, _) => {
        const rawLines = source.split("\n").filter((line) => ChatPatterns.joined.test(line.trim()));
        const lines = rawLines.map((rawLine) => rawLine.trim());
        const formatConfigs = new Map();
        const colorConfigs = new Map();
        for (const line of lines) {
          if (ChatPatterns.format.test(line)) {
            const configs = line.replace("{", "").replace("}", "").split(",").map((l) => l.trim());
            for (const config of configs) {
              const [k, v] = config.split("=").map((c) => c.trim());
              if (Object.keys(CONFIGS).contains(k) && CONFIGS[k].contains(v))
                formatConfigs.set(k, v);
            }
          } else if (ChatPatterns.colors.test(line)) {
            const configs = line.replace("[", "").replace("]", "").split(",").map((l) => l.trim());
            for (const config of configs) {
              const [k, v] = config.split("=").map((c) => c.trim());
              if (k.length > 0 && COLORS.contains(v))
                colorConfigs.set(k, v);
            }
          }
        }
        let continuedCount = 0;
        for (let index = 0; index < lines.length; index++) {
          const line = lines[index].trim();
          if (ChatPatterns.comment.test(line)) {
            el.createEl("p", { text: line.substring(1).trim(), cls: ["chat-view-comment"] });
          } else if (line === "...") {
            const delimiter = el.createDiv({ cls: ["delimiter"] });
            for (let i = 0; i < 3; i++)
              delimiter.createDiv({ cls: ["dot"] });
          } else if (ChatPatterns.message.test(line)) {
            const components = line.substring(1).split("|");
            if (components.length > 0) {
              const first = components[0];
              const header = components.length > 1 ? first.trim() : "";
              const message = components.length > 1 ? components[1].trim() : first.trim();
              const subtext = components.length > 2 ? components[2].trim() : "";
              const continued = index > 0 && line.charAt(0) === lines[index - 1].charAt(0) && header === "";
              let prevHeader = "";
              if (continued) {
                continuedCount++;
                const prevComponents = lines[index - continuedCount].trim().substring(1).split("|");
                prevHeader = prevComponents[0].length > 1 ? prevComponents[0].trim() : "";
              } else {
                continuedCount = 0;
              }
              this.createChatBubble(header, prevHeader, message, subtext, KEYMAP[line.charAt(0)], el, continued, colorConfigs, formatConfigs);
            }
          }
        }
      });
    });
  }
  createChatBubble(header, prevHeader, message, subtext, align, element, continued, colorConfigs, formatConfigs) {
    const marginClass = continued ? "chat-view-small-vertical-margin" : "chat-view-default-vertical-margin";
    const colorConfigClass = `chat-view-${colorConfigs.get(continued ? prevHeader : header)}`;
    const widthClass = formatConfigs.has("mw") ? `chat-view-max-width-${formatConfigs.get("mw")}` : import_obsidian.Platform.isMobile ? "chat-view-mobile-width" : "chat-view-desktop-width";
    const modeClass = `chat-view-bubble-mode-${formatConfigs.has("mode") ? formatConfigs.get("mode") : "default"}`;
    const headerEl = formatConfigs.has("header") ? formatConfigs.get("header") : "h4";
    const bubble = element.createDiv({
      cls: ["chat-view-bubble", `chat-view-align-${align}`, marginClass, colorConfigClass, widthClass, modeClass]
    });
    if (header.length > 0)
      bubble.createEl(headerEl, { text: header, cls: ["chat-view-header"] });
    if (message.length > 0)
      bubble.createEl("p", { text: message, cls: ["chat-view-message"] });
    if (subtext.length > 0)
      bubble.createEl("sub", { text: subtext, cls: ["chat-view-subtext"] });
  }
};
