text:
(function () {
  'use strict';

  angular
    .module('ap-file-upload')
    .factory('File', File);

  File.$inject = ['$q', '$http'];

  function File($q, $http) {

    function File(data, options) {
      var file = this;
      options = angular.copy(options);

      file.data = data;
      file.newFile = options.newFile !== false;
      file.locked = options.locked || false;
      file.allowCaptions = options.allowCaptions || false;
      file.isImage = data.type.match('image.*');

      file.presign = options.presign || null;
      file.query = options.query || null;
      file.createRecord = options.createRecord || null;
      file.removeRecord = options.removeRecord || null;

      if (file.newFile) {
        if (file.isImage) {
          getDataUrl(data).then(function(src) {
            file.data.src = src;
          })
        }
      } else {
        file.uploading = false;
        file.hasErrors = false;
      }

      return file;
    }

    //
    // Public methods
    //

    File.prototype.start = function() {
      this._upload();
    };

    File.prototype.retry = function() {
      this._upload();
    };

    File.prototype.cancel = function() {
      if (this._xhr) {
        this._xhr.abort();
      }

      this.onRemove(this);
    };

    File.prototype.remove = function() {
      var file = this;
      var $promise = file._deleteFileRecord();

      return $promise.then(function(){
        file.onRemove(file);
      });
    };

    File.prototype.setCaption = function(caption) {
      var file = this;

      file.data.caption = caption;

      file.onCaptionChange({
        caption: file.data.caption,
        id:   file.data.id,
        name: file.data.name,
        path: file.data.path,
        size: file.data.size,
        type: file.data.type
      });
    };

    File.prototype.onStart = function() { /* noop */ };
    File.prototype.onRemove = function() { /* noop */ };
    File.prototype.onProgress = function() { /* noop */ };
    File.prototype.onSuccess = function() { /* noop */ };
    File.prototype.onFailure = function() { /* noop */ };
    File.prototype.onCaptionChange = function() { /* noop */ };

    //
    // Private methods
    //

    File.prototype._upload = function() {
      var file = this;

      file.uploading = true;
      file.hasErrors = false;
      file.progress = 0;

      file.onStart();

      file._getPresignedUrl()
        .then(transformResponse)
        .then(storeFilePath.bind(file))
        .then(storeFileId.bind(file))
        .then(storePresignedUrl.bind(file))
        .then(uploadToS3.bind(file))
        .then(checkSuccessCode.bind(file))
        .then(transformXhrResponse.bind(file))
        .then(createFileRecord.bind(file))
        .then(fileRecordSuccess.bind(file))
        .catch(function(err) {
          file._failed(err);
        });
    };

    File.prototype._deleteFileRecord = function() {
      var params = this.removeRecord.params || {};
      params.fileId = this.data.id;

      return this.removeRecord.resource.delete(params).$promise;
    };

    File.prototype._getPresignedUrl = function() {
      var params = {
        param: this.presign.params || {}
      };

      params.param.fileName = this.data.name;
      params.param.fileType = this.data.type;
      params.param.fileSize = this.data.size;

      return this.presign.resource.save(params).$promise;
    };

    File.prototype._onProgress = function(e) {
      var progress = Math.round(e.lengthComputable ? e.loaded * 100 / e.total : 0);
      this.onProgress(progress);
    };

    File.prototype._failed = function(err) {
      var file = this;
      file.hasErrors = true;
      file.uploading = false;
      file.onFailure(err);
    };

    //
    // Helper methods
    //

    function transformResponse(response) {
      return response.result.content;
    }

    function storeFilePath(content) {
      var file = this;

      file.data.path = content.filePath;
      return content;
    }

    function storeFileId(content) {
      var file = this;

      if (!file.createRecord) {
        file.data.id = content.fileId;
      }

      return content;
    }

    function storePresignedUrl(content) {
      var deferred = $q.defer();
      var preSignedURL = content.preSignedURL;

      if (preSignedURL) {
        this.preSignedURL = preSignedURL;
        deferred.resolve()
      } else {
        deferred.reject('Response from presigned URL request had no presigned URL');
      }

      return deferred.promise;
    }

    function uploadToS3() {
      var file = this;
      var deferred = $q.defer();
      var xhr = file._xhr = new XMLHttpRequest();

      xhr.upload.onprogress = file._onProgress.bind(file);

      xhr.onload = function() {
        deferred.resolve();
      };

      xhr.onerror = function() {
        deferred.reject();
      };

      xhr.open('PUT', file.preSignedURL, true);
      xhr.setRequestHeader('Content-Type', file.data.type);
      xhr.send(file.data);

      return deferred.promise;
    }

    function checkSuccessCode() {
      var deferred = $q.defer();
      var status = this._xhr.status;

      if ((status >= 200 && status < 300) || status === 304) {
        deferred.resolve()
      } else {
        deferred.reject('File upload to S3 failed: ' + status);
      }

      return deferred.promise;
    }

    function transformXhrResponse() {
      var xhr = this._xhr;
      var headers = parseHeaders(xhr.getAllResponseHeaders());
      var response = xhr.response;
      var headersGetter = makeHeadersGetter(headers);

      angular.forEach($http.defaults.transformResponse, function(transformFn) {
        response = transformFn(response, headersGetter);
      });

      return response;
    }

    function createFileRecord() {
      if (this.createRecord) {
        var params = {
          param: this.createRecord.params || {}
        };

        params.param.fileName = this.data.name;
        params.param.filePath = this.data.path;
        params.param.fileType = this.data.type;
        params.param.fileSize = this.data.size;

        return this.createRecord.resource.save(params).$promise;
      } else {
        return this.data;
      }
    }

    function fileRecordSuccess(response) {
      var file = this;

      if (response.result) {
        file.data.id = response.result.content.fileId;
      } else {
        file.data.id = response.id
      }

      var filedata = {
        id: file.data.id,
        name: file.data.name,
        path: file.data.path,
        size: file.data.size,
        type: file.data.type
      }

      file.hasErrors = false;
      file.uploading = false;
      file.onSuccess(response, filedata);
    }

    function parseHeaders(headers) {
      var parsed = {}, key, val, i;

      if (!headers) return parsed;

      angular.forEach(headers.split('\n'), function(line) {
        i = line.indexOf(':');
        key = line.slice(0, i).trim().toLowerCase();
        val = line.slice(i + 1).trim();

        if (key) {
          parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;
        }
      });

      return parsed;
    }

    function makeHeadersGetter(parsedHeaders) {
      return function(name) {
        if (name) {
          return parsedHeaders[name.toLowerCase()] || null;
        }
        return parsedHeaders;
      };
    }

    function getDataUrl(fileData) {
      var deferred = $q.defer();
      var reader   = new FileReader();

      reader.onload = function(){
        deferred.resolve(reader.result);
      };

      reader.onerror = function() {
        deferred.reject();
      }

      reader.readAsDataURL(fileData);

      return deferred.promise;
    }

    return File;

  }
})();


text:
<!DOCTYPE html>

    <meta charset="utf-8">
    <title>zebra.ui.zCanvas</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.9.1/build/cssgrids/cssgrids-min.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <link rel="stylesheet" href="../assets/css/main.css" id="site_styles">
    <link rel="shortcut icon" type="image/png" href="../assets/favicon.png">

Zebra API Doc

APIs

Classes

Packages

            <input type="search" id="api-filter" placeholder="Type to filter APIs">

zebra.$cache

zebra.Class()

zebra.data.Item

zebra.data.ListModel

zebra.data.Matrix

zebra.data.SingleLineTxt

zebra.data.Text

zebra.data.TextModel

zebra.data.TreeModel

zebra.Dummy

zebra.forName()

zebra.instanceOf()

zebra.Interface()

zebra.io.b64decode()

zebra.io.b64encode()

zebra.io.GET()

zebra.io.HTTP

zebra.io.ID()

zebra.io.JRPC

zebra.io.JRPC.invoke()

zebra.io.POST()

zebra.io.QS

zebra.io.Service

zebra.io.XRPC

zebra.io.XRPC.invoke()

zebra.layout.BorderLayout

zebra.layout.Constraints

zebra.layout.FlowLayout

zebra.layout.getDirectAt()

zebra.layout.getDirectChild()

zebra.layout.getMaxPreferredSize()

zebra.layout.getTopParent()

zebra.layout.GridLayout

zebra.layout.Layout

zebra.layout.Layoutable

zebra.layout.ListLayout

zebra.layout.PercentLayout

zebra.layout.RasterLayout

zebra.layout.StackLayout

zebra.layout.toChildOrigin()

zebra.layout.toParentOrigin()

zebra.namespace()

zebra.ready()

zebra.ui.BaseLayer

zebra.ui.BaseList

zebra.ui.BoldLabel

zebra.ui.Border

zebra.ui.BorderPan

zebra.ui.Button

zebra.ui.Checkbox

zebra.ui.Checkbox.Box

zebra.ui.Combo

zebra.ui.Combo.ComboPadPan

zebra.ui.Combo.ContentPan

zebra.ui.Combo.EditableContentPan

zebra.ui.Combo.ReadonlyContentPan

zebra.ui.ComboArrowView

zebra.ui.CommandManager

zebra.ui.CompList

zebra.ui.Composite

zebra.ui.CompositeEvStatePan

zebra.ui.CompositeView

zebra.ui.CompRender

zebra.ui.CursorManager

zebra.ui.designer.ShaperPan

zebra.ui.Dotted

zebra.ui.Etched

zebra.ui.EventManager

zebra.ui.EvStatePan

zebra.ui.ExtendablePan

zebra.ui.FocusManager

zebra.ui.Font

zebra.ui.Gradient

zebra.ui.grid.BaseCaption

zebra.ui.grid.CompGridCaption

zebra.ui.grid.CompGridCaption.TitlePan

zebra.ui.grid.DefEditors

zebra.ui.grid.DefViews

zebra.ui.grid.Grid

zebra.ui.grid.GridCaption

zebra.ui.grid.GridStretchPan

zebra.ui.grid.Metrics

zebra.ui.Group

zebra.ui.HtmlElement

zebra.ui.HtmlTextArea

zebra.ui.HtmlTextField

zebra.ui.HtmlTextInput

zebra.ui.ImageLabel

zebra.ui.ImagePan

zebra.ui.InputEvent

zebra.ui.KeyEvent

zebra.ui.Label

zebra.ui.Line

zebra.ui.Link

zebra.ui.List

zebra.ui.List.ViewProvider

zebra.ui.loadImage()

zebra.ui.Manager

zebra.ui.Menu

zebra.ui.Menubar

zebra.ui.MenuItem

zebra.ui.MLabel

zebra.ui.MobileScrollMan

zebra.ui.MouseEvent

zebra.ui.MouseWheelSupport

zebra.ui.PaintManager

zebra.ui.PaintManImpl

zebra.ui.Panel

zebra.ui.PassTextField

zebra.ui.PasswordText

zebra.ui.Pattern

zebra.ui.Picture

zebra.ui.PopupLayer

zebra.ui.PopupManager

zebra.ui.Progress

zebra.ui.Radial

zebra.ui.Radiobox

zebra.ui.RadioView

zebra.ui.Raised

zebra.ui.Render

zebra.ui.RootLayer

zebra.ui.RoundBorder

zebra.ui.Scroll

zebra.ui.ScrollManager

zebra.ui.ScrollPan

zebra.ui.showModalWindow()

zebra.ui.showWindow()

zebra.ui.Slider

zebra.ui.SplitPan

zebra.ui.StatePan

zebra.ui.StatusBar

zebra.ui.StringRender

zebra.ui.Sunken

zebra.ui.SwitchManager

zebra.ui.Tabs

zebra.ui.Tabs.TabView

zebra.ui.TextArea

zebra.ui.TextField

zebra.ui.TextRender

zebra.ui.TitledBorder

zebra.ui.Toolbar

zebra.ui.Tooltip

zebra.ui.tree.$IM

zebra.ui.tree.BaseTree

zebra.ui.tree.CompTree

zebra.ui.tree.DefEditors

zebra.ui.tree.DefViews

zebra.ui.tree.Tree

zebra.ui.tree.TreeSignView

zebra.ui.VideoPan

zebra.ui.View

zebra.ui.ViewPan

zebra.ui.ViewSet

zebra.ui.Window

zebra.ui.WinLayer

zebra.ui.zCanvas

zebra.URL

zebra.util.Bag

zebra.util.findInTree()

zebra.util.intersection();

zebra.util.Listeners

zebra.util.newInstance()

zebra.util.Position

zebra.util.Position.Metric

zebra.util.rgb

zebra.util.shutdownAll

zebra.util.task

zebra.util.TaskCotext

data

io

layout

ui

ui.designer

ui.grid

ui.tree

util

zebra

zebra.ui.zCanvas Class

        Extends zebra.ui.Panel

zCanvas zebra UI component class. This is one of the key
class everybody has to use to start building an UI. The class is a wrapper
for HTML Canvas element. Internally it catches all native HTML Canvas
events and translates its into Zebra UI events.

zCanvas instantiation triggers a new HTML Canvas will be created
and added to HTML DOM tree.  It happens if developer doesn't pass
an HTML Canvas element reference or an ID of existing HTML Canvas
element If developers need to re-use an existent in DOM tree canvas
element they have to pass id of the canvas that has to be used as basis
for zebra UI creation or reference to a HTML Canvas element:

  // a new HTML canvas element is created and added into HTML DOM tree
  var canvas = zebra.ui.zCanvas();

  // a new HTML canvas element is created into HTML DOM tree
  var canvas = zebra.ui.zCanvas(400,500);  // pass canvas size

  // stick to existent HTML canvas element
  var canvas = zebra.ui.zCanvas("ExistentCanvasID");

The zCanvas has layered structure. Every layer is responsible for
showing and controlling a dedicated type of UI elements like windows
pop-up menus, tool tips and so on. Developers have to build an own UI
hierarchy on the canvas root layer. The layer is standard UI panel
that is accessible as zCanvas component instance "root" field.

  // create canvas
  var canvas = zebra.ui.zCanvas(400,500);

  // save reference to canvas root layer where
  // hierarchy of UI components have to be hosted
  var root = canvas.root;

  // fill root with UI components
  var label = new zebra.ui.Label("Label");
  label.setBounds(10,10,100,50);
  root.add(label);

Constructor

zebra.ui.zCanvas

            (

                        [element]

                        [width]

                        [height]

)

Parameters:

                        [element]
                        String | Canvas
                        optional

an ID of a HTML canvas element or
reference to an HTML Canvas element.

                        [width]
                        Integer
                        optional

a width of an HTML canvas element

                        [height]
                        Integer
                        optional

a height of an HTML canvas element

            Index

Methods

Attributes

Events

Item Index

Methods

                                $mouseMoved

                                fullScreen

                                getLayer

                                setAttribute

                                setStyles

Attributes

                                $da

                                canvas

                                isFullScreen

Events

                                canvasInitialized

Methods

$mouseMoved

            (

                        id

                        e

)

        protected

Catch native canvas mouse move events

Parameters:

                        id
                        String

an touch id (for touchable devices)

                        e
                        String

a mouse event that has been triggered by canvas element

    {
        pageX : {Integer},
        pageY : {Integer},
        target: {HTMLElement}
    }

fullScreen

        ()

Stretch Canvas to occupy full screen area

getLayer

            (

                        id

)

            zebra.ui.Panel

Get the canvas layer by the specified layer ID. Layer is a children component
of the canvas UI component. Every layer has an ID assigned to it the method
actually allows developers to get the canvas children component by its ID

Parameters:

                        id
                        String

a layer ID

                        Return: zebra.ui.Panel

a layer (children) component

setAttribute

            (

                        name

                        value

)

        protected

Set HTML Canvas element hosted by the UI component attribute

Parameters:

                        name
                        String

an attribute name

                        value
                        String

an attribute value

setStyles

            (

                        styles

)

        protected

Set HTML canvas element hosted by the UI component CSS styles

Parameters:

                        styles
                        Object

styles to be applied to the HTML canvas component

Attributes

$da

    Object
                x:Integer, y:Integer, width:Integer, height:Integer

        private

Keeps rectangular "dirty" area of the canvas component

canvas

    Canvas

        protected

        readonly

Reference to HTML Canvas element  where the zebra canvas UI
components are hosted

isFullScreen

    Boolean

        readonly

Indicate if the canvas has to be stretched to
fill the whole screen area.

Events

canvasInitialized

Implement the event handler method  to catch canvas initialized event.
The event is triggered once the canvas has been initiated and all properties
listeners of the canvas are set upped. The event can be used to load
saved data.

var p = new zebra.ui.zCanvas(300, 300, [
     function canvasInitialized() {
         // do something
     }
]);

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
	<item android:drawable="@drawable/ic_search_back_normal" />
	<item android:drawable="@drawable/ic_search_back_selected" android:state_pressed="true" />
</selector>


text:
<?php

defined('_JEXEC') or die;

$published = $this->state->get('filter.state');
?>

		<button type="button" role="presentation" class="close" data-dismiss="modal">×</button>

<?php echo JText::_('COM_WEBLINKS_BATCH_OPTIONS'); ?>

<?php echo JText::_('COM_WEBLINKS_BATCH_TIP'); ?>

					<?php echo JHtml::_('batch.tag'); ?>

					<?php echo JHtml::_('batch.language'); ?>

					<?php echo JHtml::_('batch.access'); ?>

			<?php if ($published >= 0) : ?>

						<?php echo JHtml::_('batch.item', 'com_weblinks'); ?>

			<?php endif; ?>

		<button class="btn" type="button" onclick="document.id('batch-category-id').value='';document.id('batch-access').value='';document.id('batch-language-id').value='';document.id('batch-tag-id)').value=''" data-dismiss="modal">
			<?php echo JText::_('JCANCEL'); ?>
		</button>
		<button class="btn btn-primary" type="submit" onclick="Joomla.submitbutton('weblink.batch');">
			<?php echo JText::_('JGLOBAL_BATCH_PROCESS'); ?>
		</button>


text:
/**
 * QuickBlox JavaScript SDK
 * WebRTC Module (WebRTC session model)
 */

/**
 * User's callbacks (listener-functions):
 * - onUserNotAnswerListener(session, userID)
 * - onRemoteStreamListener(session, userID, stream)
 * - onSessionConnectionStateChangedListener(session, userID, connectionState)
 * - onSessionCloseListener(session)
 * - onCallStatsReport(session, userId, stats)
 */

var config = require('../../qbConfig');
var RTCPeerConnection = require('./qbRTCPeerConnection');
var Utils = require('../../qbUtils');
var Helpers = require('./qbWebRTCHelpers');
var SignalingConstants = require('./qbWebRTCSignalingConstants');

/**
 * State of a session
 */
WebRTCSession.State = {
  NEW: 1,
  ACTIVE: 2,
  HUNGUP: 3,
  REJECTED: 4,
  CLOSED: 5
};

/**
 * Creates a session
 * @param {number} An ID if the call's initiator
 * @param {array} An array with opponents
 * @param {enum} Type of a call
 */
function WebRTCSession(sessionID, initiatorID, opIDs, callType, signalingProvider, currentUserID) {
  this.ID = sessionID ? sessionID : generateUUID();
  this.state = WebRTCSession.State.NEW;

  this.initiatorID = parseInt(initiatorID);
  this.opponentsIDs = opIDs;
  this.callType = parseInt(callType);

  this.peerConnections = {};

  this.localStream = null;

  this.signalingProvider = signalingProvider;

  this.currentUserID = currentUserID;

  /**
   * we use this timeout to fix next issue:
   * "From Android/iOS make a call to Web and kill the Android/iOS app instantly. Web accept/reject popup will be still visible.
   * We need a way to hide it if sach situation happened."
   */
  this.answerTimer = null;

  this.startCallTime = 0;
  this.acceptCallTime = 0;
}

/**
 * Get the user media stream
 * @param {map} A map media stream constrains
 * @param {function} A callback to get a result of the function
 */
WebRTCSession.prototype.getUserMedia = function(params, callback) {
  var getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia;

  if(!getUserMedia) {
    throw new Error('getUserMedia() is not supported in your browser');
  }

  getUserMedia = getUserMedia.bind(navigator);

  var self = this;

  /**
   * Additional parameters for Media Constraints
   * http://tools.ietf.org/html/draft-alvestrand-constraints-resolution-00
   *
   * googEchoCancellation: true
   * googAutoGainControl: true
   * googNoiseSuppression: true
   * googHighpassFilter: true
   * minWidth: 640
   * minHeight: 480
   * maxWidth: 1280
   * maxHeight: 720
   * minFrameRate: 60
   * maxAspectRatio: 1.333
   */

  getUserMedia(
    {
      audio: params.audio || false,
      video: params.video || false

    },function(stream) {
      self.localStream = stream;

      if (params.elemId){
        self.attachMediaStream(params.elemId, stream, params.options);
      }

      callback(null, stream);
    },function(err) {
      callback(err, null);
    }
  );
};

/**
 * Attach media stream to audio/video element
 * @param {string} The Id of an ellement to attach a stream
 * @param {object} The steram to attach
 * @param {object} The additional options
 */
WebRTCSession.prototype.attachMediaStream = function(id, stream, options) {
  var elem = document.getElementById(id);

  if (elem) {
    var URL = window.URL || window.webkitURL;
    elem.src = URL.createObjectURL(stream);

    if (options && options.muted) elem.muted = true;

    if (options && options.mirror) {
      elem.style.webkitTransform = 'scaleX(-1)';
      elem.style.transform = 'scaleX(-1)';
    }

    elem.play();
  } else {
    throw new Error('Unable to attach media stream, element ' + id  + ' is undefined');
  }
};

/**
 * Get the state of connection
 * @param {number} The User Id
 */
WebRTCSession.prototype.connectionStateForUser = function(userID){
  var peerConnection = this.peerConnections[userID];

  if(peerConnection){
    return peerConnection.state;
  }

  return null;
};

/**
 * Detach media stream from audio/video element
 * @param {string} The Id of an element to detach a stream
 */
WebRTCSession.prototype.detachMediaStream = function(id){
  var elem = document.getElementById(id);

  if (elem) {
    elem.pause();
    elem.src = "";
  }
};

/**
 * [Initiate a call]
 * @param  {object}   extension [custom parametrs]
 * @param  {Function} callback
 */
WebRTCSession.prototype.call = function(extension, callback) {
  var self = this,
      ext = _prepareExtension(extension),
      isOnlineline = window.navigator.onLine,
      error = null;

  Helpers.trace('Call, extension: ' + JSON.stringify(ext));

  if(isOnlineline) {
    self.state = WebRTCSession.State.ACTIVE;

    // create a peer connection for each opponent
    self.opponentsIDs.forEach(function(userID, i, arr) {
      self._callInternal(userID, ext, true);
    });
  } else {
    self.state = WebRTCSession.State.CLOSED;
    error = Utils.getError(408, 'Call.ERROR - ERR_INTERNET_DISCONNECTED');
  }

  if (typeof callback === 'function') {
    callback(error);
  }
};

WebRTCSession.prototype._callInternal = function(userID, extension, withOnNotAnswerCallback) {
  var peer = this._createPeer(userID, 'offer');

  peer.addLocalStream(this.localStream);
  this.peerConnections[userID] = peer;

  peer.getAndSetLocalSessionDescription(function(err) {
    if (err) {
      Helpers.trace("getAndSetLocalSessionDescription error: " + err);
    } else {
      Helpers.trace("getAndSetLocalSessionDescription success");
      /** let's send call requests to user */
      peer._startDialingTimer(extension, withOnNotAnswerCallback);
    }
  });
};

/**
 * Accept a call
 * @param {array} A map with custom parameters
 */
WebRTCSession.prototype.accept = function(extension) {
  var self = this,
      ext = _prepareExtension(extension);

  Helpers.trace('Accept, extension: ' + JSON.stringify(ext));

  if(self.state === WebRTCSession.State.ACTIVE) {
    Helpers.traceError("Can't accept, the session is already active, return.");
    return;
  }

  if(self.state === WebRTCSession.State.CLOSED) {
    Helpers.traceError("Can't accept, the session is already closed, return.");
    self.stop({});
    return;
  }

  self.state = WebRTCSession.State.ACTIVE;

  self.acceptCallTime = new Date();

  self._clearAnswerTimer();

  self._acceptInternal(self.initiatorID, ext);

  /** The group call logic starts here */
  var oppIDs = self._uniqueOpponentsIDsWithoutInitiator();

  /** in a case of group video chat */
  if(oppIDs.length > 0){

    var offerTime = (self.acceptCallTime - self.startCallTime) / 1000;
    self._startWaitingOfferOrAnswerTimer(offerTime);

    /**
     * here we have to decide to which users the user should call.
     * We have a rule: If a userID1 > userID2 then a userID1 should call to userID2.
     */
    oppIDs.forEach(function(opID, i, arr) {
      if(self.currentUserID > opID){
        /** call to the user */
        self._callInternal(opID, {}, true);
      }
    });
  }
};

WebRTCSession.prototype._acceptInternal = function(userID, extension) {
  var self = this;

  /** create a peer connection */
  var peerConnection = this.peerConnections[userID];

  if(peerConnection){
    peerConnection.addLocalStream(this.localStream);

    peerConnection.setRemoteSessionDescription('offer', peerConnection.getRemoteSDP(), function(error){
      if(error){
        Helpers.traceError("'setRemoteSessionDescription' error: " + error);
      }else{
        Helpers.trace("'setRemoteSessionDescription' success");

        peerConnection.getAndSetLocalSessionDescription(function(err) {
          if (err) {
            Helpers.trace("getAndSetLocalSessionDescription error: " + err);
          } else {

            extension["sessionID"] = self.ID;
            extension["callType"] = self.callType;
            extension["callerID"] = self.initiatorID;
            extension["opponentsIDs"] = self.opponentsIDs;
            extension["sdp"] = peerConnection.localDescription.sdp;

            self.signalingProvider.sendMessage(userID, extension, SignalingConstants.SignalingType.ACCEPT);
          }
        });
      }
    });
  }else{
    Helpers.traceError("Can't accept the call, there is no information about peer connection by some reason.");
  }
};

/**
 * Reject a call
 * @param {array} A map with custom parameters
 */
WebRTCSession.prototype.reject = function(extension) {
  var self = this,
      ext = _prepareExtension(extension);
  var peersLen = Object.keys(self.peerConnections).length;

  Helpers.trace('Reject, extension: ' + JSON.stringify(ext));

  self.state = WebRTCSession.State.REJECTED;

  self._clearAnswerTimer();

  ext["sessionID"] = self.ID;
  ext["callType"] = self.callType;
  ext["callerID"] = self.initiatorID;
  ext["opponentsIDs"] = self.opponentsIDs;

  if(peersLen > 0){
    for (var key in self.peerConnections) {
      var peerConnection = self.peerConnections[key];
      self.signalingProvider.sendMessage(peerConnection.userID, ext, SignalingConstants.SignalingType.REJECT);
    }
  }

  self._close();
};

/**
 * Stop a call
 * @param {array} A map with custom parameters
 */
WebRTCSession.prototype.stop = function(extension) {
  var self = this,
      ext = _prepareExtension(extension);
  var peersLen = Object.keys(self.peerConnections).length;

  Helpers.trace('Stop, extension: ' + JSON.stringify(ext));

  self.state = WebRTCSession.State.HUNGUP;

  self._clearAnswerTimer();

  ext["sessionID"] = self.ID;
  ext["callType"] = self.callType;
  ext["callerID"] = self.initiatorID;
  ext["opponentsIDs"] = self.opponentsIDs;

  if(peersLen > 0){
    for (var key in self.peerConnections) {
      var peerConnection = self.peerConnections[key];
      self.signalingProvider.sendMessage(peerConnection.userID, ext, SignalingConstants.SignalingType.STOP);
    }
  }

  self._close();
};

/**
 * [function close connection with user]
 * @param  {[type]} userId [id of user]
 */
WebRTCSession.prototype.closeConnection = function(userId) {
  var self = this,
    peer = this.peerConnections[userId];

  if(peer) {
    peer.release();

    self._closeSessionIfAllConnectionsClosed();
  } else {
    Helpers.traceWarn('Not found connection with user (' + userId + ')');
  }
};

/**
 * Update a call
 * @param {array} A map with custom parameters
 */
WebRTCSession.prototype.update = function(extension) {
  var self = this,
      ext = {};

  Helpers.trace('Update, extension: ' + JSON.stringify(extension));

  if(extension == null){
    Helpers.trace("extension is null, no parameters to update");
    return;
  }

  ext = _prepareExtension(extension);
  ext.sessionID = this.ID;

  for (var key in self.peerConnections) {
    var peerConnection = self.peerConnections[key];

    self.signalingProvider.sendMessage(peerConnection.userID, ext, SignalingConstants.SignalingType.PARAMETERS_CHANGED);
  }
};

/**
 * Mutes the stream
 * @param {string} what to mute: 'audio' or 'video'
 */
WebRTCSession.prototype.mute = function(type) {
  this._muteStream(0, type);
};

/**
 * Unmutes the stream
 * @param {string} what to unmute: 'audio' or 'video'
 */
WebRTCSession.prototype.unmute = function(type) {
  this._muteStream(1, type);
};

/**
 * Creates a snapshot
 * @param {string} Id of element to make a shapshot from
 */
WebRTCSession.snapshot = function(id) {
  var video = document.getElementById(id),
      canvas = document.createElement('canvas'),
      context = canvas.getContext('2d'),
      dataURL, blob;

  if (video) {
    canvas.width = video.clientWidth;
    canvas.height = video.clientHeight;
    if (video.style.transform === 'scaleX(-1)') {
      context.translate(canvas.width, 0);
      context.scale(-1, 1);
    }
    context.drawImage(video, 0, 0, video.clientWidth, video.clientHeight);
    dataURL = canvas.toDataURL();

    blob = Helpers.dataURItoBlob(dataURL, 'image/png');
    blob.name = 'snapshot_' + getLocalTime() + '.png';
    blob.url = dataURL;

    return blob;
  }
};

/**
 * Adds the CSS filters to video stream http://css-tricks.com/almanac/properties/f/filter/
 * @param {string} Id of element to apply filters to
 * @param {string} Filters string
 */
WebRTCSession.filter = function(id, filters) {
  var video = document.getElementById(id);

  if (video) {
    video.style.webkitFilter = filters;
    video.style.filter = filters;
  }
};

/**
 * DELEGATES (rtc client)
 */
WebRTCSession.prototype.processOnCall = function(callerID, extension) {
  var self = this,
      oppIDs = self._uniqueOpponentsIDs();

  oppIDs.forEach(function(opID, i, arr) {
    var pConn = self.peerConnections[opID];

    if(pConn){
      if(opID == callerID){
        pConn.updateRemoteSDP(extension.sdp);

        /** The group call logic starts here */
        if(callerID != self.initiatorID && self.state === WebRTCSession.State.ACTIVE){
          self._acceptInternal(callerID, {});
        }
      }
    } else {
      /** create peer connections for each opponent */
      var peerConnection;
      if(opID != callerID && self.currentUserID > opID){
        peerConnection = self._createPeer(opID, 'offer');
      }else{
        peerConnection = self._createPeer(opID, 'answer');
      }

      self.peerConnections[opID] = peerConnection;

      if(opID == callerID){
        peerConnection.updateRemoteSDP(extension.sdp);
        self._startAnswerTimer();
      }
    }
  });
};

WebRTCSession.prototype.processOnAccept = function(userID, extension) {
  var peerConnection = this.peerConnections[userID];

  if(peerConnection){
    peerConnection._clearDialingTimer();

    peerConnection.setRemoteSessionDescription('answer', extension.sdp, function(error){
      if(error){
        Helpers.traceError("'setRemoteSessionDescription' error: " + error);
      }else{
        Helpers.trace("'setRemoteSessionDescription' success");
      }
    });
  }else{
    Helpers.traceError("Ignore 'OnAccept', there is no information about peer connection by some reason.");
  }
};

WebRTCSession.prototype.processOnReject = function(userID, extension) {
  var peerConnection = this.peerConnections[userID];

  this._clearWaitingOfferOrAnswerTimer();

  if(peerConnection){
    peerConnection.release();
  }else{
    Helpers.traceError("Ignore 'OnReject', there is no information about peer connection by some reason.");
  }

  this._closeSessionIfAllConnectionsClosed();
};

WebRTCSession.prototype.processOnStop = function(userID, extension) {
  var self = this;

  this._clearAnswerTimer();

  /** drop the call if the initiator did it */
  if (userID === self.initiatorID) {
    if( Object.keys(self.peerConnections).length ) {
      Object.keys(self.peerConnections).forEach(function(key) {
        self.peerConnections[key].release();
      });
    } else {
      Helpers.traceError("Ignore 'OnStop', there is no information about peer connections by some reason.");
    }
  } else {
    var pc = self.peerConnections[userID];
    if(pc){
      pc.release();
    }else{
      Helpers.traceError("Ignore 'OnStop', there is no information about peer connection by some reason.");
    }
  }

  this._closeSessionIfAllConnectionsClosed();
};

WebRTCSession.prototype.processOnIceCandidates = function(userID, extension) {
  var peerConnection = this.peerConnections[userID];

  if(peerConnection){
    peerConnection.addCandidates(extension.iceCandidates);
  }else{
    Helpers.traceError("Ignore 'OnIceCandidates', there is no information about peer connection by some reason.");
  }
};

WebRTCSession.prototype.processCall = function(peerConnection, extension) {
  var extension = extension || {};

  extension["sessionID"] = this.ID;
  extension["callType"] = this.callType;
  extension["callerID"] = this.initiatorID;
  extension["opponentsIDs"] = this.opponentsIDs;
  extension["sdp"] = peerConnection.localDescription.sdp;

  this.signalingProvider.sendMessage(peerConnection.userID, extension, SignalingConstants.SignalingType.CALL);
};

WebRTCSession.prototype.processIceCandidates = function(peerConnection, iceCandidates) {
  var extension = {};
  extension["sessionID"] = this.ID;
  extension["callType"] = this.callType;
  extension["callerID"] = this.initiatorID;
  extension["opponentsIDs"] = this.opponentsIDs;

  this.signalingProvider.sendCandidate(peerConnection.userID, iceCandidates, extension);
};

WebRTCSession.prototype.processOnNotAnswer = function(peerConnection) {
  Helpers.trace("Answer timeout callback for session " + this.ID + " for user " + peerConnection.userID);

  this._clearWaitingOfferOrAnswerTimer();

  peerConnection.release();

  if(typeof this.onUserNotAnswerListener === 'function'){
    Utils.safeCallbackCall(this.onUserNotAnswerListener, this, peerConnection.userID);
  }

  this._closeSessionIfAllConnectionsClosed();
};

/**
 * DELEGATES (peer connection)
 */
WebRTCSession.prototype._onRemoteStreamListener = function(userID, stream) {
  if (typeof this.onRemoteStreamListener === 'function'){
    Utils.safeCallbackCall(this.onRemoteStreamListener, this, userID, stream);
  }
};

WebRTCSession.prototype._onCallStatsReport = function(userId, stats) {
  if (typeof this.onCallStatsReport === 'function'){
    Utils.safeCallbackCall(this.onCallStatsReport, this, userId, stats);
  }
};

WebRTCSession.prototype._onSessionConnectionStateChangedListener = function(userID, connectionState) {
  var self = this;

  if (typeof self.onSessionConnectionStateChangedListener === 'function'){
      Utils.safeCallbackCall(self.onSessionConnectionStateChangedListener, self, userID, connectionState);
  }
};

/**
 * Private
 */
WebRTCSession.prototype._createPeer = function(userID, peerConnectionType) {
  if (!RTCPeerConnection) throw new Error('_createPeer error: RTCPeerConnection() is not supported in your browser');

  this.startCallTime = new Date();

  /**
   * Additional parameters for RTCPeerConnection options
   * new RTCPeerConnection(pcConfig, options)
   *
   * DtlsSrtpKeyAgreement: true
   * RtpDataChannels: true
   */
  var pcConfig = {
    iceServers: _prepareIceServers(config.webrtc.iceServers)
  };

  Helpers.trace("_createPeer, iceServers: " + JSON.stringify(pcConfig));

  var peer = new RTCPeerConnection(pcConfig);
  peer.init(this, userID, this.ID, peerConnectionType);

  return peer;
};

/** close peer connection and local stream */
WebRTCSession.prototype._close = function() {
  Helpers.trace("_close");

  for (var key in this.peerConnections) {
    var peer = this.peerConnections[key];
    peer.release();
  }

  this._closeLocalMediaStream();

  this.state = WebRTCSession.State.CLOSED;

  if(typeof this.onSessionCloseListener === 'function'){
    Utils.safeCallbackCall(this.onSessionCloseListener, this);
  }
};

WebRTCSession.prototype._closeSessionIfAllConnectionsClosed = function (){
  var isAllConnectionsClosed = true;

  for (var key in this.peerConnections) {
    var peerCon = this.peerConnections[key];

    if(peerCon.signalingState !== 'closed'){
      isAllConnectionsClosed = false;
      break;
    }
  }

  Helpers.trace("All peer connections closed: " + isAllConnectionsClosed);

  if(isAllConnectionsClosed){
    this._closeLocalMediaStream();

    if(typeof this.onSessionCloseListener === 'function'){
      this.onSessionCloseListener(this);
    }

    this.state = WebRTCSession.State.CLOSED;
  }
};

WebRTCSession.prototype._closeLocalMediaStream = function(){
  /**
   * https://developers.google.com/web/updates/2015/07/mediastream-deprecations?hl=en
   */
  if (this.localStream) {
    this.localStream.getAudioTracks().forEach(function (audioTrack) {
      audioTrack.stop();
    });

    this.localStream.getVideoTracks().forEach(function (videoTrack) {
      videoTrack.stop();
    });

    this.localStream = null;
  }
};

WebRTCSession.prototype._muteStream = function(bool, type) {
  if (type === 'audio' && this.localStream.getAudioTracks().length > 0) {
    this.localStream.getAudioTracks().forEach(function (track) {
      track.enabled = !!bool;
    });
    return;
  }

  if (type === 'video' && this.localStream.getVideoTracks().length > 0) {
    this.localStream.getVideoTracks().forEach(function (track) {
      track.enabled = !!bool;
    });
    return;
  }
};

WebRTCSession.prototype._clearAnswerTimer = function(){
  if(this.answerTimer){
    Helpers.trace("_clearAnswerTimer");
    clearTimeout(this.answerTimer);
    this.answerTimer = null;
  }
};

WebRTCSession.prototype._startAnswerTimer = function(){
  Helpers.trace("_startAnswerTimer");

  var self = this;
  var answerTimeoutCallback = function (){
    Helpers.trace("_answerTimeoutCallback");

    if(typeof self.onSessionCloseListener === 'function'){
      self._close();
    }

    self.answerTimer = null;
  };

  var answerTimeInterval = config.webrtc.answerTimeInterval*1000;
  this.answerTimer = setTimeout(answerTimeoutCallback, answerTimeInterval);
};

WebRTCSession.prototype._clearWaitingOfferOrAnswerTimer = function() {
  if(this.waitingOfferOrAnswerTimer){
    Helpers.trace("_clearWaitingOfferOrAnswerTimer");
    clearTimeout(this.waitingOfferOrAnswerTimer);
    this.waitingOfferOrAnswerTimer = null;
  }
};

WebRTCSession.prototype._startWaitingOfferOrAnswerTimer = function(time) {
  var self = this,
      timeout = (config.webrtc.answerTimeInterval - time) < 0 ? 1 : config.webrtc.answerTimeInterval - time,
      waitingOfferOrAnswerTimeoutCallback = function() {
        Helpers.trace("waitingOfferOrAnswerTimeoutCallback");

        if(Object.keys(self.peerConnections).length > 0) {
          Object.keys(self.peerConnections).forEach(function(key) {
            var peerConnection = self.peerConnections[key];
            if(peerConnection.state === RTCPeerConnection.State.CONNECTING || peerConnection.state === RTCPeerConnection.State.NEW) {
              self.processOnNotAnswer(peerConnection);
            }
          });
        }

        self.waitingOfferOrAnswerTimer = null;
      };

  Helpers.trace("_startWaitingOfferOrAnswerTimer, timeout: " + timeout);

  this.waitingOfferOrAnswerTimer = setTimeout(waitingOfferOrAnswerTimeoutCallback, timeout*1000);
};

WebRTCSession.prototype._uniqueOpponentsIDs = function(){
  var self = this;
  var opponents = [];

  if(this.initiatorID !== this.currentUserID){
    opponents.push(this.initiatorID);
  }

  this.opponentsIDs.forEach(function(userID, i, arr) {
    if(userID != self.currentUserID){
      opponents.push(parseInt(userID));
    }
  });

  return opponents;
};

WebRTCSession.prototype._uniqueOpponentsIDsWithoutInitiator = function(){
  var self = this;
  var opponents = [];

  this.opponentsIDs.forEach(function(userID, i, arr) {
    if(userID != self.currentUserID){
      opponents.push(parseInt(userID));
    }
  });

  return opponents;
};

WebRTCSession.prototype.toString = function sessionToString() {
  return 'ID: ' + this.ID + ', initiatorID:  ' + this.initiatorID + ', opponentsIDs: ' + this.opponentsIDs + ', state: ' + this.state + ", callType: " + this.callType;
};

function generateUUID(){
    var d = new Date().getTime();
    var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
        var r = (d + Math.random()*16)%16 | 0;
        d = Math.floor(d/16);
        return (c=='x' ? r : (r&0x3|0x8)).toString(16);
    });
    return uuid;
}

/**
 * private _prepareExtension - replace property null to empty string
 * return object with property or empty if extension didn't set
 */
function _prepareExtension(extension) {
  try {
    return JSON.parse( JSON.stringify(extension).replace(/null/g, "\"\"") );
  } catch (err) {
    return {};
  }
}

function _prepareIceServers(iceServers) {
  var  iceServersCopy = JSON.parse(JSON.stringify(iceServers));

  Object.keys(iceServersCopy).forEach(function(c, i, a) {
    if(iceServersCopy[i].hasOwnProperty('url')) {
      iceServersCopy[i].urls = iceServersCopy[i].url;
    } else {
      iceServersCopy[i].url = iceServersCopy[i].urls;
    }
  });

  return iceServersCopy;
}

module.exports = WebRTCSession;


text:
begin
  require 'fiber'

  module EventMachine
    module FtpClient
      class SyncSession < Session
        def initialize(url, options={})
          f = Fiber.current
          super url, options do |conn|
            f.resume(conn)
          end

          Fiber.yield
        end

        def pwd
          f = Fiber.current
          super do |arg|
            f.resume(arg)
          end

          Fiber.yield
        end

        def cwd(dir)
          f = Fiber.current
          super dir do
            f.resume
          end

          Fiber.yield
        end

        def list
          f = Fiber.current
          super do |data|
            f.resume(data)
          end

          Fiber.yield
        end

        def get(file)
          f = Fiber.current

          super file do |data|
            f.resume(data)
          end

          Fiber.yield
        end
      end
    end
  end
rescue LoadError
  # Could not load fiber support
end


text:
"""This module parses and generates contentlines as defined in RFC 2445
(iCalendar), but will probably work for other MIME types with similar syntax.
Eg. RFC 2426 (vCard)

It is stupid in the sense that it treats the content purely as strings. No type
conversion is attempted.
"""
from icalendar import compat
from icalendar.caselessdict import CaselessDict
from icalendar.parser_tools import DEFAULT_ENCODING
from icalendar.parser_tools import SEQUENCE_TYPES
from icalendar.parser_tools import to_unicode

import re

def escape_char(text):
    """Format value according to iCalendar TEXT escaping rules.
    """
    assert isinstance(text, (compat.unicode_type, compat.bytes_type))
    # NOTE: ORDER MATTERS!
    return text.replace(r'\N', '\n')\
               .replace('\\', '\\\\')\
               .replace(';', r'\;')\
               .replace(',', r'\,')\
               .replace('\r\n', r'\n')\
               .replace('\n', r'\n')

def unescape_char(text):
    assert isinstance(text, (compat.unicode_type, compat.bytes_type))
    # NOTE: ORDER MATTERS!
    if isinstance(text, compat.unicode_type):
        return text.replace(u'\\N', u'\\n')\
                   .replace(u'\r\n', u'\n')\
                   .replace(u'\\n', u'\n')\
                   .replace(u'\\,', u',')\
                   .replace(u'\\;', u';')\
                   .replace(u'\\\\', u'\\')
    elif isinstance(text, compat.bytes_type):
        return text.replace(b'\N', b'\n')\
                   .replace(b'\r\n', b'\n')\
                   .replace(b'\n', b'\n')\
                   .replace(b'\,', b',')\
                   .replace(b'\;', b';')\
                   .replace(b'\\\\', b'\\')

def tzid_from_dt(dt):
    tzid = None
    if hasattr(dt.tzinfo, 'zone'):
        tzid = dt.tzinfo.zone  # pytz implementation
    elif hasattr(dt.tzinfo, 'tzname'):
        try:
            tzid = dt.tzinfo.tzname(dt)  # dateutil implementation
        except AttributeError:
            # No tzid available
            pass
    return tzid

def foldline(line, limit=75, fold_sep=u'\r\n '):
    """Make a string folded as defined in RFC5545
    Lines of text SHOULD NOT be longer than 75 octets, excluding the line
    break.  Long content lines SHOULD be split into a multiple line
    representations using a line "folding" technique.  That is, a long
    line can be split between any two characters by inserting a CRLF
    immediately followed by a single linear white-space character (i.e.,
    SPACE or HTAB).
    """
    assert isinstance(line, compat.unicode_type)
    assert u'\n' not in line

    # Use a fast and simple variant for the common case that line is all ASCII.
    try:
        line.encode('ascii')
    except (UnicodeEncodeError, UnicodeDecodeError):
        pass
    else:
        return fold_sep.join(
            line[i:i + limit - 1] for i in range(0, len(line), limit - 1)
        )

    ret_chars = []
    byte_count = 0
    for char in line:
        char_byte_len = len(char.encode(DEFAULT_ENCODING))
        byte_count += char_byte_len
        if byte_count >= limit:
            ret_chars.append(fold_sep)
            byte_count = char_byte_len
        ret_chars.append(char)

    return u''.join(ret_chars)

#################################################################
# Property parameter stuff

def param_value(value):
    """Returns a parameter value.
    """
    if isinstance(value, SEQUENCE_TYPES):
        return q_join(value)
    return dquote(value)

# Could be improved

# [\w-] because of the iCalendar RFC
# \. because of the vCard RFC
NAME = re.compile('[\w\.-]+')

UNSAFE_CHAR = re.compile('[\x00-\x08\x0a-\x1f\x7F",:;]')
QUNSAFE_CHAR = re.compile('[\x00-\x08\x0a-\x1f\x7F"]')
FOLD = re.compile(b'(\r?\n)+[ \t]')
uFOLD = re.compile(u'(\r?\n)+[ \t]')
NEWLINE = re.compile(r'\r?\n')

def validate_token(name):
    match = NAME.findall(name)
    if len(match) == 1 and name == match[0]:
        return
    raise ValueError(name)

def validate_param_value(value, quoted=True):
    validator = QUNSAFE_CHAR if quoted else UNSAFE_CHAR
    if validator.findall(value):
        raise ValueError(value)

# chars presence of which in parameter value will be cause the value
# to be enclosed in double-quotes
QUOTABLE = re.compile("[,;: '']")

def dquote(val):
    """Enclose parameter values containing [,;:] in double quotes.
    """
    # a double-quote character is forbidden to appear in a parameter value
    # so replace it with a single-quote character
    val = val.replace('"', "'")
    if QUOTABLE.search(val):
        return '"%s"' % val
    return val

# parsing helper
def q_split(st, sep=',', maxsplit=-1):
    """Splits a string on char, taking double (q)uotes into considderation.
    """
    if maxsplit == 0:
        return [st]

    result = []
    cursor = 0
    length = len(st)
    inquote = 0
    splits = 0
    for i in range(length):
        ch = st[i]
        if ch == '"':
            inquote = not inquote
        if not inquote and ch == sep:
            result.append(st[cursor:i])
            cursor = i + 1
            splits += 1
        if i + 1 == length or splits == maxsplit:
            result.append(st[cursor:])
            break
    return result

def q_join(lst, sep=','):
    """Joins a list on sep, quoting strings with QUOTABLE chars.
    """
    return sep.join(dquote(itm) for itm in lst)

class Parameters(CaselessDict):
    """Parser and generator of Property parameter strings. It knows nothing of
    datatypes. Its main concern is textual structure.
    """

    def params(self):
        """In rfc2445 keys are called parameters, so this is to be consitent
        with the naming conventions.
        """
        return self.keys()

# TODO?
# Later, when I get more time... need to finish this off now. The last major
# thing missing.
#   def _encode(self, name, value, cond=1):
#       # internal, for conditional convertion of values.
#       if cond:
#           klass = types_factory.for_property(name)
#           return klass(value)
#       return value
#
#   def add(self, name, value, encode=0):
#       "Add a parameter value and optionally encode it."
#       if encode:
#           value = self._encode(name, value, encode)
#       self[name] = value
#
#   def decoded(self, name):
#       "returns a decoded value, or list of same"

    def to_ical(self, sorted=True):
        result = []
        items = list(self.items())
        if sorted:
            items.sort()

        for key, value in items:
            value = param_value(value)
            if isinstance(value, compat.unicode_type):
                value = value.encode(DEFAULT_ENCODING)
            # CaselessDict keys are always unicode
            key = key.upper().encode(DEFAULT_ENCODING)
            result.append(key + b'=' + value)
        return b';'.join(result)

    @classmethod
    def from_ical(cls, st, strict=False):
        """Parses the parameter format from ical text format."""

        # parse into strings
        result = cls()
        for param in q_split(st, ';'):
            try:
                key, val = q_split(param, '=', maxsplit=1)
                validate_token(key)
                # Property parameter values that are not in quoted
                # strings are case insensitive.
                vals = []
                for v in q_split(val, ','):
                    if v.startswith('"') and v.endswith('"'):
                        v = v.strip('"')
                        validate_param_value(v, quoted=True)
                        vals.append(v)
                    else:
                        validate_param_value(v, quoted=False)
                        if strict:
                            vals.append(v.upper())
                        else:
                            vals.append(v)
                if not vals:
                    result[key] = val
                else:
                    if len(vals) == 1:
                        result[key] = vals[0]
                    else:
                        result[key] = vals
            except ValueError as exc:
                raise ValueError('%r is not a valid parameter string: %s'
                                 % (param, exc))
        return result

def escape_string(val):
    # '%{:02X}'.format(i)
    return val.replace(r'\,', '%2C').replace(r'\:', '%3A')\
              .replace(r'\;', '%3B').replace(r'\\', '%5C')

def unescape_string(val):
    return val.replace('%2C', ',').replace('%3A', ':')\
              .replace('%3B', ';').replace('%5C', '\\')

def unescape_list_or_string(val):
    if isinstance(val, list):
        return [unescape_string(s) for s in val]
    else:
        return unescape_string(val)

#########################################
# parsing and generation of content lines

class Contentline(compat.unicode_type):
    """A content line is basically a string that can be folded and parsed into
    parts.
    """
    def __new__(cls, value, strict=False, encoding=DEFAULT_ENCODING):
        value = to_unicode(value, encoding=encoding)
        assert u'\n' not in value, ('Content line can not contain unescaped '
                                    'new line characters.')
        self = super(Contentline, cls).__new__(cls, value)
        self.strict = strict
        return self

    @classmethod
    def from_parts(cls, name, params, values, sorted=True):
        """Turn a parts into a content line.
        """
        assert isinstance(params, Parameters)
        if hasattr(values, 'to_ical'):
            values = values.to_ical()
        else:
            values = vText(values).to_ical()
        # elif isinstance(values, basestring):
        #    values = escape_char(values)

        # TODO: after unicode only, remove this
        # Convert back to unicode, after to_ical encoded it.
        name = to_unicode(name)
        values = to_unicode(values)
        if params:
            params = to_unicode(params.to_ical(sorted=sorted))
            return cls(u'%s;%s:%s' % (name, params, values))
        return cls(u'%s:%s' % (name, values))

    def parts(self):
        """Split the content line up into (name, parameters, values) parts.
        """
        try:
            st = escape_string(self)
            name_split = None
            value_split = None
            in_quotes = False
            for i, ch in enumerate(st):
                if not in_quotes:
                    if ch in ':;' and not name_split:
                        name_split = i
                    if ch == ':' and not value_split:
                        value_split = i
                if ch == '"':
                    in_quotes = not in_quotes
            name = unescape_string(st[:name_split])
            if not name:
                raise ValueError('Key name is required')
            validate_token(name)
            if not name_split or name_split + 1 == value_split:
                raise ValueError('Invalid content line')
            params = Parameters.from_ical(st[name_split + 1: value_split],
                                          strict=self.strict)
            params = Parameters(
                (unescape_string(key), unescape_list_or_string(value))
                for key, value in compat.iteritems(params)
            )
            values = unescape_string(st[value_split + 1:])
            return (name, params, values)
        except ValueError as exc:
            raise ValueError(
                u"Content line could not be parsed into parts: '%s': %s"
                % (self, exc)
            )

    @classmethod
    def from_ical(cls, ical, strict=False):
        """Unfold the content lines in an iCalendar into long content lines.
        """
        ical = to_unicode(ical)
        # a fold is carriage return followed by either a space or a tab
        return cls(uFOLD.sub('', ical), strict=strict)

    def to_ical(self):
        """Long content lines are folded so they are less than 75 characters
        wide.
        """
        return foldline(self).encode(DEFAULT_ENCODING)

class Contentlines(list):
    """I assume that iCalendar files generally are a few kilobytes in size.
    Then this should be efficient. for Huge files, an iterator should probably
    be used instead.
    """
    def to_ical(self):
        """Simply join self.
        """
        return b'\r\n'.join(line.to_ical() for line in self if line) + b'\r\n'

    @classmethod
    def from_ical(cls, st):
        """Parses a string into content lines.
        """
        st = to_unicode(st)
        try:
            # a fold is carriage return followed by either a space or a tab
            unfolded = uFOLD.sub('', st)
            lines = cls(Contentline(line) for
                        line in NEWLINE.split(unfolded) if line)
            lines.append('')  # '\r\n' at the end of every content line
            return lines
        except:
            raise ValueError('Expected StringType with content lines')

# XXX: what kind of hack is this? import depends to be at end
from icalendar.prop import vText


text:
/* src/config/flirtcoin-config.h.  Generated from flirtcoin-config.h.in by configure.  */
/* src/config/flirtcoin-config.h.in.  Generated from configure.ac by autoheader.  */

#ifndef FLIRTCOIN_CONFIG_H

#define FLIRTCOIN_CONFIG_H

/* Define if building universal (internal helper macro) */
/* #undef AC_APPLE_UNIVERSAL_BUILD */

/* Version Build */
#define CLIENT_VERSION_BUILD 0

/* Version is release */
#define CLIENT_VERSION_IS_RELEASE true

/* Major version */
#define CLIENT_VERSION_MAJOR 0

/* Minor version */
#define CLIENT_VERSION_MINOR 9

/* Build revision */
#define CLIENT_VERSION_REVISION 99

/* Version is release */
#define COPYRIGHT_YEAR 2014

/* Define to 1 to enable wallet functions */
#define ENABLE_WALLET 1

/* parameter and return value type for __fdelt_chk */
/* #undef FDELT_TYPE */

/* define if the Boost library is available */
#define HAVE_BOOST /**/

/* define if the Boost::Chrono library is available */
#define HAVE_BOOST_CHRONO /**/

/* define if the Boost::Filesystem library is available */
#define HAVE_BOOST_FILESYSTEM /**/

/* define if the Boost::PROGRAM_OPTIONS library is available */
#define HAVE_BOOST_PROGRAM_OPTIONS /**/

/* define if the Boost::System library is available */
#define HAVE_BOOST_SYSTEM /**/

/* define if the Boost::Thread library is available */
#define HAVE_BOOST_THREAD /**/

/* define if the Boost::Unit_Test_Framework library is available */
#define HAVE_BOOST_UNIT_TEST_FRAMEWORK /**/

/* Define to 1 if you have the declaration of `be32toh', and to 0 if you
   don't. */
#define HAVE_DECL_BE32TOH 1

/* Define to 1 if you have the declaration of `be64toh', and to 0 if you
   don't. */
#define HAVE_DECL_BE64TOH 1

/* Define to 1 if you have the declaration of `htobe32', and to 0 if you
   don't. */
#define HAVE_DECL_HTOBE32 1

/* Define to 1 if you have the declaration of `htobe64', and to 0 if you
   don't. */
#define HAVE_DECL_HTOBE64 1

/* Define to 1 if you have the declaration of `htole32', and to 0 if you
   don't. */
#define HAVE_DECL_HTOLE32 1

/* Define to 1 if you have the declaration of `htole64', and to 0 if you
   don't. */
#define HAVE_DECL_HTOLE64 1

/* Define to 1 if you have the declaration of `le32toh', and to 0 if you
   don't. */
#define HAVE_DECL_LE32TOH 1

/* Define to 1 if you have the declaration of `le64toh', and to 0 if you
   don't. */
#define HAVE_DECL_LE64TOH 1

/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
   don't. */
#define HAVE_DECL_STRERROR_R 1

/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1

/* Define to 1 if you have the <endian.h> header file. */
#define HAVE_ENDIAN_H 1

/* Define this symbol if you have getaddrinfo_a */
#define HAVE_GETADDRINFO_A 1

/* Define this symbol if you have inet_pton */
#define HAVE_INET_PTON 1

/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1

/* Define to 1 if you have the `advapi32' library (-ladvapi32). */
/* #undef HAVE_LIBADVAPI32 */

/* Define to 1 if you have the `comctl32' library (-lcomctl32). */
/* #undef HAVE_LIBCOMCTL32 */

/* Define to 1 if you have the `comdlg32' library (-lcomdlg32). */
/* #undef HAVE_LIBCOMDLG32 */

/* Define to 1 if you have the `crypt32' library (-lcrypt32). */
/* #undef HAVE_LIBCRYPT32 */

/* Define to 1 if you have the `gdi32' library (-lgdi32). */
/* #undef HAVE_LIBGDI32 */

/* Define to 1 if you have the `imm32' library (-limm32). */
/* #undef HAVE_LIBIMM32 */

/* Define to 1 if you have the `iphlpapi' library (-liphlpapi). */
/* #undef HAVE_LIBIPHLPAPI */

/* Define to 1 if you have the `jpeg ' library (-ljpeg ). */
/* #undef HAVE_LIBJPEG_ */

/* Define to 1 if you have the `kernel32' library (-lkernel32). */
/* #undef HAVE_LIBKERNEL32 */

/* Define to 1 if you have the `mingwthrd' library (-lmingwthrd). */
/* #undef HAVE_LIBMINGWTHRD */

/* Define to 1 if you have the `mswsock' library (-lmswsock). */
/* #undef HAVE_LIBMSWSOCK */

/* Define to 1 if you have the `ole32' library (-lole32). */
/* #undef HAVE_LIBOLE32 */

/* Define to 1 if you have the `oleaut32' library (-loleaut32). */
/* #undef HAVE_LIBOLEAUT32 */

/* Define to 1 if you have the `pcre16 ' library (-lpcre16 ). */
/* #undef HAVE_LIBPCRE16_ */

/* Define to 1 if you have the `png ' library (-lpng ). */
/* #undef HAVE_LIBPNG_ */

/* Define to 1 if you have the `rpcrt4' library (-lrpcrt4). */
/* #undef HAVE_LIBRPCRT4 */

/* Define to 1 if you have the `shell32' library (-lshell32). */
/* #undef HAVE_LIBSHELL32 */

/* Define to 1 if you have the `shlwapi' library (-lshlwapi). */
/* #undef HAVE_LIBSHLWAPI */

/* Define to 1 if you have the `user32' library (-luser32). */
/* #undef HAVE_LIBUSER32 */

/* Define to 1 if you have the `uuid' library (-luuid). */
/* #undef HAVE_LIBUUID */

/* Define to 1 if you have the `winmm' library (-lwinmm). */
/* #undef HAVE_LIBWINMM */

/* Define to 1 if you have the `winspool' library (-lwinspool). */
/* #undef HAVE_LIBWINSPOOL */

/* Define to 1 if you have the `ws2_32' library (-lws2_32). */
/* #undef HAVE_LIBWS2_32 */

/* Define to 1 if you have the `z ' library (-lz ). */
/* #undef HAVE_LIBZ_ */

/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1

/* Define to 1 if you have the <miniupnpc/miniupnpc.h> header file. */
/* #undef HAVE_MINIUPNPC_MINIUPNPC_H */

/* Define to 1 if you have the <miniupnpc/miniwget.h> header file. */
/* #undef HAVE_MINIUPNPC_MINIWGET_H */

/* Define to 1 if you have the <miniupnpc/upnpcommands.h> header file. */
/* #undef HAVE_MINIUPNPC_UPNPCOMMANDS_H */

/* Define to 1 if you have the <miniupnpc/upnperrors.h> header file. */
/* #undef HAVE_MINIUPNPC_UPNPERRORS_H */

/* Define this symbol if you have MSG_NOSIGNAL */
#define HAVE_MSG_NOSIGNAL 1

/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD 1

/* Have PTHREAD_PRIO_INHERIT. */
#define HAVE_PTHREAD_PRIO_INHERIT 1

/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1

/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1

/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1

/* Define to 1 if you have the `strerror_r' function. */
#define HAVE_STRERROR_R 1

/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1

/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1

/* Define to 1 if you have the <sys/prctl.h> header file. */
#define HAVE_SYS_PRCTL_H 1

/* Define to 1 if you have the <sys/select.h> header file. */
#define HAVE_SYS_SELECT_H 1

/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1

/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1

/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1

/* Define if the visibility attribute is supported. */
#define HAVE_VISIBILITY_ATTRIBUTE 1

/* Define this symbol if boost sleep works */
/* #undef HAVE_WORKING_BOOST_SLEEP */

/* Define this symbol if boost sleep_for works */
#define HAVE_WORKING_BOOST_SLEEP_FOR 1

/* Define to the sub-directory in which libtool stores uninstalled libraries.
   */
#define LT_OBJDIR ".libs/"

/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "info@flirt.life"

/* Define to the full name of this package. */
#define PACKAGE_NAME "Flirtcoin Core"

/* Define to the full name and version of this package. */
#define PACKAGE_STRING "Flirtcoin Core 0.9.99"

/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "flirtcoin"

/* Define to the home page for this package. */
#define PACKAGE_URL ""

/* Define to the version of this package. */
#define PACKAGE_VERSION "0.9.99"

/* Define to necessary symbol if this constant uses a non-standard name on
   your system. */
/* #undef PTHREAD_CREATE_JOINABLE */

/* Define this symbol if the qt platform is cocoa */
/* #undef QT_QPA_PLATFORM_COCOA */

/* Define this symbol if the qt platform is windows */
/* #undef QT_QPA_PLATFORM_WINDOWS */

/* Define this symbol if the qt platform is xcb */
/* #undef QT_QPA_PLATFORM_XCB */

/* Define this symbol if qt plugins are static */
/* #undef QT_STATICPLUGIN */

/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

/* Define to 1 if strerror_r returns char *. */
#define STRERROR_R_CHAR_P 1

/* Define if dbus support should be compiled in */
#define USE_DBUS 1

/* Define if QR support should be compiled in */
#define USE_QRCODE 1

/* UPnP support not compiled if undefined, otherwise value (0 or 1) determines
   default state */
/* #undef USE_UPNP */

/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
   significant byte first (like Motorola and SPARC, unlike Intel). */
#if defined AC_APPLE_UNIVERSAL_BUILD
# if defined __BIG_ENDIAN__
#  define WORDS_BIGENDIAN 1
# endif
#else
# ifndef WORDS_BIGENDIAN
/* #  undef WORDS_BIGENDIAN */
# endif
#endif

/* Enable large inode numbers on Mac OS X 10.5.  */
#ifndef _DARWIN_USE_64_BIT_INODE
# define _DARWIN_USE_64_BIT_INODE 1
#endif

/* Number of bits in a file offset, on hosts where this is settable. */
/* #undef _FILE_OFFSET_BITS */

/* Define for large files, on AIX-style hosts. */
/* #undef _LARGE_FILES */

#endif //FLIRTCOIN_CONFIG_H


text:
.class Landroid/widget/AbsListView$11;
.super Ljava/lang/Object;
.source "AbsListView.java"

# interfaces
.implements Landroid/view/ViewTreeObserver$OnPreDrawListener;

# annotations
.annotation system Ldalvik/annotation/EnclosingMethod;
    value = Landroid/widget/AbsListView;->handleItemSwitch()V
.end annotation

.annotation system Ldalvik/annotation/InnerClass;
    accessFlags = 0x0
    name = null
.end annotation

# instance fields
.field final synthetic this$0:Landroid/widget/AbsListView;

.field final synthetic val$deltaY:I

.field final synthetic val$observer:Landroid/view/ViewTreeObserver;

.field final synthetic val$originalItem:I

.field final synthetic val$switchItem:I

.field final synthetic val$switchItemID:J

.field final synthetic val$switchViewStartTop:I

# direct methods
.method constructor <init>(Landroid/widget/AbsListView;Landroid/view/ViewTreeObserver;JIIII)V
    .locals 0

    .prologue
    .line 11217
    iput-object p1, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iput-object p2, p0, Landroid/widget/AbsListView$11;->val$observer:Landroid/view/ViewTreeObserver;

    iput-wide p3, p0, Landroid/widget/AbsListView$11;->val$switchItemID:J

    iput p5, p0, Landroid/widget/AbsListView$11;->val$switchItem:I

    iput p6, p0, Landroid/widget/AbsListView$11;->val$originalItem:I

    iput p7, p0, Landroid/widget/AbsListView$11;->val$deltaY:I

    iput p8, p0, Landroid/widget/AbsListView$11;->val$switchViewStartTop:I

    invoke-direct {p0}, Ljava/lang/Object;-><init>()V

    return-void
.end method

# virtual methods
.method public onPreDraw()Z
    .locals 10

    .prologue
    const/4 v9, 0x1

    const/4 v8, 0x0

    .line 11219
    iget-object v5, p0, Landroid/widget/AbsListView$11;->val$observer:Landroid/view/ViewTreeObserver;

    invoke-virtual {v5, p0}, Landroid/view/ViewTreeObserver;->removeOnPreDrawListener(Landroid/view/ViewTreeObserver$OnPreDrawListener;)V

    .line 11222
    iget-object v5, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iget-object v5, v5, Landroid/widget/AbsListView;->mAdapter:Landroid/widget/ListAdapter;

    invoke-interface {v5}, Landroid/widget/ListAdapter;->hasStableIds()Z

    move-result v5

    if-eqz v5, :cond_0

    .line 11223
    iget-object v5, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iget-object v6, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    # getter for: Landroid/widget/AbsListView;->mMobileItemId:J
    invoke-static {v6}, Landroid/widget/AbsListView;->access$7200(Landroid/widget/AbsListView;)J

    move-result-wide v6

    # invokes: Landroid/widget/AbsListView;->getViewForID(J)Landroid/view/View;
    invoke-static {v5, v6, v7}, Landroid/widget/AbsListView;->access$7300(Landroid/widget/AbsListView;J)Landroid/view/View;

    move-result-object v2

    .line 11224
    .local v2, "mobileView":Landroid/view/View;
    iget-object v5, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iget-wide v6, p0, Landroid/widget/AbsListView$11;->val$switchItemID:J

    # invokes: Landroid/widget/AbsListView;->getViewForID(J)Landroid/view/View;
    invoke-static {v5, v6, v7}, Landroid/widget/AbsListView;->access$7300(Landroid/widget/AbsListView;J)Landroid/view/View;

    move-result-object v3

    .line 11229
    .local v3, "switchView":Landroid/view/View;
    :goto_0
    invoke-virtual {v2, v8}, Landroid/view/View;->setAlpha(F)V

    .line 11230
    const/high16 v5, 0x3f800000    # 1.0f

    invoke-virtual {v3, v5}, Landroid/view/View;->setAlpha(F)V

    .line 11232
    iget-object v5, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iget v6, p0, Landroid/widget/AbsListView$11;->val$deltaY:I

    # += operator for: Landroid/widget/AbsListView;->mTotalOffset:I
    invoke-static {v5, v6}, Landroid/widget/AbsListView;->access$7412(Landroid/widget/AbsListView;I)I

    .line 11234
    invoke-virtual {v3}, Landroid/view/View;->getTop()I

    move-result v4

    .line 11235
    .local v4, "switchViewNewTop":I
    iget v5, p0, Landroid/widget/AbsListView$11;->val$switchViewStartTop:I

    sub-int v1, v5, v4

    .line 11237
    .local v1, "delta":I
    int-to-float v5, v1

    invoke-virtual {v3, v5}, Landroid/view/View;->setTranslationY(F)V

    .line 11238
    sget-object v5, Landroid/view/View;->TRANSLATION_Y:Landroid/util/Property;

    new-array v6, v9, [F

    const/4 v7, 0x0

    aput v8, v6, v7

    invoke-static {v3, v5, v6}, Landroid/animation/ObjectAnimator;->ofFloat(Ljava/lang/Object;Landroid/util/Property;[F)Landroid/animation/ObjectAnimator;

    move-result-object v0

    .line 11240
    .local v0, "animator":Landroid/animation/ObjectAnimator;
    const-wide/16 v5, 0x96

    invoke-virtual {v0, v5, v6}, Landroid/animation/ObjectAnimator;->setDuration(J)Landroid/animation/ObjectAnimator;

    .line 11241
    invoke-virtual {v0}, Landroid/animation/ObjectAnimator;->start()V

    .line 11243
    return v9

    .line 11226
    .end local v0    # "animator":Landroid/animation/ObjectAnimator;
    .end local v1    # "delta":I
    .end local v2    # "mobileView":Landroid/view/View;
    .end local v3    # "switchView":Landroid/view/View;
    .end local v4    # "switchViewNewTop":I
    :cond_0
    iget-object v5, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iget v6, p0, Landroid/widget/AbsListView$11;->val$switchItem:I

    iget-object v7, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iget v7, v7, Landroid/widget/AbsListView;->mFirstPosition:I

    sub-int/2addr v6, v7

    invoke-virtual {v5, v6}, Landroid/widget/AbsListView;->getChildAt(I)Landroid/view/View;

    move-result-object v2

    .line 11227
    .restart local v2    # "mobileView":Landroid/view/View;
    iget-object v5, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iget v6, p0, Landroid/widget/AbsListView$11;->val$originalItem:I

    iget-object v7, p0, Landroid/widget/AbsListView$11;->this$0:Landroid/widget/AbsListView;

    iget v7, v7, Landroid/widget/AbsListView;->mFirstPosition:I

    sub-int/2addr v6, v7

    invoke-virtual {v5, v6}, Landroid/widget/AbsListView;->getChildAt(I)Landroid/view/View;

    move-result-object v3

    .restart local v3    # "switchView":Landroid/view/View;
    goto :goto_0
.end method


text:
Here I'll talk about the concept of the Brief app as a tool for defining
re-usable model definitions that can be documented, shipped with
examples, templates, and other useful features.


text:
module MachineSpec (spec) where

import           Machine
import           Prelude hiding (Left, Right)
import           Test.Hspec

meta :: Meta
meta = Meta { noActionSymbol = '_', anySymbol = '*', emptySymbol = ' ', emptyTape = "" }

--TODO: add Tape datatype?
automaton0 :: Automaton
automaton0 = Automaton { state = "State0", tapeBefore = "AB", headSymbol = 'C', tapeAfter = "DE" }

withTape :: [Symbol] -> Symbol -> [Symbol] -> Automaton -> Automaton
withTape before current after a =
  a { tapeBefore = before, headSymbol = current, tapeAfter = after }

spec :: Spec
spec = describe "Turing machine" $ do
  context "with no transitions" $
    it "halts" $
      advance meta automaton0 [] `shouldBe` Nothing

  context "with no matching accepting state AND matching symbol" $
    it "halts" $ do
      let transition = Transition { accept = ("State1", 'C'), actions = [], nextState = "State0" }

      advance meta automaton0 [transition] `shouldBe` Nothing

  context "with no matching accepting symbol AND matching state" $
    it "halts" $ do
      let transition = Transition { accept = ("State0", 'X'), actions = [], nextState = "State0" }

      advance meta automaton0 [transition] `shouldBe` Nothing

  --TODO: with more than one matching transition for current state/symbol halts
  context "with exactly one matching transition" $
    it "advances once then halts" $ do
      let transition = Transition { accept = ("State0", 'C'), actions = [], nextState = "State1" }

      let automaton1 = automaton0 { state = "State1" }
      advance meta automaton0 [transition] `shouldBe` Just automaton1
      advance meta automaton1 [transition] `shouldBe` Nothing

  context "with different matching transitions" $
    it "picks matching transition for each step" $ do
      let transition0 = Transition { accept = ("State0", 'C'), actions = [], nextState = "State1" }
      let transition1 = transition0 { accept = ("State1", 'C'), nextState = "State2" }
      let badTransition = transition0 { accept = ("State1", 'X'), nextState = "State3" }
      let transitions = [transition0, transition1, badTransition]

      let automaton1 = automaton0 { state = "State1" }
      advance meta automaton0 transitions `shouldBe` Just automaton1
      let automaton2 = automaton1 { state = "State2" }
      advance meta automaton1 transitions `shouldBe` Just automaton2
      advance meta automaton2 transitions `shouldBe` Nothing

  context "with infinite looping transition in one direction" $ do
    it "moves head position left" $ do
      let loop = Transition
            { accept = ("State0", '*')
            , actions = [Move Left]
            , nextState = "State0"
            }

      let automaton1 = withTape "A" 'B' "CDE" automaton0
      advance meta automaton0 [loop] `shouldBe` Just automaton1
      let automaton2 = withTape "" 'A' "BCDE" automaton1
      advance meta automaton1 [loop] `shouldBe` Just automaton2
      let automaton3 = withTape "" ' ' "ABCDE" automaton2
      advance meta automaton2 [loop] `shouldBe` Just automaton3

    it "moves head position right" $ do
      let loop = Transition
            { accept = ("State0", '*')
            , actions = [Move Right]
            , nextState = "State0"
            }

      let automaton1 = withTape "ABC" 'D' "E" automaton0
      advance meta automaton0 [loop] `shouldBe` Just automaton1
      let automaton2 = withTape "ABCD" 'E' "" automaton1
      advance meta automaton1 [loop] `shouldBe` Just automaton2
      let automaton3 = withTape "ABCDE" ' ' "" automaton2
      advance meta automaton2 [loop] `shouldBe` Just automaton3

  it "writes symbol to the current position" $ do
    let write = Transition { accept = ("State0", 'C'), actions = [Write 'X'], nextState = "State1" }
    fmap headSymbol (advance meta automaton0 [write]) `shouldBe` Just 'X'
  context "with many actions in one transition" $
    it "executes them in order and then advances to next state" $ do
      let manyActions = Transition
            { accept = ("State0", 'C')
            , actions = [Move Left, Write 'X', Move Right, Move Right, Write 'Y']
            , nextState = "State1"
            }
      let automaton1 = (withTape "AXC" 'Y' "E" automaton0) { state = "State1" }
      advance meta automaton0 [manyActions] `shouldBe` Just automaton1


text:
<?xml version="1.0" encoding="utf-8"?>
<!--

-->
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
				android:duration="@integer/fragment_config_anim_slide_horizontal_in_back_duration"
				android:interpolator="@anim/fragment_interpolator"
				android:propertyName="fractionX"
				android:valueFrom="1.0"
				android:valueTo="0.0" />


text:
<?php

namespace ForkCMS\Modules\Extensions\Domain\ThemeTemplate;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;

/**
 * @method ThemeTemplate|null find($id, $lockMode = null, $lockVersion = null)
 * @method ThemeTemplate|null findOneBy(array $criteria, array $orderBy = null)
 * @method ThemeTemplate[] findAll()
 * @method ThemeTemplate[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
 * @extends ServiceEntityRepository<ThemeTemplate>
 */
final class ThemeTemplateRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $managerRegistry)
    {
        parent::__construct($managerRegistry, ThemeTemplate::class);
    }

    public function save(ThemeTemplate $themeTemplate): void
    {
        $entityManager = $this->getEntityManager();
        $entityManager->persist($themeTemplate);
        $entityManager->flush();
    }

    public function remove(ThemeTemplate $themeTemplate): void
    {
        $entityManager = $this->getEntityManager();
        $entityManager->remove($themeTemplate);
        $entityManager->flush();
    }
}


text:
using Cirrious.CrossCore;
using Cirrious.CrossCore.Plugins;
using MvvmCross.Plugins.Network.Reachability;
using MvvmCross.Plugins.Network.Rest;

namespace MvvmCross.Plugins.Network.Droid
{
    public class Plugin
        : IMvxPlugin
    {
        public void Load()
        {
            Mvx.RegisterType<IMvxReachability, MvxReachability>();
            Mvx.RegisterType<IMvxRestClient, MvxJsonRestClient>();
            Mvx.RegisterType<IMvxJsonRestClient, MvxJsonRestClient>();
        }
    }
}


text:
from distutils.command.sdist import sdist as _sdist
from distutils.util import convert_path
from distutils import log
import os, re, sys, pkg_resources

entities = [
    ("<","<"), (">", ">"), (""", '"'), ("'", "'"),
    ("&", "&")
]

def unescape(data):
    for old, new in entities:
        data = data.replace(old,new)
    return data

def re_finder(pattern, postproc=None):
    def find(dirname, filename):
        f = open(filename,'rU')
        data = f.read()
        f.close()
        for match in pattern.finditer(data):
            path = match.group(1)
            if postproc:
                path = postproc(path)
            yield joinpath(dirname,path)
    return find

def joinpath(prefix,suffix):
    if not prefix:
        return suffix
    return os.path.join(prefix,suffix)

def walk_revctrl(dirname=''):
    """Find all files under revision control"""
    for ep in pkg_resources.iter_entry_points('setuptools.file_finders'):
        for item in ep.load()(dirname):
            yield item

def _default_revctrl(dirname=''):
    for path, finder in finders:
        path = joinpath(dirname,path)
        if os.path.isfile(path):
            for path in finder(dirname,path):
                if os.path.isfile(path):
                    yield path
                elif os.path.isdir(path):
                    for item in _default_revctrl(path):
                        yield item

def externals_finder(dirname, filename):
    """Find any 'svn:externals' directories"""
    found = False
    f = open(filename,'rb')
    for line in iter(f.readline, ''):    # can't use direct iter!
        parts = line.split()
        if len(parts)==2:
            kind,length = parts
            data = f.read(int(length))
            if kind=='K' and data=='svn:externals':
                found = True
            elif kind=='V' and found:
                f.close()
                break
    else:
        f.close()
        return

    for line in data.splitlines():
        parts = line.split()
        if parts:
            yield joinpath(dirname, parts[0])

entries_pattern = re.compile(r'name="([^"]+)"(?![^>]+deleted="true")', re.I)

def entries_finder(dirname, filename):
    f = open(filename,'rU')
    data = f.read()
    f.close()
    if data.startswith('9') or data.startswith('8'):    # subversion 1.5/1.4
        for record in map(str.splitlines, data.split('\n\x0c\n')[1:]):
            if not record or len(record)>=6 and record[5]=="delete":
                continue    # skip deleted
            yield joinpath(dirname, record[0])
    elif data.startswith('<?xml'):
        for match in entries_pattern.finditer(data):
            yield joinpath(dirname,unescape(match.group(1)))
    else:
        log.warn("unrecognized .svn/entries format in %s", dirname)

finders = [
    (convert_path('CVS/Entries'),
        re_finder(re.compile(r"^\w?/([^/]+)/", re.M))),
    (convert_path('.svn/entries'), entries_finder),
    (convert_path('.svn/dir-props'), externals_finder),
    (convert_path('.svn/dir-prop-base'), externals_finder),  # svn 1.4
]

class sdist(_sdist):
    """Smart sdist that finds anything supported by revision control"""

    user_options = [
        ('formats=', None,
         "formats for source distribution (comma-separated list)"),
        ('keep-temp', 'k',
         "keep the distribution tree around after creating " +
         "archive file(s)"),
        ('dist-dir=', 'd',
         "directory to put the source distribution archive(s) in "
         "[default: dist]"),
        ]

    negative_opt = {}

    def run(self):
        self.run_command('egg_info')
        ei_cmd = self.get_finalized_command('egg_info')
        self.filelist = ei_cmd.filelist
        self.filelist.append(os.path.join(ei_cmd.egg_info,'SOURCES.txt'))
        self.check_readme()
        self.check_metadata()
        self.make_distribution()

        dist_files = getattr(self.distribution,'dist_files',[])
        for file in self.archive_files:
            data = ('sdist', '', file)
            if data not in dist_files:
                dist_files.append(data)

    def read_template(self):
        try:
            _sdist.read_template(self)
        except:
            # grody hack to close the template file (MANIFEST.in)
            # this prevents easy_install's attempt at deleting the file from
            # dying and thus masking the real error
            sys.exc_info()[2].tb_next.tb_frame.f_locals['template'].close()
            raise

    def check_readme(self):
        alts = ("README", "README.txt")
        for f in alts:
            if os.path.exists(f):
                return
        else:
            self.warn(
                "standard file not found: should have one of " +', '.join(alts)
            )

    def make_release_tree(self, base_dir, files):
        _sdist.make_release_tree(self, base_dir, files)

        # Save any egg_info command line options used to create this sdist
        dest = os.path.join(base_dir, 'setup.cfg')
        if hasattr(os,'link') and os.path.exists(dest):
            # unlink and re-copy, since it might be hard-linked, and
            # we don't want to change the source version
            os.unlink(dest)
            self.copy_file('setup.cfg', dest)

        self.get_finalized_command('egg_info').save_version_info(dest)


text:
from __future__ import absolute_import, print_function

import logging

from django import forms
from django.utils.translation import ugettext_lazy as _

from cobra.singleton import ratelimiter
from cobra.core.plugins import Notification, Plugin
from cobra.core.loading import get_model

UserOption = get_model('option', 'UserOption')
AccessGroup = get_model('accessgroup', 'Accessgroup')

class NotificationConfigurationForm(forms.Form):
    pass

class BaseNotificationUserOptionsForm(forms.Form):
    def __init__(self, plugin, user, *args, **kwargs):
        self.plugin = plugin
        self.user = user
        super(BaseNotificationUserOptionsForm, self).__init__(*args, **kwargs)

    def get_title(self):
        return self.plugin.get_conf_title()

    def get_description(self):
        return ""

    def save(self):
        raise NotImplementedError

class NotificationPlugin(Plugin):
    description = _('Notify project members when a new event is seen for the first time, or when an '
                    'already resolved event has changed back to unresolved.')
    # site_conf_form = NotificationConfigurationForm
    project_conf_form = NotificationConfigurationForm

    def notify(self, notification):
        event = notification.event
        return self.notify_users(event.group, event)

    def rule_notify(self, event, futures):
        rules = []
        for future in futures:
            rules.append(future.rule)
            if not future.kwargs:
                continue
            raise NotImplementedError('The default behavior for notification de-duplication does not support args')

        notification = Notification(event=event, rules=rules)
        self.notify(notification)

    def notify_users(self, group, event, fail_silently=False):
        raise NotImplementedError

    def get_sendable_users(self, project):
        conf_key = self.get_conf_key()

        alert_settings = dict(
            (o.user_id, int(o.value))
            for o in UserOption.objects.filter(
                project=project,
                key='%s:alert' % conf_key,
            )
        )

        disabled = set(u for u, v in alert_settings.iteritems() if v == 0)

        # fetch access group members
        member_set = set(AccessGroup.objects.filter(
            projects=project,
            members__is_active=True,
        ).exclude(members__in=disabled).values_list('members', flat=True))

        member_set |= set(project.member_set.exclude(
            user__in=disabled,
        ).values_list('user', flat=True))

        # determine members default settings
        members_to_check = set(u for u in member_set if u not in alert_settings)
        if members_to_check:
            disabled = set(UserOption.objects.filter(
                key='subscribe_by_default',
                value='0',
                user__in=members_to_check,
            ).values_list('user', flat=True))
            member_set = filter(lambda x: x not in disabled, member_set)

        return member_set

    def should_notify(self, group, event):
        if group.is_muted():
            return False

        project = group.project

        rate_limited = ratelimiter.is_limited(
            project=project,
            key=self.get_conf_key(),
            limit=15,
        )

        if rate_limited:
            logger = logging.getLogger('cobra.plugins.{0}'.format(self.get_conf_key()))
            logger.info('Notification for project %s dropped due to rate limiting', project.id)

        return not rate_limited

    def test_configuration(self, project):
        from cobra.core.samples import create_sample_event
        event = create_sample_event(project, default='python')
        return self.notify_users(event.group, event, fail_silently=False)

# Backwards-compatibility
NotifyConfigurationForm = NotificationConfigurationForm
NotifyPlugin = NotificationPlugin


text:
namespace Autofac.Integration.Mvc.Test.Stubs;

public class GeneratedViewMasterPageWithModel : AbstractViewMasterPageWithModel<TestModel1>
{
}


text:
package com.example.oss_sdk_demo.activity;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import com.alibaba.sdk.android.oss.ClientException;
import com.alibaba.sdk.android.oss.ServiceException;
import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
import com.alibaba.sdk.android.oss.model.GetObjectRequest;
import com.alibaba.sdk.android.oss.model.GetObjectResult;
import com.alibaba.sdk.android.oss.model.ListObjectsRequest;
import com.alibaba.sdk.android.oss.model.PutObjectRequest;
import com.alibaba.sdk.android.oss.model.PutObjectResult;
import com.example.oss_sdk_demo.R;
import com.example.oss_sdk_demo.adapter.FileListAdapter;
import com.example.oss_sdk_demo.model.FileObject;
import com.example.oss_sdk_demo.model.FileObject.FileType;
import com.example.oss_sdk_demo.task.ListObjectInBucketTask;
import com.example.oss_sdk_demo.util.AppUtil;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class FileExplorerActivity extends Activity implements OnClickListener, OnItemClickListener {

    private ListView fileListView;
    private Button uploadBtn;
    private FileListAdapter adapter;
    private String currentPath = "";
    final private String DEFAULT_FILE_SAVE_PATH = Environment.getExternalStorageDirectory().getAbsolutePath() + "/sts_file/";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.file_explorer_activity);

        File file = new File(DEFAULT_FILE_SAVE_PATH);
        if (!file.exists()) {
            file.mkdir();
        }

        fileListView = (ListView) findViewById(R.id.file_list);
        uploadBtn = (Button) findViewById(R.id.button_upload);
        adapter = new FileListAdapter(this);

        uploadBtn.setOnClickListener(this);
        uploadBtn.setEnabled(false);
        fileListView.setOnItemClickListener(this);
        initListView(fileListView);
    }

    public void initListView(ListView listView) {
        List<FileObject> data = new ArrayList<FileObject>();
        data.add(new FileObject("userA/", FileType.FOLDER));
        data.add(new FileObject("userB/", FileType.FOLDER));
        adapter.moveToNewDataSource(data);
        listView.setAdapter(adapter);
        adapter.notifyDataSetChanged();
    }

    private void showFileChooser() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("*/*");
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        try {
            startActivityForResult(Intent.createChooser(intent, "请选择一个要上传的文件"), 1);
        } catch (android.content.ActivityNotFoundException ex) {
            Toast.makeText(this, "请安装文件管理器", Toast.LENGTH_SHORT)
                    .show();
        }
    }

    public String getRealPathFromURI(Context context, Uri contentUri) {
        Cursor cursor = null;
        try {
            String[] proj = { MediaStore.Images.Media.DATA };
            cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }
    }

    public void downloadFile(String objectKey) {
        final String filePath = DEFAULT_FILE_SAVE_PATH + objectKey.substring(objectKey.lastIndexOf("/") + 1);
        GetObjectRequest get = new GetObjectRequest(AppUtil.bucketName, objectKey);
        AppUtil.oss.asyncGetObejct(get, new OSSCompletedCallback<GetObjectRequest, GetObjectResult>() {
            @Override
            public void onSuccess(GetObjectRequest getObjectRequest, GetObjectResult getObjectResult) {

                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(FileExplorerActivity.this.getApplicationContext(), "下载成功!", Toast.LENGTH_SHORT).show();
                    }
                });
            }

            @Override
            public void onFailure(GetObjectRequest getObjectRequest, ClientException e, ServiceException e1) {
                runOnUiThread(new Runnable() {
                    public void run() {
                        Toast.makeText(FileExplorerActivity.this.getApplicationContext(), "下载失败!", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode != Activity.RESULT_OK) {
            super.onActivityResult(requestCode, resultCode, data);
            return;
        }
        if (requestCode == 1) {
            Uri uri = data.getData();
            final String path = getRealPathFromURI(this.getApplicationContext(), uri);
            final String fileName = path.substring(path.lastIndexOf("/") + 1);
            final String objectKey = currentPath + fileName;
            PutObjectRequest put = new PutObjectRequest(AppUtil.bucketName, objectKey, path);
            AppUtil.oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
                @Override
                public void onSuccess(PutObjectRequest putObjectRequest, PutObjectResult putObjectResult) {
                    runOnUiThread(new Runnable() {
                        public void run() {
                            adapter.getDataSource().add(new FileObject(fileName, FileType.FILE));
                            adapter.notifyDataSetChanged();
                        }
                    });
                }

                @Override
                public void onFailure(PutObjectRequest putObjectRequest, ClientException e, ServiceException e1) {
                    runOnUiThread(new Runnable() {
                        public void run() {
                            Toast.makeText(FileExplorerActivity.this.getApplicationContext(), "上传失败!", Toast.LENGTH_SHORT).show();
                        }
                    });
                }
            });
        }
        super.onActivityResult(requestCode, resultCode, data);
    };

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
        case R.id.button_upload:
            showFileChooser();
            break;
        default:
            break;
        }
    }

    public void setCurrentPath(String currentPath) {
        this.currentPath = currentPath;
		if (currentPath.length() != 0) {
		    uploadBtn.setEnabled(true);
		} else {
		    uploadBtn.setEnabled(false);
		}
    }

    @Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long row) {
		FileObject fo = adapter.getDataSource().get(position);
		if (fo.getFileType() == FileType.FOLDER) {
		    if (fo.getFileName().equals("..")) {
                // 返回上一级目录
		        String upperFolder = currentPath.substring(0, currentPath.lastIndexOf("/"));
		        upperFolder = upperFolder.substring(0, upperFolder.lastIndexOf("/") + 1);
		        setCurrentPath(upperFolder);
		        adapter.traceBackToPreviousDataSource();
		        adapter.notifyDataSetChanged();
		    } else {
                // 发起网络请求,读取下一级文件列表
                ListObjectsRequest listObject = new ListObjectsRequest(AppUtil.bucketName);
                listObject.setDelimiter("/");
                listObject.setPrefix(currentPath + fo.getFileName());
                listObject.setMaxKeys(1000);
		       	new ListObjectInBucketTask(adapter, this).execute(listObject);
		    }
		} else if (fo.getFileType() == FileType.FILE) {
		    final String fileName = currentPath + fo.getFileName();
		    AlertDialog.Builder builder = new Builder(FileExplorerActivity.this);
		    builder.setMessage("是否下载文件?");
		    builder.setTitle("文件下载");
		    builder.setPositiveButton("开始下载", new DialogInterface.OnClickListener() {
		        @Override
		        public void onClick(DialogInterface dialog, int which) {
		            dialog.dismiss();
		            downloadFile(fileName);
		        }
		    });
		    builder.setNegativeButton("取消下载", new DialogInterface.OnClickListener() {
		        @Override
		        public void onClick(DialogInterface dialog, int which) {
		            dialog.dismiss();
		        }
		    });
		    builder.create().show();
		}
	}
}


text:
* **Name:**			PyrocyniBot
* **Type:**			Bot/Twitter
* **URL:**			https://apps.lcast15.com/PyrocyniBot
* **Links:**		https://twitter.com/PyrocyniBot
* **Language:**		Python 3.7

## Project Description

PyrocyniBot is a simple Twitter bot that replies to tweets by Pyrocynical (internet sensation) with a random meme inspired or taken from him (or her).

## How To Use

### 1. **Install Libraries Required**
 > pip install python-twitter
### 2. Create a Twitter App, If You Haven't Already
 Follow steps 1 & 2 of [this tutorial from Digital Ocean](https://www.digitalocean.com/community/tutorials/how-to-create-a-twitter-app). Disregard the other steps, we don't use them in this bot.
### 3. **Config the Bot**
 Open *pyrocynibot.py* in a text editor and change these variables to your own apps settings:
```
ConsumerKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
ConsumerSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
AccessToken = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
AccessTokenSecret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
```
 Now, go to [tweeterid.com](https://tweeterid.com/) and type the target account's Twitter handle. We require that you do not abuse this to target and harass people.
 > Please note we have left Pyrocynical's Twitter ID blank for a reason. Do not use this bot on anyone who has not approved of it.
 Then, use that ID the website gave you and paste it in here:
```
PyroAccount = 'xxxxxxxxxxxxxxxxxx'
```
### 4. **Start the Bot**
 By this point, the bot should run just fine. If you have an issue that isn't a config issue, please either contact me or use the issues feature on GitHub.

## Required Libraries

* [python-twitter](https://github.com/bear/python-twitter)


text:
Kamaelia.Codec.Crypt.Decryptor

class Decryptor(Axon.Component.component)

Inboxes

   control : Secondary inbox often used for signals. The closest analogy is unix signals

   inbox : Default inbox for bulk data. Used in a pipeline much like stdin

Outboxes

   outbox : Default data out outbox, used in a pipeline much like stdout

   signal : The default signal based outbox - kinda like stderr, but more for sending singal type signals

Methods defined here

[[boxright][[include][file=Components/MethodNote.html][croptop=1][crop
bottom=1] ] ]

__init___(self, key)

main(self)

 Feedback

Got a problem with the documentation? Something unclear, could
be clearer? Want to help with improving? Constructive criticism,
preferably in the form of suggested rewording is very welcome.

Please leave the feedback

here, in reply to the documentation thread in the Kamaelia blog.