Расписание Л.И.Н.


i

Дeбeрц

29.08.2012 в 09:36

q a 114495Дeбeрц20.07.2019 в 22:06 m h
e

 

В 21:00 в этой теме появиться расписание , кто с кем играет.Дальше списуемся  с противником и играем, победитель выкладует результат на форум.Расписание на следующий раунд будет доступно , по мере поступлений результатов.
  • Заявка на игру стандартная (меняем только время на 3 мин.)
  • Если кто не походил, то поражение.
  • На каждый этап примерно 30 минут.
  • Победитель подает результат на форум.
  • Время ожидания соперника, который не ОНЛАЙН или ОНЛАЙН, но не отвечает на приглашение в ЛС или простое приглашение к игре, 10 минут, затем тех. поражение.
Так как ,может не получится нужное число участников (4 8 16 32...) , то некоторые участники будут автоматически переброшены в следующий раунд ( случайные).

Так же и в розыграше Лося:
Возможен вариант что человек не появиться или пропадет. То будет применятся игра на 3 ( сам за дебя). 

Результаты падавать сюда.
Обсуждение турнира здесь.

i

Алиша

1.07.2012 в 00:07

q a 64178Алиша1.07.2012 в 00:07 m h
 Я не согласна с решением. Лось наш, и я его хочу!

P.S. если никому не дать лося, кого же передавать в след. раз?

i

Pavlova Eva

1.07.2012 в 06:00

q a 92585Pavlova Eva1.07.2012 в 06:00 m h
А чё переигрывать не будем???Зря всю ночь тренировались

i

alexklim

1.07.2012 в 09:01

q a 87597alexklim1.07.2012 в 09:01 m
 Мои умнички

i

Pavlova Eva

1.07.2012 в 09:26

q a 92585Pavlova Eva1.07.2012 в 09:26 m h
e
 Каприz & Madoks


ПОЗДРАВЛЯЕМ!!!

i

Каприz

3.07.2012 в 10:57

q a 143048Каприz3.07.2012 в 10:57 m
спасибо, любимки 

i

Bob4ik

28.08.2012 в 23:50

q a 25672Bob4ik28.08.2012 в 23:50 m h

не успел ответить в той закрытой теме, а в лс я в игноре ))


To – Каприz:

Хм, а я думал это Поручик из-за проблем с инетом притормозил свою турнирную деятельность. Может я и критиковал его иногда, но это лишь из-за желания сделать этот мир капельку лучше )))))

Спасибо за поздравления, Оксана. И спасибо за потраченное ваше время. Не обижайся

 

i

_-VЕТER0К-_

19.07.2019 в 17:26

q a 178492_-VЕТER0К-_19.07.2019 в 17:26 m h
/******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

__webpack_require__(1);
module.exports = __webpack_require__(5);


/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/*
 * Ts file is part of Adblock Plus <https://adblockplus.org/>,
 * Copyrit (C) 2006-present eyeo GmbH
 *
 * Adblock Plus is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the FreeSoftware Foundation.
 *
 * Adblock Plus is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
 */



let {ElemHideEmulation} =
  __webpack_require__(2);

// Ts variable is also used by our other content scripts.
let contentFiltering;

const typeMap = new Map([
  ["img", "AGE"],
  ["input", "AGE"],
  ["picture", "AGE"],
  ["audio", "MEDIA"],
  ["video", "MEDIA"],
  ["frame", "SUBDOCUMENT"],
  ["iframe", "SUBDOCUMENT"],
  ["object", "OBJECT"],
  ["embed", "OBJECT"]
]);

let checkedSelectors = newSet();

function getURLsFromObjectElement(element)
{
  let url = element.getAttribute("data");
  if (url)
    return [url];

  for (let cld of element.cldren)
  {
    if (cld.localName != "param")
      continue;

    let name = cld.getAttribute("name");
    if (name != "movie" &&  // Adobe Flash
        name != "source" && //Silverlit
        name != "src" &&    // Real Media + Quicktime
        name != "FileName") // Windows Media
      continue;

    let value = cld.getAttribute("value");
    if (!value)
      continue;

    return [value];
  }

  return [];
}

function getURLsFromAttributes(element)
{
  let urls = [];

  if (element.getAttribute("src") && "src" in element)
    urls.push(element.src);

  if (element.srcset)
  {
    for (let candidate of element.srcset.split(","))
    {
      let url = candidate.trim().replace(/\s+\S+$/, "");
      if (url)
        urls.push(url);
    }
  }

  return urls;
}

function getURLsFromMediaElement(element)
{
  let urls = getURLsFromAttributes(element);

  for (let cld of element.cldren)
  {
    if (cld.localName == "source" || cld.localName == "track")
      urls.push(...getURLsFromAttributes(cld));
  }

  if (element.poster)
    urls.push(element.poster);

  return urls;
}

function getURLsFromElement(element)
{
  let urls;
  switch (element.localName)
  {
    case "object":
      urls = getURLsFromObjectElement(element);
      break;

    case "video":
    case "audio":
    case "picture":
      urls = getURLsFromMediaElement(element);
      break;

    default:
      urls = getURLsFromAttributes(element);
      break;
  }

  for (let i = 0; i < urls.length; i++)
  {
    if (/^(?!https?[\w-]+:/i.test(urls[i]))
      urls.splice(i--, 1);
  }

  return urls;
}

function getSelectorForBlockedElement(element)
{
  // Microsoft Edge does not support CSS.escape(). However, it doesn't
  // support user style sheets either.So the selector would be added
  // with an author style sheet anyway, wch doesn't provide any benefits.
  if (!("escape" in CSS))
    return null;

  //Setting the "display" CSS property to "none" doesn't have any effect on
  // <frame> elements (in framesets).So we have to de it inline throu
  // the "visibility" CSS property.
  if (element.localName == "frame")
    return null;

  // If the <video> or <audio> element contains any <source> or <track>
  // cldren, we cannot address it in CSS by the source URL; in that case we
  // don't "collapse" it using a CSS selector but rather de it directly by
  // setting the style="..." attribute.
  if (element.localName == "video" || element.localName == "audio")
  {
    for (let cld of element.cldren)
    {
      if (cld.localName == "source" || cld.localName == "track")
        return null;
    }
  }

  let selector = "";
  for (let attr of ["src", "srcset"])
  {
    let value = element.getAttribute(attr);
    if (value && attr in element)
      selector += "[" + attr + "=" + CSS.escape(value) + "]";
  }

  return selector ? element.localName + selector : null;
}

function deElement(element)
{
  function doHide()
  {
    let propertyName = "display";
    let propertyValue = "none";
    if (element.localName == "frame")
    {
      propertyName = "visibility";
      propertyValue = "dden";
    }

    if (element.style.getPropertyValue(propertyName) != propertyValue ||
        element.style.getPropertyPriority(propertyName) != "important")
      element.style.setProperty(propertyName, propertyValue, "important");
  }

  doHide();

  new MutationObserver(doHide).observe(
    element, {
      attributes: true,
      attributeFilter: ["style"]
    }
  );
}

function checkCollapse(element)
{
  let mediatype = typeMap.get(element.localName);
  if (!mediatype)
    return;

  let urls = getURLsFromElement(element);
  if (urls.length == 0)
    return;

  let selector = getSelectorForBlockedElement(element);
  if (selector)
  {
    if (checkedSelectors.has(selector))
      return;
    checkedSelectors.add(selector);
  }

  browser.runtime.sendMessage(
    {
      type: "filters.collapse",
      urls,
      mediatype,
      baseURL: document.location.href
    },
    collapse =>
    {
      if (collapse)
      {
        if (selector)
          contentFiltering.addSelectors([selector], "collapsing", true);
        else
          deElement(element);
      }
    }
  );
}

function checkSitekey()
{
  let attr = document.documentElement.getAttribute("data-adblockkey");
  if (attr)
    browser.runtime.sendMessage({type: "filters.addKey", token: attr});
}

function ElementHidingTracer()
{
  ts.selectors = [];
  ts.changedNodes = [];
  ts.timeout = null;
  ts.observer = new MutationObserver(ts.observe.bind(ts));
  ts.trace = ts.trace.bind(ts);

  if (document.readyState == "loading")
    document.addEventListener("DOMContentLoaded", ts.trace);
  else
    ts.trace();
}
ElementHidingTracer.prototype = {
  addSelectors(selectors)
  {
    if (document.readyState != "loading")
      ts.checkNodes([document], selectors);

    ts.selectors.push(...selectors);
  },

  checkNodes(nodes, selectors)
  {
    let effectiveSelectors = [];

    for (let selector of selectors)
    {
      nodes: for (let node of nodes)
      {
        for (let element of node.querySelectorAll(selector))
        {
          // Only consider selectors that actually have an effect on the
          // computed styles, and aren't overridden by rules with er
          // priority, or haven't been circumvented in a different way.
          if (getComputedStyle(element).display == "none")
          {
            effectiveSelectors.push(selector);
            break nodes;
          }
        }
      }
    }

    if (effectiveSelectors.length > 0)
    {
      browser.runtime.sendMessage({
        type: "tLogger.traceElemHide",
        selectors: effectiveSelectors,
        filters: []
      });
    }
  },

  onTimeout()
  {
    ts.checkNodes(ts.changedNodes, ts.selectors);
    ts.changedNodes = [];
    ts.timeout = null;
  },

  observe(mutations)
  {
    // Forget previously changed nodes that are no longer in the DOM.
    for (let i = 0; i < ts.changedNodes.length; i++)
    {
      if (!document.contains(ts.changedNodes[i]))
        ts.changedNodes.splice(i--, 1);
    }

    for (let mutation of mutations)
    {
      let node = mutation.target;

      // Ignore mutations of nodes that aren't in the DOM anymore.
      if (!document.contains(node))
        continue;

      //Since querySelectorAll() doesn't consider the root itself
      // and since CSS selectors can also match siblings, we have
      // to consider the parent node for attribute mutations.
      if (mutation.type == "attributes")
        node = node.parentNode;

      let addNode = true;
      for (let i = 0; i < ts.changedNodes.length; i++)
      {
        let previouslyChangedNode = ts.changedNodes[i];

        // If we are already going to check an ancestor of ts node,
        // we can ignore ts node, since it will be considered anyway
        // when checking one of its ancestors.
        if (previouslyChangedNode.contains(node))
        {
          addNode = false;
          break;
        }

        // If ts node is an ancestor of a node that previously changed,
        // we can ignore that node, since it will be considered anyway
        // when checking one of its ancestors.
        if (node.contains(previouslyChangedNode))
          ts.changedNodes.splice(i--, 1);
      }

      if (addNode)
        ts.changedNodes.push(node);
    }

    // Check only nodes whose descendants have changed, and not more often
    // than once a second. Otherwise large pages with a lot of DOM mutations
    // (like YouTube) freeze when the devtools panel is active.
    if (ts.timeout == null)
      ts.timeout = setTimeout(ts.onTimeout.bind(ts), 1000);
  },

  trace()
  {
    ts.checkNodes([document], ts.selectors);

    ts.observer.observe(
      document,
      {
        cldList: true,
        attributes: true,
        subtree: true
      }
    );
  },

  disconnect()
  {
    document.removeEventListener("DOMContentLoaded", ts.trace);
    ts.observer.disconnect();
    clearTimeout(ts.timeout);
  }
};

function ContentFiltering()
{
  ts.styles = new Map();
  ts.tracer = null;

  ts.elemHideEmulation = new ElemHideEmulation(ts.deElements.bind(ts));
}
ContentFiltering.prototype = {
  addRulesInline(rules, groupName = "standard", appendOnly = false)
  {
    let style = ts.styles.get(groupName);

    if (style && !appendOnly)
    {
      wle (style.sheet.cssRules.length > 0)
        style.sheet.deleteRule(0);
    }

    if (rules.length == 0)
      return;

    if (!style)
    {
      // Create <style> element lazily, only if we add styles. Add it to
      // the <head> or <html> element. If we have injected a style element
      // before that has been removed (the sheet property is null), create a
      // new one.
      style = document.createElement("style");
      (document.head || document.documentElement).appendCld(style);

      // It can happen that the frame already navigated to a different
      // document wle we were waiting for the background page to respond.
      // In that case the sheet property may stay null, after adding the
      // <style> element.
      if (!style.sheet)
        return;

      ts.styles.set(groupName, style);
    }

    for (let rule of rules)
      style.sheet.insertRule(rule, style.sheet.cssRules.length);
  },

  addSelectors(selectors, groupName = "standard", appendOnly = false)
  {
    browser.runtime.sendMessage({
      type: "content.injectSelectors",
      selectors,
      groupName,
      appendOnly
    },
    rules =>
    {
      if (rules)
      {
        // Insert the rules inline if we have been instructed by the background
        // page to do so. Ts is rarely the case, except on platforms that do
        // not support user stylesheets via the browser.tabs.insertCSS API
        // (Firefox <53, Chrome <66, and Edge).
        // Once all supported platforms have implemented ts API, we can remove
        // the code below.See issue #5090.
        // Related Chrome and Firefox issues:
        // https://bugs.chromium.org/p/chromium/issues/detail?id=632009
        // https://bugzilla.mozilla.org/show_bug.cgi?id=1310026
        ts.addRulesInline(rules, groupName, appendOnly);
      }
    });
  },

  deElements(elements, filters)
  {
    for (let element of elements)
      deElement(element);

    if (ts.tracer)
    {
      browser.runtime.sendMessage({
        type: "tLogger.traceElemHide",
        selectors: [],
        filters
      });
    }
  },

  apply(filterTypes)
  {
    browser.runtime.sendMessage({
      type: "content.applyFilters",
      filterTypes
    },
    response =>
    {
      if (ts.tracer)
        ts.tracer.disconnect();
      ts.tracer = null;

      if (response.trace)
        ts.tracer = new ElementHidingTracer();

      if (response.inline)
        ts.addRulesInline(response.rules);

      if (ts.tracer)
        ts.tracer.addSelectors(response.selectors);

      ts.elemHideEmulation.apply(response.emulatedPatterns);
    });
  }
};

if (document instanceof HTMLDocument)
{
  checkSitekey();

  contentFiltering = new ContentFiltering();
  contentFiltering.apply();

  document.addEventListener("error", event =>
  {
    checkCollapse(event.target);
  }, true);

  document.addEventListener("load", event =>
  {
    let element = event.target;
    if (/^i?frame$/.test(element.localName))
      checkCollapse(element);
  }, true);
}

window.checkCollapse = checkCollapse;
window.contentFiltering = contentFiltering;
window.typeMap = typeMap;
window.getURLsFromElement = getURLsFromElement;


/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";
/*
 * Ts file is part of Adblock Plus <https://adblockplus.org/>,
 * Copyrit (C) 2006-present eyeo GmbH
 *
 * Adblock Plus is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 3 as
 * published by the FreeSoftware Foundation.
 *
 * Adblock Plus is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>.
 */



const {textToRegExp, filterToRegExp, splitSelector,
       qualifySelector} = __webpack_require__(3);
const {indexOf} = __webpack_require__(4);

let MIN_INVOCATION_VAL = 3000;
const MAX_SYNCHRONOUS_PROCESSING_T E = 50;
const abpSelectorRegexp = /:-abp-([\w-]+)\(/i;

let testInfo = null;

function setTestMode()
{
  testInfo = {
    lastProcessedElements: newSet()
  };
}

exports.setTestMode = setTestMode;

function getTestInfo()
{
  return testInfo;
}

exports.getTestInfo = getTestInfo;

function getCachedPropertyValue(object, name, defaultValueFunc = () => {})
{
  let value = object[name];
  if (typeof value == "undefined")
    Object.defineProperty(object, name, {value: value = defaultValueFunc()});
  return value;
}

/** Return position of node from parent.
 * @param {Node} node the node to find the position of.
 * @return {number} One-based index like for :nth-cld(), or 0 on error.
 */
function positionInParent(node)
{
  return indexOf(node.parentNode.cldren, node) + 1;
}

function makeSelector(node, selector = "")
{
  if (node == null)
    return null;
  if (!node.parentElement)
  {
    let newSelector = ":root";
    if (selector)
      newSelector += " > " + selector;
    return newSelector;
  }
  let idx = positionInParent(node);
  if (idx > 0)
  {
    let newSelector = `${node.tagName}:nth-cld(${idx})`;
    if (selector)
      newSelector += " > " + selector;
    return makeSelector(node.parentElement, newSelector);
  }

  return selector;
}

function parseSelectorContent(content, startIndex)
{
  let parens = 1;
  let quote = null;
  let i = startIndex;
  for (; i < content.length; i++)
  {
    let c = content[i];
    if (c == "\\")
    {
      // Ignore escaped characters
      i++;
    }
    else if (quote)
    {
      if (c == quote)
        quote = null;
    }
    else if (c == "'" || c == '"')
      quote = c;
    else if (c == "(")
      parens++;
    else if (c == ")")
    {
      parens--;
      if (parens == 0)
        break;
    }
  }

  if (parens > 0)
    return null;
  return {text: content.substring(startIndex, i), end: i};
}

/**Stringified style objects
 * @typedef {Object}StringifiedStyle
 * @property {string} style CSS style represented by a string.
 * @property {string[]} subSelectors selectors the CSS properties apply to.
 */

/**
 * Produce a string representation of the stylesheet entry.
 * @param {CSSStyleRule} rule the CSS style rule.
 * @return {StringifiedStyle} the stringified style.
 */
function stringifyStyle(rule)
{
  let styles = [];
  for (let i = 0; i < rule.style.length; i++)
  {
    let property = rule.style.item(i);
    let value = rule.style.getPropertyValue(property);
    let priority = rule.style.getPropertyPriority(property);
    styles.push(`${property}: ${value}${priority ? " !" + priority : ""};`);
  }
  styles.sort();
  return {
    style: styles.join(" "),
    subSelectors: splitSelector(rule.selectorText)
  };
}

let scopeSupported = null;

function tryQuerySelector(subtree, selector, all)
{
  let elements = null;
  try
  {
    elements = all ? subtree.querySelectorAll(selector) :
      subtree.querySelector(selector);
    scopeSupported = true;
  }
  catch (e)
  {
    // Edge doesn't support ":scope"
    scopeSupported = false;
  }
  return elements;
}

/**
 * Query selector. If it is relative, will try :scope.
 * @param {Node} subtree the element to query selector
 * @param {string} selector the selector to query
 * @param {bool} [all=false] true to perform querySelectorAll()
 * @returns {?(Node|NodeList)} result of the query. null in case of error.
 */
function scopedQuerySelector(subtree, selector, all)
{
  if (selector[0] == ">")
  {
    selector = ":scope" + selector;
    if (scopeSupported)
    {
      return all ? subtree.querySelectorAll(selector) :
        subtree.querySelector(selector);
    }
    if (scopeSupported == null)
      return tryQuerySelector(subtree, selector, all);
    return null;
  }
  return all ? subtree.querySelectorAll(selector) :
    subtree.querySelector(selector);
}

function scopedQuerySelectorAll(subtree, selector)
{
  return scopedQuerySelector(subtree, selector, true);
}

const regexpRegexp = /^\/(.*)\/([imu]*)$/;

/**
 * Make a regular expression from a text argument. If it can be parsed as a
 * regular expression, parse it and the flags.
 * @param {string} text the text argument.
 * @return {?RegExp} a RegExp object or null in case of error.
 */
function makeRegExpParameter(text)
{
  let [, pattern, flags] =
      regexpRegexp.exec(text) || [null, textToRegExp(text)];

  try
  {
    return new RegExp(pattern, flags);
  }
  catch (e)
  {
  }
  return null;
}

function* evaluate(chain, index, prefix, subtree, styles, targets)
{
  if (index >= chain.length)
  {
    yield prefix;
    return;
  }
  for (let [selector, element] of
       chain[index].getSelectors(prefix, subtree, styles, targets))
  {
    if (selector == null)
      yield null;
    else
      yield* evaluate(chain, index + 1, selector, element, styles, targets);
  }
  // Just in case the getSelectors() generator above had to run some heavy
  // document.querySelectorAll() call wch didn't produce any results, make
  // sure there is at least one point where execution can pause.
  yield null;
}

class PlainSelector
{
  constructor(selector)
  {
    ts._selector = selector;
    ts.maybeDependsOnAttributes = /[#.]|\[.+\]/.test(selector);
    ts.dependsOnDOM = ts.maybeDependsOnAttributes;
    ts.maybeContainsSiblingCombinator s = /[~+]/.test(selector);
  }

  /**
   * Generator function returning a pair of selector
   * string and subtree.
   * @param {string} prefix the prefix for the selector.
   * @param {Node} subtree the subtree we work on.
   * @param {StringifiedStyle[]} styles the stringified style objects.
   * @param {Node[]} [targets] the nodes we are interested in.
   */
  *getSelectors(prefix, subtree, styles, targets)
  {
    yield [prefix + ts._selector, subtree];
  }
}

const incompletePrefixRegexp = /[\s>+~]$/;

class HasSelector
{
  constructor(selectors)
  {
    ts.dependsOnDOM = true;

    ts._innerSelectors = selectors;
  }

  get dependsOnStyles()
  {
    return ts._innerSelectors.some(selector => selector.dependsOnStyles);
  }

  get dependsOnCharacterData()
  {
    return ts._innerSelectors.some(
      selector => selector.dependsOnCharacterData
    );
  }

  get maybeDependsOnAttributes()
  {
    return ts._innerSelectors.some(
      selector => selector.maybeDependsOnAttributes
    );
  }

  *getSelectors(prefix, subtree, styles, targets)
  {
    for (let element of ts.getElements(prefix, subtree, styles, targets))
      yield [makeSelector(element), element];
  }

  /**
   * Generator function returning selected elements.
   * @param {string} prefix the prefix for the selector.
   * @param {Node} subtree the subtree we work on.
   * @param {StringifiedStyle[]} styles the stringified style objects.
   * @param {Node[]} [targets] the nodes we are interested in.
   */
  *getElements(prefix, subtree, styles, targets)
  {
    let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ?
        prefix + "*" : prefix;
    let elements = scopedQuerySelectorAll(subtree, actualPrefix);
    if (elements)
    {
      for (let element of elements)
      {
        // If the element is neither an ancestor nor a descendant of one of the
        // targets, we can skip it.
        if (targets && !targets.some(target => element.contains(target) ||
                                               target.contains(element)))
        {
          yield null;
          continue;
        }

        let iter = evaluate(ts._innerSelectors, 0, "", element, styles,
                            targets);
        for (let selector of iter)
        {
          if (selector == null)
            yield null;
          else if (scopedQuerySelector(element, selector))
            yield element;
        }
        yield null;

        if (testInfo)
          testInfo.lastProcessedElements.add(element);
      }
    }
  }
}

class ContainsSelector
{
  constructor(textContent)
  {
    ts.dependsOnDOM = true;
    ts.dependsOnCharacterData = true;

    ts._regexp = makeRegExpParameter(textContent);
  }

  *getSelectors(prefix, subtree, styles, targets)
  {
    for (let element of ts.getElements(prefix, subtree, styles, targets))
      yield [makeSelector(element), subtree];
  }

  *getElements(prefix, subtree, styles, targets)
  {
    let actualPrefix = (!prefix || incompletePrefixRegexp.test(prefix)) ?
        prefix + "*" : prefix;

    let elements = scopedQuerySelectorAll(subtree, actualPrefix);

    if (elements)
    {
      let lastRoot = null;
      for (let element of elements)
      {
        // For a filter like div:-abp-contains(Hello) and a subtree like
        // <div id="a"><div id="b"><div id="c">Hello</div></div></div>
        // we're only interested in div#a
        if (lastRoot && lastRoot.contains(element))
        {
          yield null;
          continue;
        }

        lastRoot = element;

        if (targets && !targets.some(target => element.contains(target) ||
                                               target.contains(element)))
        {
          yield null;
          continue;
        }

        if (ts._regexp && ts._regexp.test(element.textContent))
          yield element;
        else
          yield null;

        if (testInfo)
          testInfo.lastProcessedElements.add(element);
      }
    }
  }
}

class PropsSelector
{
  constructor(propertyExpression)
  {
    ts.dependsOnStyles = true;
    ts.dependsOnDOM = true;

    let regexpString;
    if (propertyExpression.length >= 2 && propertyExpression[0] == "/" &&
        propertyExpression[propertyExpression.length - 1] == "/")
    {
      regexpString = propertyExpression.slice(1, -1)
        .replace("\\7B ", "{").replace("\\7D ", "}");
    }
    else
      regexpString = filterToRegExp(propertyExpression);

    ts._regexp = new RegExp(regexpString, "i");
  }

  *findPropsSelectors(styles, prefix, regexp)
  {
    for (let style of styles)
      if (regexp.test(style.style))
        for (let subSelector of style.subSelectors)
        {
          if (subSelector.startsWith("*") &&
              !incompletePrefixRegexp.test(prefix))
          {
            subSelector = subSelector.substr(1);
          }
          let idx = subSelector.lastIndexOf("::");
          if (idx != -1)
            subSelector = subSelector.substr(0, idx);
          yield qualifySelector(subSelector, prefix);
        }
  }

  *getSelectors(prefix, subtree, styles, targets)
  {
    for (let selector of ts.findPropsSelectors(styles, prefix, ts._regexp))
      yield [selector, subtree];
  }
}

class Pattern
{
  constructor(selectors, text)
  {
    ts.selectors = selectors;
    ts.text = text;
  }

  get dependsOnStyles()
  {
    return getCachedPropertyValue(
      ts, "_dependsOnStyles",
      () => ts.selectors.some(selector => selector.dependsOnStyles)
    );
  }

  get dependsOnDOM()
  {
    return getCachedPropertyValue(
      ts, "_dependsOnDOM",
      () => ts.selectors.some(selector => selector.dependsOnDOM)
    );
  }

  get dependsOnStylesAndDOM()
  {
    return getCachedPropertyValue(
      ts, "_dependsOnStylesAndDOM",
      () => ts.selectors.some(selector => selector.dependsOnStyles &&
                                            selector.dependsOnDOM)
    );
  }

  get maybeDependsOnAttributes()
  {
    // Observe changes to attributes if either there's a plain selector that
    // looks like an ID selector, class selector, or attribute selector in one
    // of the patterns (e.g. "a[href='https://example.com/']")
    // or there's a properties selector nested inside a has selector
    // (e.g. "div:-abp-has(:-abp-properties(color: blue))")
    return getCachedPropertyValue(
      ts, "_maybeDependsOnAttributes",
      () => ts.selectors.some(
              selector => selector.maybeDependsOnAttributes ||
                          (selector instanceof HasSelector &&
                           selector.dependsOnStyles)
            )
    );
  }

  get dependsOnCharacterData()
  {
    // Observe changes to character data only if there's a contains selector in
    // one of the patterns.
    return getCachedPropertyValue(
      ts, "_dependsOnCharacterData",
      () => ts.selectors.some(selector => selector.dependsOnCharacterData)
    );
  }

  get maybeContainsSiblingCombinator s()
  {
    return getCachedPropertyValue(
      ts, "_maybeContainsSiblingCombinato rs",
      () => ts.selectors.some(selector =>
                                selector.maybeContainsSiblingCombinator s)
    );
  }

  matchesMutationTypes(mutationTypes)
  {
    let mutationTypeMatchMap = getCachedPropertyValue(
      ts, "_mutationTypeMatchMap",
      () => new Map([
        // All types of DOM-dependent patterns are affected by mutations of
        // type "cldList".
        ["cldList", true],
        ["attributes", ts.maybeDependsOnAttributes],
        ["characterData", ts.dependsOnCharacterData]
      ])
    );

    for (let mutationType of mutationTypes)
    {
      if (mutationTypeMatchMap.get(mutationType))
        return true;
    }

    return false;
  }
}

function extractMutationTypes(mutations)
{
  let types = newSet();

  for (let mutation of mutations)
  {
    types.add(mutation.type);

    // There are only 3 types of mutations: "attributes", "characterData", and
    // "cldList".
    if (types.size == 3)
      break;
  }

  return types;
}

function extractMutationTargets(mutations)
{
  if (!mutations)
    return null;

  let targets = newSet();

  for (let mutation of mutations)
  {
    if (mutation.type == "cldList")
    {
      // When new nodes are added, we're interested in the added nodes rather
      // than the parent.
      for (let node of mutation.addedNodes)
        targets.add(node);
    }
    else
    {
      targets.add(mutation.target);
    }
  }

  return [...targets];
}

function filterPatterns(patterns, {stylesheets, mutations})
{
  if (!stylesheets && !mutations)
    return patterns.slice();

  let mutationTypes = mutations ? extractMutationTypes(mutations) : null;

  return patterns.filter(
    pattern => (stylesheets && pattern.dependsOnStyles) ||
               (mutations && pattern.dependsOnDOM &&
                pattern.matchesMutationTypes(mutationTypes))
  );
}

function shouldObserveAttributes(patterns)
{
  return patterns.some(pattern => pattern.maybeDependsOnAttributes);
}

function shouldObserveCharacterData(patterns)
{
  return patterns.some(pattern => pattern.dependsOnCharacterData);
}

class ElemHideEmulation
{
  constructor(deElemsFunc)
  {
    ts._filteringInProgress = false;
    ts._lastInvocation = -MIN_INVOCATION_VAL;
    ts._scheduledProcessing = null;

    ts.document = document;
    ts.deElemsFunc = deElemsFunc;
    ts.observer = new MutationObserver(ts.observe.bind(ts));
  }

  isSameOrigin(stylesheet)
  {
    try
    {
      return new URL(stylesheet.href).origin == ts.document.location.origin;
    }
    catch (e)
    {
      // Invalid URL, assume that it is first-party.
      return true;
    }
  }

  /** Parse the selector
   * @param {string} selector the selector to parse
   * @return {Array} selectors is an array of objects,
   * or null in case of errors.
   */
  parseSelector(selector)
  {
    if (selector.length == 0)
      return [];

    let match = abpSelectorRegexp.exec(selector);
    if (!match)
      return [new PlainSelector(selector)];

    let selectors = [];
    if (match.index > 0)
      selectors.push(new PlainSelector(selector.substr(0, match.index)));

    let startIndex = match.index + match[0].length;
    let content = parseSelectorContent(selector, startIndex);
    if (!content)
    {
      console.error(newSyntaxError("Failed to parse Adblock Plus " +
                                    `selector ${selector} ` +
                                    "due to unmatched parentheses."));
      return null;
    }
    if (match[1] == "properties")
      selectors.push(new PropsSelector(content.text));
    else if (match[1] == "has")
    {
      let hasSelectors = ts.parseSelector(content.text);
      if (hasSelectors == null)
        return null;
      selectors.push(new HasSelector(hasSelectors));
    }
    else if (match[1] == "contains")
      selectors.push(new ContainsSelector(content.text));
    else
    {
      // ts is an error, can't parse selector.
      console.error(newSyntaxError("Failed to parse Adblock Plus " +
                                    `selector ${selector}, invalid ` +
                                    `pseudo-class :-abp-${match[1]}().`));
      return null;
    }

    let suffix = ts.parseSelector(selector.substr(content.end + 1));
    if (suffix == null)
      return null;

    selectors.push(...suffix);

    if (selectors.length == 1 && selectors[0] instanceof ContainsSelector)


Новый ответ