text:
import { OvaleAuraClass } from "./Aura";
import { OvaleDataClass } from "./Data";
import { OvaleGUIDClass } from "./GUID";
import { OvalePaperDollClass, HasteType } from "./PaperDoll";
import { LastSpell, SpellCast, self_pool, createSpellCast } from "./LastSpell";
import aceEvent, { AceEvent } from "@wowts/ace_event-3.0";
import { ipairs, pairs, type, lualength, LuaObj, LuaArray, wipe, kpairs, tonumber } from "@wowts/lua";
import { sub } from "@wowts/string";
import { insert, remove } from "@wowts/table";
import { GetSpellInfo, GetTime, UnitCastingInfo, UnitChannelInfo, UnitExists, UnitGUID, UnitName, CombatLogGetCurrentEventInfo } from "@wowts/wow-mock";
import { OvaleStateClass, States } from "./State";
import { OvaleCooldownClass } from "./Cooldown";
import { BaseState } from "./BaseState";
import { isLuaArray } from "./tools";
import { Tokens, OvaleRequirement } from "./Requirement";
import { OvaleClass } from "./Ovale";
import { AceModule } from "@wowts/tsaddon";
import { Tracer, OvaleDebugClass } from "./Debug";
import { Profiler, OvaleProfilerClass } from "./Profiler";
import { OvaleStanceClass } from "./Stance";
import { OvaleSpellBookClass } from "./SpellBook";

let strsub = sub;
let tremove = remove;
let self_timeAuraAdded: undefined|number = undefined;

// let SIMULATOR_LAG = 0.005;

let CLEU_AURA_EVENT: LuaObj<"hit"> = {
    SPELL_AURA_APPLIED: "hit",
    SPELL_AURA_APPLIED_DOSE: "hit",
    SPELL_AURA_BROKEN: "hit",
    SPELL_AURA_BROKEN_SPELL: "hit",
    SPELL_AURA_REFRESH: "hit",
    SPELL_AURA_REMOVED: "hit",
    SPELL_AURA_REMOVED_DOSE: "hit"
}
let CLEU_SPELLCAST_FINISH_EVENT: LuaObj<"hit" | "miss"> = {
    SPELL_DAMAGE: "hit",
    SPELL_DISPEL: "hit",
    SPELL_DISPEL_FAILED: "miss",
    SPELL_HEAL: "hit",
    SPELL_INTERRUPT: "hit",
    SPELL_MISSED: "miss",
    SPELL_STOLEN: "hit"
}
let CLEU_SPELLCAST_EVENT: LuaObj<boolean> = {
    SPELL_CAST_FAILED: true,
    SPELL_CAST_START: true,
    SPELL_CAST_SUCCESS: true
}
{
    for (const [cleuEvent, v] of pairs(CLEU_AURA_EVENT)) {
        CLEU_SPELLCAST_FINISH_EVENT[cleuEvent] = v;
    }
    for (const [cleuEvent, ] of pairs(CLEU_SPELLCAST_FINISH_EVENT)) {
        CLEU_SPELLCAST_EVENT[cleuEvent] = true;
    }
}
let SPELLCAST_AURA_ORDER: LuaArray<"target" | "pet"> = {
    1: "target",
    2: "pet"
};
let SPELLAURALIST_AURA_VALUE: LuaObj<boolean> = {
    count: true,
    extend: true,
    refresh: true,
    refresh_keep_snapshot: true
};
let WHITE_ATTACK: LuaArray<boolean> = {
    [75]: true,
    [5019]: true,
    [6603]: true
};
let WHITE_ATTACK_NAME: LuaObj<boolean> = {};
{
    for (const [spellId] of pairs(WHITE_ATTACK)) {
        let [name] = GetSpellInfo(spellId);
        if (name) {
            WHITE_ATTACK_NAME[name] = true;
        }
    }
}

const IsSameSpellcast = function(a: SpellCast, b: SpellCast) {
    let boolean = (a.spellId == b.spellId && a.queued == b.queued);
    if (boolean) {
        if (a.channel || b.channel) {
            if (a.channel != b.channel) {
                boolean = false;
            }
        } else if (a.lineId != b.lineId) {
            boolean = false;
        }
    }
    return boolean;
}

export class OvaleFutureData {
    inCombat: boolean = false;
    combatStartTime: number = 0;
    lastCastTime: LuaObj<number> = {}
    lastOffGCDSpellcast: SpellCast = createSpellCast();
    lastGCDSpellcast: SpellCast = createSpellCast();
    lastGCDSpellIds: LuaArray<number> = {}
    lastGCDSpellId: number = 0;
    counter: LuaArray<number> = {}
    lastCast: LuaObj<number> = {};
    currentCast: SpellCast = createSpellCast();
    nextCast: number = 0;

    PushGCDSpellId(spellId: number) {
        if (this.lastGCDSpellId) {
            insert(this.lastGCDSpellIds, this.lastGCDSpellId);
            if (lualength(this.lastGCDSpellIds) > 5) {
                remove(this.lastGCDSpellIds, 1);
            }
        }
        this.lastGCDSpellId = spellId;
    }

    GetCounter (id: number) {
        return this.counter[id] || 0;
    }
    IsChanneling(atTime: number) {
        return this.currentCast.channel && (atTime < this.currentCast.stop);
    }
}

export class OvaleFutureClass extends States<OvaleFutureData> {
    private module: AceModule & AceEvent;
    private tracer: Tracer;
    private profiler: Profiler;
    constructor(
        private ovaleData: OvaleDataClass,
        private ovaleAura: OvaleAuraClass,
        private ovalePaperDoll: OvalePaperDollClass,
        private baseState: BaseState,
        private ovaleCooldown: OvaleCooldownClass,
        private ovaleState: OvaleStateClass,
        private ovaleGuid: OvaleGUIDClass,
        private lastSpell: LastSpell,
        private ovale: OvaleClass,
        ovaleDebug: OvaleDebugClass,
        ovaleProfiler: OvaleProfilerClass,
        private ovaleStance: OvaleStanceClass,
        private requirement: OvaleRequirement,
        private ovaleSpellBook: OvaleSpellBookClass
    ) {
        super(OvaleFutureData);
        const name = "OvaleFuture";
        this.tracer = ovaleDebug.create(name);
        this.profiler = ovaleProfiler.create(name);
        this.module = ovale.createModule(name, this.OnInitialize, this.OnDisable, aceEvent)
    }

    UpdateStateCounters(state: OvaleFutureData, spellId: number, atTime: number, targetGUID: string) {
        let inccounter = this.ovaleData.GetSpellInfoProperty(spellId, atTime, "inccounter", targetGUID);
        if (inccounter) {
            let value = state.counter[inccounter] && state.counter[inccounter] || 0;
            state.counter[inccounter] = value + 1;
        }
        let resetcounter = this.ovaleData.GetSpellInfoProperty(spellId, atTime, "resetcounter", targetGUID);
        if (resetcounter) {
            state.counter[resetcounter] = 0;
        }
    }

    private OnInitialize = () => {
        this.module.RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", this.COMBAT_LOG_EVENT_UNFILTERED);
        this.module.RegisterEvent("PLAYER_ENTERING_WORLD", this.PLAYER_ENTERING_WORLD);
        this.module.RegisterEvent("PLAYER_REGEN_DISABLED", this.PLAYER_REGEN_DISABLED);
        this.module.RegisterEvent("PLAYER_REGEN_ENABLED", this.PLAYER_REGEN_ENABLED);
        this.module.RegisterEvent("UNIT_SPELLCAST_CHANNEL_START", this.UNIT_SPELLCAST_CHANNEL_START);
        this.module.RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP", this.UNIT_SPELLCAST_CHANNEL_STOP);
        this.module.RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE", this.UNIT_SPELLCAST_CHANNEL_UPDATE);
        this.module.RegisterEvent("UNIT_SPELLCAST_DELAYED", this.UNIT_SPELLCAST_DELAYED);
        this.module.RegisterEvent("UNIT_SPELLCAST_FAILED", this.UnitSpellcastEnded);
        this.module.RegisterEvent("UNIT_SPELLCAST_FAILED_QUIET", this.UnitSpellcastEnded);
        this.module.RegisterEvent("UNIT_SPELLCAST_INTERRUPTED", this.UnitSpellcastEnded);
        this.module.RegisterEvent("UNIT_SPELLCAST_SENT", this.UNIT_SPELLCAST_SENT);
        this.module.RegisterEvent("UNIT_SPELLCAST_START", this.UNIT_SPELLCAST_START);
        this.module.RegisterEvent("UNIT_SPELLCAST_STOP", this.UnitSpellcastEnded);
        this.module.RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", this.UNIT_SPELLCAST_SUCCEEDED);
        this.module.RegisterMessage("Ovale_AuraAdded", this.Ovale_AuraAdded);
        this.module.RegisterMessage("Ovale_AuraChanged", this.Ovale_AuraChanged);
        this.requirement.RegisterRequirement("combat", this.CombatRequirement);
    }

    private OnDisable = () => {
        this.module.UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED");
        this.module.UnregisterEvent("PLAYER_ENTERING_WORLD");
        this.module.UnregisterEvent("PLAYER_REGEN_DISABLED");
        this.module.UnregisterEvent("PLAYER_REGEN_ENABLED");
        this.module.UnregisterEvent("UNIT_SPELLCAST_CHANNEL_START");
        this.module.UnregisterEvent("UNIT_SPELLCAST_CHANNEL_STOP");
        this.module.UnregisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE");
        this.module.UnregisterEvent("UNIT_SPELLCAST_DELAYED");
        this.module.UnregisterEvent("UNIT_SPELLCAST_FAILED");
        this.module.UnregisterEvent("UNIT_SPELLCAST_FAILED_QUIET");
        this.module.UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED");
        this.module.UnregisterEvent("UNIT_SPELLCAST_SENT");
        this.module.UnregisterEvent("UNIT_SPELLCAST_START");
        this.module.UnregisterEvent("UNIT_SPELLCAST_STOP");
        this.module.UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED");
        this.module.UnregisterMessage("Ovale_AuraAdded");
        this.module.UnregisterMessage("Ovale_AuraChanged");
        this.requirement.UnregisterRequirement("combat");
    }

    IsInCombat(atTime: number | undefined) {
        return this.GetState(atTime).inCombat;
    }

    private COMBAT_LOG_EVENT_UNFILTERED = (event: string, ...__args: any[]) => {
        this.tracer.DebugTimestamp("COMBAT_LOG_EVENT_UNFILTERED", CombatLogGetCurrentEventInfo())
        let [, cleuEvent, , sourceGUID, sourceName, , , destGUID, destName, , , spellId, spellName, , , , , , , , , , , isOffHand] = CombatLogGetCurrentEventInfo();
        if (sourceGUID == this.ovale.playerGUID || this.ovaleGuid.IsPlayerPet(sourceGUID)) {
            this.profiler.StartProfiling("OvaleFuture_COMBAT_LOG_EVENT_UNFILTERED");
            if (CLEU_SPELLCAST_EVENT[cleuEvent]) {
                let now = GetTime();
                if (strsub(cleuEvent, 1, 11) == "SPELL_CAST_" && (destName && destName != "")) {
                    this.tracer.DebugTimestamp("CLEU", cleuEvent, sourceName, sourceGUID, destName, destGUID, spellId, spellName);
                    let [spellcast] = this.GetSpellcast(spellName, spellId, undefined, now);
                    if (spellcast && spellcast.targetName && spellcast.targetName == destName && spellcast.target != destGUID) {
                        this.tracer.Debug("Disambiguating target of spell %s (%d) to %s (%s).", spellName, spellId, destName, destGUID);
                        spellcast.target = destGUID;
                    }
                }
                this.tracer.DebugTimestamp("CLUE", cleuEvent);
                let finish: "hit" | "miss" | undefined = CLEU_SPELLCAST_FINISH_EVENT[cleuEvent];
                if (cleuEvent == "SPELL_DAMAGE" || cleuEvent == "SPELL_HEAL") {
                    if (isOffHand) {
                        finish = undefined;
                    }
                }
                if (finish) {
                    let anyFinished = false;
                    for (let i = lualength(this.lastSpell.queue); i >= 1; i += -1) {
                        let spellcast = this.lastSpell.queue[i];
                        if (spellcast.success && (spellcast.spellId == spellId || spellcast.auraId == spellId)) {
                            if (this.FinishSpell(spellcast, cleuEvent, sourceName, sourceGUID, destName, destGUID, spellId, spellName, finish, i)) {
                                anyFinished = true;
                            }
                        }
                    }
                    if (!anyFinished) {
                        this.tracer.Debug("Found no spell to finish for %s (%d)", spellName, spellId);
                        for (let i = lualength(this.lastSpell.queue); i >= 1; i += -1) {
                            let spellcast = this.lastSpell.queue[i];
                            if (spellcast.success && (spellcast.spellName == spellName)) {
                                if (this.FinishSpell(spellcast, cleuEvent, sourceName, sourceGUID, destName, destGUID, spellId, spellName, finish, i)) {
                                    anyFinished = true;
                                }
                            }
                        }
                        if (!anyFinished) {
                            this.tracer.Debug("No spell found for %s", spellName, spellId);
                        }
                    }
                }
            }
            this.profiler.StopProfiling("OvaleFuture_COMBAT_LOG_EVENT_UNFILTERED");
        }
    }
    FinishSpell(spellcast: SpellCast, cleuEvent: string, sourceName: string, sourceGUID: string, destName: string, destGUID: string, spellId: number, spellName: string, finish: "hit"|"miss", i: number) {
        let finished = false;
        if (!spellcast.auraId) {
            this.tracer.DebugTimestamp("CLEU", cleuEvent, sourceName, sourceGUID, destName, destGUID, spellId, spellName);
            if (!spellcast.channel) {
                this.tracer.Debug("Finished (%s) spell %s (%d) queued at %s due to %s.", finish, spellName, spellId, spellcast.queued, cleuEvent);
                finished = true;
            }
        } else if (CLEU_AURA_EVENT[cleuEvent] && spellcast.auraGUID && destGUID == spellcast.auraGUID) {
            this.tracer.DebugTimestamp("CLEU", cleuEvent, sourceName, sourceGUID, destName, destGUID, spellId, spellName);
            this.tracer.Debug("Finished (%s) spell %s (%d) queued at %s after seeing aura %d on %s.", finish, spellName, spellId, spellcast.queued, spellcast.auraId, spellcast.auraGUID);
            finished = true;
        } else if (cleuEvent == "Ovale_AuraChanged" && spellcast.auraGUID && destGUID == spellcast.auraGUID) {
            this.tracer.Debug("Finished (%s) spell %s (%d) queued at %s after Ovale_AuraChanged was called for aura %d on %s.", finish, spellName, spellId, spellcast.queued, spellcast.auraId, spellcast.auraGUID);
            finished = true;
        }
        if (finished) {
            let now = GetTime();
            if (self_timeAuraAdded) {
                if (IsSameSpellcast(spellcast, this.lastSpell.lastGCDSpellcast)) {
                    this.UpdateSpellcastSnapshot(this.lastSpell.lastGCDSpellcast, self_timeAuraAdded);
                }
                if (IsSameSpellcast(spellcast, this.current.lastOffGCDSpellcast)) {
                    this.UpdateSpellcastSnapshot(this.current.lastOffGCDSpellcast, self_timeAuraAdded);
                }
            }
            let delta = now - spellcast.stop;
            let targetGUID = spellcast.target;
            this.tracer.Debug("Spell %s (%d) was in flight for %f seconds.", spellName, spellId, delta);
            tremove(this.lastSpell.queue, i);
            self_pool.Release(spellcast);
            this.ovale.needRefresh();
            this.module.SendMessage("Ovale_SpellFinished", now, spellId, targetGUID, finish);
        }
        return finished;
    }
    private PLAYER_ENTERING_WORLD = (event: string) => {
        this.profiler.StartProfiling("OvaleFuture_PLAYER_ENTERING_WORLD");
        this.tracer.Debug(event);
        this.profiler.StopProfiling("OvaleFuture_PLAYER_ENTERING_WORLD");
    }
    private PLAYER_REGEN_DISABLED = (event: string) => {
        this.profiler.StartProfiling("OvaleFuture_PLAYER_REGEN_DISABLED");
        this.tracer.Debug(event, "Entering combat.");
        let now = GetTime();
        this.current.inCombat = true;
        this.current.combatStartTime = now;
        this.ovale.needRefresh();
        this.module.SendMessage("Ovale_CombatStarted", now);
        this.profiler.StopProfiling("OvaleFuture_PLAYER_REGEN_DISABLED");
    }
    private PLAYER_REGEN_ENABLED = (event: string) => {
        this.profiler.StartProfiling("OvaleFuture_PLAYER_REGEN_ENABLED");
        this.tracer.Debug(event, "Leaving combat.");
        let now = GetTime();
        this.current.inCombat = false;
        this.ovale.needRefresh();
        this.module.SendMessage("Ovale_CombatEnded", now);
        this.profiler.StopProfiling("OvaleFuture_PLAYER_REGEN_ENABLED");
    }
    private UNIT_SPELLCAST_CHANNEL_START = (event: string, unitId: string, lineId: number, spellId: number) => {
        if ((unitId == "player" || unitId == "pet") && !WHITE_ATTACK[spellId]) {
            let spell = this.ovaleSpellBook.GetSpellName(spellId);
            this.profiler.StartProfiling("OvaleFuture_UNIT_SPELLCAST_CHANNEL_START");
            this.tracer.DebugTimestamp(event, unitId, spell, lineId, spellId);
            let now = GetTime();
            let [spellcast] = this.GetSpellcast(spell, spellId, undefined, now);
            if (spellcast) {
                let [name, , , startTime, endTime] = UnitChannelInfo(unitId);
                if (name == spell) {
                    startTime = startTime / 1000;
                    endTime = endTime / 1000;
                    spellcast.channel = true;
                    spellcast.spellId = spellId;
                    spellcast.success = now;
                    spellcast.start = startTime;
                    spellcast.stop = endTime;
                    let delta = now - spellcast.queued;
                    this.tracer.Debug("Channelling spell %s (%d): start = %s (+%s), ending = %s", spell, spellId, startTime, delta, endTime);
                    this.SaveSpellcastInfo(spellcast, now);
                    this.UpdateLastSpellcast(now, spellcast);
                    this.UpdateCounters(spellId, spellcast.start, spellcast.target);
                    this.ovale.needRefresh();
                } else if (!name) {
                    this.tracer.Debug("Warning: not channelling a spell.");
                } else {
                    this.tracer.Debug("Warning: channelling unexpected spell %s", name);
                }
            } else {
                this.tracer.Debug("Warning: channelling spell %s (%d) without previous UNIT_SPELLCAST_SENT.", spell, spellId);
            }
            this.profiler.StopProfiling("OvaleFuture_UNIT_SPELLCAST_CHANNEL_START");
        }
    }
    private UNIT_SPELLCAST_CHANNEL_STOP = (event: string, unitId: string, lineId: number, spellId: number) => {
        if ((unitId == "player" || unitId == "pet") && !WHITE_ATTACK[spellId]) {
            let spell = this.ovaleSpellBook.GetSpellName(spellId);
            this.profiler.StartProfiling("OvaleFuture_UNIT_SPELLCAST_CHANNEL_STOP");
            this.tracer.DebugTimestamp(event, unitId, spell, lineId, spellId);
            let now = GetTime();
            let [spellcast, index] = this.GetSpellcast(spell, spellId, undefined, now);
            if (spellcast && spellcast.channel) {
                this.tracer.Debug("Finished channelling spell %s (%d) queued at %s.", spell, spellId, spellcast.queued);
                spellcast.stop = now;
                this.UpdateLastSpellcast(now, spellcast);
                let targetGUID = spellcast.target;
                tremove(this.lastSpell.queue, index);
                self_pool.Release(spellcast);
                this.ovale.needRefresh();
                this.module.SendMessage("Ovale_SpellFinished", now, spellId, targetGUID, "hit");
            }
            this.profiler.StopProfiling("OvaleFuture_UNIT_SPELLCAST_CHANNEL_STOP");
        }
    }
    private UNIT_SPELLCAST_CHANNEL_UPDATE = (event: string, unitId: string, lineId: number, spellId: number) => {
        if ((unitId == "player" || unitId == "pet") && !WHITE_ATTACK[spellId]) {
            let spell = this.ovaleSpellBook.GetSpellName(spellId);
            this.profiler.StartProfiling("OvaleFuture_UNIT_SPELLCAST_CHANNEL_UPDATE");
            this.tracer.DebugTimestamp(event, unitId, spell, lineId, spellId);
            let now = GetTime();
            let [spellcast] = this.GetSpellcast(spell, spellId, undefined, now);
            if (spellcast && spellcast.channel) {
                let [name, , , startTime, endTime] = UnitChannelInfo(unitId);
                if (name == spell) {
                    startTime = startTime / 1000;
                    endTime = endTime / 1000;
                    let delta = endTime - spellcast.stop;
                    spellcast.start = startTime;
                    spellcast.stop = endTime;
                    this.tracer.Debug("Updating channelled spell %s (%d) to ending = %s (+%s).", spell, spellId, endTime, delta);
                    this.ovale.needRefresh();
                } else if (!name) {
                    this.tracer.Debug("Warning: not channelling a spell.");
                } else {
                    this.tracer.Debug("Warning: delaying unexpected channelled spell %s.", name);
                }
            } else {
                this.tracer.Debug("Warning: no queued, channelled spell %s (%d) found to update.", spell, spellId);
            }
            this.profiler.StopProfiling("OvaleFuture_UNIT_SPELLCAST_CHANNEL_UPDATE");
        }
    }
    private UNIT_SPELLCAST_DELAYED = (event: string, unitId: string, lineId: string, spellId: number) => {
        if ((unitId == "player" || unitId == "pet") && !WHITE_ATTACK[spellId]) {
            let spell = this.ovaleSpellBook.GetSpellName(spellId);
            this.profiler.StartProfiling("OvaleFuture_UNIT_SPELLCAST_DELAYED");
            this.tracer.DebugTimestamp(event, unitId, spell, lineId, spellId);
            let now = GetTime();
            let [spellcast] = this.GetSpellcast(spell, spellId, lineId, now);
            if (spellcast) {
                let [name, , , startTime, endTime, , castId] = UnitCastingInfo(unitId);
                if (lineId == castId && name == spell) {
                    startTime = startTime / 1000;
                    endTime = endTime / 1000;
                    let delta = endTime - spellcast.stop;
                    spellcast.start = startTime;
                    spellcast.stop = endTime;
                    this.tracer.Debug("Delaying spell %s (%d) to ending = %s (+%s).", spell, spellId, endTime, delta);
                    this.ovale.needRefresh();
                } else if (!name) {
                    this.tracer.Debug("Warning: not casting a spell.");
                } else {
                    this.tracer.Debug("Warning: delaying unexpected spell %s.", name);
                }
            } else {
                this.tracer.Debug("Warning: no queued spell %s (%d) found to delay.", spell, spellId);
            }
            this.profiler.StopProfiling("OvaleFuture_UNIT_SPELLCAST_DELAYED");
        }
    }
    private UNIT_SPELLCAST_SENT = (event: string, unitId: string, targetName: string, lineId: number, spellId: number) => {
        if ((unitId == "player" || unitId == "pet") && !WHITE_ATTACK[spellId]) {
            let spell = this.ovaleSpellBook.GetSpellName(spellId);
            this.profiler.StartProfiling("OvaleFuture_UNIT_SPELLCAST_SENT");
            this.tracer.DebugTimestamp(event, unitId, spell, targetName, lineId);
            let now = GetTime();
            let caster = this.ovaleGuid.UnitGUID(unitId);
            let spellcast = self_pool.Get();
            spellcast.lineId = lineId;
            spellcast.caster = caster;
            spellcast.spellName = spell || "Unknown spell";
            spellcast.queued = now;
            insert(this.lastSpell.queue, spellcast);
            if (targetName == "") {
                this.tracer.Debug("Queueing (%d) spell %s with no target.", lualength(this.lastSpell.queue), spell);
            } else {
                spellcast.targetName = targetName;
                let [targetGUID, nextGUID] = this.ovaleGuid.NameGUID(targetName);
                if (nextGUID) {
                    let name = this.ovaleGuid.UnitName("target");
                    if (name == targetName) {
                        targetGUID = this.ovaleGuid.UnitGUID("target");
                    } else {
                        name = this.ovaleGuid.UnitName("focus");
                        if (name == targetName) {
                            targetGUID = this.ovaleGuid.UnitGUID("focus");
                        } else if (UnitExists("mouseover")) {
                            name = UnitName("mouseover");
                            if (name == targetName) {
                                targetGUID = UnitGUID("mouseover");
                            }
                        }
                    }
                    spellcast.target = targetGUID || "unknown";
                    this.tracer.Debug("Queueing (%d) spell %s to %s (possibly %s).", lualength(this.lastSpell.queue), spell, targetName, targetGUID);
                } else {
                    spellcast.target = targetGUID || "unknown";
                    this.tracer.Debug("Queueing (%d) spell %s to %s (%s).", lualength(this.lastSpell.queue), spell, targetName, targetGUID);
                }
            }
            this.SaveSpellcastInfo(spellcast, now);
            this.profiler.StopProfiling("OvaleFuture_UNIT_SPELLCAST_SENT");
        }
    }
    private UNIT_SPELLCAST_START = (event: string, unitId: string, lineId: string, spellId: number) => {
        if ((unitId == "player" || unitId == "pet") && !WHITE_ATTACK[spellId]) {
            let spellName = this.ovaleSpellBook.GetSpellName(spellId);
            this.profiler.StartProfiling("OvaleFuture_UNIT_SPELLCAST_START");
            this.tracer.DebugTimestamp(event, unitId, spellName, lineId, spellId);
            let now = GetTime();
            let [spellcast] = this.GetSpellcast(spellName, spellId, lineId, now);
            if (spellcast) {
                let [name, , , startTime, endTime, , castId] = UnitCastingInfo(unitId);
                if (lineId == castId && name == spellName) {
                    startTime = startTime / 1000;
                    endTime = endTime / 1000;
                    spellcast.spellId = spellId;
                    spellcast.start = startTime;
                    spellcast.stop = endTime;
                    spellcast.channel = false;
                    let delta = now - spellcast.queued;
                    this.tracer.Debug("Casting spell %s (%d): start = %s (+%s), ending = %s.", spellName, spellId, startTime, delta, endTime);
                    let [auraId, auraGUID] = this.GetAuraFinish(spellId, spellcast.target, now);
                    if (auraId && auraGUID) {
                        spellcast.auraId = auraId;
                        spellcast.auraGUID = auraGUID;
                        this.tracer.Debug("Spell %s (%d) will finish after updating aura %d on %s.", spellName, spellId, auraId, auraGUID);
                    }
                    this.SaveSpellcastInfo(spellcast, now);
                    this.UpdateLastSpellcast(now, spellcast);
                    this.ovale.needRefresh();
                } else if (!name) {
                    this.tracer.Debug("Warning: not casting a spell.");
                } else {
                    this.tracer.Debug("Warning: casting unexpected spell %s.", name);
                }
            } else {
                this.tracer.Debug("Warning: casting spell %s (%d) without previous sent data.", spellName, spellId);
            }
            this.profiler.StopProfiling("OvaleFuture_UNIT_SPELLCAST_START");
        }
    }
    private UNIT_SPELLCAST_SUCCEEDED = (event: string, unitId: string, lineId: number, spellId: number) => {
        if ((unitId == "player" || unitId == "pet") && !WHITE_ATTACK[spellId]) {
            let spell = this.ovaleSpellBook.GetSpellName(spellId);
            this.profiler.StartProfiling("OvaleFuture_UNIT_SPELLCAST_SUCCEEDED");
            this.tracer.DebugTimestamp(event, unitId, spell, lineId, spellId);
            let now = GetTime();
            let [spellcast, index] = this.GetSpellcast(spell, spellId, lineId, now);
            if (spellcast) {
                let success = false;
                if (!spellcast.success && spellcast.start && spellcast.stop && !spellcast.channel) {
                    this.tracer.Debug("Succeeded casting spell %s (%d) at %s, now in flight.", spell, spellId, spellcast.stop);
                    spellcast.success = now;
                    this.UpdateSpellcastSnapshot(spellcast, now);
                    success = true;
                } else {
                    let name = UnitChannelInfo(unitId);
                    if (!name) {
                        let now = GetTime();
                        spellcast.spellId = spellId;
                        spellcast.start = now;
                        spellcast.stop = now;
                        spellcast.channel = false;
                        spellcast.success = now;
                        let delta = now - spellcast.queued;
                        this.tracer.Debug("Instant-cast spell %s (%d): start = %s (+%s).", spell, spellId, now, delta);
                        let [auraId, auraGUID] = this.GetAuraFinish(spellId, spellcast.target, now);
                        if (auraId && auraGUID) {
                            spellcast.auraId = auraId;
                            spellcast.auraGUID = auraGUID;
                            this.tracer.Debug("Spell %s (%d) will finish after updating aura %d on %s.", spell, spellId, auraId, auraGUID);
                        }
                        this.SaveSpellcastInfo(spellcast, now);
                        success = true;
                    } else {
                        this.tracer.Debug("Succeeded casting spell %s (%d) but it is channelled.", spell, spellId);
                    }
                }
                if (success) {
                    let targetGUID = spellcast.target;
                    this.UpdateLastSpellcast(now, spellcast);
                    this.next.PushGCDSpellId(spellcast.spellId);
                    this.UpdateCounters(spellId, spellcast.stop, targetGUID);
                    let finished = false;
                    let finish = "miss";
                    if (!spellcast.targetName) {
                        this.tracer.Debug("Finished spell %s (%d) with no target queued at %s.", spell, spellId, spellcast.queued);
                        finished = true;
                        finish = "hit";
                    } else if (targetGUID == this.ovale.playerGUID && this.ovaleSpellBook.IsHelpfulSpell(spellId)) {
                        this.tracer.Debug("Finished helpful spell %s (%d) cast on player queued at %s.", spell, spellId, spellcast.queued);
                        finished = true;
                        finish = "hit";
                    }
                    if (finished) {
                        tremove(this.lastSpell.queue, index);
                        self_pool.Release(spellcast);
                        this.ovale.needRefresh();
                        this.module.SendMessage("Ovale_SpellFinished", now, spellId, targetGUID, finish);
                    }
                }
            } else {
                this.tracer.Debug("Warning: no queued spell %s (%d) found to successfully complete casting.", spell, spellId);
            }
            this.profiler.StopProfiling("OvaleFuture_UNIT_SPELLCAST_SUCCEEDED");
        }
    }
    private Ovale_AuraAdded = (event: string, atTime: number, guid: string, auraId: string, caster: string) => {
        if (guid == this.ovale.playerGUID) {
            self_timeAuraAdded = atTime;
            this.UpdateSpellcastSnapshot(this.lastSpell.lastGCDSpellcast, atTime);
            this.UpdateSpellcastSnapshot(this.current.lastOffGCDSpellcast, atTime);
        }
    }
    private Ovale_AuraChanged = (event: string, atTime: number, guid: string, auraId: string, caster: string) => {
        this.tracer.DebugTimestamp("Ovale_AuraChanged", event, atTime, guid, auraId, caster);
        if (caster == this.ovale.playerGUID) {
            // let's check if the aura matches a spell we have in flight, if so we can end it
            let anyFinished = false;
            for (let i = lualength(this.lastSpell.queue); i >= 1; i += -1) {
                let spellcast = this.lastSpell.queue[i];
                if (spellcast.success && (spellcast.auraId == auraId)) {
                    if (this.FinishSpell(spellcast, "Ovale_AuraChanged", caster, this.ovale.playerGUID, spellcast.targetName, guid, spellcast.spellId, spellcast.spellName, "hit", i)) {
                        anyFinished = true;
                    }
                }
            }
            if (!anyFinished) {
                this.tracer.Debug("No spell found to finish for auraId %d", auraId);
            }
        }
    }
    private UnitSpellcastEnded = (event: string, unitId: string, lineId: number, spellId: number) => {
        if ((unitId == "player" || unitId == "pet") && !WHITE_ATTACK[spellId]) {
            if(event == 'UNIT_SPELLCAST_INTERRUPTED'){
                this.next.lastGCDSpellId = 0;
            }
            let spellName = this.ovaleSpellBook.GetSpellName(spellId);
            this.profiler.StartProfiling("OvaleFuture_UnitSpellcastEnded");
            this.tracer.DebugTimestamp(event, unitId, spellName, lineId, spellId);
            let now = GetTime();
            let [spellcast, index] = this.GetSpellcast(spellName, spellId, lineId, now);
            if (spellcast) {
                this.tracer.Debug("End casting spell %s (%d) queued at %s due to %s.", spellName, spellId, spellcast.queued, event);
                if (!spellcast.success) {
                    this.tracer.Debug("Remove spell from queue because there was no success before");
                    tremove(this.lastSpell.queue, index);
                    self_pool.Release(spellcast);
                    this.ovale.needRefresh();
                }
            } else if (lineId) {
                this.tracer.Debug("Warning: no queued spell %s (%d) found to end casting.", spellName, spellId);
            }
            this.profiler.StopProfiling("OvaleFuture_UnitSpellcastEnded");
        }
    }
    GetSpellcast(spellName: string | undefined, spellId: number, lineId: number | undefined | string, atTime: number):[SpellCast | undefined, number] {
        this.profiler.StartProfiling("OvaleFuture_GetSpellcast");
        let spellcast: SpellCast | undefined = undefined;
        let index: number = 0;
        if (!lineId || lineId != "") {
            for (const [i, sc] of ipairs(this.lastSpell.queue)) {
                if (!lineId || sc.lineId == lineId) {
                    if (spellId && sc.spellId == spellId) {
                        spellcast = sc;
                        index = i;
                        break;
                    } else if (spellName) {
                        let spellName = sc.spellName || this.ovaleSpellBook.GetSpellName(spellId);
                        if (spellName == spellName) {
                            spellcast = sc;
                            index = i;
                            break;
                        }
                    }
                }
            }
        }
        if (spellcast) {
            spellName = spellName || spellcast.spellName || this.ovaleSpellBook.GetSpellName(spellId);
            if (spellcast.targetName) {
                this.tracer.Debug("Found spellcast for %s to %s queued at %f.", spellName, spellcast.targetName, spellcast.queued);
            } else {
                this.tracer.Debug("Found spellcast for %s with no target queued at %f.", spellName, spellcast.queued);
            }
        }
        this.profiler.StopProfiling("OvaleFuture_GetSpellcast");
        return [spellcast, index];
    }
    GetAuraFinish(spellId: number, targetGUID: string, atTime: number): [string|number|undefined, string|undefined] {
        this.profiler.StartProfiling("OvaleFuture_GetAuraFinish");
        let auraId, auraGUID;
        let si = this.ovaleData.spellInfo[spellId];
        if (si && si.aura) {
            for (const [, unitId] of ipairs(SPELLCAST_AURA_ORDER)) {
                for (const [, auraList] of kpairs(si.aura[unitId])) {
                    for (const [id, spellData] of kpairs(auraList)) {
                        let [verified, value, ] = this.ovaleData.CheckSpellAuraData(id, spellData, atTime, targetGUID);
                        if (verified && (SPELLAURALIST_AURA_VALUE[<string>value] || type(value) == "number" && value > 0)) {
                            auraId = id;
                            auraGUID = this.ovaleGuid.UnitGUID(unitId);
                            break;
                        }
                    }
                    if (auraId) {
                        break;
                    }
                }
                if (auraId) {
                    break;
                }
            }
        }
        this.profiler.StopProfiling("OvaleFuture_GetAuraFinish");
        return [auraId, auraGUID];
    }

    SaveSpellcastInfo(spellcast: SpellCast, atTime: number) {
        this.profiler.StartProfiling("OvaleFuture_SaveSpellcastInfo");
        this.tracer.Debug("    Saving information from %s to the spellcast for %s.", atTime, spellcast.spellName);
        if (spellcast.spellId) {
            spellcast.damageMultiplier = this.GetDamageMultiplier(spellcast.spellId, spellcast.target, atTime);
        }
        for (const [, mod] of pairs(this.lastSpell.modules)) {
            let func = mod.SaveSpellcastInfo;
            if (func) {
                func(spellcast, atTime);
            }
        }
        this.profiler.StopProfiling("OvaleFuture_SaveSpellcastInfo");
    }
    GetDamageMultiplier(spellId: number, targetGUID: string, atTime: number) {
        let damageMultiplier = 1;
        let si = this.ovaleData.spellInfo[spellId];
        if (si && si.aura && si.aura.damage) {
            for (const [filter, auraList] of kpairs(si.aura.damage)) {
                for (const [auraId, spellData] of pairs(auraList)) {
                    let index, multiplier: number;
                    let verified;
                    if (isLuaArray(spellData)) {
                        multiplier = <number>spellData[1];
                        index = 2;
                        verified = this.requirement.CheckRequirements(spellId, atTime, spellData, index, targetGUID);
                    } else {
                        multiplier = spellData;
                        verified = true;
                    }
                    if (verified) {
                        let aura = this.ovaleAura.GetAuraByGUID(this.ovale.playerGUID, auraId, filter, false, atTime);
                        if (aura && this.ovaleAura.IsActiveAura(aura, atTime)) {
                            let siAura = this.ovaleData.spellInfo[auraId];
                            if (siAura && siAura.stacking && siAura.stacking > 0) {
                                multiplier = 1 + (multiplier - 1) * aura.stacks;
                            }
                            damageMultiplier = damageMultiplier * multiplier;
                        }
                    }
                }
            }
        }
        return damageMultiplier;
    }
    UpdateCounters(spellId: number, atTime: number, targetGUID: string) {
        return this.UpdateStateCounters(this.GetState(atTime), spellId, atTime, targetGUID);
    }

    IsActive(spellId: number) {
        for (const [, spellcast] of ipairs(this.lastSpell.queue)) {
            if (spellcast.spellId == spellId && spellcast.start) {
                return true;
            }
        }
        return false;
    }

    InFlight(spellId: number) {
        return this.IsActive(spellId);
    }

    UpdateLastSpellcast(atTime: number, spellcast: SpellCast) {
        this.profiler.StartProfiling("OvaleFuture_UpdateLastSpellcast");
        this.current.lastCastTime[spellcast.spellId] = atTime;
        if (spellcast.offgcd) {
            this.tracer.Debug("    Caching spell %s (%d) as most recent off-GCD spellcast.", spellcast.spellName, spellcast.spellId);
            for (const [k, v] of kpairs(spellcast)) {
                (<any>this.current.lastOffGCDSpellcast)[k] = v;
            }
            this.lastSpell.lastSpellcast = this.current.lastOffGCDSpellcast;
            this.next.lastOffGCDSpellcast = this.current.lastOffGCDSpellcast
        } else {
            this.tracer.Debug("    Caching spell %s (%d) as most recent GCD spellcast.", spellcast.spellName, spellcast.spellId);
            for (const [k, v] of kpairs(spellcast)) {
                (<any>this.lastSpell.lastGCDSpellcast)[k] = v;
            }
            this.lastSpell.lastSpellcast = this.lastSpell.lastGCDSpellcast;
            this.next.lastGCDSpellId = this.lastSpell.lastGCDSpellcast.spellId
        }
        this.profiler.StopProfiling("OvaleFuture_UpdateLastSpellcast");
    }
    UpdateSpellcastSnapshot(spellcast: SpellCast, atTime: number) {
        if (spellcast.queued && (!spellcast.snapshotTime || (spellcast.snapshotTime < atTime && atTime < spellcast.stop + 1))) {
            if (spellcast.targetName) {
                this.tracer.Debug("    Updating to snapshot from %s for spell %s to %s (%s) queued at %s.", atTime, spellcast.spellName, spellcast.targetName, spellcast.target, spellcast.queued);
            } else {
                this.tracer.Debug("    Updating to snapshot from %s for spell %s with no target queued at %s.", atTime, spellcast.spellName, spellcast.queued);
            }
            // TODO strange, why current?
            this.ovalePaperDoll.UpdateSnapshot(spellcast, this.ovalePaperDoll.current, true);
            if (spellcast.spellId) {
                spellcast.damageMultiplier = this.GetDamageMultiplier(spellcast.spellId, spellcast.target, atTime);
                if (spellcast.damageMultiplier != 1) {
                    this.tracer.Debug("        persistent multiplier = %f", spellcast.damageMultiplier);
                }
            }
        }
    }

    GetCounter(id: number, atTime: number) {
        return this.GetState(atTime).counter[id] || 0;
    }

    TimeOfLastCast(spellId: number, atTime: number) {
        if (!atTime) return this.current.lastCastTime[spellId];
        return this.next.lastCastTime[spellId] || this.current.lastCastTime[spellId] || 0;
    }

    IsChanneling(atTime: number) {
        return this.GetState(atTime).IsChanneling(atTime);
    }

    GetCurrentCast(atTime: number) {
        if (atTime && this.next.currentCast && this.next.currentCast.start <= atTime && this.next.currentCast.stop >= atTime) {
            return this.next.currentCast;
        }

        for (const [, value] of ipairs(this.lastSpell.queue)) {
            if (value.start && value.start <= atTime && (!value.stop || value.stop >= atTime)) {
                return value;
            }
        }
    }

    GetGCD(spellId?: number, atTime?: number, targetGUID?: string) {
        spellId = spellId || this.next.currentCast.spellId;
        if (!atTime) {
            if (this.next.currentCast.stop && this.next.currentCast.stop > this.baseState.next.currentTime) {
                atTime = this.next.currentCast.stop;
            } else {
                atTime = this.baseState.next.currentTime || this.baseState.current.currentTime;
            }
        }
        targetGUID = targetGUID || this.ovaleGuid.UnitGUID(this.baseState.next.defaultTarget);
        let gcd = spellId && this.ovaleData.GetSpellInfoProperty(spellId, atTime, "gcd", targetGUID);
        if (!gcd) {
            let haste: HasteType;
            [gcd, haste] = this.ovaleCooldown.GetBaseGCD();
            if (this.ovale.playerClass == "MONK" && this.ovalePaperDoll.IsSpecialization("mistweaver")) {
                gcd = 1.5;
                haste = "spell";
            } else if (this.ovale.playerClass == "DRUID") {
                if (this.ovaleStance.IsStance("druid_cat_form", atTime)) {
                    gcd = 1.0;
                    haste = "none";
                }
            }
            let gcdHaste = spellId && this.ovaleData.GetSpellInfoProperty(spellId, atTime, "gcd_haste", targetGUID);
            if (gcdHaste) {
                haste = gcdHaste;
            } else {
                let siHaste = spellId && this.ovaleData.GetSpellInfoProperty(spellId, atTime, "haste", targetGUID);
                if (siHaste) {
                    haste = siHaste;
                }
            }
            let multiplier = this.ovalePaperDoll.GetHasteMultiplier(haste, this.ovalePaperDoll.next);
            gcd = gcd / multiplier;
            gcd = (gcd > 0.750) && gcd || 0.750;
        }
        return gcd;
    }

    InitializeState() {
        this.next.lastCast = {}
        this.next.counter = {}
    }
    ResetState() {
        this.profiler.StartProfiling("OvaleFuture_ResetState");
        const now = this.baseState.next.currentTime;
        this.tracer.Log("Reset state with current time = %f", now);
        this.next.inCombat = this.current.inCombat;
        this.next.combatStartTime = this.current.combatStartTime || 0;
        this.next.nextCast = now;
        wipe(this.next.lastCast);
        wipe(OvaleFutureClass.staticSpellcast);
        this.next.currentCast = OvaleFutureClass.staticSpellcast;
        let reason = "";
        let [start, duration] = this.ovaleCooldown.GetGlobalCooldown(now);
        if (start && start > 0) {
            let ending = start + duration;
            if (this.next.nextCast < ending) {
                this.next.nextCast = ending;
                reason = " (waiting for GCD)";
            }
        }
        let lastGCDSpellcastFound, lastOffGCDSpellcastFound, lastSpellcastFound;
        for (let i = lualength(this.lastSpell.queue); i >= 1; i += -1) {
            let spellcast = this.lastSpell.queue[i];
            if (spellcast.spellId && spellcast.start) {
                this.tracer.Log("    Found cast %d of spell %s (%d), start = %s, stop = %s.", i, spellcast.spellName, spellcast.spellId, spellcast.start, spellcast.stop);
                if (!lastSpellcastFound) {
                    // this.next.lastCast = spellcast;
                    if (spellcast.start && spellcast.stop && spellcast.start <= now && now < spellcast.stop) {
                        this.next.currentCast = spellcast
                    }
                    lastSpellcastFound = true;
                }
                if (!lastGCDSpellcastFound && !spellcast.offgcd) {
                    // this.next.PushGCDSpellId(spellcast.spellId);
                    if (spellcast.stop && this.next.nextCast < spellcast.stop) {
                        this.next.nextCast = spellcast.stop;
                        reason = " (waiting for spellcast)";
                    }
                    lastGCDSpellcastFound = true;
                }
                if (!lastOffGCDSpellcastFound && spellcast.offgcd) {
                    this.next.lastOffGCDSpellcast = spellcast;
                    lastOffGCDSpellcastFound = true;
                }
            }
            if (lastGCDSpellcastFound && lastOffGCDSpellcastFound && lastSpellcastFound) {
                break;
            }
        }
        if (!lastSpellcastFound) {
            let spellcast = this.lastSpell.lastSpellcast;
            if (spellcast) {
                // this.next.lastCast = spellcast;
                if (spellcast.start && spellcast.stop && spellcast.start <= now && now < spellcast.stop) {
                    this.next.currentCast = spellcast;
                }
            }
        }
        if (!lastGCDSpellcastFound) {
            let spellcast = this.lastSpell.lastGCDSpellcast;
            if (spellcast) {
                this.next.lastGCDSpellcast = spellcast;
                if (spellcast.stop && this.next.nextCast < spellcast.stop) {
                    this.next.nextCast = spellcast.stop;
                    reason = " (waiting for spellcast)";
                }
            }
        }
        if (!lastOffGCDSpellcastFound) {
            this.next.lastOffGCDSpellcast = this.current.lastOffGCDSpellcast;
        }
        // OvaleFuture.Log("    lastSpellId = %s, lastGCDSpellId = %s, lastOffGCDSpellId = %s", this.next.lastSpellId, this.lastGCDSpellId, this.lastOffGCDSpellId);
        this.tracer.Log("    nextCast = %f%s", this.next.nextCast, reason);
        for (const [k, v] of pairs(this.current.counter)) {
            this.next.counter[k] = v;
        }
        this.profiler.StopProfiling("OvaleFuture_ResetState");
    }
    CleanState() {
        for (const [k] of pairs(this.next.lastCast)) {
            delete this.next.lastCast[k];
        }
        for (const [k] of pairs(this.next.counter)) {
            delete this.next.counter[k];
        }
    }
    ApplySpellStartCast(spellId: number, targetGUID: string, startCast: number, endCast: number, channel: boolean, spellcast: SpellCast) {
        this.profiler.StartProfiling("OvaleFuture_ApplySpellStartCast");
        if (channel) {
            this.UpdateCounters(spellId, startCast, targetGUID);
        }
        this.profiler.StopProfiling("OvaleFuture_ApplySpellStartCast");
    }
    ApplySpellAfterCast(spellId: number, targetGUID: string, startCast: number, endCast: number, channel: boolean, spellcast: SpellCast) {
        this.profiler.StartProfiling("OvaleFuture_ApplySpellAfterCast");
        if (!channel) {
            this.UpdateCounters(spellId, endCast, targetGUID);
        }
        this.profiler.StopProfiling("OvaleFuture_ApplySpellAfterCast");
    }

    static staticSpellcast: SpellCast = createSpellCast();

    ApplySpell(spellId:number, targetGUID:string, startCast:number, endCast?:number, channel?: boolean, spellcast?: SpellCast) {
        channel = channel || false;
        this.profiler.StartProfiling("OvaleFuture_state_ApplySpell");
        if (spellId) {
            if (!targetGUID) {
                targetGUID = this.ovale.playerGUID;
            }
            let castTime;
            if (startCast && endCast) {
                castTime = endCast - startCast;
            } else {
                castTime = this.ovaleSpellBook.GetCastTime(spellId) || 0;
                startCast = startCast || this.next.nextCast;
                endCast = endCast || (startCast + castTime);
            }
            if (!spellcast) {
                spellcast = OvaleFutureClass.staticSpellcast;
                wipe(spellcast);
                spellcast.caster = this.ovale.playerGUID;
                spellcast.spellId = spellId;
                spellcast.spellName = this.ovaleSpellBook.GetSpellName(spellId) || "unknown spell";
                spellcast.target = targetGUID;
                spellcast.targetName = this.ovaleGuid.GUIDName(targetGUID) || "target";
                spellcast.start = startCast;
                spellcast.stop = endCast;
                spellcast.channel = channel;
                this.ovalePaperDoll.UpdateSnapshot(spellcast, this.ovalePaperDoll.next);
                let atTime = channel && startCast || endCast;
                for (const [, mod] of pairs(this.lastSpell.modules)) {
                    let func = mod.SaveSpellcastInfo;
                    if (func) {
                        func(spellcast, atTime, this.ovalePaperDoll.next);
                    }
                }
            }
            // this.next.lastCast = this.next.currentCast;
            this.next.currentCast = spellcast;
            this.next.lastCast[spellId] = endCast;
            let gcd = this.GetGCD(spellId, startCast, targetGUID);
            let nextCast = (castTime > gcd) && endCast || (startCast + gcd);
            if (this.next.nextCast < nextCast) {
                this.next.nextCast = nextCast;
            }
            // if (gcd > 0) {
            //     this.next.PushGCDSpellId(spellId);
            // } else {
            //     this.next.lastOffGCDSpellcast = this.next.currentCast;
            // }
            // let now = GetTime();
            // if (startCast >= now) {
            //     baseState.next.currentTime = startCast + SIMULATOR_LAG;
            // } else {
            //     baseState.next.currentTime = now;
            // }
            this.tracer.Log("Apply spell %d at %f currentTime=%f nextCast=%f endCast=%f targetGUID=%s", spellId, startCast, this.baseState.next.currentTime, nextCast, endCast, targetGUID);
            if (!this.next.inCombat && this.ovaleSpellBook.IsHarmfulSpell(spellId)) {
                this.next.inCombat = true;
                if (channel) {
                    this.next.combatStartTime = startCast;
                } else {
                    this.next.combatStartTime = endCast;
                }
            }
            if (startCast > this.baseState.next.currentTime) {
                this.ovaleState.ApplySpellStartCast(spellId, targetGUID, startCast, endCast, channel, spellcast);
            }
            if (endCast > this.baseState.next.currentTime) {
                this.ovaleState.ApplySpellAfterCast(spellId, targetGUID, startCast, endCast, channel, spellcast);
            }
            this.ovaleState.ApplySpellOnHit(spellId, targetGUID, startCast, endCast, channel, spellcast);
        }
        this.profiler.StopProfiling("OvaleFuture_state_ApplySpell");
    }

    ApplyInFlightSpells() {
        this.profiler.StartProfiling("OvaleFuture_ApplyInFlightSpells");
        let now = GetTime();
        let index = 1;
        while (index <= lualength(this.lastSpell.queue)) {
            let spellcast = this.lastSpell.queue[index];
            if (spellcast.stop) {
                let isValid = false;
                let description;
                if (now < spellcast.stop) {
                    isValid = true;
                    description = spellcast.channel && "channelling" || "being cast";
                } else if (now < spellcast.stop + 5) {
                    isValid = true;
                    description = "in flight";
                }
                if (isValid) {
                    if (spellcast.target) {
                        this.tracer.Log("Active spell %s (%d) is %s to %s (%s), now=%f, endCast=%f, start=%f", spellcast.spellName, spellcast.spellId, description, spellcast.targetName, spellcast.target, now, spellcast.stop, spellcast.start);
                    } else {
                        this.tracer.Log("Active spell %s (%d) is %s, now=%f, endCast=%f, start=%f", spellcast.spellName, spellcast.spellId, description, now, spellcast.stop, spellcast.start);
                    }
                    this.ApplySpell(spellcast.spellId, spellcast.target, spellcast.start, spellcast.stop, spellcast.channel, spellcast);
                } else {
                    if (spellcast.target) {
                        this.tracer.Debug("Warning: removing active spell %s (%d) to %s (%s) that should have finished.", spellcast.spellName, spellcast.spellId, spellcast.targetName, spellcast.target);
                    } else {
                        this.tracer.Debug("Warning: removing active spell %s (%d) that should have finished.", spellcast.spellName, spellcast.spellId);
                    }
                    remove(this.lastSpell.queue, index);
                    self_pool.Release(spellcast);
                    index = index - 1;
                }
            }
            index = index + 1;
        }
        this.profiler.StopProfiling("OvaleFuture_ApplyInFlightSpells");
    }

    CombatRequirement = (spellId: number, atTime: number, requirement: string, tokens: Tokens, index: number, targetGUID: string | undefined):[boolean, string, number] => {
        let verified = false;
        let combatFlag = tokens[index];
        index = index + 1;

        if(combatFlag) {
            combatFlag = tonumber(combatFlag);
            if(combatFlag == 1 && this.IsInCombat(atTime) || combatFlag != 1 && !this.IsInCombat(atTime))
            {
                verified = true;
            }
            let result = verified && "passed" || "FAILED";
            if (combatFlag == 1) {
                this.tracer.Log("    Require combat at time=%f: %s", atTime, result);
            } else {
                this.tracer.Log("    Require NOT combat at time=%f: %s", atTime, result);
            }
        } else {
            this.ovale.OneTimeMessage("Warning: requirement '%s' is missing an argument.", requirement);
        }
        return [verified, requirement, index];
    }
}


text:
require("../../es/test/kit/skip")();
global.skipTests = {};

describe("regenerator with abstract interface", function() {
  describe("with default options", function() {
    global.skipTests = {
      // it doesn't capture `this` but it uses it for context passing
      "shouldn't capture this when not needed": true
    };
    require("./default/links/regenerator");
  });
  describe("with top level handlers", function() {
    global.skipTests = {
      // it doesn't capture `this` but it uses it for context passing
      "shouldn't capture this when not needed": true,
      // not supporting ES object model
      "@@iterator": true,
      isGeneratorFunction: true,
      "generator function prototype": true,
      "should get a reference to the caught error": true,
      "function declaration hoisting": true,
      // not implemented arguments object aliasing
      "should alias function parameters": true,
      // preserved but moved out of function
      "should be preserved in generated code": true,
      // not implemented arguments object aliasing
      "should alias function parameters": true,
      // preserved but moved out of function
      "should be preserved in generated code": true,
      // BUG: classes aren't really supported
      "should support super.method(...) in async methods": true
    };
    require("./topLevel/links/regenerator");
  });
});

redpajama_set_name: RedPajamaGithub


text:
package com.intellij.ide.projectView.impl.nodes;

import com.intellij.ide.projectView.PresentationData;
import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.ide.projectView.ViewSettings;
import com.intellij.ide.projectView.impl.ModuleGroup;
import com.intellij.ide.projectView.impl.ProjectViewPane;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.openapi.application.Application;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import consulo.logging.Logger;

import javax.annotation.Nonnull;
import java.util.*;

public abstract class AbstractProjectNode extends ProjectViewNode<Project> {
  private static final Logger LOG = Logger.getInstance(AbstractProjectNode.class);

  protected AbstractProjectNode(Project project, Project value, ViewSettings viewSettings) {
    super(project, value, viewSettings);
  }

  protected Collection<AbstractTreeNode> modulesAndGroups(Module[] modules) {
    Map<String, List<Module>> groups = new HashMap<>();
    List<Module> nonGroupedModules = new ArrayList<>(Arrays.asList(modules));
    for (final Module module : modules) {
      final String[] path = ModuleManager.getInstance(getProject()).getModuleGroupPath(module);
      if (path != null) {
        final String topLevelGroupName = path[0];
        List<Module> moduleList = groups.get(topLevelGroupName);
        if (moduleList == null) {
          moduleList = new ArrayList<>();
          groups.put(topLevelGroupName, moduleList);
        }
        moduleList.add(module);
        nonGroupedModules.remove(module);
      }
    }
    List<AbstractTreeNode> result = new ArrayList<>();
    try {
      for (String groupPath : groups.keySet()) {
        result.add(createModuleGroupNode(new ModuleGroup(new String[]{groupPath})));
      }
      for (Module module : nonGroupedModules) {
        result.add(createModuleGroup(module));
      }
    }
    catch (ProcessCanceledException e) {
      throw e;
    }
    catch (Exception e) {
      LOG.error(e);
      return new ArrayList<>();
    }
    return result;
  }

  protected abstract AbstractTreeNode createModuleGroup(final Module module);

  protected abstract AbstractTreeNode createModuleGroupNode(final ModuleGroup moduleGroup);

  @Override
  public void update(PresentationData presentation) {
    presentation.setIcon(Application.get().getIcon());
    presentation.setPresentableText(getProject().getName());
  }

  @Override
  public String getTestPresentation() {
    return "Project";
  }

  @Override
  public boolean contains(@Nonnull VirtualFile file) {
    return ProjectViewPane.canBeSelectedInProjectView(myProject, file);
  }
}


text:
Gazoozle

Front-End Development

Gazoozle is a college-centric marketing and ad agency that was in its startup phase when I joined. I was brought in to get the ball-rolling on their web presence, while developing a website for Gazoozle as well as web assets for their clients. Some of these clients included (but not limited to) Columbia Pictures (22 Jump Street), Made Eyewear, and BPong.

Date: March 2014

Client: Gazoozle

Category: Front-End Development.

                            <button type="button" class="btn btn-primary" data-dismiss="modal"> Close Project</button>


text:
require 'test_helper'

class UsersEditTest < ActionDispatch::IntegrationTest
  def setup
    @user  = users(:yig)
    @admin = users(:cthulhu)
  end

  test 'unsuccessful edit' do
    log_in_as(@user)
    get edit_user_path(@user)
    assert_template 'users/edit'
    patch user_path(@user), params: { user: { name:                  '',
                                              email:                 'foo@invalid',
                                              password:              'foo',
                                              password_confirmation: 'bar' } }
    assert_template 'users/edit'
    assert_select 'div#error_explanation'
    assert_select 'li.error-item', count: 4
  end

  test 'successful edit' do
    log_in_as(@user)
    get edit_user_path(@user)
    assert_template 'users/edit'
    name  = 'Foo Bar'
    email = 'foo@bar.com'
    patch user_path(@user), params: { user: { name:                  name,
                                              email:                 email,
                                              password:              '',
                                              password_confirmation: '' } }
    assert_not flash.empty?
    assert_redirected_to root_or_admin_url
    @user.reload
    assert_equal name, @user.name
    assert_equal email, @user.email
  end

  test 'edit screen has right fields' do
    log_in_as(@admin)
    get edit_user_path(@admin)
    assert_template 'users/edit'
    assert_select 'input[name=?]', 'user[name]'
    assert_select 'input[name=?]', 'user[email]'
    assert_select 'input[name=?]', 'user[password]'
    assert_select 'input[name=?]', 'user[password_confirmation]'
    assert_select 'input[name=?]', 'user[admin]'
  end
end


text:
SYNONYM

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
J. Bot. 19:209. 1881 (non Salisb. 1796)

#### Original name
null

### Remarks
null


text:
<?php

namespace Pvm\ArtisanBeans\Console;

class UnpauseTubeCommand extends PauseTubeCommand
{
    protected $commandName = 'unpause';

    protected $commandArguments = '
        {tube : Tube name}
    ';

    protected $description = 'Upause the tube';

    protected $delay = 0;

    /**
     * {$@inheritdoc}.
     */
    protected function getSuccessMessage($tube)
    {
        return "Tube '$tube' has been unpaused.";
    }

    /**
     *{@inheritdoc}.
     */
    protected function parseCommandArguments()
    {
        // Override parent's parseCommandArguments
        // since we use a predefined value for $this->delay
    }
}


text:
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,600');

body {
  width: 100%;
  z-index: 1;
  min-height: 60px !important;
  font-family: 'Source Sans Pro', 'Lato', 'Helvetica Neue', Arial, Helvetica, sans-serif  !important;
  background-color: #f3faf6 !important;
}

body .container{
}

.main-content {
  padding-top: 70px;
  width: 1100px;
  margin: 0 auto;
  min-height: 100vh;
}

textarea:hover,
input:hover,
textarea:active,
input:active,
textarea:focus,
input:focus,
button:focus,
button:active,
button:hover,
label:focus,
.btn:active,
.btn.active
{
  outline:0px !important;
  -webkit-appearance:none;
}


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns:wicket="http://wicket.apache.org/dtds.data/wicket-xhtml1.4-strict.dtd" >
<head>
    <title><wicket:message key="app.title" /></title>
</head>
<body>
    <div wicket:id="siteinfo" style="padding: 5px;"/>
</body>
</html>


text:
#include "config.h"

#define NS_HandleScriptError XG_HandleScriptError

#include "xpgom/xgWindow.hh"
#include "xgIParser.hh"

#include <nsComponentManagerUtils.h>
#include <nsDOMCID.h>
#include <nsIClassInfoImpl.h>
#include <nsIDocument.h>
#include <nsIDOMDocument.h>
#include <nsIDOMElement.h>
#include <nsIDOMLocation.h>
#include <nsIDOMNavigator.h>
#include <nsIDOMScriptObjectFactory.h>
#include <nsIScriptContext.h>
#include <nsIScriptRuntime.h>
#include <nsMemory.h>
#include <nsServiceManagerUtils.h>
#include <nsStringAPI.h>
#include <nsIURL.h>
#include <nsIIOService.h>

#include <glib/gmacros.h>
#include <glib/gmessages.h>

#include <gtk/gtkmain.h>

#include "gommacros.h"

static NS_DEFINE_CID (kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);

class xgLocation : public nsIDOMLocation
{
    friend class xgWindow;
public:
    NS_DECL_ISUPPORTS
    NS_DECL_NSIDOMLOCATION

    xgLocation (xgWindow *aWindow);

private:
    ~xgLocation();

protected:
    xgWindow *mWindow;
    nsCOMPtr<nsIURI> mUri;
};

class xgWindowParserListener : public xgIParserListener
{
public:
    NS_DECL_ISUPPORTS
    NS_DECL_XGIPARSERLISTENER

    xgWindowParserListener(xgWindow *aWindow);

private:
    ~xgWindowParserListener();

protected:
    xgWindow *mWindow;
};

xgWindow::xgWindow ()
{
    memset (mGlobal, 0, sizeof (mGlobal));
}

xgWindow::~xgWindow ()
{
    /* destructor code */
}

NS_IMPL_ISUPPORTS7_CI (xgWindow,
		       nsIScriptGlobalObject,
		       nsIDOMWindow,
		       nsIDOMWindow2,
		       nsIDOMJSWindow,
		       nsIDOMWindowInternal,
		       nsISupportsWeakReference,
		       xgIWindow)

nsresult
xgWindow::Init ()
{
    nsresult rv;
    mNavigator = do_CreateInstance ("@ilovegom.org/navigator;1", &rv);
    NS_ENSURE_SUCCESS (rv, rv);

    mLocation = new xgLocation (this);
    NS_ENSURE_TRUE (mLocation, NS_ERROR_OUT_OF_MEMORY);

    mParser = do_CreateInstance ("@ilovegom.org/parser;1", &rv);
    NS_ENSURE_SUCCESS (rv, rv);

    mListener = new xgWindowParserListener (this);
    NS_ENSURE_TRUE (mListener, NS_ERROR_OUT_OF_MEMORY);

    return mLocation->Assign (NS_LITERAL_STRING ("about:blank"));
}

// nsIDOMWindowInternal
/* readonly attribute nsIDOMWindowInternal window; */
NS_IMETHODIMP
xgWindow::GetWindow (nsIDOMWindowInternal **aWindow)
{
    NS_ADDREF (*aWindow = this);
    return NS_OK;
}

/* readonly attribute nsIDOMWindowInternal self; */
NS_IMETHODIMP
xgWindow::GetSelf (nsIDOMWindowInternal **aSelf)
{
    NS_ADDREF (*aSelf = this);
    return NS_OK;
}

/* readonly attribute nsIDOMNavigator navigator; */
NS_IMETHODIMP
xgWindow::GetNavigator (nsIDOMNavigator **aNavigator)
{
    NS_IF_ADDREF (*aNavigator = mNavigator);
    return NS_OK;
}

/* readonly attribute nsIDOMLocation location; */
NS_IMETHODIMP
xgWindow::GetLocation (nsIDOMLocation **aLocation)
{
    NS_IF_ADDREF (*aLocation = mLocation);
    return NS_OK;
}

/* readonly attribute nsIDOMDocument document; */
NS_IMETHODIMP
xgWindow::GetDocument (nsIDOMDocument **aDocument)
{
    NS_IF_ADDREF (*aDocument = mDocument);
    return NS_OK;
}

/* void close (); */
NS_IMETHODIMP
xgWindow::Close()
{
    gtk_main_quit ();
    mDocument = NULL;
    return NS_OK;
}

// nsIDOMJSWindow
/* void dump (in DOMString str); */
NS_IMETHODIMP xgWindow::Dump(const nsAString &str)
{
    GOM_ASTRING_TO_GSTRING_RETURN (gstr, str, NS_ERROR_INVALID_ARG);
    g_message ("JAVASCRIPT: %s\n", gstr);
    return NS_OK;
}

/* xgIWindow */
/* void main (); */
NS_IMETHODIMP
xgWindow::Main ()
{
    gtk_main ();
    return NS_OK;
}

nsresult
xgWindow::EnsureScriptEnvironment (PRUint32 aLangID)
{
    NS_ENSURE_TRUE (NS_STID_VALID (aLangID), NS_ERROR_INVALID_ARG);

    if (mGlobal[aLangID]) {
	return NS_OK;
    }

    nsresult rv;
    nsCOMPtr<nsIDOMScriptObjectFactory> sof (do_GetService (kDOMScriptObjectFactoryCID, &rv));
    NS_ENSURE_SUCCESS (rv, rv);

    nsCOMPtr<nsIScriptRuntime> rt;
    rv = sof->GetScriptRuntimeByID (aLangID, getter_AddRefs (rt));
    NS_ENSURE_SUCCESS (rv, rv);

    nsCOMPtr<nsIScriptContext> cx;
    rv = rt->CreateContext (getter_AddRefs (cx));
    NS_ENSURE_SUCCESS (rv, rv);

    return SetScriptContext (aLangID, cx);
}

nsIScriptContext *
xgWindow::GetScriptContext (PRUint32 lang)
{
    NS_ENSURE_TRUE (NS_STID_VALID (lang), NULL);
    return mContext[NS_STID_INDEX (lang)];
}

void *
xgWindow::GetScriptGlobal (PRUint32 lang)
{
    NS_ENSURE_TRUE (NS_STID_VALID (lang), NULL);
    return mGlobal[NS_STID_INDEX (lang)];
}

nsresult
xgWindow::SetScriptContext (PRUint32 lang, nsIScriptContext *aContext)
{
    NS_ENSURE_TRUE (NS_STID_VALID (lang), NULL);
    nsresult rv;
    void * global = NULL;
    if (aContext) {
	aContext->WillInitializeContext ();
	rv = aContext->InitContext (this);
	NS_ENSURE_TRUE (rv, rv);

	aContext->DidInitializeContext ();

	global = aContext->GetNativeGlobal ();
	NS_ENSURE_TRUE (global, NS_ERROR_FAILURE);

	rv = aContext->InitClasses (global);
	NS_ENSURE_TRUE (rv, rv);
    }
    PRUint32 lang_idx = NS_STID_INDEX (lang);
    mContext[lang_idx] = aContext;
    mGlobal[lang_idx] = global;

    if (aContext && mDocument) {
	aContext->DidSetDocument (mDocument, global);
    }

    return NS_OK;
}

void
xgWindow::OnFinalize (PRUint32 aLangID, void *aScriptGlobal)
{
    if (!NS_STID_VALID (aLangID) ||
	mGlobal[NS_STID_INDEX (aLangID)] != aScriptGlobal) {
	return;
    }
    mGlobal[NS_STID_INDEX (aLangID)] = NULL;
}

nsresult
xgWindow::DidSetDocument ()
{
    NS_ENSURE_TRUE (mDocument, NS_ERROR_INVALID_ARG);

    nsCOMPtr<nsIDocument> doc = do_QueryInterface (mDocument);
    if (doc) {
	doc->SetScriptGlobalObject (this);
	doc->SetDocumentURI (mLocation->mUri);
    } else {
	g_warning (GOM_LOC ("mDocument does not support nsIDocument; things will likely go awry"));
    }

    PRUint32 lang;
    nsresult rv;
    NS_STID_FOR_INDEX (lang) {
	nsIScriptContext *cx = mContext[lang];
	if (cx) {
	    rv = cx->InitClasses (mGlobal[lang]);
	    if (NS_SUCCEEDED (rv)) {
		cx->DidSetDocument (mDocument, mGlobal[lang]);
	    }
	}
    }

    return NS_OK;
}

/*
 * nsILocation implementation
 */

xgLocation::xgLocation (xgWindow *aWindow)
    : mWindow (aWindow)
{
}

xgLocation::~xgLocation ()
{
    mWindow = NULL;
}

NS_IMPL_ISUPPORTS1 (xgLocation, nsIDOMLocation)

/* void assign (in DOMString url); */
NS_IMETHODIMP
xgLocation::Assign (const nsAString &url)
{
    nsresult rv;
    nsCOMPtr<nsIIOService> io (do_GetService ("@mozilla.org/network/io-service;1", &rv));
    NS_ENSURE_SUCCESS (rv, rv);

    g_message (GOM_LOC ("Setting URI to: %s"), NS_ConvertUTF16toUTF8 (url).get ());

    nsCOMPtr<nsIURI> uri;
    rv = io->NewURI (NS_ConvertUTF16toUTF8 (url), "UTF-8", mUri, getter_AddRefs (uri));
    NS_ENSURE_SUCCESS (rv, rv);

    mUri = uri;

    g_message (GOM_LOC ("mUri is now: %p"), mUri.get());

    nsCOMPtr<nsIDOMDocument> doc;
    return mWindow->mParser->ParseURI (url, mWindow->mListener, getter_AddRefs (doc));
}

/* DOMString toString (); */
NS_IMETHODIMP
xgLocation::ToString (nsAString &_retval)
{
    NS_ENSURE_TRUE (mUri, NS_ERROR_FAILURE);

    g_message (GOM_LOC ("mUri is: %p"), mUri.get());

    nsCAutoString s;
    nsresult rv = mUri->GetSpec (s);
    NS_ENSURE_SUCCESS (rv, rv);

    return NS_CStringToUTF16 (s, NS_CSTRING_ENCODING_UTF8, _retval);
}

/*
 * an xgParserListener
 */

xgWindowParserListener::xgWindowParserListener (xgWindow *aWindow)
    : mWindow (aWindow)
{
}

xgWindowParserListener::~xgWindowParserListener ()
{
}

/* Implementation file */
NS_IMPL_ISUPPORTS1 (xgWindowParserListener, xgIParserListener)

/* void documentCreated (in nsIDOMDocument document); */
NS_IMETHODIMP
xgWindowParserListener::DocumentCreated (nsIDOMDocument *aDocument)
{
    // friend access!
    mWindow->mDocument = aDocument;
    return mWindow->DidSetDocument ();
}

PRBool
XG_HandleScriptError (nsIScriptGlobalObject *aScriptGlobal,
		      nsScriptErrorEvent *aErrorEvent,
		      nsEventStatus *aEventStatus)
{
    return PR_FALSE;
}

#include "xgWindowUnimplemented.cc"


text:
<component name="ShelveChangesManager" show_recycled="true">
  <recycled_changelist date="945907200000" toDelete="true">
    <option name="PATH" value="$PROJECT_DIR$/.shelf/test.patch" />
    <option name="DESCRIPTION" value="test" />
  </recycled_changelist>
  <recycled_changelist date="946166400000" toDelete="true">
    <option name="PATH" value="$PROJECT_DIR$/.shelf/test2.patch" />
    <option name="DESCRIPTION" value="test2" />
  </recycled_changelist>
</component>


text:
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE TypeSynonymInstances #-}

module HW05.Calc where

import HW05.ExprT
import HW05.Parser
import qualified HW05.StackVM as SVM

-- Exercise 1

eval :: ExprT -> Integer
eval (Lit i) = i
eval (Add e1 e2) = (eval e1) + (eval e2)
eval (Mul e1 e2) = (eval e1) * (eval e2)

-- Exercise 2

evalStr :: String -> Maybe Integer
evalStr s = case parseExp Lit Add Mul s of
    (Just mul) -> Just $ eval mul
    otherwise  -> Nothing

-- Exercise 3

class Expr a where
    lit :: Integer -> a
    add :: a -> a -> a
    mul :: a -> a -> a

instance Expr ExprT where
    lit = Lit
    add = Add
    mul = Mul

-- Exercise 4

instance Expr Integer where
    lit = id
    add = (+)
    mul = (*)

instance Expr Bool where
    lit x
        | x <= 0    = False
        | otherwise = True
    add = (||)
    mul = (&&)

newtype MinMax = MinMax Integer deriving (Eq, Show)
newtype Mod7 = Mod7 Integer deriving (Eq, Show)

instance Expr MinMax where
    lit = MinMax
    add (MinMax x) (MinMax y) = MinMax $ max x y
    mul (MinMax x) (MinMax y) = MinMax $ min x y

instance Expr Mod7 where
    lit i = Mod7 $ i `mod` 7
    add (Mod7 x) (Mod7 y) = Mod7 $ (x + y) `mod` 7
    mul (Mod7 x) (Mod7 y) = Mod7 $ (x * y) `mod` 7

testExp :: Expr a => Maybe a
testExp = parseExp lit add mul "(3 * -4) + 5"

testInteger = testExp :: Maybe Integer
testBool = testExp :: Maybe Bool
testMM = testExp :: Maybe MinMax
testSat = testExp :: Maybe Mod7

-- Exercise 5

instance Expr SVM.Program where
    lit i = [SVM.PushI i]
    add x y = x ++ y ++ [SVM.Add]
    mul x y = x ++ y ++ [SVM.Mul]

compile :: String -> Maybe SVM.Program
compile = parseExp lit add mul


text:
from struct import pack

from vertica_python.vertica.messages.message import FrontendMessage

class Close(FrontendMessage):

    def __init__(self, close_type, close_name):
        self.close_name = close_name

        if close_type == 'portal':
            self.close_type = 'P'
        elif close_type == 'prepared_statement':
            self.close_type = 'S'
        else:
            raise ValueError("{0} is not a valid close_type.  Must be either portal or prepared_statement".format(close_type))

    def to_bytes(self):
        return self.message_string(pack('c{0}sx'.format(len(self.close_name)), self.close_type, self.close_name))

Close._message_id(b'C')


text:
import argparse
import logging
import os
import yaml
from kubeflow.testing import test_helper, util
from kubernetes.config import kube_config

def parse_args():
  parser = argparse.ArgumentParser()
  parser.add_argument(
      "--cluster",
      default=None,
      type=str,
      help=(
          "The name of the cluster. If not set assumes the script is running in"
          " a cluster and uses that cluster."))
  parser.add_argument(
      "--zone",
      default="us-east1-d",
      type=str,
      help="The zone for the cluster.")
  parser.add_argument(
      "--project", default=None, type=str, help="The project to use.")
  args, _ = parser.parse_known_args()
  return args

def get_gke_credentials(test_case):
  """Configure kubeconfig to talk to the supplied GKE cluster."""
  args = parse_args()
  util.maybe_activate_service_account()
  config_file = os.path.expanduser(kube_config.KUBE_CONFIG_DEFAULT_LOCATION)
  logging.info("Using Kubernetes config file: %s", config_file)
  project = args.project
  cluster_name = args.cluster
  zone = args.zone
  logging.info("Using cluster: %s in project: %s in zone: %s", cluster_name,
               project, zone)
  # Print out config to help debug issues with accounts and
  # credentials.
  util.run(["gcloud", "config", "list"])
  util.configure_kubectl(project, zone, cluster_name)

  # We want to modify the KUBECONFIG file to remove the gcloud commands
  # for any users that are authenticating using service accounts.
  # This will allow the script to be truly headless and not require gcloud.
  # More importantly, kubectl will properly attach auth.info scope so that
  # RBAC rules can be applied to the email and not the id.
  # See https://github.com/kubernetes/kubernetes/pull/58141
  #
  # TODO(jlewi): We might want to check GOOGLE_APPLICATION_CREDENTIALS
  # to see whether we are actually using a service account. If we aren't
  # using a service account then we might not want to delete the gcloud
  # commands.
  logging.info("Modifying kubeconfig %s", config_file)
  with open(config_file, "r") as hf:
    config = yaml.load(hf)

  for user in config["users"]:
    auth_provider = user.get("user", {}).get("auth-provider", {})
    if auth_provider.get("name") != "gcp":
      continue
    logging.info("Modifying user %s which has gcp auth provider", user["name"])
    if "config" in auth_provider:
      logging.info("Deleting config from user %s", user["name"])
      del auth_provider["config"]

      # This is a hack because the python client library will complain
      # about an invalid config if there is no config field.
      #
      # It looks like the code checks here but that doesn't seem to work
      # https://github.com/kubernetes-client/python-base/blob/master/config/kube_config.py#L209
      auth_provider["config"] = {
          "dummy": "dummy",
      }
  logging.info("Writing update kubeconfig:\n %s", yaml.dump(config))
  with open(config_file, "w") as hf:
    yaml.dump(config, hf)

def main():
  test_case = test_helper.TestCase(
      name='get_gke_credentials', test_func=get_gke_credentials)
  test_suite = test_helper.init(
      name='get_gke_credentials', test_cases=[test_case])
  test_suite.run()

if __name__ == "__main__":
  main()


text:
include ../support/Makefile.inc

CXXFLAGS += -g -Wall

.PHONY: clean

interpolate: interpolate.cpp
	$(CXX) $(CXXFLAGS) interpolate.cpp $(LIB_HALIDE) -o interpolate -lpthread -ldl -lz \
	$(PNGFLAGS) $(LDFLAGS) $(LLVM_SHARED_LIBS)

out.png: interpolate
	./interpolate ../images/rgba.png out.png

clean:
	rm -f interpolate interpolate.h out.png


text:
using System;

class test
{
    public static int Main()
    {
        try
        {
            Console.WriteLine("In try1");

            throw new Exception();
        }
        catch (Exception)
        {
            Console.WriteLine("In catch1");

            try
            {
                Console.WriteLine("In try2");

                try
                {
                    Console.WriteLine("In try3");

                    throw new Exception();
                }
                catch
                {
                    Console.WriteLine("In catch3");
                    goto L;
                }
            }
            finally
            {
                Console.WriteLine("In finally2");
            }
        }
        finally
        {
            Console.WriteLine("In finally1");
        }

        Console.WriteLine("Never executed");
        return 1;
    L:
        Console.WriteLine("Done");
        return 100;

    }
}


text:
import { AnyAction } from "redux";

export const LOADING_START = "LOADING_START";
function start(blocking = false) {
  return {
    type: LOADING_START,
    blocking
  };
}

export const LOADING_COMPLETE = "LOADING_COMPLETE";
function complete() {
  return {
    type: LOADING_COMPLETE
  };
}

export const LoadingActions = {
  start,
  complete
};

export type LoadingState = {
  enabled: boolean;
  blocking: boolean;
};
const initialState: LoadingState = {
  enabled: false,
  blocking: false
};
export default function loadingReducer(
  state = initialState,
  action: AnyAction
) {
  switch (action.type) {
    case LOADING_START: {
      const { blocking } = action;
      return {
        enabled: true,
        blocking
      };
    }
    case LOADING_COMPLETE: {
      return {
        enabled: false,
        blocking: false
      };
    }
    default:
      return state;
  }
}


text:
package com.daxslab.mail.view;

import android.content.Context;
import android.graphics.Canvas;
import android.util.AttributeSet;
import android.widget.TextView;

/**
 * This {@link TextView} is used in the custom view of the {@link com.daxslab.mail.activity.MessageList}
 * action bar.
 * It will hide the subject line in {@link MessageHeader} if the subject fits completely into the
 * action bar's title view.
 */
public class MessageTitleView extends TextView {
    private static final int MAX_LINES = 2;
    private static final String ELLIPSIS = "\u2026";

    private MessageHeader mHeader;
    private boolean mNeedEllipsizeCheck = true;

    public MessageTitleView(Context context) {
        this(context, null);
    }

    public MessageTitleView(Context context, AttributeSet attrs) {
        this(context, attrs, android.R.attr.textViewStyle);
    }

    public MessageTitleView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onTextChanged(CharSequence text, int start,
            int lengthBefore, int lengthAfter) {
        super.onTextChanged(text, start, lengthBefore, lengthAfter);
        mNeedEllipsizeCheck = true;
    }
    /**
     * Check to see if we need to hide the subject line in {@link MessageHeader} or not.
     */
    @Override
    public void onDraw(Canvas canvas) {
        /*
         * Android does not support ellipsize in combination with maxlines
         * for TextViews. To work around that, check for ourselves whether
         * the text is longer than MAX_LINES, and ellipsize manually.
         */
        if (mNeedEllipsizeCheck) {
            if (getLayout() != null && mHeader != null) {
                if (getLayout().getLineCount() > MAX_LINES) {
                    int lineEndIndex = getLayout().getLineEnd(MAX_LINES - 1);
                    setText(getText().subSequence(0, lineEndIndex - 2) + ELLIPSIS);
                } else {
                    mHeader.hideSubjectLine();
                }
                mNeedEllipsizeCheck = false;
            }
        }
        super.onDraw(canvas);
    }

    public void setMessageHeader(final MessageHeader header) {
        mHeader = header;
    }
}


text:
/**
 */
package substationStandard.Enumerations;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import org.eclipse.emf.common.util.Enumerator;

/**
 *
 * A representation of the literals of the enumeration 'DP Status Kind',
 * and utility methods for working with them.
 *
 * @see substationStandard.Enumerations.EnumerationsPackage#getDPStatusKind()
 * @model
 * @generated
 */
public enum DPStatusKind implements Enumerator {
	/**
	 * The 'Intermediate State' literal object.
	 *
	 *
	 * @see #INTERMEDIATE_STATE_VALUE
	 * @generated
	 * @ordered
	 */
	INTERMEDIATE_STATE(0, "intermediateState", "intermediateState"),

	/**
	 * The 'Off Or False' literal object.
	 *
	 *
	 * @see #OFF_OR_FALSE_VALUE
	 * @generated
	 * @ordered
	 */
	OFF_OR_FALSE(0, "offOrFalse", "offOrFalse"),

	/**
	 * The 'On Or True' literal object.
	 *
	 *
	 * @see #ON_OR_TRUE_VALUE
	 * @generated
	 * @ordered
	 */
	ON_OR_TRUE(0, "onOrTrue", "onOrTrue"),

	/**
	 * The 'Bad State' literal object.
	 *
	 *
	 * @see #BAD_STATE_VALUE
	 * @generated
	 * @ordered
	 */
	BAD_STATE(0, "badState", "badState");

	/**
	 * The 'Intermediate State' literal value.
	 *
	 *

	 * If the meaning of 'Intermediate State' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #INTERMEDIATE_STATE
	 * @model name="intermediateState"
	 * @generated
	 * @ordered
	 */
	public static final int INTERMEDIATE_STATE_VALUE = 0;

	/**
	 * The 'Off Or False' literal value.
	 *
	 *

	 * If the meaning of 'Off Or False' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #OFF_OR_FALSE
	 * @model name="offOrFalse"
	 * @generated
	 * @ordered
	 */
	public static final int OFF_OR_FALSE_VALUE = 0;

	/**
	 * The 'On Or True' literal value.
	 *
	 *

	 * If the meaning of 'On Or True' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #ON_OR_TRUE
	 * @model name="onOrTrue"
	 * @generated
	 * @ordered
	 */
	public static final int ON_OR_TRUE_VALUE = 0;

	/**
	 * The 'Bad State' literal value.
	 *
	 *

	 * If the meaning of 'Bad State' literal object isn't clear,
	 * there really should be more of a description here...
	 *

	 *
	 * @see #BAD_STATE
	 * @model name="badState"
	 * @generated
	 * @ordered
	 */
	public static final int BAD_STATE_VALUE = 0;

	/**
	 * An array of all the 'DP Status Kind' enumerators.
	 *
	 *
	 * @generated
	 */
	private static final DPStatusKind[] VALUES_ARRAY =
		new DPStatusKind[] {
			INTERMEDIATE_STATE,
			OFF_OR_FALSE,
			ON_OR_TRUE,
			BAD_STATE,
		};

	/**
	 * A public read-only list of all the 'DP Status Kind' enumerators.
	 *
	 *
	 * @generated
	 */
	public static final List<DPStatusKind> VALUES = Collections.unmodifiableList(Arrays.asList(VALUES_ARRAY));

	/**
	 * Returns the 'DP Status Kind' literal with the specified literal value.
	 *
	 *
	 * @param literal the literal.
	 * @return the matching enumerator or null.
	 * @generated
	 */
	public static DPStatusKind get(String literal) {
		for (int i = 0; i < VALUES_ARRAY.length; ++i) {
			DPStatusKind result = VALUES_ARRAY[i];
			if (result.toString().equals(literal)) {
				return result;
			}
		}
		return null;
	}

	/**
	 * Returns the 'DP Status Kind' literal with the specified name.
	 *
	 *
	 * @param name the name.
	 * @return the matching enumerator or null.
	 * @generated
	 */
	public static DPStatusKind getByName(String name) {
		for (int i = 0; i < VALUES_ARRAY.length; ++i) {
			DPStatusKind result = VALUES_ARRAY[i];
			if (result.getName().equals(name)) {
				return result;
			}
		}
		return null;
	}

	/**
	 * Returns the 'DP Status Kind' literal with the specified integer value.
	 *
	 *
	 * @param value the integer value.
	 * @return the matching enumerator or null.
	 * @generated
	 */
	public static DPStatusKind get(int value) {
		switch (value) {
			case INTERMEDIATE_STATE_VALUE: return INTERMEDIATE_STATE;
		}
		return null;
	}

	/**
	 *
	 *
	 * @generated
	 */
	private final int value;

	/**
	 *
	 *
	 * @generated
	 */
	private final String name;

	/**
	 *
	 *
	 * @generated
	 */
	private final String literal;

	/**
	 * Only this class can construct instances.
	 *
	 *
	 * @generated
	 */
	private DPStatusKind(int value, String name, String literal) {
		this.value = value;
		this.name = name;
		this.literal = literal;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public int getValue() {
	  return value;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public String getName() {
	  return name;
	}

	/**
	 *
	 *
	 * @generated
	 */
	public String getLiteral() {
	  return literal;
	}

	/**
	 * Returns the literal value of the enumerator, which is its string representation.
	 *
	 *
	 * @generated
	 */
	@Override
	public String toString() {
		return literal;
	}

} //DPStatusKind


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

  <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Close file</title>

eio_chown

eio_custom

Eio Functions

PHP Manual

eio_close

(PECL eio >= 0.0.1dev)

eio_close — Close file

Description

   resource eio_close
    ( mixed $fd
   [, int $pri = EIO_PRI_DEFAULT
   [, callable $callback = NULL
   [, mixed $data = NULL
  ]]] )

  eio_close() closes file specified by
  fd.

Parameters

fd

      Stream, Socket resource, or numeric file descriptor

pri

The request priority: EIO_PRI_DEFAULT, EIO_PRI_MIN, EIO_PRI_MAX, or NULL.
If NULL passed, pri internally is set to
EIO_PRI_DEFAULT.

callback

callback function is called when the request is done.
It should match the following prototype:

void callback(mixed $data, int $result[, resource $req]);

data

is custom data passed to the request.

result

request-specific result value; basically, the value returned by corresponding
system call.

req

is optional request resource which can be used with functions like eio_get_last_error()

data

     Arbitrary variable passed to callback.

Return Values

   eio_close() returns request resource on success or FALSE on error.

See Also

eio_open

eio_chown

eio_custom

Eio Functions

PHP Manual


text:
Click here to create some history.

This button is what it's all about!

<input type="button" value="hokey pokey" onclick="goForward();" />


text:
.infoContainer {
    display: flex;
    position: relative;
    align-items: center;
    color: inherit;
    text-decoration: none;
    border-bottom: 1px solid #c9c9c985;
}

.infoContainer:last-child {
    border: none;
}

.featureLink {
    position: relative;
    display: flex;
    box-sizing: content-box;
    overflow: hidden;
    width: 100%;
    text-decoration: none;
    justify-content: space-between;
    align-items: center;
    padding: 20px 10px 20px 20px;
    cursor: pointer;

    &:hover {
        background-color: #c2e9dd;
    }
}

.arrow {
    width: 30px;
    opacity: 0.6;
}

.headingSubheading {
    display: flex;
    flex-direction: column;
}

.featureHeading {
    font-weight: bold;
    color: black;
    text-transform: uppercase;
}

.featureSubheading {
    color: #858585;
    font-size: 16px;
    margin-top: 5px;
}


text:
from sqlalchemy import create_engine
from werkzeug import ClosingIterator, exceptions

import os,sys
root = os.path.join(os.path.dirname(__file__),'..')
sys.path.insert(0, root)

activate_this = os.path.join(root, 'environ/bin/activate_this.py')
if os.path.exists(activate_this):
    execfile(activate_this, dict(__file__=activate_this))

from mizwiki.local import local, local_manager, metadata, session
from mizwiki import config, models, controllers

import re
re_invalidchars = re.compile(r'[^\w_./+\-]',re.U)

class MizWiki(object):
    def __init__(self,repository_path):
        self.repository_path = repository_path
        self.database_engine = create_engine(config.DATABASE, convert_unicode=True)
        local.application = self

    def init_database(self):
        metadata.create_all(self.database_engine)
        metadata.reflect(bind=self.database_engine)
        for table in reversed(metadata.sorted_tables):
            self.database_engine.execute(table.delete())

    def __call__(self, environ, start_response):
        local.application = self
        if not hasattr(local,'repository'):
            local.repository = models.Repository(self.repository_path)

        local.head = local.repository.youngest
        try:
            path_info = environ.get('PATH_INFO','')
            if path_info == '':
                raise exceptions.Forbidden()
            if path_info != '/' and path_info[-1]=='/':
                raise exceptions.Forbidden()

            path_info = path_info.strip('/')
            if re_invalidchars.search(path_info) != None:
                raise exceptions.Forbidden()

            response = controllers.mapper.dispatch(path_info)
            if not response:
                response = exceptions.Forbidden()

            return ClosingIterator(response(environ, start_response), [session.remove, local_manager.cleanup])
        except exceptions.HTTPException, e:
            return e(environ, start_response)

application = MizWiki(config.REPOSITORY_PATH)


text:
Weather in Moscow
=============================

Trial task.

[https://atestweather.herokuapp.com](https://atestweather.herokuapp.com)


text:
package com.puresoltechnologies.ductiledb.core.graph;

import java.util.Map;

/**
 * This interface provides the functionality of a DuctileDB vertex.
 *
 * @author Rick-Rainer Ludwig
 */
public interface DuctileDBVertex extends DuctileDBElement, Cloneable {

    /**
     * This method returns all types of the vertex. The type is used to
     * distinguish the different edges from each other and also to bind schema
     * information and constraints to it.
     *
     * @return An {@link Iterable} of {@link String} is returned containing the
     *         type names.
     */
    public Iterable<String> getTypes();

    /**
     * This add a new type to the vertex.
     *
     * @param type
     *            is a {@link String} containing the name of the type.
     */
    public void addType(String type);

    /**
     * This method removed a type from the vertex. The removal does not remove
     * the properties bound to the type, but the type name only.
     *
     * @param type
     *            is a {@link String} containing the name of the type.
     */
    public void removeType(String type);

    /**
     * Checks whether this vertex has a certain type.
     *
     * @param type
     *            is a {@link String} containing the name of the type.
     * @return true is returned in case the type is available.
     *         false is returned otherwise.
     */
    public boolean hasType(String type);

    /**
     * This method adds a new edge to the vertex.
     *
     * @param type
     *            is the type name of the edge.
     * @param targetVertex
     *            is the target vertex of the edge.
     * @param properties
     *            is a {@link Map} of properties to be added to the edge.
     * @return A newly created {@link DuctileDBEdge} object is returned.
     */
    public DuctileDBEdge addEdge(String type, DuctileDBVertex targetVertex, Map<String, Object> properties);

    /**
     * This method returns all vertices which are of defined type and direction.
     *
     * @param direction
     *            is the {@link EdgeDirection} to check for. Only vertices of
     *            edges are returned which are pointing to this direction.
     * @param edgeTypes
     *            is an array of {@link String} containing a list of edge types.
     *            Only vertices of edges are returned which have at least one of
     *            these types.
     * @return An {@link Iterable} of {@link DuctileDBVertex} is returned
     *         containing the vertices found.
     */
    public Iterable<DuctileDBVertex> getVertices(EdgeDirection direction, String... edgeTypes);

    /**
     * This method returns all edges which are of defined type and direction.
     *
     * @param direction
     *            is the {@link EdgeDirection} to check for. Only edges are
     *            returned which are pointing to this direction.
     * @param edgeTypes
     *            is an array of {@link String} containing a list of edge types.
     *            Only edges which have at least one of these types are
     *            returned.
     * @return An {@link Iterable} of {@link DuctileDBVertex} is returned
     *         containing the vertices found.
     */
    public Iterable<DuctileDBEdge> getEdges(EdgeDirection direction, String... edgeTypes);

    @Override
    public DuctileDBVertex clone();
}


text:
import json
import xml.etree.ElementTree as ET
# Import SQL Alchemy
from sqlalchemy import create_engine, text
import lib.es as es

def run(p):
    AllGood = True
    # Read Query and parse parameters
    root = ET.fromstring(p["action"]["query"])
    SOURCE_SQL_CONNECTION = root.find("SOURCE_SQL_CONNECTION").text.strip()
    SOURCE_SQL = root.find("SOURCE_SQL").text.strip()
    ELASTIC_SEARCH_HOST = root.find("ELASTIC_SEARCH_HOST").text
    INDEX = root.find("INDEX").text
    DOC_TYPE = root.find("DOC_TYPE").text
    # Data Body
    SQL_RESULT = None
    # Create sql engine
    engine = create_engine(SOURCE_SQL_CONNECTION)
    # Get SQL connection
    with engine.connect() as conn:
        try:
            p["log"].info(SOURCE_SQL)
            SQL_RESULT = conn.execute(text(SOURCE_SQL))
            p["log"].success("SQL execution success.")
        except Exception, e:
            AllGood = False
            p["log"].error("SQL execution failed.", e)

        # Fetch the dataset
        p["log"].info("start indexing ...")
        row_count = 0
        for r in SQL_RESULT:
            body = {}; id = None; updated = None;
            for column, value in r.items():
                if column == "id": id = value; continue;
                if column == "updated": updated = value;
                body[column] = value
            # Check if the document has id
            if not id:
                AllGood = False
                p["log"].log("ERROR", "id doesn't exist\nid: {}\n{}".format(id, str(body)))
                break
            # Check if the document has updated field
            if not updated or updated[0] == "0":
                AllGood = False
                p["log"].log("ERROR", "update field should not be NULL or 0")
                break
            # Create Index
            try:
                es.create(ELASTIC_SEARCH_HOST, INDEX, DOC_TYPE, id, body)
            except Exception,e:
                AllGood = False
                p["log"].error("id: {}\n{}".format(id, str(body)), e)

            # total indexed document count
            row_count += 1
        # indexing completed
        p["log"].success("Indexing completed: {}".format(row_count))

    return AllGood