đó anh em biết cái này cái gì:
{"version":3,"sources":["webpack:///webpack/bootstrap 904acc8fd883d952de40","webpack:///./include.preload.js","webpack:///./adblockpluscore/lib/content/elemHideEmulation.js","webpack:///./adblockpluscore/lib/common.js","webpack:///./inject.preload.js"],"names":[],"mappings":";QAAA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;QACA;;QAEA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;;;QAGA;QACA;;QAEA;QACA;;QAEA;QACA;QACA;QACA;QACA;QACA;QACA;QACA,KAAK;QACL;QACA;;QAEA;QACA;QACA;QACA,2BAA2B,0BAA0B,EAAE;QACvD,iCAAiC,eAAe;QAChD;QACA;QACA;;QAEA;QACA,sDAAsD,+DAA+D;;QAErH;QACA;;QAEA;QACA;;;;;;;;;;;;;;;;AC7DA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;;AAEa;;AAEb,KAAK,kBAAkB;AACvB,EAAE,mBAAO,CAAC,CAAiD;;AAE3D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,iBAAiB,iBAAiB;AAClC;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,6DAA6D;AAC7D;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;;AAEA;AACA;AACA;AACA;AACA,iCAAiC,oCAAoC;AACrE;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA,mBAAmB,8BAA8B;AACjD;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,8BAA8B;AACnD;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,KAAK;AACL,GAAG;;AAEH;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,KAAK;AACL;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA,KAAK;AACL;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA,GAAG;;AAEH;AACA;AACA;AACA;AACA;AACA,GAAG;AACH;;AAEA;AACA;AACA;AACA;;;;;;;;ACxgBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEa;;AAEb,OAAO;AACP,uBAAuB,GAAG,mBAAO,CAAC,CAAW;;AAE7C;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA,wDAAwD,aAAa;AACrE;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,yEAAyE;AACzE;AACA;AACA;AACA,yCAAyC,kCAAkC;AAC3E;AACA;;AAEA;AACA;AACA,WAAW,KAAK;AAChB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,yBAAyB,aAAa,aAAa,IAAI;AACvD;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,QAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,UAAU;AACV;;AAEA;AACA;AACA,aAAa,OAAO;AACpB,cAAc,OAAO;AACrB,cAAc,SAAS;AACvB;;AAEA;AACA;AACA,WAAW,aAAa;AACxB,YAAY,iBAAiB;AAC7B;AACA;AACA;AACA;AACA,iBAAiB,uBAAuB;AACxC;AACA;AACA;AACA;AACA,mBAAmB,SAAS,IAAI,MAAM,EAAE,iCAAiC;AACzE;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,KAAK;AAChB,WAAW,OAAO;AAClB,WAAW,KAAK;AAChB;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB;AACA,YAAY,QAAQ;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,KAAK;AAClB,aAAa,mBAAmB;AAChC,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,OAAO;AACpB,aAAa,KAAK;AAClB,aAAa,mBAAmB;AAChC,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA,mCAAmC,uBAAuB;AAC1D;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,OAAO;AACpB,cAAc,MAAM;AACpB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,+CAA+C,SAAS;AACxD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,+CAA+C,SAAS;AACxD,yDAAyD,SAAS;AAClE;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA,+CAA+C,SAAS;AACxD;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,gBAAgB;AAC7B;AACA;AACA;AACA;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA,aAAa,SAAS;AACtB;AACA;AACA;AACA;AACA;AACA;;AAEA,kDAAkD,uBAAuB;;AAEzE;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA,aAAa,gBAAgB;AAC7B;AACA;AACA,aAAa,iBAAiB;AAC9B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA,uCAAuC;AACvC;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA;AACA,mCAAmC;AACnC;AACA;AACA;AACA,qCAAqC;AACrC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,UAAU,8BAA8B,gBAAgB,WAAW;AACnE;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;ACj/BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEa;;AAEb;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA,0CAA0C;AAC1C;;AAEA;AACA;AACA,WAAW,OAAO;AAClB,YAAY,OAAO;AACnB;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA,iBAAiB,qBAAqB;AACtC;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA,eAAe;AACf;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAgB;AAChB;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,wBAAwB;AACxB;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA,WAAW,OAAO;AAClB,WAAW,OAAO;AAClB,aAAa,OAAO;AACpB;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA,kCAAkC;AAClC;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;;;;;;;ACpOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,4BAA4B;AAC5B;AACA;AACA;AACA;AACA;AACA;;AAEa;;AAEb;;AAEA;AACA;AACA;AACA;AACA,OAAO,IAAI;;AAEX;AACA;AACA;AACA,GAAG;AACH;AACA;AACA,oCAAoC;AACpC;AACA,GAAG;AACH,CAAC;;AAED;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,mEAAmE;AACnE;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA,oDAAoD,SAAS,KAAK;AAClE;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAS,qCAAqC;;AAE9C;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA,qBAAqB,sBAAsB;AAC3C;AACA;AACA;AACA;AACA,SAAS;AACT;AACA;AACA;AACA;AACA,OAAO;AACP;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,eAAe,UAAU;;AAEzB;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA,aAAa;AACb;AACA;AACA;AACA;AACA,WAAW;AACX;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO;AACP;;AAEA;AACA;AACA;AACA;AACA,uBAAuB,qCAAqC;AAC5D;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA,6BAA6B,2BAA2B;AACxD;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,8DAA8D;;AAE9D;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA","file":"include.preload.js","sourcesContent":[" \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 904acc8fd883d952de40","/*\n * This file is part of Adblock Plus <https://adblockplus.org/>,\n * Copyright (C) 2006-present eyeo GmbH\n *\n * Adblock Plus is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 3 as\n * published by the Free Software Foundation.\n *\n * Adblock Plus is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.\n */\n\n\"use strict\";\n\nlet {ElemHideEmulation} =\n require(\"./adblockpluscore/lib/content/elemHideEmulation\");\n\n// This variable is also used by our other content scripts.\nlet contentFiltering;\n\nconst typeMap = new Map([\n [\"img\", \"IMAGE\"],\n [\"input\", \"IMAGE\"],\n [\"picture\", \"IMAGE\"],\n [\"audio\", \"MEDIA\"],\n [\"video\", \"MEDIA\"],\n [\"frame\", \"SUBDOCUMENT\"],\n [\"iframe\", \"SUBDOCUMENT\"],\n [\"object\", \"OBJECT\"],\n [\"embed\", \"OBJECT\"]\n]);\n\nlet checkedSelectors = new Set();\n\nfunction getURLsFromObjectElement(element)\n{\n let url = element.getAttribute(\"data\");\n if (url)\n return [url];\n\n for (let child of element.children)\n {\n if (child.localName != \"param\")\n continue;\n\n let name = child.getAttribute(\"name\");\n if (name != \"movie\" && // Adobe Flash\n name != \"source\" && // Silverlight\n name != \"src\" && // Real Media + Quicktime\n name != \"FileName\") // Windows Media\n continue;\n\n let value = child.getAttribute(\"value\");\n if (!value)\n continue;\n\n return [value];\n }\n\n return [];\n}\n\nfunction getURLsFromAttributes(element)\n{\n let urls = [];\n\n if (element.getAttribute(\"src\") && \"src\" in element)\n urls.push(element.src);\n\n if (element.srcset)\n {\n for (let candidate of element.srcset.split(\",\"))\n {\n let url = candidate.trim().replace(/\\s+\\S+$/, \"\");\n if (url)\n urls.push(url);\n }\n }\n\n return urls;\n}\n\nfunction getURLsFromMediaElement(element)\n{\n let urls = getURLsFromAttributes(element);\n\n for (let child of element.children)\n {\n if (child.localName == \"source\" || child.localName == \"track\")\n urls.push(...getURLsFromAttributes(child));\n }\n\n if (element.poster)\n urls.push(element.poster);\n\n return urls;\n}\n\nfunction getURLsFromElement(element)\n{\n let urls;\n switch (element.localName)\n {\n case \"object\":\n urls = getURLsFromObjectElement(element);\n break;\n\n case \"video\":\n case \"audio\":\n case \"picture\":\n urls = getURLsFromMediaElement(element);\n break;\n\n default:\n urls = getURLsFromAttributes(element);\n break;\n }\n\n for (let i = 0; i < urls.length; i++)\n {\n if (/^(?!https?:)[\\w-]+:/i.test(urls[i]))\n urls.splice(i--, 1);\n }\n\n return urls;\n}\n\nfunction getSelectorForBlockedElement(element)\n{\n // Microsoft Edge does not support CSS.escape(). However, it doesn't\n // support user style sheets either. So the selector would be added\n // with an author style sheet anyway, which doesn't provide any benefits.\n if (!(\"escape\" in CSS))\n return null;\n\n // Setting the \"display\" CSS property to \"none\" doesn't have any effect on\n // <frame> elements (in framesets). So we have to hide it inline through\n // the \"visibility\" CSS property.\n if (element.localName == \"frame\")\n return null;\n\n // If the <video> or <audio> element contains any <source> or <track>\n // children, we cannot address it in CSS by the source URL; in that case we\n // don't \"collapse\" it using a CSS selector but rather hide it directly by\n // setting the style=\"...\" attribute.\n if (element.localName == \"video\" || element.localName == \"audio\")\n {\n for (let child of element.children)\n {\n if (child.localName == \"source\" || child.localName == \"track\")\n return null;\n }\n }\n\n let selector = \"\";\n for (let attr of [\"src\", \"srcset\"])\n {\n let value = element.getAttribute(attr);\n if (value && attr in element)\n selector += \"[\" + attr + \"=\" + CSS.escape(value) + \"]\";\n }\n\n return selector ? element.localName + selector : null;\n}\n\nfunction hideElement(element)\n{\n function doHide()\n {\n let propertyName = \"display\";\n let propertyValue = \"none\";\n if (element.localName == \"frame\")\n {\n propertyName = \"visibility\";\n propertyValue = \"hidden\";\n }\n\n if (element.style.getPropertyValue(propertyName) != propertyValue ||\n element.style.getPropertyPriority(propertyName) != \"important\")\n element.style.setProperty(propertyName, propertyValue, \"important\");\n }\n\n doHide();\n\n new MutationObserver(doHide).observe(\n element, {\n attributes: true,\n attributeFilter: [\"style\"]\n }\n );\n}\n\nfunction checkCollapse(element)\n{\n let mediatype = typeMap.get(element.localName);\n if (!mediatype)\n return;\n\n let urls = getURLsFromElement(element);\n if (urls.length == 0)\n return;\n\n let selector = getSelectorForBlockedElement(element);\n if (selector)\n {\n if (checkedSelectors.has(selector))\n return;\n checkedSelectors.add(selector);\n }\n\n browser.runtime.sendMessage(\n {\n type: \"filters.collapse\",\n urls,\n mediatype,\n baseURL: document.location.href\n }).then(collapse =>\n {\n if (collapse)\n {\n if (selector)\n contentFiltering.addSelectors([selector], \"collapsing\", true);\n else\n hideElement(element);\n }\n });\n}\n\nfunction checkSitekey()\n{\n let attr = document.documentElement.getAttribute(\"data-adblockkey\");\n if (attr)\n browser.runtime.sendMessage({type: \"filters.addKey\", token: attr});\n}\n\nfunction ElementHidingTracer(selectors, exceptions)\n{\n this.selectors = selectors;\n this.exceptions = exceptions;\n this.changedNodes = [];\n this.timeout = null;\n this.observer = new MutationObserver(this.observe.bind(this));\n this.trace = this.trace.bind(this);\n\n if (document.readyState == \"loading\")\n document.addEventListener(\"DOMContentLoaded\", this.trace);\n else\n this.trace();\n}\nElementHidingTracer.prototype = {\n checkNodes(nodes)\n {\n let effectiveSelectors = [];\n let effectiveExceptions = [];\n\n for (let selector of this.selectors)\n {\n nodes: for (let node of nodes)\n {\n for (let element of node.querySelectorAll(selector))\n {\n // Only consider selectors that actually have an effect on the\n // computed styles, and aren't overridden by rules with higher\n // priority, or haven't been circumvented in a different way.\n if (getComputedStyle(element).display == \"none\")\n {\n effectiveSelectors.push(selector);\n break nodes;\n }\n }\n }\n }\n\n for (let exception of this.exceptions)\n {\n for (let node of nodes)\n {\n if (node.querySelector(exception.selector))\n {\n effectiveExceptions.push(exception.text);\n break;\n }\n }\n }\n\n if (effectiveSelectors.length > 0 || effectiveExceptions.length > 0)\n {\n browser.runtime.sendMessage({\n type: \"hitLogger.traceElemHide\",\n selectors: effectiveSelectors,\n filters: effectiveExceptions\n });\n }\n },\n\n onTimeout()\n {\n this.checkNodes(this.changedNodes);\n this.changedNodes = [];\n this.timeout = null;\n },\n\n observe(mutations)\n {\n // Forget previously changed nodes that are no longer in the DOM.\n for (let i = 0; i < this.changedNodes.length; i++)\n {\n if (!document.contains(this.changedNodes[i]))\n this.changedNodes.splice(i--, 1);\n }\n\n for (let mutation of mutations)\n {\n let node = mutation.target;\n\n // Ignore mutations of nodes that aren't in the DOM anymore.\n if (!document.contains(node))\n continue;\n\n // Since querySelectorAll() doesn't consider the root itself\n // and since CSS selectors can also match siblings, we have\n // to consider the parent node for attribute mutations.\n if (mutation.type == \"attributes\")\n node = node.parentNode;\n\n let addNode = true;\n for (let i = 0; i < this.changedNodes.length; i++)\n {\n let previouslyChangedNode = this.changedNodes[i];\n\n // If we are already going to check an ancestor of this node,\n // we can ignore this node, since it will be considered anyway\n // when checking one of its ancestors.\n if (previouslyChangedNode.contains(node))\n {\n addNode = false;\n break;\n }\n\n // If this node is an ancestor of a node that previously changed,\n // we can ignore that node, since it will be considered anyway\n // when checking one of its ancestors.\n if (node.contains(previouslyChangedNode))\n this.changedNodes.splice(i--, 1);\n }\n\n if (addNode)\n this.changedNodes.push(node);\n }\n\n // Check only nodes whose descendants have changed, and not more often\n // than once a second. Otherwise large pages with a lot of DOM mutations\n // (like YouTube) freeze when the devtools panel is active.\n if (this.timeout == null)\n this.timeout = setTimeout(this.onTimeout.bind(this), 1000);\n },\n\n trace()\n {\n this.checkNodes([document]);\n\n this.observer.observe(\n document,\n {\n childList: true,\n attributes: true,\n subtree: true\n }\n );\n },\n\n disconnect()\n {\n document.removeEventListener(\"DOMContentLoaded\", this.trace);\n this.observer.disconnect();\n clearTimeout(this.timeout);\n }\n};\n\nfunction ContentFiltering()\n{\n this.styles = new Map();\n this.tracer = null;\n\n this.elemHideEmulation = new ElemHideEmulation(this.hideElements.bind(this));\n}\nContentFiltering.prototype = {\n addRulesInline(rules, groupName = \"standard\", appendOnly = false)\n {\n let style = this.styles.get(groupName);\n\n if (style && !appendOnly)\n {\n while (style.sheet.cssRules.length > 0)\n style.sheet.deleteRule(0);\n }\n\n if (rules.length == 0)\n return;\n\n if (!style)\n {\n // Create <style> element lazily, only if we add styles. Add it to\n // the <head> or <html> element. If we have injected a style element\n // before that has been removed (the sheet property is null), create a\n // new one.\n style = document.createElement(\"style\");\n (document.head || document.documentElement).appendChild(style);\n\n // It can happen that the frame already navigated to a different\n // document while we were waiting for the background page to respond.\n // In that case the sheet property may stay null, after adding the\n // <style> element.\n if (!style.sheet)\n return;\n\n this.styles.set(groupName, style);\n }\n\n for (let rule of rules)\n style.sheet.insertRule(rule, style.sheet.cssRules.length);\n },\n\n addSelectors(selectors, groupName = \"standard\", appendOnly = false)\n {\n browser.runtime.sendMessage({\n type: \"content.injectSelectors\",\n selectors,\n groupName,\n appendOnly\n }).then(rules =>\n {\n if (rules)\n {\n // Insert the rules inline if we have been instructed by the background\n // page to do so. This is rarely the case, except on platforms that do\n // not support user stylesheets via the browser.tabs.insertCSS API\n // (Firefox <53, Chrome <66, and Edge).\n // Once all supported platforms have implemented this API, we can remove\n // the code below. See issue #5090.\n // Related Chrome and Firefox issues:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=632009\n // https://bugzilla.mozilla.org/show_bug.cgi?id=1310026\n this.addRulesInline(rules, groupName, appendOnly);\n }\n });\n },\n\n hideElements(elements, filters)\n {\n for (let element of elements)\n hideElement(element);\n\n if (this.tracer)\n {\n browser.runtime.sendMessage({\n type: \"hitLogger.traceElemHide\",\n selectors: [],\n filters\n });\n }\n },\n\n apply(filterTypes)\n {\n browser.runtime.sendMessage({\n type: \"content.applyFilters\",\n filterTypes\n }).then(response =>\n {\n if (this.tracer)\n {\n this.tracer.disconnect();\n this.tracer = null;\n }\n\n if (response.inline)\n this.addRulesInline(response.rules);\n\n if (response.trace)\n {\n this.tracer = new ElementHidingTracer(\n response.selectors,\n response.exceptions\n );\n }\n\n this.elemHideEmulation.apply(response.emulatedPatterns);\n });\n }\n};\n\nif (document instanceof HTMLDocument)\n{\n checkSitekey();\n\n contentFiltering = new ContentFiltering();\n contentFiltering.apply();\n\n document.addEventListener(\"error\", event =>\n {\n checkCollapse(event.target);\n }, true);\n\n document.addEventListener(\"load\", event =>\n {\n let element = event.target;\n if (/^i?frame$/.test(element.localName))\n checkCollapse(element);\n }, true);\n}\n\nwindow.checkCollapse = checkCollapse;\nwindow.contentFiltering = contentFiltering;\nwindow.typeMap = typeMap;\nwindow.getURLsFromElement = getURLsFromElement;\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./include.preload.js\n// module id = 1\n// module chunks = 0","/*\n * This file is part of Adblock Plus <https://adblockplus.org/>,\n * Copyright (C) 2006-present eyeo GmbH\n *\n * Adblock Plus is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 3 as\n * published by the Free Software Foundation.\n *\n * Adblock Plus is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.\n */\n\n/** @module */\n\n\"use strict\";\n\nconst {textToRegExp, filterToRegExp, splitSelector,\n qualifySelector} = require(\"../common\");\n\nconst MIN_INVOCATION_INTERVAL = 3000;\nconst MAX_SYNCHRONOUS_PROCESSING_TIME = 50;\n\nlet abpSelectorRegexp = /:-abp-([\\w-]+)\\(/i;\n\nlet testInfo = null;\n\nfunction toCSSStyleDeclaration(value)\n{\n return Object.assign(document.createElement(\"test\"), {style: value}).style;\n}\n\nexports.setTestMode = function setTestMode()\n{\n testInfo = {\n lastProcessedElements: new Set()\n };\n};\n\nexports.getTestInfo = function getTestInfo()\n{\n return testInfo;\n};\n\nfunction getCachedPropertyValue(object, name, defaultValueFunc = () => {})\n{\n let value = object[name];\n if (typeof value == \"undefined\")\n Object.defineProperty(object, name, {value: value = defaultValueFunc()});\n return value;\n}\n\n/**\n * Return position of node from parent.\n * @param {Node} node the node to find the position of.\n * @return {number} One-based index like for :nth-child(), or 0 on error.\n */\nfunction positionInParent(node)\n{\n let index = 0;\n for (let child of node.parentNode.children)\n {\n if (child == node)\n return index + 1;\n\n index++;\n }\n\n return 0;\n}\n\nfunction makeSelector(node, selector = \"\")\n{\n if (node == null)\n return null;\n if (!node.parentElement)\n {\n let newSelector = \":root\";\n if (selector)\n newSelector += \" > \" + selector;\n return newSelector;\n }\n let idx = positionInParent(node);\n if (idx > 0)\n {\n let newSelector = `${node.tagName}:nth-child(${idx})`;\n if (selector)\n newSelector += \" > \" + selector;\n return makeSelector(node.parentElement, newSelector);\n }\n\n return selector;\n}\n\nfunction parseSelectorContent(content, startIndex)\n{\n let parens = 1;\n let quote = null;\n let i = startIndex;\n for (; i < content.length; i++)\n {\n let c = content[i];\n if (c == \"\\\\\")\n {\n // Ignore escaped characters\n i++;\n }\n else if (quote)\n {\n if (c == quote)\n quote = null;\n }\n else if (c == \"'\" || c == '\"')\n {\n quote = c;\n }\n else if (c == \"(\")\n {\n parens++;\n }\n else if (c == \")\")\n {\n parens--;\n if (parens == 0)\n break;\n }\n }\n\n if (parens > 0)\n return null;\n return {text: content.substring(startIndex, i), end: i};\n}\n\n/**\n * Stringified style objects\n * @typedef {Object} StringifiedStyle\n * @property {string} style CSS style represented by a string.\n * @property {string[]} subSelectors selectors the CSS properties apply to.\n */\n\n/**\n * Produce a string representation of the stylesheet entry.\n * @param {CSSStyleRule} rule the CSS style rule.\n * @return {StringifiedStyle} the stringified style.\n */\nfunction stringifyStyle(rule)\n{\n let styles = [];\n for (let i = 0; i < rule.style.length; i++)\n {\n let property = rule.style.item(i);\n let value = rule.style.getPropertyValue(property);\n let priority = rule.style.getPropertyPriority(property);\n styles.push(`${property}: ${value}${priority ? \" !\" + priority : \"\"};`);\n }\n styles.sort();\n return {\n style: styles.join(\" \"),\n subSelectors: splitSelector(rule.selectorText)\n };\n}\n\nlet scopeSupported = null;\n\nfunction tryQuerySelector(subtree, selector, all)\n{\n let elements = null;\n try\n {\n elements = all ? subtree.querySelectorAll(selector) :\n subtree.querySelector(selector);\n scopeSupported = true;\n }\n catch (e)\n {\n // Edge doesn't support \":scope\"\n scopeSupported = false;\n }\n return elements;\n}\n\n/**\n * Query selector.\n *\n * If it is relative, will try :scope.\n *\n * @param {Node} subtree the element to query selector\n * @param {string} selector the selector to query\n * @param {bool} [all=false] true to perform querySelectorAll()\n *\n * @returns {?(Node|NodeList)} result of the query. null in case of error.\n */\nfunction scopedQuerySelector(subtree, selector, all)\n{\n if (selector[0] == \">\")\n {\n selector = \":scope\" + selector;\n if (scopeSupported)\n {\n return all ? subtree.querySelectorAll(selector) :\n subtree.querySelector(selector);\n }\n if (scopeSupported == null)\n return tryQuerySelector(subtree, selector, all);\n return null;\n }\n return all ? subtree.querySelectorAll(selector) :\n subtree.querySelector(selector);\n}\n\nfunction scopedQuerySelectorAll(subtree, selector)\n{\n return scopedQuerySelector(subtree, selector, true);\n}\n\nconst regexpRegexp = /^\\/(.*)\\/([imu]*)$/;\n\n/**\n * Make a regular expression from a text argument.\n *\n * If it can be parsed as a regular expression, parse it and the flags.\n *\n * @param {string} text the text argument.\n *\n * @return {?RegExp} a RegExp object or null in case of error.\n */\nfunction makeRegExpParameter(text)\n{\n let [, pattern, flags] =\n regexpRegexp.exec(text) || [null, textToRegExp(text)];\n\n try\n {\n return new RegExp(pattern, flags);\n }\n catch (e)\n {\n }\n return null;\n}\n\nfunction* evaluate(chain, index, prefix, subtree, styles, targets)\n{\n if (index >= chain.length)\n {\n yield prefix;\n return;\n }\n for (let [selector, element] of chain[index].getSelectors(prefix, subtree,\n styles, targets))\n {\n if (selector == null)\n yield null;\n else\n yield* evaluate(chain, index + 1, selector, element, styles, targets);\n }\n // Just in case the getSelectors() generator above had to run some heavy\n // document.querySelectorAll() call which didn't produce any results, make\n // sure there is at least one point where execution can pause.\n yield null;\n}\n\nclass PlainSelector\n{\n constructor(selector)\n {\n this._selector = selector;\n this.maybeDependsOnAttributes = /[#.]|\\[.+\\]/.test(selector);\n this.dependsOnDOM = this.maybeDependsOnAttributes;\n this.maybeContainsSiblingCombinators = /[~+]/.test(selector);\n }\n\n /**\n * Generator function returning a pair of selector string and subtree.\n * @param {string} prefix the prefix for the selector.\n * @param {Node} subtree the subtree we work on.\n * @param {StringifiedStyle[]} styles the stringified style objects.\n * @param {Node[]} [targets] the nodes we are interested in.\n */\n *getSelectors(prefix, subtree, styles, targets)\n {\n yield [prefix + this._selector, subtree];\n }\n}\n\nconst incompletePrefixRegexp = /[\\s>+~]$/;\n\nclass HasSelector\n{\n constructor(selectors)\n {\n this.dependsOnDOM = true;\n\n this._innerSelectors = selectors;\n }\n\n get dependsOnStyles()\n {\n return this._innerSelectors.some(selector => selector.dependsOnStyles);\n }\n\n get dependsOnCharacterData()\n {\n return this._innerSelectors.some(\n selector => selector.dependsOnCharacterData\n );\n }\n\n get maybeDependsOnAttributes()\n {\n return this._innerSelectors.some(\n selector => selector.maybeDependsOnAttributes\n );\n }\n\n *getSelectors(prefix, subtree, styles, targets)\n {\n for (let element of this.getElements(prefix, subtree, styles, targets))\n yield [makeSelector(element), element];\n }\n\n /**\n * Generator function returning selected elements.\n * @param {string} prefix the prefix for the selector.\n * @param {Node} subtree the subtree we work on.\n * @param {StringifiedStyle[]} styles the stringified style objects.\n * @param {Node[]} [targets] the nodes we are interested in.\n */\n *getElements(prefix, subtree, styles, targets)\n {\n let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ?\n prefix + \"*\" : prefix;\n let elements = scopedQuerySelectorAll(subtree, actualPrefix);\n if (elements)\n {\n for (let element of elements)\n {\n // If the element is neither an ancestor nor a descendant of one of the\n // targets, we can skip it.\n if (targets && !targets.some(target => element.contains(target) ||\n target.contains(element)))\n {\n yield null;\n continue;\n }\n\n let iter = evaluate(this._innerSelectors, 0, \"\", element, styles,\n targets);\n for (let selector of iter)\n {\n if (selector == null)\n yield null;\n else if (scopedQuerySelector(element, selector))\n yield element;\n }\n yield null;\n\n if (testInfo)\n testInfo.lastProcessedElements.add(element);\n }\n }\n }\n}\n\nclass ContainsSelector\n{\n constructor(textContent)\n {\n this.dependsOnDOM = true;\n this.dependsOnCharacterData = true;\n\n this._regexp = makeRegExpParameter(textContent);\n }\n\n *getSelectors(prefix, subtree, styles, targets)\n {\n for (let element of this.getElements(prefix, subtree, styles, targets))\n yield [makeSelector(element), subtree];\n }\n\n *getElements(prefix, subtree, styles, targets)\n {\n let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ?\n prefix + \"*\" : prefix;\n\n let elements = scopedQuerySelectorAll(subtree, actualPrefix);\n\n if (elements)\n {\n let lastRoot = null;\n for (let element of elements)\n {\n // For a filter like div:-abp-contains(Hello) and a subtree like\n // <div id=\"a\"><div id=\"b\"><div id=\"c\">Hello</div></div></div>\n // we're only interested in div#a\n if (lastRoot && lastRoot.contains(element))\n {\n yield null;\n continue;\n }\n\n lastRoot = element;\n\n if (targets && !targets.some(target => element.contains(target) ||\n target.contains(element)))\n {\n yield null;\n continue;\n }\n\n if (this._regexp && this._regexp.test(element.textContent))\n yield element;\n else\n yield null;\n\n if (testInfo)\n testInfo.lastProcessedElements.add(element);\n }\n }\n }\n}\n\nclass PropsSelector\n{\n constructor(propertyExpression)\n {\n this.dependsOnStyles = true;\n this.dependsOnDOM = true;\n\n let regexpString;\n if (propertyExpression.length >= 2 && propertyExpression[0] == \"/\" &&\n propertyExpression[propertyExpression.length - 1] == \"/\")\n regexpString = propertyExpression.slice(1, -1);\n else\n regexpString = filterToRegExp(propertyExpression);\n\n this._regexp = new RegExp(regexpString, \"i\");\n }\n\n *findPropsSelectors(styles, prefix, regexp)\n {\n for (let style of styles)\n {\n if (regexp.test(style.style))\n {\n for (let subSelector of style.subSelectors)\n {\n if (subSelector.startsWith(\"*\") &&\n !incompletePrefixRegexp.test(prefix))\n subSelector = subSelector.substring(1);\n\n let idx = subSelector.lastIndexOf(\"::\");\n if (idx != -1)\n subSelector = subSelector.substring(0, idx);\n\n yield qualifySelector(subSelector, prefix);\n }\n }\n }\n }\n\n *getSelectors(prefix, subtree, styles, targets)\n {\n for (let selector of this.findPropsSelectors(styles, prefix, this._regexp))\n yield [selector, subtree];\n }\n}\n\nclass Pattern\n{\n constructor(selectors, text)\n {\n this.selectors = selectors;\n this.text = text;\n }\n\n get dependsOnStyles()\n {\n return getCachedPropertyValue(\n this, \"_dependsOnStyles\",\n () => this.selectors.some(selector => selector.dependsOnStyles)\n );\n }\n\n get dependsOnDOM()\n {\n return getCachedPropertyValue(\n this, \"_dependsOnDOM\",\n () => this.selectors.some(selector => selector.dependsOnDOM)\n );\n }\n\n get dependsOnStylesAndDOM()\n {\n return getCachedPropertyValue(\n this, \"_dependsOnStylesAndDOM\",\n () => this.selectors.some(selector => selector.dependsOnStyles &&\n selector.dependsOnDOM)\n );\n }\n\n get maybeDependsOnAttributes()\n {\n // Observe changes to attributes if either there's a plain selector that\n // looks like an ID selector, class selector, or attribute selector in one\n // of the patterns (e.g. \"a[href='https://example.com/']\")\n // or there's a properties selector nested inside a has selector\n // (e.g. \"div:-abp-has(:-abp-properties(color: blue))\")\n return getCachedPropertyValue(\n this, \"_maybeDependsOnAttributes\",\n () => this.selectors.some(\n selector => selector.maybeDependsOnAttributes ||\n (selector instanceof HasSelector &&\n selector.dependsOnStyles)\n )\n );\n }\n\n get dependsOnCharacterData()\n {\n // Observe changes to character data only if there's a contains selector in\n // one of the patterns.\n return getCachedPropertyValue(\n this, \"_dependsOnCharacterData\",\n () => this.selectors.some(selector => selector.dependsOnCharacterData)\n );\n }\n\n get maybeContainsSiblingCombinators()\n {\n return getCachedPropertyValue(\n this, \"_maybeContainsSiblingCombinators\",\n () => this.selectors.some(\n selector => selector.maybeContainsSiblingCombinators\n )\n );\n }\n\n matchesMutationTypes(mutationTypes)\n {\n let mutationTypeMatchMap = getCachedPropertyValue(\n this, \"_mutationTypeMatchMap\",\n () => new Map([\n // All types of DOM-dependent patterns are affected by mutations of\n // type \"childList\".\n [\"childList\", true],\n [\"attributes\", this.maybeDependsOnAttributes],\n [\"characterData\", this.dependsOnCharacterData]\n ])\n );\n\n for (let mutationType of mutationTypes)\n {\n if (mutationTypeMatchMap.get(mutationType))\n return true;\n }\n\n return false;\n }\n}\n\nfunction extractMutationTypes(mutations)\n{\n let types = new Set();\n\n for (let mutation of mutations)\n {\n types.add(mutation.type);\n\n // There are only 3 types of mutations: \"attributes\", \"characterData\", and\n // \"childList\".\n if (types.size == 3)\n break;\n }\n\n return types;\n}\n\nfunction extractMutationTargets(mutations)\n{\n if (!mutations)\n return null;\n\n let targets = new Set();\n\n for (let mutation of mutations)\n {\n if (mutation.type == \"childList\")\n {\n // When new nodes are added, we're interested in the added nodes rather\n // than the parent.\n for (let node of mutation.addedNodes)\n targets.add(node);\n }\n else\n {\n targets.add(mutation.target);\n }\n }\n\n return [...targets];\n}\n\nfunction filterPatterns(patterns, {stylesheets, mutations})\n{\n if (!stylesheets && !mutations)\n return patterns.slice();\n\n let mutationTypes = mutations ? extractMutationTypes(mutations) : null;\n\n return patterns.filter(\n pattern => (stylesheets && pattern.dependsOnStyles) ||\n (mutations && pattern.dependsOnDOM &&\n pattern.matchesMutationTypes(mutationTypes))\n );\n}\n\nfunction shouldObserveAttributes(patterns)\n{\n return patterns.some(pattern => pattern.maybeDependsOnAttributes);\n}\n\nfunction shouldObserveCharacterData(patterns)\n{\n return patterns.some(pattern => pattern.dependsOnCharacterData);\n}\n\nexports.ElemHideEmulation = class ElemHideEmulation\n{\n constructor(hideElemsFunc)\n {\n this._minInvocationInterval = MIN_INVOCATION_INTERVAL;\n this._filteringInProgress = false;\n this._lastInvocation = -MIN_INVOCATION_INTERVAL;\n this._scheduledProcessing = null;\n\n this.document = document;\n this.hideElemsFunc = hideElemsFunc;\n this.observer = new MutationObserver(this.observe.bind(this));\n }\n\n isSameOrigin(stylesheet)\n {\n try\n {\n return new URL(stylesheet.href).origin == this.document.location.origin;\n }\n catch (e)\n {\n // Invalid URL, assume that it is first-party.\n return true;\n }\n }\n\n /**\n * Parse the selector\n * @param {string} selector the selector to parse\n * @return {Array} selectors is an array of objects,\n * or null in case of errors.\n */\n parseSelector(selector)\n {\n if (selector.length == 0)\n return [];\n\n let match = abpSelectorRegexp.exec(selector);\n if (!match)\n return [new PlainSelector(selector)];\n\n let selectors = [];\n if (match.index > 0)\n selectors.push(new PlainSelector(selector.substring(0, match.index)));\n\n let startIndex = match.index + match[0].length;\n let content = parseSelectorContent(selector, startIndex);\n if (!content)\n {\n console.warn(new SyntaxError(\"Failed to parse Adblock Plus \" +\n `selector ${selector} ` +\n \"due to unmatched parentheses.\"));\n return null;\n }\n if (match[1] == \"properties\")\n {\n selectors.push(new PropsSelector(content.text));\n }\n else if (match[1] == \"has\")\n {\n let hasSelectors = this.parseSelector(content.text);\n if (hasSelectors == null)\n return null;\n selectors.push(new HasSelector(hasSelectors));\n }\n else if (match[1] == \"contains\")\n {\n selectors.push(new ContainsSelector(content.text));\n }\n else\n {\n // this is an error, can't parse selector.\n console.warn(new SyntaxError(\"Failed to parse Adblock Plus \" +\n `selector ${selector}, invalid ` +\n `pseudo-class :-abp-${match[1]}().`));\n return null;\n }\n\n let suffix = this.parseSelector(selector.substring(content.end + 1));\n if (suffix == null)\n return null;\n\n selectors.push(...suffix);\n\n if (selectors.length == 1 && selectors[0] instanceof ContainsSelector)\n {\n console.warn(new SyntaxError(\"Failed to parse Adblock Plus \" +\n `selector ${selector}, can't ` +\n \"have a lonely :-abp-contains().\"));\n return null;\n }\n return selectors;\n }\n\n /**\n * Processes the current document and applies all rules to it.\n * @param {CSSStyleSheet[]} [stylesheets]\n * The list of new stylesheets that have been added to the document and\n * made reprocessing necessary. This parameter shouldn't be passed in for\n * the initial processing, all of document's stylesheets will be considered\n * then and all rules, including the ones not dependent on styles.\n * @param {MutationRecord[]} [mutations]\n * The list of DOM mutations that have been applied to the document and\n * made reprocessing necessary. This parameter shouldn't be passed in for\n * the initial processing, the entire document will be considered\n * then and all rules, including the ones not dependent on the DOM.\n * @param {function} [done]\n * Callback to call when done.\n */\n _addSelectors(stylesheets, mutations, done)\n {\n if (testInfo)\n testInfo.lastProcessedElements.clear();\n\n let patterns = filterPatterns(this.patterns, {stylesheets, mutations});\n\n let elements = [];\n let elementFilters = [];\n\n let cssStyles = [];\n\n // If neither any style sheets nor any DOM mutations have been specified,\n // do full processing.\n if (!stylesheets && !mutations)\n stylesheets = this.document.styleSheets;\n\n // If there are any DOM mutations and any of the patterns depends on both\n // style sheets and the DOM (e.g. -abp-has(-abp-properties)), find all the\n // rules in every style sheet in the document, because we need to run\n // querySelectorAll afterwards. On the other hand, if we only have patterns\n // that depend on either styles or DOM both not both (e.g. -abp-contains),\n // we can skip this part.\n if (mutations && patterns.some(pattern => pattern.dependsOnStylesAndDOM))\n stylesheets = this.document.styleSheets;\n\n for (let stylesheet of stylesheets || [])\n {\n // Explicitly ignore third-party stylesheets to ensure consistent behavior\n // between Firefox and Chrome.\n if (!this.isSameOrigin(stylesheet))\n continue;\n\n let rules;\n try\n {\n rules = stylesheet.cssRules;\n }\n catch (e)\n {\n // On Firefox, there is a chance that an InvalidAccessError\n // get thrown when accessing cssRules. Just skip the stylesheet\n // in that case.\n // See https://searchfox.org/mozilla-central/rev/f65d7528e34ef1a7665b4a1a7b7cdb1388fcd3aa/layout/style/StyleSheet.cpp#699\n continue;\n }\n\n if (!rules)\n continue;\n\n for (let rule of rules)\n {\n if (rule.type != rule.STYLE_RULE)\n continue;\n\n cssStyles.push(stringifyStyle(rule));\n }\n }\n\n let targets = extractMutationTargets(mutations);\n\n let pattern = null;\n let generator = null;\n\n let processPatterns = () =>\n {\n let cycleStart = performance.now();\n\n if (!pattern)\n {\n if (!patterns.length)\n {\n if (elements.length > 0)\n this.hideElemsFunc(elements, elementFilters);\n if (typeof done == \"function\")\n done();\n return;\n }\n\n pattern = patterns.shift();\n\n let evaluationTargets = targets;\n\n // If the pattern appears to contain any sibling combinators, we can't\n // easily optimize based on the mutation targets. Since this is a\n // special case, skip the optimization. By setting it to null here we\n // make sure we process the entire DOM.\n if (pattern.maybeContainsSiblingCombinators)\n evaluationTargets = null;\n\n generator = evaluate(pattern.selectors, 0, \"\",\n this.document, cssStyles, evaluationTargets);\n }\n for (let selector of generator)\n {\n if (selector != null)\n {\n for (let element of this.document.querySelectorAll(selector))\n {\n elements.push(element);\n elementFilters.push(pattern.text);\n }\n }\n if (performance.now() - cycleStart > MAX_SYNCHRONOUS_PROCESSING_TIME)\n {\n setTimeout(processPatterns, 0);\n return;\n }\n }\n pattern = null;\n return processPatterns();\n };\n\n processPatterns();\n }\n\n // This property is only used in the tests\n // to shorten the invocation interval\n get minInvocationInterval()\n {\n return this._minInvocationInterval;\n }\n\n set minInvocationInterval(interval)\n {\n this._minInvocationInterval = interval;\n }\n\n /**\n * Re-run filtering either immediately or queued.\n * @param {CSSStyleSheet[]} [stylesheets]\n * new stylesheets to be processed. This parameter should be omitted\n * for full reprocessing.\n * @param {MutationRecord[]} [mutations]\n * new DOM mutations to be processed. This parameter should be omitted\n * for full reprocessing.\n */\n queueFiltering(stylesheets, mutations)\n {\n let completion = () =>\n {\n this._lastInvocation = performance.now();\n this._filteringInProgress = false;\n if (this._scheduledProcessing)\n {\n let params = Object.assign({}, this._scheduledProcessing);\n this._scheduledProcessing = null;\n this.queueFiltering(params.stylesheets, params.mutations);\n }\n };\n\n if (this._scheduledProcessing)\n {\n if (!stylesheets && !mutations)\n {\n this._scheduledProcessing = {};\n }\n else if (this._scheduledProcessing.stylesheets ||\n this._scheduledProcessing.mutations)\n {\n if (stylesheets)\n {\n if (!this._scheduledProcessing.stylesheets)\n this._scheduledProcessing.stylesheets = [];\n this._scheduledProcessing.stylesheets.push(...stylesheets);\n }\n if (mutations)\n {\n if (!this._scheduledProcessing.mutations)\n this._scheduledProcessing.mutations = [];\n this._scheduledProcessing.mutations.push(...mutations);\n }\n }\n }\n else if (this._filteringInProgress)\n {\n this._scheduledProcessing = {stylesheets, mutations};\n }\n else if (performance.now() - this._lastInvocation <\n this.minInvocationInterval)\n {\n this._scheduledProcessing = {stylesheets, mutations};\n setTimeout(\n () =>\n {\n let params = Object.assign({}, this._scheduledProcessing);\n this._filteringInProgress = true;\n this._scheduledProcessing = null;\n this._addSelectors(params.stylesheets, params.mutations, completion);\n },\n this.minInvocationInterval - (performance.now() - this._lastInvocation)\n );\n }\n else if (this.document.readyState == \"loading\")\n {\n this._scheduledProcessing = {stylesheets, mutations};\n let handler = () =>\n {\n this.document.removeEventListener(\"DOMContentLoaded\", handler);\n let params = Object.assign({}, this._scheduledProcessing);\n this._filteringInProgress = true;\n this._scheduledProcessing = null;\n this._addSelectors(params.stylesheets, params.mutations, completion);\n };\n this.document.addEventListener(\"DOMContentLoaded\", handler);\n }\n else\n {\n this._filteringInProgress = true;\n this._addSelectors(stylesheets, mutations, completion);\n }\n }\n\n onLoad(event)\n {\n let stylesheet = event.target.sheet;\n if (stylesheet)\n this.queueFiltering([stylesheet]);\n }\n\n observe(mutations)\n {\n if (testInfo)\n {\n // In test mode, filter out any mutations likely done by us\n // (i.e. style=\"display: none !important\"). This makes it easier to\n // observe how the code responds to DOM mutations.\n mutations = mutations.filter(\n ({type, attributeName, target: {style: newValue}, oldValue}) =>\n !(type == \"attributes\" && attributeName == \"style\" &&\n newValue.display == \"none\" &&\n toCSSStyleDeclaration(oldValue).display != \"none\")\n );\n\n if (mutations.length == 0)\n return;\n }\n\n this.queueFiltering(null, mutations);\n }\n\n apply(patterns)\n {\n this.patterns = [];\n for (let pattern of patterns)\n {\n let selectors = this.parseSelector(pattern.selector);\n if (selectors != null && selectors.length > 0)\n this.patterns.push(new Pattern(selectors, pattern.text));\n }\n\n if (this.patterns.length > 0)\n {\n this.queueFiltering();\n let attributes = shouldObserveAttributes(this.patterns);\n this.observer.observe(\n this.document,\n {\n childList: true,\n attributes,\n attributeOldValue: attributes && !!testInfo,\n characterData: shouldObserveCharacterData(this.patterns),\n subtree: true\n }\n );\n this.document.addEventListener(\"load\", this.onLoad.bind(this), true);\n }\n }\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./adblockpluscore/lib/content/elemHideEmulation.js\n// module id = 2\n// module chunks = 0","/*\n * This file is part of Adblock Plus <https://adblockplus.org/>,\n * Copyright (C) 2006-present eyeo GmbH\n *\n * Adblock Plus is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 3 as\n * published by the Free Software Foundation.\n *\n * Adblock Plus is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.\n */\n\n/** @module */\n\n\"use strict\";\n\n/**\n * Converts raw text into a regular expression string\n * @param {string} text the string to convert\n * @return {string} regular expression representation of the text\n * @package\n */\nexports.textToRegExp = function textToRegExp(text)\n{\n return text.replace(/[-/\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\");\n};\n\n/**\n * Converts filter text into regular expression string\n * @param {string} text as in Filter()\n * @return {string} regular expression representation of filter text\n * @package\n */\nexports.filterToRegExp = function filterToRegExp(text)\n{\n // remove multiple wildcards\n text = text.replace(/\\*+/g, \"*\");\n\n // remove leading wildcard\n if (text[0] == \"*\")\n text = text.substring(1);\n\n // remove trailing wildcard\n if (text[text.length - 1] == \"*\")\n text = text.substring(0, text.length - 1);\n\n return text\n // remove anchors following separator placeholder\n .replace(/\\^\\|$/, \"^\")\n // escape special symbols\n .replace(/\\W/g, \"\\\\$&\")\n // replace wildcards by .*\n .replace(/\\\\\\*/g, \".*\")\n // process separator placeholders (all ANSI characters but alphanumeric\n // characters and _%.-)\n .replace(/\\\\\\^/g, \"(?:[\\\\x00-\\\\x24\\\\x26-\\\\x2C\\\\x2F\\\\x3A-\\\\x40\\\\x5B-\\\\x5E\\\\x60\\\\x7B-\\\\x7F]|$)\")\n // process extended anchor at expression start\n .replace(/^\\\\\\|\\\\\\|/, \"^[\\\\w\\\\-]+:\\\\/+(?!\\\\/)(?:[^\\\\/]+\\\\.)?\")\n // process anchor at expression start\n .replace(/^\\\\\\|/, \"^\")\n // process anchor at expression end\n .replace(/\\\\\\|$/, \"$\");\n};\n\nlet splitSelector = exports.splitSelector = function splitSelector(selector)\n{\n if (!selector.includes(\",\"))\n return [selector];\n\n let selectors = [];\n let start = 0;\n let level = 0;\n let sep = \"\";\n\n for (let i = 0; i < selector.length; i++)\n {\n let chr = selector[i];\n\n if (chr == \"\\\\\") // ignore escaped characters\n {\n i++;\n }\n else if (chr == sep) // don't split within quoted text\n {\n sep = \"\"; // e.g. [attr=\",\"]\n }\n else if (sep == \"\")\n {\n if (chr == '\"' || chr == \"'\")\n {\n sep = chr;\n }\n else if (chr == \"(\") // don't split between parentheses\n {\n level++; // e.g. :matches(div,span)\n }\n else if (chr == \")\")\n {\n level = Math.max(0, level - 1);\n }\n else if (chr == \",\" && level == 0)\n {\n selectors.push(selector.substring(start, i));\n start = i + 1;\n }\n }\n }\n\n selectors.push(selector.substring(start));\n return selectors;\n};\n\nfunction findTargetSelectorIndex(selector)\n{\n let index = 0;\n let whitespace = 0;\n let scope = [];\n\n // Start from the end of the string and go character by character, where each\n // character is a Unicode code point.\n for (let character of [...selector].reverse())\n {\n let currentScope = scope[scope.length - 1];\n\n if (character == \"'\" || character == \"\\\"\")\n {\n // If we're already within the same type of quote, close the scope;\n // otherwise open a new scope.\n if (currentScope == character)\n scope.pop();\n else\n scope.push(character);\n }\n else if (character == \"]\" || character == \")\")\n {\n // For closing brackets and parentheses, open a new scope only if we're\n // not within a quote. Within quotes these characters should have no\n // meaning.\n if (currentScope != \"'\" && currentScope != \"\\\"\")\n scope.push(character);\n }\n else if (character == \"[\")\n {\n // If we're already within a bracket, close the scope.\n if (currentScope == \"]\")\n scope.pop();\n }\n else if (character == \"(\")\n {\n // If we're already within a parenthesis, close the scope.\n if (currentScope == \")\")\n scope.pop();\n }\n else if (!currentScope)\n {\n // At the top level (not within any scope), count the whitespace if we've\n // encountered it. Otherwise if we've hit one of the combinators,\n // terminate here; otherwise if we've hit a non-colon character,\n // terminate here.\n if (/\\s/.test(character))\n whitespace++;\n else if ((character == \">\" || character == \"+\" || character == \"~\") ||\n (whitespace > 0 && character != \":\"))\n break;\n }\n\n // Zero out the whitespace count if we've entered a scope.\n if (scope.length > 0)\n whitespace = 0;\n\n // Increment the index by the size of the character. Note that for Unicode\n // composite characters (like emoji) this will be more than one.\n index += character.length;\n }\n\n return selector.length - index + whitespace;\n}\n\n/**\n * Qualifies a CSS selector with a qualifier, which may be another CSS selector\n * or an empty string. For example, given the selector \"div.bar\" and the\n * qualifier \"#foo\", this function returns \"div#foo.bar\".\n * @param {string} selector The selector to qualify.\n * @param {string} qualifier The qualifier with which to qualify the selector.\n * @returns {string} The qualified selector.\n * @package\n */\nexports.qualifySelector = function qualifySelector(selector, qualifier)\n{\n let qualifiedSelector = \"\";\n\n let qualifierTargetSelectorIndex = findTargetSelectorIndex(qualifier);\n let [, qualifierType = \"\"] =\n /^([a-z][a-z-]*)?/i.exec(qualifier.substring(qualifierTargetSelectorIndex));\n\n for (let sub of splitSelector(selector))\n {\n sub = sub.trim();\n\n qualifiedSelector += \", \";\n\n let index = findTargetSelectorIndex(sub);\n\n // Note that the first group in the regular expression is optional. If it\n // doesn't match (e.g. \"#foo::nth-child(1)\"), type will be an empty string.\n let [, type = \"\", rest] =\n /^([a-z][a-z-]*)?\\*?(.*)/i.exec(sub.substring(index));\n\n if (type == qualifierType)\n type = \"\";\n\n // If the qualifier ends in a combinator (e.g. \"body #foo>\"), we put the\n // type and the rest of the selector after the qualifier\n // (e.g. \"body #foo>div.bar\"); otherwise (e.g. \"body #foo\") we merge the\n // type into the qualifier (e.g. \"body div#foo.bar\").\n if (/[\\s>+~]$/.test(qualifier))\n qualifiedSelector += sub.substring(0, index) + qualifier + type + rest;\n else\n qualifiedSelector += sub.substring(0, index) + type + qualifier + rest;\n }\n\n // Remove the initial comma and space.\n return qualifiedSelector.substring(2);\n};\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./adblockpluscore/lib/common.js\n// module id = 3\n// module chunks = 0","/*\n * This file is part of Adblock Plus <https://adblockplus.org/>,\n * Copyright (C) 2006-present eyeo GmbH\n *\n * Adblock Plus is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License version 3 as\n * published by the Free Software Foundation.\n *\n * Adblock Plus is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>.\n */\n\n\"use strict\";\n\nlet randomEventName = \"abp-request-\" + Math.random().toString(36).substr(2);\n\n// Proxy \"should we block?\" messages from checkRequest inside the injected\n// code to the background page and back again.\ndocument.addEventListener(randomEventName, event =>\n{\n let {url} = event.detail;\n\n browser.runtime.sendMessage({\n type: \"request.blockedByRTCWrapper\",\n url\n }).then(block =>\n {\n document.dispatchEvent(new CustomEvent(\n randomEventName + \"-\" + url, {detail: block}\n ));\n });\n});\n\nfunction injected(eventName, injectedIntoContentWindow)\n{\n let checkRequest;\n\n /*\n * Frame context wrapper\n *\n * For some edge-cases Chrome will not run content scripts inside of frames.\n * Website have started to abuse this fact to access unwrapped APIs via a\n * frame's contentWindow (#4586, 5207). Therefore until Chrome runs content\n * scripts consistently for all frames we must take care to (re)inject our\n * wrappers when the contentWindow is accessed.\n */\n let injectedToString = Function.prototype.toString.bind(injected);\n let injectedFrames = new WeakSet();\n let injectedFramesAdd = WeakSet.prototype.add.bind(injectedFrames);\n let injectedFramesHas = WeakSet.prototype.has.bind(injectedFrames);\n\n function injectIntoContentWindow(contentWindow)\n {\n if (contentWindow && !injectedFramesHas(contentWindow))\n {\n injectedFramesAdd(contentWindow);\n try\n {\n contentWindow[eventName] = checkRequest;\n contentWindow.eval(\n \"(\" + injectedToString() + \")('\" + eventName + \"', true);\"\n );\n delete contentWindow[eventName];\n }\n catch (e) {}\n }\n }\n\n for (let element of [HTMLFrameElement, HTMLIFrameElement, HTMLObjectElement])\n {\n let contentDocumentDesc = Object.getOwnPropertyDescriptor(\n element.prototype, \"contentDocument\"\n );\n let contentWindowDesc = Object.getOwnPropertyDescriptor(\n element.prototype, \"contentWindow\"\n );\n\n // Apparently in HTMLObjectElement.prototype.contentWindow does not exist\n // in older versions of Chrome such as 51.\n if (!contentWindowDesc)\n continue;\n\n let getContentDocument = Function.prototype.call.bind(\n contentDocumentDesc.get\n );\n let getContentWindow = Function.prototype.call.bind(\n contentWindowDesc.get\n );\n\n contentWindowDesc.get = function()\n {\n let contentWindow = getContentWindow(this);\n injectIntoContentWindow(contentWindow);\n return contentWindow;\n };\n contentDocumentDesc.get = function()\n {\n injectIntoContentWindow(getContentWindow(this));\n return getContentDocument(this);\n };\n Object.defineProperty(element.prototype, \"contentWindow\",\n contentWindowDesc);\n Object.defineProperty(element.prototype, \"contentDocument\",\n contentDocumentDesc);\n }\n\n /*\n * RTCPeerConnection wrapper\n *\n * The webRequest API in Chrome does not yet allow the blocking of\n * WebRTC connections.\n * See https://bugs.chromium.org/p/chromium/issues/detail?id=707683\n */\n let RealCustomEvent = window.CustomEvent;\n\n // If we've been injected into a frame via contentWindow then we can simply\n // grab the copy of checkRequest left for us by the parent document. Otherwise\n // we need to set it up now, along with the event handling functions.\n if (injectedIntoContentWindow)\n checkRequest = window[eventName];\n else\n {\n let addEventListener = document.addEventListener.bind(document);\n let dispatchEvent = document.dispatchEvent.bind(document);\n let removeEventListener = document.removeEventListener.bind(document);\n checkRequest = (url, callback) =>\n {\n let incomingEventName = eventName + \"-\" + url;\n\n function listener(event)\n {\n callback(event.detail);\n removeEventListener(incomingEventName, listener);\n }\n addEventListener(incomingEventName, listener);\n\n dispatchEvent(new RealCustomEvent(eventName, {detail: {url}}));\n };\n }\n\n // Only to be called before the page's code, not hardened.\n function copyProperties(src, dest, properties)\n {\n for (let name of properties)\n {\n if (Object.prototype.hasOwnProperty.call(src, name))\n {\n Object.defineProperty(dest, name,\n Object.getOwnPropertyDescriptor(src, name));\n }\n }\n }\n\n let RealRTCPeerConnection = window.RTCPeerConnection ||\n window.webkitRTCPeerConnection;\n\n // Firefox has the option (media.peerconnection.enabled) to disable WebRTC\n // in which case RealRTCPeerConnection is undefined.\n if (typeof RealRTCPeerConnection != \"undefined\")\n {\n let closeRTCPeerConnection = Function.prototype.call.bind(\n RealRTCPeerConnection.prototype.close\n );\n let RealArray = Array;\n let RealString = String;\n let {create: createObject, defineProperty} = Object;\n\n let normalizeUrl = url =>\n {\n if (typeof url != \"undefined\")\n return RealString(url);\n };\n\n let safeCopyArray = (originalArray, transform) =>\n {\n if (originalArray == null || typeof originalArray != \"object\")\n return originalArray;\n\n let safeArray = RealArray(originalArray.length);\n for (let i = 0; i < safeArray.length; i++)\n {\n defineProperty(safeArray, i, {\n configurable: false, enumerable: false, writable: false,\n value: transform(originalArray[i])\n });\n }\n defineProperty(safeArray, \"length\", {\n configurable: false, enumerable: false, writable: false,\n value: safeArray.length\n });\n return safeArray;\n };\n\n // It would be much easier to use the .getConfiguration method to obtain\n // the normalized and safe configuration from the RTCPeerConnection\n // instance. Unfortunately its not implemented as of Chrome unstable 59.\n // See https://www.chromestatus.com/feature/5271355306016768\n let protectConfiguration = configuration =>\n {\n if (configuration == null || typeof configuration != \"object\")\n return configuration;\n\n let iceServers = safeCopyArray(\n configuration.iceServers,\n iceServer =>\n {\n let {url, urls} = iceServer;\n\n // RTCPeerConnection doesn't iterate through pseudo Arrays of urls.\n if (typeof urls != \"undefined\" && !(urls instanceof RealArray))\n urls = [urls];\n\n return createObject(iceServer, {\n url: {\n configurable: false, enumerable: false, writable: false,\n value: normalizeUrl(url)\n },\n urls: {\n configurable: false, enumerable: false, writable: false,\n value: safeCopyArray(urls, normalizeUrl)\n }\n });\n }\n );\n\n return createObject(configuration, {\n iceServers: {\n configurable: false, enumerable: false, writable: false,\n value: iceServers\n }\n });\n };\n\n let checkUrl = (peerconnection, url) =>\n {\n checkRequest(url, blocked =>\n {\n if (blocked)\n {\n // Calling .close() throws if already closed.\n try\n {\n closeRTCPeerConnection(peerconnection);\n }\n catch (e) {}\n }\n });\n };\n\n let checkConfiguration = (peerconnection, configuration) =>\n {\n if (configuration && configuration.iceServers)\n {\n for (let i = 0; i < configuration.iceServers.length; i++)\n {\n let iceServer = configuration.iceServers[i];\n if (iceServer)\n {\n if (iceServer.url)\n checkUrl(peerconnection, iceServer.url);\n\n if (iceServer.urls)\n {\n for (let j = 0; j < iceServer.urls.length; j++)\n checkUrl(peerconnection, iceServer.urls[j]);\n }\n }\n }\n }\n };\n\n // Chrome unstable (tested with 59) has already implemented\n // setConfiguration, so we need to wrap that if it exists too.\n // https://www.chromestatus.com/feature/5596193748942848\n if (RealRTCPeerConnection.prototype.setConfiguration)\n {\n let realSetConfiguration = Function.prototype.call.bind(\n RealRTCPeerConnection.prototype.setConfiguration\n );\n\n RealRTCPeerConnection.prototype.setConfiguration = function(configuration)\n {\n configuration = protectConfiguration(configuration);\n\n // Call the real method first, so that validates the configuration for\n // us. Also we might as well since checkRequest is asynchronous anyway.\n realSetConfiguration(this, configuration);\n checkConfiguration(this, configuration);\n };\n }\n\n let WrappedRTCPeerConnection = function(...args)\n {\n if (!(this instanceof WrappedRTCPeerConnection))\n return RealRTCPeerConnection();\n\n let configuration = protectConfiguration(args[0]);\n\n // Since the old webkitRTCPeerConnection constructor takes an optional\n // second argument we need to take care to pass that through. Necessary\n // for older versions of Chrome such as 51.\n let constraints = undefined;\n if (args.length > 1)\n constraints = args[1];\n\n let peerconnection = new RealRTCPeerConnection(configuration,\n constraints);\n checkConfiguration(peerconnection, configuration);\n return peerconnection;\n };\n\n WrappedRTCPeerConnection.prototype = RealRTCPeerConnection.prototype;\n\n let boundWrappedRTCPeerConnection = WrappedRTCPeerConnection.bind();\n copyProperties(RealRTCPeerConnection, boundWrappedRTCPeerConnection,\n [\"generateCertificate\", \"name\", \"prototype\"]);\n RealRTCPeerConnection.prototype.constructor = boundWrappedRTCPeerConnection;\n\n if (\"RTCPeerConnection\" in window)\n window.RTCPeerConnection = boundWrappedRTCPeerConnection;\n if (\"webkitRTCPeerConnection\" in window)\n window.webkitRTCPeerConnection = boundWrappedRTCPeerConnection;\n }\n}\n\nif (document instanceof HTMLDocument)\n{\n let sandbox;\n\n // We have to wrap the following code in a try catch\n // because of this Microsoft Edge bug:\n // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/19082980/\n try\n {\n sandbox = window.frameElement &&\n window.frameElement.getAttribute(\"sandbox\");\n }\n catch (e) {}\n\n if (typeof sandbox != \"string\" || /(^|\\s)allow-scripts(\\s|$)/i.test(sandbox))\n {\n let script = document.createElement(\"script\");\n let code = \"(\" + injected + \")('\" + randomEventName + \"');\";\n\n script.type = \"application/javascript\";\n script.async = false;\n\n // Firefox 58 only bypasses site CSPs when assigning to 'src',\n // while Chrome 67 and Microsoft Edge 44.17763.1.0\n // only bypass site CSPs when using 'textContent'.\n if (browser.runtime.getURL(\"\").startsWith(\"moz-extension://\"))\n {\n let url = URL.createObjectURL(new Blob([code]));\n script.src = url;\n document.documentElement.appendChild(script);\n URL.revokeObjectURL(url);\n }\n else\n {\n script.textContent = code;\n document.documentElement.appendChild(script);\n }\n\n document.documentElement.removeChild(script);\n }\n}\n\n\n\n//////////////////\n// WEBPACK FOOTER\n// ./inject.preload.js\n// module id = 4\n// module chunks = 0"],"sourceRoot":""}
TL :
Số cuối - số đầu : khoảng cách + 1
100 - 2 ( số chẵn đầu tiên ) : 2 ( vì tính số chẵn ) + 1 = 50
~HT~