Guest User

bitburner infiltration.js custom v2.6.0

a guest
Mar 12th, 2024
472
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. const state = {
  2.     // Name of the company that's infiltrated.
  3.     company: "",
  4.  
  5.     // Whether infiltration started. False means, we're
  6.     // waiting to arrive on the infiltration screen.
  7.     started: false,
  8.  
  9.     // Details/state of the current mini game.
  10.     // Is reset after every game.
  11.     game: {},
  12. };
  13.  
  14. // Speed of game actions, in milliseconds.
  15. const speed = 22;
  16.  
  17. // Small hack to save RAM.
  18. // This will work smoothly, because the script does not use
  19. // any "ns" functions, it's a pure browser automation tool.
  20. const wnd = eval("window");
  21. const doc = wnd["document"];
  22.  
  23. // List of all games and an automated solver.
  24. const infiltrationGames = [
  25.     {
  26.         name: "type it backward",
  27.         init: function (screen) {            
  28.             const lines = getLines(getEl(screen, "p"));            
  29.             state.game.data = lines[0].split("");            
  30.         },
  31.         play: function (screen) {
  32.             if (!state.game.data || !state.game.data.length) {
  33.                 delete state.game.data;
  34.                 return;
  35.             }
  36.  
  37.             pressKey(state.game.data.shift());
  38.         },
  39.     },
  40.     {
  41.         name: "type it",
  42.         init: function (screen) {            
  43.             const lines = getLines(getEl(screen, "p"));
  44.             state.game.data = lines[0].split("");            
  45.         },
  46.         play: function (screen) {
  47.             if (!state.game.data || !state.game.data.length) {
  48.                 delete state.game.data;
  49.                 return;
  50.             }
  51.  
  52.             pressKey(state.game.data.shift());
  53.         },
  54.     },
  55.     {
  56.         name: "enter the code",
  57.         init: function(screen) {
  58.             console.log("Script initialized. Awaiting game start...");
  59.         },
  60.         play: function(screen) {
  61.             const arrowsText = getEl(screen, "h4")[1].textContent; // Get arrow sequence from the second <h4>
  62.             console.log(`Current sequence: '${arrowsText}'`);
  63.  
  64.             // Determine the last revealed arrow using its index
  65.             const lastArrowIndex = Math.max(...["↑", "↓", "←", "→"].map(arrow => arrowsText.lastIndexOf(arrow)));
  66.  
  67.             if (lastArrowIndex !== -1) { // Arrow found
  68.                 const lastArrow = arrowsText.charAt(lastArrowIndex);
  69.                 console.log(`Responding to the most recent arrow: '${lastArrow}'`);
  70.  
  71.                 // Mapping of arrows to keyboard inputs
  72.                 const keyMap = { "↑": "w", "↓": "s", "←": "a", "→": "d" };
  73.                 console.log(`Pressing '${keyMap[lastArrow]}' for ${lastArrow}`);
  74.                 pressKey(keyMap[lastArrow]);
  75.             } else {
  76.                 console.log("No new arrow to respond to.");
  77.             }
  78.         },
  79.     },
  80.     {
  81.         name: "close the brackets",
  82.         init: function (screen) {
  83.             const data = getLines(getEl(screen, "p"));
  84.             const brackets = data.join("").split("");
  85.             state.game.data = [];
  86.  
  87.             for (let i = brackets.length - 1; i >= 0; i--) {
  88.                 const char = brackets[i];
  89.  
  90.                 if ("<" == char) {
  91.                     state.game.data.push(">");
  92.                 } else if ("(" == char) {
  93.                     state.game.data.push(")");
  94.                 } else if ("{" == char) {
  95.                     state.game.data.push("}");
  96.                 } else if ("[" == char) {
  97.                     state.game.data.push("]");
  98.                 }
  99.             }
  100.         },
  101.         play: function (screen) {
  102.             if (!state.game.data || !state.game.data.length) {
  103.                 delete state.game.data;
  104.                 return;
  105.             }
  106.  
  107.             pressKey(state.game.data.shift());
  108.         },
  109.     },
  110.     {
  111.         name: "attack when his guard is down",
  112.         init: function (screen) {
  113.             console.log("Slash game initialized");
  114.             state.game.data = "wait";
  115.             state.game.guardingTimeStart = new Date().getTime();
  116.             state.game.predictedPreparationTime = Math.random() * 3250 + 1500; // Approximate preparation time
  117.         },
  118.         play: function (screen) {
  119.             if (state.game.data === "done") return; // Exit if game is already done
  120.  
  121.             const currentTime = new Date().getTime();
  122.             const elapsedTime = currentTime - state.game.guardingTimeStart;
  123.  
  124.             // Fetch the current game phase from the screen
  125.             const data = getLines(getEl(screen, "h4"));
  126.             console.log(`Current phase: ${data}`);
  127.  
  128.             // Text Detection
  129.             if ('wait' === state.game.data && (-1 !== data.indexOf("Preparing?") || -1 !== data.indexOf("ATTACKING!"))) {
  130.                 console.log("Text detection trigger activated");
  131.                 state.game.data = "attack";
  132.             }
  133.  
  134.             // Execute Attack
  135.             if ("attack" === state.game.data) {
  136.                 console.log("Pressing spacebar");
  137.                 pressKey(" ");
  138.                 state.game.data = "done";
  139.             }
  140.         },
  141.     },
  142.     {
  143.         name: "say something nice about the guard",
  144.         init: function (screen) { },
  145.         play: function (screen) {
  146.             const correct = [
  147.                 "affectionate",
  148.                 "agreeable",
  149.                 "bright",
  150.                 "charming",
  151.                 "creative",
  152.                 "determined",
  153.                 "energetic",
  154.                 "friendly",
  155.                 "funny",
  156.                 "generous",
  157.                 "polite",
  158.                 "likable",
  159.                 "diplomatic",
  160.                 "helpful",
  161.                 "giving",
  162.                 "kind",
  163.                 "hardworking",
  164.                 "patient",
  165.                 "dynamic",
  166.                 "loyal",
  167.                 "straightforward"
  168.             ];
  169.             const word = getLines(getEl(screen, "h5"))[1];
  170.  
  171.             if (-1 !== correct.indexOf(word)) {
  172.                 pressKey(" ");
  173.             } else {
  174.                 pressKey("w");
  175.             }
  176.         },
  177.     },
  178.     {
  179.         name: "remember all the mines",
  180.         init: function (screen) {
  181.             const rows = getEl(screen, "p");
  182.             let gridSize = null;
  183.             switch (rows.length) {
  184.                 case 9:
  185.                     gridSize = [3, 3];
  186.                     break;
  187.                 case 12:
  188.                     gridSize = [3, 4];
  189.                     break;
  190.                 case 16:
  191.                     gridSize = [4, 4];
  192.                     break;
  193.                 case 20:
  194.                     gridSize = [4, 5];
  195.                     break;
  196.                 case 25:
  197.                     gridSize = [5, 5];
  198.                     break;
  199.                 case 30:
  200.                     gridSize = [5, 6];
  201.                     break;
  202.                 case 36:
  203.                     gridSize = [6, 6];
  204.                     break;
  205.             }
  206.             if (gridSize == null) {
  207.                 return;
  208.             }
  209.             //12 20 30 42
  210.             state.game.data = [];
  211.             let index = 0;
  212.             //for each row
  213.             for (let y = 0; y < gridSize[1]; y++) {
  214.                 //initialize array data
  215.                 state.game.data[y] = [];
  216.                 for (let x = 0; x < gridSize[0]; x++) {
  217.                     //for each column in the row add to state data if it has a child
  218.                     if (rows[index].children.length > 0) {
  219.                         state.game.data[y].push(true);
  220.                     } else state.game.data[y].push(false);
  221.                     index += 1;
  222.                 }
  223.             }
  224.         },
  225.         play: function (screen) { },
  226.     },
  227.     {
  228.         name: "mark all the mines",
  229.         init: function (screen) {
  230.             state.game.x = 0;
  231.             state.game.y = 0;
  232.             state.game.cols = state.game.data[0].length;
  233.             state.game.dir = 1;
  234.         },
  235.         play: function (screen) {
  236.             let { data, x, y, cols, dir } = state.game;
  237.  
  238.             if (data[y][x]) {
  239.                 pressKey(" ");
  240.                 data[y][x] = false;
  241.             }
  242.  
  243.             x += dir;
  244.  
  245.             if (x < 0 || x >= cols) {
  246.                 x = Math.max(0, Math.min(cols - 1, x));
  247.                 y++;
  248.                 dir *= -1;
  249.                 pressKey("s");
  250.             } else {
  251.                 pressKey(dir > 0 ? "d" : "a");
  252.             }
  253.  
  254.             state.game.data = data;
  255.             state.game.x = x;
  256.             state.game.y = y;
  257.             state.game.dir = dir;
  258.         },
  259.     },
  260.     {
  261.         name: "match the symbols",
  262.         init: function (screen) {
  263.             const data = getLines(getEl(screen, "h5 span"));
  264.             const rows = getLines(getEl(screen, "p"));
  265.             const keypad = [];
  266.             const targets = [];
  267.             let gridSize = null;
  268.             switch (rows.length) {
  269.                 case 9:
  270.                     gridSize = [3, 3];
  271.                     break;
  272.                 case 12:
  273.                     gridSize = [3, 4];
  274.                     break;
  275.                 case 16:
  276.                     gridSize = [4, 4];
  277.                     break;
  278.                 case 20:
  279.                     gridSize = [4, 5];
  280.                     break;
  281.                 case 25:
  282.                     gridSize = [5, 5];
  283.                     break;
  284.                 case 30:
  285.                     gridSize = [5, 6];
  286.                     break;
  287.                 case 36:
  288.                     gridSize = [6, 6];
  289.                     break;
  290.             }
  291.             if (gridSize == null) {
  292.                 return;
  293.             }
  294.             //build the keypad grid.
  295.             let index = 0;
  296.             for (let i = 0; i < gridSize[1]; i++) {
  297.                 keypad[i] = [];
  298.                 for (let y = 0; y < gridSize[0]; y++) {
  299.  
  300.                     keypad[i].push(rows[index]);
  301.                     index += 1;
  302.                 }
  303.             }
  304.             //foreach data get coords of keypad entry
  305.             for (let i = 0; i < data.length; i++) {
  306.                 const symbol = data[i].trim();
  307.                 //for each keypad entry
  308.                 for (let j = 0; j < keypad.length; j++) {
  309.                     const k = keypad[j].indexOf(symbol);
  310.  
  311.                     if (-1 !== k) {
  312.                         targets.push([j, k]);
  313.                         break;
  314.                     }
  315.                 }
  316.             }
  317.             state.game.data = targets;
  318.             state.game.x = 0;
  319.             state.game.y = 0;
  320.         },
  321.         play: function (screen) {
  322.             const target = state.game.data[0];
  323.             let { x, y } = state.game;
  324.  
  325.             if (!target) {
  326.                 return;
  327.             }
  328.  
  329.             const to_y = target[0];
  330.             const to_x = target[1];
  331.  
  332.             if (to_y < y) {
  333.                 y--;
  334.                 pressKey("w");
  335.             } else if (to_y > y) {
  336.                 y++;
  337.                 pressKey("s");
  338.             } else if (to_x < x) {
  339.                 x--;
  340.                 pressKey("a");
  341.             } else if (to_x > x) {
  342.                 x++;
  343.                 pressKey("d");
  344.             } else {
  345.                 pressKey(" ");
  346.                 state.game.data.shift();
  347.             }
  348.  
  349.             state.game.x = x;
  350.             state.game.y = y;
  351.         },
  352.     },
  353.     {
  354.         name: "cut the wires with the following properties",
  355.         init: function (screen) {
  356.             let numberHack = ["1","2","3","4","5","6","7","8","9"];
  357.             const colors = {
  358.                 red: "red",
  359.                 white: "white",
  360.                 blue: "blue",
  361.                 "rgb(255, 193, 7)": "yellow",
  362.             };
  363.             const wireColor = {
  364.                 red: [],
  365.                 white: [],
  366.                 blue: [],
  367.                 yellow: [],
  368.             };
  369.             //gather the instructions
  370.             var instructions = []
  371.             for (let child of screen.children) instructions.push(child);
  372.             var wiresData = instructions.pop();
  373.             instructions.shift();
  374.             instructions = getLines(instructions);
  375.             //get the wire information
  376.             const samples = getEl(wiresData, "p");
  377.             const wires = [];
  378.             //get the amount of wires
  379.             let wireCount = 0;
  380.             for (let i = wireCount; i < samples.length; i++) {
  381.                 if (numberHack.includes(samples[i].innerText)) wireCount += 1;
  382.                 else break;
  383.             }
  384.             let index = 0;
  385.             //get just the first 3 rows of wires.
  386.             for (let i = 0; i < 3; i++) {
  387.                 //for each row
  388.                 for (let j = 0; j < wireCount; j++) {
  389.                     const node = samples[index];
  390.                     const color = colors[node.style.color];
  391.                     if (!color) {
  392.                         index += 1;
  393.                         continue;
  394.                     }
  395.                     wireColor[color].push(j+1);
  396.                     index += 1;
  397.                 }
  398.             }
  399.  
  400.             for (let i = 0; i < instructions.length; i++) {
  401.                 const line = instructions[i].trim().toLowerCase();
  402.  
  403.                 if (!line || line.length < 10) {
  404.                     continue;
  405.                 }
  406.                 if (-1 !== line.indexOf("cut wires number")) {
  407.                     const parts = line.split(/(number\s*|\.)/);
  408.                     wires.push(parseInt(parts[2]));
  409.                 }
  410.                 if (-1 !== line.indexOf("cut all wires colored")) {
  411.                     const parts = line.split(/(colored\s*|\.)/);
  412.                     const color = parts[2];
  413.  
  414.                     if (!wireColor[color]) {
  415.                         // should never happen.
  416.                         continue;
  417.                     }
  418.  
  419.                     wireColor[color].forEach((num) => wires.push(num));
  420.                 }
  421.             }
  422.  
  423.             // new Set() removes duplicate elements.
  424.             state.game.data = [...new Set(wires)];
  425.         },
  426.         play: function (screen) {
  427.             const wire = state.game.data;
  428.             //state.game.data.shift();
  429.             if (!wire) {
  430.                 return;
  431.             }
  432.             for (let i=0;i<wire.length;i++) {
  433.                 pressKey(wire[i].toString());
  434.             }
  435.         },
  436.     },
  437. ];
  438.  
  439. /** @param {NS} ns **/
  440. export async function main(ns) {
  441.     const args = ns.flags([
  442.         ["start", false],
  443.         ["stop", false],
  444.         ["status", false],
  445.         ["quiet", false],
  446.     ]);
  447.  
  448.     function print(msg) {
  449.         if (!args.quiet) {
  450.             ns.tprint(`\n${msg}\n`);
  451.         }
  452.     }
  453.  
  454.     if (args.status) {
  455.         if (wnd.tmrAutoInf) {
  456.             print("Automated infiltration is active");
  457.         } else {
  458.             print("Automated infiltration is inactive");
  459.         }
  460.         return;
  461.     }
  462.  
  463.     if (wnd.tmrAutoInf) {
  464.         print("Stopping automated infiltration...");
  465.         clearInterval(wnd.tmrAutoInf);
  466.         delete wnd.tmrAutoInf;
  467.     }
  468.  
  469.     if (args.stop) {
  470.         return;
  471.     }
  472.  
  473.     print(
  474.         "Automated infiltration is enabled...\nVWhen you visit the infiltration screen of any company, all tasks are completed automatically."
  475.     );
  476.  
  477.     endInfiltration();
  478.  
  479.     // Monitor the current screen and start infiltration once a
  480.     // valid screen is detected.
  481.     wnd.tmrAutoInf = setInterval(infLoop, speed);
  482.  
  483.     // Modify the addEventListener logic.
  484.     wrapEventListeners();
  485. }
  486.  
  487. /**
  488.  * The infiltration loop, which is called at a rapid interval
  489.  */
  490. function infLoop() {
  491.     if (!state.started) {
  492.         waitForStart();
  493.     } else {
  494.         playGame();
  495.     }
  496. }
  497.  
  498. /**
  499.  * Returns a list of DOM elements from the main game
  500.  * container.
  501.  */
  502. function getEl(parent, selector) {
  503.     let prefix = ":scope";
  504.  
  505.     if ("string" === typeof parent) {
  506.         selector = parent;
  507.         parent = doc;
  508.  
  509.         prefix = ".MuiBox-root>.MuiBox-root>.MuiBox-root";
  510.  
  511.         if (!doc.querySelectorAll(prefix).length) {
  512.             prefix = ".MuiBox-root>.MuiBox-root>.MuiGrid-root";
  513.         }
  514.         if (!doc.querySelectorAll(prefix).length) {
  515.             prefix = ".MuiContainer-root>.MuiPaper-root";
  516.         }
  517.         if (!doc.querySelectorAll(prefix).length) {
  518.             return [];
  519.         }
  520.     }
  521.  
  522.     selector = selector.split(",");
  523.     selector = selector.map((item) => `${prefix} ${item}`);
  524.     selector = selector.join(",");
  525.  
  526.     return parent.querySelectorAll(selector);
  527. }
  528.  
  529. /**
  530.  * Returns the first element with matching text content.
  531.  */
  532. function filterByText(elements, text) {
  533.     text = text.toLowerCase();
  534.  
  535.     for (let i = 0; i < elements.length; i++) {
  536.         const content = elements[i].textContent.toLowerCase();
  537.  
  538.         if (-1 !== content.indexOf(text)) {
  539.             return elements[i];
  540.         }
  541.     }
  542.  
  543.     return null;
  544. }
  545.  
  546. /**
  547.  * Returns an array with the text-contents of the given elements.
  548.  *
  549.  * @param {NodeList} elements
  550.  * @returns {string[]}
  551.  */
  552. function getLines(elements) {
  553.     const lines = [];
  554.     elements.forEach((el) => lines.push(el.textContent));
  555.  
  556.     return lines;
  557. }
  558.  
  559. /**
  560.  * Reset the state after infiltration is done.
  561.  */
  562. function endInfiltration() {
  563.     unwrapEventListeners();
  564.     state.company = "";
  565.     state.started = false;
  566. }
  567.  
  568. /**
  569.  * Simulate a keyboard event (keydown + keyup).
  570.  *
  571.  * @param {string|int} keyOrCode A single letter (string) or key-code to send.
  572.  */
  573. function pressKey(keyOrCode) {
  574.     let keyCode = 0;
  575.     let key = "";
  576.  
  577.     if ("string" === typeof keyOrCode && keyOrCode.length > 0) {
  578.         key = keyOrCode.toLowerCase().substr(0, 1);
  579.         keyCode = key.charCodeAt(0);
  580.     } else if ("number" === typeof keyOrCode) {
  581.         keyCode = keyOrCode;
  582.         key = String.fromCharCode(keyCode);
  583.     }
  584.  
  585.     if (!keyCode || key.length !== 1) {
  586.         return;
  587.     }
  588.  
  589.     function sendEvent(event) {
  590.         const keyboardEvent = new KeyboardEvent(event, {
  591.             key,
  592.             keyCode,
  593.         });
  594.  
  595.         doc.dispatchEvent(keyboardEvent);
  596.     }
  597.  
  598.     sendEvent("keydown");
  599. }
  600.  
  601. /**
  602.  * Infiltration monitor to start automatic infiltration.
  603.  *
  604.  * This function runs asynchronously, after the "main" function ended,
  605.  * so we cannot use any "ns" function here!
  606.  */
  607. function waitForStart() {
  608.     if (state.started) {
  609.         return;
  610.     }
  611.  
  612.     const h4 = getEl("h4");
  613.  
  614.     if (!h4.length) {
  615.         return;
  616.     }
  617.     const title = h4[0].textContent;
  618.     if (0 !== title.indexOf("Infiltrating")) {
  619.         return;
  620.     }
  621.  
  622.     const btnStart = filterByText(getEl("button"), "Start");
  623.     if (!btnStart) {
  624.         return;
  625.     }
  626.  
  627.     state.company = title.substr(13);
  628.     state.started = true;
  629.     wrapEventListeners();
  630.  
  631.     console.log("Start automatic infiltration of", state.company);
  632.     btnStart.click();
  633. }
  634.  
  635. /**
  636.  * Identify the current infiltration game.
  637.  */
  638. function playGame() {
  639.     const screens = doc.querySelectorAll(".MuiContainer-root");
  640.  
  641.     if (!screens.length) {
  642.         endInfiltration();
  643.         return;
  644.     }
  645.     if (screens[0].children.length < 3) {
  646.         return;
  647.     }
  648.  
  649.     const screen = screens[0].children[2];
  650.     const h4 = getEl(screen, "h4");
  651.  
  652.     if (!h4.length) {
  653.         endInfiltration();
  654.         return;
  655.     }
  656.  
  657.     const title = h4[0].textContent.trim().toLowerCase().split(/[!.(]/)[0];
  658.  
  659.     if ("infiltration successful" === title) {
  660.         endInfiltration();
  661.         return;
  662.     }
  663.  
  664.     if ("get ready" === title) {
  665.         return;
  666.     }
  667.  
  668.     const game = infiltrationGames.find((game) => game.name === title);
  669.  
  670.     if (game) {
  671.         if (state.game.current !== title) {
  672.             state.game.current = title;
  673.             game.init(screen);
  674.         }
  675.  
  676.         game.play(screen);
  677.     } else {
  678.         console.error("Unknown game:", title);
  679.     }
  680. }
  681.  
  682. /**
  683.  * Wrap all event listeners with a custom function that injects
  684.  * the "isTrusted" flag.
  685.  *
  686.  * Is this cheating? Or is it real hacking? Don't care, as long
  687.  * as it's working :)
  688.  */
  689. function wrapEventListeners() {
  690.     if (!doc._addEventListener) {
  691.         doc._addEventListener = doc.addEventListener;
  692.  
  693.         doc.addEventListener = function (type, callback, options) {
  694.             if ("undefined" === typeof options) {
  695.                 options = false;
  696.             }
  697.             let handler = false;
  698.  
  699.             // For this script, we only want to modify "keydown" events.
  700.             if ("keydown" === type) {
  701.                 handler = function (...args) {
  702.                     if (!args[0].isTrusted) {
  703.                         const hackedEv = {};
  704.  
  705.                         for (const key in args[0]) {
  706.                             if ("isTrusted" === key) {
  707.                                 hackedEv.isTrusted = true;
  708.                             } else if ("function" === typeof args[0][key]) {
  709.                                 hackedEv[key] = args[0][key].bind(args[0]);
  710.                             } else {
  711.                                 hackedEv[key] = args[0][key];
  712.                             }
  713.                         }
  714.  
  715.                         args[0] = hackedEv;
  716.                     }
  717.  
  718.                     return callback.apply(callback, args);
  719.                 };
  720.  
  721.                 for (const prop in callback) {
  722.                     if ("function" === typeof callback[prop]) {
  723.                         handler[prop] = callback[prop].bind(callback);
  724.                     } else {
  725.                         handler[prop] = callback[prop];
  726.                     }
  727.                 }
  728.             }
  729.  
  730.             if (!this.eventListeners) {
  731.                 this.eventListeners = {};
  732.             }
  733.             if (!this.eventListeners[type]) {
  734.                 this.eventListeners[type] = [];
  735.             }
  736.             this.eventListeners[type].push({
  737.                 listener: callback,
  738.                 useCapture: options,
  739.                 wrapped: handler,
  740.             });
  741.  
  742.             return this._addEventListener(
  743.                 type,
  744.                 handler ? handler : callback,
  745.                 options
  746.             );
  747.         };
  748.     }
  749.  
  750.     if (!doc._removeEventListener) {
  751.         doc._removeEventListener = doc.removeEventListener;
  752.  
  753.         doc.removeEventListener = function (type, callback, options) {
  754.             if ("undefined" === typeof options) {
  755.                 options = false;
  756.             }
  757.  
  758.             if (!this.eventListeners) {
  759.                 this.eventListeners = {};
  760.             }
  761.             if (!this.eventListeners[type]) {
  762.                 this.eventListeners[type] = [];
  763.             }
  764.  
  765.             for (let i = 0; i < this.eventListeners[type].length; i++) {
  766.                 if (
  767.                     this.eventListeners[type][i].listener === callback &&
  768.                     this.eventListeners[type][i].useCapture === options
  769.                 ) {
  770.                     if (this.eventListeners[type][i].wrapped) {
  771.                         callback = this.eventListeners[type][i].wrapped;
  772.                     }
  773.  
  774.                     this.eventListeners[type].splice(i, 1);
  775.                     break;
  776.                 }
  777.             }
  778.  
  779.             if (this.eventListeners[type].length == 0) {
  780.                 delete this.eventListeners[type];
  781.             }
  782.  
  783.             return this._removeEventListener(type, callback, options);
  784.         };
  785.     }
  786. }
  787.  
  788. /**
  789.  * Revert the "wrapEventListeners" changes.
  790.  */
  791. function unwrapEventListeners() {
  792.     if (doc._addEventListener) {
  793.         doc.addEventListener = doc._addEventListener;
  794.         delete doc._addEventListener;
  795.     }
  796.     if (doc._removeEventListener) {
  797.         doc.removeEventListener = doc._removeEventListener;
  798.         delete doc._removeEventListener;
  799.     }
  800.     delete doc.eventListeners;
  801. }
Advertisement
Add Comment
Please, Sign In to add comment