'use strict';

var fuselage = require('@rocket.chat/fuselage');
var i18next = require('i18next');
var require$$0$1 = require('react');
var require$$0 = require('react-dom');
var reactI18next = require('react-i18next');
var electron = require('electron');
var fuselageHooks = require('@rocket.chat/fuselage-hooks');
var reactVirtuoso = require('react-virtuoso');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

var i18next__default = /*#__PURE__*/_interopDefault(i18next);
var require$$0__default$1 = /*#__PURE__*/_interopDefault(require$$0$1);
var require$$0__default = /*#__PURE__*/_interopDefault(require$$0);

function getDefaultExportFromCjs (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

var createRoot;

var m$1 = require$$0__default.default;
{
  createRoot = m$1.createRoot;
  m$1.hydrateRoot;
}

const fallbackLng = 'en';
const byteUnits = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte'];
const formatBytes = bytes => {
  const order = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), byteUnits.length - 1);
  const unit = byteUnits[order];
  if (!unit) {
    return '???';
  }
  const formatter = new Intl.NumberFormat(undefined, {
    notation: 'compact',
    style: 'unit',
    unit,
    maximumFractionDigits: 1
  });
  return formatter.format(bytes / Math.pow(1024, order));
};
const formatByteSpeed = bytesPerSecond => {
  const order = Math.min(Math.floor(Math.log(bytesPerSecond) / Math.log(1024)), byteUnits.length - 1);
  const unit = byteUnits[order];
  if (!unit) {
    return '???';
  }
  const formatter = new Intl.NumberFormat(undefined, {
    notation: 'compact',
    style: 'unit',
    unit: `${unit}-per-second`,
    maximumFractionDigits: 1
  });
  return formatter.format(bytesPerSecond / Math.pow(1024, order));
};
const formatPercentage = ratio => {
  const formatter = new Intl.NumberFormat(undefined, {
    style: 'percent',
    maximumFractionDigits: 0
  });
  return formatter.format(ratio);
};
const formatDuration = duration => {
  const formatter = new Intl.RelativeTimeFormat(undefined, {
    style: 'narrow',
    numeric: 'always'
  });
  duration /= 1000;
  if (duration / 60 < 1) {
    return formatter.format(duration, 'second');
  }
  duration /= 60;
  if (duration / 60 < 1) {
    return formatter.format(duration, 'minute');
  }
  duration /= 60;
  if (duration / 24 < 1) {
    return formatter.format(duration, 'hour');
  }
  duration /= 24;
  if (duration / 7 < 1) {
    return formatter.format(duration, 'day');
  }
  duration /= 7;
  if (duration / 30 < 1) {
    return formatter.format(duration, 'week');
  }
  duration /= 30;
  if (duration / 12 < 1) {
    return formatter.format(duration, 'month');
  }
  duration /= 12;
  return formatter.format(duration, 'year');
};
const interpolation = {
  escapeValue: false,
  format: (value, format, lng) => {
    if (value instanceof Date && !Number.isNaN(value.getTime())) {
      return new Intl.DateTimeFormat(lng).format(value);
    }
    switch (format) {
      case 'byteSize':
        return formatBytes(value);
      case 'byteSpeed':
        return formatByteSpeed(value);
      case 'percentage':
        return formatPercentage(value);
      case 'duration':
        return formatDuration(value);
    }
    return String(value);
  }
};

var renderer$1 = {exports: {}};

var scope = scopeFactory$1;
function scopeFactory$1(logger) {
  return Object.defineProperties(scope, {
    defaultLabel: {
      value: '',
      writable: true
    },
    labelPadding: {
      value: true,
      writable: true
    },
    maxLabelLength: {
      value: 0,
      writable: true
    },
    labelLength: {
      get() {
        switch (typeof scope.labelPadding) {
          case 'boolean':
            return scope.labelPadding ? scope.maxLabelLength : 0;
          case 'number':
            return scope.labelPadding;
          default:
            return 0;
        }
      }
    }
  });
  function scope(label) {
    scope.maxLabelLength = Math.max(scope.maxLabelLength, label.length);
    const newScope = {};
    for (const level of logger.levels) {
      newScope[level] = (...d) => logger.logData(d, {
        level,
        scope: label
      });
    }
    newScope.log = newScope.info;
    return newScope;
  }
}

let Buffering$1 = class Buffering {
  constructor({
    processMessage
  }) {
    this.processMessage = processMessage;
    this.buffer = [];
    this.enabled = false;
    this.begin = this.begin.bind(this);
    this.commit = this.commit.bind(this);
    this.reject = this.reject.bind(this);
  }
  addMessage(message) {
    this.buffer.push(message);
  }
  begin() {
    this.enabled = [];
  }
  commit() {
    this.enabled = false;
    this.buffer.forEach(item => this.processMessage(item));
    this.buffer = [];
  }
  reject() {
    this.enabled = false;
    this.buffer = [];
  }
};
var Buffering_1 = Buffering$1;

const scopeFactory = scope;
const Buffering = Buffering_1;

/**
 * @property {Function} error
 * @property {Function} warn
 * @property {Function} info
 * @property {Function} verbose
 * @property {Function} debug
 * @property {Function} silly
 */
class Logger {
  static instances = {};
  dependencies = {};
  errorHandler = null;
  eventLogger = null;
  functions = {};
  hooks = [];
  isDev = false;
  levels = null;
  logId = null;
  scope = null;
  transports = {};
  variables = {};
  constructor({
    allowUnknownLevel = false,
    dependencies = {},
    errorHandler,
    eventLogger,
    initializeFn,
    isDev = false,
    levels = ['error', 'warn', 'info', 'verbose', 'debug', 'silly'],
    logId,
    transportFactories = {},
    variables
  } = {}) {
    this.addLevel = this.addLevel.bind(this);
    this.create = this.create.bind(this);
    this.initialize = this.initialize.bind(this);
    this.logData = this.logData.bind(this);
    this.processMessage = this.processMessage.bind(this);
    this.allowUnknownLevel = allowUnknownLevel;
    this.buffering = new Buffering(this);
    this.dependencies = dependencies;
    this.initializeFn = initializeFn;
    this.isDev = isDev;
    this.levels = levels;
    this.logId = logId;
    this.scope = scopeFactory(this);
    this.transportFactories = transportFactories;
    this.variables = variables || {};
    for (const name of this.levels) {
      this.addLevel(name, false);
    }
    this.log = this.info;
    this.functions.log = this.log;
    this.errorHandler = errorHandler;
    errorHandler?.setOptions({
      ...dependencies,
      logFn: this.error
    });
    this.eventLogger = eventLogger;
    eventLogger?.setOptions({
      ...dependencies,
      logger: this
    });
    for (const [name, factory] of Object.entries(transportFactories)) {
      this.transports[name] = factory(this, dependencies);
    }
    Logger.instances[logId] = this;
  }
  static getInstance({
    logId
  }) {
    return this.instances[logId] || this.instances.default;
  }
  addLevel(level, index = this.levels.length) {
    if (index !== false) {
      this.levels.splice(index, 0, level);
    }
    this[level] = (...args) => this.logData(args, {
      level
    });
    this.functions[level] = this[level];
  }
  catchErrors(options) {
    this.processMessage({
      data: ['log.catchErrors is deprecated. Use log.errorHandler instead'],
      level: 'warn'
    }, {
      transports: ['console']
    });
    return this.errorHandler.startCatching(options);
  }
  create(options) {
    if (typeof options === 'string') {
      options = {
        logId: options
      };
    }
    return new Logger({
      dependencies: this.dependencies,
      errorHandler: this.errorHandler,
      initializeFn: this.initializeFn,
      isDev: this.isDev,
      transportFactories: this.transportFactories,
      variables: {
        ...this.variables
      },
      ...options
    });
  }
  compareLevels(passLevel, checkLevel, levels = this.levels) {
    const pass = levels.indexOf(passLevel);
    const check = levels.indexOf(checkLevel);
    if (check === -1 || pass === -1) {
      return true;
    }
    return check <= pass;
  }
  initialize(options = {}) {
    this.initializeFn({
      logger: this,
      ...this.dependencies,
      ...options
    });
  }
  logData(data, options = {}) {
    if (this.buffering.enabled) {
      this.buffering.addMessage({
        data,
        date: new Date(),
        ...options
      });
    } else {
      this.processMessage({
        data,
        ...options
      });
    }
  }
  processMessage(message, {
    transports = this.transports
  } = {}) {
    if (message.cmd === 'errorHandler') {
      this.errorHandler.handle(message.error, {
        errorName: message.errorName,
        processType: 'renderer',
        showDialog: Boolean(message.showDialog)
      });
      return;
    }
    let level = message.level;
    if (!this.allowUnknownLevel) {
      level = this.levels.includes(message.level) ? message.level : 'info';
    }
    const normalizedMessage = {
      date: new Date(),
      logId: this.logId,
      ...message,
      level,
      variables: {
        ...this.variables,
        ...message.variables
      }
    };
    for (const [transName, transFn] of this.transportEntries(transports)) {
      if (typeof transFn !== 'function' || transFn.level === false) {
        continue;
      }
      if (!this.compareLevels(transFn.level, message.level)) {
        continue;
      }
      try {
        // eslint-disable-next-line arrow-body-style
        const transformedMsg = this.hooks.reduce((msg, hook) => {
          return msg ? hook(msg, transFn, transName) : msg;
        }, normalizedMessage);
        if (transformedMsg) {
          transFn({
            ...transformedMsg,
            data: [...transformedMsg.data]
          });
        }
      } catch (e) {
        this.processInternalErrorFn(e);
      }
    }
  }
  processInternalErrorFn(_e) {
    // Do nothing by default
  }
  transportEntries(transports = this.transports) {
    const transportArray = Array.isArray(transports) ? transports : Object.entries(transports);
    return transportArray.map(item => {
      switch (typeof item) {
        case 'string':
          return this.transports[item] ? [item, this.transports[item]] : null;
        case 'function':
          return [item.name, item];
        default:
          return Array.isArray(item) ? item : null;
      }
    }).filter(Boolean);
  }
}
var Logger_1 = Logger;

// eslint-disable-next-line no-console
const consoleError = console.error;
class RendererErrorHandler {
  logFn = null;
  onError = null;
  showDialog = false;
  preventDefault = true;
  constructor({
    logFn = null
  } = {}) {
    this.handleError = this.handleError.bind(this);
    this.handleRejection = this.handleRejection.bind(this);
    this.startCatching = this.startCatching.bind(this);
    this.logFn = logFn;
  }
  handle(error, {
    logFn = this.logFn,
    errorName = '',
    onError = this.onError,
    showDialog = this.showDialog
  } = {}) {
    try {
      if (onError?.({
        error,
        errorName,
        processType: 'renderer'
      }) !== false) {
        logFn({
          error,
          errorName,
          showDialog
        });
      }
    } catch {
      consoleError(error);
    }
  }
  setOptions({
    logFn,
    onError,
    preventDefault,
    showDialog
  }) {
    if (typeof logFn === 'function') {
      this.logFn = logFn;
    }
    if (typeof onError === 'function') {
      this.onError = onError;
    }
    if (typeof preventDefault === 'boolean') {
      this.preventDefault = preventDefault;
    }
    if (typeof showDialog === 'boolean') {
      this.showDialog = showDialog;
    }
  }
  startCatching({
    onError,
    showDialog
  } = {}) {
    if (this.isActive) {
      return;
    }
    this.isActive = true;
    this.setOptions({
      onError,
      showDialog
    });
    window.addEventListener('error', event => {
      this.preventDefault && event.preventDefault?.();
      this.handleError(event.error || event);
    });
    window.addEventListener('unhandledrejection', event => {
      this.preventDefault && event.preventDefault?.();
      this.handleRejection(event.reason || event);
    });
  }
  handleError(error) {
    this.handle(error, {
      errorName: 'Unhandled'
    });
  }
  handleRejection(reason) {
    const error = reason instanceof Error ? reason : new Error(JSON.stringify(reason));
    this.handle(error, {
      errorName: 'Unhandled rejection'
    });
  }
}
var RendererErrorHandler_1 = RendererErrorHandler;

var transform_1 = {
  transform: transform$2
};
function transform$2({
  logger,
  message,
  transport,
  initialData = message?.data || [],
  transforms = transport?.transforms
}) {
  return transforms.reduce((data, trans) => {
    if (typeof trans === 'function') {
      return trans({
        data,
        logger,
        message,
        transport
      });
    }
    return data;
  }, initialData);
}

/* eslint-disable no-console */
const {
  transform: transform$1
} = transform_1;
var console_1 = consoleTransportRendererFactory;
const consoleMethods = {
  error: console.error,
  warn: console.warn,
  info: console.info,
  verbose: console.info,
  debug: console.debug,
  silly: console.debug,
  log: console.log
};
function consoleTransportRendererFactory(logger) {
  return Object.assign(transport, {
    format: '{h}:{i}:{s}.{ms}{scope} › {text}',
    transforms: [formatDataFn],
    writeFn({
      message: {
        level,
        data
      }
    }) {
      const consoleLogFn = consoleMethods[level] || consoleMethods.info;

      // make an empty call stack
      setTimeout(() => consoleLogFn(...data));
    }
  });
  function transport(message) {
    transport.writeFn({
      message: {
        ...message,
        data: transform$1({
          logger,
          message,
          transport
        })
      }
    });
  }
}
function formatDataFn({
  data = [],
  logger = {},
  message = {},
  transport = {}
}) {
  if (typeof transport.format === 'function') {
    return transport.format({
      data,
      level: message?.level || 'info',
      logger,
      message,
      transport
    });
  }
  if (typeof transport.format !== 'string') {
    return data;
  }
  data.unshift(transport.format);

  // Concatenate the first two data items to support printf-like templates
  if (typeof data[1] === 'string' && data[1].match(/%[1cdfiOos]/)) {
    data = [`${data[0]}${data[1]}`, ...data.slice(2)];
  }
  const date = message.date || new Date();
  data[0] = data[0].replace(/\{(\w+)}/g, (substring, name) => {
    switch (name) {
      case 'level':
        return message.level;
      case 'logId':
        return message.logId;
      case 'scope':
        {
          const scope = message.scope || logger.scope?.defaultLabel;
          return scope ? ` (${scope})` : '';
        }
      case 'text':
        return '';
      case 'y':
        return date.getFullYear().toString(10);
      case 'm':
        return (date.getMonth() + 1).toString(10).padStart(2, '0');
      case 'd':
        return date.getDate().toString(10).padStart(2, '0');
      case 'h':
        return date.getHours().toString(10).padStart(2, '0');
      case 'i':
        return date.getMinutes().toString(10).padStart(2, '0');
      case 's':
        return date.getSeconds().toString(10).padStart(2, '0');
      case 'ms':
        return date.getMilliseconds().toString(10).padStart(3, '0');
      case 'iso':
        return date.toISOString();
      default:
        return message.variables?.[name] || substring;
    }
  }).trim();
  return data;
}

const {
  transform
} = transform_1;
var ipc = ipcTransportRendererFactory;
const RESTRICTED_TYPES = new Set([Promise, WeakMap, WeakSet]);
function ipcTransportRendererFactory(logger) {
  return Object.assign(transport, {
    depth: 5,
    transforms: [serializeFn]
  });
  function transport(message) {
    if (!window.__electronLog) {
      logger.processMessage({
        data: ['electron-log: logger isn\'t initialized in the main process'],
        level: 'error'
      }, {
        transports: ['console']
      });
      return;
    }
    try {
      const serialized = transform({
        initialData: message,
        logger,
        message,
        transport
      });
      __electronLog.sendToMain(serialized);
    } catch (e) {
      logger.transports.console({
        data: ['electronLog.transports.ipc', e, 'data:', message.data],
        level: 'error'
      });
    }
  }
}

/**
 * Is type primitive, including null and undefined
 * @param {any} value
 * @returns {boolean}
 */
function isPrimitive(value) {
  return Object(value) !== value;
}
function serializeFn({
  data,
  depth,
  seen = new WeakSet(),
  transport = {}
} = {}) {
  const actualDepth = depth || transport.depth || 5;
  if (seen.has(data)) {
    return '[Circular]';
  }
  if (actualDepth < 1) {
    if (isPrimitive(data)) {
      return data;
    }
    if (Array.isArray(data)) {
      return '[Array]';
    }
    return `[${typeof data}]`;
  }
  if (['function', 'symbol'].includes(typeof data)) {
    return data.toString();
  }
  if (isPrimitive(data)) {
    return data;
  }

  // Object types

  if (RESTRICTED_TYPES.has(data.constructor)) {
    return `[${data.constructor.name}]`;
  }
  if (Array.isArray(data)) {
    return data.map(item => serializeFn({
      data: item,
      depth: actualDepth - 1,
      seen
    }));
  }
  if (data instanceof Date) {
    return data.toISOString();
  }
  if (data instanceof Error) {
    return data.stack;
  }
  if (data instanceof Map) {
    return new Map(Array.from(data).map(([key, value]) => [serializeFn({
      data: key,
      depth: actualDepth - 1,
      seen
    }), serializeFn({
      data: value,
      depth: actualDepth - 1,
      seen
    })]));
  }
  if (data instanceof Set) {
    return new Set(Array.from(data).map(val => serializeFn({
      data: val,
      depth: actualDepth - 1,
      seen
    })));
  }
  seen.add(data);
  return Object.fromEntries(Object.entries(data).map(([key, value]) => [key, serializeFn({
    data: value,
    depth: actualDepth - 1,
    seen
  })]));
}

(function (module) {

	const Logger = Logger_1;
	const RendererErrorHandler = RendererErrorHandler_1;
	const transportConsole = console_1;
	const transportIpc = ipc;
	if (typeof process === 'object' && process.type === 'browser') {
	  // eslint-disable-next-line no-console
	  console.warn('electron-log/renderer is loaded in the main process. ' + 'It could cause unexpected behaviour.');
	}
	module.exports = createLogger();
	module.exports.Logger = Logger;
	module.exports.default = module.exports;
	function createLogger() {
	  const logger = new Logger({
	    allowUnknownLevel: true,
	    errorHandler: new RendererErrorHandler(),
	    initializeFn: () => {},
	    logId: 'default',
	    transportFactories: {
	      console: transportConsole,
	      ipc: transportIpc
	    },
	    variables: {
	      processType: 'renderer'
	    }
	  });
	  logger.errorHandler.setOptions({
	    logFn({
	      error,
	      errorName,
	      showDialog
	    }) {
	      logger.transports.console({
	        data: [errorName, error].filter(Boolean),
	        level: 'error'
	      });
	      logger.transports.ipc({
	        cmd: 'errorHandler',
	        error: {
	          cause: error?.cause,
	          code: error?.code,
	          name: error?.name,
	          message: error?.message,
	          stack: error?.stack
	        },
	        errorName,
	        logId: logger.logId,
	        showDialog
	      });
	    }
	  });
	  if (typeof window === 'object') {
	    window.addEventListener('message', event => {
	      const {
	        cmd,
	        logId,
	        ...message
	      } = event.data || {};
	      const instance = Logger.getInstance({
	        logId
	      });
	      if (cmd === 'message') {
	        instance.processMessage(message, {
	          transports: ['console']
	        });
	      }
	    });
	  }

	  // To support custom levels
	  return new Proxy(logger, {
	    get(target, prop) {
	      if (typeof target[prop] !== 'undefined') {
	        return target[prop];
	      }
	      return (...data) => logger.logData(data, {
	        level: prop
	      });
	    }
	  });
	} 
} (renderer$1));

var rendererExports = renderer$1.exports;

const renderer = rendererExports;
var renderer_1 = renderer;

var log = /*@__PURE__*/getDefaultExportFromCjs(renderer_1);

// Maps webContentsId → server hostname (for context lookup)

// Define the log context interface

/**
 * Get process context information
 */
const getProcessContext = () => {
  if (typeof process === 'undefined') return 'unknown';
  if (process.type === 'browser') {
    return 'main';
  }
  if (process.type === 'renderer') {
    // Try to detect renderer type based on environment
    if (typeof window !== 'undefined') {
      var _window$location, _window$location2, _window$location3;
      // Check if this is the root window
      if (((_window$location = window.location) === null || _window$location === undefined ? undefined : _window$location.pathname) === '/index.html' || ((_window$location2 = window.location) === null || _window$location2 === undefined ? undefined : _window$location2.pathname) === '/') {
        return 'renderer:root';
      }

      // Check if this is the video call window
      if (((_window$location3 = window.location) === null || _window$location3 === undefined ? undefined : _window$location3.pathname) === '/video-call-window.html') {
        return 'renderer:videocall';
      }

      // Default to webview for other renderer processes
      return 'renderer:webview';
    }
    return 'renderer:unknown';
  }
  return 'preload';
};

/**
 * Get component context based on the calling code location
 */
// eslint-disable-next-line complexity
const getComponentContext = (captureStack = false) => {
  if (!captureStack) {
    return 'general';
  }
  const error = new Error();
  const stack = error.stack || '';

  // Analyze stack trace to determine component context (privacy-safe)
  if (stack.includes('auth') || stack.includes('login') || stack.includes('Login')) {
    return 'auth';
  }
  if (stack.includes('connection') || stack.includes('websocket') || stack.includes('network')) {
    return 'connection';
  }
  if (stack.includes('notification') || stack.includes('Notification')) {
    return 'notifications';
  }
  if (stack.includes('update') || stack.includes('Update')) {
    return 'updates';
  }
  if (stack.includes('outlook') || stack.includes('Outlook') || stack.includes('outlookCalendar') || stack.includes('getOutlookEvents') || stack.includes('syncEventsWithRocketChatServer')) {
    return 'outlook';
  }
  if (stack.includes('server') || stack.includes('Server') || stack.includes('servers')) {
    return 'servers';
  }
  if (stack.includes('video') || stack.includes('Video') || stack.includes('jitsi')) {
    return 'videocall';
  }
  if (stack.includes('preload')) {
    return 'preload';
  }
  if (stack.includes('ipc') || stack.includes('IPC')) {
    return 'ipc';
  }
  if (stack.includes('storage') || stack.includes('Storage') || stack.includes('store')) {
    return 'storage';
  }
  if (stack.includes('ui') || stack.includes('UI') || stack.includes('component')) {
    return 'ui';
  }
  if (stack.includes('app') || stack.includes('App') || stack.includes('main')) {
    return 'app';
  }
  return 'general';
};

// Function to override console methods in renderer processes with enhanced context
try {
  // Get process context once
  const processContext = getProcessContext();

  // For webviews, try to get server index from main process
  let serverTag = '';
  if (processContext === 'renderer:webview' && typeof window !== 'undefined') {
    try {
      var _window$location;
      const result = electron.ipcRenderer.sendSync('log-viewer-window/get-server-tag', ((_window$location = window.location) === null || _window$location === void 0 ? void 0 : _window$location.origin) || '');
      if (result) {
        serverTag = ` [${result}]`;
      }
    } catch {
      // Silently fail if IPC not available
    }
  }
  if (typeof console !== 'undefined') {
    // Store original console methods
    const originalConsole = {
      log: console.log,
      info: console.info,
      warn: console.warn,
      error: console.error,
      debug: console.debug
    };

    // Override console.log to use electron-log debug level with context
    console.log = (...args) => {
      try {
        const component = getComponentContext();
        const contextStr = `[${processContext}]${serverTag}${component !== 'general' ? ` [${component}]` : ''}`;
        log.debug(contextStr, ...args);
      } catch {
        originalConsole.log(...args);
      }
    };

    // Override console.info to use electron-log info level with context
    console.info = (...args) => {
      try {
        const component = getComponentContext();
        const contextStr = `[${processContext}]${serverTag}${component !== 'general' ? ` [${component}]` : ''}`;
        log.info(contextStr, ...args);
      } catch {
        originalConsole.info(...args);
      }
    };

    // Override console.warn to use electron-log warn level with context
    console.warn = (...args) => {
      try {
        const component = getComponentContext(true);
        const contextStr = `[${processContext}]${serverTag}${component !== 'general' ? ` [${component}]` : ''}`;
        log.warn(contextStr, ...args);
      } catch {
        originalConsole.warn(...args);
      }
    };

    // Override console.error to use electron-log error level with context
    console.error = (...args) => {
      try {
        const component = getComponentContext(true);
        const contextStr = `[${processContext}]${serverTag}${component !== 'general' ? ` [${component}]` : ''}`;
        log.error(contextStr, ...args);
      } catch {
        originalConsole.error(...args);
      }
    };

    // Override console.debug to use electron-log debug level with context
    console.debug = (...args) => {
      try {
        const component = getComponentContext();
        const contextStr = `[${processContext}]${serverTag}${component !== 'general' ? ` [${component}]` : ''}`;
        log.debug(contextStr, ...args);
      } catch {
        originalConsole.debug(...args);
      }
    };

    // Add marker to know console override is active
    console.original = originalConsole;
  }
} catch (error) {
  // Silently fail if electron-log isn't available in this context
}

var resources = {
  'de-DE': () => Promise.resolve().then(function () { return require('./de-DE.i18n-LjCz_6v_.js'); }),
  'en': () => Promise.resolve().then(function () { return require('./en.i18n-tSOW0b2p.js'); }),
  'es': () => Promise.resolve().then(function () { return require('./es.i18n-BPEvA6Eu.js'); }),
  'fi': () => Promise.resolve().then(function () { return require('./fi.i18n-c5J-X7bw.js'); }),
  'sv': () => Promise.resolve().then(function () { return require('./sv.i18n-DPPaCtsT.js'); }),
  'no': () => Promise.resolve().then(function () { return require('./no.i18n-DjEA_1t4.js'); }),
  'fr': () => Promise.resolve().then(function () { return require('./fr.i18n-CedrZv2y.js'); }),
  'hu': () => Promise.resolve().then(function () { return require('./hu.i18n-DjHjsJUq.js'); }),
  'it-IT': () => Promise.resolve().then(function () { return require('./it-IT.i18n-DF18Si-C.js'); }),
  'ja': () => Promise.resolve().then(function () { return require('./ja.i18n-DdfYsFJ2.js'); }),
  'pl': () => Promise.resolve().then(function () { return require('./pl.i18n-DgfYDbAT.js'); }),
  'pt-BR': () => Promise.resolve().then(function () { return require('./pt-BR.i18n-C8oYUcCz.js'); }),
  'ru': () => Promise.resolve().then(function () { return require('./ru.i18n-CE4cC6oZ.js'); }),
  'tr-TR': () => Promise.resolve().then(function () { return require('./tr-TR.i18n-CyxkAN-C.js'); }),
  'uk-UA': () => Promise.resolve().then(function () { return require('./uk-UA.i18n-BkqkMhw4.js'); }),
  'zh-CN': () => Promise.resolve().then(function () { return require('./zh-CN.i18n-C-Voh6oB.js'); }),
  'zh-TW': () => Promise.resolve().then(function () { return require('./zh-TW.i18n-BJUiDIeM.js'); })
};

var jsxRuntime = {exports: {}};

var reactJsxRuntime_production_min = {};

/**
 * @license React
 * react-jsx-runtime.production.min.js
 *
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

var f = require$$0__default$1.default,
  k = Symbol.for("react.element"),
  l = Symbol.for("react.fragment"),
  m = Object.prototype.hasOwnProperty,
  n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,
  p = {
    key: true,
    ref: true,
    __self: true,
    __source: true
  };
function q(c, a, g) {
  var b,
    d = {},
    e = null,
    h = null;
  undefined !== g && (e = "" + g);
  undefined !== a.key && (e = "" + a.key);
  undefined !== a.ref && (h = a.ref);
  for (b in a) m.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
  if (c && c.defaultProps) for (b in a = c.defaultProps, a) undefined === d[b] && (d[b] = a[b]);
  return {
    $$typeof: k,
    type: c,
    key: e,
    ref: h,
    props: d,
    _owner: n.current
  };
}
reactJsxRuntime_production_min.Fragment = l;
reactJsxRuntime_production_min.jsx = q;
reactJsxRuntime_production_min.jsxs = q;

{
  jsxRuntime.exports = reactJsxRuntime_production_min;
}

var jsxRuntimeExports = jsxRuntime.exports;

/**
 * Find the server hostname tag in a context string by matching against
 * known hostnames from the server mapping.
 */
const findServerTag = (context, serverMapping) => {
  const contextTags = context.split(/\s+/);
  const hostnames = Object.keys(serverMapping);
  return contextTags.find(tag => hostnames.includes(tag)) || '';
};
const getLevelColor = level => {
  switch (level) {
    case 'error':
      return 'danger';
    case 'warn':
      return 'warning';
    case 'info':
      return 'primary';
    case 'debug':
      return 'secondary';
    case 'verbose':
      return 'ghost';
    default:
      return 'ghost';
  }
};
const getLevelTextColor = level => {
  switch (level) {
    case 'error':
      return 'danger';
    case 'warn':
      return 'default';
    case 'info':
      return 'info';
    case 'debug':
      return 'default';
    case 'verbose':
      return 'default';
    default:
      return 'default';
  }
};
const getLevelBorderColor = level => {
  switch (level) {
    case 'error':
      return 'var(--rcx-color-stroke-highlight)';
    case 'warn':
      return 'var(--rcx-color-stroke-highlight)';
    case 'info':
      return 'var(--rcx-color-stroke-highlight)';
    case 'debug':
      return 'var(--rcx-color-stroke-light)';
    case 'verbose':
      return 'var(--rcx-color-stroke-light)';
    default:
      return 'var(--rcx-color-stroke-light)';
  }
};
const LogEntry = ({
  entry,
  showContext,
  showServer,
  serverMapping
}) => {
  const {
    serverTag,
    serverDisplayName,
    contextWithoutServer
  } = require$$0$1.useMemo(() => {
    const tag = findServerTag(entry.context, serverMapping);
    const displayName = tag ? serverMapping[tag] || tag : '';
    const ctxWithout = tag ? entry.context.split(/\s+/).filter(token => token !== tag).join(' ').trim() : entry.context;
    return {
      serverTag: tag,
      serverDisplayName: displayName,
      contextWithoutServer: ctxWithout
    };
  }, [entry.context, serverMapping]);
  return /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
    display: "flex",
    flexDirection: "row",
    alignItems: "flex-start",
    padding: "x12",
    borderBlockEnd: "1px solid var(--rcx-color-stroke-light)",
    backgroundColor: "surface-light",
    borderInlineStart: `4px solid ${getLevelBorderColor(entry.level)}`,
    fontFamily: "mono",
    fontSize: "x12",
    lineHeight: "x16",
    children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
      minWidth: "x140",
      marginInlineEnd: "x12",
      color: "hint",
      fontWeight: "normal",
      fontSize: "x11",
      style: {
        whiteSpace: 'nowrap'
      },
      children: entry.timestamp
    }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
      marginInlineEnd: "x12",
      children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Badge, {
        variant: getLevelColor(entry.level),
        children: entry.level.toUpperCase()
      })
    }), showServer && serverTag && /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
      marginInlineEnd: "x12",
      children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Chip, {
        children: serverDisplayName
      })
    }), showContext && contextWithoutServer && /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
      marginInlineEnd: "x12",
      children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Chip, {
        children: contextWithoutServer
      })
    }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
      flexGrow: 1,
      wordBreak: "break-word",
      style: {
        whiteSpace: 'pre-wrap'
      },
      color: getLevelTextColor(entry.level),
      fontWeight: "normal",
      children: entry.message
    })]
  });
};

/**
 * Constants for Log Viewer window
 */

/** Auto-refresh interval in milliseconds */
const AUTO_REFRESH_INTERVAL_MS = 2000;

/** Delay before scrolling to ensure Virtuoso is ready */
const SCROLL_DELAY_MS = 100;

/** Debounce delay for search filter in milliseconds */
const SEARCH_DEBOUNCE_MS = 300;

/** Virtuoso overscan count for smooth scrolling */
const VIRTUOSO_OVERSCAN = 50;

const isLogLevel = value => {
  if (typeof value !== 'string') return false;
  return ['debug', 'info', 'warn', 'error', 'verbose', 'silly'].includes(value.toLowerCase());
};
const parseLogLevel = value => {
  if (typeof value !== 'string') return 'info';
  const trimmed = value.trim().toLowerCase();
  return isLogLevel(trimmed) ? trimmed : 'info';
};

const LOG_LINE_REGEX = /^\[([^\]]+)\]\s+\[([^\]]+)\]\s*(.*)$/;
const CONTEXT_REGEX = /^(\[[^\]]+\](?:\s*\[[^\]]+\])*)\s*(.*)$/;
const formatFileSize = bytes => {
  if (bytes === 0) return '0 B';
  if (bytes < 1024) return `${bytes} B`;
  const kb = bytes / 1024;
  if (kb < 1024) return `${kb.toFixed(1)} KB`;
  const mb = kb / 1024;
  return `${mb.toFixed(1)} MB`;
};
function LogViewerWindow() {
  const {
    t
  } = reactI18next.useTranslation();
  const [searchFilter, setSearchFilter] = require$$0$1.useState('');
  const debouncedSearchFilter = fuselageHooks.useDebouncedValue(searchFilter, SEARCH_DEBOUNCE_MS);
  const [logEntries, setLogEntries] = require$$0$1.useState([]);
  const [isLoading, setIsLoading] = require$$0$1.useState(false);
  const [isStreaming, setIsStreaming] = require$$0$1.useState(false);
  const virtuosoRef = require$$0$1.useRef(null);
  const lastModifiedTimeRef = require$$0$1.useRef(undefined);
  const lastKnownSizeRef = require$$0$1.useRef(0);
  const isAutoScrollingRef = require$$0$1.useRef(false);
  const [autoScroll, setAutoScroll] = require$$0$1.useState(true);
  const [userHasScrolled, setUserHasScrolled] = require$$0$1.useState(false);
  const [showContext, setShowContext] = require$$0$1.useState(true);
  const [showServer, setShowServer] = require$$0$1.useState(true);
  const [serverMapping, setServerMapping] = require$$0$1.useState({});
  const [fileInfo, setFileInfo] = require$$0$1.useState(null);
  const [currentLogFile, setCurrentLogFile] = require$$0$1.useState({
    fileName: 'main.log',
    isDefaultLog: true
  });
  const entryLimitOptions = require$$0$1.useMemo(() => [['100', t('logViewer.filters.entryLimit.last100')], ['500', t('logViewer.filters.entryLimit.last500')], ['1000', t('logViewer.filters.entryLimit.last1000')], ['5000', t('logViewer.filters.entryLimit.last5000')], ['all', t('logViewer.filters.entryLimit.all')]], [t]);
  const [entryLimit, setEntryLimit] = require$$0$1.useState('100');
  const handleSearchFilterChange = require$$0$1.useCallback(event => {
    setSearchFilter(event.target.value);
  }, [setSearchFilter]);
  const levelFilterOptions = require$$0$1.useMemo(() => [['all', t('logViewer.filters.level.all')], ['debug', t('logViewer.filters.level.debug')], ['info', t('logViewer.filters.level.info')], ['warn', t('logViewer.filters.level.warn')], ['error', t('logViewer.filters.level.error')], ['verbose', t('logViewer.filters.level.verbose')]], [t]);
  const [levelFilter, setLevelFilter] = fuselageHooks.useLocalStorage('log-level', 'all');
  const handleLevelFilterChange = require$$0$1.useCallback(value => {
    setLevelFilter(String(value));
  }, [setLevelFilter]);
  const contextFilterOptions = require$$0$1.useMemo(() => [['all', t('logViewer.filters.context.all')], ['main', t('logViewer.filters.context.main')], ['renderer', t('logViewer.filters.context.renderer')], ['webview', t('logViewer.filters.context.webview')], ['videocall', t('logViewer.filters.context.videocall')], ['outlook', t('logViewer.filters.context.outlook')], ['auth', t('logViewer.filters.context.auth')], ['updates', t('logViewer.filters.context.updates')], ['notifications', t('logViewer.filters.context.notifications')], ['servers', t('logViewer.filters.context.servers')], ['ipc', t('logViewer.filters.context.ipc')]], [t]);
  const [contextFilter, setContextFilter] = fuselageHooks.useLocalStorage('log-context', 'all');
  const handleContextFilterChange = require$$0$1.useCallback(value => {
    setContextFilter(String(value));
  }, [setContextFilter]);
  const serverFilterOptions = require$$0$1.useMemo(() => {
    const options = [['all', t('logViewer.filters.server.all')]];
    Object.entries(serverMapping).forEach(([hostname, name]) => {
      options.push([hostname, name || hostname]);
    });
    return options;
  }, [serverMapping, t]);
  const [serverFilter, setServerFilter] = fuselageHooks.useLocalStorage('log-server', 'all');

  // Reset persisted server filter if the stored value no longer exists
  require$$0$1.useEffect(() => {
    const validKeys = serverFilterOptions.map(([key]) => key);
    if (!validKeys.includes(serverFilter)) {
      setServerFilter('all');
    }
  }, [serverFilter, serverFilterOptions, setServerFilter]);
  const handleServerFilterChange = require$$0$1.useCallback(value => {
    setServerFilter(String(value));
  }, [setServerFilter]);
  const handleEntryLimitChange = require$$0$1.useCallback(value => {
    setEntryLimit(String(value));
  }, [setEntryLimit]);
  const handleClearAll = require$$0$1.useCallback(() => {
    setSearchFilter('');
    setLevelFilter('all');
    setContextFilter('all');
    setServerFilter('all');
    setEntryLimit('100');
  }, [setSearchFilter, setLevelFilter, setContextFilter, setServerFilter, setEntryLimit]);
  const parseLogLines = require$$0$1.useCallback(logText => {
    if (!logText || logText.trim() === '') {
      return [];
    }
    const lines = logText.split(/\r?\n/).filter(line => line.trim());
    const entries = [];
    let currentEntry = null;
    lines.forEach((line, _index) => {
      const match = line.match(LOG_LINE_REGEX);
      if (match) {
        const [, timestamp, level, rest] = match;
        const contextMatch = rest.match(CONTEXT_REGEX);
        const context = (contextMatch === null || contextMatch === undefined ? undefined : contextMatch[1]) || '';
        const message = (contextMatch === null || contextMatch === undefined ? undefined : contextMatch[2]) || rest;
        if (currentEntry) {
          entries.push(currentEntry);
        }
        currentEntry = {
          id: `log-${entries.length}`,
          timestamp,
          level: parseLogLevel(level),
          context: context.replace(/[\[\]]/g, ' ').trim(),
          message: message.trim(),
          raw: line
        };
      } else if (currentEntry && line.trim()) {
        currentEntry.message += `\n${line}`;
        currentEntry.raw += `\n${line}`;
      }
    });
    if (currentEntry) {
      entries.push(currentEntry);
    }
    return entries.reverse();
  }, []);
  const loadLogs = require$$0$1.useCallback(async () => {
    setIsLoading(true);
    try {
      const response = await electron.ipcRenderer.invoke('log-viewer-window/read-logs', {
        limit: 'all',
        filePath: currentLogFile.isDefaultLog ? undefined : currentLogFile.filePath
      });
      if (response !== null && response !== void 0 && response.success && response.logs !== undefined) {
        var _response$isDefaultLo;
        const parsedLogs = parseLogLines(response.logs);
        setLogEntries(parsedLogs);
        setCurrentLogFile({
          filePath: response.filePath,
          fileName: response.fileName || 'main.log',
          isDefaultLog: (_response$isDefaultLo = response.isDefaultLog) !== null && _response$isDefaultLo !== void 0 ? _response$isDefaultLo : true
        });
        const logText = response.logs;
        const sizeInBytes = new Blob([logText]).size;
        const sizeFormatted = formatFileSize(sizeInBytes);
        const timestamps = parsedLogs.map(entry => new Date(entry.timestamp)).filter(date => !isNaN(date.getTime()));
        const oldestDate = timestamps.length > 0 ? new Date(Math.min(...timestamps.map(d => d.getTime()))) : null;
        const newestDate = timestamps.length > 0 ? new Date(Math.max(...timestamps.map(d => d.getTime()))) : null;
        let dateRange = t('logViewer.fileInfo.noEntries');
        if (oldestDate && newestDate) {
          if (oldestDate.toDateString() === newestDate.toDateString()) {
            dateRange = `${oldestDate.toLocaleTimeString()} - ${newestDate.toLocaleTimeString()}`;
          } else {
            dateRange = `${oldestDate.toLocaleString()} - ${newestDate.toLocaleString()}`;
          }
        }
        if (response.fileSize !== undefined) {
          lastKnownSizeRef.current = response.fileSize;
        }
        setFileInfo({
          size: sizeFormatted,
          totalEntries: parsedLogs.length,
          totalEntriesInFile: response.totalEntries,
          lastModified: new Date().toLocaleString(),
          dateRange,
          lastModifiedTime: response.lastModifiedTime
        });
      } else {
        console.error('Failed to load logs:', response === null || response === void 0 ? void 0 : response.error);
        setFileInfo(null);
      }
    } catch (error) {
      console.error('Failed to load logs:', error);
      setFileInfo(null);
    } finally {
      setIsLoading(false);
    }
  }, [parseLogLines, currentLogFile.filePath, currentLogFile.isDefaultLog, t]);
  const filteredLogs = require$$0$1.useMemo(() => {
    const filtered = logEntries.filter(entry => {
      const matchesSearch = !debouncedSearchFilter || entry.message.toLowerCase().includes(debouncedSearchFilter.toLowerCase()) || entry.context.toLowerCase().includes(debouncedSearchFilter.toLowerCase());
      const matchesLevel = levelFilter === 'all' || entry.level === levelFilter;
      const contextTags = entry.context.toLowerCase().split(/\s+/);
      const matchesContext = contextFilter === 'all' || contextTags.some(tag => tag.startsWith(contextFilter.toLowerCase()));
      const matchesServer = serverFilter === 'all' || contextTags.some(tag => tag === serverFilter.toLowerCase()) || entry.raw.toLowerCase().includes(serverFilter.toLowerCase());
      return matchesSearch && matchesLevel && matchesContext && matchesServer;
    });

    // Apply entry limit as a display cap on filtered results
    if (entryLimit !== 'all') {
      const limit = parseInt(entryLimit);
      if (filtered.length > limit) {
        return filtered.slice(0, limit);
      }
    }
    return filtered;
  }, [logEntries, debouncedSearchFilter, levelFilter, contextFilter, serverFilter, entryLimit]);
  require$$0$1.useEffect(() => {
    lastModifiedTimeRef.current = fileInfo === null || fileInfo === undefined ? undefined : fileInfo.lastModifiedTime;
  }, [fileInfo === null || fileInfo === undefined ? undefined : fileInfo.lastModifiedTime]);

  // Fetch server-N → workspace name mapping from the main process
  require$$0$1.useEffect(() => {
    const fetchMapping = async () => {
      try {
        const response = await electron.ipcRenderer.invoke('log-viewer-window/get-server-mapping');
        if (response !== null && response !== void 0 && response.success) {
          setServerMapping(response.mapping);
        }
      } catch {
        // Non-critical: mapping not available yet
      }
    };
    fetchMapping();
    const interval = setInterval(fetchMapping, 30_000);
    return () => clearInterval(interval);
  }, []);
  require$$0$1.useEffect(() => {
    loadLogs();
  }, [loadLogs, currentLogFile.filePath, currentLogFile.isDefaultLog]);
  const checkForUpdates = require$$0$1.useCallback(async () => {
    if (!isStreaming || !currentLogFile.isDefaultLog) return;
    try {
      var _statResponse$size;
      const statResponse = await electron.ipcRenderer.invoke('log-viewer-window/stat-log', {
        filePath: undefined
      });
      if (!(statResponse !== null && statResponse !== void 0 && statResponse.success) || !statResponse.lastModifiedTime) return;
      const currentModTime = lastModifiedTimeRef.current;
      if (!currentModTime || statResponse.lastModifiedTime <= currentModTime) return;
      const currentSize = (_statResponse$size = statResponse.size) !== null && _statResponse$size !== void 0 ? _statResponse$size : 0;
      const previousSize = lastKnownSizeRef.current;

      // File was truncated/rotated (or cleared) — full re-read
      if (currentSize < previousSize) {
        loadLogs();
        return;
      }

      // No new bytes — just a timestamp change (e.g. chmod)
      if (currentSize === previousSize) {
        lastModifiedTimeRef.current = statResponse.lastModifiedTime;
        return;
      }

      // Incremental read: only fetch new bytes appended since last read
      const tailResponse = await electron.ipcRenderer.invoke('log-viewer-window/read-logs-tail', {
        fromByte: previousSize
      });
      if (tailResponse !== null && tailResponse !== void 0 && tailResponse.success && tailResponse.logs) {
        const newEntries = parseLogLines(tailResponse.logs);
        if (newEntries.length > 0) {
          setLogEntries(prev => {
            // newEntries are already reversed (newest first)
            // Prepend them to existing entries
            return [...newEntries, ...prev];
          });
          setFileInfo(prev => {
            var _prev$totalEntriesInF;
            return prev ? {
              ...prev,
              totalEntries: prev.totalEntries + newEntries.length,
              totalEntriesInFile: ((_prev$totalEntriesInF = prev.totalEntriesInFile) !== null && _prev$totalEntriesInF !== void 0 ? _prev$totalEntriesInF : 0) + newEntries.length,
              lastModified: new Date().toLocaleString(),
              lastModifiedTime: tailResponse.lastModifiedTime
            } : prev;
          });
        }
        if (tailResponse.newSize !== undefined) {
          lastKnownSizeRef.current = tailResponse.newSize;
        }
        lastModifiedTimeRef.current = tailResponse.lastModifiedTime;
      }
    } catch (error) {
      console.error('Failed to check for updates:', error);
    }
  }, [isStreaming, currentLogFile.isDefaultLog, loadLogs, parseLogLines]);
  require$$0$1.useEffect(() => {
    if (!isStreaming || !currentLogFile.isDefaultLog) return;
    const interval = setInterval(checkForUpdates, AUTO_REFRESH_INTERVAL_MS);
    return () => clearInterval(interval);
  }, [isStreaming, currentLogFile.isDefaultLog, checkForUpdates]);
  require$$0$1.useEffect(() => {
    if (autoScroll) {
      setUserHasScrolled(false);
    }
  }, [autoScroll]);
  require$$0$1.useEffect(() => {
    if (autoScroll && !userHasScrolled && logEntries.length > 0 && virtuosoRef.current) {
      const timeoutId = setTimeout(() => {
        isAutoScrollingRef.current = true;
        if (virtuosoRef.current && autoScroll && !userHasScrolled) {
          virtuosoRef.current.scrollToIndex({
            index: 0,
            behavior: 'auto'
          });
        }
        isAutoScrollingRef.current = false;
      }, SCROLL_DELAY_MS);
      return () => clearTimeout(timeoutId);
    }
    return undefined;
  }, [logEntries, autoScroll, userHasScrolled]);
  const handleScroll = require$$0$1.useCallback(() => {
    if (isAutoScrollingRef.current) return;
    if (autoScroll && !userHasScrolled) {
      setUserHasScrolled(true);
    }
  }, [autoScroll, userHasScrolled]);
  const renderLogEntry = require$$0$1.useCallback((_index, entry) => {
    return /*#__PURE__*/jsxRuntimeExports.jsx(LogEntry, {
      entry: entry,
      showContext: showContext,
      showServer: showServer,
      serverMapping: serverMapping
    }, entry.id);
  }, [showContext, showServer, serverMapping]);
  const handleOpenLogFile = require$$0$1.useCallback(async () => {
    try {
      const response = await electron.ipcRenderer.invoke('log-viewer-window/select-log-file');
      if (response !== null && response !== void 0 && response.success && response.filePath) {
        setLogEntries([]);
        setFileInfo(null);
        setIsStreaming(false);
        setCurrentLogFile({
          filePath: response.filePath,
          fileName: response.fileName || 'custom.log',
          isDefaultLog: false
        });
      }
    } catch (error) {
      console.error('Failed to open log file:', error);
    }
  }, []);
  const handleOpenDefaultLog = require$$0$1.useCallback(() => {
    setLogEntries([]);
    setFileInfo(null);
    setCurrentLogFile({
      filePath: undefined,
      fileName: 'main.log',
      isDefaultLog: true
    });
  }, []);
  const handleRefresh = require$$0$1.useCallback(() => {
    loadLogs();
  }, [loadLogs]);
  const handleClearLogs = require$$0$1.useCallback(async () => {
    if (!currentLogFile.isDefaultLog) {
      return;
    }
    try {
      const confirmed = await electron.ipcRenderer.invoke('log-viewer-window/confirm-clear-logs');
      if (!confirmed) return;
      const response = await electron.ipcRenderer.invoke('log-viewer-window/clear-logs');
      if (response !== null && response !== void 0 && response.success) {
        lastKnownSizeRef.current = 0;
        loadLogs();
      }
    } catch (error) {
      console.error('Failed to clear logs:', error);
    }
  }, [currentLogFile.isDefaultLog, loadLogs]);
  const handleToggleStreaming = require$$0$1.useCallback(() => {
    setIsStreaming(!isStreaming);
  }, [isStreaming]);
  const handleCopyLogs = require$$0$1.useCallback(() => {
    const logText = filteredLogs.map(entry => entry.raw).join('\n');
    navigator.clipboard.writeText(logText).catch(error => {
      console.error('Failed to copy logs to clipboard:', error);
    });
  }, [filteredLogs]);
  const handleSaveLogs = require$$0$1.useCallback(async () => {
    try {
      const logText = filteredLogs.map(entry => entry.raw).join('\n');
      const timestamp = new Date().toISOString().slice(0, 19).replace(/:/g, '-');
      const response = await electron.ipcRenderer.invoke('log-viewer-window/save-logs', {
        content: logText,
        defaultFileName: `rocketchat_${timestamp}.zip`
      });
      if (response !== null && response !== void 0 && response.success) {
        console.log('Logs saved successfully to:', response.filePath);
      } else if (response !== null && response !== void 0 && response.error) {
        console.error('Failed to save logs:', response.error);
      }
    } catch (error) {
      console.error('Failed to save logs:', error);
    }
  }, [filteredLogs]);
  require$$0$1.useEffect(() => {
    const handleKeyDown = e => {
      if ((e.ctrlKey || e.metaKey) && e.key === 'f') {
        e.preventDefault();
        const searchInput = document.querySelector('input[type="search"]');
        searchInput === null || searchInput === undefined || searchInput.focus();
      }
      if ((e.ctrlKey || e.metaKey) && e.key === 's') {
        e.preventDefault();
        handleSaveLogs();
      }
      if (e.key === 'Escape' && searchFilter) {
        setSearchFilter('');
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [searchFilter, setSearchFilter, handleSaveLogs]);
  const handleClose = require$$0$1.useCallback(() => {
    electron.ipcRenderer.invoke('log-viewer-window/close-requested');
  }, []);
  return /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
    display: "flex",
    flexDirection: "column",
    height: "100vh",
    width: "100%",
    backgroundColor: "surface-light",
    children: [/*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
      minHeight: "x64",
      padding: "x24",
      display: "flex",
      flexDirection: "row",
      flexWrap: "nowrap",
      alignItems: "center",
      borderBlockEnd: "1px solid var(--rcx-color-stroke-light)",
      backgroundColor: "surface-tint",
      children: [/*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
        display: "flex",
        flexDirection: "row",
        alignItems: "center",
        flexGrow: 1,
        children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
          name: "list-alt",
          size: "x20",
          color: "default",
          "aria-label": t('logViewer.aria.logIcon')
        }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
          fontScale: "h4",
          marginInlineStart: "x8",
          color: "default",
          children: t('logViewer.title')
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
          display: "flex",
          flexDirection: "column",
          alignItems: "flex-start",
          color: "hint",
          fontSize: "x12",
          marginInlineStart: "x16",
          children: [/*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
            display: "flex",
            alignItems: "center",
            marginBlockEnd: "x4",
            children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
              name: currentLogFile.isDefaultLog ? 'home' : 'attachment',
              size: "x12"
            }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
              marginInlineStart: "x4",
              fontWeight: "bold",
              color: currentLogFile.isDefaultLog ? 'default' : 'info',
              children: [currentLogFile.fileName, !currentLogFile.isDefaultLog && ` (${t('logViewer.fileInfo.custom')})`]
            })]
          }), fileInfo && /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
            display: "flex",
            alignItems: "center",
            flexWrap: "wrap",
            children: [/*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
              marginInlineEnd: "x8",
              display: "flex",
              alignItems: "center",
              children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
                name: "hash",
                size: "x12"
              }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
                marginInlineStart: "x4",
                children: fileInfo.totalEntriesInFile && fileInfo.totalEntriesInFile !== fileInfo.totalEntries ? t('logViewer.fileInfo.entriesOfTotal', {
                  count: fileInfo.totalEntries,
                  total: fileInfo.totalEntriesInFile
                }) : t('logViewer.fileInfo.entries', {
                  count: fileInfo.totalEntries
                })
              })]
            }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
              marginInlineEnd: "x8",
              display: "flex",
              alignItems: "center",
              children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
                name: "file",
                size: "x12"
              }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
                marginInlineStart: "x4",
                children: fileInfo.size
              })]
            }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
              marginInlineEnd: "x8",
              display: "flex",
              alignItems: "center",
              children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
                name: "clock",
                size: "x12"
              }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
                marginInlineStart: "x4",
                children: fileInfo.dateRange
              })]
            })]
          })]
        })]
      }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.ButtonGroup, {
        children: [/*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Button, {
          onClick: handleOpenLogFile,
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: "folder",
            size: "x16"
          }), t('logViewer.buttons.openLogFile')]
        }), !currentLogFile.isDefaultLog && /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Button, {
          onClick: handleOpenDefaultLog,
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: "home",
            size: "x16"
          }), t('logViewer.buttons.defaultLog')]
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Button, {
          onClick: handleRefresh,
          disabled: isLoading,
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: "refresh",
            size: "x16",
            "aria-label": t('logViewer.buttons.refresh')
          }), t('logViewer.buttons.refresh')]
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Button, {
          onClick: handleToggleStreaming,
          primary: isStreaming,
          disabled: !currentLogFile.isDefaultLog,
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: isStreaming ? 'pause' : 'play',
            size: "x16"
          }), isStreaming ? t('logViewer.buttons.stopAutoRefresh') : t('logViewer.buttons.autoRefresh')]
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Button, {
          onClick: handleCopyLogs,
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: "copy",
            size: "x16"
          }), t('logViewer.buttons.copy')]
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Button, {
          onClick: handleSaveLogs,
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: "download",
            size: "x16"
          }), t('logViewer.buttons.save')]
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Button, {
          onClick: handleClearLogs,
          danger: true,
          disabled: !currentLogFile.isDefaultLog,
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: "trash",
            size: "x16"
          }), t('logViewer.buttons.clear')]
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Button, {
          onClick: handleClose,
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: "cross",
            size: "x16"
          }), t('logViewer.buttons.close')]
        })]
      })]
    }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
      padding: "x24",
      paddingBlockStart: "x12",
      paddingBlockEnd: "x12",
      display: "flex",
      flexDirection: "row",
      flexWrap: "wrap",
      alignItems: "center",
      justifyContent: "space-between",
      borderBlockEnd: "1px solid var(--rcx-color-stroke-light)",
      backgroundColor: "surface-tint",
      children: [/*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
        display: "flex",
        alignItems: "center",
        flexWrap: "wrap",
        children: [/*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
          display: "flex",
          alignItems: "center",
          marginInlineEnd: "x16",
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.CheckBox, {
            "aria-label": t('logViewer.controls.showContext'),
            checked: showContext,
            onChange: () => setShowContext(!showContext)
          }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
            marginInlineStart: "x4",
            display: "inline",
            color: "default",
            children: t('logViewer.controls.showContext')
          })]
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
          display: "flex",
          alignItems: "center",
          marginInlineEnd: "x16",
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.CheckBox, {
            "aria-label": t('logViewer.controls.showServer'),
            checked: showServer,
            onChange: () => setShowServer(!showServer)
          }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
            marginInlineStart: "x4",
            display: "inline",
            color: "default",
            children: t('logViewer.controls.showServer')
          })]
        }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
          display: "flex",
          alignItems: "center",
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.CheckBox, {
            "aria-label": t('logViewer.controls.autoScrollToTop'),
            checked: autoScroll,
            onChange: () => {
              const newAutoScroll = !autoScroll;
              setAutoScroll(newAutoScroll);
              if (newAutoScroll) {
                setUserHasScrolled(false);
                if (filteredLogs.length > 0 && virtuosoRef.current) {
                  setTimeout(() => {
                    var _virtuosoRef$current;
                    (_virtuosoRef$current = virtuosoRef.current) === null || _virtuosoRef$current === undefined || _virtuosoRef$current.scrollToIndex({
                      index: 0,
                      behavior: 'smooth'
                    });
                  }, 100);
                }
              }
            }
          }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
            marginInlineStart: "x4",
            display: "inline",
            color: "default",
            children: t('logViewer.controls.autoScrollToTop')
          })]
        })]
      }), /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
        display: "flex",
        alignItems: "center",
        flexWrap: "wrap",
        children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
          marginInlineEnd: "x12",
          children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Select, {
            placeholder: t('logViewer.placeholders.loadAmount'),
            value: entryLimit,
            options: entryLimitOptions,
            onChange: handleEntryLimitChange,
            width: 180
          })
        }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
          minWidth: "x200",
          marginInlineEnd: "x12",
          children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.SearchInput, {
            "aria-label": t('logViewer.placeholders.searchLogs'),
            placeholder: t('logViewer.placeholders.searchLogs'),
            value: searchFilter,
            onChange: handleSearchFilterChange
          })
        }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
          marginInlineEnd: "x12",
          children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Select, {
            placeholder: t('logViewer.placeholders.level'),
            value: levelFilter,
            options: levelFilterOptions,
            onChange: handleLevelFilterChange,
            width: 120
          })
        }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
          marginInlineEnd: "x12",
          children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Select, {
            placeholder: t('logViewer.placeholders.context'),
            value: contextFilter,
            options: contextFilterOptions,
            onChange: handleContextFilterChange,
            width: 200
          })
        }), serverFilterOptions.length > 1 && /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
          marginInlineEnd: "x12",
          children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Select, {
            placeholder: t('logViewer.filters.server.all'),
            value: serverFilter,
            options: serverFilterOptions,
            onChange: handleServerFilterChange,
            width: 240
          })
        }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Button, {
          onClick: handleClearAll,
          children: t('logViewer.buttons.clearFilters')
        })]
      })]
    }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
      flexGrow: 1,
      padding: "x24",
      paddingBlockStart: "x12",
      children: /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Tile, {
        elevation: "2",
        padding: 0,
        overflow: "hidden",
        height: "100%",
        children: [isLoading && /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
          display: "flex",
          justifyContent: "center",
          alignItems: "center",
          height: "x400",
          backgroundColor: "surface-light",
          children: /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Throbber, {
            size: "x32"
          })
        }), !isLoading && filteredLogs.length === 0 && /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
          display: "flex",
          flexDirection: "column",
          justifyContent: "center",
          alignItems: "center",
          height: "100%",
          color: "hint",
          backgroundColor: "surface-light",
          children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Icon, {
            name: "list-alt",
            size: "x32",
            color: "hint"
          }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
            marginBlockStart: "x8",
            fontScale: "p2",
            children: t('logViewer.messages.noLogsFound')
          }), /*#__PURE__*/jsxRuntimeExports.jsx(fuselage.Box, {
            marginBlockStart: "x4",
            fontScale: "c1",
            color: "hint",
            children: t('logViewer.messages.adjustFilters')
          })]
        }), !isLoading && filteredLogs.length > 0 && /*#__PURE__*/jsxRuntimeExports.jsxs(fuselage.Box, {
          style: {
            height: '100%',
            position: 'relative'
          },
          children: [/*#__PURE__*/jsxRuntimeExports.jsx("div", {
            style: {
              position: 'absolute',
              top: '8px',
              right: '8px',
              color: 'var(--rcx-color-font-hint)',
              fontSize: '12px',
              zIndex: 10,
              background: 'var(--rcx-color-surface-tint)',
              padding: '4px 8px',
              borderRadius: '4px'
            },
            children: t('logViewer.fileInfo.entries', {
              count: filteredLogs.length
            })
          }), /*#__PURE__*/jsxRuntimeExports.jsx(reactVirtuoso.Virtuoso, {
            ref: virtuosoRef,
            data: filteredLogs,
            itemContent: renderLogEntry,
            overscan: VIRTUOSO_OVERSCAN,
            style: {
              height: '100%',
              width: '100%'
            },
            onScroll: handleScroll
          })]
        })]
      })
    })]
  });
}

const useSystemTheme = () => {
  const [theme, setTheme] = require$$0$1.useState(() => window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
  require$$0$1.useEffect(() => {
    const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
    const handleChange = e => {
      setTheme(e.matches ? 'dark' : 'light');
    };
    mediaQuery.addEventListener('change', handleChange);
    return () => mediaQuery.removeEventListener('change', handleChange);
  }, []);
  return theme;
};
const ThemedLogViewerWindow = () => {
  const theme = useSystemTheme();
  return /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
    children: [/*#__PURE__*/jsxRuntimeExports.jsx(fuselage.PaletteStyleTag, {
      theme: theme,
      selector: ":root"
    }), /*#__PURE__*/jsxRuntimeExports.jsx(LogViewerWindow, {})]
  });
};
const detectLocale = () => {
  const browserLang = navigator.language;
  if (!browserLang) return fallbackLng;

  // Try exact match first (e.g., "pt-BR" → "pt-BR")
  if (browserLang in resources) return browserLang;

  // Try language code only (e.g., "fr-FR" → "fr")
  const [langCode] = browserLang.split('-');
  if (langCode && langCode in resources) return langCode;
  return fallbackLng;
};
const setupI18n = async () => {
  const lng = detectLocale();
  const resourceBundles = {
    [fallbackLng]: {
      translation: await resources[fallbackLng]()
    }
  };

  // Load detected locale if different from fallback
  if (lng !== fallbackLng && lng in resources) {
    resourceBundles[lng] = {
      translation: await resources[lng]()
    };
  }
  await i18next__default.default.use(reactI18next.initReactI18next).init({
    lng,
    fallbackLng,
    resources: resourceBundles,
    interpolation,
    initImmediate: true
  });
};
const start = async () => {
  await setupI18n();
  const rootElement = document.getElementById('root');
  if (!rootElement) {
    throw new Error('Root element not found');
  }
  const root = createRoot(rootElement);
  root.render(/*#__PURE__*/jsxRuntimeExports.jsx(reactI18next.I18nextProvider, {
    i18n: i18next__default.default,
    children: /*#__PURE__*/jsxRuntimeExports.jsx(ThemedLogViewerWindow, {})
  }));
};
start().catch(console.error);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,[encoded data, 197816 characters]
