text:
`master` [![Build Status](http://54.222.242.222:1010/buildStatus/icon?job=TensorGraph/master)](http://54.222.242.222:1010/job/TensorGraph/master)
`develop` [![Build Status](http://54.222.242.222:1010/buildStatus/icon?job=TensorGraph/develop)](http://54.222.242.222:1010/job/TensorGraph/develop)

# TensorGraph
TensorGraph is a simple, lean, and clean framework on TensorFlow for building any imaginable models.

As deep learning becomes more and more common and the architectures becoming more
and more complicated, it seems that we need some easy to use framework to quickly
build these models and that's what TensorGraph is designed for. It's a very simple
framework that adds a very thin layer above tensorflow. It is for more advanced
users who want to have more control and flexibility over his model building and
who wants efficiency at the same time.

-----
## Target Audience
TensorGraph is targeted more at intermediate to advance users who feel keras or
other packages is having too much restrictions and too much black box on model
building, and someone who don't want to rewrite the standard layers in tensorflow
constantly. Also for enterprise users who want to share deep learning models
easily between teams.

-----
## Install

First you need to install [tensorflow](https://www.tensorflow.org/versions/r0.9/get_started/os_setup.html)

To install tensorgraph for bleeding edge version via pip
```bash
sudo pip install --upgrade git+https://github.com/hycis/TensorGraph.git@master
```
or simply clone and add to `PYTHONPATH`.
```bash
git clone https://github.com/hycis/TensorGraph.git
export PYTHONPATH=/path/to/TensorGraph:$PYTHONPATH
```
in order for the install to persist via export `PYTHONPATH`. Add `PYTHONPATH=/path/to/TensorGraph:$PYTHONPATH` to your `.bashrc` for linux or
`.bash_profile` for mac. While this method works, you will have to ensure that
all the dependencies in [setup.py](setup.py) are installed.

-----
## Everything in TensorGraph is about Layers
Everything in TensorGraph is about layers. A model such as VGG or Resnet can be a layer. An identity block from Resnet or a dense block from Densenet can be a layer as well. Building models in TensorGraph is same as building a toy with lego. For example you can create a new model (layer) by subclass the `BaseModel` layer and use `DenseBlock` layer inside your `ModelA` layer.

```python
from tensorgraph.layers import DenseBlock, BaseModel, Flatten, Linear, Softmax
import tensorgraph as tg
class ModelA(BaseModel):
    @BaseModel.init_name_scope
    def __init__(self):
        layers = []
        layers.append(DenseBlock())
        layers.append(Flatten())
        layers.append(Linear())
        layers.append(Softmax())
        self.startnode = tg.StartNode(input_vars=[None])
        hn = tg.HiddenNode(prev=[self.startnode], layers=layers)
        self.endnode = tg.EndNode(prev=[hn])
```

if someone wants to use your `ModelA` in his `ModelB`, he can easily do this
```python
class ModelB(BaseModel):
    @BaseModel.init_name_scope
    def __int__(self):
        layers = []
        layers.append(ModelA())
        layers.append(Linear())
        layers.append(Softmax())
        self.startnode = tg.StartNode(input_vars=[None])
        hn = tg.HiddenNode(prev=[self.startnode], layers=layers)
        self.endnode = tg.EndNode(prev=[hn])
```

creating a layer only created all the `Variables`. To connect the `Variables` into a graph, you can do a `train_fprop(X)` or `test_fprop(X)` to create the tensorflow graph. By abstracting `Variable` creation away from linking the `Variable` nodes into graph prevent the problem of certain tensorflow layers that always reinitialise its weights when it's called, example the [`tf.nn.batch_normalization`](https://www.tensorflow.org/api_docs/python/tf/nn/batch_normalization) layer. Also having a separate channel for training and testing is to cater to layers with different training and testing behaviours such as batchnorm and dropout.

```python
modelb = ModelB()
X_ph = tf.placeholder()
y_train = modelb.train_fprop(X_ph)
y_test = modelb.test_fprop(X_ph)
```

checkout some well known models in TensorGraph
1. [VGG16 code](tensorgraph/layers/backbones.py#L37) and [VGG19 code](tensorgraph/layers/backbones.py#L125) - [Very Deep Convolutional Networks for Large-Scale Image Recognition](https://arxiv.org/abs/1409.1556)
2. [DenseNet code](tensorgraph/layers/backbones.py#L477) - [Densely Connected Convolutional Networks](https://arxiv.org/abs/1608.06993)
3. [ResNet code](tensorgraph/layers/backbones.py#L225) - [Deep Residual Learning for Image Recognition](https://arxiv.org/abs/1512.03385)
4. [Unet code](tensorgraph/layers/backbones.py#L531) - [U-Net: Convolutional Networks for Biomedical Image Segmentation](https://arxiv.org/abs/1505.04597)

-----
## Type of Layers
There are three types of layers, `BaseLayer`, `BaseModel` and `Merge`.

### BaseLayer
`BaseLayer` is a low lying layer that wraps tensorflow codes directly, and define
the low level operations that we want the tensorflow to perform within a layer.
When implementing `BaseLayer` we need to implement `_train_fprop()` and `_test_fprop()`,
by default `_test_fprop()` calls `_train_fprop()`.

```python
class MyLayer(BaseLayer):

    @BaseLayer.init_name_scope
    def __init__(self):
        ''' place all your variables and variables initialization here. '''
        pass

    @BaseLayer.init_name_scope
    def __init_var__(self, state_below):
        '''Define variables which requires input information from state_below,
           this is called during forward propagation
        '''
        pass

    def _train_fprop(self, state_below):
        '''
        your tensorflow operations for training,
        do not initialize variables here.
        '''
        pass

    def _test_fprop(self, state_below):
        '''
        your tensorflow operations for testing, do not initialize variables
        here. Defaults to _train_fprop.
        '''
        pass
```

To use `BaseLayer`, we can initialize the `Variables` inside ```__init__``` and/or
```__init_var__(self, state_below)``` if our layer requires information from the
layer below.

### BaseModel
`BaseModel` is a higher level layer that can be made up of BaseLayers and
BaseModels. For BaseModel, a default implementation of `_train_fprop`
and `_test_fprop` has been done for a single `StartNode` and single `EndNode`
Graph, to use this default implementation, we have to define `self.startnode`
and `self.endnode` inside BaseModel's ```__init__```.

For Graph defined inside `BaseModel`, `BaseModel` will automatically call
the `_train_fprop` and `_test_fprop` within each layer inside its model.

```python
class MyLayer(BaseModel):
    def __init__(self):
        '''
         place all your layers inside here and define self.startnode and
         self.endnode
         example:
           layers = []
           layers.append(DenseBlock())
           layers.append(Flatten())
           layers.append(Linear())
           layers.append(Softmax())
           self.startnode = tg.StartNode(input_vars=[None])
           hn = tg.HiddenNode(prev=[self.startnode], layers=layers)
           self.endnode = tg.EndNode(prev=[hn])
        '''
        pass
```
It is possible for BaseModel to return multiple outputs, example
```python
class MyLayerFork(BaseModel):

    @BaseModel.init_name_scope
    def __init__(self):
       # a Y shape model, where we have one input and two outputs
       self.startnode = tg.StartNode(input_vars=[None])
       # first fork output
       layers = []
       layers.append(Linear())
       layers.append(Softmax())
       hn = tg.HiddenNode(prev=[self.startnode], layers=layers)

       # second fork output
       layers2 = []
       layers2.append(Linear())
       layers2.append(Softmax())
       hn2 = tg.HiddenNode(prev=[self.startnode], layers=layers2)

       # two forks outputs
       self.endnode = tg.EndNode(prev=[hn, h2])
```
In this case, a call to `train_fprop` will return two outputs
```python
mylayer = MylayerFork()
y1, y2 = mylayer.train_fprop(X_ph)
```

#### Customize inputs and outputs for BaseModel

Another way to customize your own inputs and outputs is to redefine `_train_fprop`
and `_test_fprop` within `BaseModel`.

The default `_train_fprop` and `_test_fprop` in `BaseModel` looks like this

```python
class BaseModel(Template):

    @staticmethod
    def check_y(y):
        if len(y) == 1:
            return y[0]
        elif len(y) > 1:
            return y
        else:
            raise Exception('{} is empty or not a list'.format(y))

    def _train_fprop(self, *state_belows):
        self.startnode.input_vars = state_belows
        graph = Graph(start=[self.startnode], end=[self.endnode])
        y = graph.train_fprop()
        return BaseModel.check_y(y)

    def _test_fprop(self, *state_belows):
        self.startnode.input_vars = state_belows
        graph = Graph(start=[self.startnode], end=[self.endnode])
        y = graph.test_fprop()
        return BaseModel.check_y(y)
```

for the `MyLayerFork` Model, for two inputs and two outputs, we can redefine it
with multiple `StartNodes` and `EndNodes` within `_train_fprop` and `_test_fprop`.

```python
class MyLayerFork(BaseModel):

    @BaseModel.init_name_scope
    def __init__(self):
       # multiple inputs and multiple outputs

       self.startnode1 = tg.StartNode(input_vars=[None])
       self.startnode2 = tg.StartNode(input_vars=[None])

       layers1 = []
       layers1.append(Linear())
       layers1.append(Softmax())
       hn1 = tg.HiddenNode(prev=[self.startnode1], layers=layers)

       layers2 = []
       layers2.append(Linear())
       layers2.append(Softmax())
       hn2 = tg.HiddenNode(prev=[self.startnode2], layers=layers2)

       # two forks outputs
       self.endnode1 = tg.EndNode(prev=[hn1])
       self.endnode2 = tg.EndNode(prev=[hn2])

     def _train_fprop(self, input1, input2):
         self.startnode1.input_vars = [input1]
         self.startnode2.input_vars = [input2]
         graph = Graph(start=[self.startnode1, self.startnode2], end=[self.endnode1, self.endnode2])
         y = graph.train_fprop()
         return BaseModel.check_y(y)

     def _test_fprop(self, input1, input2):
         self.startnode1.input_vars = [input1]
         self.startnode2.input_vars = [input2]
         graph = Graph(start=[self.startnode1, self.startnode2], end=[self.endnode1, self.endnode2])
         y = graph.test_fprop()
         return BaseModel.check_y(y)

if __name__ == '__main__':
    model = MyLayerFork()
    y1, y2 = model.train_fprop(X1, X2)
```

### Merge
When we have more than one outputs from previous layer and we want to merge them,
we can use the `Merge` layer in [tensorgraph.layers.merge.Merge](./tensorgraph/layers/merge.py)
to merge multiple inputs into one.

```python
class Concat(Merge):
    @Merge.init_name_scope
    def __init__(self, axis=1):
        '''
        Concat which is a Merge layer is used to concat the list of states from
        layer below into one state
        '''
        self.axis = axis

    def _train_fprop(self, state_list):
        return tf.concat(axis=self.axis, values=state_list)
```

We can use `Merge` layer in conjunction with `BaseModel` layer with multiple outputs,
example

```python
class MyLayerMergeFork(BaseModel):
    def __init__(self):
        layers = []
        # fork layer from above example
        layers.append(MyLayerFork())
        # merge layer
        layers.append(Concat())
        self.startnode = tg.StartNode(input_vars=[None])
        hn = tg.HiddenNode(prev=[self.startnode], input_merge_mode=NoChange(), layers=layers)
        self.endnode = tg.EndNode(prev=[hn])
```

-----
## How TensorGraph Works?
In TensorGraph models, layers are put into nodes and nodes are connected together
into graph. When we create nodes and layers, we also initializes all the tensorflow
`Variables`, then we connect the nodes together to form a computational graph.
The initialization of `Variables` and the linking of `Variables` into a computational
graph are two separate steps. By splitting them into two separate steps, we ensure
the flexibility of building our computational graph without the worry of accidental
reinitialization of the `Variables`.
We defined three types of nodes

1. StartNode : for inputs to the graph
2. HiddenNode : for putting sequential layers inside
3. EndNode : for getting outputs from the model

We put all the sequential layers into a `HiddenNode`, `HiddenNode` can be connected
to another `HiddenNode` or `StartNode`, the nodes are connected together to form
an architecture. The graph always starts with `StartNode` and ends with `EndNode`.
Once we have defined an architecture, we can use the `Graph` object to connect the
path we want in the architecture, there can be multiple StartNodes (s1, s2, etc)
and multiple EndNodes (e1, e2, etc), we can define which path we want in the
entire architecture, example to link from `s2` to `e1`. The `StartNode` is where you place
your starting point, it can be a `placeholder`, a symbolic output from another graph,
or data output from `tfrecords`. `EndNode` is where you want to get an output from
the graph, where the output can be used to calculate loss or simply just a peek at the
outputs at that particular layer. Below shows an
[example](examples/example.py) of building a tensor graph.

-----
## Graph Example

First define the `StartNode` for putting the input placeholder
```python
y1_dim = 50
y2_dim = 100
batchsize = 32
learning_rate = 0.01

y1 = tf.placeholder('float32', [None, y1_dim])
y2 = tf.placeholder('float32', [None, y2_dim])
s1 = StartNode(input_vars=[y1])
s2 = StartNode(input_vars=[y2])
```
Then define the `HiddenNode` for putting the sequential layers in each `HiddenNode`
```python
h1 = HiddenNode(prev=[s1, s2],
                input_merge_mode=Concat(),
                layers=[Linear(y2_dim), RELU()])
h2 = HiddenNode(prev=[s2],
                layers=[Linear(y2_dim), RELU()])
h3 = HiddenNode(prev=[h1, h2],
                input_merge_mode=Sum(),
                layers=[Linear(y1_dim), RELU()])
                layers=[Linear(y1_dim+y2_dim, y2_dim), RELU()])
h2 = HiddenNode(prev=[s2],
                layers=[Linear(y2_dim, y2_dim), RELU()])
h3 = HiddenNode(prev=[h1, h2],
                input_merge_mode=Sum(),
                layers=[Linear(y2_dim, y1_dim), RELU()])
```
Then define the `EndNode`. `EndNode` is used to back-trace the graph to connect
the nodes together.
```python
e1 = EndNode(prev=[h3])
e2 = EndNode(prev=[h2])
```
Finally build the graph by putting `StartNodes` and `EndNodes` into `Graph`, we
can choose to use the entire architecture by using all the `StartNodes` and `EndNodes`
and run the forward propagation to get symbolic output from train mode. The number
of outputs from `graph.train_fprop` is the same as the number of `EndNodes` put
into `Graph`
```python
graph = Graph(start=[s1, s2], end=[e1, e2])
o1, o2 = graph.train_fprop()
```
or we can choose which node to start and which node to end, example
```python
graph = Graph(start=[s2], end=[e1])
o1, = graph.train_fprop()
```
Finally build an optimizer to optimize the objective function
```python
o1_mse = tf.reduce_mean((y1 - o1)**2)
o2_mse = tf.reduce_mean((y2 - o2)**2)
mse = o1_mse + o2_mse
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(mse)
```

-----
## TensorGraph on Multiple GPUS
To use tensorgraph on multiple gpus, you can easily integrate it with [horovod](https://github.com/uber/horovod).

```python
import horovod.tensorflow as hvd
from tensorflow.python.framework import ops
import tensorflow as tf
hvd.init()

# tensorgraph model derived previously
modelb = ModelB()
X_ph = tf.placeholder()
y_ph = tf.placeholder()
y_train = modelb.train_fprop(X_ph)
y_test = modelb.test_fprop(X_ph)

train_cost = mse(y_train, y_ph)
test_cost = mse(y_test, y_ph)

opt = tf.train.RMSPropOptimizer(0.001)
opt = hvd.DistributedOptimizer(opt)

# required for BatchNormalization layer
update_ops = ops.get_collection(ops.GraphKeys.UPDATE_OPS)
with ops.control_dependencies(update_ops):
    train_op = opt.minimize(train_cost)

init_op = tf.group(tf.global_variables_initializer(),
                   tf.local_variables_initializer())
bcast = hvd.broadcast_global_variables(0)

# Pin GPU to be used to process local rank (one GPU per process)
config = tf.ConfigProto()
config.gpu_options.allow_growth = True
config.gpu_options.visible_device_list = str(hvd.local_rank())

with tf.Session(graph=graph, config=config) as sess:
    sess.run(init_op)
    bcast.run()

    # training model
    for epoch in range(100):
        for X,y in train_data:
            _, loss_train = sess.run([train_op, train_cost], feed_dict={X_ph:X, y_ph:y})
```

for a full example on [tensorgraph on horovod](./examples/multi_gpus_horovod.py)

-----
## Hierachical Softmax Example
Below is another example for building a more powerful [hierachical softmax](examples/hierachical_softmax.py)
whereby the lower hierachical softmax layer can be conditioned on all the upper
hierachical softmax layers.

```python
## params
x_dim = 50
component_dim = 100
batchsize = 32
learning_rate = 0.01

x_ph = tf.placeholder('float32', [None, x_dim])
# the three hierachical level
y1_ph = tf.placeholder('float32', [None, component_dim])
y2_ph = tf.placeholder('float32', [None, component_dim])
y3_ph = tf.placeholder('float32', [None, component_dim])

# define the graph model structure
start = StartNode(input_vars=[x_ph])

h1 = HiddenNode(prev=[start], layers=[Linear(component_dim), Softmax()])
h2 = HiddenNode(prev=[h1], layers=[Linear(component_dim), Softmax()])
h3 = HiddenNode(prev=[h2], layers=[Linear(component_dim), Softmax()])
h1 = HiddenNode(prev=[start], layers=[Linear(x_dim, component_dim), Softmax()])
h2 = HiddenNode(prev=[h1], layers=[Linear(component_dim, component_dim), Softmax()])
h3 = HiddenNode(prev=[h2], layers=[Linear(component_dim, component_dim), Softmax()])

e1 = EndNode(prev=[h1], input_merge_mode=Sum())
e2 = EndNode(prev=[h1, h2], input_merge_mode=Sum())
e3 = EndNode(prev=[h1, h2, h3], input_merge_mode=Sum())

graph = Graph(start=[start], end=[e1, e2, e3])

o1, o2, o3 = graph.train_fprop()

o1_mse = tf.reduce_mean((y1_ph - o1)**2)
o2_mse = tf.reduce_mean((y2_ph - o2)**2)
o3_mse = tf.reduce_mean((y3_ph - o3)**2)
mse = o1_mse + o2_mse + o3_mse
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(mse)
```

-----
## Transfer Learning Example
Below is an example on transfer learning with bi-modality inputs and merge at
the middle layer with shared representation, in fact, TensorGraph can be used
to build any number of modalities for transfer learning.

```python
## params
x1_dim = 50
x2_dim = 100
shared_dim = 200
y_dim = 100
batchsize = 32
learning_rate = 0.01

x1_ph = tf.placeholder('float32', [None, x1_dim])
x2_ph = tf.placeholder('float32', [None, x2_dim])
y_ph = tf.placeholder('float32', [None, y_dim])

# define the graph model structure
s1 = StartNode(input_vars=[x1_ph])
s2 = StartNode(input_vars=[x2_ph])

h1 = HiddenNode(prev=[s1], layers=[Linear(shared_dim), RELU()])
h2 = HiddenNode(prev=[s2], layers=[Linear(shared_dim), RELU()])
h3 = HiddenNode(prev=[h1,h2], input_merge_mode=Sum(),
                layers=[Linear(y_dim), Softmax()])
h1 = HiddenNode(prev=[s1], layers=[Linear(x1_dim, shared_dim), RELU()])
h2 = HiddenNode(prev=[s2], layers=[Linear(x2_dim, shared_dim), RELU()])
h3 = HiddenNode(prev=[h1,h2], input_merge_mode=Sum(),
                layers=[Linear(shared_dim, y_dim), Softmax()])

e1 = EndNode(prev=[h3])

graph = Graph(start=[s1, s2], end=[e1])
o1, = graph.train_fprop()

mse = tf.reduce_mean((y_ph - o1)**2)
optimizer = tf.train.AdamOptimizer(learning_rate).minimize(mse)
```


text:
package io.machinecode.chainlink.core.jsl.xml.task;

import io.machinecode.chainlink.spi.jsl.inherit.task.InheritableExceptionClass;

import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;

import static javax.xml.bind.annotation.XmlAccessType.NONE;

/**
 * @author Brent Douglas
 * @since 1.0
 */
@XmlAccessorType(NONE)
public class XmlExceptionClass implements InheritableExceptionClass<XmlExceptionClass> {

    @XmlAttribute(name = "class", required = true)
    private String className;

    @Override
    public String getClassName() {
        return className;
    }

    public XmlExceptionClass setClassName(final String className) {
        this.className = className;
        return this;
    }

    @Override
    public XmlExceptionClass copy() {
        return copy(new XmlExceptionClass());
    }

    @Override
    public XmlExceptionClass copy(final XmlExceptionClass that) {
        return ExceptionClassTool.copy(this, that);
        //that.setClassName(this.className);
        //return that;
    }

    @Override
    public XmlExceptionClass merge(final XmlExceptionClass that) {
        return ExceptionClassTool.merge(this, that);
        //this.setClassName(Rules.attributeRule(this.className, that.className));
        //return this;
    }
}

redpajama_set_name: RedPajamaGithub


text:
layout: post
title: Tiffany Taylor fucks like a pro in sexy lingerie and heels
titleinfo: pornvd
desc: Watch Tiffany Taylor fucks like a pro in sexy lingerie and heels. Pornhub is the ultimate xxx porn and sex site.
---

Tiffany Taylor fucks like a pro in sexy lingerie and heels

Watch Tiffany Taylor fucks like a pro in sexy lingerie and heels. Pornhub is the ultimate xxx porn and sex site.


text:
package edu.rice.cs.caper.bayou.annotations;

public class Bayou {
    public static Object $init() {
        return null;
    }
}


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

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

    <title>Messaging API — Kango 1.7.0 documentation</title>

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

    <link rel="top" title="Kango 1.7.0 documentation" href="../index.html" />
    <link rel="up" title="General information" href="index.html" />
    <link rel="next" title="Autoupdating Extensions" href="autoupdating-extensions.html" />
    <link rel="prev" title="Popup API" href="popup-api.html" />

Navigation

          index

          next |

          previous |

Kango 1.7.0 documentation »

General information »

Messaging API¶

Kango framework providing convenient and easy way to pass any JSON serializable data from content script to background script and vice versa. This allows developer to use any combinations of background-content scripts for their needs. Here we will show how data could be passed between scripts.

Please also refer to the <tt class="docutils literal">MessagingDemo</tt> project.

To send/receive any message we need to use a pair of functions <tt class="xref js js-func docutils literal">kango.addMessageListener()</tt> and <tt class="xref js js-func docutils literal">kango.dispatchMessage()</tt>

What Kango messages are?¶

Each Kango message has a name and an optional JSON serializable data attached. For example sending a message could be something like that:

var data = {
    policy: 'strict',
    urls: [ 'http://server1.com/', 'http://server2.com/', 'http://server3.com/' ]
};
kango.dispatchMessage('CheckWithAntivirus', data);

This will send a message named <tt class="docutils literal">CheckWithAntivirus</tt> with attached data object. Kango will find a listener by message name and call appropriate listener function with data object as param.

The data object must be JSON serializable, for instance you can not pass a function in data object.
If you want to have a callback after message processing please use event.target to send a message back to sender.

What is the message listener signature?¶

The message listener is 1 param function:

function(event) {
    // message processing goes here
}

The event param will be an object:

event = {
    data: variant,  // JSON serializable data object attached to the message
    target: object, // Point to object sent the message
    source: KangoMessageSource // Message source
}

target field could be either KangoBrowserTab or kango objects. For instance if message came from background to content script then target will be a kango object. And if message came from content to background target will be KangoBrowserTab.

The event.target.dispatchMessage function could be used inside message listener.

source KangoMessageSource object.

From background to content script¶

Subscribing inside a content script¶

Inside the content script where you need to receive a message you need to subscribe for that message by calling <tt class="xref js js-func docutils literal">kango.addMessageListener()</tt> function as follows:

kango.addMessageListener('Background2Content', function(event) {
    // event.data - the data sent with message
    alert('Background script says: ' + event.data);
});

Posting message from background script¶

Inside the background script you can call <tt class="xref js js-func docutils literal">dispatchMessage</tt> function to call the code inside content script:

kango.browser.tabs.getCurrent(function(tab) {
    // tab is KangoBrowserTab object
    tab.dispatchMessage('Background2Content', 'Hello from background');
});

Please note that firstly we choose a tab for posting a message. If you want to post a message to all the tabs you can enumerate them via <tt class="xref js js-func docutils literal">kango.browser.tabs.getAll()</tt> function like follow:

kango.browser.tabs.getAll(function(tabs) {
    for (var i = 0; i < tabs.length; i++) {
     tabs[i].dispatchMessage('MyMessage', 'Hello');
    }
});

From content to background¶

Subscribing inside background script¶

Inside background script you can add a listener by calling the same <tt class="xref js js-func docutils literal">kango.addMessageListener()</tt> function:

kango.addMessageListener('Content2Background', function(event) {
    // event.data - point to data attached
    // event.target - point to the KangoBrowseTab object that sent the message
    console.log('Content script says: ' + event.data);
});

Posting message from content script¶

Content to background message could be sent by calling <tt class="xref js js-func docutils literal">kango.dispatchMessage()</tt> function:

kango.dispatchMessage('Content2Background', 'Hello');

Please enable JavaScript to view the comments powered by Disqus.

Table Of Contents

Messaging API

What Kango messages are?

What is the message listener signature?

From background to content script

Subscribing inside a content script

Posting message from background script

From content to background

Subscribing inside background script

Posting message from content script

Previous topic

Popup API

Next topic

Autoupdating Extensions

Quick search

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

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

Navigation

          index

          next |

          previous |

Kango 1.7.0 documentation »

General information »

        © Copyright 2011-2014, Kango.
      Created using Sphinx 1.2.2.


text:
export FLIPS_DB=flips_test

# http_proxy="" curl -X DELETE http://localhost:5984/$FLIPS_DB/

node_modules/jasmine-node/bin/jasmine-node --coffee spec/urlgenerator.spec.coffee


text:
/* -*-c++-*- */
/*
  -------------------------------------------------------------------------

  Copyright 2015 roxlu <info#AT#roxlu.com>

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

  -------------------------------------------------------------------------

  OpenGL Screen Capture
  ======================

  The `ScreenCaptureGL` class can be used when a GL context is available
  and you want to draw the captured screen. Because every OS and game engine
  has it's own way to include the GL headers you need to include this header
  only after you've include the necessary GL headers (and so all GL functions
  that we need are available). Then, in one file you need to use
  `#defined SCREEN_CAPTURE_IMPLEMENTATION` to include the implementation of
  this class (also after including the GL headers.).

  How to include
  ---------------
  In every file where you want to use the `ScreenCaptureGL` class you can use:

         #include <screencapture/ScreenCaptureGL.h>

   And in one .cpp file you need to do:

         #define SCREEN_CAPTURE_IMPLEMENTATION
         #include <screencapture/ScreenCaptureGL.h>

  Usage
  -----
  See src/test_opengl.cpp

  Note:
  -----
  I removed using a projection matrix + view matrix because it's easier to
  manager just a viewport and rendering a full-viewport triangle-strip to draw
  the contents. This makes it easier to work with e.g. FBOs and RTT features.
  See commit 877dda9005d0bcf793f600100eca7d75387948d4 for a version with
  projection- and view matrix.

*/
/* --------------------------------------------------------------------------- */
/*                               H E A D E R                                   */
/* --------------------------------------------------------------------------- */
#ifndef SCREENCAPTURE_OPENGL_H
#define SCREENCAPTURE_OPENGL_H

#include <math.h>
#include <assert.h>
#include <screencapture/ScreenCapture.h>
#include <screencapture/Utils.h>

#if defined(_WIN32)
   #define WIN32_LEAN_AND_MEAN
   #include <windows.h>
#elif defined(__linux) or defined(__APPLE__)
   #include <pthread.h>
#endif

namespace sc {

  /* --------------------------------------------------------------------------- */
  /* Shaders                                                                     */
  /* --------------------------------------------------------------------------- */

  static const char* SCREENCAPTURE_GL_VS = ""
    "#version 330\n"
    "uniform float u_texcoords[8]; "
    ""
    " const vec2[] pos = vec2[4]("
    "   vec2(-1.0, 1.0),"
    "   vec2(-1.0, -1.0),"
    "   vec2(1.0, 1.0),"
    "   vec2(1.0, -1.0)"
    "   );"
    ""
    "out vec2 v_tex; "
    ""
    "void main() { "
    "  gl_Position = vec4(pos[gl_VertexID], 0.0, 1.0);"
    "  v_tex = vec2(u_texcoords[gl_VertexID * 2], u_texcoords[(gl_VertexID * 2) + 1]);"
    "}"
    "";

  static const char* SCREENCAPTURE_GL_FS_BGRA = ""
    "#version 330\n"
    "uniform sampler2D u_tex;"
    ""
    "in vec2 v_tex;"
    "layout( location = 0 ) out vec4 fragcolor; "
    ""
    "void main() {"
    "  vec4 tc = texture(u_tex, v_tex);"
    "  fragcolor.rgb = tc.bgr;"
    "  fragcolor.a = 1.0f;"
    "}"
    "";

  /* --------------------------------------------------------------------------- */
  /* Cross platform mutex.                                                       */
  /* --------------------------------------------------------------------------- */

#if defined(_WIN32)
  struct ScreenMutex {
    CRITICAL_SECTION handle;
  };
#elif defined(__linux) or defined(__APPLE__)
  struct ScreenMutex {
    pthread_mutex_t handle;
  };
#endif

  int sc_gl_create_mutex(ScreenMutex& m);
  int sc_gl_destroy_mutex(ScreenMutex& m);
  int sc_gl_lock_mutex(ScreenMutex& m);
  int sc_gl_unlock_mutex(ScreenMutex& m);

  /* --------------------------------------------------------------------------- */
  /* OpenGL ScreenCapture drawer                                                 */
  /* --------------------------------------------------------------------------- */

  class ScreenCaptureGL {
  public:
    ScreenCaptureGL();
    ~ScreenCaptureGL();

    int init();                                                                  /* Initializes the screencapturer driver. Should be used as constructor.*/
    int shutdown();                                                              /* Shutdown the capturer, removes allocated GL textures and memory for the received frames. */
    int configure(Settings settings);                                            /* Configure the capturer, see Types.h for the available settings. */
    int start();                                                                 /* Start capturing the screen. */
    int stop();                                                                  /* Stop capturing the screen. */

    void update();                                                               /* Update the texture; must be called before you want to draw. */
    void draw();                                                                 /* Draw the captured screen using at 0, 0 using the provided output_width and output_height of the settings youpassed into configure.*/
    void draw(float x, float y, float w, float h);                               /* Draw the captured screen at the given location. */
    int flip(bool horizontal, bool vertical);                                    /* Flip the screen horizontally or vertically according to Photoshops flip feature. */
    int lock();                                                                  /* Whenever you want to access the `pixels` member you need to lock first. */
    int unlock();                                                                /* Unlock when you're ready witht eh `pixels` member. */

  private:
    int setupGraphics();                                                         /* Used internally to create the shaders when they're not yet created, calls `setupShaders()` and `setupTextures()`. */
    int setupShaders();                                                          /* Creates the shader when it's not yet created; all `ScreenCaptureGL instances shared the same shader instance. */
    int setupTextures();                                                         /* Create the texture(s) that are needed to render the captured screen in the set pixel format. */

  public:
    static GLuint prog;                                                          /* The shader program that renders the captured screen (shared among all `ScreenCapture` instances). */
    static GLuint vert;                                                          /* The vertex shader. Shared among all instances of `ScreenCapture` */
    static GLuint frag;                                                          /* The fragment shader. Shared among all instances of `ScreenCapture` */
    static GLuint vao;                                                           /* The vao we use for attributeless rendering. */
    static GLint u_texcoords;                                                    /* Texcoord uniform location; `flip()` uploads the correct texture coordinates. */
    static GLint u_tex;                                                          /* Texture uniform location. */
    ScreenMutex mutex;                                                           /* It's possible (and probably will be) that the received pixel buffers are passed to the frame callback from another thread so we need to sync access to it. */
    ScreenCapture cap;                                                           /* The actual capturer */
    Settings settings;                                                           /* The settings you passed into `configure()`. */
    uint8_t* pixels;                                                             /* The pixels we received in the frame callback. */
    bool has_new_frame;                                                          /* Is set to true when in the frame callback. When true, we will update the texture data. */
    GLuint tex0;                                                                 /* First plane, or the only tex when using GL_BGRA */
    GLuint tex1;                                                                 /* Second plane, only used when we receive planar data. */
    int unpack_alignment[3];
    int unpack_row_length[3];
  };

  /* --------------------------------------------------------------------------- */

  inline int ScreenCaptureGL::start() {
      return cap.start();
  }

  inline int ScreenCaptureGL::stop() {
    return cap.stop();
  }

  inline int ScreenCaptureGL::lock() {

    if (0 != sc_gl_lock_mutex(mutex)) {
      printf("Error: failed to lock the mutex in ScreenCaptureGL.\n");
      return -1;
    }

    return 0;
  }

  inline int ScreenCaptureGL::unlock() {

    if (0 != sc_gl_unlock_mutex(mutex)) {
      printf("Error: failed to unlock the mutex in ScreenCaptureGL.\n");
      return -1;
    }

    return 0;
  }

} /* namespace sc */
#endif

/* --------------------------------------------------------------------------- */
/*                       I M P L E M E N T A T I O N                           */
/* --------------------------------------------------------------------------- */
#if defined(SCREEN_CAPTURE_IMPLEMENTATION)

namespace sc {

  /* See: https://gist.github.com/roxlu/6152fccfdd0446533e1b for latest version. */
  /* --------------------------------------------------------------------------- */
  /* Embeddable OpenGL wrappers.                                                 */
  /* --------------------------------------------------------------------------- */
  static int create_shader(GLuint* out, GLenum type, const char* src);           /* Create a shader, returns 0 on success, < 0 on error. e.g. create_shader(&vert, GL_VERTEX_SHADER, DRAWER_VS); */
  static int create_program(GLuint* out, GLuint vert, GLuint frag, int link);    /* Create a program from the given vertex and fragment shader. returns 0 on success, < 0 on error. e.g. create_program(&prog, vert, frag, 1); */
  static int print_shader_compile_info(GLuint shader);                           /* Prints the compile info of a shader. returns 0 when shader compiled, < 0 on error. */
  static int print_program_link_info(GLuint prog);                               /* Prints the program link info. returns 0 on success, < 0 on error. */
  /* --------------------------------------------------------------------------- */

  static void sc_gl_frame_callback(PixelBuffer& buffer);

  /* --------------------------------------------------------------------------- */

  GLuint ScreenCaptureGL::prog = 0;
  GLuint ScreenCaptureGL::vert = 0;
  GLuint ScreenCaptureGL::frag = 0;
  GLuint ScreenCaptureGL::vao = 0;
  GLint ScreenCaptureGL::u_texcoords = -1;
  GLint ScreenCaptureGL::u_tex = -1;

  /* --------------------------------------------------------------------------- */

  ScreenCaptureGL::ScreenCaptureGL()
    :cap(sc_gl_frame_callback, this)
    ,pixels(NULL)
    ,has_new_frame(false)
    ,tex0(0)
    ,tex1(0)
  {
    memset(unpack_alignment, 0x00, sizeof(unpack_alignment));
    memset(unpack_row_length, 0x00, sizeof(unpack_row_length));
  }

  ScreenCaptureGL::~ScreenCaptureGL() {

    shutdown();
  }

  int ScreenCaptureGL::init() {

    if (0 != sc_gl_create_mutex(mutex)) {
      return -1;
    }

    if (0 != cap.init()) {
      return -1;
    }

    return 0;
  }

  int ScreenCaptureGL::shutdown() {

    int r = 0;

    if (0 != sc_gl_destroy_mutex(mutex)) {
      r -= 1;
    }

    if (0 != cap.shutdown()) {
      r -= 2;
    }

    if (NULL != pixels) {
      delete[] pixels;
      pixels = NULL;
    }

    if (0 != tex0) {
      glDeleteTextures(1, &tex0);
      tex0 = 0;
    }

    if (0 != tex1) {
      glDeleteTextures(1, &tex1);
      tex1 = 0;
    }

    has_new_frame = false;

    return r;
  }

  int ScreenCaptureGL::configure(Settings cfg) {

    settings = cfg;

    if (SC_BGRA != cfg.pixel_format) {
      printf("Error: currently we only support SC_BGRA in ScreenCaptureGL.\n");
      return -1;
    }

    if (0 != cap.configure(cfg)) {
      return -2;
    }

    if (NULL != pixels) {
      delete[] pixels;
      pixels = NULL;
    }

    if (0 != setupGraphics()) {
      return -4;
    }

    return 0;
  }

  int ScreenCaptureGL::setupGraphics() {

    if (0 == prog) {
      if (0 != setupShaders()) {
        return -1;
      }
    }

    if (0 == tex0) {
      if (0 != setupTextures()) {
        return -2;
      }
    }

    if (0 == vao) {
      glGenVertexArrays(1, &vao);
    }

    /* We should store the flip as state, not in the global shader. */
    if (0 != flip(false, false)) {
      /* @todo - we should remove all GL objects here. */
      return -3;
    }

    return 0;
  }

  int ScreenCaptureGL::setupShaders() {

     if (0 != prog) {
      printf("Error: trying to setup shaders but the shader is already created.\n");
      return -1;
    }

    if (SC_NONE == settings.pixel_format) {
      printf("Error: cannot setup screencapture shaders; pixel format not set in settings.\n");
      return -2;
    }

    if (0 != create_shader(&vert, GL_VERTEX_SHADER, SCREENCAPTURE_GL_VS)) {
      printf("Error: failed to create the screencapture vertex shader.\n");
      return -2;
    }

    if (SC_BGRA == settings.pixel_format) {
      if (0 != create_shader(&frag, GL_FRAGMENT_SHADER, SCREENCAPTURE_GL_FS_BGRA)) {
        printf("Error: failed to create the screencapture fragment shader.\n");
        return -3;
      }
    }
    else {
      printf("Error: failed to create the shader; no supported shader found.\n");
      glDeleteShader(vert);
      vert = 0;
      return -4;
    }

    if (0 != create_program(&prog, vert, frag, 1)) {
      printf("Error: failed to create the screencapture program.\n");
      glDeleteShader(vert);
      glDeleteShader(frag);
      vert = 0;
      frag = 0;
      return -5;
    }

    glUseProgram(prog);

    u_texcoords = glGetUniformLocation(prog, "u_texcoords");
    u_tex = glGetUniformLocation(prog, "u_tex");

    assert(-1 != u_texcoords);
    assert(-1 != u_tex);

    return 0;
  }

  int ScreenCaptureGL::setupTextures() {

    if (0 > settings.output_width) {
      printf("Error: cannot setup the texture for screencapture, output width is invalid: %d\n", settings.output_width);
      return -1;
    }

    if (0 > settings.output_height) {
      printf("Error: cannot setup the texture for screencapture, output height is invalid: %d\n", settings.output_height);
      return -2;
    }

    if (0 != tex0) {
      /* @todo we could delete the current texture. */
      printf("Error: trying to setup the textures, but it seems that the texture is already created.\n");
      return -3;
    }

    if (SC_BGRA == settings.pixel_format) {

      glGenTextures(1, &tex0);
      glBindTexture(GL_TEXTURE_2D, tex0);
      glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, settings.output_width, settings.output_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, NULL);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
      glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    }
    else {
      printf("Error: we didn't create textures for the ScreenCaptureGL because we need to add support for the pixel format: %s\n", screencapture_pixelformat_to_string(settings.pixel_format).c_str());
      return -4;
    }

    return 0;
  }

  void ScreenCaptureGL::update() {

    bool changed_unpack = false;

    cap.update();

#if !defined(NDEBUG)
    if (SC_BGRA != settings.pixel_format) {
      printf("Error: trying to update the ScreenCaptureGL, but we only support uploading of SC_BGRA data atm.\n");
      return;
    }
#endif

    /* Update the pixel data. */
    /* @todo maybe we can profile if we should lock the `pixels` a bit shorter. */
    lock();
    {
      if (true == has_new_frame) {

        /* When we have a new frame, make sure we set the correct upload state. */
        if (0 != unpack_row_length[0]) {
          glPixelStorei(GL_UNPACK_ROW_LENGTH, unpack_row_length[0]);
          changed_unpack = true;
        }

        if (0 != unpack_alignment[0]) {
          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
          changed_unpack = true;
        }

        glBindTexture(GL_TEXTURE_2D, tex0);
        glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, settings.output_width,  settings.output_height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
        has_new_frame = false;

        /* Reset unpack state. */
        if (true == changed_unpack) {
          glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
          glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
        }
      }
    }
    unlock();
  }

  void ScreenCaptureGL::draw() {
    draw(0.0f, 0.0f, settings.output_width, settings.output_height);
  }

  void ScreenCaptureGL::draw(float x, float y, float w, float h) {

#if !defined(NDEBUG)
    if (0 == prog) {
      printf("Error: cannot draw because the shader program hasn't been created.\n");
      return;
    }
#endif

    /* Based on the pixelf format bind the correct textures. */
    if (SC_BGRA == settings.pixel_format) {
      glActiveTexture(GL_TEXTURE0);
      glBindTexture(GL_TEXTURE_2D, tex0);
    }
    else {
      printf("Error: cannot bind texture for the current pixel format. %s\n", screencapture_pixelformat_to_string(settings.pixel_format).c_str());
      return;
    }

    glViewport(x, y, w, h);

    /* And draw. */
    glUseProgram(prog);
    glBindVertexArray(vao);
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  }

  int ScreenCaptureGL::flip(bool horizontal, bool vertical) {

    float* texcoords = NULL;
    float tex_normal[] =     { 0.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0 } ;
    float tex_vert[] =       { 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0 } ;
    float tex_hori[] =       { 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0 } ;
    float tex_verthori[] =   { 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 } ;

    if (0 == prog) {
      printf("Error: You're trying to flip the capture device but we're not yet setup.\n");
      return -1;
    }

    if (-1 == u_texcoords) {
      printf("Error: the u_texcoords uniform location hasn't been set.\n");
      return -2;
    }

    if (false == horizontal && false == vertical) {
      texcoords = tex_normal;
    }
    else if(false == horizontal && true == vertical) {
      texcoords = tex_vert;
    }
    else if(true == horizontal && false == vertical) {
      texcoords = tex_hori;
    }
    else if (true == horizontal && true == vertical) {
      texcoords = tex_verthori;
    }

    if (NULL == texcoords) {
      printf("Error: texcoords == NULL in %s\n", __FUNCTION__);
      return -2;
    }

    glUseProgram(prog);
    glUniform1fv(u_texcoords, 8, texcoords);

    return 0;
  }

  /* ------------------------------------------------------------------------*/
  /* Embeddable OpenGL wrappers.                                             */
  /* ------------------------------------------------------------------------*/

  static int create_shader(GLuint* out, GLenum type, const char* src) {

    *out = glCreateShader(type);
    glShaderSource(*out, 1, &src, NULL);
    glCompileShader(*out);

    if (0 != print_shader_compile_info(*out)) {
      *out = 0;
      return -1;
    }

    return 0;
  }

  /* create a program, store the result in *out. when link == 1 we link too. returns -1 on error, otherwise 0 */
  static int create_program(GLuint* out, GLuint vert, GLuint frag, int link) {
    *out = glCreateProgram();
    glAttachShader(*out, vert);
    glAttachShader(*out, frag);

    if(1 == link) {
      glLinkProgram(*out);
      if (0 != print_program_link_info(*out)) {
        *out = 0;
        return -1;
      }
    }

    return 0;
  }

  /* checks + prints program link info. returns 0 when linking didn't result in an error, on link erorr < 0 */
  static int print_program_link_info(GLuint prog) {

    GLint status = 0;
    GLint count = 0;
    GLchar* error = NULL;
    GLsizei nchars = 0;

    glGetProgramiv(prog, GL_LINK_STATUS, &status);
    if(status) {
      return 0;
    }

    glGetProgramiv(prog, GL_INFO_LOG_LENGTH, &count);
    if(count <= 0) {
      return 0;
    }

    error = (GLchar*)malloc(count);
    glGetProgramInfoLog(prog, count, &nchars, error);
    if (nchars <= 0) {
      free(error);
      error = NULL;
      return -1;
    }

    printf("\nPROGRAM LINK ERROR");
    printf("\n--------------------------------------------------------\n");
    printf("%s", error);
    printf("--------------------------------------------------------\n\n");

    free(error);
    error = NULL;
    return -1;
  }

  /* checks the compile info, if it didn't compile we return < 0, otherwise 0 */
  static int print_shader_compile_info(GLuint shader) {

    GLint status = 0;
    GLint count = 0;
    GLchar* error = NULL;

    glGetShaderiv(shader, GL_COMPILE_STATUS, &status);
    if(status) {
      return 0;
    }

    error = (GLchar*) malloc(count);
    glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &count);
    if(count <= 0) {
      free(error);
      error = NULL;
      return 0;
    }

    glGetShaderInfoLog(shader, count, NULL, error);
    printf("\nSHADER COMPILE ERROR");
    printf("\n--------------------------------------------------------\n");
    printf("%s", error);
    printf("--------------------------------------------------------\n\n");

    free(error);
    error = NULL;
    return -1;
  }

  /* --------------------------------------------------------------------------- */
  /* Cross platform mutex.                                                       */
  /* --------------------------------------------------------------------------- */

#if defined(_WIN32)

  int sc_gl_create_mutex(ScreenMutex& m) {
     InitializeCriticalSection(&m.handle);
    return 0;
  }

  int sc_gl_lock_mutex(ScreenMutex& m) {
    EnterCriticalSection(&m.handle);
    return 0;
  }

  int sc_gl_unlock_mutex(ScreenMutex& m) {
    LeaveCriticalSection(&m.handle);
    return 0;
  }

  int sc_gl_destroy_mutex(ScreenMutex& m) {
     DeleteCriticalSection(&m.handle);
    return 0;
  }

#elif defined(__linux) or defined(__APPLE__)

  int sc_gl_create_mutex(ScreenMutex& m) {

    if (0 != pthread_mutex_init(&m.handle, NULL)) {
      printf("Error: failed to create the mutex to sync the pixel data in ScreenCaptureGL.\n");
      return -1;
    }

    return 0;
  }

  int sc_gl_lock_mutex(ScreenMutex& m) {
    if (0 != pthread_mutex_lock(&m.handle)) {
      printf("Error: failed to lock the mutex to sync the pixel data in ScreenCaptureGL.\n");
      return -1;
    }

    return 0;
  }

  int sc_gl_unlock_mutex(ScreenMutex& m) {
    if (0 != pthread_mutex_unlock(&m.handle)) {
      printf("Error: failed to unlock the mutex to sync the pixel data in ScreenCaptureGL.\n");
      return -1;
    }

    return 0;
  }

  int sc_gl_destroy_mutex(ScreenMutex& m) {

    if (0 != pthread_mutex_destroy(&m.handle)) {
      printf("Error: failed to destroy the mutex to sync the pixel data in ScreenCaptureGL.\n");
      return -2;
    }

    return 0;
  }

  #endif

  /* --------------------------------------------------------------------------- */

  static void sc_gl_frame_callback(PixelBuffer& buffer) {

    ScreenCaptureGL* gl = static_cast<ScreenCaptureGL*>(buffer.user);
    if (NULL == gl) {
      printf("Error: failed to cast the user pointer to a ScreenCapture*\n");
      return;
    }

    if (SC_BGRA == buffer.pixel_format) {

      if (0 == buffer.nbytes[0]) {
        printf("Error: the number of bytes hasn't been set in the ScreenCapture.\n");
        return;
      }

      if (NULL == buffer.plane[0]) {
        printf("Error: the plane data pointer is NULL.\n");
        return;
      }

      if (NULL == gl->pixels) {

        gl->pixels = new uint8_t[buffer.nbytes[0]];

        /* Check if we need to change the alignment. */
        int vals[] = { 1, 2, 4, 8 } ;
        int unpack = 0;
        for (int i = 0; i < 4; ++i) {
          int p = pow(2, vals[i]);
          int d = buffer.stride[0] % p;
          if (0 != d) {
            break;
          }
          unpack = vals[i];
        }

        /* 4 is default. */
        if (4 != unpack) {
          gl->unpack_alignment[0] = unpack;
        }

        /* Do we need a different unpack row length? (the 4 is from GL_BGRA) */
        if (buffer.stride[0] > buffer.width * 4) {
          gl->unpack_row_length[0] = buffer.stride[0] / 4;
        }
      }

      gl->lock();
      {
        memcpy(gl->pixels, buffer.plane[0], buffer.nbytes[0]);
        gl->has_new_frame = true;
      }
      gl->unlock();
    }
  }

  /* --------------------------------------------------------------------------- */
} /* namespace sc */

#endif

#undef SCREEN_CAPTURE_IMPLEMENTATION


text:
function isOdd = mtIsOdd(number)
%mtIsOdd
% Checks whether a number is odd
%
% USAGE: isOdd = mtIsOdd(number)

isOdd = ~mtIsEven(number);


text:
/*     */ package edu.drexel.cis.dragon.config;
/*     */
/*     */ import edu.drexel.cis.dragon.onlinedb.ArticleParser;
/*     */ import edu.drexel.cis.dragon.onlinedb.BasicCollectionReader;
/*     */ import edu.drexel.cis.dragon.onlinedb.CollectionReader;
/*     */ import edu.drexel.cis.dragon.onlinedb.SimpleCollectionReader;
/*     */ import edu.drexel.cis.dragon.onlinedb.trec.EarlyTrecTopicReader;
/*     */ import edu.drexel.cis.dragon.onlinedb.trec.Genomics2004TopicReader;
/*     */ import edu.drexel.cis.dragon.onlinedb.trec.Genomics2005TopicReader;
/*     */ import edu.drexel.cis.dragon.onlinedb.trec.TrecCollectionReader;
/*     */ import edu.drexel.cis.dragon.onlinedb.trec.TrecFileReader;
/*     */ import java.io.File;
/*     */ import java.io.PrintStream;
/*     */
/*     */ public class CollectionReaderConfig extends ConfigUtil
/*     */ {
/*     */   public CollectionReaderConfig()
/*     */   {
/*     */   }
/*     */
/*     */   public CollectionReaderConfig(ConfigureNode root)
/*     */   {
/*  22 */     super(root);
/*     */   }
/*     */
/*     */   public CollectionReaderConfig(String configFile) {
/*  26 */     super(configFile);
/*     */   }
/*     */
/*     */   public CollectionReader getCollectionReader(int collectionID) {
/*  30 */     return loadCollectionReader(this.root, collectionID);
/*     */   }
/*     */
/*     */   public CollectionReader getCollectionReader(ConfigureNode node, int extractorID) {
/*  34 */     return loadCollectionReader(node, extractorID);
/*     */   }
/*     */
/*     */   private CollectionReader loadCollectionReader(ConfigureNode node, int extractorID)
/*     */   {
/*  41 */     ConfigureNode extractorNode = getConfigureNode(node, "collectionreader", extractorID);
/*  42 */     if (extractorNode == null)
/*  43 */       return null;
/*  44 */     String extractorName = extractorNode.getNodeName();
/*  45 */     return loadCollectionReader(extractorName, extractorNode);
/*     */   }
/*     */
/*     */   protected CollectionReader loadCollectionReader(String collectionName, ConfigureNode collectionNode) {
/*  49 */     if (collectionName.equalsIgnoreCase("BasicCollectionReader"))
/*  50 */       return loadBasicCollectionReader(collectionNode);
/*  51 */     if (collectionName.equalsIgnoreCase("SimpleCollectionReader"))
/*  52 */       return loadSimpleCollectionReader(collectionNode);
/*  53 */     if (collectionName.equalsIgnoreCase("TrecCollectionReader"))
/*  54 */       return loadTrecCollectionReader(collectionNode);
/*  55 */     if (collectionName.equalsIgnoreCase("TrecFileReader"))
/*  56 */       return loadTrecFileReader(collectionNode);
/*  57 */     if (collectionName.equalsIgnoreCase("EarlyTrecTopicReader"))
/*  58 */       return new EarlyTrecTopicReader(collectionNode.getString("topicfile"));
/*  59 */     if (collectionName.equalsIgnoreCase("Genomics2005TopicReader"))
/*  60 */       return new Genomics2005TopicReader(collectionNode.getString("topicfile"));
/*  61 */     if (collectionName.equalsIgnoreCase("Genomics2004TopicReader")) {
/*  62 */       return new Genomics2004TopicReader(collectionNode.getString("topicfile"));
/*     */     }
/*  64 */     return (CollectionReader)loadResource(collectionNode);
/*     */   }
/*     */
/*     */   private CollectionReader loadBasicCollectionReader(ConfigureNode curNode)
/*     */   {
/*     */     try
/*     */     {
/*  74 */       String collectionPath = curNode.getString("collectionpath");
/*  75 */       String collectionName = curNode.getString("collectionname");
/*  76 */       String collectionFile = curNode.getString("collectionfile");
/*  77 */       String indexFile = curNode.getString("indexfile");
/*  78 */       String articleParser = curNode.getString("articleparser", "dragon.onlinedb.BasicArticleParser");
/*     */       CollectionReader reader;
/*  79 */       if (collectionFile == null) {
/*  80 */         collectionFile = collectionPath + "/" + collectionName + ".collection";
/*  81 */         indexFile = collectionPath + "/" + collectionName + ".index";
/*  82 */         reader = new BasicCollectionReader(collectionFile, indexFile);
/*     */       }
/*     */       else {
/*  85 */         reader = new BasicCollectionReader(collectionFile, indexFile);
/*  86 */       }ArticleParser parser = getArticleParser(articleParser);
/*  87 */       if (parser == null) {
/*  88 */         System.out.println("Can not load the article parser.");
/*  89 */         return null;
/*     */       }
/*  91 */       reader.setArticleParser(parser);
/*  92 */       return reader;
/*     */     }
/*     */     catch (Exception e) {
/*  95 */       e.printStackTrace();
/*  96 */     }return null;
/*     */   }
/*     */
/*     */   private CollectionReader loadSimpleCollectionReader(ConfigureNode curNode)
/*     */   {
/*     */     try
/*     */     {
/* 107 */       String collectionPath = curNode.getString("collectionpath", null);
/* 108 */       String articleParser = curNode.getString("articleparser", "dragon.onlinedb.SimpleArticleParser");
/* 109 */       ArticleParser parser = getArticleParser(articleParser);
/* 110 */       if (parser == null) {
/* 111 */         System.out.println("Can not load the article parser.");
/* 112 */         return null;
/*     */       }
/*     */       CollectionReader reader;
/* 115 */       if (collectionPath == null) {
/* 116 */         reader = new SimpleCollectionReader(parser);
/*     */       }
/* 118 */       return new SimpleCollectionReader(collectionPath, parser);
/*     */     }
/*     */     catch (Exception e)
/*     */     {
/* 122 */       e.printStackTrace();
/* 123 */     }return null;
/*     */   }
/*     */
/*     */   private CollectionReader loadTrecCollectionReader(ConfigureNode curNode)
/*     */   {
/*     */     try
/*     */     {
/* 134 */       String articleRoot = curNode.getString("articleroot", "DOC");
/* 135 */       String collectionPath = curNode.getString("collectionpath", null);
/* 136 */       String indexFile = curNode.getString("indexfile", null);
/* 137 */       String articleParser = curNode.getString("articleparser", "dragon.onlinedb.BasicArticleParser");
/* 138 */       ArticleParser parser = getArticleParser(articleParser);
/* 139 */       if (parser == null) {
/* 140 */         System.out.println("Can not load the article parser.");
/* 141 */         return null;
/*     */       }
/*     */       CollectionReader reader;
/* 143 */       if ((collectionPath == null) && (indexFile == null)) {
/* 144 */         reader = new TrecCollectionReader(parser, articleRoot);
/*     */       }
/*     */       else
/*     */       {
/* 145 */         if (indexFile == null)
/* 146 */           reader = new TrecCollectionReader(collectionPath, parser, articleRoot);
/*     */       }
/* 148 */       return new TrecCollectionReader(collectionPath, indexFile, parser, articleRoot);
/*     */     }
/*     */     catch (Exception e)
/*     */     {
/* 152 */       e.printStackTrace();
/* 153 */     }return null;
/*     */   }
/*     */
/*     */   private CollectionReader loadTrecFileReader(ConfigureNode curNode)
/*     */   {
/*     */     try
/*     */     {
/* 164 */       String articleRoot = curNode.getString("articleroot", "DOC");
/* 165 */       String filename = curNode.getString("filename", null);
/* 166 */       String articleParser = curNode.getString("articleparser", "dragon.onlinedb.BasicArticleParser");
/* 167 */       ArticleParser parser = getArticleParser(articleParser);
/* 168 */       if (parser == null) {
/* 169 */         System.out.println("Can not load the article parser.");
/* 170 */         return null;
/*     */       }
/*     */       CollectionReader reader;
/* 172 */       if (filename == null) {
/* 173 */         reader = new TrecFileReader(parser, articleRoot);
/*     */       }
/* 175 */       return new TrecFileReader(new File(filename), parser, articleRoot);
/*     */     }
/*     */     catch (Exception e)
/*     */     {
/* 179 */       e.printStackTrace();
/* 180 */     }return null;
/*     */   }
/*     */
/*     */   protected ArticleParser getArticleParser(String className)
/*     */   {
/*     */     try
/*     */     {
/* 189 */       Class myClass = Class.forName(className);
/* 190 */       return (ArticleParser)myClass.newInstance();
/*     */     }
/*     */     catch (Exception e) {
/* 193 */       e.printStackTrace();
/* 194 */     }return null;
/*     */   }
/*     */ }

/* Location:           C:\dragontoolikt\dragontool.jar
 * Qualified Name:     dragon.config.CollectionReaderConfig
 * JD-Core Version:    0.6.2
 */


text:
using System;

namespace ConsoleApplicationParceAttribute.Attributes
{
    public class MapAttribute : Attribute
    {
        public string Name { get; set; }
        public string FunctionTo { get; set; }
        public string FunctionFrom { get; set; }

    }
}


text:
<?php
class Kwf_Controller_Action_Redirects_RedirectController extends Kwf_Controller_Action_Auto_Form
{
    protected $_modelName = 'Kwf_Util_Model_Redirects';
    protected $_buttons = array('save');
    protected $_permissions = array('save', 'add');

    public static function getDomains()
    {
        if (!Kwf_Component_Data_Root::getComponentClass()) {
            return null;
        }
        $ret = array();
        $acl = Zend_Registry::get('acl');
        $user = Kwf_Registry::get('userModel')->getAuthedUser();
        foreach (Kwf_Component_Data_Root::getInstance()->getDomainComponents() as $component) {
            if ($acl->getComponentAcl()->isAllowed($user, $component)) {
                $ret[$component->dbId] = $component->name;
            }
        }
        return $ret;
    }

    protected function _initFields()
    {
        parent::_initFields();
        $domains = self::getDomains();
        if ($domains && count($domains) > 1) {
            $this->_form->add(new Kwf_Form_Field_Select('domain_component_id', trlKwf('Domain')))
                ->setWidth(150)
                ->setValues($domains)
                ->setAllowBlank(false);
        }

        $fs = $this->_form->add(new Kwf_Form_Container_FieldSet(trlKwf('Source')));
        $fs->add(new Kwf_Form_Field_Select('type', trlKwf('Type')))
            ->setWidth(150)
            ->setValues(array(
                'path' => trlKwf('Path'),
                'domain' => trlKwf('Domain'),
                'domainPath' => trlKwf('Domain and Path'),
            ))
            ->setAllowBlank(false);
        $fs->add(new Kwf_Form_Field_TextField('source', trlKwf('Source')))
            ->setWidth(500)
            ->setAllowBlank(false);

        $fs = $this->_form->add(new Kwf_Form_Container_FieldSet(trlKwf('Target')));
        $cards = $fs->add(new Kwf_Form_Container_Cards('target_type', trlKwf('Type')));

        if (Kwf_Registry::get('acl') instanceof Kwf_Acl_Component) {
            $card = $cards->add();
            $card->setName('intern');
            $card->fields->setFormName('intern');
            $card->setTitle(trlKwf('Internal Page'));
            $card->add(new Kwf_Form_Field_PageSelect('target', trlKwf('Target')))
                ->setControllerUrl('/kwf/redirects/pages')
                ->setAllowBlank(false);

            $card = $cards->add();
            $card->setName('downloadTag');
            $card->fields->setFormName('downloadTag');
            $card->setTitle(trlKwf('Internal Download'));
            $card->add(new Kwf_Form_Field_TextField('target', trlKwf('Component-Id')))
                ->setAllowBlank(false);
        }

        $card = $cards->add();
        $card->setName('extern');
        $card->fields->setFormName('extern');
        $card->setTitle(trlKwf('External Url'));
        $card->add(new Kwf_Form_Field_UrlField('target', trlKwf('Target')))
            ->setAllowBlank(false)
            ->setWidth(500);

        $this->_form->add(new Kwf_Form_Field_TextField('comment', trlKwf('Comment')))
            ->setWidth(500);
    }

    protected function _beforeSave(Kwf_Model_Row_Interface $row)
    {
        parent::_beforeSave($row);
        $domains = self::getDomains();
        if ($domains && count($domains) == 1) {
            $keys = array_keys($domains);
            $row->domain_component_id = array_pop($keys);
        }
    }

    protected function _hasPermissions($row, $action)
    {
        $ret = parent::_hasPermissions($row, $action);

        $acl = Zend_Registry::get('acl');
        if ($ret) {
            foreach (Kwf_Component_Data_Root::getInstance()->getComponentsByDbId($row->domain_component_id, array('limit'=>1)) as $d) {
                if (!$acl->getComponentAcl()->isAllowed(Kwf_Registry::get('userModel')->getAuthedUser(), $d)) {
                    $ret = false;
                    break;
                }
            }
        }
        return $ret;
    }
}


text:
    $('.button-collapse').sideNav({
        menuWidth: 300, // Default is 300
        edge: 'left', // Choose the horizontal origin
        closeOnClick: true, // Closes side-nav on <a> clicks, useful for Angular/Meteor
        draggable: true // Choose whether you can drag to open on touch screens
      }
    );


text:
from .query import QueryRequest
from .text import TextRequest
from .voice import VoiceRequest

from .query import Entry
from .query import Entity

"""
apiai
~~~~~~~~~~~~~~~~
This module provides a ApiAI classes to manage requests.
"""

__all__ = [
    'QueryRequest',
    'TextRequest',
    'VoiceRequest',
    'Entry',
    'Entity'
]


text:
<?php

class Scalr_Util_IgnoringQueue implements Scalr_Util_Queue {

    protected $queue;

    protected $ignoringSet;

    /**
     * @param Scalr_Util_Queue $queue
     * @param Scalr_Util_Set $ignoringSet
     */
    function __construct ($queue, $ignoringSet) {
        $this->queue = $queue;
        $this->ignoringSet = $ignoringSet;
    }

    function put ($data) {
        if (!$this->ignoringSet->contains($data)) {
            return $this->queue->put($data);
        }
        return false;
    }

    function peek () {
        do {
            $item = $this->queue->peek();
        } while ($item !== null && $this->ignoringSet->contains($item));

        return $item;
    }

    function capacity () {
        return $this->queue->capacity();
    }

    /**
     * @return Scalr_Util_Queue
     */
    function getWrappedQueue () {
        return $this->queue;
    }

    /**
     * @return Scalr_Util_Set
     */
    function getIgnoringSet () {
        return $this->ignoringSet;
    }
}


text:
<!DOCTYPE html>

        <meta charset="utf-8"/>
        <title> QuickHull 3D |  Alex Catalán</title>
        <link rel="stylesheet" href="/css/style.css" />
        <link rel="stylesheet" href="/css/syntax.css" />
        <link rel="stylesheet" href="/css/menu.css" />
        <link rel="stylesheet" href="/css/sidebar.css" />
        <meta name="description" content="Game Engineer"/>
        <meta name="author" content="Alex Catalán"/>
        <link rel="icon" href="/favicon.ico" type="image/x-icon">
        <link rel="alternate" type="application/rss+xml" title="RSS Feed" href="/feed.xml" />

        <link rel="stylesheet" href="/resources/fontello/css/fontello.css">
        <link rel="stylesheet" href="/resources/fontello/css/animation.css">

Alex Catalán

Game Engineer

Home

Categories

computational geometry

graphics

interactive systems

unity3d

games

Archive

Personal

Curriculum

Cover Letter

QuickHull 3D

            <metadata>
                <time datetime="2013-04-13">Apr 13, 2013</time> |

                computational geometry

                 |  Alex Catalán
            </metadata>

    At the Computational Geometry course I have implemented the Quickhull algorithm for its application in 3D, following the paper "Barber, C. B., Dobkin, D. P., & Huhdanpaa, H. T. (1996). The Quickhull algorithm for convex hulls. ACM Trans. on Mathematical Software, 22(4), 469—483". And following the example of this java applet developed by UNSW School of Computer Science and Engineering.

        Algorithm

        The algorithm proposed by the paper says:

            create a simplex of d+1 points

            for each facet F

            for each unassigned point p

            if p is above F

            assign p to F's outside set

            for each facet F with a non-empty outside set

            select the furthest point p of F's outside set

            initialize the visible set V to F

            for all unvisited neighbors N of facets in V

            if p is above N

            add N to V

            the boundary of V is the set of horizon ridges H

            for each ridge R in H

            create a new facet from R and p

            link the new facet to its neighbors

            for each new facet F'

            for each unassigned point q in an outside set of a facet in V

            if q is above F'

            assign q to F''s outside set

            delete the facets in V

        I made some changes on my implementation but the essence is the same.

        Data Structures

        Before explaining the implementation, it should explain how are the data structures.

            vector3f is a 3 float vector with some geometrical functions (dotProduct, crossProduct, etc...)

            facet is a 3 int vector and a std::Vector<int>, to store the indices of the 3 points of the triangle and the indices of the outside points.

            All the collection used are class std::Vector

            The QuickHull class has:

                    A points collection is a std::Vector <vector3f>, where there are stored all the points. This should not be changed any time.

                    A facets collection is a std::Vector <facet>, where there are stored all the facets.

        Implementation

        The first thing to do is calculate the simplex. The simplex is a triangle that separates points in two areas. This will take 3 points, two with maximum X and Y coordinate, and another with the minimum Z coordinate of the whole set of points.

        After the simplex is created, split the remaining points that are visible for the two facets from the simplex (a triangle in 3D has 2 faces). To know if a point is visible for a facet, we have to calculate if this point is above the facet. And to know if a point is above a plane, we evaluate the point on the plane normal.

        Now the main loop begins. In each iteration and for each facet, the facet's furthest point is calculated. This point p is checked whether is visible from the facets neighbourhood, the neighbourhood facets are the ones that have at least one vertex in common, then all ridges and outside points from the neighbourhood facets are saved in different collections.

        The ridge collection determine the boundary from the hole that is created when the neighbourhood facets are deleted. Using this boundary and the furthest point p will create new triangles using the Delaunay algorithm.

        Finally once created the new triangles will split the points of collection points on the new triangles created. This loop is executed while there are facets with outside points.

        Solved Facts

        Triangle orientation

        One of the problems that can happen when you are adding new triangles on a closed polygon, is that according to the order of the vertices of the triangles, the normal of the triangle is pointing inside the polygon. This is a problem because to perform calculations to find the location of the points on the triangle requires that the normal is facing outside the polygon.

        The solution implemented, was using a reference point. This point must always remain within the polygon, even in the first iteration. Therefore, is calculated the baricenter of the initial simplex.

        Here is the source code: SRC

My name is Alex Catalán (MaDowen) born in 1988 at Barcelona, Spain.

Computer Engineer since 2015, I have proffesional experience on web and mobile development. Right now I'm working hard to get into the Game Industry in the future.

I've been coding for over 7 years with multiple languajes. I have knowledge of 3D Programming. Now I'm learning WebGL and developing an Engine with it for my Degree Final Project.

                © <time>2014</time> Alex Catalán


text:
import { module } from 'angular';
import { Subject, Subscription } from 'rxjs';

import {
  IPipeline,
  IStage,
  IStageOrTriggerTypeConfig,
  IStageTypeConfig,
  ITrigger,
  ITriggerTypeConfig
} from 'core/domain';
import { PIPELINE_CONFIG_PROVIDER } from 'core/pipeline/config/pipelineConfigProvider';

export interface IStageValidationResults {
  stage: IStage;
  messages: string[];
}

export interface IPipelineValidationResults {
  stages: IStageValidationResults[];
  pipeline: string[];
  hasWarnings?: boolean;
  preventSave?: boolean;
}

export interface IValidatorConfig {
  type: string;
  message?: string;
  skipValidation?: (pipeline: IPipeline, stage: IStage) => boolean;
  preventSave?: boolean;
  fieldName?: string;
  fieldLabel?: string;
  checkParentTriggers?: boolean;
}

export interface IStageOrTriggerValidator {
  validate(pipeline: IPipeline,
           stageOrTrigger: IStage | ITrigger,
           validator: IValidatorConfig,
           config: IStageOrTriggerTypeConfig): string | ng.IPromise<string>;
}

export interface ICustomValidator extends IStageOrTriggerValidator, IValidatorConfig {
  [k: string]: any;
}

export class PipelineConfigValidator implements ng.IServiceProvider {

  private validators: Map<string, IStageOrTriggerValidator> = new Map();
  private validationStream: Subject<IPipelineValidationResults> = new Subject();

  public registerValidator(type: string, validator: IStageOrTriggerValidator) {
    this.validators.set(type, validator);
  }

  constructor(private $log: ng.ILogService,
              private $q: ng.IQService,
              private pipelineConfig: any) {
    'ngInject';
  }

  public validatePipeline(pipeline: IPipeline): ng.IPromise<IPipelineValidationResults> {
    const stages: IStage[] = pipeline.stages || [],
          triggers: ITrigger[] = pipeline.triggers || [],
          validations: ng.IPromise<string>[] = [],
          pipelineValidations: string[] = this.getPipelineLevelValidations(pipeline),
          stageValidations: Map<IStage, string[]> = new Map();
    let preventSave = false;

    triggers.forEach((trigger, index) => {
      const config: ITriggerTypeConfig = this.pipelineConfig.getTriggerConfig(trigger.type);
      if (config && config.validators) {
        config.validators.forEach((validator) => {
          const typedValidator = this.getValidator(validator);
          if (!typedValidator) {
            this.$log.warn(`No validator of type "${validator.type}" found, ignoring validation on trigger "${(index + 1)}" (${trigger.type})`);
          } else {
            validations.push(
              this.$q.resolve<string>(typedValidator.validate(pipeline, trigger, validator, config))
                .then(message => {
                  if (message && !pipelineValidations.includes(message)) {
                    pipelineValidations.push(message);
                    if (validator.preventSave) {
                      preventSave = true;
                    }
                  }
                  return message;
                })
            );
          }
        });
      }
    });
    stages.forEach((stage) => {
      const config: IStageTypeConfig = this.pipelineConfig.getStageConfig(stage);
      if (config && config.validators) {
        config.validators.forEach((validator) => {
          if (validator.skipValidation && validator.skipValidation(pipeline, stage)) {
            return;
          }
          const typedValidator = this.getValidator(validator);
          if (!typedValidator) {
            this.$log.warn(`No validator of type "${validator.type}" found, ignoring validation on stage "${stage.name}" (${stage.type})`);
          } else {
            validations.push(
              this.$q.resolve<string>(typedValidator.validate(pipeline, stage, validator, config)).then((message: string) => {
                if (message) {
                  if (!stageValidations.has(stage)) {
                    stageValidations.set(stage, [] as string[]);
                  }
                  if (!stageValidations.get(stage).includes(message)) {
                    stageValidations.get(stage).push(message);
                    if (validator.preventSave) {
                      preventSave = true;
                    }
                  }
                }
                return message;
              })
            );
          }
        });
      }
    });

    return this.$q.all(validations).then(() => {
      const results = {
        stages: Array.from(stageValidations).map(([stage, messages]) => ({ stage, messages })),
        pipeline: pipelineValidations,
        hasWarnings: false,
        preventSave,
      };
      results.hasWarnings = results.pipeline.length > 0 || results.stages.length > 0;
      this.validationStream.next(results);
      return results;
    });
  }

  private getValidator(validator: IValidatorConfig): IStageOrTriggerValidator {
    return validator.type === 'custom' ? validator as ICustomValidator : this.validators.get(validator.type);
  }

  private getPipelineLevelValidations(pipeline: IPipeline): string[] {
    const messages: string[] = [];
    if ((pipeline.parameterConfig || []).some(p => !p.name)) {
      messages.push('<b>Name</b> is a required field for parameters.');
    }
    if (pipeline.strategy && !(pipeline.stages.some(stage => stage.type === 'deploy'))) {
      messages.push('To be able to create new server groups, a custom strategy should contain a Deploy stage.');
    }
    return messages;
  }

  /**
   * Subscribes to validation events
   * @param method
   * @returns {Subscription}, which should be unsubscribed when the subscriber is destroyed
   */
  public subscribe(method: (result: IPipelineValidationResults) => any): Subscription {
    return this.validationStream.subscribe(method);
  }

  public $get() {
    return this;
  }

}

export const PIPELINE_CONFIG_VALIDATOR = 'spinnaker.core.pipeline.config.validator';
module(PIPELINE_CONFIG_VALIDATOR, [
  PIPELINE_CONFIG_PROVIDER,
]).service('pipelineConfigValidator', PipelineConfigValidator)
  .run((pipelineConfigValidator: PipelineConfigValidator) => {
    // placeholder - custom validators must implement the ICustomValidator interface
    pipelineConfigValidator.registerValidator('custom', null);
  });


text:
/**
 * T'MediaArt library for Javascript
 *  - MajVj extension - frame plugin - ledpanel -
 * @param options options (See MajVj.prototype.create)
 */
MajVj.frame.ledpanel = function(options) {
  var size = options.size || 128;
  this._columns = (options.width / size) | 0;
  this._rows = (options.height / size) | 0;
  this._effect = options.mv.create('effect', 'mask', { patch: 'led' });
  this._effect.properties.resolution = [ this._columns, this._rows ];

  this.properties = {
    image: options.screen.createImage(this._columns, this._rows),
    volume: 1.0
  }

  this._texture = options.screen.createTexture(
      this.properties.image, true, Tma3DScreen.FILTER_NEAREST);
};

/**
 * Loads resource asynchronously.
 * @return a Promise object
 */
MajVj.frame.ledpanel.load = function() {
  return new Promise(function(resolve, reject) {
    resolve();
  });
};

/**
 * Handles screen resize.
 * @param aspect screen aspect ratio
 */
MajVj.frame.ledpanel.prototype.onresize = function(aspect) {
};

/**
 * Draws a frame.
 * @param delta delta time from the last rendering
 */
MajVj.frame.ledpanel.prototype.draw = function(delta) {
  this._texture.update();
  this._effect.properties.volume = this.properties.volume;
  this._effect.draw(delta, this._texture);
};