<|start_filename|>ui/oopsyraidsy/oopsy_live.css<|end_filename|>
::-webkit-scrollbar {
  width: 11px;
  height: 11px;
}

::-webkit-scrollbar-button {
  width: 4px;
  height: 4px;
}

::-webkit-scrollbar-track {
  background: #666;
  border: 4px solid #202020;
  border-radius: 0;
}

::-webkit-scrollbar-thumb {
  background: #f0f4ce;
  border: 1px inset #ddd391;
  border-radius: 0;
}

::-webkit-scrollbar-corner {
  background: transparent;
}

:root {
  --text-shadow-color: #217aa2;
  --damage-shadow-color: rgba(217, 255, 0, 0.2);
  --live-list-max-width: 500px;
}

::-webkit-scrollbar-thumb:hover {
  background: #f0f4ce;
}

::-webkit-scrollbar-thumb:active {
  background: #f0f4ce;
}

::-webkit-scrollbar-track:hover {
  background: #666;
}

::-webkit-scrollbar-track:active {
  background: #333;
}

.resize-helper {
  display: none;
}

.resizeHandle .resize-helper {
  display: inline-block;
}

.flexcontainer {
  position: absolute;
  height: 100%;
  width: 100%;
  display: flex;
  justify-content: flex-end;
}

.livelist {
  min-width: 300px;
  max-width: var(--live-list-max-width);
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
}

.resize-helper .livelist {
  width: var(--live-list-max-width);
}

.livelist-shadow {
  box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.5);
  margin: 5px;
}

.out-of-combat .livelist-shadow {
  box-shadow: 0 0 5px 2px rgba(200, 200, 70, 0.3);
}

div {
  font-family: "Meiryo", sans-serif;
  font-size: 12;
  text-shadow: -1px 0 3px var(--text-shadow-color), 0 1px 3px var(--text-shadow-color), 1px 0 3px var(--text-shadow-color), 0 -1px 3px var(--text-shadow-color);
  font-weight: 300;
  color: #e2ebf5;
}

.mistake-row {
  justify-content: space-between;
}

.mistake-row:nth-child(even) {
  background-color: rgba(20, 20, 20, 0.3);
}

.mistake-row:nth-child(odd) {
  background-color: rgba(50, 50, 50, 0.3);
}

.mistake-row > div {
  height: 100%;
  display: flex;
  align-items: center;
  user-select: none;
}

.mistake-icon {
  flex: 0 0 auto;
  order: 1;
  justify-content: center;
}

.mistake-text {
  flex: 1 1 auto;
  order: 2;
}

.mistake-time {
  align-self: flex-end;
  padding-right: 3px;
  order: 3;
}

.resizeHandle .hide-if-resizing {
  display: none;
}

.death-report {
  width: 300px;
  height: 100%;
  overflow-x: hidden;
  overflow-y: auto;
}

.death-report > div {
  padding: 5px;
  background-color: rgba(20, 20, 20, 0.3);
}

.death-title {
  display: flex;
  margin-bottom: 5px;
}

.death-title div {
  font-size: 18px;
}

.death-title-icon {
  flex: 0 0 auto;
  order: 1;
}

.death-title-text {
  flex: 1 1 auto;
  order: 2;
}

.death-title-close {
  align-self: flex-end;
  order: 3;
  width: 25px;
  height: 20px;
}

.death-details {
  display: grid;
  grid-template-columns: max-content minmax(50px, max-content) minmax(10px, max-content) auto auto;
}

.death-row-hp {
  text-align: right;
}

.death-row-amount {
  text-align: right;
}

.death-details .damage {
  color: rgb(255, 0, 0);
  font-weight: bold;

  /* blue text shadow looks really weird, and I can't find a shadow combination with red
     that doesn't make it look washed out */
  text-shadow: none;
}

.death-details .heal {
  color: rgb(125, 250, 125);
}

.death-row-icon.mistake-icon {
  order: unset;
}

.death-row-text {
  text-align: left;
}

.death-row-time {
  text-align: right;
}

/* by default the report is on the left */
.report-side-right .flexcontainer {
  flex-direction: row-reverse;
}

.report-side-disabled .death-report {
  display: none;
}

@keyframes fadeOut {
  50% {
    opacity: 1;
  }

  100% {
    opacity: 0;
  }
}

.copied-msg {
  /* width/height set programatically */
  display: flex;
  justify-content: center;
  position: absolute;
  margin: 0 auto;
  color: white;
  box-shadow: 0 0 5px 2px rgba(70, 115, 200, 0.3);
  background-color: rgba(50, 50, 50, 0.5);
  pointer-events: none;
  animation: 1s fadeOut;
  animation-fill-mode: forwards;
}

.icons {
  display: none;
  margin-top: 5px;
}

.out-of-combat .icons {
  display: flex;
  flex-direction: column;
}

.icons.hide {
  display: none;
}

.icon-close {
  color: rgb(230, 230, 230);
}

.icon-close::before {
  content: '\f00d';
}

.icon-summary {
  color: rgb(230, 230, 230);
}

.icon-summary::before {
  content: '\f35d';
}

.icon-entry {
  width: 20px;
  height: 20px;
  font-size: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.icon-entry:hover {
  color: rgb(247, 255, 129);
}


<|start_filename|>tsconfig-for-webpack.json<|end_filename|>
{
  "extends": "./tsconfig.base.json",
  "ts-node": {
    // This can be omitted when using ts-patch
    "compiler": "ttypescript",
    "moduleTypes": {
      "webpack/*": "cjs",
      // Globs are also supported with the same behavior as tsconfig "include"
      "webpack/**/*": "cjs"
    }
  },
  "compilerOptions": {
    "moduleResolution": "node",
    "skipLibCheck": false
  }
}


<|start_filename|>ui/oopsyraidsy/oopsy_summary.css<|end_filename|>
:root {
  --table-cols: 5;
}

html {
  overflow: visible !important;
  font-family: "Meiryo", sans-serif;
  font-size: 16;
}

.mistake-row {
  height: 25px;
  align-items: center;
}

.mistake-row .mistake-icon {
  order: 2;
  margin-right: 3px;
  font-size: 20px;
}

.mistake-text {
  order: 3;
}

.mistake-time {
  order: 1;
  margin-right: 5px;
}

.mistake-collapser {
  order: 5;
  margin-left: 5px;
}

.mistake-collapser::before {
  display: inline-block;
  font-style: normal;
  font-variant: normal;
  text-rendering: auto;

  /* these are icon fonts, so there's no fallback for this */
  /* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */
  font-family: 'Font Awesome 5 Free';
  font-weight: 900;
  content: '\f138';
}

.mistake-collapser.expanded::before {
  content: '\f13a';
}

.summary {
  margin: 5px;
}

.section {
  margin-bottom: 20px;
  max-width: 800px;
}

.section-header {
  display: flex;
  font-weight: bold;
  font-size: 18;
}

.section-header > div {
  margin-right: 5px;
}

.section-rows {
  padding-left: 10px;
  max-width: 500px;
}

.mistake-table {
  display: grid;
  grid-template-columns: repeat(var(--table-cols), max-content);
  margin: 20px;
}

.mistake-table div {
  padding-top: 3px;
  padding-bottom: 3px;
  text-align: right;
  box-sizing: border-box;

  /* give all columns a light border, override first column below */
  border-right: solid grey 1px;
}

/* first row */
.mistake-table .header {
  border-bottom: solid black 2px;
  order: -1;
}

/* first row, not first column */
.mistake-table .mistake-icon {
  text-align: center;
  min-width: 30px;
  width: 100%;
}

/* first column */
.mistake-table .name {
  padding-right: 5px;
  border-right: solid black 2px;
}

/* not first column, not first row */
.mistake-table .number {
  /* numbers are aligned right, but "centered" a little with padding */
  padding-left: 12px;
  padding-right: 12px;
}

.death-details {
  display: none;
}

.death-details.expanded {
  margin-left: 40px;
  display: grid;
  grid-template-columns: max-content minmax(50px, max-content) minmax(10px, max-content) max-content max-content;
  column-gap: 10px;
}

.death-row-hp {
  text-align: right;
}

.death-row-amount {
  text-align: right;
  font-weight: bold;
}

.death-row-icon {
  width: 18px;
}

.death-details .damage {
  color: rgb(255, 0, 0);
}

.death-details .heal {
  color: rgb(16, 205, 16);
}

.death-row-icon.mistake-icon {
  order: unset;
}

.death-row-text {
  text-align: left;
}

.death-row-time {
  text-align: right;
}


<|start_filename|>user/raidboss-example.js<|end_filename|>
// Rename this file to `raidboss.js` and edit it to change the raidboss ui.
// This file is Javascript.  Anything after "//" on a line is a comment.
// If you edit this file, remember to reload ACT or click the "Reload overlay"
// button on the raidboss overlay.
// If there are errors in this file, they will appear in the OverlayPlugin.dll
// log window in ACT.
// See: http://github.com/quisquous/cactbot/blob/main/docs/CactbotCustomization.md#check-the-overlayplugin-log-for-errors

// Path to sound played for info-priority text popups, or when "Info" is
// specified as the sound name.
Options.InfoSound = '../../resources/sounds/freesound/percussion_hit.webm';

// Path to sound played for alert-priority text popups, or when "Alert" is
// specified as the sound name.
Options.AlertSound = '../../resources/sounds/BigWigs/Alert.webm';

// Path to sound played for alarm-priority text popups, or when "Alarm" is
// specified as the sound name.
Options.AlarmSound = '../../resources/sounds/BigWigs/Alarm.webm';

// Path to sound played when "Long" is specified as the sound name.
Options.LongSound = '../../resources/sounds/BigWigs/Long.webm';

// Path to sound played when the fight starts, or when "Pull" is
// specified as the sound name.
Options.PullSound = '../../resources/sounds/freesound/sonar.webm';

// A set of nicknames to use for players, when trying to shorten names.
// See: https://github.com/quisquous/cactbot/blob/main/docs/CactbotCustomization.md#customizing-behavior
Options.PlayerNicks = {
  '<NAME>': 'Jimmy',
  '<NAME>': 'Fish',
};

// An array of user-defined triggers, in the format defined in the trigger guide:
// See: https://github.com/quisquous/cactbot/blob/main/docs/CactbotCustomization.md#overriding-raidboss-triggers
// See also: https://github.com/quisquous/cactbot/tree/main/docs/RaidbossGuide.md

// Here's an example of overriding a trigger.
// This overrides the "Test Poke" trigger from:
// https://github.com/quisquous/cactbot/blob/main/ui/raidboss/data/00-misc/test.js

Options.Triggers.push({
  zoneId: ZoneId.MiddleLaNoscea,
  triggers: [
    {
      id: 'Test Poke',
      netRegex: NetRegexes.gameNameLog({ line: 'You poke the striking dummy.*?', capture: false }),
      netRegexDe: NetRegexes.gameNameLog(
        { line: 'Du stupst die Trainingspuppe an.*?', capture: false },
      ),
      netRegexFr: NetRegexes.gameNameLog(
        {
          line: 'Vous touchez légèrement le mannequin d\'entraînement du doigt.*?',
          capture: false,
        },
      ),
      netRegexJa: NetRegexes.gameNameLog({ line: '.*は木人をつついた.*?', capture: false }),
      netRegexCn: NetRegexes.gameNameLog({ line: '.*用手指戳向木人.*?', capture: false }),
      netRegexKo: NetRegexes.gameNameLog({ line: '.*나무인형을 쿡쿡 찌릅니다.*?', capture: false }),
      preRun: function(data) {
        data.pokes = (data.pokes || 0) + 1;
      },
      // Instead of printing the number of pokes with infoText like the original trigger,
      // This overrides the type and text of the output.
      alarmText: 'POKE (user file override)',
    },
  ],
});

// Here's an example of overriding a timeline.
// This overrides the test timeline that you normally play with a `/countdown 5` in Middle La Noscea
// with an updated one from `user/test-override.txt`.
Options.Triggers.push({
  zoneId: ZoneId.MiddleLaNoscea,
  // This flag is required to clear any previously specified timelines.
  overrideTimelineFile: true,
  // This file is in the same directory as this JavaScript file.
  timelineFile: 'test-override.txt',
});

// Here's an example of a adding a custom regen trigger.
// It reminds you to use regen again when you are in Sastasha (unsynced).
Options.Triggers.push({
  // The zone this should apply to.
  // This should match the zoneId in the triggers file.
  zoneId: ZoneId.Sastasha,
  triggers: [
    // A more complicated regen trigger.
    {
      // This is a made up id that does not exist in cactbot.
      id: 'User Example Regen',
      // This will match log lines from ACT that look like this:
      // "Nacho Queen gains the effect of Regen from Taco Cat for 21.00 Seconds."
      regex: Regexes.gainsEffect({ effect: 'Regen' }),
      delaySeconds: function(data, matches) {
        // Wait the amount of seconds regen lasts before reminding you to
        // reapply it.  This is not smart enough to figure out if you
        // cast it twice, and is left as an exercise for the reader to
        // figure out how to do so via storing variables on `data`.
        return data.ParseLocaleFloat(matches.duration);
      },
      alertText: 'Regen',
    },
  ],
});
