text:
/* -*- Mode: js; js-indent-level: 2; -*- */
/*
 * Copyright 2011 Mozilla Foundation and contributors
 * Licensed under the New BSD license. See LICENSE or:
 * http://opensource.org/licenses/BSD-3-Clause
 */
define(function (require, exports, module) {

  var util = require('source-map/util');
  var binarySearch = require('source-map/binary-search');
  var ArraySet = require('source-map/array-set').ArraySet;
  var base64VLQ = require('source-map/base64-vlq');

  // TODO:  bug 673487
  //
  // Sometime in the future, if we decide we need to be able to query where in
  // the generated source a piece of the original code came from, we may want to
  // add a slot `_originalMappings` which would be an object keyed by the
  // original source and whose value would be an array of mappings ordered by
  // original line/col rather than generated (which is what we have now in
  // `_generatedMappings`).

  /**
   * A SourceMapConsumer instance represents a parsed source map which we can
   * query for information about the original file positions by giving it a file
   * position in the generated source.
   *
   * The only parameter is the raw source map (either as a JSON string, or
   * already parsed to an object). According to the spec, source maps have the
   * following attributes:
   *
   *   - version: Which version of the source map spec this map is following.
   *   - sources: An array of URLs to the original source files.
   *   - names: An array of identifiers which can be referrenced by individual mappings.
   *   - sourceRoot: Optional. The URL root from which all sources are relative.
   *   - mappings: A string of base64 VLQs which contain the actual mappings.
   *   - file: The generated file this source map is associated with.
   *
   * Here is an example source map, taken from the source map spec[0]:
   *
   *     {
   *       version : 3,
   *       file: "out.js",
   *       sourceRoot : "",
   *       sources: ["foo.js", "bar.js"],
   *       names: ["src", "maps", "are", "fun"],
   *       mappings: "AA,AB;;ABCDE;"
   *     }
   *
   * [0]: https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit?pli=1#
   */
  function SourceMapConsumer(aSourceMap) {
    var sourceMap = aSourceMap;
    if (typeof aSourceMap === 'string') {
      sourceMap = JSON.parse(aSourceMap.replace(/^\)\]\}'/, ''));
    }

    var version = util.getArg(sourceMap, 'version');
    var sources = util.getArg(sourceMap, 'sources');
    var names = util.getArg(sourceMap, 'names');
    var sourceRoot = util.getArg(sourceMap, 'sourceRoot', null);
    var mappings = util.getArg(sourceMap, 'mappings');
    var file = util.getArg(sourceMap, 'file');

    if (version !== this._version) {
      throw new Error('Unsupported version: ' + version);
    }

    this._names = ArraySet.fromArray(names);
    this._sources = ArraySet.fromArray(sources);

    // `this._generatedMappings` hold the parsed mapping coordinates from the
    // source map's "mappings" attribute. Each object in the array is of the
    // form
    //
    //     {
    //       generatedLine: The line number in the generated code,
    //       generatedColumn: The column number in the generated code,
    //       source: The path to the original source file that generated this
    //               chunk of code,
    //       originalLine: The line number in the original source that
    //                     corresponds to this chunk of generated code,
    //       originalColumn: The column number in the original source that
    //                       corresponds to this chunk of generated code,
    //       name: The name of the original symbol which generated this chunk of
    //             code.
    //     }
    //
    // All properties except for `generatedLine` and `generatedColumn` can be
    // `null`.
    this._generatedMappings = [];
    this._parseMappings(mappings, sourceRoot);
  }

  /**
   * The version of the source mapping spec that we are consuming.
   */
  SourceMapConsumer.prototype._version = 3;

  /**
   * Parse the mappings in a string in to a data structure which we can easily
   * query (an ordered list in this._generatedMappings).
   */
  SourceMapConsumer.prototype._parseMappings =
    function SourceMapConsumer_parseMappings(aStr, aSourceRoot) {
      var generatedLine = 1;
      var previousGeneratedColumn = 0;
      var previousOriginalLine = 0;
      var previousOriginalColumn = 0;
      var previousSource = 0;
      var previousName = 0;
      var mappingSeparator = /^[,;]/;
      var str = aStr;
      var mapping;
      var temp;

      while (str.length > 0) {
        if (str.charAt(0) === ';') {
          generatedLine++;
          str = str.slice(1);
          previousGeneratedColumn = 0;
        }
        else if (str.charAt(0) === ',') {
          str = str.slice(1);
        }
        else {
          mapping = {};
          mapping.generatedLine = generatedLine;

          // Generated column.
          temp = base64VLQ.decode(str);
          mapping.generatedColumn = previousGeneratedColumn + temp.value;
          previousGeneratedColumn = mapping.generatedColumn;
          str = temp.rest;

          if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
            // Original source.
            temp = base64VLQ.decode(str);
            if (aSourceRoot) {
              mapping.source = util.join(aSourceRoot, this._sources.at(previousSource + temp.value));
            }
            else {
              mapping.source = this._sources.at(previousSource + temp.value);
            }
            previousSource += temp.value;
            str = temp.rest;
            if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
              throw new Error('Found a source, but no line and column');
            }

            // Original line.
            temp = base64VLQ.decode(str);
            mapping.originalLine = previousOriginalLine + temp.value;
            previousOriginalLine = mapping.originalLine;
            // Lines are stored 0-based
            mapping.originalLine += 1;
            str = temp.rest;
            if (str.length === 0 || mappingSeparator.test(str.charAt(0))) {
              throw new Error('Found a source and line, but no column');
            }

            // Original column.
            temp = base64VLQ.decode(str);
            mapping.originalColumn = previousOriginalColumn + temp.value;
            previousOriginalColumn = mapping.originalColumn;
            str = temp.rest;

            if (str.length > 0 && !mappingSeparator.test(str.charAt(0))) {
              // Original name.
              temp = base64VLQ.decode(str);
              mapping.name = this._names.at(previousName + temp.value);
              previousName += temp.value;
              str = temp.rest;
            }
          }

          this._generatedMappings.push(mapping);
        }
      }
    };

  /**
   * Returns the original source, line, and column information for the generated
   * source's line and column positions provided. The only argument is an object
   * with the following properties:
   *
   *   - line: The line number in the generated source.
   *   - column: The column number in the generated source.
   *
   * and an object is returned with the following properties:
   *
   *   - source: The original source file, or null.
   *   - line: The line number in the original source, or null.
   *   - column: The column number in the original source, or null.
   *   - name: The original identifier, or null.
   */
  SourceMapConsumer.prototype.originalPositionFor =
    function SourceMapConsumer_originalPositionFor(aArgs) {
      // To return the original position, we must first find the mapping for the
      // given generated position and then return the original position it
      // points to. Because the mappings are sorted by generated line/column, we
      // can use binary search to find the best mapping.

      // To perform a binary search on the mappings, we must be able to compare
      // two mappings.
      function compare(mappingA, mappingB) {
        var cmp = mappingA.generatedLine - mappingB.generatedLine;
        return cmp === 0
          ? mappingA.generatedColumn - mappingB.generatedColumn
          : cmp;
      }

      // This is the mock of the mapping we are looking for: the needle in the
      // haystack of mappings.
      var needle = {
        generatedLine: util.getArg(aArgs, 'line'),
        generatedColumn: util.getArg(aArgs, 'column')
      };

      if (needle.generatedLine <= 0) {
        throw new TypeError('Line must be greater than or equal to 1.');
      }
      if (needle.generatedColumn < 0) {
        throw new TypeError('Column must be greater than or equal to 0.');
      }

      var mapping = binarySearch.search(needle, this._generatedMappings, compare);

      if (mapping) {
        return {
          source: util.getArg(mapping, 'source', null),
          line: util.getArg(mapping, 'originalLine', null),
          column: util.getArg(mapping, 'originalColumn', null),
          name: util.getArg(mapping, 'name', null)
        };
      }

      return {
        source: null,
        line: null,
        column: null,
        name: null
      };

    };

  exports.SourceMapConsumer = SourceMapConsumer;

});


text:
:mod:`numbers` --- Numeric abstract base classes
================================================

.. module:: numbers
   :synopsis: Numeric abstract base classes (Complex, Real, Integral, etc.).

.. versionadded:: 2.6

The :mod:`numbers` module (:pep:`3141`) defines a hierarchy of numeric abstract
base classes which progressively define more operations.  None of the types
defined in this module can be instantiated.

.. class:: Number

   The root of the numeric hierarchy. If you just want to check if an argument
   *x* is a number, without caring what kind, use ``isinstance(x, Number)``.

The numeric tower
-----------------

.. class:: Complex

   Subclasses of this type describe complex numbers and include the operations
   that work on the builtin :class:`complex` type. These are: conversions to
   :class:`complex` and :class:`bool`, :attr:`.real`, :attr:`.imag`, ``+``,
   ``-``, ``*``, ``/``, :func:`abs`, :meth:`conjugate`, ``==``, and ``!=``. All
   except ``-`` and ``!=`` are abstract.

   .. attribute:: real

      Abstract. Retrieves the :class:`Real` component of this number.

   .. attribute:: imag

      Abstract. Retrieves the :class:`Real` component of this number.

   .. method:: conjugate()

      Abstract. Returns the complex conjugate. For example, ``(1+3j).conjugate()
      == (1-3j)``.

.. class:: Real

   To :class:`Complex`, :class:`Real` adds the operations that work on real
   numbers.

   In short, those are: a conversion to :class:`float`, :func:`trunc`,
   :func:`round`, :func:`math.floor`, :func:`math.ceil`, :func:`divmod`, ``//``,
   ``%``, ``<``, ``<=``, ``>``, and ``>=``.

   Real also provides defaults for :func:`complex`, :attr:`~Complex.real`,
   :attr:`~Complex.imag`, and :meth:`~Complex.conjugate`.

.. class:: Rational

   Subtypes :class:`Real` and adds
   :attr:`~Rational.numerator` and :attr:`~Rational.denominator` properties, which
   should be in lowest terms. With these, it provides a default for
   :func:`float`.

   .. attribute:: numerator

      Abstract.

   .. attribute:: denominator

      Abstract.

.. class:: Integral

   Subtypes :class:`Rational` and adds a conversion to :class:`int`.
   Provides defaults for :func:`float`, :attr:`~Rational.numerator`, and
   :attr:`~Rational.denominator`, and bit-string operations: ``<<``,
   ``>>``, ``&``, ``^``, ``|``, ``~``.

Notes for type implementors
---------------------------

Implementors should be careful to make equal numbers equal and hash
them to the same values. This may be subtle if there are two different
extensions of the real numbers. For example, :class:`fractions.Fraction`
implements :func:`hash` as follows::

    def __hash__(self):
        if self.denominator == 1:
            # Get integers right.
            return hash(self.numerator)
        # Expensive check, but definitely correct.
        if self == float(self):
            return hash(float(self))
        else:
            # Use tuple's hash to avoid a high collision rate on
            # simple fractions.
            return hash((self.numerator, self.denominator))

Adding More Numeric ABCs
~~~~~~~~~~~~~~~~~~~~~~~~

There are, of course, more possible ABCs for numbers, and this would
be a poor hierarchy if it precluded the possibility of adding
those. You can add ``MyFoo`` between :class:`Complex` and
:class:`Real` with::

    class MyFoo(Complex): ...
    MyFoo.register(Real)

Implementing the arithmetic operations
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

We want to implement the arithmetic operations so that mixed-mode
operations either call an implementation whose author knew about the
types of both arguments, or convert both to the nearest built in type
and do the operation there. For subtypes of :class:`Integral`, this
means that :meth:`__add__` and :meth:`__radd__` should be defined as::

    class MyIntegral(Integral):

        def __add__(self, other):
            if isinstance(other, MyIntegral):
                return do_my_adding_stuff(self, other)
            elif isinstance(other, OtherTypeIKnowAbout):
                return do_my_other_adding_stuff(self, other)
            else:
                return NotImplemented

        def __radd__(self, other):
            if isinstance(other, MyIntegral):
                return do_my_adding_stuff(other, self)
            elif isinstance(other, OtherTypeIKnowAbout):
                return do_my_other_adding_stuff(other, self)
            elif isinstance(other, Integral):
                return int(other) + int(self)
            elif isinstance(other, Real):
                return float(other) + float(self)
            elif isinstance(other, Complex):
                return complex(other) + complex(self)
            else:
                return NotImplemented

There are 5 different cases for a mixed-type operation on subclasses
of :class:`Complex`. I'll refer to all of the above code that doesn't
refer to ``MyIntegral`` and ``OtherTypeIKnowAbout`` as
"boilerplate". ``a`` will be an instance of ``A``, which is a subtype
of :class:`Complex` (``a : A <: Complex``), and ``b : B <:
Complex``. I'll consider ``a + b``:

    1. If ``A`` defines an :meth:`__add__` which accepts ``b``, all is
       well.
    2. If ``A`` falls back to the boilerplate code, and it were to
       return a value from :meth:`__add__`, we'd miss the possibility
       that ``B`` defines a more intelligent :meth:`__radd__`, so the
       boilerplate should return :const:`NotImplemented` from
       :meth:`__add__`. (Or ``A`` may not implement :meth:`__add__` at
       all.)
    3. Then ``B``'s :meth:`__radd__` gets a chance. If it accepts
       ``a``, all is well.
    4. If it falls back to the boilerplate, there are no more possible
       methods to try, so this is where the default implementation
       should live.
    5. If ``B <: A``, Python tries ``B.__radd__`` before
       ``A.__add__``. This is ok, because it was implemented with
       knowledge of ``A``, so it can handle those instances before
       delegating to :class:`Complex`.

If ``A <: Complex`` and ``B <: Real`` without sharing any other knowledge,
then the appropriate shared operation is the one involving the built
in :class:`complex`, and both :meth:`__radd__` s land there, so ``a+b
== b+a``.

Because most of the operations on any given type will be very similar,
it can be useful to define a helper function which generates the
forward and reverse instances of any given operator. For example,
:class:`fractions.Fraction` uses::

    def _operator_fallbacks(monomorphic_operator, fallback_operator):
        def forward(a, b):
            if isinstance(b, (int, long, Fraction)):
                return monomorphic_operator(a, b)
            elif isinstance(b, float):
                return fallback_operator(float(a), b)
            elif isinstance(b, complex):
                return fallback_operator(complex(a), b)
            else:
                return NotImplemented
        forward.__name__ = '__' + fallback_operator.__name__ + '__'
        forward.__doc__ = monomorphic_operator.__doc__

        def reverse(b, a):
            if isinstance(a, Rational):
                # Includes ints.
                return monomorphic_operator(a, b)
            elif isinstance(a, numbers.Real):
                return fallback_operator(float(a), float(b))
            elif isinstance(a, numbers.Complex):
                return fallback_operator(complex(a), complex(b))
            else:
                return NotImplemented
        reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
        reverse.__doc__ = monomorphic_operator.__doc__

        return forward, reverse

    def _add(a, b):
        """a + b"""
        return Fraction(a.numerator * b.denominator +
                        b.numerator * a.denominator,
                        a.denominator * b.denominator)

    __add__, __radd__ = _operator_fallbacks(_add, operator.add)

    # ...

redpajama_set_name: RedPajamaGithub


text:
package org.apache.geode.cache.wan;

import static java.lang.System.lineSeparator;
import static org.apache.geode.cache.Region.SEPARATOR;
import static org.apache.geode.distributed.ConfigurationProperties.DISTRIBUTED_SYSTEM_ID;
import static org.apache.geode.distributed.ConfigurationProperties.LOCATORS;
import static org.apache.geode.distributed.ConfigurationProperties.REMOTE_LOCATORS;
import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;
import java.util.Vector;

import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import org.apache.geode.cache.Cache;
import org.apache.geode.cache.CacheFactory;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionFactory;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.persistence.PartitionOfflineException;
import org.apache.geode.distributed.Locator;
import org.apache.geode.internal.cache.ForceReattemptException;
import org.apache.geode.internal.cache.PoolStats;
import org.apache.geode.internal.cache.wan.AbstractGatewaySender;
import org.apache.geode.internal.cache.wan.GatewaySenderStats;
import org.apache.geode.internal.cache.wan.InternalGatewaySenderFactory;
import org.apache.geode.rules.DockerComposeRule;
import org.apache.geode.test.dunit.IgnoredException;
import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.rules.DistributedRule;
import org.apache.geode.test.junit.categories.WanTest;
import org.apache.geode.util.internal.GeodeGlossary;

/**
 * These tests use two Geode sites:
 *
 * - One site (the remote one) consisting of a 2-server, 1-locator Geode cluster. The servers host a
 * partition region (region-wan) and have gateway senders to receive events from the other site with
 * the same value for hostname-for-senders and listening on the same port (2324). The servers and
 * locator run each inside a Docker container and are not route-able from the host (where this JUnit
 * test is running). Another Docker container is running the HAProxy image and it's set up as a TCP
 * load balancer. The other site connects to the locator and to the gateway receivers via the TCP
 * load balancer that forwards traffic directed to the 20334 port to the locator and traffic
 * directed to the 2324 port to the receivers in a round robin fashion.
 *
 * - Another site consisting of a 1-server, 1-locator Geode cluster. The server hosts a partition
 * region (region-wan) and has a gateway receiver to send events to the remote site.
 */
@Category({WanTest.class})
public class SeveralGatewayReceiversWithSamePortAndHostnameForSendersTest {

  private static final int NUM_SERVERS = 2;

  private static Cache cache;

  private static final URL DOCKER_COMPOSE_PATH =
      SeveralGatewayReceiversWithSamePortAndHostnameForSendersTest.class
          .getResource("docker-compose.yml");

  @ClassRule
  public static DockerComposeRule docker = new DockerComposeRule.Builder()
      .file(DOCKER_COMPOSE_PATH.getPath())
      .service("haproxy", 20334)
      .service("haproxy", 2324)
      .build();

  @Rule
  public DistributedRule distributedRule =
      DistributedRule.builder().withVMCount(NUM_SERVERS + 1).build();

  @BeforeClass
  public static void beforeClass() throws Exception {
    // Start locator
    docker.execForService("locator", "gfsh", "-e",
        startLocatorCommand());
    // Start server1
    docker.execForService("server1", "gfsh", "-e",
        "start server --name=server1 --locators=locator[20334]");
    docker.execForService("server2", "gfsh", "-e",
        "start server --name=server2 --locators=locator[20334]");

    docker.execForService("locator", "gfsh",
        "-e", "connect --locator=locator[20334]",
        "-e", "create region --name=region-wan --type=PARTITION");

    // Create gateway receiver
    String createGatewayReceiverCommand = createGatewayReceiverCommand();
    docker.execForService("locator", "gfsh", "-e",
        "connect --locator=locator[20334]", "-e", createGatewayReceiverCommand);
  }

  public SeveralGatewayReceiversWithSamePortAndHostnameForSendersTest() {
    super();
  }

  /**
   * The aim of this test is verify that when several gateway receivers in a remote site share the
   * same port and hostname-for-senders, the pings sent from the gateway senders reach the right
   * gateway receiver and not just any of the receivers. Failure to do this may result in the
   * closing of connections by a gateway receiver for not having received the ping in time.
   */
  @Test
  public void testPingsToReceiversWithSamePortAndHostnameForSendersReachTheRightReceivers()
      throws InterruptedException {
    String senderId = "ln";
    String regionName = "region-wan";
    final int remoteLocPort = docker.getExternalPortForService("haproxy", 20334);

    int locPort = createLocator(VM.getVM(0), 1, remoteLocPort);

    VM vm1 = VM.getVM(1);
    createCache(vm1, locPort);

    // We must use more than one dispatcher thread. With just one dispatcher thread, only one
    // connection will be created by the sender towards one of the receivers and it will be
    // monitored by the one ping thread for that remote receiver.
    // With more than one thread, several connections will be opened and there should be one ping
    // thread per remote receiver.
    createGatewaySender(vm1, senderId, 2, true, 5,
        5, GatewaySender.DEFAULT_ORDER_POLICY);

    createPartitionedRegion(vm1, regionName, senderId, 0, 10);

    int NUM_PUTS = 10;

    putKeyValues(vm1, NUM_PUTS, regionName);

    await()
        .untilAsserted(() -> assertThat(getQueuedEvents(vm1, senderId)).isEqualTo(0));

    // Wait longer than the value set in the receivers for
    // maximum-time-between-pings: 10000 (see geode-starter-create.gfsh)
    // to verify that connections are not closed
    // by the receivers because each has received the pings timely.
    int maxTimeBetweenPingsInReceiver = 15000;
    Thread.sleep(maxTimeBetweenPingsInReceiver);

    int senderPoolDisconnects = getSenderPoolDisconnects(vm1, senderId);
    assertEquals(0, senderPoolDisconnects);
  }

  @Test
  public void testSerialGatewaySenderThreadsConnectToSameReceiver() {
    String senderId = "ln";
    String regionName = "region-wan";
    final int remoteLocPort = docker.getExternalPortForService("haproxy", 20334);

    int locPort = createLocator(VM.getVM(0), 1, remoteLocPort);

    VM vm1 = VM.getVM(1);
    createCache(vm1, locPort);

    createGatewaySender(vm1, senderId, 2, false, 5,
        3, GatewaySender.DEFAULT_ORDER_POLICY);

    createPartitionedRegion(vm1, regionName, senderId, 0, 10);

    assertTrue(allDispatchersConnectedToSameReceiver(1));
    assertTrue(allDispatchersConnectedToSameReceiver(2));

  }

  @Test
  public void testTwoSendersWithSameIdShouldUseSameValueForEnforceThreadsConnectToSameServer() {
    String senderId = "ln";
    final int remoteLocPort = docker.getExternalPortForService("haproxy", 20334);

    int locPort = createLocator(VM.getVM(0), 1, remoteLocPort);

    VM vm1 = VM.getVM(1);
    createCache(vm1, locPort);

    VM vm2 = VM.getVM(2);
    createCache(vm2, locPort);

    createGatewaySender(vm1, senderId, 2, false, 5,
        3, GatewaySender.DEFAULT_ORDER_POLICY);

    Exception exception =
        assertThrows(Exception.class, () -> createGatewaySender(vm2, senderId, 2, false, 5,
            3, GatewaySender.DEFAULT_ORDER_POLICY, false));
    assertEquals(exception.getCause().getMessage(), "Cannot create Gateway Sender " + senderId
        + " with enforceThreadsConnectSameReceiver false because another cache has the same Gateway Sender defined with enforceThreadsConnectSameReceiver true");

  }

  /**
   * The aim of this test is verify that when several gateway receivers in a remote site share the
   * same port and hostname-for-senders, the pings sent from the gateway senders reach the right
   * gateway receiver and not just any of the receivers. Check that only one additional connection
   * is used.
   */
  @Test
  public void testPingsToReceiversWithSamePortAndHostnameForSendersUseOnlyOneMoreConnection()
      throws InterruptedException {
    String senderId = "ln";
    String regionName = "region-wan";
    final int remoteLocPort = docker.getExternalPortForService("haproxy", 20334);

    int locPort = createLocator(VM.getVM(0), 1, remoteLocPort);

    VM vm1 = VM.getVM(1);

    vm1.invoke(() -> {
      System.setProperty(
          GeodeGlossary.GEMFIRE_PREFIX
              + "LiveServerPinger.INITIAL_DELAY_MULTIPLIER_IN_MILLISECONDS",
          "500");

      Properties props = new Properties();
      props.setProperty(LOCATORS, "localhost[" + locPort + "]");
      CacheFactory cacheFactory = new CacheFactory(props);
      cache = cacheFactory.create();
    });

    createGatewaySender(vm1, senderId, 2, true, 5,
        2, GatewaySender.DEFAULT_ORDER_POLICY);

    createPartitionedRegion(vm1, regionName, senderId, 0, 10);

    int NUM_PUTS = 10;

    putKeyValues(vm1, NUM_PUTS, regionName);

    await().untilAsserted(() -> assertThat(getQueuedEvents(vm1, senderId)).isEqualTo(0));

    await().untilAsserted(() -> assertThat(getSenderPoolDisconnects(vm1, senderId)).isEqualTo(0));

    await().untilAsserted(
        () -> assertThat(getSenderPoolConnects(vm1, senderId)).isIn(3, 4));
  }

  private boolean allDispatchersConnectedToSameReceiver(int server) {

    String gfshOutput = runListGatewayReceiversCommandInServer(server);
    Vector<String> sendersConnectedToServer = parseSendersConnectedFromGfshOutput(gfshOutput);
    String firstSenderId = "";
    for (String senderId : sendersConnectedToServer) {
      if (firstSenderId.equals("")) {
        firstSenderId = senderId;
      } else {
        assertEquals("Found two different senders (" + firstSenderId + " and " + senderId
            + ") connected to same receiver in server " + server, firstSenderId, senderId);
      }
    }
    return true;
  }

  private String runListGatewayReceiversCommandInServer(int serverN) {
    return docker.execForService("locator", "gfsh",
        "-e", "set variable --name=APP_RESULT_VIEWER --value=200",
        "-e", "connect --locator=locator[20334]",
        "-e", "list gateways --receivers-only --member=server" + serverN);
  }

  private Vector<String> parseSendersConnectedFromGfshOutput(String gfshOutput) {
    String[] lines = gfshOutput.split(lineSeparator());
    final String sendersConnectedColumnHeader = "Senders Connected";
    String receiverInfo = null;
    for (int i = 0; i < lines.length; i++) {
      if (lines[i].contains(sendersConnectedColumnHeader)) {
        receiverInfo = lines[i + 2];
        break;
      }
    }
    assertNotNull(
        "Error parsing gfsh output. '" + sendersConnectedColumnHeader + "' column header not found",
        receiverInfo);
    String[] tableRow = receiverInfo.split("\\|");
    String sendersConnectedColumnValue = tableRow[3].trim();
    Vector<String> senders = new Vector<>();
    for (String sender : sendersConnectedColumnValue.split(",")) {
      senders.add(sender.trim());
    }
    return senders;
  }

  private int createLocator(VM memberVM, int dsId, int remoteLocPort) {
    return memberVM.invoke("create locator", () -> {
      Properties props = new Properties();
      props.setProperty(DISTRIBUTED_SYSTEM_ID, "" + dsId);
      props.setProperty(REMOTE_LOCATORS, "localhost[" + remoteLocPort + "]");
      return Locator.startLocatorAndDS(0, new File(""), props)
          .getPort();
    });
  }

  private static void createCache(VM vm, Integer locPort) {
    vm.invoke(() -> {
      Properties props = new Properties();
      props.setProperty(LOCATORS, "localhost[" + locPort + "]");
      CacheFactory cacheFactory = new CacheFactory(props);
      cache = cacheFactory.create();
    });
  }

  public static void createGatewaySender(VM vm, String dsName, int remoteDsId,
      boolean isParallel, Integer batchSize,
      int numDispatchers,
      GatewaySender.OrderPolicy orderPolicy) {
    createGatewaySender(vm, dsName, remoteDsId, isParallel, batchSize, numDispatchers, orderPolicy,
        true);
  }

  public static void createGatewaySender(VM vm, String dsName, int remoteDsId,
      boolean isParallel, Integer batchSize,
      int numDispatchers,
      GatewaySender.OrderPolicy orderPolicy,
      boolean enforceThreadsConnectToSameReceiver) {
    vm.invoke(() -> {
      final IgnoredException exln = IgnoredException.addIgnoredException("Could not connect");
      try {
        InternalGatewaySenderFactory gateway =
            (InternalGatewaySenderFactory) cache.createGatewaySenderFactory();
        gateway.setParallel(isParallel);
        gateway.setBatchSize(batchSize);
        gateway.setDispatcherThreads(numDispatchers);
        gateway.setOrderPolicy(orderPolicy);
        gateway.setEnforceThreadsConnectSameReceiver(enforceThreadsConnectToSameReceiver);
        gateway.create(dsName, remoteDsId);

      } finally {
        exln.remove();
      }
    });
  }

  private static void createPartitionedRegion(VM vm, String regionName, String senderIds,
      Integer redundantCopies, Integer totalNumBuckets) {
    vm.invoke(() -> {
      IgnoredException exp =
          IgnoredException.addIgnoredException(ForceReattemptException.class.getName());
      IgnoredException exp1 =
          IgnoredException.addIgnoredException(PartitionOfflineException.class.getName());
      try {
        RegionFactory fact = cache.createRegionFactory(RegionShortcut.PARTITION);
        if (senderIds != null) {
          StringTokenizer tokenizer = new StringTokenizer(senderIds, ",");
          while (tokenizer.hasMoreTokens()) {
            String senderId = tokenizer.nextToken();
            fact.addGatewaySenderId(senderId);
          }
        }
        PartitionAttributesFactory pfact = new PartitionAttributesFactory();
        pfact.setTotalNumBuckets(totalNumBuckets);
        pfact.setRedundantCopies(redundantCopies);
        pfact.setRecoveryDelay(0);
        fact.setPartitionAttributes(pfact.create());
        Region r = fact.create(regionName);
        assertNotNull(r);
      } finally {
        exp.remove();
        exp1.remove();
      }
    });
  }

  private static int getQueuedEvents(VM vm, String senderId) {
    return vm.invoke(() -> {
      AbstractGatewaySender sender = (AbstractGatewaySender) cache.getGatewaySender(senderId);
      GatewaySenderStats statistics = sender.getStatistics();
      return statistics.getEventQueueSize();
    });
  }

  private static int getSenderPoolDisconnects(VM vm, String senderId) {
    return vm.invoke(() -> {
      AbstractGatewaySender sender =
          (AbstractGatewaySender) CacheFactory.getAnyInstance().getGatewaySender(senderId);
      assertThat(sender).isNotNull();
      PoolStats poolStats = sender.getProxy().getStats();
      return poolStats.getDisConnects();
    });
  }

  private static int getSenderPoolConnects(VM vm, String senderId) {
    return vm.invoke(() -> {
      AbstractGatewaySender sender =
          (AbstractGatewaySender) CacheFactory.getAnyInstance().getGatewaySender(senderId);
      assertThat(sender).isNotNull();
      PoolStats poolStats = sender.getProxy().getStats();
      return poolStats.getConnects();
    });
  }

  private static void putKeyValues(VM vm, int numPuts, String region) {
    final HashMap<Integer, Integer> keyValues = new HashMap<>();
    for (int i = 0; i < numPuts; i++) {
      keyValues.put(i, i);
    }
    vm.invoke(() -> putGivenKeyValue(region, keyValues));
  }

  private static void putGivenKeyValue(String regionName, Map<Integer, Integer> keyValues) {
    Region<Integer, Integer> r = cache.getRegion(SEPARATOR + regionName);
    assertNotNull(r);
    for (Object key : keyValues.keySet()) {
      r.put((Integer) key, keyValues.get(key));
    }
  }

  private static String createGatewayReceiverCommand() {
    String ipAddress = docker.getIpAddressForService("haproxy", "geode-wan-test");
    return "create gateway-receiver --hostname-for-senders=" + ipAddress
        + " --start-port=2324 --end-port=2324 --maximum-time-between-pings=10000";
  }

  private static String startLocatorCommand() {
    String ipAddress = docker.getIpAddressForService("haproxy", "geode-wan-test");
    return "start locator --name=locator --port=20334 --connect=false --redirect-output --enable-cluster-configuration=true --hostname-for-clients="
        + ipAddress + " --J=-Dgemfire.distributed-system-id=2";

  }

}


text:
package Bio::EnsEMBL::Analysis::Hive::RunnableDB::HiveDownloadRefSeqmRNA;

use strict;
use warnings;
use feature 'say';
use Bio::EnsEMBL::Utils::PolyA;
use Bio::SeqIO;
#use Bio::EnsEMBL::IO::Parser::Fasta;
use POSIX qw(strftime);

use parent ('Bio::EnsEMBL::Analysis::Hive::RunnableDB::HiveBaseRunnableDB');

sub fetch_input {
  my $self = shift;

  my $ftp_path = $self->param('ftp_path');
  my $output_path = $self->param('output_path');

  unless(-e $output_path) {
    system("mkdir -p ".$output_path);
  }

  my $cmd = "wget ".$ftp_path." -O ".$output_path."/refseq_cdnas.fa.gz";
  my $result = system($cmd);
  if($result) {
    $self->throw("Unable to download the RefSeq mRNA file. Commandline used:\n".$cmd);
  }

  $cmd = "gunzip -f ".$output_path."/refseq_cdnas.fa.gz";
  $result = system($cmd);
  if($result) {
    $self->throw("Unable to unzip the RefSeq mRNA file. Commandline used:\n".$cmd);
  }

  return 1;
}

sub run {
  my $self = shift;

  return 1;
}

sub write_output {
  my $self = shift;

  my $db_path = $self->param('output_path')."/refseq_cdnas.fa";
  my $min_length = $self->param("min_seq_length");
  unless($min_length) {
    $min_length = 60;
  }

#  my $parser = Bio::EnsEMBL::IO::Parser::Fasta->open($db_path);
  my $date = strftime "%m/%d/%Y", localtime;

  my $table_adaptor = $self->db->get_NakedTableAdaptor();
  $table_adaptor->table_name('refseq_sequences');

  my $seq_file = new Bio::SeqIO( -file   => $db_path,
                              -format => "Fasta", );

  while (my $seq = $seq_file->next_seq) {
    my $biotype = 'cdna';
    my $header = $seq->display_id;
    say "Header: ".$header;

    if($header =~ /^XR/ || $header =~ /^NR/) {
      say "Not storing RNA accession: ".$header;
      next;
    }

    unless($header =~ /^NM/ || $header =~ /^AM/) {
      $biotype .= "_predicted";
    }

    my $polyA_clipper = Bio::EnsEMBL::Utils::PolyA->new();

    my $clipped_seq = $polyA_clipper->clip($seq);
    unless (defined $clipped_seq) {
      say "Clipping made a cdna vanish...";
      next;
    }

    if ($clipped_seq->length < $min_length) {
      say "Sequence is below min length...";
      next;
    }

    my $output_hash = {};
    $output_hash->{'iid'} = [$header];

    my $db_row = [{ 'accession'  => $header,
                    'source_db'  => 'RefSeq',
                    'date'       => $date,
                    'seq'        => $clipped_seq->seq,
                    'biotype'    => $biotype,
                  }];
    $table_adaptor->store($db_row);

    $self->dataflow_output_id($output_hash,2);
  }
  return 1;
}

1;


text:
angular.module('mnAdminServersAddDialogService').factory('mnAdminServersAddDialogService',
  function (mnHttpService) {
    var mnAdminServersAddDialogService = {};
    var initialNewServer = {
      hostname: '',
      user: 'Administrator',
      password: ''
    };
    mnAdminServersAddDialogService.model = {
      selectedGroup: undefined
    };
    mnAdminServersAddDialogService.model.newServer = {};
    mnAdminServersAddDialogService.resetModel = function () {
      mnAdminServersAddDialogService.model.newServer = _.clone(initialNewServer);
    };

    mnAdminServersAddDialogService.addServer = _.compose(mnHttpService({
      method: 'POST'
    }), function (url) {
      var selectedGroup = mnAdminServersAddDialogService.model.selectedGroup;
      return {
        url: (selectedGroup && selectedGroup.addNodeURI) || url,
        data: mnAdminServersAddDialogService.model.newServer
      };
    });

    return mnAdminServersAddDialogService;

  });


text:
#include "StateMachine.h"
#include "Graphics.h"
#include "Logger.h"
#include "Status.h"
#include "Timing.h"
#include "input/Input.h"
#include "platform.h"
#include "render/Text.h"
#include "utility/misc.h"
#include "version.h"

#if IMGUI
#include "imgui-events-SFML.h"
#include "imgui-rendering-SFML.h"
#include <SFML/System.hpp>
#endif

using namespace WalrusRPG; /*::StateMachine*/
using namespace WalrusRPG::Graphics;
using namespace WalrusRPG::Timing;
using namespace WalrusRPG::Logger;
using WalrusRPG::Input::Key;
using WalrusRPG::Input::KeyState;
using WalrusRPG::States::State;

namespace
{
#if IMGUI
    float update_times[200] = {0};
    float render_times[200] = {0};
    bool show_logger = false;
    bool show_state_debug = false;

    /**
     * Debug function showing a button state.
     */
    void draw_button(ImDrawList *list, signed x, signed y, KeyState state)
    {
        uint32_t button_color;
        switch (state)
        {
            case KeyState::KS_RELEASED:
                button_color = 0xFFFFFFFF;
                break;
            case KeyState::KS_JUST_RELEASED:
                button_color = 0xFFFFFF00;
                break;
            case KeyState::KS_JUST_PRESSED:
                button_color = 0xFFFF00FF;
                break;
            case KeyState::KS_PRESSED:
                button_color = 0xFF000000;
                break;
        }
        list->AddRectFilled({static_cast<float>(x), static_cast<float>(y)},
                            {static_cast<float>(x) + 8, static_cast<float>(y) + 8},
                            button_color);
    }

    /**
     * Draws WRPG's buttons states.
     */
    void draw_buttons()
    {
        ImGui::BeginGroup();
        ImGui::Text("Input state");
        ImGui::Indent();
        ImVec2 s = ImGui::GetCursorScreenPos();
        ImDrawList *list = ImGui::GetWindowDrawList();
        draw_button(list, s.x + 0, s.y, key_get_state(Key::K_L));
        draw_button(list, s.x + 56, s.y, key_get_state(Key::K_R));

        draw_button(list, s.x + 8, s.y + 8, key_get_state(Key::K_UP));
        draw_button(list, s.x + 0, s.y + 16, key_get_state(Key::K_LEFT));
        draw_button(list, s.x + 16, s.y + 16, key_get_state(Key::K_RIGHT));
        draw_button(list, s.x + 8, s.y + 24, key_get_state(Key::K_DOWN));

        draw_button(list, s.x + 27, s.y + 24, key_get_state(Key::K_SELECT));
        draw_button(list, s.x + 37, s.y + 24, key_get_state(Key::K_START));

        draw_button(list, s.x + 48, s.y + 20, key_get_state(Key::K_B));
        draw_button(list, s.x + 56, s.y + 12, key_get_state(Key::K_A));
        ImGui::SetCursorPosY(ImGui::GetCursorPosY() + 32 +
                             ImGui::GetTextLineHeightWithSpacing());
        ImGui::Unindent();
        ImGui::EndGroup();
    }
#endif

    // State stack. Pointer because polymorphism.
    static tinystl::vector<WalrusRPG::States::State *> stack;

} /* namespace */

void StateMachine::init()
{
    log("State Machine init");
}

void StateMachine::deinit()
{
    log("State Machine deinit");
    while (!stack.empty())
    {
        delete stack.back();
        stack.pop_back();
    }
    stack.clear();
}

void StateMachine::push(State *state)
{
    stack.push_back(state);
}

void StateMachine::pop()
{
    // Mmmh, should StateMachine manage the state's destruction?...
    delete stack.back();
    stack.pop_back();
}

void StateMachine::run()
{
    const unsigned loop_time = TIMER_FREQ / 60;
    unsigned loop_next = loop_time;
    unsigned last_update = 0, update_stamp, update_time;
    unsigned last_frame = 0, frame_stamp, frame_time;

    // TODO : Better way to handle FPS while not breaking anything. There are some issues
    // if the update loop takes too much time.
    unsigned lag = 0;
    while (!stack.empty() && !Status::mustQuit())
    {
        Status::update();
        Input::key_poll();
        update_stamp = Timing::gettime();
        update_time = update_stamp - last_update;
        last_update = update_stamp;
        lag += update_time;

        while (lag >= loop_time)
        {
            stack.back()->update();
            lag -= loop_time;
        }

        // if (Timing::gettime() < loop_next)
        {
            frame_stamp = Timing::gettime();
            frame_time = frame_stamp - last_frame;
            Graphics::frame_begin();
            // Update the current state
            stack.back()->render();
            last_frame = frame_stamp;

            // Text::print_format(0, 0, "WRPG build %s", git_version);
            if (frame_time != 0 && update_time != 0)
            {
                Text::print_format(0, 240 - 8, "%ufps, %uups", TIMER_FREQ / frame_time,
                                   TIMER_FREQ / update_time);
            }

#ifdef IMGUI
            // Updating time graph
            float update_time = (frame_stamp - update_stamp) / 1000.;
            float render_time = (Timing::gettime() - frame_stamp) / 1000.;
            for (int i = 0; i < 200; ++i)
            {
                update_times[i] = update_times[i + 1];
                render_times[i] = render_times[i + 1];
            }
            update_times[199] = update_time;
            render_times[199] = render_time;
            // Drawing FPS and render graphs
            ImGui::BeginGroup();
            ImGui::Text("FPS: %.2f", TIMER_FREQ / (float) frame_time);
            ImGui::PlotLines("", update_times, 200, 0, "Update");
            ImGui::SameLine();
            ImGui::Text("%.2fms", update_time);
            ImGui::PlotLines("", render_times, 200, 0, "Render");
            ImGui::SameLine();
            ImGui::Text("%.2fms", render_time);
            ImGui::EndGroup();

            ImGui::Separator();

            // Drawing Window Toggles
            ImGui::Text("Toggles");
            ImGui::Indent();
            ImGui::BeginGroup();
            ImGui::Checkbox("Logger", &show_logger);
            ImGui::Checkbox("State", &show_state_debug);
            ImGui::EndGroup();
            ImGui::Unindent();

            ImGui::Separator();

            // Drawing buttons
            draw_buttons();

            if (show_logger)
                Logger::debug_render();
            if (show_state_debug)
                stack.back()->debug();
#endif

            Graphics::frame_end();
        }

#ifdef ACTIVE_WAIT
        while (Timing::gettime() < loop_next)
            ;
#endif
        loop_next += loop_time;
    }
}


text:
module Azure::IotHub::Mgmt::V2018_04_01
  module Models
    #
    # SKU properties.
    #
    class IotHubSkuDescription

      include MsRestAzure

      # @return [String] The type of the resource.
      attr_accessor :resource_type

      # @return [IotHubSkuInfo] The type of the resource.
      attr_accessor :sku

      # @return [IotHubCapacity] IotHub capacity
      attr_accessor :capacity

      #
      # Mapper for IotHubSkuDescription class as Ruby Hash.
      # This will be used for serialization/deserialization.
      #
      def self.mapper()
        {
          client_side_validation: true,
          required: false,
          serialized_name: 'IotHubSkuDescription',
          type: {
            name: 'Composite',
            class_name: 'IotHubSkuDescription',
            model_properties: {
              resource_type: {
                client_side_validation: true,
                required: false,
                read_only: true,
                serialized_name: 'resourceType',
                type: {
                  name: 'String'
                }
              },
              sku: {
                client_side_validation: true,
                required: true,
                serialized_name: 'sku',
                type: {
                  name: 'Composite',
                  class_name: 'IotHubSkuInfo'
                }
              },
              capacity: {
                client_side_validation: true,
                required: true,
                serialized_name: 'capacity',
                type: {
                  name: 'Composite',
                  class_name: 'IotHubCapacity'
                }
              }
            }
          }
        }
      end
    end
  end
end


text:
/*

The original idea and inspiration for this module comes from Armin Buescher.

*/

#include <yara/modules.h>
#include <magic.h>

#define MODULE_NAME magic

magic_t magic_cookie[MAX_THREADS];

const char* cached_types[MAX_THREADS];
const char* cached_mime_types[MAX_THREADS];

define_function(magic_mime_type)
{
  YR_MEMORY_BLOCK* block;
  YR_SCAN_CONTEXT* context = scan_context();

  int tidx = yr_get_tidx();

  if (context->flags & SCAN_FLAGS_PROCESS_MEMORY)
    return_string(UNDEFINED);

  if (cached_mime_types[tidx] == NULL)
  {
    block = first_memory_block(context);

    magic_setflags(magic_cookie[tidx], MAGIC_MIME_TYPE);

    cached_mime_types[tidx] = magic_buffer(
        magic_cookie[tidx],
        block->data,
        block->size);
  }

  return_string((char*) cached_mime_types[tidx]);
}

define_function(magic_type)
{
  YR_MEMORY_BLOCK* block;
  YR_SCAN_CONTEXT* context = scan_context();

  int tidx = yr_get_tidx();

  if (context->flags & SCAN_FLAGS_PROCESS_MEMORY)
    return_string(UNDEFINED);

  if (cached_types[tidx] == NULL)
  {
    block = first_memory_block(context);

    magic_setflags(magic_cookie[tidx], 0);

    cached_types[tidx] = magic_buffer(
        magic_cookie[tidx],
        block->data,
        block->size);
  }

  return_string((char*) cached_types[tidx]);
}

begin_declarations;

  declare_function("mime_type", "", "s", magic_mime_type);
  declare_function("type", "", "s", magic_type);

end_declarations;

int module_initialize(
    YR_MODULE* module)
{
  for (int i = 0; i < MAX_THREADS; i++)
    magic_cookie[i] = NULL;

  return ERROR_SUCCESS;
}

int module_finalize(
    YR_MODULE* module)
{
  for (int i = 0; i < MAX_THREADS; i++)
    if (magic_cookie[i] != NULL)
      magic_close(magic_cookie[i]);

  return ERROR_SUCCESS;
}

int module_load(
    YR_SCAN_CONTEXT* context,
    YR_OBJECT* module_object,
    void* module_data,
    size_t module_data_size)
{
  int tidx = yr_get_tidx();

  cached_types[tidx] = NULL;
  cached_mime_types[tidx] = NULL;

  if (magic_cookie[tidx] == NULL)
  {
    magic_cookie[tidx] = magic_open(0);

    if (magic_cookie[tidx] != NULL)
    {
      if (magic_load(magic_cookie[tidx], NULL) != 0)
      {
        magic_close(magic_cookie[tidx]);
        return ERROR_INTERNAL_FATAL_ERROR;
      }
    }
    else
    {
      return ERROR_INSUFICIENT_MEMORY;
    }
  }

  return ERROR_SUCCESS;
}

int module_unload(
    YR_OBJECT* module)
{
  return ERROR_SUCCESS;
}


text:
using System.Text;

namespace _6_Int_Remove_Dup
{
    public class DuplicateRemover
    {
        public static string Remove(string input)
        {
            if (string.IsNullOrEmpty(input))
            {
                return string.Empty;
            }

            if (input.Length < 3)
            {
                return input;
            }

            //string output2 = input;

            //StringBuilder output = new StringBuilder();

            //int chunkSize = 3;
            //bool done = false;
            //string first = input.Substring(0, chunkSize);
            //int start = chunkSize;

            //while (!done)
            //{
            //    if (start + chunkSize > input.Length)
            //    {
            //        done = true;
            //        break;
            //    }

            //    string comparer = input.Substring(start, chunkSize);
            //    if (DoWordsMatch(first, comparer))
            //    {
            //        output2 = output2.Replace(first, "");
            //    }

            //    start++;
            //}

            //return output2;

            StringBuilder output = new StringBuilder();
            // Split the string in half and compare one half to the other.
            string first = input.Substring(0, input.Length / 2);
            string second = input.Substring(input.Length / 2);

            if (DoWordsMatch(first, second))
            {
                output.Append(first);
            }
            else
            {
                output.Append(first);
                output.Append(second);
            }

            return output.ToString();
        }

        private static bool DoWordsMatch(string first, string second)
        {
            foreach (char c in first)
            {
                if (!second.Contains(c.ToString()))
                    return false;
            }

            foreach (char c in second)
            {
                if (!first.Contains(c.ToString()))
                    return false;
            }

            return true;
        }
    }
}


text:
<?php

namespace Softfly\GeneratorBundle\GeneratorRestFromDoctrine\Model;

class AssociationMappingModel {

    private $singular_name;
    private $full_name;
    private $get_method;
    private $map_type;
    private $depth;
    private $columns = array();
    private $mapping = array();

    function getSingularName() {
        return $this->singular_name;
    }

    function getFullName() {
        return $this->full_name;
    }

    function getGetMethod() {
        return $this->get_method;
    }

    function getMapType() {
        return $this->map_type;
    }

    function getColumns() {
        return $this->columns;
    }

    function getMapping() {
        return $this->mapping;
    }

    function setSingularName($singular_name) {
        $this->singular_name = $singular_name;
    }

    function setFullName($full_name) {
        $this->full_name = $full_name;
    }

    function setGetMethod($get_method) {
        $this->get_method = $get_method;
    }

    function setMapType($map_type) {
        $this->map_type = $map_type;
    }

    function setColumns($columns) {
        $this->columns = $columns;
    }

    function setMapping($mapping) {
        $this->mapping = $mapping;
    }

    function getDepth() {
        return $this->depth;
    }

    function setDepth($depth) {
        $this->depth = $depth;
    }

    function toArray() {
        $a = array(
            'singular_name' => $this->singular_name,
            'full_name' => $this->full_name,
            'get_method' => $this->get_method,
            'map_type' => $this->map_type,
            'depth' => $this->depth,
        );
        $a['columns']=array();
        foreach ($this->columns as $column) {
            $a['columns'][] = $column->toArray();
        }
        $a['mapping']=array();
        foreach ($this->mapping as $mapping) {
            $a['mapping'][] = $mapping->toArray();
        }
        return $a;
    }

}


text: Gazebo package for my ROS driven robot


text:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>selenium.webdriver.common.action_chains — Selenium 2.0 documentation</title>

    <link rel="stylesheet" href="../_static/default.css" type="text/css" />
    <link rel="stylesheet" href="../_static/pygments.css" type="text/css" />

    <link rel="top" title="Selenium 2.0 documentation" href="../index.html" />

Navigation

          index

          modules |

Selenium 2.0 documentation »

selenium.webdriver.common.action_chains¶

The ActionChains implementation,

class <tt class="descclassname">selenium.webdriver.common.action_chains.</tt><tt class="descname">ActionChains</tt><big>(</big>driver<big>)</big>[source]¶

ActionChains are a way to automate low level interactions such as
mouse movements, mouse button actions, key press, and context menu interactions.
This is useful for doing more complex actions like hover over and drag and drop.

Generate user actions.

When you call methods for actions on the ActionChains object,
the actions are stored in a queue in the ActionChains object.
When you call perform(), the events are fired in the order they
are queued up.

ActionChains can be used in a chain pattern:

menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

ActionChains(driver).move_to_element(menu).click(hidden_submenu).perform()

Or actions can be queued up one by one, then performed.:

menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")

actions = ActionChains(driver)
actions.move_to_element(menu)
actions.click(hidden_submenu)
actions.perform()

Either way, the actions are performed in the order they are called, one after
another.

Creates a new ActionChains.

<col class="field-name" />
<col class="field-body" />

Args :

driver: The WebDriver instance which performs user actions.

<tt class="descname">click</tt><big>(</big>on_element=None<big>)</big>[source]¶

Clicks an element.

<col class="field-name" />
<col class="field-body" />

Args :

on_element: The element to click.
If None, clicks on current mouse position.

<tt class="descname">click_and_hold</tt><big>(</big>on_element=None<big>)</big>[source]¶

Holds down the left mouse button on an element.

<col class="field-name" />
<col class="field-body" />

Args :

on_element: The element to mouse down.
If None, clicks on current mouse position.

<tt class="descname">context_click</tt><big>(</big>on_element=None<big>)</big>[source]¶

Performs a context-click (right click) on an element.

<col class="field-name" />
<col class="field-body" />

Args :

on_element: The element to context-click.
If None, clicks on current mouse position.

<tt class="descname">double_click</tt><big>(</big>on_element=None<big>)</big>[source]¶

Double-clicks an element.

<col class="field-name" />
<col class="field-body" />

Args :

on_element: The element to double-click.
If None, clicks on current mouse position.

<tt class="descname">drag_and_drop</tt><big>(</big>source, target<big>)</big>[source]¶

Holds down the left mouse button on the source element,

then moves to the target element and releases the mouse button.

<col class="field-name" />
<col class="field-body" />

Args :

source: The element to mouse down.

target: The element to mouse up.

<tt class="descname">drag_and_drop_by_offset</tt><big>(</big>source, xoffset, yoffset<big>)</big>[source]¶

Holds down the left mouse button on the source element,

then moves to the target offset and releases the mouse button.

<col class="field-name" />
<col class="field-body" />

Args :

source: The element to mouse down.

xoffset: X offset to move to.

yoffset: Y offset to move to.

<tt class="descname">key_down</tt><big>(</big>value, element=None<big>)</big>[source]¶

Sends a key press only, without releasing it.

Should only be used with modifier keys (Control, Alt and Shift).

<col class="field-name" />
<col class="field-body" />

Args :

value: The modifier key to send. Values are defined in Keys class.

element: The element to send keys.
If None, sends a key to current focused element.

Example, pressing ctrl+c:

ActionsChains(driver).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()

<tt class="descname">key_up</tt><big>(</big>value, element=None<big>)</big>[source]¶

Releases a modifier key.

<col class="field-name" />
<col class="field-body" />

Args :

value: The modifier key to send. Values are defined in Keys class.

element: The element to send keys.
If None, sends a key to current focused element.

Example, pressing ctrl+c:

ActionsChains(driver).key_down(Keys.CONTROL).send_keys('c').key_up(Keys.CONTROL).perform()

<tt class="descname">move_by_offset</tt><big>(</big>xoffset, yoffset<big>)</big>[source]¶

Moving the mouse to an offset from current mouse position.

<col class="field-name" />
<col class="field-body" />

Args :

xoffset: X offset to move to, as a positive or negative integer.

yoffset: Y offset to move to, as a positive or negative integer.

<tt class="descname">move_to_element</tt><big>(</big>to_element<big>)</big>[source]¶

Moving the mouse to the middle of an element.

<col class="field-name" />
<col class="field-body" />

Args :

to_element: The WebElement to move to.

<tt class="descname">move_to_element_with_offset</tt><big>(</big>to_element, xoffset, yoffset<big>)</big>[source]¶

Move the mouse by an offset of the specified element.

Offsets are relative to the top-left corner of the element.

<col class="field-name" />
<col class="field-body" />

Args :

to_element: The WebElement to move to.

xoffset: X offset to move to.

yoffset: Y offset to move to.

<tt class="descname">perform</tt><big>(</big><big>)</big>[source]¶

Performs all stored actions.

<tt class="descname">release</tt><big>(</big>on_element=None<big>)</big>[source]¶

Releasing a held mouse button on an element.

<col class="field-name" />
<col class="field-body" />

Args :

on_element: The element to mouse up.
If None, releases on current mouse position.

<tt class="descname">send_keys</tt><big>(</big>*keys_to_send<big>)</big>[source]¶

Sends keys to current focused element.

<col class="field-name" />
<col class="field-body" />

Args :

keys_to_send: The keys to send.  Modifier keys constants can be found in the

‘Keys’ class.

<tt class="descname">send_keys_to_element</tt><big>(</big>element, *keys_to_send<big>)</big>[source]¶

Sends keys to an element.

<col class="field-name" />
<col class="field-body" />

Args :

element: The element to send keys.

keys_to_send: The keys to send.  Modifier keys constants can be found in the

‘Keys’ class.

This Page

Show Source

Quick search

    <form class="search" action="../search.html" method="get">
      <input type="text" name="q" />
      <input type="submit" value="Go" />
      <input type="hidden" name="check_keywords" value="yes" />
      <input type="hidden" name="area" value="default" />
    </form>

    Enter search terms or a module, class or function name.

Navigation

          index

          modules |

Selenium 2.0 documentation »

        © Copyright 2011, plightbo, simon.m.stewart, hbchai, jrhuggins, et al..


text:
import React from 'react';

export default class Flag extends React.Component{
    render()
    {
        return(
            <i className = {this.props.post.flagged ? "fa fa-flag red" : "fa fa-flag flag-this"}
               title     = {this.props.post.flagged ? "This post has been flagged for removal." : "Flag this post as inappropriate"}
               onClick   = {this.props.post.flagged ? "" : this.props.flag }/>
        );
    }
}


text:
package com.cardpay.pccredit.customer.dao;

import java.util.List;

import org.apache.ibatis.annotations.Param;

import com.cardpay.pccredit.customer.model.AverageDailyOverdraft;
import com.wicresoft.util.annotation.Mapper;

/**
 * AverageDailyOverdraft类的描述
 *
 * @author 王海东
 * @created on 2014-11-26
 *
 * @version $Id:$
 */
@Mapper
public interface AverageDailyOverdraftDao {

	public List<AverageDailyOverdraft> findHalfYearAverageDailyOverdraft(@Param("productId")String productId); //获取六个月内全额还款的用户

	public List<AverageDailyOverdraft> findHalfYearAverageDailyOverdraftZDHK(@Param("productId")String productId); //连续半年内每月只还最低还款额 (灵活金)用户

	//查询所有全额还款的用户
	public List<AverageDailyOverdraft> findAllDueStatusTrue();
}


text:
NS_ASSUME_NONNULL_BEGIN

#define MenuContentMargin       15          //默认文本图片边距
#define MenuImageWidth          30          //默认图片最小尺寸
#define MenuBorderMinMargin     10          //默认下拉框边界围栏
#define MenuTitleFontSize       15          //默认文本字体大小

@interface ZWPullMenuConfig : NSObject
//文本图片边距
@property (nonatomic, assign) CGFloat zw_menuContentMargin;
//图片最小尺寸
@property (nonatomic, assign) CGFloat zw_menuImageWidth;
//下拉框边界围栏
@property (nonatomic, assign) CGFloat zw_menuBorderMinMargin;
//文本字体大小
@property (nonatomic, assign) CGFloat zw_menuTitleFontSize;

@end

NS_ASSUME_NONNULL_END


text:
module Liquid
  class Raw < Block
    FullTokenPossiblyInvalid = /\A(.*)#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}\z/om

    def parse(tokens)
      @nodelist ||= []
      @nodelist.clear
      while token = tokens.shift
        if token =~ FullTokenPossiblyInvalid
          @nodelist << $1 if $1 != "".freeze
          return if block_delimiter == $2
        end
        @nodelist << token if not token.empty?
      end
    end
  end

  Template.register_tag('raw'.freeze, Raw)
end


text:
package line

import (
	"fmt"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/satori/go.uuid"

	"k8s.io/test-infra/prow/github"
	"k8s.io/test-infra/prow/kube"
)

var (
	// Set by LINE_IMAGE environment variable.
	lineImage string
	// Set by DRY_RUN environment variable, defaults to true.
	dryRun bool
)

func init() {
	lineImage = os.Getenv("LINE_IMAGE")
	dry := os.Getenv("DRY_RUN")
	if dry == "" {
		dryRun = true
	} else if db, err := strconv.ParseBool(dry); err != nil {
		panic(fmt.Sprintf("DRY_RUN not parseable: %v", err))
	} else {
		dryRun = db
	}
}

// Cut off line jobs after 10 hours.
const jobDeadline = 10 * time.Hour

type StartClient interface {
	CreateJob(kube.Job) (kube.Job, error)
}

type Pull struct {
	Number int
	Author string
	SHA    string
}

type BuildRequest struct {
	periodic bool

	Org  string
	Repo string

	BaseRef string
	BaseSHA string

	Pulls []Pull
}

func (b BuildRequest) GetRefs() string {
	rs := []string{fmt.Sprintf("%s:%s", b.BaseRef, b.BaseSHA)}
	for _, pull := range b.Pulls {
		rs = append(rs, fmt.Sprintf("%d:%s", pull.Number, pull.SHA))
	}
	return strings.Join(rs, ",")
}

func StartPRJob(k *kube.Client, jobName, context string, pr github.PullRequest, baseSHA string) error {
	br := BuildRequest{
		Org:  pr.Base.Repo.Owner.Login,
		Repo: pr.Base.Repo.Name,

		BaseRef: pr.Base.Ref,
		BaseSHA: baseSHA,

		Pulls: []Pull{
			{
				Number: pr.Number,
				Author: pr.User.Login,
				SHA:    pr.Head.SHA,
			},
		},
	}
	errDel := deleteJob(k, jobName, pr)
	_, errStart := startJob(k, jobName, context, br)
	if errDel != nil || errStart != nil {
		return fmt.Errorf("error deleting old job: %v, error starting new job: %v", errDel, errStart)
	}
	return nil
}

func StartJob(k StartClient, jobName, context string, br BuildRequest) (string, error) {
	return startJob(k, jobName, context, br)
}

func StartPushJob(k *kube.Client, jobName string, pe github.PushEvent) error {
	br := BuildRequest{
		Org:     pe.Repo.Owner.Name,
		Repo:    pe.Repo.Name,
		BaseRef: pe.Branch(),
		BaseSHA: pe.After,
	}
	_, err := startJob(k, jobName, "", br)
	return err
}

func StartPeriodicJob(k StartClient, jobName string) (string, error) {
	return startJob(k, jobName, "", BuildRequest{periodic: true})
}

func startJob(k StartClient, jobName, context string, br BuildRequest) (string, error) {
	refs := br.GetRefs()

	labels := map[string]string{
		"owner":            br.Org,
		"repo":             br.Repo,
		"jenkins-job-name": jobName,
	}
	annotations := map[string]string{
		"state":       "triggered",
		"description": "Build triggered.",
		"url":         "",
		"refs":        refs,
		"base-ref":    br.BaseRef,
		"base-sha":    br.BaseSHA,
	}
	args := []string{
		"--job-name=" + jobName,
		"--repo-owner=" + br.Org,
		"--repo-name=" + br.Repo,
		"--base-ref=" + br.BaseRef,
		"--base-sha=" + br.BaseSHA,
		"--refs=" + refs,
		"--dry-run=" + strconv.FormatBool(dryRun),
		"--jenkins-url=$(JENKINS_URL)",
	}
	if br.periodic {
		labels["type"] = "periodic"
		args = append(args, "--report=false")
	} else if len(br.Pulls) == 0 {
		labels["type"] = "push"
		args = append(args, "--report=false")
	} else if len(br.Pulls) == 1 {
		labels["type"] = "pr"
		labels["pr"] = strconv.Itoa(br.Pulls[0].Number)
		annotations["context"] = context
		annotations["author"] = br.Pulls[0].Author
		annotations["pull-sha"] = br.Pulls[0].SHA
		args = append(args, "--pr="+strconv.Itoa(br.Pulls[0].Number))
		args = append(args, "--pull-sha="+br.Pulls[0].SHA)
		args = append(args, "--author="+br.Pulls[0].Author)
		args = append(args, "--report=true")
	} else if len(br.Pulls) > 1 {
		labels["type"] = "batch"
		annotations["context"] = context
		args = append(args, "--report=false")
	}

	name := uuid.NewV1().String()
	job := kube.Job{
		Metadata: kube.ObjectMeta{
			Name:        name,
			Namespace:   "default",
			Labels:      labels,
			Annotations: annotations,
		},
		Spec: kube.JobSpec{
			ActiveDeadlineSeconds: int(jobDeadline / time.Second),
			Template: kube.PodTemplateSpec{
				Spec: kube.PodSpec{
					NodeSelector: map[string]string{
						"role": "build",
					},
					RestartPolicy: "Never",
					Containers: []kube.Container{
						{
							Name:  "line",
							Image: lineImage,
							Args:  args,
							VolumeMounts: []kube.VolumeMount{
								{
									Name:      "jenkins",
									ReadOnly:  true,
									MountPath: "/etc/jenkins",
								},
								{
									Name:      "labels",
									ReadOnly:  true,
									MountPath: "/etc/labels",
								},
								{
									Name:      "config",
									ReadOnly:  true,
									MountPath: "/etc/config",
								},
							},
							Env: []kube.EnvVar{
								{
									Name:  "LINE_IMAGE",
									Value: lineImage,
								},
								{
									Name:  "DRY_RUN",
									Value: strconv.FormatBool(dryRun),
								},
								{
									Name: "JENKINS_URL",
									ValueFrom: &kube.EnvVarSource{
										ConfigMap: kube.ConfigMapKeySelector{
											Name: "jenkins-address",
											Key:  "jenkins-address",
										},
									},
								},
							},
						},
					},
					Volumes: []kube.Volume{
						{
							Name: "labels",
							DownwardAPI: &kube.DownwardAPISource{
								Items: []kube.DownwardAPIFile{
									{
										Path: "labels",
										Field: kube.ObjectFieldSelector{
											FieldPath: "metadata.labels",
										},
									},
								},
							},
						},
						{
							Name: "jenkins",
							Secret: &kube.SecretSource{
								Name: "jenkins-token",
							},
						},
						{
							Name: "config",
							ConfigMap: &kube.ConfigMapSource{
								Name: "config",
							},
						},
					},
				},
			},
		},
	}
	actual, err := k.CreateJob(job)
	return actual.Metadata.Name, err
}

type deleteClient interface {
	ListJobs(labels map[string]string) ([]kube.Job, error)
	GetJob(name string) (kube.Job, error)
	PatchJob(name string, job kube.Job) (kube.Job, error)
	PatchJobStatus(name string, job kube.Job) (kube.Job, error)
}

func deleteJob(k deleteClient, jobName string, pr github.PullRequest) error {
	jobs, err := k.ListJobs(map[string]string{
		"owner":            pr.Base.Repo.Owner.Login,
		"repo":             pr.Base.Repo.Name,
		"pr":               strconv.Itoa(pr.Number),
		"jenkins-job-name": jobName,
	})
	if err != nil {
		return err
	}
	// Retry on conflict. This can happen if the job finishes and updates its
	// state right when we want to delete it.
	var job kube.Job
	for _, j := range jobs {
		job = j
		for i := 0; i < 3; i++ {
			if err := deleteKubeJob(k, job); err == nil {
				break
			} else {
				if _, ok := err.(kube.ConflictError); !ok {
					return err
				}
			}
			job, err = k.GetJob(j.Metadata.Name)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func deleteKubeJob(k deleteClient, job kube.Job) error {
	if job.Spec.Parallelism != nil && *job.Spec.Parallelism == 0 {
		// Already aborted this one.
		return nil
	} else if job.Status.Succeeded > 0 {
		// Already finished.
		return nil
	}
	// Delete the old job's pods by setting its parallelism to 0.
	parallelism := 0
	newStatus := job.Status
	newStatus.CompletionTime = time.Now()
	newAnnotations := job.Metadata.Annotations
	if newAnnotations == nil {
		newAnnotations = make(map[string]string)
	}
	newAnnotations["state"] = "aborted"
	newAnnotations["description"] = "Build aborted."
	newJob := kube.Job{
		Metadata: kube.ObjectMeta{
			Annotations: newAnnotations,
		},
		Spec: kube.JobSpec{
			Parallelism: &parallelism,
		},
		Status: newStatus,
	}
	// For some reason kubernetes makes you do this in two steps.
	if _, err := k.PatchJob(job.Metadata.Name, newJob); err != nil {
		return err
	}
	if _, err := k.PatchJobStatus(job.Metadata.Name, newJob); err != nil {
		return err
	}
	return nil
}

func updateAnnotations(k *kube.Client, jobName string, updates map[string]string) error {
	j, err := k.GetJob(jobName)
	if err != nil {
		return err
	}
	newAnnotations := j.Metadata.Annotations
	if newAnnotations == nil {
		newAnnotations = make(map[string]string)
	}
	for k, v := range updates {
		newAnnotations[k] = v
	}
	_, err = k.PatchJob(jobName, kube.Job{
		Metadata: kube.ObjectMeta{
			Annotations: newAnnotations,
		},
	})
	return err
}

func SetJobAgent(k *kube.Client, jobName, agent string) error {
	return updateAnnotations(k, jobName, map[string]string{
		"agent": agent,
	})
}

func SetJobStatus(k *kube.Client, podName, jobName, state, desc, url string) error {
	return updateAnnotations(k, jobName, map[string]string{
		"pod-name":    podName,
		"state":       state,
		"description": desc,
		"url":         url,
	})
}


text:
Use this library to develop a bot for the Viber platform.
The library is available on [GitHub](https://github.com/Viber/viber-bot-node) as well as a package on [npm](https://www.npmjs.com/package/viber-bot).

## License
This library is released under the terms of the Apache 2.0 license. See [License](https://github.com/Viber/viber-bot-node/blob/master/LICENSE.md) for more information.

## Library Prerequisites
* Node >= 5.0.0
* Get your Viber Public Account authentication token. Your token is generated and provided to you during the Public Account creation process. As a Public Account admin, you can always find the account token in the "edit info" page.
* SSL Certification - You'll need a trusted (ca.pem) certificate, not self-signed. You can find one at [Let's Encrypt](https://letsencrypt.org/) or buy one.

## Installation
This library is released on [npm](https://www.npmjs.com/package/viber-bot).

### npm
Install with [`npm install viber-bot --save`](https://www.npmjs.com/package/viber-bot)

### Express
If you are already using express or equivalent, you can do the following:

```javascript
app.use("/viber/webhook", bot.middleware());
```
Please revisit [app.use()](http://expressjs.com/en/api.html#app.use) documentation.
For more information see [ViberBot.middleware()](#middleware).

## Let's get started!
Creating a basic Viber bot is simple:

1. Import `viber-bot` library to your project
2. Create a Public Account and use the API key from [https://developers.viber.com]()
3. Configure your bot as described in the documentation below
4. Add the bot as middleware to your server with `bot.middleware()`
5. Start your web server
6. Call setWebhook(url) with your web server url

### Creating an echo Bot
Firstly, let's *import and configure* our bot:

```javascript
'use strict';

const ViberBot  = require('viber-bot').Bot;
const BotEvents = require('viber-bot').Events;

const bot    = new ViberBot({
	authToken: YOUR_AUTH_TOKEN_HERE,
	name: "EchoBot",
	avatar: "http://viber.com/avatar.jpg" // It is recommended to be 720x720, and no more than 100kb.
});

// Perfect! Now here's the key part:
bot.on(BotEvents.MESSAGE_RECEIVED, (message, response) => {
	// Echo's back the message to the client. Your bot logic should sit here.
	response.send(message);
});

// Wasn't that easy? Let's create HTTPS server and set the webhook:
const https = require('https');
const port  = process.env.PORT || 8080;

// Viber will push messages sent to this URL. Web server should be internet-facing.
const webhookUrl = process.env.WEBHOOK_URL;

const httpsOptions = { key: ... , cert: ... , ca: ... }; // Trusted SSL certification (not self-signed).
https.createServer(httpsOptions, bot.middleware()).listen(port, () => bot.setWebhook(webhookUrl));
```

### Using Winston logger
We provide an option to use [Winston](https://www.npmjs.com/package/winston) logger with our library.
The only requirement is that you use Winston >= 2.0.0.

```javascript
'use strict';

const ViberBot  = require('viber-bot').Bot;
const winston   = require('winston');
const toYAML    = require('winston-console-formatter'); // makes the output more friendly

function createLogger() {
	const logger = new winston.Logger({ level: "debug" }); // We recommend DEBUG for development
	logger.add(winston.transports.Console, toYAML.config());
	return logger;
}

const logger = createLogger();
const bot    = new ViberBot({
	logger: logger,
	authToken: ...,
	...
});
```

### Do you supply a basic router for text messages?
Well funny you ask. Yes we do. But a word of warning - messages sent to your router callback will also be emitted to the `BotEvents.MESSAGE_RECEIVED` event.

```javascript
const TextMessage = require('viber-bot').Message.Text;

// A simple regular expression to answer messages in the form of 'hi' and 'hello'.
bot.onTextMessage(/^hi|hello$/i, (message, response) =>
    response.send(new TextMessage(`Hi there ${response.userProfile.name}. I am ${bot.name}`)));
```

Have you noticed how we created the `TextMessage` instance? There's a all bunch of message types you should get familiar with.

* [Text Message](#TextMessage)
* [Url Message](#UrlMessage)
* [Contact Message](#ContactMessage)
* [Picture Message](#PictureMessage)
* [Video Message](#VideoMessage)
* [Location Message](#LocationMessage)
* [Sticker Message](#StickerMessage)
* [File Message](#FileMessage)

Creating them is easy! Every message object has its own unique constructor corresponding to its API implementation. Click on each type in the list to find out more. Check out the full API documentation for more advanced uses.

## API
### Viber Bot
`require('viber-bot').Bot`

An event emitter, emitting events [described here](#onEvent).

* ViberBot
    * [new ViberBot()](#newViberBot)
    * [.getBotProfile()](#getBotProfile) ⇒ `promise.JSON`
    * [.getUserDetails(userProfile)](#getUserDetails) ⇒ `promise.JSON`
    * [.getOnlineStatus(viberUserIds)](#getOnlineStatus) ⇒ `promise.JSON`
    * [.setWebhook(url)](#setWebhook) ⇒ `promise.JSON`
    * [.sendMessage(userProfile, messages, [optionalTrackingData])](#sendMessage) ⇒ `promise.ARRAY`
    * [.on(handler)](#onEvent)
    * [.onTextMessage(regex, handler)](#onTextMessage) : `handler` = [`TextMessageHandlerCallback`](#TextMessageHandlerCallback)
    * [.onError(handler)](#onError) : `handler` = [`ErrorHandlerCallback`](#ErrorHandlerCallback)
    * [.onConversationStarted(userProfile, onFinish)](#onConversationStarted) : `onFinish` = [`ConversationStartedOnFinishCallback`](#ConversationStartedOnFinishCallback)
    * [.onSubscribe(handler)](#onSubscribe) : `handler` = [`SubscribeResponseHandlerCallback`](#SubscribeResponseHandlerCallback)
    * [.onUnsubscribe(handler)](#onUnsubscribe) : `handler` = [`UnsubscribeResponseHandlerCallback`](#UnsubscribeResponseHandlerCallback)
    * [.middleware()](#middleware)

### New ViberBot()

| Param | Type | Description |
| --- | --- | --- |
| options.logger | `object` | Winston logger |
| options.authToken | `string` | Viber Auth Token  |
| options.name | `string` | Your BOT Name |
| options.avatar | `string` | Avatar URL. **No more than 100kb.** |
| options.registerToEvents | `array` | example: ["message", "delivered"] |

### bot.on(handler)
`require('viber-bot').Events`

| Param | Type |
| --- | --- |
| handler | `EventHandlerCallback` |
| message | [`Message Object`](#MessageObject) |
| response | [`Response Object`](#ResponseObject) |
| err | `Error Object` |

Subscribe to events:

* MESSAGE_RECEIVED (Callback:  `function (message, response) {}`)
* MESSAGE_SENT (Callback:  `function (message, userProfile) {}`)
* SUBSCRIBED (Callback:  `function (response) {}`)
* UNSUBSCRIBED (Callback:  `function (response) {}`)
* CONVERSATION_STARTED (Callback:  `function (userProfile, onFinish) {}`)
* ERROR (Callback:  `function (err) {}`)

**Example**

```js
bot.on(BotEvents.MESSAGE_RECEIVED, (message, response) => ... );
bot.on(BotEvents.MESSAGE_SENT, (message, userProfile) => ... );
bot.on(BotEvents.CONVERSATION_STARTED, (userProfile, onFinish) => ... );
bot.on(BotEvents.ERROR, err => ... );
bot.on(BotEvents.UNSUBSCRIBED, response => ... );
bot.on(BotEvents.SUBSCRIBED, response =>
    response.send(`Thanks for subscribing, ${response.userProfile.name}`));
```

### bot.getBotProfile()
Returns a `promise.JSON` [with the following JSON](https://developers.viber.com/api/rest-bot-api/index.html#get-account-info).

```js
bot.getBotProfile().then(response => console.log(`Public Account Named: ${response.name}`));
```

### bot.getUserDetails(userProfile)
| Param | Type | Description |
| --- | --- | --- |
| userProfile | [`UserProfile`](#UserProfile) | `UserProfile` object |

The `getUserDetails` function will fetch the details of a specific Viber user based on his unique user ID. The user ID can be obtained from the callbacks sent to the PA regrading user's actions. This request can be sent twice during a 12 hours period for each user ID.

Returns a `promise.JSON`.

```js
bot.onSubscribe(response => bot.getUserDetails(response.userProfile)
        .then(userDetails => console.log(userDetails)));
```

### bot.getOnlineStatus(viberUserIds)
| Param | Type | Description |
| --- | --- | --- |
| viberUserIds | `array of strings` | Collection of Viber user ids |

Returns a `promise.JSON`.

```js
bot.getOnlineStatus(["a1, "a2"]).then(onlineStatus => console.log(onlineStatus));
```

### bot.setWebhook(url)
| Param | Type | Description |
| --- | --- | --- |
| url | `string` | Trusted SSL Certificate |

Returns a `promise.JSON`.

```js
bot.setWebhook("https://my.bot/incoming").then(() => yourBot.doSomething()).catch(err => console.log(err));
```

### bot.sendMessage(userProfile, messages, [optionalTrackingData])
| Param | Type | Description |
| --- | --- | --- |
| userProfile | [`UserProfile`](#UserProfile) | `UserProfile` object |
| Messages | `object or array` | Can be `Message` object or array of `Message` objects |
| [optionalTrackingData] | `JSON` | Optional. JSON Object. Returned on every message sent by the client |

*Note*: When passing array of messages to `sendMessage`, messages will be sent by explicit order (the order which they were given to the `sendMessage` method). The library will also cancel all custom keyboards except the last one, sending only the last message keyboard.

Returns a `promise.ARRAY` array of message tokens.

```js
// single message
const TextMessage = require('viber-bot').Message.Text;
bot.sendMessage(userProfile, new TextMessage("Thanks for shopping with us"));

// multiple messages
const UrlMessage  = require('viber-bot').Message.Url;
bot.sendMessage(userProfile, [
    new TextMessage("Here's the product you've requested:"),
    new UrlMessage("http://my.ecommerce.site/product1"),
    new TextMessage("Shipping time: 1-3 business days")
]);
```

### bot.middleware()
Returns a middleware implementation to use with `http/https`.

```js
const https = require('https');
https.createServer({ key: ... , cert: ... , ca: ... }, bot.middleware()).listen(8080);
```

### bot.onTextMessage(regex, handler)
| Param | Type |
| --- | --- |
| regex | `regular expression` |
| handler | [`TextMessageHandlerCallback`](#TextMessageHandlerCallback) |

##### TextMessageHandlerCallback: `function (message, response) {}`

```js
bot.onTextMessage(/^hi|hello$/i, (message, response) =>
    response.send(new TextMessage(`Hi there ${response.userProfile.name}. I am ${bot.name}`)));
```

### bot.onError(handler)
| Param | Type |
| --- | --- |
| handler | [`ErrorHandlerCallback`](#ErrorHandlerCallback) |

##### ErrorHandlerCallback: `function (err) {}`

```js
bot.onError(err => logger.error(err));
```

### bot.onConversationStarted(userProfile, onFinish)
| Param | Type |
| --- | --- |
| userProfile | [`UserProfile`](#UserProfile) |
| onFinish | [`ConversationStartedOnFinishCallback`](#ConversationStartedOnFinishCallback) |

Conversation started event fires when a user opens a conversation with the PA using the "message" button (found on the PA's info screen) or using a [deep link](https://developers.viber.com/tools/deep-links/index.html).

This event is **not** considered a subscribe event and doesn't allow the PA to send messages to the user; however, it will allow sending one "welcome message" to the user.

##### ConversationStartedOnFinishCallback: `function (responseMessage, optionalTrackingData) {}`

The `ConversationStartedOnFinishCallback` accepts `null` and [`MessageObject`](#MessageObject) only. Otherwise, an exception is thrown.

```js
bot.onConversationStarted((userProfile, onFinish) =>
	onFinish(new TextMessage(`Hi, ${userProfile.name}! Nice to meet you.`)));

bot.onConversationStarted((userProfile, onFinish) =>
    onFinish(new TextMessage(`Thanks`), { saidThanks: true }));
```

### bot.onSubscribe(handler)
| Param | Type |
| --- | --- |
| handler | [`SubscribeResponseHandlerCallback`](#SubscribeResponseHandlerCallback) |

##### SubscribeResponseHandlerCallback: `function (response) {}`

```js
bot.onSubscribe(response => console.log(`Subscribed: ${response.userProfile.name}`));
```

### bot.onUnsubscribe(handler)
| Param | Type |
| --- | --- |
| handler | [`UnsubscribeResponseHandlerCallback`](#UnsubscribeResponseHandlerCallback) |

##### UnsubscribeResponseHandlerCallback: `function (userId) {}`

```js
bot.onUnsubscribe(userId => console.log(`Unsubscribed: ${userId}`));
```

### Response object
Members:

| Param | Type | Notes |
| --- | --- | --- |
| userProfile | [`UserProfile`](#UserProfile) | --- |

* Response
    * [.send(messages, [optionalTrackingData])](#sendMessage) ⇒ `promise.JSON`

### UserProfile object
Members:

| Param | Type | Notes |
| --- | --- | --- |
| id | `string` | --- |
| name | `string` | --- |
| avatar | `string` | Optional Avatar URL |
| country | `string` | **currently set in CONVERSATION_STARTED event only** |
| language | `string` | **currently set in CONVERSATION_STARTED event only** |

### Message Object

```javascript
const TextMessage     = require('viber-bot').Message.Text;
const UrlMessage      = require('viber-bot').Message.Url;
const ContactMessage  = require('viber-bot').Message.Contact;
const PictureMessage  = require('viber-bot').Message.Picture;
const VideoMessage    = require('viber-bot').Message.Video;
const LocationMessage = require('viber-bot').Message.Location;
const StickerMessage  = require('viber-bot').Message.Sticker;
```

**Common Members for `Message` interface**:

| Param | Type | Description |
| --- | --- | --- |
| timestamp | `long` | Epoch time |
| token | `long` | Sequential message token |
| trackingData | `JSON` | JSON Tracking Data from Viber Client |

**Common Constructor Arguments `Message` interface**:

| Param | Type | Description |
| --- | --- | --- |
| optionalKeyboard | `JSON` | [Writing Custom Keyboards](https://developers.viber.com/tools/keyboards/index.html) |
| optionalTrackingData | `JSON` | Data to be saved on Viber Client device, and sent back each time message is received |

#### TextMessage object
| Member | Type
| --- | --- |
| text | `string` |

```javascript
const message = new TextMessage(text, [optionalKeyboard], [optionalTrackingData]);
console.log(message.text);
```

#### UrlMessage object
| Member | Type
| --- | --- |
| url | `string` |

```javascript
const message = new UrlMessage(url, [optionalKeyboard], [optionalTrackingData]);
console.log(message.url);
```

#### ContactMessage object
| Member | Type
| --- | --- |
| contactName | `string` |
| contactPhoneNumber | `string` |

```javascript
const message = new ContactMessage(contactName, contactPhoneNumber, [optionalAvatar], [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.contactName}, ${message.contactPhoneNumber}`);
```

#### PictureMessage object
| Member | Type
| --- | --- |
| url | `string` |
| text | `string` |
| thumbnail | `string` |

```javascript
const message = new PictureMessage(url, [optionalText], [optionalThumbnail], [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.url}, ${message.text}, ${message.thumbnail}`);
```

#### VideoMessage object
| Member | Type
| --- | --- |
| url | `string` |
| size | `int` |
| thumbnail | `string` |
| duration | `int` |

```javascript
const message = new VideoMessage(url, size, [optionalText], [optionalThumbnail], [optionalDuration], [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.url}, ${message.size}, ${message.thumbnail}, ${message.duration}`);
```

#### LocationMessage object
| Member | Type
| --- | --- |
| latitude | `float` |
| longitude | `float` |

```javascript
const message = new LocationMessage(latitude, longitude, [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.latitude}, ${message.longitude}`);
```

#### StickerMessage object
| Member | Type
| --- | --- |
| stickerId | `int` |

```javascript
const message = new StickerMessage(stickerId, [optionalKeyboard], [optionalTrackingData]);
console.log(message.stickerId);
```

#### FileMessage object
| Member | Type
| --- | --- |
| url | `string` |
| sizeInBytes | `long` |
| filename | `string` |

```javascript
const message = new FileMessage(url, sizeInBytes, filename, [optionalKeyboard], [optionalTrackingData]);
console.log(`${message.url}, ${message.sizeInBytes}, ${message.filename}`);
```

## Sample project
We've created the [Is It Up sample project](https://github.com/Viber/sample-bot-isitup) to help you get started.

## Community
Join the conversation on **[Gitter] (https://gitter.im/viber/bot-node)**.


text:
<?php

namespace Components\Oaipmh\Site;

require_once dirname(__DIR__) . DS . 'models' . DS . 'service.php';

$controllerName = 'xml';
require_once __DIR__ . DS . 'controllers' . DS . $controllerName . '.php';
$controllerName = __NAMESPACE__ . '\\Controllers\\' . ucfirst($controllerName);

// Instantiate controller
$controller = new $controllerName();
$controller->execute();


text:
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class RiwayatAnak extends Model
{
    //
}


text:
from __future__ import absolute_import, division, unicode_literals

import itertools

import pytest

try:
    import lxml.etree
except ImportError:
    pass

from .support import treeTypes

from html5lib import html5parser, treewalkers
from html5lib.filters.lint import Filter as Lint

import re
attrlist = re.compile(r"^(\s+)\w+=.*(\n\1\w+=.*)+", re.M)

def sortattrs(x):
    lines = x.group(0).split("\n")
    lines.sort()
    return "\n".join(lines)

def test_all_tokens():
    expected = [
        {'data': {}, 'type': 'StartTag', 'namespace': 'http://www.w3.org/1999/xhtml', 'name': 'html'},
        {'data': {}, 'type': 'StartTag', 'namespace': 'http://www.w3.org/1999/xhtml', 'name': 'head'},
        {'type': 'EndTag', 'namespace': 'http://www.w3.org/1999/xhtml', 'name': 'head'},
        {'data': {}, 'type': 'StartTag', 'namespace': 'http://www.w3.org/1999/xhtml', 'name': 'body'},
        {'data': 'a', 'type': 'Characters'},
        {'data': {}, 'type': 'StartTag', 'namespace': 'http://www.w3.org/1999/xhtml', 'name': 'div'},
        {'data': 'b', 'type': 'Characters'},
        {'type': 'EndTag', 'namespace': 'http://www.w3.org/1999/xhtml', 'name': 'div'},
        {'data': 'c', 'type': 'Characters'},
        {'type': 'EndTag', 'namespace': 'http://www.w3.org/1999/xhtml', 'name': 'body'},
        {'type': 'EndTag', 'namespace': 'http://www.w3.org/1999/xhtml', 'name': 'html'}
    ]
    for _, treeCls in sorted(treeTypes.items()):
        if treeCls is None:
            continue
        p = html5parser.HTMLParser(tree=treeCls["builder"])
        document = p.parse("a
b
c")
        document = treeCls.get("adapter", lambda x: x)(document)
        output = Lint(treeCls["walker"](document))
        for expectedToken, outputToken in zip(expected, output):
            assert expectedToken == outputToken

def set_attribute_on_first_child(docfrag, name, value, treeName):
    """naively sets an attribute on the first child of the document
    fragment passed in"""
    setter = {'ElementTree': lambda d: d[0].set,
              'DOM': lambda d: d.firstChild.setAttribute}
    setter['cElementTree'] = setter['ElementTree']
    try:
        setter.get(treeName, setter['DOM'])(docfrag)(name, value)
    except AttributeError:
        setter['ElementTree'](docfrag)(name, value)

def runTreewalkerEditTest(intext, expected, attrs_to_add, tree):
    """tests what happens when we add attributes to the intext"""
    treeName, treeClass = tree
    if treeClass is None:
        pytest.skip("Treebuilder not loaded")
    parser = html5parser.HTMLParser(tree=treeClass["builder"])
    document = parser.parseFragment(intext)
    for nom, val in attrs_to_add:
        set_attribute_on_first_child(document, nom, val, treeName)

    document = treeClass.get("adapter", lambda x: x)(document)
    output = treewalkers.pprint(treeClass["walker"](document))
    output = attrlist.sub(sortattrs, output)
    if output not in expected:
        raise AssertionError("TreewalkerEditTest: %s\nExpected:\n%s\nReceived:\n%s" % (treeName, expected, output))

def test_treewalker_six_mix():
    """Str/Unicode mix. If str attrs added to tree"""

    # On Python 2.x string literals are of type str. Unless, like this
    # file, the programmer imports unicode_literals from __future__.
    # In that case, string literals become objects of type unicode.

    # This test simulates a Py2 user, modifying attributes on a document
    # fragment but not using the u'' syntax nor importing unicode_literals
    sm_tests = [
        ('Example',
         [(str('class'), str('test123'))],
         '\n  class="test123"\n  href="http://example.com"\n  "Example"'),

        ('<link href="http://example.com/cow">',
         [(str('rel'), str('alternate'))],
         '<link>\n  href="http://example.com/cow"\n  rel="alternate"\n  "Example"')
    ]

    for tree in sorted(treeTypes.items()):
        for intext, attrs, expected in sm_tests:
            yield runTreewalkerEditTest, intext, expected, attrs, tree

@pytest.mark.parametrize("tree,char", itertools.product(sorted(treeTypes.items()), ["x", "\u1234"]))
def test_fragment_single_char(tree, char):
    expected = [
        {'data': char, 'type': 'Characters'}
    ]

    treeName, treeClass = tree
    if treeClass is None:
        pytest.skip("Treebuilder not loaded")

    parser = html5parser.HTMLParser(tree=treeClass["builder"])
    document = parser.parseFragment(char)
    document = treeClass.get("adapter", lambda x: x)(document)
    output = Lint(treeClass["walker"](document))

    assert list(output) == expected

@pytest.mark.skipif(treeTypes["lxml"] is None, reason="lxml not importable")
def test_lxml_xml():
    expected = [
        {'data': {}, 'name': 'div', 'namespace': None, 'type': 'StartTag'},
        {'data': {}, 'name': 'div', 'namespace': None, 'type': 'StartTag'},
        {'name': 'div', 'namespace': None, 'type': 'EndTag'},
        {'name': 'div', 'namespace': None, 'type': 'EndTag'}
    ]

    lxmltree = lxml.etree.fromstring('

')
    walker = treewalkers.getTreeWalker('lxml')
    output = Lint(walker(lxmltree))

    assert list(output) == expected


text:
package nom.bdezonia.zorbage.type.tuple;

import nom.bdezonia.zorbage.function.Function1;
import nom.bdezonia.zorbage.function.Function2;
import nom.bdezonia.zorbage.procedure.Procedure1;
import nom.bdezonia.zorbage.procedure.Procedure2;
import nom.bdezonia.zorbage.tuple.Tuple2;
import nom.bdezonia.zorbage.algebra.Algebra;

/**
 *
 * @author Barry DeZonia
 *
 */
public class Tuple2Algebra<AA extends Algebra<AA,A>, A, BB extends Algebra<BB,B>, B>
	implements Algebra<Tuple2Algebra<AA,A,BB,B>, Tuple2<A,B>>
{
	private final AA algA;
	private final BB algB;

	@Override
	public String typeDescription() {
		return "2 element tuple";
	}

	public Tuple2Algebra(AA algA, BB algB) {
		this.algA = algA;
		this.algB = algB;
	}

	@Override
	public Tuple2<A,B> construct() {
		return new Tuple2<A,B>(algA.construct(), algB.construct());
	}

	@Override
	public Tuple2<A,B> construct(Tuple2<A,B> other) {
		Tuple2<A,B> result = construct();
		assign().call(other, result);
		return result;
	}

	@Override
	public Tuple2<A,B> construct(String str) {
		String[] elements = str.split(":");
		A a = (elements.length > 0 ? algA.construct(elements[0]) : algA.construct());
		B b = (elements.length > 1 ? algB.construct(elements[1]) : algB.construct());
		return new Tuple2<A,B>(a,b);
	}

	private final Function2<Boolean, Tuple2<A,B>, Tuple2<A,B>> EQ =
			new Function2<Boolean, Tuple2<A,B>, Tuple2<A,B>>()
	{
		@Override
		public Boolean call(Tuple2<A,B> a, Tuple2<A,B> b) {
			return algA.isEqual().call(a.a(), b.a()) && algB.isEqual().call(a.b(), b.b());
		}
	};

	@Override
	public Function2<Boolean, Tuple2<A,B>, Tuple2<A,B>> isEqual() {
		return EQ;
	}

	private final Function2<Boolean, Tuple2<A,B>, Tuple2<A,B>> NEQ =
			new Function2<Boolean, Tuple2<A,B>, Tuple2<A,B>>()
	{
		@Override
		public Boolean call(Tuple2<A,B> a, Tuple2<A,B> b) {
			return !isEqual().call(a, b);
		}
	};

	@Override
	public Function2<Boolean, Tuple2<A,B>, Tuple2<A,B>> isNotEqual() {
		return NEQ;
	}

	private final Procedure2<Tuple2<A,B>, Tuple2<A,B>> ASSIGN =
			new Procedure2<Tuple2<A,B>, Tuple2<A,B>>()
	{
		@Override
		public void call(Tuple2<A,B> a, Tuple2<A,B> b) {
			algA.assign().call(a.a(), b.a());
			algB.assign().call(a.b(), b.b());
		}
	};

	@Override
	public Procedure2<Tuple2<A,B>, Tuple2<A,B>> assign() {
		return ASSIGN;
	}

	private final Function1<Boolean, Tuple2<A,B>> ISZERO =
			new Function1<Boolean, Tuple2<A,B>>()
	{
		@Override
		public Boolean call(Tuple2<A,B> a) {
			return algA.isZero().call(a.a()) && algB.isZero().call(a.b());
		}
	};

	@Override
	public Function1<Boolean, Tuple2<A,B>> isZero() {
		return ISZERO;
	}

	private final Procedure1<Tuple2<A,B>> ZERO =
			new Procedure1<Tuple2<A,B>>()
	{
		@Override
		public void call(Tuple2<A,B> a) {
			algA.zero().call(a.a());
			algB.zero().call(a.b());
		}
	};

	@Override
	public Procedure1<Tuple2<A,B>> zero() {
		return ZERO;
	}

}


text:
package pl.krych14m.ramki.wycennikram.ramki.calculators;

import org.apache.commons.math3.util.Precision;

import pl.krych14m.ramki.wycennikram.api.calculators.Calculator;
import pl.krych14m.ramki.wycennikram.api.calculators.CalculatorException;
import pl.krych14m.ramki.wycennikram.api.products.Product;
import pl.krych14m.ramki.wycennikram.ramki.priceproviders.AccessoryParametersProvider;
import pl.krych14m.ramki.wycennikram.ramki.priceproviders.ProfilePriceProvider;
import pl.krych14m.ramki.wycennikram.ramki.products.Back;
import pl.krych14m.ramki.wycennikram.ramki.products.Badges;
import pl.krych14m.ramki.wycennikram.ramki.products.Frame;
import pl.krych14m.ramki.wycennikram.ramki.products.Glass;
import pl.krych14m.ramki.wycennikram.ramki.products.Hook;

public class FrameCalculator implements Calculator {

    private PureFrameCalculator pureFrameCalculator;
    private GlassCalculator glassCalculator;
    private BackCalculator backCalculator;
    private HookCalculator hookCalculator;
    private BadgesCalculator badgesCalculator;

    public FrameCalculator(ProfilePriceProvider profilePriceProvider, AccessoryParametersProvider accessoryParametersProvider) {
        this.pureFrameCalculator = new PureFrameCalculator(profilePriceProvider);
        this.glassCalculator = new GlassCalculator(accessoryParametersProvider);
        this.backCalculator = new BackCalculator(accessoryParametersProvider);
        this.hookCalculator = new HookCalculator(accessoryParametersProvider);
        this.badgesCalculator = new BadgesCalculator(accessoryParametersProvider);
    }

    @Override
    public double getPrice(Product product) throws CalculatorException {
        Frame frame = (Frame) product;

        double pureFramePrice = pureFrameCalculator.getPrice(frame.getPureFrame());

        double glassPrice = 0;
        double backPrice = 0;
        double badgesPrice = 0;
        double hookPrice = 0;

        if (frame.isGlass()) {
            Glass glass = new Glass(frame.getX(), frame.getY());
            glassPrice = glassCalculator.getPrice(glass);
        }
        if (frame.isBack()) {
            Back back = new Back(frame.getX(), frame.getY());
            backPrice = backCalculator.getPrice(back);
        }
        if (frame.isBadges() && (frame.isGlass() || frame.isBack())) {
            glassPrice *= 1.5;
            backPrice *= 1.5;
        }
        if (frame.isBadges()) {
            Badges badges = new Badges(frame.getX(), frame.getY());
            badgesPrice = badgesCalculator.getPrice(badges);
        }
        if (frame.isHook()) {
            Hook hook = new Hook();
            hookPrice = hookCalculator.getPrice(hook);
        }

        pureFramePrice = Precision.round(pureFramePrice, 2);
        glassPrice = Precision.round(glassPrice, 2);
        backPrice = Precision.round(backPrice, 2);
        hookPrice = Precision.round(hookPrice, 2);
        badgesPrice = Precision.round(badgesPrice, 2);

        double price = pureFramePrice + glassPrice + backPrice + hookPrice + badgesPrice;
        return Precision.round(price, 2);
    }

    @Override
    public boolean isProductSupported(Product product) {
        return product.getClass().equals(Frame.class);
    }

}