text:
<?php

namespace Drupal\Core\Render\Element;

use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\PluginBase;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Element;
use Drupal\Core\Url;

/**
 * Provides a base class for render element plugins.
 *
 * Render elements are referenced in render arrays; see the
 * @link theme_render Render API topic @endlink for an overview of render
 * arrays and render elements.
 *
 * The elements of render arrays are divided up into properties (whose keys
 * start with #) and children (whose keys do not start with #). The properties
 * provide data or settings that are used in rendering. Some properties are
 * specific to a particular type of render element, some are available for any
 * render element, and some are available for any form input element. A list of
 * the properties that are available for all render elements follows; the
 * properties that are for all form elements are documented on
 * \Drupal\Core\Render\Element\FormElement, and properties specific to a
 * particular element are documented on that element's class. See the
 * @link theme_render Render API topic @endlink for a list of the most
 * commonly-used properties.
 *
 * Many of the properties are strings that are displayed to users. These
 * strings, if they are literals provided by your module, should be
 * internationalized and translated; see the
 * @link i18n Internationalization topic @endlink for more information. Note
 * that although in the properies list that follows, they are designated to be
 * of type string, they would generally end up being
 * \Drupal\Core\StringTranslation\TranslatableMarkup objects instead.
 *
 * Here is the list of the properties used during the rendering of all render
 * elements:
 * - #access: (bool) Whether the element is accessible or not. When FALSE,
 *   the element is not rendered and user-submitted values are not taken
 *   into consideration.
 * - #access_callback: A callable or function name to call to check access.
 *   Argument: element.
 * - #allowed_tags: (array) Array of allowed HTML tags for XSS filtering of
 *   #markup, #prefix, #suffix, etc.
 * - #attached: (array) Array of attachments associated with the element.
 *   See the "Attaching libraries in render arrays" section of the
 *   @link theme_render Render API topic @endlink for an overview, and
 *   \Drupal\Core\Render\AttachmentsResponseProcessorInterface::processAttachments
 *   for a list of what this can contain. Besides this list, it may also contain
 *   a 'placeholders' element; see the Placeholders section of the
 *   @link theme_render Render API topic @endlink for an overview.
 * - #attributes: (array) HTML attributes for the element. The first-level
 *   keys are the attribute names, such as 'class', and the attributes are
 *   usually given as an array of string values to apply to that attribute
 *   (the rendering system will concatenate them together into a string in
 *   the HTML output).
 * - #cache: (array) Cache information. See the Caching section of the
 *   @link theme_render Render API topic @endlink for more information.
 * - #children: (array, internal) Array of child elements of this element.
 *   Set and used during the rendering process.
 * - #create_placeholder: (bool) TRUE if the element has placeholders that
 *   are generated by #lazy_builder callbacks. Set internally during rendering
 *   in some cases. See also #attached.
 * - #defaults_loaded: (bool) Set to TRUE during rendering when the defaults
 *   for the element #type have been added to the element.
 * - #id: (string) The HTML ID on the element. This is automatically set for
 *   form elements, but not for all render elements; you can override the
 *   default value or add an ID by setting this property.
 * - #lazy_builder: (array) Array whose first element is a lazy building
 *   callback (callable), and whose second is an array of scalar arguments to
 *   the callback. To use lazy building, the element array must be very
 *   simple: no properties except #lazy_builder, #cache, #weight, and
 *   #create_placeholder, and no children. A lazy builder callback typically
 *   generates #markup and/or placeholders; see the Placeholders section of the
 *   @link theme_render Render API topic @endlink for information about
 *   placeholders.
 * - #markup: (string) During rendering, this will be set to the HTML markup
 *   output. It can also be set on input, as a fallback if there is no
 *   theming for the element. This will be filtered for XSS problems during
 *   rendering; see also #plain_text and #allowed_tags.
 * - #plain_text: (string) Elements can set this instead of #markup. All HTML
 *   tags will be escaped in this text, and if both #plain_text and #markup
 *   are provided, #plain_text is used.
 * - #post_render: (array) Array of callables or function names, which are
 *   called after the element is rendered. Arguments: rendered element string,
 *   children.
 * - #pre_render: (array) Array of callables or function names, which are
 *   called just before the element is rendered. Argument: $element.
 *   Return value: an altered $element.
 * - #prefix: (string) Text to render before the entire element output. See
 *   also #suffix. If it is not already wrapped in a safe markup object, will
 *   be filtered for XSS safety.
 * - #printed: (bool, internal) Set to TRUE when an element and its children
 *   have been rendered.
 * - #render_children: (bool, internal) Set to FALSE by the rendering process
 *   if the #theme call should be bypassed (normally, the theme is used to
 *   render the children). Set to TRUE by the rendering process if the children
 *   should be rendered by rendering each one separately and concatenating.
 * - #suffix: (string) Text to render after the entire element output. See
 *   also #prefix. If it is not already wrapped in a safe markup object, will
 *   be filtered for XSS safety.
 * - #theme: (string) Name of the theme hook to use to render the element.
 *   A default is generally set for elements; users of the element can
 *   override this (typically by adding __suggestion suffixes).
 * - #theme_wrappers: (array) Array of theme hooks, which are invoked
 *   after the element and children are rendered, and before #post_render
 *   functions.
 * - #type: (string) The machine name of the type of render/form element.
 * - #weight: (float) The sort order for rendering, with lower numbers coming
 *   before higher numbers. Default if not provided is zero; elements with
 *   the same weight are rendered in the order they appear in the render
 *   array.
 *
 * @see \Drupal\Core\Render\Annotation\RenderElement
 * @see \Drupal\Core\Render\ElementInterface
 * @see \Drupal\Core\Render\ElementInfoManager
 * @see plugin_api
 *
 * @ingroup theme_render
 */
abstract class RenderElement extends PluginBase implements ElementInterface {

  /**
   * {@inheritdoc}
   */
  public static function setAttributes(&$element, $class = array()) {
    if (!empty($class)) {
      if (!isset($element['#attributes']['class'])) {
        $element['#attributes']['class'] = array();
      }
      $element['#attributes']['class'] = array_merge($element['#attributes']['class'], $class);
    }
    // This function is invoked from form element theme functions, but the
    // rendered form element may not necessarily have been processed by
    // \Drupal::formBuilder()->doBuildForm().
    if (!empty($element['#required'])) {
      $element['#attributes']['class'][] = 'required';
      $element['#attributes']['required'] = 'required';
      $element['#attributes']['aria-required'] = 'true';
    }
    if (isset($element['#parents']) && isset($element['#errors']) && !empty($element['#validated'])) {
      $element['#attributes']['class'][] = 'error';
      $element['#attributes']['aria-invalid'] = 'true';
    }
  }

  /**
   * Adds members of this group as actual elements for rendering.
   *
   * @param array $element
   *   An associative array containing the properties and children of the
   *   element.
   *
   * @return array
   *   The modified element with all group members.
   */
  public static function preRenderGroup($element) {
    // The element may be rendered outside of a Form API context.
    if (!isset($element['#parents']) || !isset($element['#groups'])) {
      return $element;
    }

    // Inject group member elements belonging to this group.
    $parents = implode('][', $element['#parents']);
    $children = Element::children($element['#groups'][$parents]);
    if (!empty($children)) {
      foreach ($children as $key) {
        // Break references and indicate that the element should be rendered as
        // group member.
        $child = (array) $element['#groups'][$parents][$key];
        $child['#group_details'] = TRUE;
        // Inject the element as new child element.
        $element[] = $child;

        $sort = TRUE;
      }
      // Re-sort the element's children if we injected group member elements.
      if (isset($sort)) {
        $element['#sorted'] = FALSE;
      }
    }

    if (isset($element['#group'])) {
      // Contains form element summary functionalities.
      $element['#attached']['library'][] = 'core/drupal.form';

      $group = $element['#group'];
      // If this element belongs to a group, but the group-holding element does
      // not exist, we need to render it (at its original location).
      if (!isset($element['#groups'][$group]['#group_exists'])) {
        // Intentionally empty to clarify the flow; we simply return $element.
      }
      // If we injected this element into the group, then we want to render it.
      elseif (!empty($element['#group_details'])) {
        // Intentionally empty to clarify the flow; we simply return $element.
      }
      // Otherwise, this element belongs to a group and the group exists, so we do
      // not render it.
      elseif (Element::children($element['#groups'][$group])) {
        $element['#printed'] = TRUE;
      }
    }

    return $element;
  }

  /**
   * Form element processing handler for the #ajax form property.
   *
   * This method is useful for non-input elements that can be used in and
   * outside the context of a form.
   *
   * @param array $element
   *   An associative array containing the properties of the element.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param array $complete_form
   *   The complete form structure.
   *
   * @return array
   *   The processed element.
   *
   * @see self::preRenderAjaxForm()
   */
  public static function processAjaxForm(&$element, FormStateInterface $form_state, &$complete_form) {
    return static::preRenderAjaxForm($element);
  }

  /**
   * Adds Ajax information about an element to communicate with JavaScript.
   *
   * If #ajax is set on an element, this additional JavaScript is added to the
   * page header to attach the Ajax behaviors. See ajax.js for more information.
   *
   * @param array $element
   *   An associative array containing the properties of the element.
   *   Properties used:
   *   - #ajax['event']
   *   - #ajax['prevent']
   *   - #ajax['url']
   *   - #ajax['callback']
   *   - #ajax['options']
   *   - #ajax['wrapper']
   *   - #ajax['parameters']
   *   - #ajax['effect']
   *   - #ajax['accepts']
   *
   * @return array
   *   The processed element with the necessary JavaScript attached to it.
   */
  public static function preRenderAjaxForm($element) {
    // Skip already processed elements.
    if (isset($element['#ajax_processed'])) {
      return $element;
    }
    // Initialize #ajax_processed, so we do not process this element again.
    $element['#ajax_processed'] = FALSE;

    // Nothing to do if there are no Ajax settings.
    if (empty($element['#ajax'])) {
      return $element;
    }

    // Add a data attribute to disable automatic refocus after ajax call.
    if (!empty($element['#ajax']['disable-refocus'])) {
      $element['#attributes']['data-disable-refocus'] = "true";
    }

    // Add a reasonable default event handler if none was specified.
    if (isset($element['#ajax']) && !isset($element['#ajax']['event'])) {
      switch ($element['#type']) {
        case 'submit':
        case 'button':
        case 'image_button':
          // Pressing the ENTER key within a textfield triggers the click event of
          // the form's first submit button. Triggering Ajax in this situation
          // leads to problems, like breaking autocomplete textfields, so we bind
          // to mousedown instead of click.
          // @see https://www.drupal.org/node/216059
          $element['#ajax']['event'] = 'mousedown';
          // Retain keyboard accessibility by setting 'keypress'. This causes
          // ajax.js to trigger 'event' when SPACE or ENTER are pressed while the
          // button has focus.
          $element['#ajax']['keypress'] = TRUE;
          // Binding to mousedown rather than click means that it is possible to
          // trigger a click by pressing the mouse, holding the mouse button down
          // until the Ajax request is complete and the button is re-enabled, and
          // then releasing the mouse button. Set 'prevent' so that ajax.js binds
          // an additional handler to prevent such a click from triggering a
          // non-Ajax form submission. This also prevents a textfield's ENTER
          // press triggering this button's non-Ajax form submission behavior.
          if (!isset($element['#ajax']['prevent'])) {
            $element['#ajax']['prevent'] = 'click';
          }
          break;

        case 'password':
        case 'textfield':
        case 'number':
        case 'tel':
        case 'textarea':
          $element['#ajax']['event'] = 'blur';
          break;

        case 'radio':
        case 'checkbox':
        case 'select':
          $element['#ajax']['event'] = 'change';
          break;

        case 'link':
          $element['#ajax']['event'] = 'click';
          break;

        default:
          return $element;
      }
    }

    // Attach JavaScript settings to the element.
    if (isset($element['#ajax']['event'])) {
      $element['#attached']['library'][] = 'core/jquery.form';
      $element['#attached']['library'][] = 'core/drupal.ajax';

      $settings = $element['#ajax'];

      // Assign default settings. When 'url' is set to NULL, ajax.js submits the
      // Ajax request to the same URL as the form or link destination is for
      // someone with JavaScript disabled. This is generally preferred as a way to
      // ensure consistent server processing for js and no-js users, and Drupal's
      // content negotiation takes care of formatting the response appropriately.
      // However, 'url' and 'options' may be set when wanting server processing
      // to be substantially different for a JavaScript triggered submission.
      $settings += [
        'url' => NULL,
        'options' => ['query' => []],
        'dialogType' => 'ajax',
      ];
      if (array_key_exists('callback', $settings) && !isset($settings['url'])) {
        $settings['url'] = Url::fromRoute('<current>');
        // Add all the current query parameters in order to ensure that we build
        // the same form on the AJAX POST requests. For example,
        // \Drupal\user\AccountForm takes query parameters into account in order
        // to hide the password field dynamically.
        $settings['options']['query'] += \Drupal::request()->query->all();
        $settings['options']['query'][FormBuilderInterface::AJAX_FORM_REQUEST] = TRUE;
      }

      // @todo Legacy support. Remove in Drupal 8.
      if (isset($settings['method']) && $settings['method'] == 'replace') {
        $settings['method'] = 'replaceWith';
      }

      // Convert \Drupal\Core\Url object to string.
      if (isset($settings['url']) && $settings['url'] instanceof Url) {
        $url = $settings['url']->setOptions($settings['options'])->toString(TRUE);
        BubbleableMetadata::createFromRenderArray($element)
          ->merge($url)
          ->applyTo($element);
        $settings['url'] = $url->getGeneratedUrl();
      }
      else {
        $settings['url'] = NULL;
      }
      unset($settings['options']);

      // Add special data to $settings['submit'] so that when this element
      // triggers an Ajax submission, Drupal's form processing can determine which
      // element triggered it.
      // @see _form_element_triggered_scripted_submission()
      if (isset($settings['trigger_as'])) {
        // An element can add a 'trigger_as' key within #ajax to make the element
        // submit as though another one (for example, a non-button can use this
        // to submit the form as though a button were clicked). When using this,
        // the 'name' key is always required to identify the element to trigger
        // as. The 'value' key is optional, and only needed when multiple elements
        // share the same name, which is commonly the case for buttons.
        $settings['submit']['_triggering_element_name'] = $settings['trigger_as']['name'];
        if (isset($settings['trigger_as']['value'])) {
          $settings['submit']['_triggering_element_value'] = $settings['trigger_as']['value'];
        }
        unset($settings['trigger_as']);
      }
      elseif (isset($element['#name'])) {
        // Most of the time, elements can submit as themselves, in which case the
        // 'trigger_as' key isn't needed, and the element's name is used.
        $settings['submit']['_triggering_element_name'] = $element['#name'];
        // If the element is a (non-image) button, its name may not identify it
        // uniquely, in which case a match on value is also needed.
        // @see _form_button_was_clicked()
        if (!empty($element['#is_button']) && empty($element['#has_garbage_value'])) {
          $settings['submit']['_triggering_element_value'] = $element['#value'];
        }
      }

      // Convert a simple #ajax['progress'] string into an array.
      if (isset($settings['progress']) && is_string($settings['progress'])) {
        $settings['progress'] = array('type' => $settings['progress']);
      }
      // Change progress path to a full URL.
      if (isset($settings['progress']['url']) && $settings['progress']['url'] instanceof Url) {
        $settings['progress']['url'] = $settings['progress']['url']->toString();
      }

      $element['#attached']['drupalSettings']['ajax'][$element['#id']] = $settings;
      $element['#attached']['drupalSettings']['ajaxTrustedUrl'][$settings['url']] = TRUE;

      // Indicate that Ajax processing was successful.
      $element['#ajax_processed'] = TRUE;
    }
    return $element;
  }

  /**
   * Arranges elements into groups.
   *
   * This method is useful for non-input elements that can be used in and
   * outside the context of a form.
   *
   * @param array $element
   *   An associative array containing the properties and children of the
   *   element. Note that $element must be taken by reference here, so processed
   *   child elements are taken over into $form_state.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param array $complete_form
   *   The complete form structure.
   *
   * @return array
   *   The processed element.
   */
  public static function processGroup(&$element, FormStateInterface $form_state, &$complete_form) {
    $parents = implode('][', $element['#parents']);

    // Each details element forms a new group. The #type 'vertical_tabs' basically
    // only injects a new details element.
    $groups = &$form_state->getGroups();
    $groups[$parents]['#group_exists'] = TRUE;
    $element['#groups'] = &$groups;

    // Process vertical tabs group member details elements.
    if (isset($element['#group'])) {
      // Add this details element to the defined group (by reference).
      $group = $element['#group'];
      $groups[$group][] = &$element;
    }

    return $element;
  }

}


text:
require 'test_helper'

class AttributeInstancesControllerTest < ActionController::TestCase
  test "should get create" do
    get :create
    assert_response :success
  end

  test "should get update" do
    get :update
    assert_response :success
  end

end

redpajama_set_name: RedPajamaGithub


text:
#include <aws/kinesis/model/MergeShardsRequest.h>
#include <aws/core/utils/json/JsonSerializer.h>

#include <utility>

using namespace Aws::Kinesis::Model;
using namespace Aws::Utils::Json;
using namespace Aws::Utils;

MergeShardsRequest::MergeShardsRequest() :
    m_streamNameHasBeenSet(false),
    m_shardToMergeHasBeenSet(false),
    m_adjacentShardToMergeHasBeenSet(false)
{
}

Aws::String MergeShardsRequest::SerializePayload() const
{
  JsonValue payload;

  if(m_streamNameHasBeenSet)
  {
   payload.WithString("StreamName", m_streamName);

  }

  if(m_shardToMergeHasBeenSet)
  {
   payload.WithString("ShardToMerge", m_shardToMerge);

  }

  if(m_adjacentShardToMergeHasBeenSet)
  {
   payload.WithString("AdjacentShardToMerge", m_adjacentShardToMerge);

  }

  return payload.View().WriteReadable();
}

Aws::Http::HeaderValueCollection MergeShardsRequest::GetRequestSpecificHeaders() const
{
  Aws::Http::HeaderValueCollection headers;
  headers.insert(Aws::Http::HeaderValuePair("X-Amz-Target", "Kinesis_20131202.MergeShards"));
  return headers;

}


text:
package collector

import (
	"autoscaler/db"

	"code.cloudfoundry.org/clock"
	"code.cloudfoundry.org/lager"
	"sync"
	"time"
)

type AppCollector interface {
	Start()
	Stop()
}

type Collector struct {
	refreshInterval    time.Duration
	logger             lager.Logger
	database           db.PolicyDB
	cclock             clock.Clock
	createAppCollector func(string) AppCollector
	doneChan           chan bool
	appCollectors      map[string]AppCollector
	ticker             clock.Ticker
	lock               *sync.Mutex
}

func NewCollector(refreshInterval time.Duration, logger lager.Logger, database db.PolicyDB, cclock clock.Clock, createAppCollector func(string) AppCollector) *Collector {
	return &Collector{
		refreshInterval:    refreshInterval,
		logger:             logger,
		database:           database,
		cclock:             cclock,
		createAppCollector: createAppCollector,
		doneChan:           make(chan bool),
		appCollectors:      make(map[string]AppCollector),
		lock:               &sync.Mutex{},
	}
}

func (c *Collector) Start() {
	c.ticker = c.cclock.NewTicker(c.refreshInterval)
	go c.startAppRefresh()
	c.logger.Info("collector-started")
}

func (c *Collector) startAppRefresh() {
	for {
		c.refreshApps()
		select {
		case <-c.doneChan:
			return
		case <-c.ticker.C():
		}
	}
}

func (c *Collector) refreshApps() {
	appIds, err := c.database.GetAppIds()
	if err != nil {
		c.logger.Error("refresh-apps", err)
		return
	}

	c.logger.Debug("refresh-apps", lager.Data{"appIds": appIds})

	c.lock.Lock()
	for id, ap := range c.appCollectors {
		_, exist := appIds[id]
		if !exist {
			c.logger.Debug("refresh-apps-remove", lager.Data{"appId": id})
			ap.Stop()
			delete(c.appCollectors, id)
		}
	}

	for id, _ := range appIds {
		_, exist := c.appCollectors[id]
		if !exist {
			c.logger.Debug("refresh-apps-add", lager.Data{"appId": id})
			ap := c.createAppCollector(id)
			ap.Start()
			c.appCollectors[id] = ap
		}
	}
	c.lock.Unlock()
}

func (c *Collector) Stop() {
	if c.ticker != nil {
		c.ticker.Stop()
		close(c.doneChan)

		c.lock.Lock()
		for _, ap := range c.appCollectors {
			ap.Stop()
		}
		c.lock.Unlock()
	}
	c.logger.Info("collector-stopped")
}

func (c *Collector) GetCollectorAppIds() []string {
	var appIds []string
	c.lock.Lock()
	for id, _ := range c.appCollectors {
		appIds = append(appIds, id)
	}
	c.lock.Unlock()
	return appIds
}


text:
<?php

namespace Tests\unit\WindowsAzure\MediaServices\Models;

use WindowsAzure\MediaServices\Models\StorageAccount;
use PHPUnit\Framework\TestCase;

/**
 * Represents access policy object used in media services.
 *
 * @category  Microsoft
 *
 * @author    Azure PHP SDK <azurephpsdk@microsoft.com>
 * @copyright Microsoft Corporation
 * @license   http://www.apache.org/licenses/LICENSE-2.0  Apache License 2.0
 *
 * @version   Release: 0.5.0_2016-11
 *
 * @link      https://github.com/windowsazure/azure-sdk-for-php
 */
class StorageAccountTest extends TestCase
{
    /**
     * @covers \WindowsAzure\MediaServices\Models\StorageAccount::createFromOptions
     * @covers \WindowsAzure\MediaServices\Models\StorageAccount::fromArray
     * @covers \WindowsAzure\MediaServices\Models\StorageAccount::__construct
     */
    public function testCreateFromArray()
    {
        // Setup
        $name = 'SomeName-42';
        $isDefault = true;
        $options = [
                'Name' => $name,
                'IsDefault' => $isDefault,
        ];

        // Test
        $storageAccount = StorageAccount::createFromOptions($options);

        // Assert
        $this->assertEquals($name, $storageAccount->getName());
        $this->assertEquals($isDefault, $storageAccount->getIsDefault());
    }

    /**
     * @covers \WindowsAzure\MediaServices\Models\StorageAccount::getName
     */
    public function testGetName()
    {
        // Setup
        $name = 'SomeName-42';
        $options = [
                'Name' => $name,
        ];
        $storageAccount = StorageAccount::createFromOptions($options);

        // Test
        $result = $storageAccount->getName();

        // Assert
        $this->assertEquals($name, $result);
    }

    /**
     * @covers \WindowsAzure\MediaServices\Models\StorageAccount::getIsDefault
     */
    public function testGetIsDefault()
    {
        // Setup
        $isDefault = true;
        $options = [
                'IsDefault' => $isDefault,
        ];
        $storageAccount = StorageAccount::createFromOptions($options);

        // Test
        $result = $storageAccount->getIsDefault();

        // Assert
        $this->assertEquals($isDefault, $result);
    }
}


text: export {default} from 'ember-frost-bunsen/components/inputs/geolocation'


text:
using namespace std::literals;

namespace arbenv {

static std::optional<long long> read_env_integer_(const char* env_var, bool throw_on_err) {
    const char* str = std::getenv(env_var);
    if (!str || !*str) return std::nullopt;

    char* end = 0;
    errno = 0;
    long long v = std::strtoll(str, &end, 10);
    bool out_of_range = errno==ERANGE;
    errno = 0;

    if (out_of_range && throw_on_err) {
        throw invalid_env_value(env_var, str);
    }

    while (*end && std::isspace(*end)) ++end;
    if (*end) {
        if (throw_on_err) {
            throw invalid_env_value(env_var, str);
        }
        else {
            return std::nullopt;
        }
    }

    return v;
}

std::optional<long long> read_env_integer(const char* env_var) {
    return read_env_integer_(env_var, false);
}

std::optional<long long> read_env_integer(const char* env_var, throw_on_invalid_t) {
    return read_env_integer_(env_var, true);
}

} // namespace arbenv


text:
@import GoogleMobileAds;

//@class WIPBrowserViewController;
//@class RighMenuViewController;
//@class LeftMenuViewController;

@interface PPViewController()<PPImageScrollingTableViewCellDelegate,JsonDownloaderDelegate>

@property (strong, nonatomic) NSMutableArray* categoryList;
@property (strong, nonatomic) UINavigationController *navController;

@property (strong, nonatomic) BrowserViewController *wipViewController;
@property (strong, nonatomic) TopStoryView *headerView;

@property (strong, nonatomic) DFPBannerView *bannerView;

@property (strong, nonatomic) Article *firstArticle;

@end

@implementation PPViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.

    list = ((AppDelegate*)[[UIApplication sharedApplication] delegate]).list;

    self.title = @"Main";
    [self addTitleBarItems];
    [self.tableView setBackgroundColor:[UIColor whiteColor]];

    static NSString *CellIdentifier = @"Cell";
    [self.tableView registerClass:[PPImageScrollingTableViewCell class] forCellReuseIdentifier:CellIdentifier];

    self.categoryList = [[NSMutableArray alloc] initWithCapacity:6];

    jsonDownloader = [[JsonDownloader alloc] initWithList:list];
    jsonDownloader.delegate = self;

    [self loadArticleList];

    [self initWebview];

    [self initHeadView];

    [self initAdBannerView];

}

- (void) initAdBannerView
{
//    GADAdSize customAdSize = GADAdSizeFromCGSize(CGSizeMake(728, 90));
    NSLog(@"Google Mobile Ads SDK version: %@", [DFPRequest sdkVersion]);

    self.bannerView = [[DFPBannerView alloc] initWithAdSize:kGADAdSizeSmartBannerPortrait];

    self.bannerView.adUnitID = @"/50807330/RPM_RECD_Leaderboard_728x90";
    self.bannerView.rootViewController = self;

    GADRequest *request = [GADRequest request];

    [self.bannerView loadRequest:request];

    //
//    GADAdSize customAdSize = GADAdSizeFromCGSize(CGSizeMake(728, 90));
//    self.bannerView.adSize = customAdSize;

    [self reloadAdBannerView : YES];

}

- (void) reloadAdBannerView : (Boolean)isPortrait
{

    self.bannerView.adSize =isPortrait?kGADAdSizeSmartBannerPortrait:kGADAdSizeSmartBannerLandscape;

    self.tableView.tableFooterView = self.bannerView;

}

- (void) initHeadView
{

    self.headerView = [[TopStoryView alloc] init];

    self.tableView.tableHeaderView = self.headerView; //test

    UITapGestureRecognizer *singleFingerTap =
    [[UITapGestureRecognizer alloc] initWithTarget:self
                                            action:@selector(handleSingleTap:)];
    [self.headerView addGestureRecognizer:singleFingerTap];
}

- (void)addImageViewIfPortraitIpad
{
    UIInterfaceOrientation orientation=[UIApplication sharedApplication].statusBarOrientation;
    if (IS_IPAD) {
        if (UIInterfaceOrientationIsPortrait(orientation)){

             self.tableView.tableHeaderView = self.headerView;

            [self reloadAdBannerView:YES];
        }

        else
        {
            self.tableView.tableHeaderView = nil;
            [self reloadAdBannerView:NO];
        }

    }else
        self.tableView.tableHeaderView = nil;

}

- (void)viewDidAppear:(BOOL)animated
{

    [[[UIApplication sharedApplication] keyWindow] setBackgroundColor:[UIColor whiteColor]];
    [self addImageViewIfPortraitIpad];
}

- (void)viewWillAppear:(BOOL)animated
{

    NSString* currentVersion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];

    //detect if it is the first login, if yes show the welcome screen
    if (![currentVersion isEqualToString:[[NSUserDefaults standardUserDefaults]
                                objectForKey:KEY_IF_FIRST_TIME_LOGIN]]) {
        [[NSUserDefaults standardUserDefaults] setValue:currentVersion forKey:KEY_IF_FIRST_TIME_LOGIN];
        [[NSUserDefaults standardUserDefaults] synchronize];
//    if(1)
//    {

        WelcomeViewController *welcomeViews = [[WelcomeViewController alloc] initWithImageCount:4];

//    UINavigationController* navigationController =[[UINavigationController alloc] initWithRootViewController:[[WelcomeViewController alloc] initWithImageCount:4]];

        CATransition* transition = [CATransition animation];
        transition.duration = .2;
        transition.type = kCATransitionPush;
        transition.subtype = kCATransitionFromRight;
        [self.view.window.layer addAnimation:transition forKey:kCATransition];

        [self presentViewController:welcomeViews animated:NO completion:nil];

    }

    [super viewWillAppear:animated];

}

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
//    [self.tableView reloadData];

    [self addImageViewIfPortraitIpad];

    if (list.count >0) {
        ArticleCategory* category = [list objectAtIndex:0];
        if (category.articleList.count>0) {

            if (toInterfaceOrientation == UIInterfaceOrientationPortrait) {
                if(self.firstArticle.link == ((Article*)[category.articleList objectAtIndex:0]).link)
                {
                    [category.articleList removeObjectAtIndex:0];
                }
            }else if ((toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft )|| (toInterfaceOrientation == UIInterfaceOrientationLandscapeRight))
            {
                if(self.firstArticle.link != ((Article*)[category.articleList objectAtIndex:0]).link)
                {
                    [category.articleList insertObject:self.firstArticle atIndex:0];
                }

            }
        }
    }

    [self.tableView reloadData];

}

- (void)initWebview
{
    NSString *userAgent = [self getAppUA];
    NSString *userAgentPre = [self getAppUA];
    self.wipViewController = [[BrowserViewController alloc] initWithUserAgent:userAgent prevUserAgent:userAgentPre];

    NSString *preload_link = HOMEPAGE_URL;
    if (self.firstArticle != NULL) {

        if (self.firstArticle.link != NULL) {
            preload_link = self.firstArticle.link;
        }
    }
    [self.wipViewController navigateTo:[NSURL URLWithString:preload_link]];

}

- (void) showUrlInContentView : (NSString *) url
{
    if (self.wipViewController != NULL) {
        [self openWebView:url];
    }

}

-(NSString*)getAppUA
{

    NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"];
    //    NSLog(@"build version = :  %@",version);
    // Modify the user-agent
    NSString* suffixUA = [NSString stringWithFormat:@" mobileapp %@",version];//@" mobileapp";
    UIWebView* webView = [[UIWebView alloc] initWithFrame:CGRectZero];
    NSString* defaultUA = [webView stringByEvaluatingJavaScriptFromString:@"navigator.userAgent"];
    NSString* finalUA = [defaultUA stringByAppendingString:suffixUA];
    NSDictionary *dictionary = [NSDictionary dictionaryWithObjectsAndKeys:finalUA, @"UserAgent", nil];
    [[NSUserDefaults standardUserDefaults] registerDefaults:dictionary];

    return finalUA;
}

#pragma mark -
#pragma mark  Load article list

-(void)loadArticleList
{
    [list removeAllObjects];
    [self.categoryList removeAllObjects];
    [self.categoryList addObjectsFromArray: @[@{@"id":@"17",@"name":@"NEWS"},
                                              @{@"id":@"51",@"name":@"FEATURES"},
                                              @{@"id":@"21",@"name":@"BLOGS"},
                                              @{@"id":@"48",@"name":@"VIDEO"}
                                              ]];

//    [self loadNextCategory];
    [jsonDownloader loadArticleList:self.categoryList];

}

- (void)onDownloadFinished:(NSMutableArray* ) outList
{
    NSLog(@"onDownloadFinished:=======================================================");
    list = outList;
    [self fillData];

}

- (void) fillData
{

    [self fillHeadView];

    [self.tableView reloadData];
}

- (void) fillHeadView
{
    if (list.count >0) {
        ArticleCategory* category = [list objectAtIndex:0];
        if (category.articleList.count>0) {
            Article* article = [category.articleList objectAtIndex:0];
            self.firstArticle = article;
            NSString *firstlink = article.link;
            [self.wipViewController navigateTo:[NSURL URLWithString:firstlink]];

            [self.headerView fillWithFirstArticle:article];

            [self.tableView setTableHeaderView:self.headerView];

            UIInterfaceOrientation orientation=[UIApplication sharedApplication].statusBarOrientation;
            if (IS_IPAD) {
                if (UIInterfaceOrientationIsPortrait(orientation)){

                    [category.articleList removeObjectAtIndex:0];
                }else{
                    self.tableView.tableHeaderView = nil;
                }

            }else
                self.tableView.tableHeaderView = nil;

        }
    }
}

//The event handling method
- (void)handleSingleTap:(UITapGestureRecognizer *)recognizer {
//    CGPoint location = [recognizer locationInView:[recognizer.view superview]];
    if (self.firstArticle != NULL) {

        if (self.firstArticle.link != NULL) {

//            NSString *firstlink = self.firstArticle.link;
            [self openWebView:self.firstArticle];
        }
    }
}

#pragma mark -
#pragma mark  UITableViewDataSource

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//    return [self.images count];

    return [list count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
//    NSDictionary *cellData = [self.images objectAtIndex:[indexPath section]];
    ArticleCategory* category = [list objectAtIndex:[indexPath section]];
    PPImageScrollingTableViewCell *customCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    [customCell setBackgroundColor:[UIColor whiteColor]];
    [customCell setDelegate:self];
//    [customCell setImageData:cellData];
    [customCell setArticleCategory:category];
//    [customCell setCategoryLabelText:[cellData objectForKey:@"category"] withColor:[UIColor darkGrayColor]];
    [customCell setCategoryLabelText:category.catName withColor:[UIColor darkGrayColor]];
    [customCell setTag:[indexPath section]];
    [customCell setImageTitleTextColor:[UIColor whiteColor] withBackgroundColor:[UIColor colorWithRed:0 green:0 blue:0 alpha:0.7]];
    [customCell setImageTitleLabelWitdh:190 withHeight:45];
    [customCell setCollectionViewBackgroundColor:[UIColor whiteColor]];

    return customCell;
}

#pragma mark - UITableViewDelegate

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 250;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - PPImageScrollingTableViewCellDelegate

- (void)scrollingTableViewCell:(PPImageScrollingTableViewCell *)scrollingTableViewCell didSelectImageAtIndexPath:(NSIndexPath*)indexPathOfImage atCategoryRowIndex:(NSInteger)categoryRowIndex
{

    NSInteger num = [indexPathOfImage row];
    ArticleCategory* ar = (ArticleCategory*)[list objectAtIndex:categoryRowIndex];
    Article* a = [ar.articleList objectAtIndex:num];
//    NSString* link = a.link;

    [self openWebView:a];

}

- (void) openWebView:(Article *) a
{
//    WIPBrowserViewController* nextController = [[WIPBrowserViewController alloc] init];
//
//
//    [nextController navigateToFromClearPage:[NSURL URLWithString:link]];
//     [self.wipViewController navigateToFromClearPage:[NSURL URLWithString:link]];

    [self.wipViewController navigationToTestPage:a];
//    CATransition* transition = [CATransition animation];
//    transition.duration = .2;
//    transition.type = kCATransitionPush;
//    transition.subtype = kCATransitionFromRight;
//    [self.view.window.layer addAnimation:transition forKey:kCATransition];
//    NSLog(@"self.navigationController=%@", self.navigationController);

     [(UINavigationController*)self.navigationController pushViewController:self.wipViewController  animated:YES];

//    [self presentViewController:self.sideMenuViewController animated:NO completion:nil];

}

#pragma mark - Navigation Bar
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
-(void)addTitleBarItems
{
    [[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];

    self.title = INITIAL_NAVIGATION_BAR_TITLE;
    UIImage *imgMenu = [UIImage imageNamed:@"IconMenu"];

   UIImage *imgEmpty = [UIImage imageNamed:@"IconEmpty"];

    UIBarButtonItem *emptyItem = [[UIBarButtonItem alloc] initWithImage:imgEmpty
                                                                  style:UIBarButtonItemStylePlain
                                                                 target:self action:nil];

    UIBarButtonItem *menuItem = [[UIBarButtonItem alloc] initWithImage:imgMenu
                                                                 style:UIBarButtonItemStyleBordered
                                                                target:self
                                                                action:@selector(mainMenu:)];
    NSArray *leftactionButtonItems = @[ emptyItem,emptyItem];

//    self.navigationItem.leftBarButtonItems = leftactionButtonItems;

    NSArray *rightactionButtonItems = @[ emptyItem,emptyItem];

//    self.navigationItem.rightBarButtonItems = rightactionButtonItems;

    NSString *logo = IsIPad()?@"Logo-40":@"Logo-40-slim";
    NSString *logosmall = IsIPad()?@"Logo-small":@"Logo-small-slim";

    UIButton *titleLabel = [UIButton buttonWithType:UIButtonTypeCustom];

    [titleLabel setImage:[UIImage imageNamed:logo] forState:UIControlStateNormal];
    [titleLabel setImage:[UIImage imageNamed:logosmall] forState:UIControlStateHighlighted];

    titleLabel.frame = CGRectMake(100, 0, 200, 80);
    titleLabel.titleLabel.backgroundColor = [UIColor clearColor];
    titleLabel.titleLabel.font = [UIFont boldSystemFontOfSize:20.0];
    titleLabel.titleLabel.shadowColor = [UIColor colorWithWhite:0.0 alpha:0.3];

    [titleLabel addTarget:self action:@selector(backToHomePage:) forControlEvents:UIControlEventTouchUpInside];
    self.navigationItem.titleView = titleLabel;
    self.navigationItem.titleView.frame = CGRectMake(100, 0, 200, 80);

}
#pragma clang diagnostic pop

- (IBAction)backToHomePage:(id)sender
{

    [self loadArticleList];

}

- (IBAction)mainMenu:(id)sender
{

}

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation {
//    [self.tableView reloadData];
}

@end


text:
package br.cefetrj.sagitarii.persistence;

import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.BlockLocation;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

import br.cefetrj.sagitarii.core.config.Configurator;

public class HDFS {
	private FileSystem fs;

	public class HdfsData {
		private String hdfsCapacity = "";
		private String hdfsUsed = "";
		private String hdfsRemaining = "";

		public String getHdfsCapacity() {
			return hdfsCapacity;
		}

		public String getHdfsRemaining() {
			return hdfsRemaining;
		}

		public String getHdfsUsed() {
			return hdfsUsed;
		}

	}

	public List<String> getNodesStoringFile( String fileFullPath ) throws Exception {
		List<String> result = new ArrayList<String>();

		Path path = new Path( fileFullPath );

		FileStatus fileStatus = fs.getFileStatus( path );

		BlockLocation[] blkLocations = fs.getFileBlockLocations(path, 0, fileStatus.getLen());
		int blkCount = blkLocations.length;
		for (int i=0; i < blkCount; i++) {
			String[] hosts = blkLocations[i].getHosts();
			for( String ss : hosts ) {
				result.add( ss );
			}
		}
		return result;
	}

	public boolean deleteDirectory( String path ) throws Exception  {
		return fs.delete( new Path ( path ), true );
	}

	public HDFS() throws Exception {
		Configuration conf=new Configuration();

		String hadoopConfigPath = Configurator.getInstance().getHadoopConfigPath();

		conf.addResource(new Path( hadoopConfigPath + "core-site.xml") );
		conf.addResource(new Path( hadoopConfigPath + "hdfs-site.xml") );

		conf.set("fs.hdfs.impl", org.apache.hadoop.hdfs.DistributedFileSystem.class.getName() );
		conf.set("fs.file.impl", org.apache.hadoop.fs.LocalFileSystem.class.getName() );
		fs = FileSystem.get(conf);
	}

	public HdfsData getHDFSSpace() throws Exception {
		HdfsData hd = new HdfsData();
		hd.hdfsCapacity = formatSize ( fs.getStatus().getCapacity() );
		hd.hdfsUsed = formatSize ( fs.getStatus().getUsed() ) ;
		hd.hdfsRemaining = formatSize ( fs.getStatus().getRemaining() ) ;
		return hd;
	}

	public InputStream getFile( String file ) throws Exception {
		String firstSlash = "";
		if ( !file.startsWith("/") ) {
			firstSlash = "/";
		}
		Path inFile = new Path( firstSlash + file + ".gz");

		System.out.println("****************************************");
		System.out.println(" > " + inFile );
		System.out.println("****************************************");

		InputStream fsd = fs.open(inFile);
		return fsd;
	}

	private String formatSize( long size ) {
	    String hrSize = null;

	    double b = size;
	    double k = size/1024.0;
	    double m = ((size/1024.0)/1024.0);
	    double g = (((size/1024.0)/1024.0)/1024.0);
	    double t = ((((size/1024.0)/1024.0)/1024.0)/1024.0);

	    DecimalFormat dec = new DecimalFormat("0.00");

	    if ( t>1 ) {
	        hrSize = dec.format(t).concat(" TB");
	    } else if ( g>1 ) {
	        hrSize = dec.format(g).concat(" GB");
	    } else if ( m>1 ) {
	        hrSize = dec.format(m).concat(" MB");
	    } else if ( k>1 ) {
	        hrSize = dec.format(k).concat(" KB");
	    } else {
	        hrSize = dec.format(b).concat(" Bytes");
	    }

	    return hrSize;
	}

}


text:
'use strict';

var allureReporter = require('../index'),
    EventEmitter = require('events').EventEmitter,
    writer = require('allure-js-commons/writer'),
    Tree = require('./suite-tree');

describe('Allure reporter', function() {
    var sandbox = sinon.sandbox.create(),
        hermione,
        suites;

    function initHermione_() {
        hermione = new EventEmitter();
        hermione.events = require('hermione/lib/constants/runner-events');
        hermione.config = {
            getBrowserIds: sandbox.stub().returns([]),
            forBrowser: sandbox.stub({})
        };

        allureReporter(hermione, {targetDir: 'allure-results'});
    }

    beforeEach(function() {
        initHermione_();

        suites = [];
        sandbox.stub(writer, 'writeSuite', function(dir, suite) {
            suites.push(suite);
        });
    });

    afterEach(function() {
        sandbox.restore();
    });

    describe('suite', function() {
        it('should be saved with one test with correct names', function() {
            var tree = new Tree()
                    .suite('topSuite')
                        .test('someTest')
                        .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.topSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.topSuite);

            assert.lengthOf(suites, 1);
            assert.lengthOf(suites[0].testcases, 1);
            assert.equal(suites[0].name, 'topSuite');
            assert.equal(suites[0].testcases[0].name, 'someTest');
            assert.equal(suites[0].testcases[0].status, 'passed');
        });

        it('should be saved one test with correct names when it fails', function() {
            var tree = new Tree()
                    .suite('topSuite')
                        .test('someTest')
                        .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.topSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_FAIL, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.topSuite);

            assert.lengthOf(suites, 1);
            assert.lengthOf(suites[0].testcases, 1);
            assert.equal(suites[0].name, 'topSuite');
            assert.equal(suites[0].testcases[0].name, 'someTest');
            assert.equal(suites[0].testcases[0].status, 'failed');
        });

        it('should not be duplicated on calling SUITE_BEGIN twice', function() {
            var tree = new Tree()
                    .suite('someSuite')
                    .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);

            assert.lengthOf(suites, 1);
        });

        it('should not be duplicated on calling SUITE_END twice', function() {
            var tree = new Tree()
                    .suite('someSuite')
                    .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);

            assert.lengthOf(suites, 1);
        });

        it('should be ignored if it is not top level suite', function() {
            var tree = new Tree()
                    .suite('topSuite')
                        .suite('middleSuite')
                        .end()
                    .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.middleSuite);
            hermione.emit(hermione.events.SUITE_END, tree.middleSuite);

            assert.lengthOf(suites, 0);
        });

        describe('`before all` hook fail', function() {
            var fullTitle = sinon.stub().returns('');

            it('should be supposed as one test fail', function() {
                var tree = new Tree().suite('suite').end();

                hermione.emit(hermione.events.SUITE_FAIL, {fullTitle: fullTitle, parent: tree.suite});

                assert.lengthOf(suites, 1);
                assert.lengthOf(suites[0].testcases, 1);
            });

            it('should be handled as one test fail', function() {
                var tree = new Tree().suite('awesomeSuite').end();

                hermione.emit(hermione.events.SUITE_FAIL, {
                    fullTitle: fullTitle.returns('"before all" hook failed'),
                    parent: tree.awesomeSuite,
                    err: new Error('awesome-error')
                });

                assert.equal(suites[0].name, 'awesomeSuite');
                assert.equal(suites[0].testcases[0].name, '"before all" hook failed');
                assert.equal(suites[0].testcases[0].status, 'failed');
                assert.equal(suites[0].testcases[0].failure.message, 'awesome-error');
            });
        });
    });

    describe('test', function() {
        it('should be ignored when started without suite', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end();

            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);

            assert.lengthOf(suites, 0);
        });

        it('should not be attached to wrong suite', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end()
                    .suite('otherSuite')
                    .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.otherSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.otherSuite);

            assert.lengthOf(suites, 1);
            assert.lengthOf(suites[0].testcases, 0);
        });

        it('should not be attached to suite with another browser', function() {
            var firefoxTree = new Tree({browserId: 'firefox'})
                    .suite('firefox')
                .end(),
                chromeTree = new Tree({browserId: 'chrome'})
                .suite('firefox')
                    .test('someTest')
                .end();

            hermione.emit(hermione.events.SUITE_BEGIN, firefoxTree.firefox);
            hermione.emit(hermione.events.SUITE_BEGIN, chromeTree.firefox);
            hermione.emit(hermione.events.TEST_BEGIN, chromeTree.someTest);
            hermione.emit(hermione.events.TEST_PASS, chromeTree.someTest);
            hermione.emit(hermione.events.SUITE_END, firefoxTree.firefox);
            hermione.emit(hermione.events.SUITE_END, chromeTree.firefox);

            assert.lengthOf(suites, 2);
            assert.lengthOf(suites[0].testcases, 0);
            assert.lengthOf(suites[1].testcases, 1);
        });

        it('should be attached to suite with proper browser', function() {
            var firefoxTree = new Tree({browserId: 'firefox'})
                    .suite('suite')
                        .test('test')
                    .end(),
                chromeTree = new Tree({browserId: 'chrome'})
                    .suite('suite')
                        .test('test')
                    .end();

            hermione.emit(hermione.events.SUITE_BEGIN, firefoxTree.suite);
            hermione.emit(hermione.events.SUITE_BEGIN, chromeTree.suite);
            hermione.emit(hermione.events.TEST_BEGIN, chromeTree.test);
            hermione.emit(hermione.events.TEST_BEGIN, firefoxTree.test);
            hermione.emit(hermione.events.TEST_PASS, chromeTree.test);
            hermione.emit(hermione.events.TEST_PASS, firefoxTree.test);
            hermione.emit(hermione.events.SUITE_END, chromeTree.suite);
            hermione.emit(hermione.events.SUITE_END, firefoxTree.suite);

            assert.lengthOf(suites, 2);
            suites.forEach(function(suite) {
                assert.lengthOf(suite.testcases, 1);
            });
        });

        it('should be attached to suite with proper browser with different status', function() {
            var firefoxTree = new Tree({browserId: 'firefox'})
                    .suite('suite')
                    .test('test')
                    .end(),
                chromeTree = new Tree({browserId: 'chrome'})
                    .suite('suite')
                    .test('test')
                    .end();

            hermione.emit(hermione.events.SUITE_BEGIN, firefoxTree.suite);
            hermione.emit(hermione.events.SUITE_BEGIN, chromeTree.suite);
            hermione.emit(hermione.events.TEST_BEGIN, chromeTree.test);
            hermione.emit(hermione.events.TEST_BEGIN, firefoxTree.test);
            hermione.emit(hermione.events.TEST_PASS, chromeTree.test);
            hermione.emit(hermione.events.TEST_FAIL, firefoxTree.test);
            hermione.emit(hermione.events.SUITE_END, chromeTree.suite);
            hermione.emit(hermione.events.SUITE_END, firefoxTree.suite);

            assert.lengthOf(suites, 2);
            assert.equal(suites[0].testcases[0].status, 'passed');
            assert.equal(suites[1].testcases[0].status, 'failed');
        });

        it('should not be attached to finished suite', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end()
                    .suite('otherSuite')
                    .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.otherSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.otherSuite);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);

            assert.lengthOf(suites, 1);
            assert.lengthOf(suites[0].testcases, 0);
        });

        it('should not be duplicated on calling TEST_BEGIN twice for one test', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);

            assert.lengthOf(suites, 1);
            assert.lengthOf(suites[0].testcases, 1);
            assert.equal(suites[0].testcases[0].name, 'someTest');
        });

        it('should not be duplicated on calling TEST_PASS twice for one test', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end();

            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);

            assert.lengthOf(suites, 1);
            assert.lengthOf(suites[0].testcases, 1);
            assert.equal(suites[0].testcases[0].name, 'someTest');
        });

        describe('pending', function() {
            var tree;

            beforeEach(function() {
                tree = new Tree()
                    .suite('topSuite')
                        .suite('middleSuite')
                            .test('someTest')
                            .end()
                        .end();
            });

            function emitPending_() {
                hermione.emit(hermione.events.SUITE_BEGIN, tree.topSuite);
                hermione.emit(hermione.events.TEST_PENDING, tree.someTest);
                hermione.emit(hermione.events.SUITE_END, tree.topSuite);
            }

            it('should save whole tree', function() {
                emitPending_();

                assert.lengthOf(suites, 1);
                assert.lengthOf(suites[0].testcases, 1);
                assert.equal(suites[0].name, 'topSuite');
                assert.equal(suites[0].testcases[0].name, 'middleSuite someTest');
                assert.equal(suites[0].testcases[0].status, 'pending');
            });

            it('should show skip reason', function() {
                tree.someTest.skipReason = 'some-reason';

                emitPending_();

                assert.equal(
                    suites[0].testcases[0].failure.message,
                    'Test ignored: some-reason'
                );
            });

            it('should show skip reason if it is set for whole suite', function() {
                tree.topSuite.skipReason = 'some-reason';

                emitPending_();

                assert.equal(
                    suites[0].testcases[0].failure.message,
                    'Test ignored: some-reason'
                );
            });

            it('should show default skip reason if no reason set', function() {
                emitPending_();

                assert.equal(
                    suites[0].testcases[0].failure.message,
                    'Test ignored: Unknown reason'
                );
            });

            it('should attach issue label if there is a link in skip reason', function() {
                tree.someTest.skipReason = 'Will be fixed in https://som.tracker/TASK-100500 asap';

                emitPending_();

                assert.deepEqual(
                    suites[0].testcases[0].labels[0],
                    {name: 'issue', value: 'https://som.tracker/TASK-100500'}
                );
            });
        });

        it('should add screenshot attachment to failed test', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end();

            tree.someTest.err = {screenshot: 'base64image='};
            sandbox.stub(writer, 'writeBuffer').returns('attachment.png');

            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_FAIL, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);

            var attachment = suites[0].testcases[0].attachments[0];

            assert.isOk(attachment);
            assert.equal(attachment.title, 'Screenshot');
            assert.equal(attachment.source, 'attachment.png');
            assert.equal(attachment.type, 'image/png');
        });

        it('should add meta info to failed test', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end();

            tree.someTest.meta = {
                url: '/some/url',
                foo: 'bar'
            };
            sandbox.stub(writer, 'writeBuffer').returns('attachment.png');

            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_FAIL, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);

            var params = suites[0].testcases[0].parameters;
            assert.includeDeepMembers(params, [
                {name: 'url', value: '/some/url', kind: 'environment-variable'},
                {name: 'foo', value: 'bar', kind: 'environment-variable'}
            ]);
        });

        it('should add meta info to passed test', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end();

            tree.someTest.meta = {
                url: '/some/url',
                foo: 'bar'
            };
            sandbox.stub(writer, 'writeBuffer').returns('attachment.png');

            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);

            var params = suites[0].testcases[0].parameters;
            assert.includeDeepMembers(params, [
                {name: 'url', value: '/some/url', kind: 'environment-variable'},
                {name: 'foo', value: 'bar', kind: 'environment-variable'}
            ]);
        });

        it('should add testId meta as a label', function() {
            var tree = new Tree()
                    .suite('someSuite')
                        .test('someTest')
                        .end();

            tree.someTest.meta = {
                testId: 'testcase-100500'
            };
            sandbox.stub(writer, 'writeBuffer').returns('attachment.png');

            hermione.emit(hermione.events.SUITE_BEGIN, tree.someSuite);
            hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
            hermione.emit(hermione.events.TEST_PASS, tree.someTest);
            hermione.emit(hermione.events.SUITE_END, tree.someSuite);

            assert.deepEqual(
                suites[0].testcases[0].labels[0],
                {name: 'testId', value: 'testcase-100500'}
            );

            assert.notInclude(
                suites[0].testcases[0].parameters,
                {name: 'testId', value: 'testcase-100500', kind: 'environment-variable'}
            );
        });
    });

    it('should unbend mocha tree structure', function() {
        var tree = new Tree()
                .suite('topSuite')
                    .suite('middleSuite')
                        .test('someTest')
                        .end()
                    .end();

        hermione.emit(hermione.events.SUITE_BEGIN, tree.topSuite);
        hermione.emit(hermione.events.TEST_BEGIN, tree.someTest);
        hermione.emit(hermione.events.TEST_PASS, tree.someTest);
        hermione.emit(hermione.events.SUITE_END, tree.topSuite);

        assert.lengthOf(suites, 1);
        assert.lengthOf(suites[0].testcases, 1);
        assert.equal(suites[0].name, 'topSuite');
        assert.equal(suites[0].testcases[0].name, 'middleSuite someTest');
    });
});


text:
'use strict';

var util = require('util'),
    _ = require('lodash');

var sensorDriver = require('../../index'),
    Sensor = sensorDriver.Sensor,
    logger = Sensor.getLogger();

var ble;

function SensorTagAcc(sensorInfo, options) {
  Sensor.call(this, sensorInfo, options);
  ble = sensorDriver.getNetwork('ble');
}

SensorTagAcc.properties = {
  supportedNetworks: ['ble'],
  dataTypes: ['accelerometer'],
  onChange: false, // FIXME: app.listen
  discoverable: true,
  addressable: false,
  recommendedInterval: 20000, // miliseconds
  validCachedValueTimeout: 7000,
  maxInstances: 1,
  models: ['sensorTagAcc'],
  ble: {
    service:'f000aa1004514000b000000000000000',
    config: 'f000aa1204514000b000000000000000',
    data:   'f000aa1104514000b000000000000000',
    period: 'f000aa1304514000b000000000000000'
  },
  bleLocalName: 'SensorTag',
  idTemplate: '{model}-{deviceAddress}',
  category: 'sensor'
};

util.inherits(SensorTagAcc, Sensor);

SensorTagAcc.prototype.readAccData = function(cb) {
  var service, dataChar, configChar;
  service = this.deviceHandle && this.deviceHandle.services &&
        _.find(this.deviceHandle.services, {uuid: SensorTagAcc.properties.ble.service});
  if (service && service.characteristics) {
    dataChar = _.find(service.characteristics, {uuid: SensorTagAcc.properties.ble.data});
    configChar = _.find(service.characteristics, {uuid: SensorTagAcc.properties.ble.config});
  }

  if (dataChar && configChar) {
    logger.debug('enable data');
    // to enable Characteristic
    configChar.write(new Buffer([0x01]), false, function () { // FIXME: config first time only, error handling(timeout)
      logger.debug('data read');
      dataChar.read(function (err, data) {
        if (!err && data) {
          var x = data.readInt8(0) * 4.0 / 256.0;
          var y = data.readInt8(1) * 4.0 / 256.0;
          var z = data.readInt8(2) * 4.0 / 256.0;
          var accelerometer = {x: x, y: y, z: z};
          logger.debug('accelerometer', accelerometer);
          return cb && cb(null, accelerometer);
        } else {
          return cb && cb(err);
        }
      });
    });
  } else {
    return cb && cb (new Error('service or characteristics not found'));
  }
};

SensorTagAcc.prototype._get = function () {
  var result = {},
      self = this,
      options;

  if (this.deviceHandle && this.deviceHandle.state === 'connected') {
    logger.debug('[SensorTagAcc] W/ deviceHandle', this.deviceHandle.state);
    this.readAccData(function (err, data) {
      if (err) {
        self.emit('data', {status: 'error', id : self.id, message: err || 'read error'});
      } else {
        result[_.first(SensorTagAcc.properties.dataTypes)] = data;
        self.emit('data', {status: 'ok', id: self.id, result: result});
      }
    });
  } else {
    logger.debug('getDevice', this.info);

    options = {
      model: this.model,
      serviceUUID: SensorTagAcc.properties.ble.service
    };

    ble.getDevice(this.info.device.address, options, function (err, device) {
      if (!err && device) {
        logger.debug('got device');

        self.deviceHandle = device.deviceHandle[self.info.id];

        self.readAccData(function (err, data) {
          if (err) {
            self.emit('data', {status: 'error', id : self.id, message: err || 'read error'});
          } else {
            result[_.first(SensorTagAcc.properties.dataTypes)] = data;
            self.emit('data', {status: 'ok', id : self.id, result: result});
          }
        });
      }
    });
  }
};

SensorTagAcc.prototype._clear = function () {
  logger.info('[SensorTagAcc] clearing ble sensor', this.info.id, this.deviceHandle);

  if (this.deviceHandle && typeof this.deviceHandle.disconnect) {
    this.deviceHandle.disconnect();
    delete this.deviceHandle;
  }
};

module.exports = SensorTagAcc;


text:
var $ = require('jquery');

module.exports = {
  fetchProducts: function(params){
    var options = {
      url: 'backend',
      data: params
    };
    return $.ajax(options);
  }
};


text:
import urlparse

from django import forms
from django.conf import settings

from .models import Report

class ReportForm(forms.ModelForm):

    def clean_url(self):
        if 'url' in self.cleaned_data:
            site_url = urlparse.urlparse(settings.SITE_URL)
            parsed = urlparse.urlparse(self.cleaned_data['url'])
            if site_url.netloc == parsed.netloc:
                return self.cleaned_data['url']
        raise forms.ValidationError('This is an invalid URL')

    class Meta:
        model = Report
        fields = ('url', 'description')


text:
function [Mobj] = read_gmsh_mesh(varargin)
% Read gmsh mesh files (version 2.2) into MATLAB mesh object.
%
% Mobj = function read_fvcom_mesh(varargin)
%
% DESCRIPTION:
%    Read gmsh msh file and bathymetry file. Store in a matlab mesh object.
%
% INPUT [keyword pairs]:
%   'msh'                   = gmsh msh file [e.g. casename.msh]
%   [optional] 'bath'       = gmsh bathymetry file [e.g. tst_dep.dat]
%   [optional] 'coordinate' = coordinate system [spherical; cartesian (default)]
%   [optional] 'addCoriolis' = calculate Coriolis param (f), requires [lon, lat]
%
% OUTPUT:
%    Mobj = MATLAB structure containing mesh data
%
% EXAMPLE USAGE
%    Mobj = read_gmsh_mesh('msh', 'casename.msh', 'bath', 'bathy.dat')
%
% Author(s):
%    Pierre Cazenave (Plymouth Marine Laboratory)
%
% Revision history
%
%   2014-02-07 First version.
%
%==============================================================================

subname = 'read_gmsh_mesh';
global ftbverbose
if ftbverbose
    fprintf('\nbegin : %s \n', subname)
end

have_bath = false;
have_strings = false;

%--------------------------------------------------------------------------
% Create a blank mesh object
%--------------------------------------------------------------------------
Mobj = make_blank_mesh;
coordinate = 'cartesian';

%--------------------------------------------------------------------------
% Parse input arguments
%--------------------------------------------------------------------------

assert(mod(length(varargin), 2) == 0, 'incorrect usage of read_gmsh_mesh, use keyword pairs')

% Assume we have nothing sensible.
have_msh = false;
have_bath = false;
have_lonlat = false;
have_xy = false;

for i = 1:2:length(varargin) - 1
    keyword = lower(varargin{i});

    assert(ischar(keyword), 'incorrect usage of read_gmsh_mesh')

    switch keyword
        case 'msh'
            gmsh_msh = varargin{i + 1};
            have_msh = true;
        case 'bath'
            gmsh_bath = varargin{i + 1};
            have_bath = true;
        case 'coordinate'
            coord = varargin{i + 1};
            if strcmpi(coord, 'spherical')
                coordinate = 'spherical';
                have_lonlat = true;
            elseif strcmpi(coord, 'cartesian')
                coordinate = 'cartesian';
                have_xy = true;
            else
                warning('Unrecognised coordinate system (%s). Valid values are ''spherical'' and ''cartesian''.', coordinate)
            end
        case 'addcoriolis'
            val = varargin{i + 1};
            if val
                addCoriolis = true;
            else
                addCoriolis = false;
            end
        otherwise
            disp(varargin{i + 1})
            error('Can''t understand property: %s', varargin{i + 1});

    end
end

%--------------------------------------------------------------------------
% Read the mesh from the msh file
%--------------------------------------------------------------------------

fid = fopen(gmsh_msh, 'rt');
assert(fid >= 0, sprintf('file: %s does not exist\n',  gmsh_msh));

% Count number of elements and vertices
if ftbverbose
    fprintf('Reading from: %s\n', gmsh_msh)
end

% Read mesh type, taken from:
%
% http://www.geuz.org/pipermail/gmsh/attachments/20071002/642cb6c3/attachment.m
%

lin = fgetl(fid);
if strcmp(lin, '$NOD')
    fileformat = 1;
elseif strcmp(lin, '$MeshFormat')
    fileformat = 2;
    lin = fgetl(fid);
    if feof(fid)
        fprintf(sprintf('Syntax error (no version) in: %s\n', filename));
        fileformat = 0;
    end
    form = sscanf(lin, '%f %d %d');
    if form(1) < 2
        fprintf(sprintf('Unknown mesh format: %s\n', lin));
        fileformat = 0;
    end
    if form(2) ~= 0
        fprintf('Sorry, this program can only read ASCII format\n');
        fileformat = 0;
    end
    fgetl(fid); % this should be $EndMeshFormat
    if feof(fid)
        fprintf('Syntax error (no $EndMeshFormat) in: %s\n', filename);
        fileformat = 0;
    end
    lin = fgetl(fid); % this should be $Nodes
    if feof(fid)
        fprintf('Syntax error (no $Nodes) in: %s\n', filename);
        fileformat = 0;
    end
end

assert(logical(fileformat), 'Unrecognised mesh.')
% Read in the number of nodes
nVerts = str2double(fgetl(fid));

% Read the node positions.
C = textscan(fid, '%d %f %f %f', nVerts);
nid = C{1};
x = C{2};
y = C{3};
z = C{4};

if have_lonlat
    lon = x;
    lat = y;
else
    lon = zeros(size(x));
    lat = zeros(size(y));
end

% Now we should be at the end of the nodes and about to read the elements.
lin = fgetl(fid); lin = fgetl(fid); % need to skip one for some reason.
assert(strcmp(lin, '$EndNodes'), 'Improperly formatted msh file.')
lin = fgetl(fid);
assert(strcmp(lin, '$Elements'), 'Improperly formatted msh file.')
nElems = str2double(fgetl(fid));

% Preallocate some arrays of use. We'll trim the NaNs later.
tri12 = nan(nElems, 3);

% Read the element triangulation table. Format is:
%   ID, dim, n1, n2, n3[, n4]
% If dim is 1, then n4 is omitted, otherwise if dim is 2, then we have an
% extra link.
c1 = 1;
c2 = 1;
for i = 1:nElems
    lin = fgetl(fid);
    C = regexpi(lin, ' ', 'split');
    if str2double(C(2)) == 1
        tri12(c1, :) = str2double(C(end-2:end));
        c1 = c1 + 1;
    elseif str2double(C(2)) == 2
        tri12(c2, :) = str2double(C(end-2:end));
        c2 = c2 + 1;
%         else
%             warning('Unsupported number of dimensions (up to 2).')
    end
end
tri1 = tri12(1:c1, :);
tri2 = tri12(c1 + 1:c1 + c2, :);

% Trim the excess NaNs
tri2 = tri2(~isnan(tri2(:, 1)), :);

% Reset the number of elements to the actual number of 2D ones.
nElems = size(tri2, 1);

have_lonlat = false;
have_xy     = false;
if strcmpi(coordinate, 'spherical')
    lon = x;
    lat = y;
    % Why reset everything to zero here?
    %x = x * 0.0;
    %y = y * 0.0;
    have_lonlat = true;
    % Just do a double check on the coordinates to make sure we don't
    % actually have cartesian
    if max(lon) > 360
        warning('You''ve specified spherical coordinates, but your upper longitude value exceeds 360 degrees. Are you sure you have spherical data?')
    end
elseif strcmpi(coordinate, 'cartesian')
    have_xy = true;
else
    warning('Unrecognised coordinate system (%s). Valid values are ''spherical'' and ''cartesian''.', coordinate)
end

fclose(fid);

%--------------------------------------------------------------------------
% Read the topography from the bathymetry file
%--------------------------------------------------------------------------

if have_bath
    bath_range = max(h) - min(h);
    if have_bath || bath_range == 0
        fid = fopen(gmsh_bath, 'rt');
        if fid < 0
            error('File: %s does not exist', gmsh_bath);
        else
            if ftbverbose; fprintf('reading gmsh bathymetry from: %s\n', gmsh_bath); end
        end
        lin = fgetl(fid);
        lin = fgetl(fid);
        lin = fgetl(fid);
        C = textscan(fid, '%s %d', 1);
        nVerts_tmp = C{2};
        C = textscan(fid, '%s %d', 1);
        nElems_tmp = C{2};
        if (nVerts - nVerts_tmp) * (nElems - nElems_tmp) ~= 0
            fprintf('Dimensions of bathymetry file do not match msh file\n')
            fprintf('Bathymetry nVerts: %d\n', nVerts_tmp)
            fprintf('Bathymetry nElems: %d\n', nElems_tmp)
            error('Stopping...')
        end
        lin = fgetl(fid);
        lin = fgetl(fid);
        lin = fgetl(fid);
        lin = fgetl(fid); % extra one for the new format from SMS 10.1, I think
        C2 = textscan(fid, '%f', nVerts);
        h = C2{1};
        have_bath = true;

        clear C2
    elseif bath_range ~= 0
        have_bath = true;
    end

    % Make sure we have positive depths
    if sum(h > 0) < sum(h < 0)
        h = -h;
    end
end

%--------------------------------------------------------------------------
% Transfer to Mesh structure
%--------------------------------------------------------------------------

Mobj.nVerts  = nVerts;
Mobj.nElems  = nElems;
Mobj.nativeCoords = coordinate;

if have_lonlat
    Mobj.have_lonlat    = have_lonlat;
end
if have_xy
    Mobj.have_xy        = have_xy;
end
if have_bath
    Mobj.have_bath      = have_bath;
    Mobj.h              = h;
end
if have_strings
    Mobj.have_strings   = have_strings;
    Mobj.read_obc_nodes = read_obc_nodes;
end
if exist('addCoriolis', 'var') && addCoriolis
    Mobj.have_cor       = true;
end

Mobj.x            = x;
Mobj.y            = y;
Mobj.z            = z; % for 3D grids
Mobj.lon          = lon;
Mobj.lat          = lat;
Mobj.tri          = tri2;

if ftbverbose
  fprintf('end   : %s\n', subname)
end


text:
+++
date = "2017-07-05T17:30:36+02:00"
draft = false
title = "Finding vector perpendicular to another vector"
tags = ['3D', 'math']
useTex = true
+++

Hello, in this post I will present solution for math problem I stumbled upon
recently. The task was given as follows:

> Given arbitrary 3D vector from 3D space find any vector that is perpendicular to
> it. Note that there is infinite number of vectors perpendicular to given one.

At first glance the task seems to be very difficult. Let's write some
mathematical equations to help us find solution.

<!--more-->

## Dot product
First of all we will remind ourselves about dot product operator defined for
vectors. Given any two vectors \\( \vec{A} \\) and \\( \vec{B} \\) we define dot product
as following equation:

$$\vec{A} \cdot \vec{B} = \sum_{i = 1}^N \vec{A}_i * \vec{B}_i$$

Where \\( \vec{A}_i \\) and \\( \vec{B}_i \\) are \\( i \\) -th components of
\\( N \\) dimensional
vectors. As we can see dot product is only defined for vectors that are the same
size. In other words we can't compute dot product for pair of 2D and 3D vector directly.

### Angle between vectors
Using dot product we can compute angle between vectors. Let's write formula
that will allow us to make this calculation:

$$\vec{A} \cdot \vec{B} = ||\vec{A}|| * ||\vec{B}|| * \cos(\theta)$$

so the angle \\( \theta \\) is given by
$$\theta = \cos^{-1}\left(\frac{\vec{A} \cdot \vec{B}}{||\vec{A}|| * ||\vec{B}||}\right)$$

### Perpendicular vectors
If vectors have to be perpendicular to each other the angle between them needs to be equal
\\( 90^\circ \\) (\\( \frac{\pi}{4} \\)).

We know that:
$$\cos(\frac{\pi}{4}) = 0$$

So let's insert it into out previous equation:
$$\vec{A} \cdot \vec{B} = ||\vec{A}|| * ||\vec{B}|| * \cos(\frac{\pi}{4})$$
$$\vec{A} \cdot \vec{B} = ||\vec{A}|| * ||\vec{B}|| * 0$$

Which leads us to following very important formula:
$$\vec{A} \cdot \vec{B} = 0$$

It is only true when both \\( \vec{A} \\) and \\( \vec{B} \\) have length not equal
to \\( 0 \\). This equation tells us that if vectors will satisfy it,
then angle between them is equal to \\( 90^\circ \\) (\\( \frac{\pi}{4} \\)).

## 2D example
Let's suppose we have vector \\( \vec{A} = (A_x, A_y) \\) and we want to find vector that is
perpendicular to it. Starting with formula:
$$\vec{A} \cdot \vec{U} = 0$$

we set up our unknown vector to \\( \vec{U} = (U_x, U_y) \\)

By inserting vectors to equation:
$$\vec{A} \cdot \vec{B} = \sum_{i = 1}^N \vec{A}_i * \vec{B}_i$$

we get:
$$\vec{A} \cdot \vec{U} = \vec{A}_x * \vec{U}_x + \vec{A}_y * \vec{U}_y$$

so it lead us to:
$$\vec{A}_x * \vec{U}_x + \vec{A}_y * \vec{U}_y = 0$$

Right now it is obvious that this equation have more than one solution. Having in mind that any
of perpendicular vectors that we can find will be correct solution - let's use some assumption. If we
arbitrarily set \\( \vec{U}_x = 1 \\) then our equation will turn into:
$$\vec{A}_x + \vec{A}_y * \vec{U}_y = 0$$

so:
$$\vec{U}_y = - \left(\frac{\vec{A}_x}{\vec{A}_y}\right)$$

and the whole solution will turn to be:
$$\vec{U} = \left(1, -\left(\frac{\vec{A}_x}{\vec{A}_y}\right)\right)$$

But what to do if \\( \vec{A}_y = 0 \\) ?

Then you need to set \\( \vec{U}_y = 1 \\) and follow previous steps which will lead us to:

$$\vec{U} = \left(-\left(\frac{\vec{A}_y}{\vec{A}_x}\right), 1\right)$$

If both \\( \vec{A}_x \\) and \\( \vec{A}_y \\) are equal to \\( 0 \\) then we can't find perpendicular vector
because \\( \vec{A} \\) has a length of \\( 0 \\).

## 3D example
After showing 2D example 3D one will be more understandable. Now let's suppose we have vector
\\( \vec{A} = (A_x, A_y, A_z) \\) and we want to find vector that is perpendicular to it.
Let's state that unknown vector is \\( \vec{U} = (U_x, U_y, U_z) \\).

We write dot product formula:
$$\vec{A} \cdot \vec{U} = \vec{A}_x * \vec{U}_x + \vec{A}_y * \vec{U}_y + \vec{A_z} * \vec{U}_z$$

And use property:
$$\vec{A} \cdot \vec{U} = 0$$

so:
$$\vec{A}_x * \vec{U}_x + \vec{A}_y * \vec{U}_y + \vec{A_z} * \vec{U}_z = 0$$

Now we use similar assumption to one used in 2D case. Suppose that \\( \vec{U}_x = 1 \\). This will
reduce out equation to
$$\vec{A}_x + \vec{A}_y * \vec{U}_y + \vec{A_z} * \vec{U}_z = 0$$

which is very similar to 2D equation. Now we suppose also that \\( \vec{U}_y = 1 \\) and we get
$$\vec{A}_x + \vec{A}_y + \vec{A_z} * \vec{U}_z = 0$$

So solution is
$$\vec{U} = \left(1, 1, -\left(\frac{\vec{A}_x +
            \vec{A}_y}{\vec{A}_z}\right)\right)$$

But only if \\( \vec{A}_z \\) is not equal \\( 0 \\). If that is not the case then you need to choose
another component of \\( \vec{U} \\) and set it arbitrarily to \\( 1 \\).

## Final python example code
To sum up I prepared simple Python method that will compute vector perpendicular to another for 3D
case. It can be easily inserted into existing implementation of vector class.
{{< highlight python >}}
class Vector:
    def __init__(self, x, y, z):
        self.x = x
        self.y = y
        self.z = z

    def give_perpendicular_vector(self):
        if self.x != 0:
            return Vector(-(self.y + self.z)/self.x, 1, 1)
        if self.y != 0:
            return Vector(1, -(self.x + self.z)/self.y, 1)
        if self.z != 0:
            return Vector(1, 1, -(self.x + self.y)/self.z)

        raise ValueError("Can't compute perpendicular vector")
{{< / highlight >}}

## References
- http://tutorial.math.lamar.edu/Classes/CalcII/DotProduct.aspx
- https://math.stackexchange.com/questions/133177/finding-a-unit-vector-perpendicular-to-another-vector


text:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace customwidget {
    class MainWindow;
}

class customwidget::MainWindow : public QMainWindow
{
    public:
        MainWindow(QWidget* parent = 0);
};

#endif


text:
'use strict';

jest
  .autoMockOff()
  .setMock('Text', {})
  .setMock('View', {})
  .setMock('Image', {})
  .setMock('React', {Component: class {}});

var Animated = require('Animated');

describe('Animated', () => {
  it('works end to end', () => {
    var anim = new Animated.Value(0);

    var callback = jest.genMockFunction();

    var node = new Animated.__PropsOnlyForTests({
      style: {
        backgroundColor: 'red',
        opacity: anim,
        transform: [
          {translateX: anim.interpolate({
            inputRange: [0, 1],
            outputRange: [100, 200],
          })},
          {scale: anim},
        ]
      }
    }, callback);

    expect(anim.__getChildren().length).toBe(3);

    expect(node.__getValue()).toEqual({
      style: {
        backgroundColor: 'red',
        opacity: 0,
        transform: [
          {translateX: 100},
          {scale: 0},
        ],
      },
    });

    anim.setValue(0.5);

    expect(callback).toBeCalled();

    expect(node.__getValue()).toEqual({
      style: {
        backgroundColor: 'red',
        opacity: 0.5,
        transform: [
          {translateX: 150},
          {scale: 0.5},
        ],
      },
    });

    node.__detach();
    expect(anim.__getChildren().length).toBe(0);

    anim.setValue(1);
    expect(callback.mock.calls.length).toBe(1);
  });

  it('does not detach on updates', () => {
    var anim = new Animated.Value(0);
    anim.__detach = jest.genMockFunction();

    var c = new Animated.View();
    c.props = {
      style: {
        opacity: anim,
      },
    };
    c.componentWillMount();

    expect(anim.__detach).not.toBeCalled();
    c.componentWillReceiveProps({
      style: {
        opacity: anim,
      },
    });
    expect(anim.__detach).not.toBeCalled();

    c.componentWillUnmount();
    expect(anim.__detach).toBeCalled();
  });

  it('stops animation when detached', () => {
    // jest environment doesn't have cancelAnimationFrame :(
    if (!window.cancelAnimationFrame) {
      window.cancelAnimationFrame = jest.genMockFunction();
    }

    var anim = new Animated.Value(0);
    var callback = jest.genMockFunction();

    var c = new Animated.View();
    c.props = {
      style: {
        opacity: anim,
      },
    };
    c.componentWillMount();

    Animated.timing(anim, {toValue: 10, duration: 1000}).start(callback);

    c.componentWillUnmount();

    expect(callback).toBeCalledWith({finished: false});
    expect(callback).toBeCalledWith({finished: false});
  });

  it('triggers callback when spring is at rest', () => {
    var anim = new Animated.Value(0);
    var callback = jest.genMockFunction();
    Animated.spring(anim, {toValue: 0, velocity: 0}).start(callback);
    expect(callback).toBeCalled();
  });

  it('send toValue when a spring stops', () => {
    var anim = new Animated.Value(0);
    var listener = jest.genMockFunction();
    anim.addListener(listener);
    Animated.spring(anim, {toValue: 15}).start();
    jest.runAllTimers();
    var lastValue = listener.mock.calls[listener.mock.calls.length - 2][0].value;
    expect(lastValue).not.toBe(15);
    expect(lastValue).toBeCloseTo(15);
    expect(anim.__getValue()).toBe(15);
  });

});

describe('Animated Sequence', () => {

  it('works with an empty sequence', () => {
    var cb = jest.genMockFunction();
    Animated.sequence([]).start(cb);
    expect(cb).toBeCalledWith({finished: true});
  });

  it('sequences well', () => {
    var anim1 = {start: jest.genMockFunction()};
    var anim2 = {start: jest.genMockFunction()};
    var cb = jest.genMockFunction();

    var seq = Animated.sequence([anim1, anim2]);

    expect(anim1.start).not.toBeCalled();
    expect(anim2.start).not.toBeCalled();

    seq.start(cb);

    expect(anim1.start).toBeCalled();
    expect(anim2.start).not.toBeCalled();
    expect(cb).not.toBeCalled();

    anim1.start.mock.calls[0][0]({finished: true});

    expect(anim2.start).toBeCalled();
    expect(cb).not.toBeCalled();

    anim2.start.mock.calls[0][0]({finished: true});
    expect(cb).toBeCalledWith({finished: true});
  });

  it('supports interrupting sequence', () => {
    var anim1 = {start: jest.genMockFunction()};
    var anim2 = {start: jest.genMockFunction()};
    var cb = jest.genMockFunction();

    Animated.sequence([anim1, anim2]).start(cb);

    anim1.start.mock.calls[0][0]({finished: false});

    expect(anim1.start).toBeCalled();
    expect(anim2.start).not.toBeCalled();
    expect(cb).toBeCalledWith({finished: false});
  });

  it('supports stopping sequence', () => {
    var anim1 = {start: jest.genMockFunction(), stop: jest.genMockFunction()};
    var anim2 = {start: jest.genMockFunction(), stop: jest.genMockFunction()};
    var cb = jest.genMockFunction();

    var seq = Animated.sequence([anim1, anim2]);
    seq.start(cb);
    seq.stop();

    expect(anim1.stop).toBeCalled();
    expect(anim2.stop).not.toBeCalled();
    expect(cb).not.toBeCalled();

    anim1.start.mock.calls[0][0]({finished: false});

    expect(cb).toBeCalledWith({finished: false});
  });
});

describe('Animated Parallel', () => {

  it('works with an empty parallel', () => {
    var cb = jest.genMockFunction();
    Animated.parallel([]).start(cb);
    expect(cb).toBeCalledWith({finished: true});
  });

  it('works with an empty element in array', () => {
    var anim1 = {start: jest.genMockFunction()};
    var cb = jest.genMockFunction();
    Animated.parallel([null, anim1]).start(cb);

    expect(anim1.start).toBeCalled();
    anim1.start.mock.calls[0][0]({finished: true});

    expect(cb).toBeCalledWith({finished: true});
  });

  it('parellelizes well', () => {
    var anim1 = {start: jest.genMockFunction()};
    var anim2 = {start: jest.genMockFunction()};
    var cb = jest.genMockFunction();

    var par = Animated.parallel([anim1, anim2]);

    expect(anim1.start).not.toBeCalled();
    expect(anim2.start).not.toBeCalled();

    par.start(cb);

    expect(anim1.start).toBeCalled();
    expect(anim2.start).toBeCalled();
    expect(cb).not.toBeCalled();

    anim1.start.mock.calls[0][0]({finished: true});
    expect(cb).not.toBeCalled();

    anim2.start.mock.calls[0][0]({finished: true});
    expect(cb).toBeCalledWith({finished: true});
  });

  it('supports stopping parallel', () => {
    var anim1 = {start: jest.genMockFunction(), stop: jest.genMockFunction()};
    var anim2 = {start: jest.genMockFunction(), stop: jest.genMockFunction()};
    var cb = jest.genMockFunction();

    var seq = Animated.parallel([anim1, anim2]);
    seq.start(cb);
    seq.stop();

    expect(anim1.stop).toBeCalled();
    expect(anim2.stop).toBeCalled();
    expect(cb).not.toBeCalled();

    anim1.start.mock.calls[0][0]({finished: false});
    expect(cb).not.toBeCalled();

    anim2.start.mock.calls[0][0]({finished: false});
    expect(cb).toBeCalledWith({finished: false});
  });

  it('does not call stop more than once when stopping', () => {
    var anim1 = {start: jest.genMockFunction(), stop: jest.genMockFunction()};
    var anim2 = {start: jest.genMockFunction(), stop: jest.genMockFunction()};
    var anim3 = {start: jest.genMockFunction(), stop: jest.genMockFunction()};
    var cb = jest.genMockFunction();

    var seq = Animated.parallel([anim1, anim2, anim3]);
    seq.start(cb);

    anim1.start.mock.calls[0][0]({finished: false});

    expect(anim1.stop.mock.calls.length).toBe(0);
    expect(anim2.stop.mock.calls.length).toBe(1);
    expect(anim3.stop.mock.calls.length).toBe(1);

    anim2.start.mock.calls[0][0]({finished: false});

    expect(anim1.stop.mock.calls.length).toBe(0);
    expect(anim2.stop.mock.calls.length).toBe(1);
    expect(anim3.stop.mock.calls.length).toBe(1);

    anim3.start.mock.calls[0][0]({finished: false});

    expect(anim1.stop.mock.calls.length).toBe(0);
    expect(anim2.stop.mock.calls.length).toBe(1);
    expect(anim3.stop.mock.calls.length).toBe(1);
  });
});

describe('Animated delays', () => {
  it('should call anim after delay in sequence', () => {
    var anim = {start: jest.genMockFunction(), stop: jest.genMockFunction()};
    var cb = jest.genMockFunction();
    Animated.sequence([
      Animated.delay(1000),
      anim,
    ]).start(cb);
    jest.runAllTimers();
    expect(anim.start.mock.calls.length).toBe(1);
    expect(cb).not.toBeCalled();
    anim.start.mock.calls[0][0]({finished: true});
    expect(cb).toBeCalledWith({finished: true});
  });
  it('should run stagger to end', () => {
    var cb = jest.genMockFunction();
    Animated.stagger(1000, [
      Animated.delay(1000),
      Animated.delay(1000),
      Animated.delay(1000),
    ]).start(cb);
    jest.runAllTimers();
    expect(cb).toBeCalledWith({finished: true});
  });
});

describe('Animated Events', () => {
  it('should map events', () => {
    var value = new Animated.Value(0);
    var handler = Animated.event(
      [null, {state: {foo: value}}],
    );
    handler({bar: 'ignoreBar'}, {state: {baz: 'ignoreBaz', foo: 42}});
    expect(value.__getValue()).toBe(42);
  });
  it('should call listeners', () => {
    var value = new Animated.Value(0);
    var listener = jest.genMockFunction();
    var handler = Animated.event(
      [{foo: value}],
      {listener},
    );
    handler({foo: 42});
    expect(value.__getValue()).toBe(42);
    expect(listener.mock.calls.length).toBe(1);
    expect(listener).toBeCalledWith({foo: 42});
  });
});

describe('Animated Tracking', () => {
  it('should track values', () => {
    var value1 = new Animated.Value(0);
    var value2 = new Animated.Value(0);
    Animated.timing(value2, {
      toValue: value1,
      duration: 0,
    }).start();
    value1.setValue(42);
    expect(value2.__getValue()).toBe(42);
    value1.setValue(7);
    expect(value2.__getValue()).toBe(7);
  });

  it('should track interpolated values', () => {
    var value1 = new Animated.Value(0);
    var value2 = new Animated.Value(0);
    Animated.timing(value2, {
      toValue: value1.interpolate({
        inputRange: [0, 2],
        outputRange: [0, 1]
      }),
      duration: 0,
    }).start();
    value1.setValue(42);
    expect(value2.__getValue()).toBe(42 / 2);
  });

  it('should stop tracking when animated', () => {
    var value1 = new Animated.Value(0);
    var value2 = new Animated.Value(0);
    Animated.timing(value2, {
      toValue: value1,
      duration: 0,
    }).start();
    value1.setValue(42);
    expect(value2.__getValue()).toBe(42);
    Animated.timing(value2, {
      toValue: 7,
      duration: 0,
    }).start();
    value1.setValue(1492);
    expect(value2.__getValue()).toBe(7);
  });
});

describe('Animated Vectors', () => {
  it('should animate vectors', () => {
    var vec = new Animated.ValueXY();

    var callback = jest.genMockFunction();

    var node = new Animated.__PropsOnlyForTests({
      style: {
        opacity: vec.x.interpolate({
          inputRange: [0, 42],
          outputRange: [0.2, 0.8],
        }),
        transform: vec.getTranslateTransform(),
        ...vec.getLayout(),
      }
    }, callback);

    expect(node.__getValue()).toEqual({
      style: {
        opacity: 0.2,
        transform: [
          {translateX: 0},
          {translateY: 0},
        ],
        left: 0,
        top: 0,
      },
    });

    vec.setValue({x: 42, y: 1492});

    expect(callback.mock.calls.length).toBe(2); // once each for x, y

    expect(node.__getValue()).toEqual({
      style: {
        opacity: 0.8,
        transform: [
          {translateX: 42},
          {translateY: 1492},
        ],
        left: 42,
        top: 1492,
      },
    });

    node.__detach();

    vec.setValue({x: 1, y: 1});
    expect(callback.mock.calls.length).toBe(2);
  });

  it('should track vectors', () => {
    var value1 = new Animated.ValueXY();
    var value2 = new Animated.ValueXY();
    Animated.timing(value2, {
      toValue: value1,
      duration: 0,
    }).start();
    value1.setValue({x: 42, y: 1492});
    expect(value2.__getValue()).toEqual({x: 42, y: 1492});

    // Make sure tracking keeps working (see stopTogether in ParallelConfig used
    // by maybeVectorAnim).
    value1.setValue({x: 3, y: 4});
    expect(value2.__getValue()).toEqual({x: 3, y: 4});
  });

  it('should track with springs', () => {
    var value1 = new Animated.ValueXY();
    var value2 = new Animated.ValueXY();
    Animated.spring(value2, {
      toValue: value1,
      tension: 3000, // faster spring for faster test
      friction: 60,
    }).start();
    value1.setValue({x: 1, y: 1});
    jest.runAllTimers();
    expect(Math.round(value2.__getValue().x)).toEqual(1);
    expect(Math.round(value2.__getValue().y)).toEqual(1);
    value1.setValue({x: 2, y: 2});
    jest.runAllTimers();
    expect(Math.round(value2.__getValue().x)).toEqual(2);
    expect(Math.round(value2.__getValue().y)).toEqual(2);
  });
});

describe('Animated Listeners', () => {
  it('should get updates', () => {
    var value1 = new Animated.Value(0);
    var listener = jest.genMockFunction();
    var id = value1.addListener(listener);
    value1.setValue(42);
    expect(listener.mock.calls.length).toBe(1);
    expect(listener).toBeCalledWith({value: 42});
    expect(value1.__getValue()).toBe(42);
    value1.setValue(7);
    expect(listener.mock.calls.length).toBe(2);
    expect(listener).toBeCalledWith({value: 7});
    expect(value1.__getValue()).toBe(7);
    value1.removeListener(id);
    value1.setValue(1492);
    expect(listener.mock.calls.length).toBe(2);
    expect(value1.__getValue()).toBe(1492);
  });

  it('should removeAll', () => {
    var value1 = new Animated.Value(0);
    var listener = jest.genMockFunction();
    [1,2,3,4].forEach(() => value1.addListener(listener));
    value1.setValue(42);
    expect(listener.mock.calls.length).toBe(4);
    expect(listener).toBeCalledWith({value: 42});
    value1.removeAllListeners();
    value1.setValue(7);
    expect(listener.mock.calls.length).toBe(4);
  });
});