text:
using System;
using System.Collections.Generic;
using XPT.Games.Generic.Entities;
using XPT.Games.Generic.Maps;
using XPT.Games.Yserbius;
using XPT.Games.Yserbius.Entities;

namespace XPT.Games.Yserbius.Maps {
    class YserMap21 : YsMap {

        public override int MapIndex => 21;
        protected override int RandomEncounterChance => 0;
        protected override int RandomEncounterExtraCount => 0;

        public YserMap21() {
            MapEvent01 = FnPIT_01;
            MapEvent02 = FnENCGUARD_02;
            MapEvent03 = FnENCEARTH_03;
            MapEvent04 = FnGUARDIAN_04;
            MapEvent05 = FnEARTHELE_05;
            MapEvent06 = FnPLATA_06;
            MapEvent07 = FnPLATB_07;
            MapEvent08 = FnYBOXA_08;
            MapEvent09 = FnYBOXB_09;
            MapEvent0A = FnYBOXC_0A;
            MapEvent0B = FnYBOXD_0B;
            MapEvent0C = FnYBOXE_0C;
            MapEvent0D = FnYBOXF_0D;
            MapEvent0E = FnXBOXG_0E;
            MapEvent0F = FnXBOXH_0F;
            MapEvent10 = FnXBOXI_10;
            MapEvent11 = FnXBOXJ_11;
            MapEvent12 = FnXBOXK_12;
            MapEvent13 = FnXBOXL_13;
            MapEvent14 = FnXBOXM_14;
            MapEvent15 = FnPITAJ_15;
            MapEvent16 = FnPITAK_16;
            MapEvent17 = FnPITAL_17;
            MapEvent18 = FnPITAM_18;
            MapEvent19 = FnPITBG_19;
            MapEvent1A = FnPITBI_1A;
            MapEvent1B = FnPITBJ_1B;
            MapEvent1C = FnPITBK_1C;
            MapEvent1D = FnPITBL_1D;
            MapEvent1E = FnPITBM_1E;
            MapEvent1F = FnPITCG_1F;
            MapEvent20 = FnPITCH_20;
            MapEvent21 = FnPITCI_21;
            MapEvent22 = FnPITCJ_22;
            MapEvent23 = FnPITCK_23;
            MapEvent24 = FnPITCL_24;
            MapEvent25 = FnPITCM_25;
            MapEvent26 = FnPITDG_26;
            MapEvent27 = FnPITDH_27;
            MapEvent28 = FnPITDI_28;
            MapEvent29 = FnPITDJ_29;
            MapEvent2A = FnPITDK_2A;
            MapEvent2B = FnPITDL_2B;
            MapEvent2C = FnPITDM_2C;
            MapEvent2D = FnPITEG_2D;
            MapEvent2E = FnPITEH_2E;
            MapEvent2F = FnPITEI_2F;
            MapEvent30 = FnPITEJ_30;
            MapEvent31 = FnPITEK_31;
            MapEvent32 = FnPITFG_32;
            MapEvent33 = FnPITFH_33;
            MapEvent34 = FnPITFI_34;
            MapEvent35 = FnPITFJ_35;
            MapEvent36 = FnPITFK_36;
            MapEvent37 = FnPITFL_37;
            MapEvent38 = FnPITFM_38;
            MapEvent39 = FnENCPITBJ_39;
            MapEvent3A = FnENCPITDI_3A;
            MapEvent3B = FnPITENCDK_3B;
            MapEvent3C = FnPITENCBL_3C;
            MapEvent3D = FnDOORARNK_3D;
            MapEvent3E = FnTELEARNK_3E;
            MapEvent3F = FnSETEKILL_3F;
        }

        // === Strings ================================================
        private const string String03FC = "You step into a bottomless pit and die.";
        private const string String0424 = "Guardians stand ready.  'We are sworn to defend Arnakkian.'";
        private const string String0460 = "Earth Elemental Andreas rises from his mountainous perch.";
        private const string String049A = "Enlikil's Phantasm Guardians stand watch over the entrance to Arnakkian's Tomb.";
        private const string String04EA = "The earth elemental palace is filled with a bounty of priceless gems.  It seems to shake with great power.";
        private const string String0555 = "The Endless Void has ruptured your dimension and forms a chasm between here and a distant platform.";
        private const string String05B8 = "Heroes who work together can bridge the gap of time. A yellow gem shall suffice if you are alone.";
        private const string String05FC = "Quiet solitude fills the chasm.  You are on the other side.";
        private const string String0737 = "You step over the edge and into oblivion.";
        private const string String1147 = "Andreas no longer defends this door.";
        private const string String116C = "The Earth Elemental holds power over this door.";
        private const string String119C = "A magic field grabs you and teleports you down into Arnakkian's tomb.  The laugh of an ancient archmage fills the chamber.";

        private int _TileBridgeY = 0, _TileBridgeX = 0;

        // === Functions ================================================
        private void FnPIT_01(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: ShowMessage(player, doMsgs, String03FC); // You step into a bottomless pit and die.
            L0010: DamagePlayer(player, GetMaxHits(player));
            L0021: return; // RETURN;
        }

        private void FnENCGUARD_02(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: ShowMessage(player, doMsgs, String0424); // Guardians stand ready.  'We are sworn to defend Arnakkian.'
            L0010: AddEncounter(player, 0x01, 0x27);
            L0022: AddEncounter(player, 0x02, 0x27);
            L0034: AddEncounter(player, 0x03, 0x27);
            L0046: AddEncounter(player, 0x04, 0x27);
            L0058: AddEncounter(player, 0x05, 0x27);
            L006A: RefreshCompareFlags(GetFlag(player, FlagTypeDungeon, YsIndexes.FlagCastleParapetsGuardiansExperience));
            L007D: if (JumpNotEqual) goto L00A6;
            L007F: SetFlag(player, FlagTypeDungeon, YsIndexes.FlagCastleParapetsGuardiansExperience, 0x01);
            L0094: AddExperience(player, 0x0007A120);
            L00A6: return; // RETURN;
        }

        private void FnENCEARTH_03(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: RefreshCompareFlags(GetFlag(player, FlagTypeMap, 0x01));
            L0016: if (JumpEqual) goto L001B;
            L0018: goto L0123;
            L001B: ShowMessage(player, doMsgs, String0460); // Earth Elemental Andreas rises from his mountainous perch.
            L0028: AddEncounter(player, 0x01, 0x04);
            L003A: AddEncounter(player, 0x02, 0x04);
            L004C: AddEncounter(player, 0x03, 0x22);
            L005E: AddEncounter(player, 0x04, 0x0F);
            L0070: AddEncounter(player, 0x05, 0x23);
            L0082: AddEncounter(player, 0x06, 0x28);
            L0094: ax = HasItem(player, YsIndexes.ItemNaturesRobe);
            L00A2: if (JumpEqual) goto L00C6;
            L00A4: AddTreasure(player, 0x0000, 0x00, 0x00, 0x50, 0x50, 0xD0);
            L00C4: goto L0123;
            L00C6: AddTreasure(player, 0x03E8, 0x00, 0x00, 0x88, 0x1D, YsIndexes.ItemNaturesRobe);
            L00E7: RefreshCompareFlags(GetFlag(player, FlagTypeDungeon, YsIndexes.FlagCastleParapetsAndreasExperience));
            L00FA: if (JumpNotEqual) goto L0123;
            L00FC: SetFlag(player, FlagTypeDungeon, YsIndexes.FlagCastleParapetsAndreasExperience, 0x01);
            L0111: AddExperience(player, 0x0003D090);
            L0123: return; // RETURN;
        }

        private void FnGUARDIAN_04(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: ShowMessage(player, doMsgs, String049A); // Enlikil's Phantasm Guardians stand watch over the entrance to Arnakkian's Tomb.
            L0010: return; // RETURN;
        }

        private void FnEARTHELE_05(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: RefreshCompareFlags(GetFlag(player, FlagTypeMap, 0x01));
            L0016: if (JumpNotEqual) goto L0025;
            L0018: ShowMessage(player, doMsgs, String04EA); // The earth elemental palace is filled with a bounty of priceless gems.  It seems to shake with great power.
            L0025: return; // RETURN;
        }

        private void FnPLATA_06(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: ShowMessage(player, doMsgs, String0555); // The Endless Void has ruptured your dimensionand forms a chasm between here and a distant platform.
            L0010: ShowMessage(player, doMsgs, String05B8); // A voice whispers 'Only true friendship can bridge the gap of time.'
            L001D: return; // RETURN;
        }

        private void FnPLATB_07(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, String05FC); // Quiet solitude fills the chasm.  You are on the other side.
            SetFlag(player, FlagTypeDungeon, YsIndexes.FlagMedievaLandsCastleParapetsBridge, 1);
        }

        private void FnYBOXA_08(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the East.");
            SetBridgeVariables(1, _TileBridgeX);
        }

        private void FnYBOXB_09(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the East.");
            SetBridgeVariables(2, _TileBridgeX);
        }

        private void FnYBOXC_0A(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the East.");
            SetBridgeVariables(3, _TileBridgeX);
        }

        private void FnYBOXD_0B(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the East.");
            SetBridgeVariables(4, _TileBridgeX);
        }

        private void FnYBOXE_0C(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the East.");
            SetBridgeVariables(5, _TileBridgeX);
        }

        private void FnYBOXF_0D(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the East.");
            SetBridgeVariables(6, _TileBridgeX);
        }

        private void FnXBOXG_0E(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the North.");
            SetBridgeVariables(_TileBridgeY, 1);
        }

        private void FnXBOXH_0F(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the North.");
            SetBridgeVariables(_TileBridgeY, 2);
        }

        private void FnXBOXI_10(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the North.");
            SetBridgeVariables(_TileBridgeY, 3);
        }

        private void FnXBOXJ_11(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the North.");
            SetBridgeVariables(_TileBridgeY, 4);
        }

        private void FnXBOXK_12(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the North.");
            SetBridgeVariables(_TileBridgeY, 5);
        }

        private void FnXBOXL_13(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the North.");
            SetBridgeVariables(_TileBridgeY, 6);
        }

        private void FnXBOXM_14(YsPlayerServer player, MapEventType type, bool doMsgs) {
            ShowMessage(player, doMsgs, "The wall glows when you touch it. You feel air rushing past you to the North.");
            SetBridgeVariables(_TileBridgeY, 7);
        }

        private void SetBridgeVariables(int y, int x) {
            // the first tile is at map position 5, 6
            // this corresponds to tileBridgeX/Y 1/1
            _TileBridgeX = x;
            _TileBridgeY = y;
            int playerX = _TileBridgeX + 5;
            int playerY = _TileBridgeY + 4;
            foreach (YsPlayerServer player in Mobiles) {
                if (player.Position.X == playerX) {
                    if (playerY == player.Position.Y - 1) {
                        ShowMessage(player, true, "A path forms in the air to the North.");
                    }
                    if (playerY == player.Position.Y + 1) {
                        ShowMessage(player, true, "A path forms in the air to the South.");
                    }
                }
                if (player.Position.Y == playerY) {
                    if (playerX == player.Position.X - 1) {
                        ShowMessage(player, true, "A path forms in the air to the West.");
                    }
                    if (playerX == player.Position.X + 1) {
                        ShowMessage(player, true, "A path forms in the air to the East.");
                    }
                }
            }
        }

        private void DoAttemptWalkThroughVoid(YsPlayerServer player, int y, int x, string successMessage) {
            // the first tile is at map position 5, 6
            // this corresponds to tileBridgeX/Y 1/1
            if (_TileBridgeX == x && _TileBridgeY == y) {
                ShowMessage(player, true, successMessage);
                return;
            }
            if (player.GetPartyLeader().HasItemByTypeIndex(245)) {
                ShowMessage(player, true, "The yellow rainbow gem illuminates a path through the Void.");
                return;
            }
            ShowMessage(player, true, String0737); // You step over the edge and into oblivion.
            DamagePlayer(player, GetMaxHits(player));
        }

        private void FnPITAJ_15(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 1, 4, "You step on solid air. This was a wise move.");
        }

        private void FnPITAK_16(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 1, 5, "You selected your next move wisely.");
        }

        private void FnPITAL_17(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 1, 6, "Your next step is a safe one.");
        }

        private void FnPITAM_18(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 1, 7, "The step you take is wisely chosen.");
        }

        private void FnPITBG_19(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 2, 1, "You take one good step forward.");
        }

        private void FnPITBI_1A(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 2, 3, "You safely step forward.");
        }

        private void FnPITBJ_1B(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 2, 4, "You take a step in the right direction.");
        }

        private void FnPITBK_1C(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 2, 5, "Your move is wise.");
        }

        private void FnPITBL_1D(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 2, 6, "You select your next move wisely.");
        }

        private void FnPITBM_1E(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 2, 7, "You move forward with confidence.");
        }

        private void FnPITCG_1F(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 3, 1, "Your next step is a good one.");
        }

        private void FnPITCH_20(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 3, 2, "You move ahead assuredly.");
        }

        private void FnPITCI_21(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 3, 3, "You choose your next step correctly.");
        }

        private void FnPITCJ_22(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 3, 4, "Your choice of movement saves you.");
        }

        private void FnPITCK_23(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 3, 5, "You step in the right direction.");
        }

        private void FnPITCL_24(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 3, 6, "You select your next step wisely.");
        }

        private void FnPITCM_25(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 3, 7, "Your next step is sagely chosen.");
        }

        private void FnPITDG_26(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 4, 1, "You take a wise step forward.");
        }

        private void FnPITDH_27(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 4, 2, "You move forward wisely.");
        }

        private void FnPITDI_28(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 4, 3, "Your next step is wisely decided.");
        }

        private void FnPITDJ_29(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 4, 4, "You step ahead with confidence.");
        }

        private void FnPITDK_2A(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 4, 5, "You move forward carefully.");
        }

        private void FnPITDL_2B(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 4, 6, "You move ahead.");
        }

        private void FnPITDM_2C(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 4, 7, "Your step is wisely selected.");
        }

        private void FnPITEG_2D(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 5, 1, "You forge ahead.");
        }

        private void FnPITEH_2E(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 5, 2, "You select your next move wisely.");
        }

        private void FnPITEI_2F(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 5, 3, "Good sense guides your feet.");
        }

        private void FnPITEJ_30(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 5, 4, "You walk ahead.");
        }

        private void FnPITEK_31(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 5, 5, "Your next step is assuredly taken.");
        }

        private void FnPITFG_32(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 6, 1, "The next step is an intelligent one.");
        }

        private void FnPITFH_33(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 6, 2, "You move safely ahead.");
        }

        private void FnPITFI_34(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 6, 3, "Your move was correct.");
        }

        private void FnPITFJ_35(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 6, 4, "You move forward with confidence.");
        }

        private void FnPITFK_36(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 6, 5, "You carefully selected your next step.");
        }

        private void FnPITFL_37(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 6, 6, "You make a sage choice.");
        }

        private void FnPITFM_38(YsPlayerServer player, MapEventType type, bool doMsgs) {
            DoAttemptWalkThroughVoid(player, 6, 7, "You have made a wise decision.");
        }

        private void FnENCPITBJ_39(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: AddEncounter(player, 0x01, 0x19);
            L0015: AddEncounter(player, 0x02, 0x1A);
            L0027: AddEncounter(player, 0x03, 0x1A);
            L0039: AddEncounter(player, 0x04, 0x1B);
            L004B: AddEncounter(player, 0x05, 0x1C);
            L005D: return; // RETURN;
        }

        private void FnENCPITDI_3A(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: AddEncounter(player, 0x01, 0x1F);
            L0015: AddEncounter(player, 0x02, 0x1F);
            L0027: AddEncounter(player, 0x03, 0x20);
            L0039: AddEncounter(player, 0x04, 0x20);
            L004B: return; // RETURN;
        }

        private void FnPITENCDK_3B(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: AddEncounter(player, 0x01, 0x1B);
            L0015: AddEncounter(player, 0x02, 0x1B);
            L0027: AddEncounter(player, 0x03, 0x19);
            L0039: AddEncounter(player, 0x04, 0x19);
            L004B: AddEncounter(player, 0x05, 0x1B);
            L005D: AddEncounter(player, 0x06, 0x1B);
            L006F: return; // RETURN;
        }

        private void FnPITENCBL_3C(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: AddEncounter(player, 0x01, 0x24);
            L0015: AddEncounter(player, 0x02, 0x24);
            L0027: AddEncounter(player, 0x03, 0x24);
            L0039: AddEncounter(player, 0x04, 0x25);
            L004B: AddEncounter(player, 0x05, 0x26);
            L005D: return; // RETURN;
        }

        private void FnDOORARNK_3D(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: RefreshCompareFlags(GetFlag(player, FlagTypeMap, 0x01));
            L0016: if (JumpEqual) goto L005B;
            L0018: SetWallPassable(player, GetCurrentTile(player), 0x03, 0x01);
            L0032: SetWallItem(player, 0x01, GetCurrentTile(player), 0x03);
            L004C: ShowMessage(player, doMsgs, String1147); // Andreas no longer defends this door.
            L0059: goto L0068;
            L005B: ShowMessage(player, doMsgs, String116C); // The Earth Elemental holds power over this door.
            L0068: return; // RETURN;
        }

        private void FnTELEARNK_3E(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: ShowMessage(player, doMsgs, String119C); // A magic field grabs you and teleports you down into Arnakkian's tomb.  The laugh of an ancient archmage fills the chamber.
            L0010: TeleportParty(player, 0x34, 0x02, 0x76, 0x03, type);
            L002B: return; // RETURN;
        }

        private void FnSETEKILL_3F(YsPlayerServer player, MapEventType type, bool doMsgs) {
            int ax = 0, bx = 0, cx = 0, dx = 0, si = 0, di = 0, tmp = 0;
            L0000: // BEGIN;
            L0003: SetFlag(player, FlagTypeMap, 0x01, 0x01);
            L0018: return; // RETURN;
        }

    }
}


text:
<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta charset="utf-8">
    <script src="/hammerhead.js" class="script-hammerhead-shadow-ui"></script>
</head>
<body>
<script type="text/javascript">
    var hammerhead = window['%hammerhead%'];

    hammerhead.utils.destLocation.forceLocation('http://localhost/sessionId/https://example.com');
    hammerhead.start({ crossDomainProxyPort: 2000 });
    hammerhead.shadowUI.getRoot();

    var anchor = document.createElement('a');

    anchor.id = 'anchor';
    anchor.setAttribute('href', '/index.html');
    anchor.setAttribute('target', '_parent');
    document.body.appendChild(anchor);
</script>
</body>
</html>

redpajama_set_name: RedPajamaGithub


text:
require File.expand_path(File.dirname(__FILE__)+"/spec_helper.rb")
describe Rubyvis::Scale::Ordinal do
  if Rubyvis::JohnsonLoader.available?
    context "direct protovis API comparison" do
      before(:all) do
        @rt=  Rubyvis::JohnsonLoader.new("/data/OrdinalScale.js").runtime
      end
      before do
        @base  = %w{a b c d e f}
        @range = %w{black red white orange yellow blue}
        @n=rand(3)+3
        @base=@base[0,@n]
        @range=@range[0,@n]
        @y = Rubyvis.Scale.ordinal(@base).range(@range)
        @rt[:domain] = @base
        @rt[:range] = @range
        @y_js=@rt.evaluate("y=pv.Scale.ordinal(domain).range(range)")

      end

      it "domain() implemented equally" do
        @y.domain(@base[0])
        @rt.evaluate("y.domain(domain[0])")
        expect(@y.domain).to eq(@rt.evaluate("y.domain()").to_a)
        @y.domain(@base[0],@base[1])
        @rt.evaluate("y.domain(domain[0],domain[1])")
        expect(@y.domain).to eq(@rt.evaluate("y.domain()").to_a)
      end

    end
  end
  describe "on ruby domain" do
    it "should be created as Javascript" do
      expect {y = Rubyvis.Scale.ordinal(%w{a b c}).range(%w{red blue black})}.not_to raise_exception
    end

    before do
      @domain=%w{a b c}
      @range=%w{red white blue}
      @y = Rubyvis.Scale.ordinal(@domain).range(@range)
    end
    it "y should be a Scale::Ordinal" do
      expect(@y).to be_a(Rubyvis::Scale::Ordinal)
    end
    it "should respond to domain" do
      expect(@y.domain).to eq(%w{a b c})
      @y.domain(%w{a})
      expect(@y.domain).to eq(%w{a})
      @y.domain(1,100,300)
      expect(@y.domain).to eq([1,100,300])
    end
    it "should respond to range" do
      expect(@y.range).to eq(@range.map {|c| pv.color(c)})
      @y.range('red')
      expect(@y.range).to eq([pv.color('red')])
      @y.range('black','white')
      expect(@y.range).to eq([pv.color('black'), pv.color('white')])
    end
    it "should returns correct scale with unknown values" do
      expect(@y.scale(1)).to eq(pv.color('red'))
      expect(@y.scale('x')).to eq(pv.color('white'))
      expect(@y.scale(9)).to eq(pv.color('blue'))
      expect(@y.scale(1)).to eq(pv.color('red'))
    end
    it "should return the same using [] and scale()" do
      a=rand()
      expect(@y[a]).to eq(@y.scale(a))
    end
    it "should returns correct scale with known values" do
      expect(@y.scale('a')).to eq(pv.color('red'))
      expect(@y.scale('b')).to eq(pv.color('white'))
      expect(@y.scale('c')).to eq(pv.color('blue'))
    end
    it "should return correct by" do
      @y = Rubyvis.Scale.ordinal(@domain).range(@range).by(lambda {|v| v.nombre})
      a=OpenStruct.new({:nombre=>'c'})
      b=OpenStruct.new({:nombre=>'b'})
      c=OpenStruct.new({:nombre=>'a'})
      expect(@y.call(a)).to eq(pv.color('blue'))
      expect(@y.call(b)).to eq(pv.color('white'))
      expect(@y.call(c)).to eq(pv.color('red'))

    end
  end
end


text:
package i2am.query.parser;

import java.util.Arrays;
import java.util.Map;

public class Operator {
	private enum OPERATOR {TEQ, TNE, TIN, TNI, NEQ, NNE, NGT, NLT, NGE, NLE, FROM, TO, AND, OR};
    private final static OPERATOR[] RELATIONAL_OPERATOR =
    	{OPERATOR.TEQ, OPERATOR.TNE, OPERATOR.TIN,
         OPERATOR.TNI, OPERATOR.NEQ, OPERATOR.NNE,
         OPERATOR.NGT, OPERATOR.NLT, OPERATOR.NGE,
         OPERATOR.NLE, OPERATOR.FROM, OPERATOR.TO};
    private final static OPERATOR[] LOGICAL_OPERATOR =
    	{OPERATOR.AND, OPERATOR.OR};

	private OPERATOR op;

	public Operator (String op) {
		this.op = OPERATOR.valueOf(op);
	}

	public boolean isRelationalOperator() {
        return Arrays.asList(RELATIONAL_OPERATOR).contains(this.op);
	}

	public boolean isLogicalOperator() {
        return Arrays.asList(LOGICAL_OPERATOR).contains(this.op);
	}

	public static boolean isLogicalOperator(String op) {
        return Arrays.asList(LOGICAL_OPERATOR).contains(OPERATOR.valueOf(op));
	}

	public String toString() {
		return this.op.name();
	}

	public boolean evaluate(Node l, Node r, Map<String, String> tuple) {
		// for logical operator
		if (this.op.equals(OPERATOR.AND))
			return l.evaluate(tuple)
					&& r.evaluate(tuple);
		else if (this.op.equals(OPERATOR.OR))
			return l.evaluate(tuple)
					|| r.evaluate(tuple);

		// for text
		String textL = tuple.get(l.getLeaf());
		String textR = r.getLeaf();
		if (this.op.equals(OPERATOR.TEQ))
			return textL.equals(textR);
		else if (this.op.equals(OPERATOR.TNE))
			return !textL.equals(textR);
		else if (this.op.equals(OPERATOR.TIN))
			return textL.contains(textR);
		else if (this.op.equals(OPERATOR.TNI))
			return !textL.contains(textR);

		// for numeric
		double numericL = Double.parseDouble(textL);
		double numericR = Double.parseDouble(textR);
		if (this.op.equals(OPERATOR.NEQ))
			return numericL == numericR;
		else if (this.op.equals(OPERATOR.NNE))
			return numericL != numericR;
		else if (this.op.equals(OPERATOR.NGT))
			return numericL > numericR;
		else if (this.op.equals(OPERATOR.NLT))
			return numericL < numericR;
		else if (this.op.equals(OPERATOR.NGE))
			return numericL >= numericR;
		else if (this.op.equals(OPERATOR.NLE))
			return numericL <= numericR;

		// for timestamp
		else if (this.op.equals(OPERATOR.FROM))
			return numericL >= numericR;
		else if (this.op.equals(OPERATOR.TO))
			return numericL <= numericR;
		else
			throw new java.lang.UnsupportedOperationException("Not supported yet.");
	}
}


text:
package sql.sqlCallback.asyncEventListener;

import java.sql.*;
import java.util.List;

import hydra.Log;
import sql.ClientDiscDBManager;
import sql.SQLHelper;
import sql.sqlCallback.SQLAsyncEventListenerTest;
import util.TestException;
import util.TestHelper;

import com.pivotal.gemfirexd.callbacks.Event;

public class CustomersAsyncListener extends AbstractAsyncListener {
	static String delete = "delete from trade.customers where cid=?";
	static String insert = "insert into trade.customers values (?,?,?,?,?)";

	private Event failedEvent = null;

	private static ThreadLocal<PreparedStatement> insertStmt = new ThreadLocal<PreparedStatement> () {
		protected PreparedStatement initialValue()  {

			PreparedStatement stmt = null;
			try {
				stmt = dConn.get().prepareStatement(insert);
			}catch (SQLException se) {
				SQLHelper.handleSQLException(se);
			}
			return stmt;
		}
	};

	private static ThreadLocal<PreparedStatement> deleteStmt = new ThreadLocal<PreparedStatement> () {
		protected PreparedStatement initialValue()  {
			PreparedStatement stmt = null;
			try {
				stmt = dConn.get().prepareStatement(delete);
			}catch (SQLException se) {
				SQLHelper.handleSQLException(se);
			}
			return stmt;
		}
	};

	private static ThreadLocal<Statement> stmt = new ThreadLocal<Statement> () {
		protected Statement initialValue()  {
			Statement s = null;
			try {
				s = dConn.get().createStatement();
			}catch (SQLException se) {
				SQLHelper.handleSQLException(se);
			}
			return s;
		}
	};

  public boolean processEvents(List<Event> events) {
    Log.getLogWriter().info("start processing the list of async events");
    for (Event event : events){
      if (failedEvent != null) {
        if (!isSame(failedEvent, event)) {
          if (!event.isPossibleDuplicate()) Log.getLogWriter().warning("an already processed " +
              "event does not have isPossibleDuplicate() set to true");
          else Log.getLogWriter().info("this event has been processed before, do not retry");
          continue;
        } else {
          failedEvent = null; //reset the flag.
        }
      }

      boolean success = processEvent(event);
      if (!success) {
        if (testUniqueKeys) {
          failedEvent = event;
          //restart from the batching from previously failed one, should not have out of order delivery to queue
          Log.getLogWriter().info("test unique key, will retry the failed event");
          return false;
        } else {
          Log.getLogWriter().info("the event does not succeed in back end, but will not continue to retry" +
              "to block the queue");
          //in the multiple listener case, insert p, insert c, delete c, delete p
          //if delete c and insert c are executed out of order in back end db,
          //the delete p will continue to be retried and will block all the following events for the table.
        }
      }
    }
    return true;
  }

  public boolean processEvent(Event event) {
    try {
      Event.Type type = event.getType();
      switch (type) {
      case AFTER_UPDATE:
        update(event);
        break;
      case AFTER_INSERT:
        insert(event);
        break;
      case AFTER_DELETE:
        delete(event);
        break;
      default:
        Log.getLogWriter().warning("TestException: AsyncEventListener got a 'none_after' callback event: " + type);
      }
      dConn.get().commit(); //do not hold the lock
    }catch(SQLException se){
      SQLHelper.printSQLException(se);
      if (se.getSQLState().equals("08006") || se.getSQLState().equals("08003") ||
          se.getSQLState().equals("08001")) {
        Log.getLogWriter().info("connection is lost");
        Connection conn =null;
        try {
          conn = ClientDiscDBManager.getConnection();
          //may need to use url to get the correct db connection
        } catch (SQLException ex) {
          SQLHelper.handleSQLException(ex);
        }
        dConn.set(conn); //provide new connection
        resetStatements();
      } else
        Log.getLogWriter().warning("AsyncEventListener Test gets exception\n" +
            TestHelper.getStackTrace(se));
      return false;
    }
    return true;
  }

	protected void insert (Event event) throws SQLException {
		List<Object> oldRow = event.getOldRow();
		List<Object> newRow = event.getNewRow();
		boolean isPossibleDuplicate = event.isPossibleDuplicate();
		//for HA case, before insert check if record has been inserted already to avoid duplicate
		if (isPossibleDuplicate) {
			ResultSet rs = stmt.get().executeQuery("select * from trade.customers where cid = "
					+ (Integer)event.getPrimaryKey()[0]) ;
			if (rs.next()) {
				Log.getLogWriter().info("this row has been inserted already " + newRow);
				//if it is there, do not insert again
			} else {
				doInsert(oldRow, newRow, isPossibleDuplicate);
			}
		} else doInsert(oldRow, newRow, isPossibleDuplicate);

	}

	private void doInsert(List<Object> oldRow, List<Object> newRow,
			boolean isPossibleDuplicate) throws SQLException {
	  /*
	   * trade.customers table fields
	   *   private int cid;
	   *   String cust_name;
	   *   Date since;
	   *   String addr;
	   *   int tid; //for update or delete unique records
	   */

		int count = 0;
		if (oldRow != null) throw new TestException("BEFORE_INSERT is invoked, but " +
				"oldRow is not null: " + oldRow);

		insertStmt.get().setInt(1, (Integer)( newRow.get(0)));
		insertStmt.get().setString(2, (String) newRow.get(1));
		insertStmt.get().setDate(3, (Date) newRow.get(2));
		insertStmt.get().setString(4, (String) newRow.get(3));
		insertStmt.get().setInt(5, (Integer) newRow.get(4));
		Log.getLogWriter().info("inserting into customers in derby " +
				"cid is " + (Integer)( newRow.get(0)) +
				" cust_name is " + (String) newRow.get(1) +
				" since is " + (Date) newRow.get(2) +
				" addr is " + (String) newRow.get(3) +
				" tid is " + (Integer) newRow.get(4));

		count = insertStmt.get().executeUpdate();
		Log.getLogWriter().info("inserted " + count + " row");

		if (count !=1 && !isPossibleDuplicate && testUniqueKeys) throw new TestException("insert from listener does not " +
				"insert the corresponding row in back_end, inserted row is " + count);
	}

	protected void delete (Event event) throws SQLException {
		List<Object> newRow = event.getNewRow();
		boolean isPossibleDuplicate = event.isPossibleDuplicate();
		int count =0;
		if (newRow != null) throw new TestException("BEFORE_DELETE is invoked, but " +
				"newRow is not null: " + newRow);
		deleteStmt.get().setInt(1, (Integer)event.getPrimaryKey()[0]); //through primary key
		Log.getLogWriter().info("deleting from customers in derby where cid ="
				+  (Integer)event.getPrimaryKey()[0]);

		count = deleteStmt.get().executeUpdate();
		Log.getLogWriter().info("deleted " + count + " row");

		if (count !=1 && !isPossibleDuplicate && testUniqueKeys) {
		  SQLAsyncEventListenerTest.testException = new TestException("insert from listener does not " +
				"insert the corresponding row in back_end, inserted row is " + count);
		  throw SQLAsyncEventListenerTest.testException;
		}
	}

	protected void update(Event event) throws SQLException{
		boolean isPossibleDuplicate = event.isPossibleDuplicate();
		int count =0;
		String sql = getSql(event);
		//add where clause
		sql +=" where cid = " + event.getPrimaryKey()[0];
		Log.getLogWriter().info("update to derby: " + sql);

		count = stmt.get().executeUpdate(sql);
		Log.getLogWriter().info("updated " + count + " row");

		if (count !=1 && !isPossibleDuplicate && testUniqueKeys) {
		  SQLAsyncEventListenerTest.testException = new TestException("update from listener does not " +
				"update the corresponding row in back_end, updated row is " + count);
		  throw SQLAsyncEventListenerTest.testException;
		}
	}

  protected void resetStatements() {
    resetInsert();
    resetDelete();
    resetStmt();
  }

  protected void resetInsert() {
    PreparedStatement stmt = null;
    try {
      stmt = dConn.get().prepareStatement(insert);
    }catch (SQLException se) {
      SQLHelper.handleSQLException(se);
    }
    insertStmt.set(stmt);
  }

  protected void resetDelete() {
    PreparedStatement stmt = null;
    try {
      stmt = dConn.get().prepareStatement(delete);
    }catch (SQLException se) {
      SQLHelper.handleSQLException(se);
    }
    deleteStmt.set(stmt);
  }

  protected void resetStmt() {
    Statement s = null;
    try {
      s = dConn.get().createStatement();
    }catch (SQLException se) {
      SQLHelper.handleSQLException(se);
    }
    stmt.set(s);
  }

  protected static ThreadLocal<Connection> dConn = new ThreadLocal<Connection>()  {
    protected Connection initialValue()  {
      Connection dConn =null;
      try {
        dConn = ClientDiscDBManager.getConnection();
        //may need to use url to get the correct db connection
      } catch (SQLException se) {
        SQLHelper.handleSQLException(se);
      }
      return dConn;
    }
  };
}


text:
<sly data-sly-use.mapper="com.axamit.gc.core.sightly.models.AjaxMapperModel">
    <sly data-sly-use.mapperView="/apps/gathercontent/components/content/mapping-export/mapper-template.html"
         data-sly-call="${mapperView.mapperTemplate @ mapper = mapper}">
    </sly>
</sly>


text:
classdef raw_line_data_options
    %
    %   Class:
    %   big_plot.raw_line_data_options
    %
    %   Options for processing big_plot.raw_line_data
    %
    %   See Also
    %   --------
    %   big_plot.raw_line_data

    properties
        get_x_data = true
        %Populates the 'x' property in raw_line_data. Note this might be an
        %expensive memory operation which is why we have the option to
        %disable it

        xlim = []
        %Range over which to retrieve the data.

        get_calibrated = true
        %If a calibration is present, this will return the calibrated data
        %when true. Calibration is generally only present (I think) with
        %streaming data.

        get_raw = false
        %Retrieves the uncalibrated data. In conjunction with
        %get_calibrated this allows us to potentially get both raw and
        %calibrated data.
    end

    methods
    end

end


text:
/**
 * CrossCompare.js - JavaScript library for quick dc.js chart comparison
 *
 * Github - https://github.com/RRothfeld/CrossCompare-js
 * MIT License - https://github.com/RRothfeld/CrossCompare-js/blob/master/LICENSE
 *
 * @author RRothfeld
 * @version 1.0.0
 */

/**
 * Object storing CrossCompare's default and users' values.
 * @type {Object}
 */
var crosscompare = {
	// Comparison graph display settings
	height: 200, // in px
	width: 'auto',// in px  or 'auto' (scales to container width)
	padding: { top: 20, right: 5, bottom: 10, left: 25 }, // in px
	anchor: '#crosscompare', // HTML id of container for comparison chart
	dateFormat: '%d/%m/%Y', // format for JavaScript/D3.js dates
	xGrid: false, // show grid-lines along x-axis
	yGrid: false, // show grid-lines along y-axis

	// CrossCompare behavior settings
	flash: true, // lights up cached source chart when caching
	legends: [], // filters and selection defining the naming of cached data
	overwrite: false, // update existing data (true) or add new dimension (false)
										// in case same filters have already been cached

	// Operational variables
	chart: {}, // stores pointers to comparison chart and data-source chart
	charts: {}, // stores pointers to all charts available for comparison
	queue: [] // stores all cached data for simultaneous rendering
};

/**
 * Set comparison chart height (in px).
 * @param {number} height The desired height of the comparison chart.
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.setHeight = function(height) {
	// Accept height of zero or more pixels
	if (height >= 0)
		this.height = height;
	return this;
};

/**
 * Set comparison chart width (in px).
 * @param {number/string} width The desired width of the comparison chart.
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.setWidth = function(width) {
	// Accept width of zero or more pixels, or 'auto'
	if (width >= 0 || width == 'auto')
		this.width = width;
	return this;
};

/**
 * Set comparison chart padding (in px).
 * @param {number} top    The desired top-padding of the comparison chart.
 * @param {number} right  The desired right-padding of the comparison chart.
 * @param {number} bottom The desired bottom-padding of the comparison chart.
 * @param {number} left   The desired left-padding of the comparison chart.
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.setPadding = function(top, right, bottom, left) {
	// Accept if all padding sides are provided and are numbers (negative padding
	// is allowed)
	if (typeof top === 'number' && typeof right === 'number' &&
		typeof bottom === 'number' &&	typeof left === 'number')
		this.padding = { top: top, right: right, bottom: bottom, left: left};
	return this;
};

/**
 * Set comparison chart anchor (HTML id).
 * @param {string} anchor The desired HTML anchor of the comparison chart.
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.setAnchor = function(anchor) {
	// Accept non-empty anchors
	if (typeof anchor !== 'undefined' && anchor.length > 0)
		this.anchor = anchor;
	return this;
};

/**
 * Set data input and comparison chart output date format.
 * See https://github.com/mbostock/d3/wiki/Time-Formatting
 * @param {string} format The desired date format of the comparison chart.
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.setDateFormat = function(format) {
	// Accept non-empty date formats
	if (typeof format !== 'undefined' && format.length > 0)
		this.dateFormat = format;
	return this;
};

/**
 * Show or hide comparison chart x- and y-axis grid-lines.
 * @param {boolean} xGrid Show (true) or hide (false) x-axis grid-lines.
 * @param {boolean} yGrid Show (true) or hide (false) y-axis grid-lines.
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.setGrid = function(xGrid, yGrid) {
	// Accept two booleans
	if (typeof xGrid === 'boolean' && typeof yGrid === 'boolean') {
		this.xGrid = xGrid;
		this.yGrid = yGrid;
	}
	return this;
};

/**
 * Set CrossCompare source-chart flashing behavior.
 * @param {boolean} active The desired behavior for visually indicating caching.
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.setFlash = function(active) {
	// Accept boolean
	if (typeof active === 'boolean')
		this.flash = active;
	return this;
};

/**
 * Register dc.js chart or HTML selection as name-defining.
 * @param {string/Chart} legend The desired element to be used for the legend.
 * @param {string} title The desired description for this filter (optional).
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.addLegend = function(legend, title) {
	// Accept existing legend element (string or Chart)
	if (typeof legend !== 'undefined')
		this.legends.push({ 'legend': legend, 'title': (title ? title : '') });
	return this;
};

/**
 * Set CrossCompare overwrite behavior.
 * @param {boolean} overwrite The desired behavior for overwriting (true) or
 * keeping (false) data upon re-caching.
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.setOverwrite = function(overwrite) {
	// Accept boolean
	if (typeof overwrite === 'boolean')
		this.overwrite = overwrite;
	return this;
};

/**
 * Adds a dc.js chart with CrossCompare for latter comparison.
 * @param {Chart} chart   The to-be-comparable dc.js chart.
 * @param {JSON}  options Desired options for CrossCompare on how to handle this
 *  chart's comparisons (optional).
 * @return {crosscompare} The crosscompare instance (chain-able).
 */
crosscompare.add = function(chart, options) {

	// Stores all options for the provided chart (default or users')
	var allOptions = {
		'chart': chart, // pointer to source-chart
		'type': 'line', // comparison chart type ('line','line-spline','area','bar')
		'ratio': 0.5, // bar-width ratio for type 'bar'
		'value': 'default', // select specific crossfilter group value
		'anchor': chart.anchor() + '-cross', // id of caching link of source-chart
		'order': 'default', // ordering of comparison data ('default','desc','asc')
		'yLabel': '', // label for y-axis
		'xLabel': '' // label for x-axis
	};

	// If user options have been provided, overwrite default values
	if(typeof options !== 'undefined')
		$.each(options, function(key, value) {
			allOptions[key] = value;
		});

	// Retrieve chart's caching anchor
	var anchor = allOptions.anchor;

	// Store the chart's options with the chart's anchor as key (for later lookup)
	this.charts[anchor] = allOptions;

	// Cache source-chart if anchor clicked
	$(anchor).on('click', function() {
		// Flash source-chart if flash option is activated to indicate caching
		if (crosscompare.flash)
			$(chart.anchor()).fadeTo(10, 0.3).fadeTo(700, 1.0);

		// Update CrossCompare status text variable
		var text = 'You have cached ';
		if ($.isEmptyObject(crosscompare.chart)) // First caching
			text += '1 state.';
		else if (crosscompare.chart.source == chart) // Subsequent caching
			text += (crosscompare.queue.length + 1) + ' states.';
		else { // Caching of an incompatible chart resets cache
			crosscompare.clear();
			text = 'Overwritten with new state.'
		}

		// Update CrossCompare status text in HTML page
		$(crosscompare.anchor + '-info').text(text);

		// Store source-chart pointer within CrossCompare
		crosscompare.chart.source = chart;

		// Cache the data of the related chart (identified via anchor)
		crosscompare.cache(anchor);
	});

	// Return the CrossCompare instance to make this function chain-able
	return this;
};

/**
 * Cache the data of a chart and store it in the queue for later rendering.
 * @param {string} anchor The anchor of the chart.
 */
crosscompare.cache = function(anchor) {

	// Create legend for the cached data
	var legend = '';
	if (this.legends.length == 0) // Enumerate data if no legends defined
		legend += (this.queue.length + 1);
	else {
		// Else, form legend from each defined entry in legends
		$.each(this.legends, function(i, item) {
			// If legend entry is string, handle it as a HTML selection
			if (typeof item.legend === 'string') {
				// If legend entry has description, add legend description
				if (item.title != '')
					legend += item.title + ':';

				// Add legend value
				legend += $(item.legend).val() + ' ';
			} else {
				// Legend entry is DC.js chart with potential filters
				var filters = item.legend.filters(),
						format = d3.time.format(crosscompare.dateFormat);

				// Test if DC.js chart has applied filters
				if (typeof filters !== 'undefined' && filters.length > 0) {
					// If legend entry has description, add legend description
					if (item.title != '')
						legend += item.title + ':';

					// If filters is array, read out filtered range and add to legend
					if (filters[0].constructor === Array) {
						if (filters[0][0] instanceof Date)
							legend += format(filters[0][0]) + ' - ' + format(filters[0][1]) + ' ';
						else
							legend += filters[0][0] + ' - ' + filters[0][1];
					} else
						// Filters is singular value, add to legend
						legend += filters + ' ';
				}
			}
		});

		// An empty legend would result if legends have been added but no filters
		// applied - in this case, show 'All' as legend
		if (legend == '')
			legend = 'ALL ';

		// If overwrite option has been disabled, enumerate cached data with same
		// legend as already existing cache
		if (!this.overwrite)
			// Test for duplicate legend
			$.each(crosscompare.queue, function(key, value) {
				if (value.id == legend)
					legend += '(' + (crosscompare.queue.length + 1) + ')';
			});
	}

	// Retrieve chart and the key of the data field
	var chart = this.charts[anchor].chart;
	var value = this.charts[anchor].value;

	// Cache the chart's data (deep copy)
	var cache = $.extend(true, [], chart.group().all());

	// Retrieve chart's own filters to apply those to the data (as the chart's
	// data is being filtered by crossfilter for all chart-external filters, but
	// not the chart's own filter)
	var filters = chart.filters();

	// For each element in cache, test if it passes the filters and rename it to
	// be identified via the legend as the key, otherwise delete
	var i = cache.length;
	while (i--) {
		// Set chosen value if chart's data is a crossfilter group with multiple
		// values, otherwise take the only value available
		if (value != 'default')
			cache[i].value = cache[i].value[value];

		// If the chart has filters applied, test data
		if (typeof filters !== 'undefined' && filters.length > 0) {
			if (filters[0].constructor === Array) { // Filter is a number range
				if (cache[i].key < filters[0][0] || cache[i].key > filters[0][1])
					// Null value if outside filter range, as to keep x-axis range
					cache[i].value = null;
			} else { // Filter a or multiple specific values
				if (filters.indexOf(cache[i].key) == -1) {
					// Delete instead of null, as to remove category from x-axis
					cache.splice(i, 1);
					continue; // Skip rest of iteration (below) as entry is deleted
				}
			}
		}

		// Rename data field with legend name as to enable C3.js to stack the various
		// caches, as same names would overwrite existing data
		cache[i][legend] = cache[i].value;
		delete cache[i].value;
	};

	// After a legend for the cached data has been created, and the cache has been
	// filtered, add it to cache with the anchor as identifier
	this.queue.push({ 'anchor': anchor, 'id': legend, 'data': cache});
};

/**
 * Resets the current CrossCompare instance and deletes any rendered comparison
 * chart.
 */
crosscompare.reset = function() {
	// Destroy comparison chart if it has been rendered
	var chart = crosscompare.chart.rendered;
	if (typeof chart !== 'undefined')
		chart.destroy();

	// Clear CrossCompare's internal data and option stores
	crosscompare.clear();
};

/**
 * Clears the current CrossCompare instance's internal data and option stores.
 */
crosscompare.clear = function () {
	// Update CrossCompare status text in HTML page
	$(crosscompare.anchor + '-info').text('Cache cleared.');

	// Clear internal stores
	this.chart = {};
	this.queue = [];
};

/**
 * Draws the comparison chart showing all cached data.
 */
crosscompare.render = function() {

	/**
	 * Sorting function for ordering data according to specified order.
	 * See http://stackoverflow.com/questions/881510/sorting-json-by-values
	 * @param  {Array} array  Data to-be-sorted.
	 * @param  {string} key   The key of which values to be compared for order.
	 * @param  {boolean} asc  Specifies ascending (true) or descending (false).
	 */
	function sort(array, key, asc) {
		array = array.sort(function(a, b) {
			if (asc) return (a[key] > b[key]) ? 1 : ((a[key] < b[key]) ? -1 : 0);
			else return (b[key] > a[key]) ? 1 : ((b[key] < a[key]) ? -1 : 0);
		});
	}

	// Test if caches have been queued
	if (this.queue.length > 0) {

		// Update CrossCompare status text in HTML page
		$(crosscompare.anchor + '-info').text('Comparison rendered.');

		// Retrieve chart information and settings
		var anchor = this.queue[0].anchor,
				type = this.charts[anchor].type,
				order = this.charts[anchor].order,
				yLabel = this.charts[anchor].yLabel,
				xLabel = this.charts[anchor].xLabel;

		// Retrieve first data item (exemplary) to test if it is number (or date)
		var n = this.queue[0].data[0].key,
				isDate = n instanceof Date,
				isNumber = !isNaN(parseFloat(n)) && isFinite(n);

		// Set up array for the combined cached data sets, and array to store the
		// name of each combined data set for C3.js to identify as columns (i.e.
		// each data set is being represented as its own line/bar)
		var totalCache = [], columns = [];

		// Over all cached data, find maximum and minimum values for correct scaling
		var globalMin, globalMax;
		$.each(crosscompare.queue, function(index, item) {
			// Retrieve data from the queue's item
			var data = item.data;

			// Find this cache's minimum and maximum if data is numeric (or date) via
			// finding the first or last non-null value (as data is already ordered,
			// but may be padded in null values)
			var min, max;
			if (isDate || isNumber) {
				// Find minimum
				for (i = 0; i < data.length; i++) {
					if (data[i][item.id] != null) {
						min = data[i].key;
						break;
					}
				};

				// Find maximum
				for (i = data.length -1; i >= 0; i--) {
					if (data[i][item.id] != null) {
						max = data[i].key;
						break;
					}
				};

				// Compare this cache's min and max with global min and max of all
				// caches so far (can be skipped for first cache in queue)
				if (index != 0) {
					min = Math.min(min, globalMin);
					max = Math.max(max, globalMax);
				}

				// Update global minimum and maximum
				globalMin = min;
				globalMax = max;
			}

			// Combine all caches and add each cache's name as a column
			$.extend(true, totalCache, data);
			columns.push(item.id);
		});

		// If ordering has been set, retrieve key of values to be ordered by (always
		// sorts by first cache) and sort data
		var orderBy = this.queue[0].id;
		if (order != 'default') {
			if (order == 'asc')
				sort(totalCache, orderBy, true);
			else
				sort(totalCache, orderBy, false);
		}

		// JSON object containing C3.js graphing information
		var options = {
			bindto: crosscompare.anchor,
			size: { height: crosscompare.height },
			padding: crosscompare.padding,
			data: { json: totalCache, keys: { x: 'key', value: columns } },
			zoom: { enabled: true, rescale: true }, // Enable using mouse-wheel to zoom in
			color: { pattern: d3.scale.category10().range() } // D3.js colors
		};

		// If legends have been added, show legend
		if (crosscompare.legends.length == 0)
			options.legend = { show: false };

		// If specific chart width has been set, use provided width
		if (crosscompare.width != 'auto')
			options.size.width = crosscompare.width;

		// If data is numeric (or date), add x-axis formatting information
		if (isDate || isNumber) {
			options.axis = { x: {
					tick: { fit: false },
					min: Number(globalMin),
					max: Number(globalMax)
			} };

			// Add time formatting information for x-axis if data is date
			if (isDate) {
				options.axis.x.type = 'timeseries';
				options.axis.x.tick.format = crosscompare.dateFormat;
			}
		} else
			// If data is non-numeric, add category x-axis information
			options.axis = { x: { type: 'category' } };

		// If comparison chart type is not line, add that type (as C3.js' default
		// chart is line-chart)
		if (type != 'line')
			options.data.type = type;

		// If comparison chart type is bar, add bar-width information
		if (type == 'bar')
			options.bar = { width: { ratio: this.charts[anchor].ratio } };

		// Add information on whether to show or hide x- and y-axis grid-lines
		options.grid = {
			x: { show: crosscompare.xGrid },
			y: { show: crosscompare.yGrid }
		}

		// If y-axis label has been provided, show label
		if (yLabel != '')
			options.axis.y = { label: yLabel };

		// If x-axis label has been provided, show label; Option has to be provided
		// as value (instead of JSON (see yLabel above)), as all previous axis.x
		// options would be overwritten
		if (xLabel != '')
			options.axis.x.label = xLabel;

		// Render comparison chart with compiled options and store pointer
		crosscompare.chart.rendered = c3.generate(options);

	} else
		// Update CrossCompare status text in HTML page if no data has been cached
		$(crosscompare.anchor + '-info').text('Nothing cached.');
};

/**
 * Export to enable CrossCompare usage with Node.js.
 * @exports crosscompare The CrossCompare instance.
 */
if (typeof exports !== 'undefined')
	module.exports = crosscompare;


text:
//  Copyright 2021 Google Inc. All Rights Reserved.
//
//  Licensed under the Apache License, Version 2.0 (the "License");
//  you may not use this file except in compliance with the License.
//  You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.

using NtApiDotNet.Utilities.Reflection;
using System;

namespace NtApiDotNet.Win32.Security.Sam
{
    /// <summary>
    /// Access rights for the SAM group.
    /// </summary>
    [Flags]
    public enum SamGroupAccessRights : uint
    {
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
        None = 0,
        [SDKName("GROUP_READ_INFORMATION")]
        ReadInformation = 0x00000001,
        [SDKName("GROUP_WRITE_ACCOUNT")]
        WriteAccount = 0x00000002,
        [SDKName("GROUP_ADD_MEMBER")]
        AddMember = 0x00000004,
        [SDKName("GROUP_REMOVE_MEMBER")]
        RemoveMember = 0x00000008,
        [SDKName("GROUP_LIST_MEMBERS")]
        ListMembers = 0x00000010,
        [SDKName("GENERIC_READ")]
        GenericRead = GenericAccessRights.GenericRead,
        [SDKName("GENERIC_WRITE")]
        GenericWrite = GenericAccessRights.GenericWrite,
        [SDKName("GENERIC_EXECUTE")]
        GenericExecute = GenericAccessRights.GenericExecute,
        [SDKName("GENERIC_ALL")]
        GenericAll = GenericAccessRights.GenericAll,
        [SDKName("DELETE")]
        Delete = GenericAccessRights.Delete,
        [SDKName("READ_CONTROL")]
        ReadControl = GenericAccessRights.ReadControl,
        [SDKName("WRITE_DAC")]
        WriteDac = GenericAccessRights.WriteDac,
        [SDKName("WRITE_OWNER")]
        WriteOwner = GenericAccessRights.WriteOwner,
        [SDKName("MAXIMUM_ALLOWED")]
        MaximumAllowed = GenericAccessRights.MaximumAllowed,
        [SDKName("ACCESS_SYSTEM_SECURITY")]
        AccessSystemSecurity = GenericAccessRights.AccessSystemSecurity
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
    }
}


text:
'use strict';

//Setting up route
angular.module('mean').config(['$stateProvider', '$urlRouterProvider',
    function($stateProvider, $urlRouterProvider) {

        //================================================
        // Check if the user is connected
        //================================================
        var checkLoggedin = function($q, $timeout, $http, $location){
            // Initialize a new promise
            var deferred = $q.defer();

            // Make an AJAX call to check if the user is logged in
            $http.get('/loggedin').success(function(user){
                // Authenticated
                if (user !== '0')
                    $timeout(deferred.resolve, 0);

                // Not Authenticated
                else {
                    $timeout(function(){deferred.reject();}, 0);
                    $location.url('/login');
                }
            });

            return deferred.promise;
        };
        //================================================
        // Check if the user is not conntect
        //================================================
        var checkLoggedOut = function($q, $timeout, $http, $location){
            // Initialize a new promise
            var deferred = $q.defer();

            // Make an AJAX call to check if the user is logged in
            $http.get('/loggedin').success(function(user){
                // Authenticated
                if (user !== '0'){
                    $timeout(function(){deferred.reject();}, 0);
                    $location.url('/login');

                }

                // Not Authenticated
                else {
                    $timeout(deferred.resolve, 0);

                }
            });

            return deferred.promise;
        };
        //================================================

        // For unmatched routes:
        $urlRouterProvider.otherwise('/');

        // states for my app
        $stateProvider
            .state('all articles', {
                url: '/articles',
                templateUrl: 'views/articles/list.html',
                resolve: {
                    loggedin: checkLoggedin
                }
            })
            .state('create article', {
                url: '/articles/create',
                templateUrl: 'views/articles/create.html',
                resolve: {
                    loggedin: checkLoggedin
                }
            })
            .state('edit article', {
                url: '/articles/:articleId/edit',
                templateUrl: 'views/articles/edit.html',
                resolve: {
                    loggedin: checkLoggedin
                }
            })
            .state('article by id', {
                url: '/articles/:articleId',
                templateUrl: 'views/articles/view.html',
                resolve: {
                    loggedin: checkLoggedin
                }
            })
            .state('account', {
                url: '/account',
                templateUrl: 'views/account.html'
            })
            .state('home', {
                url: '/',
                templateUrl: 'views/index.html'
            })
            .state('auth', {
                templateUrl: 'views/auth/index.html'
            })
            .state('auth.login', {
                url: '/login',
                templateUrl: 'views/auth/login.html',
                resolve: {
                    loggedin: checkLoggedOut
                }
            })
            .state('auth.register', {
                url: '/register',
                templateUrl: 'views/auth/register.html',
                resolve: {
                    loggedin: checkLoggedOut
                }
            });
    }])
    .config(['$locationProvider',
        function($locationProvider) {
            $locationProvider.hashPrefix('!');
        }
    ]);


text:
'use strict';

/* Services */
var dexterServices = angular.module('dexterAnnotator.services', ['ngResource', 'ngCookies']);

dexterServices.factory('Auth', function($resource, $http, $cookies, $q, appConfig, $timeout) {
	var service = {
		updated: false,
		user: undefined
	};

	service.getUser = function() {
		return service.user;
	}

	service.getUsers = function() {
		var user = service.user;
		var Users = $resource(
			appConfig.restApi + '/users',
			{ id:user.uid, psw:user.password },
			{ get: {method:'GET'} }
		);
		return Users.get();
	}

	service.login = function(email, psw) {

		// Initialize a new promise
		var deferred = $q.defer();

		var User = $resource(appConfig.restApi + '/login');
		User.get({email:email, psw:psw}, function(user) {

			// Positive answer
			service.user = user;
			service.updated = true;

			$cookies.uid = user.uid.toString();
			$cookies.psw = user.password;
			$cookies.mail = user.email;

			$timeout(function() {
				deferred.resolve(user);
			}, 0);

		}, function() {
			// Negative answer
			service.logout();

			$timeout(function() {
				service.updated = true;
				deferred.reject('Wrong Credentials');
			}, 0);

		});

		return deferred.promise;
	}

	service.updateLogIn = function() {
		var uid = $cookies.uid;
		var psw = $cookies.psw;

		// Initialize a new promise
		var deferred = $q.defer();

		if (uid && psw && !service.user) {

			var UserDetail = $resource(appConfig.restApi + '/user');
			UserDetail.get({id:uid, psw:psw}, function(user) {

				// Positive answer
				service.user = user;
				service.updated = true;

				$timeout(function() {
					deferred.resolve(user);
				}, 0);

			}, function() {
				// Negative answer
				service.logout();

				$timeout(function() {
					service.updated = true;
					deferred.resolve('Wrong Credentials');
				}, 0);

			});
		} else if (service.user) {
			$timeout(function() {
				service.updated = true;
				deferred.resolve(service.user);
			}, 0);
		} else {
			$timeout(function() {
				service.updated = true;
				deferred.resolve('Missing Credentials');
			}, 0);
		}

		return deferred.promise;
	}

	service.signup = function(firstName, lastName, email, psw) {

		// Initialize a new promise
		var deferred = $q.defer();

		var User = $resource(appConfig.restApi + '/signup');
		User.get({firstName: firstName, lastName: lastName, email:email, psw:psw}, function(user) {

			// Positive answer
			service.user = user;
			service.updated = true;

			$cookies.uid = user.uid.toString();
			$cookies.psw = user.password;
			$cookies.mail = user.email;

			$timeout(function() {
				deferred.resolve(user);
			}, 0);

		}, function(response) {

			$timeout(function() {
				service.updated = true;
				deferred.reject(response.data.error);
			}, 0);

		});

		return deferred.promise;
	}

	service.isUpdated = function() {
		return service.updated;
	}

	service.isLogged = function() {
		return Boolean(service.user);
	}

	service.logout = function() {
		$cookies.uid = undefined;
		$cookies.psw = undefined;
		$cookies.mail = undefined;
		service.user = undefined;
	}

	return service;
});

dexterServices.factory('Annotator', function($resource, $q, $timeout, Auth, appConfig) {
	var service = {
		tasks: undefined
	};

	service.getCollectionTasks = function() {
		return service.tasks;
	}

	service.updateCollectionTasks = function() {

		var CollectionTasks = $resource(appConfig.restApi + '/getCollectionTasks');

		// Initialize a new promise
		var deferred = $q.defer();

		if (!service.tasks) {

			CollectionTasks.get({coll: 'conll'}, function(tasks) {

				// Positive answer
				service.tasks = tasks.value.toLocaleLowerCase().split(',');

				$timeout(function() {
					deferred.resolve(service.tasks);
				}, 0);

			}, function() {

				console.error("Negative answer from updateCollectionTasks");

				// Negative answer
				service.tasks = undefined;
				$timeout(function() {
					deferred.reject('Problem retrieving the collection tasks!');
				}, 0);
			});
		} else {
			$timeout(function() {
				deferred.resolve(service.tasks);
			}, 0);
		}

		return deferred.promise;
	}

	service.getNextDoc = function() {

		if (!Auth.isLogged())
			return undefined;
		var user = Auth.getUser();

		var NextStep = $resource(
			appConfig.restApi + '/next',
			{ coll: 'conll', id:user.uid, psw:user.password },
			{ get: {method:'GET'} }
		);
		return NextStep.get();
	}

	service.getDocument = function(docId, userId) {

		if (!Auth.isLogged())
			return undefined;
		var user = Auth.getUser();
		if (!userId)
			userId = user.uid;

		var Document = $resource(
			appConfig.restApi + '/getAnnotatedDocument',
			{ coll: 'conll', id:user.uid, psw:user.password },
			{ get: {method:'GET'} }
		);
		return Document.get({ docid: docId, userid: userId });
	}

	service.saveProgress = function(docId, status) {

		if (!Auth.isLogged())
			return undefined;
		var user = Auth.getUser();

		var Progress = $resource(
			appConfig.restApi + '/saveProgress',
			{ id:user.uid, psw:user.password },
			{ save: {method:'GET'} }
		);
		return Progress.save({ docId: docId, status: status });
	}

	service.saveUserAnnotation = function(params) {
		// params = { docid: docId, spotid: spotId, e: entityId, spotter: spotter, score: score}
		if (!Auth.isLogged())
			return undefined;

		var user = Auth.getUser();
		var UserAnnotation = $resource(
			appConfig.restApi + '/setUserAnnotation',
			{ spotter: 'std', id: user.uid, psw: user.password },
			{ save: {method:'GET'} }
		);
		return UserAnnotation.save(params);
	}

	service.deleteUserAnnotation = function(params) {
		// params = { docid: docId, spotid: spotId}
		if (!Auth.isLogged())
			return undefined;

		var user = Auth.getUser();
		var UserAnnotation = $resource(
			appConfig.restApi + '/deleteUserAnnotation',
			{ id: user.uid, psw: user.password },
			{ save: {method:'GET'} }
		);

		return UserAnnotation.save(params);
	}

	service.getUserAnnotations = function(params) {
		// params = { coll: collection}
		if (!Auth.isLogged())
			return undefined;

		var user = Auth.getUser();
		var UserAnnotations = $resource(
			appConfig.restApi + '/userAnnotations',
			{ id: user.uid, psw: user.password, coll: 'conll' },
			{ get: {method:'GET', isArray: true} }
		);
		return UserAnnotations.get(params);
	}

	service.getCollectionStatus = function(params) {
		// params = { coll: collection}
		if (!Auth.isLogged())
			return undefined;

		var user = Auth.getUser();
		var CollectionStatus = $resource(
			appConfig.restApi + '/collectionStatus',
			{ id: user.uid, psw: user.password, coll: 'conll' },
			{ get: {method:'GET', isArray: true} }
		);
		return CollectionStatus.get(params);
	}

	service.getLeaderBoard = function(params) {
		// params = { coll: collection}
		if (!Auth.isLogged())
			return undefined;

		var user = Auth.getUser();
		var LeaderBoard = $resource(
			appConfig.restApi + '/leaderBoard',
			{ id: user.uid, psw: user.password, coll: 'conll' },
			{ get: {method:'GET', isArray: true} }
		);
		return LeaderBoard.get(params);
	}

	service.getAnnotationStatus = function(docId, userId) {
		if (!Auth.isLogged())
			return undefined;
		var user = Auth.getUser();
		if (!userId)
			userId = user.uid;

		var user = Auth.getUser();
		var UserAnnotations = $resource(
			appConfig.restApi + '/annotationStatus',
			{ id: user.uid, psw: user.password },
			{ get: {method:'GET'} }
		);
		return UserAnnotations.get({ docid: docId, userId: userId });
	}

	service.saveComment = function(params) {
		// params = { docId: docId, status: status, comment: comment}
		if (!Auth.isLogged())
			return undefined;

		var user = Auth.getUser();
		var UserAnnotations = $resource(
			appConfig.restApi + '/saveComment',
			{ id: user.uid, psw: user.password },
			{ get: {method:'GET'} }
		);
		return UserAnnotations.get(params);
	}

	service.createSpot = function(params) {
		// params = { docid: docId, field: field, start: start, end: end, spot: mention}
		if (!Auth.isLogged())
			return undefined;

		var user = Auth.getUser();
		var Spot = $resource(
			appConfig.restApi + '/createSpot',
			{ id:user.uid, psw:user.password },
			{ create: {method:'GET'} }
		);
		return Spot.create(params);
	}

	return service;
});

dexterServices.factory('EntityLinker', function($resource, $timeout, $q, appConfig) {
	var service = {};

	service.getCandidatesForMention = function(mention) {
		var EntityLinker = $resource(
			appConfig.restELApi + '/jsonp/get-candidates?query=:mention',
			{ callback:'JSON_CALLBACK', n: appConfig['numCandidatesPerSpot'], field: appConfig['fieldToUseForSpotting'] },
			{ getCandidates: {method:'JSONP', isArray: true} }
		);
		return EntityLinker.getCandidates({mention:mention});
	}

	service.getEntityFromTitle = function(title) {
		var EntityLinkerId = $resource(
			appConfig.restELApi + '/jsonp/get-id?title=:title',
			{ callback:'JSON_CALLBACK' },
			{ getId: {method:'JSONP'} }
		);

		var EntityLinkerDescription = $resource(
			appConfig.restELApi + '/jsonp/get-desc?id=:id',
			{ callback:'JSON_CALLBACK' },
			{ getDesc: {method:'JSONP'} }
		);

		// Initialize a new promise
		var deferred = $q.defer();

		EntityLinkerId.getId({title: title}, function(data) {

			if (data.id !== 0) {
				// Positive answer for getId
				EntityLinkerDescription.getDesc({id: data.id}, function(desc) {

					if (desc.title != '') {
						// Positive answer for getDesc
						$timeout(function() {
							deferred.resolve(desc);
						}, 0);
					} else {
						// Negative answer for getDesc
						$timeout(function() {
							deferred.reject('Description not found');
						}, 0);
					}

				}, function() {
					// Negative answer for getDesc
					$timeout(function() {
						deferred.reject('API server problem');
					}, 0);

				});
			} else {
				// Negative answer for getId
				$timeout(function() {
					deferred.reject('Title not found');
				}, 0);
			}

		}, function() {
			// Negative answer for getId
			$timeout(function() {
				deferred.reject('API server problem');
			}, 0);

		});

		return deferred.promise;
	}

	return service;
});