text:
#include <iomanip>
#include <dae/daeElement.h>
#include <dae/daeArray.h>
#include <dae/daeMetaAttribute.h>
#include <dae/daeMetaElementAttribute.h>
#include <dae/daeMetaElement.h>
#include <dae/daeDatabase.h>
#include <dae/daeErrorHandler.h>
#include <dae/daeURI.h>
#include <dae/daeUtils.h>
#include <dae/daeDom.h>

#include <limits>
#include <iomanip>

using namespace std;

daeElement* daeElement::simpleAdd(daeString name, int index) {
    if (daeElementRef elt = _meta->create(name))
        return add(elt, index);
    return NULL;
}

daeElement* daeElement::add(daeString names_, int index) {
    list<string> names;
    cdom::tokenize(names_, " ", names);
    cdom::tokenIter iter = names.begin();
    daeElement* root = simpleAdd(iter->c_str(), index);
    if (!root)
        return NULL;

    iter++;
    daeElement* elt = root;
    for (; iter != names.end(); iter++) {
        elt = elt->simpleAdd(iter->c_str());
        if (!elt) {
            removeChildElement(root);
            return NULL;
        }
    }

    return elt;
}

daeElement* daeElement::add(daeElement* elt, int index) {
    if (!elt)
        return NULL;
    if (elt == this)
        return this;
    bool result = (index == -1 ? _meta->place(this, elt) : _meta->placeAt(index, this, elt));
    return result ? elt : NULL;
}

daeElement* daeElement::addBefore(daeElement* elt, daeElement* index) {
    if (!index || !elt || index->getParent() != this)
        return NULL;
    return _meta->placeBefore(index, this, elt) ? elt : NULL;
}

daeElement* daeElement::addAfter(daeElement* elt, daeElement* index) {
    if (!index || !elt || index->getParent() != this)
        return NULL;
    return _meta->placeAfter(index, this, elt) ? elt : NULL;
}

daeElementRef
daeElement::createElement(daeString className)
{
    daeElementRef elem = _meta->create(className);
    // Bug #225 work around
//	if ( elem != NULL)
//		elem->ref(); // change premature delete into memory leak.
    return elem;
}

daeElement* daeElement::createAndPlace(daeString className) {
    return add(className);
}

daeElement* daeElement::createAndPlaceAt(daeInt index, daeString className) {
    return add(className, index);
}

daeBool daeElement::placeElement(daeElement* e) {
    return add(e) != NULL;
}

daeBool daeElement::placeElementAt(daeInt index, daeElement* e) {
    return add(e, index) != NULL;
}

daeBool daeElement::placeElementBefore( daeElement *marker, daeElement *element ) {
    return addBefore(element, marker) != NULL;
}

daeBool daeElement::placeElementAfter( daeElement *marker, daeElement *element ) {
    return addAfter(element, marker) != NULL;
}

daeInt daeElement::findLastIndexOf( daeString elementName ) {
    if ( _meta->getContents() != NULL ) {
        daeElementRefArray* contents =
            (daeElementRefArray*)_meta->getContents()->getWritableMemory(this);
        for ( int i = (int)contents->getCount()-1; i >= 0; --i ) {
            if ( strcmp( contents->get(i)->getElementName(), elementName ) == 0 ) {
                return i;
            }
        }
    }
    return -1;
}

daeBool
daeElement::removeChildElement(daeElement* element)
{
    // error traps
    if(element==NULL)
        return false;
    if(element->_parent != this)
        return false;

    return _meta->remove( this, element );
}

void daeElement::setDocument( daeDocument *c, bool notifyDocument ) {
    if( _document == c )
        return;

    // Notify our parent document if necessary.
    if ( _document != NULL && notifyDocument )
        _document->removeElement(this);
    _document = c;
    if ( _document != NULL && notifyDocument )
        _document->insertElement(this);

    // Notify our attributes
    daeMetaAttributeRefArray& metaAttrs = getMeta()->getMetaAttributes();
    for (size_t i = 0; i < metaAttrs.getCount(); i++)
        metaAttrs[i]->setDocument(this, c);

    // Notify our char data object
    if (getCharDataObject())
        getCharDataObject()->setDocument(this, c);

    // Notify our children
    daeElementRefArray ea;
    getChildren( ea );
    for ( size_t x = 0; x < ea.getCount(); x++ ) {
        // Since inserting and removing elements works recursively in the database,
        // we don't need to notify it about inserts/removals as we process the
        // children of this element.
        ea[x]->setDocument( c, false );
    }
}

void daeElement::deleteCMDataArray(daeTArray<daeCharArray*>& cmData) {
    for (unsigned int i = 0; i < cmData.getCount(); i++)
        delete cmData.get(i);
    cmData.clear();
}

size_t daeElement::getAttributeCount() {
    return getMeta()->getMetaAttributes().getCount();
}

namespace {
// A helper function to get the index of an attribute given the attribute name.
size_t getAttributeIndex(daeElement& el, daeString name) {
    if (el.getMeta()) {
        daeMetaAttributeRefArray& metaAttrs = el.getMeta()->getMetaAttributes();
        for (size_t i = 0; i < metaAttrs.getCount(); i++)
            if (metaAttrs[i]->getName()  &&  strcmp(metaAttrs[i]->getName(), name) == 0)
                return i;
    }
    return (size_t)-1;
}
}

daeMetaAttribute* daeElement::getAttributeObject(size_t i) {
    daeMetaAttributeRefArray& attrs = getMeta()->getMetaAttributes();
    if (i >= attrs.getCount())
        return NULL;
    return attrs[i];
}

daeMetaAttribute* daeElement::getAttributeObject(daeString name) {
    return getAttributeObject(getAttributeIndex(*this, name));
}

std::string daeElement::getAttributeName(size_t i) {
    if (daeMetaAttribute* attr = getAttributeObject(i))
        return (daeString)attr->getName();
    return "";
}

daeBool daeElement::hasAttribute(daeString name) {
    return getAttributeObject(name) != 0;
}

daeBool daeElement::isAttributeSet(daeString name) {
    size_t i = getAttributeIndex(*this, name);
    if (i != (size_t)-1)
        return _validAttributeArray[i];
    return false;
}

std::string daeElement::getAttribute(size_t i) {
    std::string value;
    getAttribute(i, value);
    return value;
}

void daeElement::getAttribute(size_t i, std::string& value) {
    value = "";
    if (daeMetaAttribute* attr = getAttributeObject(i)) {
        std::ostringstream buffer;
#ifdef COLLADA_DOM_DAEFLOAT_IS64
        buffer << std::setprecision(std::numeric_limits<PLATFORM_FLOAT64>::digits10+1); // set the default precision to daeFloat digit
#endif
        attr->memoryToString(this, buffer);
        value = buffer.str();
    }
}

std::string daeElement::getAttribute(daeString name) {
    std::string value;
    getAttribute(name, value);
    return value;
}

void daeElement::getAttribute(daeString name, std::string& value) {
    getAttribute(getAttributeIndex(*this, name), value);
}

daeElement::attr::attr() {
}
daeElement::attr::attr(const std::string& name, const std::string& value)
    : name(name), value(value) {
}

daeTArray<daeElement::attr> daeElement::getAttributes() {
    daeTArray<daeElement::attr> attrs;
    getAttributes(attrs);
    return attrs;
}

void daeElement::getAttributes(daeTArray<attr>& attrs) {
    attrs.clear();
    for (size_t i = 0; i < getAttributeCount(); i++) {
        std::string value;
        getAttribute(i, value);
        attrs.append(attr(getAttributeName(i), value));
    }
}

daeBool daeElement::setAttribute(size_t i, daeString value) {
    if (daeMetaAttribute* attr = getAttributeObject(i)) {
        if (attr->getType()) {
            attr->stringToMemory(this, value);
            _validAttributeArray.set(i, true);
            return true;
        }
    }
    return false;
}

daeBool daeElement::setAttribute(daeString name, daeString value) {
    return setAttribute(getAttributeIndex(*this, name), value);
}

// Deprecated
daeMemoryRef daeElement::getAttributeValue(daeString name) {
    if (daeMetaAttribute* attr = getAttributeObject(name))
        return attr->get(this);
    return NULL;
}

daeMetaAttribute* daeElement::getCharDataObject() {
    if (_meta)
        return _meta->getValueAttribute();
    return NULL;
}

daeBool daeElement::hasCharData() {
    return getCharDataObject() != NULL;
}

std::string daeElement::getCharData() {
    std::string result;
    getCharData(result);
    return result;
}

void daeElement::getCharData(std::string& data) {
    data = "";
    if (daeMetaAttribute* charDataAttr = getCharDataObject()) {
        std::ostringstream buffer; // no need to setprecision since this is char data?
        charDataAttr->memoryToString(this, buffer);
        data = buffer.str();
    }
}

daeBool daeElement::setCharData(const std::string& data) {
    if (daeMetaAttribute* charDataAttr = getCharDataObject()) {
        charDataAttr->stringToMemory(this, data.c_str());
        return true;
    }
    return false;
}

daeBool daeElement::hasValue() {
    return hasCharData();
}

daeMemoryRef daeElement::getValuePointer() {
    if (daeMetaAttribute* charDataAttr = getCharDataObject())
        return charDataAttr->get(this);
    return NULL;
}

void
daeElement::setup(daeMetaElement* meta)
{
    if (_meta)
        return;
    _meta = meta;
    daeMetaAttributeRefArray& attrs = meta->getMetaAttributes();
    int macnt = (int)attrs.getCount();

    _validAttributeArray.setCount(macnt, false);

    for (int i = 0; i < macnt; i++) {
        if (attrs[i]->getDefaultValue() != NULL)
            attrs[i]->copyDefault(this);
    }

    //set up the _CMData array if there is one
    if ( _meta->getMetaCMData() != NULL )
    {
        daeTArray< daeCharArray *> *CMData = (daeTArray< daeCharArray *>*)_meta->getMetaCMData()->getWritableMemory(this);
        CMData->setCount( _meta->getNumChoices() );
        for ( unsigned int i = 0; i < _meta->getNumChoices(); i++ )
        {
            CMData->set( i, new daeCharArray() );
        }
    }
}

void daeElement::init() {
    _parent = NULL;
    _document = NULL;
    _meta = NULL;
    _elementName = NULL;
    _userData = NULL;
}

daeElement::daeElement() {
    init();
}

daeElement::daeElement(DAE& dae) {
    init();
}

daeElement::~daeElement()
{
    if (_elementName) {
        delete[] _elementName;
        _elementName = NULL;
    }
}

//function used until we clarify what's a type and what's a name for an element
daeString daeElement::getTypeName() const
{
    return _meta->getName();
}
daeString daeElement::getElementName() const
{
    return _elementName ? _elementName : (daeString)_meta->getName();
}
void daeElement::setElementName( daeString nm ) {
    if ( nm == NULL ) {
        if ( _elementName ) delete[] _elementName;
        _elementName = NULL;
        return;
    }
    if ( !_elementName ) _elementName = new daeChar[128];
    strcpy( (char*)_elementName, nm );
}

daeString daeElement::getID() const {
    daeElement* this_ = const_cast<daeElement*>(this);
    if (_meta)
        if (daeMetaAttribute* idAttr = this_->getAttributeObject("id"))
            return *(daeStringRef*)idAttr->get(this_);
    return NULL;
}

daeElementRefArray daeElement::getChildren() {
    daeElementRefArray array;
    getChildren(array);
    return array;
}

void daeElement::getChildren( daeElementRefArray &array ) {
    _meta->getChildren( this, array );
}

daeSmartRef<daeElement> daeElement::clone(daeString idSuffix, daeString nameSuffix) {
    // Use the meta object system to create a new instance of this element. We need to
    // create a new meta if we're cloning a domAny object because domAnys never share meta objects.
    // Ideally we'd be able to clone the _meta for domAny objects. Then we wouldn't need
    // any additional special case code for cloning domAny. Unfortunately, we don't have a
    // daeMetaElement::clone method.
    bool any = typeID() == getDomAnyID(*getDAE());
    daeElementRef ret = any ? registerElementAny(*getDAE())->create() : _meta->create();
    ret->setElementName( _elementName );

    // Copy the attributes and character data. Requires special care for domAny.
    if (any) {
        copyElementAny(this,ret);
    } else {
        // Use the meta system to copy attributes
        daeMetaAttributeRefArray &attrs = _meta->getMetaAttributes();
        for (unsigned int i = 0; i < attrs.getCount(); i++) {
            attrs[i]->copy( ret, this );
            ret->_validAttributeArray[i] = _validAttributeArray[i];
        }
        if (daeMetaAttribute* valueAttr = getCharDataObject())
            valueAttr->copy( ret, this );
    }

    daeElementRefArray children;
    _meta->getChildren( this, children );
    for ( size_t x = 0; x < children.getCount(); x++ ) {
        ret->placeElement( children.get(x)->clone( idSuffix, nameSuffix ) );
    }

    // Mangle the id
    if (idSuffix) {
        std::string id = ret->getAttribute("id");
        if (!id.empty())
            ret->setAttribute("id", (id + idSuffix).c_str());
    }
    // Mangle the name
    if (nameSuffix) {
        std::string name = ret->getAttribute("name");
        if (!name.empty())
            ret->setAttribute("name", (name + nameSuffix).c_str());
    }
    return ret;
}

// Element comparison

namespace { // Utility functions
int getNecessaryColumnWidth(const vector<string>& tokens) {
    int result = 0;
    for (size_t i = 0; i < tokens.size(); i++) {
        int tokenLength = int(tokens[i].length() > 0 ? tokens[i].length()+2 : 0);
        result = max(tokenLength, result);
    }
    return result;
}

string formatToken(const string& token) {
    if (token.length() <= 50)
        return token;
    return token.substr(0, 47) + "...";
}
} // namespace {

daeElement::compareResult::compareResult()
    : compareValue(0),
    elt1(NULL),
    elt2(NULL),
    nameMismatch(false),
    attrMismatch(""),
    charDataMismatch(false),
    childCountMismatch(false) {
}

string daeElement::compareResult::format() {
    if (!elt1 || !elt2)
        return "";

    // Gather the data we'll be printing
    string name1 = formatToken(elt1->getElementName()),
           name2 = formatToken(elt2->getElementName()),
           type1 = formatToken(elt1->getTypeName()),
           type2 = formatToken(elt2->getTypeName()),
           id1 = formatToken(elt1->getAttribute("id")),
           id2 = formatToken(elt2->getAttribute("id")),
           attrName1 = formatToken(attrMismatch),
           attrName2 = formatToken(attrMismatch),
           attrValue1 = formatToken(elt1->getAttribute(attrMismatch.c_str())),
           attrValue2 = formatToken(elt2->getAttribute(attrMismatch.c_str())),
           charData1 = formatToken(elt1->getCharData()),
           charData2 = formatToken(elt2->getCharData()),
           childCount1 = formatToken(cdom::toString(elt1->getChildren().getCount())),
           childCount2 = formatToken(cdom::toString(elt2->getChildren().getCount()));

    // Compute formatting information
    vector<string> col1Tokens = cdom::makeStringArray("Name", "Type", "ID",
                                                      "Attr name", "Attr value", "Char data", "Child count", 0);
    vector<string> col2Tokens = cdom::makeStringArray("Element 1", name1.c_str(),
                                                      type1.c_str(), id1.c_str(), attrName1.c_str(), attrValue1.c_str(),
                                                      charData1.c_str(), childCount1.c_str(), 0);

    int c1w = getNecessaryColumnWidth(col1Tokens),
        c2w = getNecessaryColumnWidth(col2Tokens);
    ostringstream msg;
    msg << setw(c1w) << left << ""            << setw(c2w) << left << "Element 1" << "Element 2\n"
        << setw(c1w) << left << ""            << setw(c2w) << left << "---------" << "---------\n"
        << setw(c1w) << left << "Name"        << setw(c2w) << left << name1 << name2 << endl
        << setw(c1w) << left << "Type"        << setw(c2w) << left << type1 << type2 << endl
        << setw(c1w) << left << "ID"          << setw(c2w) << left << id1 << id2 << endl
        << setw(c1w) << left << "Attr name"   << setw(c2w) << left << attrName1 << attrName2 << endl
        << setw(c1w) << left << "Attr value"  << setw(c2w) << left << attrValue1 << attrValue2 << endl
        << setw(c1w) << left << "Char data"   << setw(c2w) << left << charData1 << charData2 << endl
        << setw(c1w) << left << "Child count" << setw(c2w) << left << childCount1 << childCount2;

    return msg.str();
}

namespace {
daeElement::compareResult compareMatch() {
    daeElement::compareResult result;
    result.compareValue = 0;
    return result;
}

daeElement::compareResult nameMismatch(daeElement& elt1, daeElement& elt2) {
    daeElement::compareResult result;
    result.elt1 = &elt1;
    result.elt2 = &elt2;
    result.compareValue = strcmp(elt1.getElementName(), elt2.getElementName());
    result.nameMismatch = true;
    return result;
}

daeElement::compareResult attrMismatch(daeElement& elt1, daeElement& elt2, const string& attr) {
    daeElement::compareResult result;
    result.elt1 = &elt1;
    result.elt2 = &elt2;
    result.compareValue = strcmp(elt1.getAttribute(attr.c_str()).c_str(),
                                 elt2.getAttribute(attr.c_str()).c_str());
    result.attrMismatch = attr;
    return result;
}

daeElement::compareResult charDataMismatch(daeElement& elt1, daeElement& elt2) {
    daeElement::compareResult result;
    result.elt1 = &elt1;
    result.elt2 = &elt2;
    result.compareValue = strcmp(elt1.getCharData().c_str(),
                                 elt2.getCharData().c_str());
    result.charDataMismatch = true;
    return result;
}

daeElement::compareResult childCountMismatch(daeElement& elt1, daeElement& elt2) {
    daeElement::compareResult result;
    result.elt1 = &elt1;
    result.elt2 = &elt2;
    daeElementRefArray children1 = elt1.getChildren(),
                       children2 = elt2.getChildren();
    result.compareValue = int(children1.getCount()) - int(children2.getCount());
    result.childCountMismatch = true;
    return result;
}

daeElement::compareResult compareElementsSameType(daeElement& elt1, daeElement& elt2) {
    // Compare attributes
    for (size_t i = 0; i < elt1.getAttributeCount(); i++)
        if (elt1.getAttributeObject(i)->compare(&elt1, &elt2) != 0)
            return attrMismatch(elt1, elt2, elt1.getAttributeName(i));

    // Compare character data
    if (elt1.getCharDataObject())
        if (elt1.getCharDataObject()->compare(&elt1, &elt2) != 0)
            return charDataMismatch(elt1, elt2);

    // Compare children
    daeElementRefArray children1 = elt1.getChildren(),
                       children2 = elt2.getChildren();
    if (children1.getCount() != children2.getCount())
        return childCountMismatch(elt1, elt2);
    for (size_t i = 0; i < children1.getCount(); i++) {
        daeElement::compareResult result = daeElement::compareWithFullResult(*children1[i], *children2[i]);
        if (result.compareValue != 0)
            return result;
    }

    return compareMatch();
}

daeElement::compareResult compareElementsDifferentTypes(daeElement& elt1, daeElement& elt2) {
    string value1, value2;

    // Compare attributes. Be careful because each element could have a
    // different number of attributes.
    if (elt1.getAttributeCount() > elt2.getAttributeCount())
        return attrMismatch(elt1, elt2, elt1.getAttributeName(elt2.getAttributeCount()));
    if (elt2.getAttributeCount() > elt1.getAttributeCount())
        return attrMismatch(elt1, elt2, elt2.getAttributeName(elt1.getAttributeCount()));
    for (size_t i = 0; i < elt1.getAttributeCount(); i++) {
        elt1.getAttribute(i, value1);
        elt2.getAttribute(elt1.getAttributeName(i).c_str(), value2);
        if (value1 != value2)
            return attrMismatch(elt1, elt2, elt1.getAttributeName(i));
    }

    // Compare character data
    elt1.getCharData(value1);
    elt2.getCharData(value2);
    if (value1 != value2)
        return charDataMismatch(elt1, elt2);

    // Compare children
    daeElementRefArray children1 = elt1.getChildren(),
                       children2 = elt2.getChildren();
    if (children1.getCount() != children2.getCount())
        return childCountMismatch(elt1, elt2);
    for (size_t i = 0; i < children1.getCount(); i++) {
        daeElement::compareResult result = daeElement::compareWithFullResult(*children1[i], *children2[i]);
        if (result.compareValue != 0)
            return result;
    }

    return compareMatch();
}
} // namespace {

int daeElement::compare(daeElement& elt1, daeElement& elt2) {
    return compareWithFullResult(elt1, elt2).compareValue;
}

daeElement::compareResult daeElement::compareWithFullResult(daeElement& elt1, daeElement& elt2) {
    // Check the element name
    if (strcmp(elt1.getElementName(), elt2.getElementName()) != 0)
        return nameMismatch(elt1, elt2);

    // Dispatch to a specific function based on whether or not the types are the same
    if ((elt1.typeID() != elt2.typeID())  ||  elt1.typeID() == getDomAnyID(*elt1.getDAE()))
        return compareElementsDifferentTypes(elt1, elt2);
    else
        return compareElementsSameType(elt1, elt2);
}

daeURI *daeElement::getDocumentURI() const {
    if ( _document == NULL ) {
        return NULL;
    }
    return _document->getDocumentURI();
}

daeElement::matchName::matchName(daeString name) : name(name) {
}

bool daeElement::matchName::operator()(daeElement* elt) const {
    return strcmp(elt->getElementName(), name.c_str()) == 0;
}

daeElement::matchType::matchType(daeInt typeID) : typeID(typeID) {
}

bool daeElement::matchType::operator()(daeElement* elt) const {
    return elt->typeID() == typeID;
}

daeElement* daeElement::getChild(const matchElement& matcher) {
    daeElementRefArray children;
    getChildren(children);
    for (size_t i = 0; i < children.getCount(); i++)
        if (matcher(children[i]))
            return children[i];

    return NULL;
}

daeElement* daeElement::getDescendant(const matchElement& matcher) {
    daeElementRefArray elts;
    getChildren(elts);

    for (size_t i = 0; i < elts.getCount(); i++) {
        // Check the current element for a match
        if (matcher(elts[i]))
            return elts[i];

        // Append the element's children to the queue
        daeElementRefArray children;
        elts[i]->getChildren(children);
        size_t oldCount = elts.getCount();
        elts.setCount(elts.getCount() + children.getCount());
        for (size_t j = 0; j < children.getCount(); j++)
            elts[oldCount + j] = children[j];
    }

    return NULL;
}

daeElement* daeElement::getAncestor(const matchElement& matcher) {
    daeElement* elt = getParent();
    while (elt) {
        if (matcher(elt))
            return elt;
        elt = elt->getParent();
    }

    return NULL;
}

daeElement* daeElement::getParent() {
    return _parent;
}

daeElement* daeElement::getChild(daeString eltName) {
    if (!eltName)
        return NULL;
    matchName test(eltName);
    return getChild(matchName(eltName));
}

daeElement* daeElement::getDescendant(daeString eltName) {
    if (!eltName)
        return NULL;
    return getDescendant(matchName(eltName));
}

daeElement* daeElement::getAncestor(daeString eltName) {
    if (!eltName)
        return NULL;
    return getAncestor(matchName(eltName));
}

DAE* daeElement::getDAE() {
    return _meta->getDAE();
}

void daeElement::setUserData(void* data) {
    _userData = data;
}

void* daeElement::getUserData() {
    return _userData;
}


text:
package org.snaker.engine.handlers.impl;

import java.util.List;

import org.snaker.engine.SnakerEngine;
import org.snaker.engine.SnakerException;
import org.snaker.engine.access.QueryFilter;
import org.snaker.engine.core.Execution;
import org.snaker.engine.entity.Order;
import org.snaker.engine.entity.Process;
import org.snaker.engine.entity.Task;
import org.snaker.engine.handlers.IHandler;
import org.snaker.engine.helper.StringHelper;
import org.snaker.engine.model.ProcessModel;
import org.snaker.engine.model.SubProcessModel;

/**
 * 结束流程实例的处理器
 * @author yuqs
 * @version 1.0
 */
public class EndProcessHandler implements IHandler {
	/**
	 * 结束当前流程实例,如果存在父流程,则触发父流程继续执行
	 */
	public void handle(Execution execution) {
		SnakerEngine engine = execution.getEngine();
		Order order = execution.getOrder();
		List<Task> tasks = engine.query().getActiveTasks(new QueryFilter().setOrderId(order.getId()));
		for(Task task : tasks) {
			if(task.isMajor()) throw new SnakerException("存在未完成的主办任务,请确认.");
			engine.task().complete(task.getId(), SnakerEngine.AUTO);
		}
		/**
		 * 结束当前流程实例
		 */
		engine.order().complete(order.getId());

		/**
		 * 如果存在父流程,则重新构造Execution执行对象,交给父流程的SubProcessModel模型execute
		 */
		if(StringHelper.isNotEmpty(order.getParentId())) {
			Order parentOrder = engine.query().getOrder(order.getParentId());
			if(parentOrder == null) return;
			Process process = engine.process().getProcessById(parentOrder.getProcessId());
			ProcessModel pm = process.getModel();
			if(pm == null) return;
			SubProcessModel spm = (SubProcessModel)pm.getNode(order.getParentNodeName());
            Execution newExecution = new Execution(engine, process, parentOrder, execution.getArgs());
            newExecution.setChildOrderId(order.getId());
            newExecution.setTask(execution.getTask());
			spm.execute(newExecution);
			/**
			 * SubProcessModel执行结果的tasks合并到当前执行对象execution的tasks列表中
			 */
			execution.addTasks(newExecution.getTasks());
		}
	}
}

redpajama_set_name: RedPajamaGithub


text:
package lab.uue.core.exception;

public class DuplicateTokenException extends BaseRuntimeException{

    public DuplicateTokenException(String msg) {
        super(msg);
    }

    public DuplicateTokenException(String msg, Throwable cause) {
        super(msg, cause);
    }
}


text:
#!/data/data/marzec/app_bin/sh
#
# see attacks-common for arguments, the args are converted to vars there. The
# first arg $1 is the "app payload" directory, where the included scripts are
# kept.

# many phones don't even include 'test', so set the path to our
# busybox tools first, where we provide all the UNIX tools needed by
# this script
export PATH=$1:$PATH

test -e $1/marzecpro_co || exit 1
. $1/marzecpro_co

echo -n "Asking all processes to terminate..."
# first send TERM
for root in /proc/*/root; do
  if [ ! -r "$root" ] || [ ! "`readlink "$root"`" = "$mnt" ]; then
    continue
  fi
  pid="${root#/proc/}"
  pid="${pid%/root}"
  kill -TERM "$pid" 2>/dev/null || true
done
# /debian/shell starts outside of the chroot, so it must be killed separately
for pid in `ps | grep '/[d]ebian/shell' | cut -b1-5`; do
    kill -TERM $pid
done
sleep 1
echo "done"
# then send KILL to force the rest to die
echo "Killing remaining processes:"
for root in /proc/*/root; do
  if [ ! -r "$root" ] || [ ! "`readlink "$root"`" = "$mnt" ]; then
    continue
  fi
  pid="${root#/proc/}"
  pid="${pid%/root}"
  echo "$pid `readlink $(dirname $root)/exe`"
  kill -KILL "$pid" 2>/dev/null || true
done
for pid in `ps | grep '/[d]ebian/shell' | cut -b1-5`; do
    echo "$pid /debian/shell"
    kill -KILL $pid
done
echo "done"

echo -n "Checking for open files in Debian chroot..."
openfiles=`lsof $mnt | grep -v $(basename $install_path) | sed -n "s|.*\($mnt.*\)|\1|p"`
echo "done"

if [ ! -z "$openfiles" ]; then
    echo "Files that are still open:"
    for line in $openfiles; do
        echo $line
    done

    echo ""
    echo "Not stopping MarzecPro because of open files, quit all processes and running shell sessions!"
    exit 1
else
    echo -n "Unmounting everything..."
    # sort reverse so it gets the nested mounts first
    for mount in `cut -d ' ' -f 2 /proc/mounts | grep $mnt/ | sort -r`; do
        $busybox_path/umount -f $mount
    done

    if [ x"$install_on_internal_storage" = xno ]; then
        umount -d $mnt || /system/bin/umount $mnt || echo "Failed to unmount $mnt!"
    fi
    echo "done"

    attached=`find_attached_loopdev`
    if [ ! -z $attached ]; then
        echo -n "Deleting loopback device..."
        $losetup -d $attached
        echo "done"
    fi

    echo ""
    echo "MarzecPro stopped and unmounted."
    if [ -e $sha1file ]; then
        echo -n "Calculating new SHA1 checksum of $install_path..."
        $app_bin/sha1sum $install_path > $sha1file
        chmod 0600 $sha1file
        cp $sha1file `dirname $install_path`
        echo "Done!"
    fi
fi


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

<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>GLM_GTX_mixed_producte: Mixed product</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="doxygen.css" rel="stylesheet" type="text/css"/>

Main Page

Related Pages

Modules

Classes

Files

Functions

GLM_GTX_mixed_producte: Mixed product

GTX Extensions (Experimental)

Mixed product of 3 vectors.
More...

Functions

template<typename valType >

valType 	mixedProduct (detail::tvec3< valType > const &v1, detail::tvec3< valType > const &v2, detail::tvec3< valType > const &v3)

Detailed Description

Mixed product of 3 vectors.

<glm/gtx/mixed_product.hpp> need to be included to use these functionalities.

<address class="footer">Generated by

 1.7.4 </address>


text:
hub: git + hub = github
=======================

`hub` is a command line utility which adds GitHub knowledge to `git`.

It can be used on its own or as a `git` wrapper.

Normal:

    $ hub clone rtomayko/tilt

    Expands to:
    $ git clone git://github.com/rtomayko/tilt.git

Wrapping `git`:

    $ git clone rack/rack

    Expands to:
    $ git clone git://github.com/rack/rack.git

hub requires you have `git` installed and in your `$PATH`. It also
requires Ruby 1.8.6+ or Ruby 1.9.1+. No other libraries necessary.

Install
-------

### Standalone

`hub` is most easily installed as a standalone script:

    curl http://defunkt.io/hub/standalone -sLo ~/bin/hub &&
    chmod 755 ~/bin/hub

Assuming `~/bin/` is in your `$PATH`, you're ready to roll:

    $ hub version
    git version 1.7.0.4
    hub version 1.1.0

### Homebrew

    $ brew install hub
    $ which hub
    /usr/local/bin/hub
    $ hub version
    ...

### RubyGems

Though not recommended, `hub` can also be installed as a RubyGem:

    $ gem install hub

(It's not recommended for casual use because of the RubyGems startup
time. See [this gist][speed] for information.)

### Standalone via RubyGems

    $ gem install hub
    $ hub hub standalone > ~/bin/hub && chmod 755 ~/bin/hub

This installs a standalone version which doesn't require RubyGems to
run.

### Source

You can also install from source:

    $ git clone git://github.com/defunkt/hub.git
    $ cd hub
    $ rake install prefix=/usr/local

### Help! It's Slow!

Is your prompt slow? It may be hub.

1. Check that it's **not** installed using RubyGems.
2. Check that RUBYOPT isn't loading anything shady:

       $ echo $RUBYOPT

3. Check that your system Ruby is speedy:

       $ time /usr/bin/env ruby -e0

If #3 is slow, it may be your [GC settings][gc].

Aliasing
--------

`hub` works best when it wraps `git`. This is not dangerous - your
normal git commands should all work. hub merely adds some sugar.

Typing `hub alias <shell>` will display alias instructions for
your shell. `hub alias` alone will show the known shells.

For example:

    $ hub alias bash
    Run this in your shell to start using `hub` as `git`:
      alias git=hub

You should place this command in your `.bash_profile` or other startup
script to ensure runs on login.

The alias command can also be eval'd directly using the `-s` flag:

    $ eval `hub alias -s bash`

Commands
--------

Assuming you've aliased `hub` to `git` the following commands now have
superpowers:

### git clone

    $ git clone schacon/ticgit
    > git clone git://github.com/schacon/ticgit.git

    $ git clone -p schacon/ticgit
    > git clone git@github.com:schacon/ticgit.git

    $ git clone resque
    > git clone git://github.com/YOUR_USER/resque.git

    $ git clone -p resque
    > git clone git@github.com:YOUR_USER/resque.git

### git remote add

    $ git remote add rtomayko
    > git remote add rtomayko git://github.com/rtomayko/CURRENT_REPO.git

    $ git remote add -p rtomayko
    > git remote add rtomayko git@github.com:rtomayko/CURRENT_REPO.git

    $ git remote add origin
    > git remote add origin git://github.com/YOUR_USER/CURRENT_REPO.git

### git fetch

    $ git fetch mislav
    > git remote add mislav git://github.com/mislav/REPO.git
    > git fetch mislav

    $ git fetch mislav,xoebus
    > git remote add mislav ...
    > git remote add xoebus ...
    > git fetch --multiple mislav xoebus

### git cherry-pick

    $ git cherry-pick http://github.com/mislav/REPO/commit/SHA
    > git remote add -f mislav git://github.com/mislav/REPO.git
    > git cherry-pick SHA

    $ git cherry-pick mislav@SHA
    > git remote add -f mislav git://github.com/mislav/CURRENT_REPO.git
    > git cherry-pick SHA

    $ git cherry-pick mislav@SHA
    > git fetch mislav
    > git cherry-pick SHA

### git fork

    $ git fork
    ... hardcore forking action ...
    > git remote add -f YOUR_USER git@github.com:YOUR_USER/CURRENT_REPO.git

Forks the original repo on GitHub and adds the new remote under your
username. It requires your GitHub token to be present; see "GitHub
login" below for details.

### git create

    $ git create
    ... hardcore creating action ...
    > git remote add origin git@github.com:YOUR_USER/CURRENT_REPO.git

Creates a new public github repository and adds the remote `origin` at
"git@github.com:<USER>/<REPOSITORY>.git"

### git init

    $ git init -g
    > git init
    > git remote add origin git@github.com:YOUR_USER/REPO.git

### git push

    $ git push origin,staging,qa bert_timeout
    > git push origin bert_timeout
    > git push staging bert_timeout
    > git push qa bert_timeout

### git browse

    $ git browse
    > open https://github.com/YOUR_USER/CURRENT_REPO

    $ git browse -- issues
    > open https://github.com/YOUR_USER/CURRENT_REPO/issues

    $ git browse schacon/ticgit
    > open https://github.com/schacon/ticgit

    $ git browse resque
    > open https://github.com/YOUR_USER/resque

    $ git browse resque network
    > open https://github.com/YOUR_USER/resque/network

### git compare

    $ git compare refactor
    > open https://github.com/CURRENT_REPO/compare/refactor

    $ git compare 1.0..1.1
    > open https://github.com/CURRENT_REPO/compare/1.0...1.1

    $ git compare -u fix
    > (https://github.com/CURRENT_REPO/compare/fix)

    $ git compare other-user patch
    > open https://github.com/other-user/REPO/compare/patch

### git submodule

    $ hub submodule add wycats/bundler vendor/bundler
    > git submodule add git://github.com/wycats/bundler.git vendor/bundler

    $ hub submodule add -p wycats/bundler vendor/bundler
    > git submodule add git@github.com:wycats/bundler.git vendor/bundler

    $ hub submodule add -b ryppl ryppl/pip vendor/pip
    > git submodule add -b ryppl git://github.com/ryppl/pip.git vendor/pip

### git help

    $ git help
    > (improved git help)
    $ git help hub
    > (hub man page)

GitHub Login
------------

To get the most out of `hub`, you'll want to ensure your GitHub login
is stored locally in your Git config or environment variables.

To test it run this:

    $ git config --global github.user

If you see nothing, you need to set the config setting:

    $ git config --global github.user YOUR_USER

For commands that require write access to GitHub (such as `fork`), you'll want to
setup "github.token" as well. See [local GitHub config guide][2] for more information.

Want to use environment variables instead of a local gitconfig?

* `GITHUB_USER`  - If set, this will be used instead of the `github.user` config
                   value to determine your GitHub username.
* `GITHUB_TOKEN` - If set, this will be used instead of the `github.token` config
                   value to determine your GitHub API token.

Configuration
-------------

If you prefer `http://` clones to `git://` clones, you can set the
`hub.http-clone` option to true using `git-config`.

For example:

    $ git clone defunkt/repl
    < git clone >
    $ git config --global --bool hub.http-clone true
    $ git clone defunkt/repl
    < http clone >

Or you can enter this manually into your `~/.gitconfig` file:

    $ cat ~/.gitconfig
    [hub]
      http-clone = yes

Prior Art
---------

These projects also aim to either improve git or make interacting with
GitHub simpler:

* [eg](http://www.gnome.org/~newren/eg/)
* [github-gem](http://github.com/defunkt/github-gem)
* [gh](http://github.com/visionmedia/gh)

Contributing
------------

Once you've made your great commits:

1. [Fork][0] hub
2. Create a topic branch - `git checkout -b my_branch`
3. Push to your branch - `git push origin my_branch`
4. Create an [Issue][1] with a link to your branch
5. That's it!

### Development Gems
You will need the following gems (and their dependencies) to
contribute to `hub`:

* `rake` (`gem install rake`)
* `kicker` (`gem install kicker`)
* `turn` (`gem install turn`)
* `mg` (`gem install mg`)
* `ronn` (`gem install ronn`)
* `webmock` (`gem install webmock`)

Meta
----

* Code: `git clone git://github.com/defunkt/hub.git`
* Home: <http://github.com/defunkt/hub>
* Bugs: <http://github.com/defunkt/hub/issues>
* List: <http://groups.google.com/group/github>
* Test: <http://runcoderun.com/defunkt/hub>
* Gems: <http://gemcutter.org/gems/hub>

Authors
-------

<https://github.com/defunkt/hub/contributors>

[0]: http://help.github.com/forking/
[1]: http://github.com/defunkt/hub/issues
[speed]: http://gist.github.com/284823
[2]: http://github.com/guides/local-github-config
[gc]: https://twitter.com/brynary/status/49560668994674688


text:
package ru.lanwen.raml.rarc.api.ra.root;

import com.squareup.javapoet.ClassName;
import com.squareup.javapoet.JavaFile;
import com.squareup.javapoet.MethodSpec;
import com.squareup.javapoet.TypeSpec;
import org.raml.model.Raml;

import static javax.lang.model.element.Modifier.PRIVATE;
import static javax.lang.model.element.Modifier.PUBLIC;
import static javax.lang.model.element.Modifier.STATIC;
import static org.apache.commons.lang3.StringUtils.capitalize;
import static org.apache.commons.lang3.StringUtils.lowerCase;
import static ru.lanwen.raml.rarc.api.ApiResourceClass.sanitize;
import static ru.lanwen.raml.rarc.api.ra.NextResourceMethods.baseResource;

/**
 * @author lanwen (Merkushev Kirill)
 */
public class RootApiClase {

    private NestedConfigClass configClass;
    private ConfigField configField = new ConfigField();

    public RootApiClase(NestedConfigClass configClass) {
        this.configClass = configClass;
    }

    public JavaFile javaFile(Raml raml, String basePackage) {

        TypeSpec.Builder api = TypeSpec.classBuilder("Api" + capitalize(sanitize(raml.getTitle())))
                .addJavadoc("$L api client\n", raml.getTitle())
                .addJavadoc("Base URI pattern: $L\n", raml.getBaseUri())
                .addField(configField.fieldSpec())
                .addType(configClass.nestedConfSpec())
                .addMethod(MethodSpec.constructorBuilder().addParameter(ClassName.bestGuess(NestedConfigClass.CONFIG_NESTED_STATIC_CLASS_NAME), configField.name())
                        .addStatement("this.$N = $N", configField.name(), configField.name())
                        .addModifiers(PRIVATE)
                        .build())
                .addModifiers(PUBLIC);

        api.addMethod(MethodSpec.methodBuilder(lowerCase(sanitize(raml.getTitle())))
                .addParameter(ClassName.bestGuess(NestedConfigClass.CONFIG_NESTED_STATIC_CLASS_NAME), configField.name())
                .returns(ClassName.bestGuess(api.build().name))
                .addStatement("return new $N($N)", api.build().name, configField.name())
                .addModifiers(PUBLIC, STATIC)
                .build());

        raml.getResources().values().stream().forEach(resource ->
                api.addMethod(
                        baseResource(resource, basePackage, configField.name(), configClass.getBaseSupplField().name())
                ));

        return JavaFile.builder(basePackage, api.build()).build();
    }
}


text:
Knock.setup do |config|

  ## Expiration claim
  ## ----------------
  ##
  ## How long before a token is expired. If nil is provided, token will
  ## last forever.
  ##
  ## Default:
  expiraton = ENV['SOMBRA_TOKEN_EXPIRATION_IN_S'] || 3600
  config.token_lifetime = expiraton.to_i.seconds

  ## Audience claim
  ## --------------
  ##
  ## Configure the audience claim to identify the recipients that the token
  ## is intended for.
  ##
  ## Default:
  # config.token_audience = nil

  ## If using Auth0, uncomment the line below
  # config.token_audience = -> { Rails.application.secrets.auth0_client_id }

  ## Signature algorithm
  ## -------------------
  ##
  ## Configure the algorithm used to encode the token
  ##
  ## Default:
  config.token_signature_algorithm = 'ES256'

  ## Signature key
  ## -------------
  ##
  ## Configure the key used to sign tokens.
  ##
  ## Default:
  #config.token_secret_signature_key = -> { Rails.application.secrets.secret_key_base }
  config.token_secret_signature_key = -> { OpenSSL::PKey::EC.new Rails.application.secrets.token_es256_priv }

  ## If using Auth0, uncomment the line below
  # config.token_secret_signature_key = -> { JWT.base64url_decode Rails.application.secrets.auth0_client_secret }

  ## Public key
  ## ----------
  ##
  ## Configure the public key used to decode tokens, if required.
  ##
  ## Default:
  pubkey = OpenSSL::PKey::EC.new Rails.application.secrets.token_es256_priv
  pubkey.private_key = nil
  config.token_public_key = pubkey

  ## Exception Class
  ## ---------------
  ##
  ## Configure the exception to be used when user cannot be found.
  ##
  ## Default:
  config.not_found_exception_class_name = 'UserNotFound'
end


text: If you don't already have one, `sign up for a Google Account <https://accounts.google.com/SignUp>`_


text:
import {Injectable, EventEmitter} from 'angular2/core';

declare var window: any;

interface DrupalStateUser {
  uid: number;
  name: string;
  mail: string;
  roles: Array<any>;
}

@Injectable()
export class DrupalStateService {
  // @TODO: switch to RxJS Subject instead of EventEmitter
  private locationWatcher = new EventEmitter();
  private drupalSettings: any = {};
  private angleSettings: any = {};
  private authenticated: boolean = false;
  private user: DrupalStateUser;

  constructor() {
    this.drupalSettings = window.drupalSettings;
    this.angleSettings = this.drupalSettings.angled;
    this.user = this.angleSettings.user;
    this.authenticated = this.user.uid > 0;
  }

  public getPath() {
    return this.drupalSettings.path.baseUrl;
  }

  public getUser() {
    return this.user;
  }

  public setUser(user: DrupalStateUser) {
    this.user = user;
    // this.angleSettings.user: DrupalStateUser = user:
  }

  public emitAuthStatus(success: boolean) {
    this.authenticated = success;
    this.locationWatcher.emit({ success: success, authenticated: this.authenticated });
  }

  public subscribe(onNext:(value:any) => void, onThrow?:(exception:any) => void, onReturn?:() => void) {
    return this.locationWatcher.subscribe(onNext, onThrow, onReturn);
  }

  public isAuthenticated() {
    return this.authenticated;
  }
}


text:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

<TITLE>404 Not Found</TITLE>

Not Found

The requested URL /otherconf.html was not found on this server.


text:
//NOTE, feel free to experiment and edit whatever in this file

/*

INTRODUCTION

(some important) Plena modules and their use:

- Plena
    inital setup and some handy global functions (you don't really need to use this one)
- Assets
    for the loading of everything audio / images (textues, sprites), functions start with load
    furthermore assets can create some assets from nothing (canvases, fontmaps, text images, writable textures), functions start with mk
    And you can also transform assets canvas -> image for example (getTexture) and a function to get a font from a family and size (getFont)
    There is even some documentation for this module :), you can see it when you type assets and browser to the methods or start typing one.
- Font
    some predefined fonts, for use in the mkFont... and mkText... of assets. It contains stuff such as arial, times new roman etc...
- Mouse
    Everything related to the mouse, from adding click events to getting its position relative in the world to hiding the mouse and changing its icon
- Keyboard
    Everyting related to the keyboard, from binding key events to checking wether keys are down to disableing browser controll keys
- Color
    255 of defualt colors in the Color (a class you can access direcly) format. Means you can get the rbg/hex values easily (you can also set an alpha). Color is used in the libray for everything color related
    you can create your own color with new Color(...) or new AColor(...) for colors with a defined alpha value (you won't really use this, since we have textures)
- Views
    To create a new view, views are used for differnt perspectives, such as the UI and 2D view of the world. After making a view you can use it by calling YOUR_VIEW.view(). You can get the perdefined view with Plena.getDefaultView().
    You probebely wont be using this though, I will probebely set up the views, so you don't need to worry about it.
- MMath
    Some math functions I sometimes use (random, logaritems, angles and some more).
- Grix (MOST IMPORTANT ONE)
    (some information about them, not that imporant, but please read, a TL;DR (to long, didn't read) is below with the most important point)

    This contais funcitons to create specific grixes (grix stands for Graphics), and you need those to do all the drawing of stuff
    Actually, these grixes are the second level drawing classes in this library (second is the highest), which means they are the simpelest to use, but have the most restrictions (although are game can completely be build with them)
    There is also collection of classes in this library for first level (btw, I arbetrarely choose to call them levels and gave them numbers when writing this) drawing (which are used by the grixes), which are more powerfull and much harder to use.
    Finaly there is the lowest level of drawing, which means to direcly use WebGl for the drawing, this is the most powerfull, but also the most complicated, the first level classes use this.

    To give you a perspecive of how much harder it is to use a new level:

    To draw a walking cat:
        Second level +- 15 lines of code (HEAVEN!)
        First level +- 100 lines of code (Thats OK!)
        Zero level +500 lines of code (HELL!)

    But the second level, which this game will probaliy only use, is already very powerfull, really.

    TL;DR - with this module you can create objects with which you can easily render everthing you want. (you will mostly be useding these classes)
- Vector and Matrix
    You can create one of those if you want to do some operations with matrixes or vectors, such as making non standard transformations with images (if have got simple funcitons for the standart transforamtions, so you will probabily not use it)

And that concludes some of the most important parts of the library which we will use.
There is much more, especially on the graphics side (first level), but don't worry about it and be happy it is used by the second level.
Next to this, I have a file callsed data.ts which contains some datastructures such as lists, maps and trees, javascript and typescrpt do not have inbuild datasctures execpt for the array (which can be used as a map and a list), so I though about writing those myself.
But it is not neccacary to use and array will do just fine for everything. If you are interested, it contains (List, Bag, Queue, Stack, Heap, PriorityQueue, TreeMap, and a DeepTreeMap (something original, the others are default datastructures))

Don't worry if you forget everything from the above, but make sure to remember:

- Assets. -> you get methods for creating and loading assets (also called resources)
- Grix -> methods for creating drawable objects, then use those objects to draw.

Below are some examples that will make everything clear :).

*/

/*******
EXAMPLES, the examples can be viewed/run by running the server (the triangle button at the top, and then you can o to: localhost:3000/examples/EXAMPLE_ID).
You can find the example id at every example.

Every example has a commented and a clean version below it.
*******/

/*
 * ID : setup
 */

//This is how the default plena setup looks, as you can see the code for the game also has this.
module DefaultPlanaSetup {
    //This wil be run once
    function setup() {

    }

    //This will run every tick/frame, rendering code will be placed here
    function render(delta: number) {

    }

    //This will run every tick, logic will be placed here
    function update(delta: number) {

    }

    //normally this would not be in a function (so function run would not be there). It is here now so I cna have multiple examples in one file.
    export function run() {
        //The following line will setup the library, creaing a canvas etc.. does some magic (you won't see anything though).
        Plena.init(setup, render, update)

        //We can also gives background color, size and position of the game screen we want to create to the init function, nothing as above, means full window with a white background
        //example of a 200 by 200 window colored crimson poisitioned in the center (that is default):
        //Plena.init(setup, render, update, 500, 500, Color.Red.crimson())

        //Here follows an example of a 500 by 500 window colored crimson positiond in the top left corner:
        //Plena.init(setup, render, update, 0, 0, 500, 500, Color.Red.crimson())

        //And this will create a fullscreen canvas with wheat color
        //Plena.init(setup, render, update, Color.Brown.wheat())

        //You can uncomment the inits (commend the other out) to see what it does, you can also experiment of course
    }
}
//But do not worry too much about the setup, I did that already for the game.

//clean version
module DefaultPlanaSetup {
    function setup() { }
    function render(delta: number) { }
    function update(delta: number) { }

    //Plena.init(setup, render, update)
}

/*
 * ID : texture
 */

//note that I put this all into modules (DefaultPlanaSetup/SimpleTextureDrawing/etc.. to make sure code does not collide, it is not neccesary to put stuff into modules.)
module SimpleTextureDrawing {
    let cat: ImgGrix // you can see the type of grix you get when you use Grix.SOME_METHOD

    function setup() {
        //loading an image with Assets, and using it in Grix to create something from it which we can draw.
        //Two more paraeters are anvailable which can be used to set default width ans height, it defaults to the size of the image
        cat = Grix.fromTexture(Assets.loadImg("/scripts/tutorials/cat.png")) //width height bug, I just fixed it in the code, fix it in plena and push and new build here
    }

    function update(delta: number) {

    }

    function render(delta: number) {
        cat.render()//renders the cat at the 0, 0 position (left top) of our screen (the 500 by 500 thing we create below with the init function)
    }

    export function run() {
        //some random 700 by 700 screen colored gray slate light
        Plena.init(setup, render, update, 700, 700, Color.Gray.GRAY_SLATE_LIGHT);
    }
}

//a clean version
module SimpleTextureDrawingClean {
    let cat: ImgGrix

    function setup() {
        cat = Grix.fromTexture(Assets.loadImg("/scripts/tutorials/cat.png"))
    }

    function update(delta: number) { }
    function render(delta: number) {
        cat.render()
    }

    //Plena.init(setup, render, update, 700, 700, Color.Gray.GRAY_SLATE_LIGHT);
}

/*
 * ID : trans
 */

//everything about render transformations, moving, scaling, rotating etc..
module GrixTransformations {
    let cat: ImgGrix
    let rotation:number = 0

    function setup() {
        cat = Grix.fromTexture(Assets.loadImg("/scripts/tutorials/cat.png"))
    }

    function update(delta: number) {
        rotation += 0.001 * delta //delta depends on the clockspeed of a computer
        //multiplying things with it makes the update tick independent of the speed
        //of a computer we multiply everything concerning movement, updates etc..
        //so it will run with the same speed on any computer
    }

    function render(delta: number) {
        // here follow the basic transfoamtions that can be done with any grix

        //translation methods:
        //move, moveTo, moveXTo, moveYTo, setPiovtMove

        //default position of any grix is (0, 0)
        //move(x, y) : it moves the grix from (x_0, y_0) to (x_0 + x, y_0 + y)
        //moveTo(x, y) : it moves the grix from (x_0, y_0) to (x, y)
        //moveXTo(x) : it moves the grix (x_0, y_0) to (x_0 + x, y_0)
        //moveYTo(y) : it moves the grix (x_0, y_0) to (x_0, y_0 + y)
        //setPivotMove(x, y) : the coordinates are relative to the size of the image
        //which means that (0, 0) is the left top corner of the image, (1, 1) the
        //right bottom and (0.5, 0.5) the middle of the image. Use this to set the main
        //point of the grix, that where the grix is moved to. So with (0.5, 0.5) you set
        //the middle of the image to some location, which is handy for centering stuff.
        //and (0, 0) is handy for setting things in the top left corner etc...

        //scale methods:
        //scale, scaleTo, scaleToSize, scaleWithToSize, scaleHeightToSize

        //default scale of any grix is (1, 1) which is equal to the default width and the height
        //scale and scale to work the same as the move functions, now with scale
        //scale size is can be used to work instead of in a relative scale of 1 equals width/height
        //in a absolute scale were the width and height is put in units (pixels)

        //rotate methods:
        //rotate, rotateTo, rotateDeg, rotateToDeg, setPivotRotate
        //same as other methods above, two versions of for redians and one for degrees
        //you can also use MMath.toRad/toDeg to change between them.
        //use setPivotRotate to set the point of rotation, works the same as for the move one
        //it defaults to the middle so, (0.5, 0.5)

        //mirror methods:
        //mirrorHorizontal, mirrowVertical
        //should be intuitive enough

        //cleaning transformations:
        //clean
        //resets all translatoins, all translations are reset by default after one tick (as shoul be expected)

        //here is an example of the cat drawn in the middle of the screen, rotating arround with a width of 200 units (pixels, see text below)
        cat.setPivotMove(0.5, 0.5)
        cat.scaleWidthToSize(200)
        cat.moveTo(350, 350)//half of the screen size we set below (the default projection is 1:1, so one pixel is one unit in the game, this can also be changed)
        //to make sure you have always, say, the half of the view, you use: VIEW.getWith() / 2 and VIEW.getHeight() / 2. If you don't have a view you are most likely
        //using the default view which can be got by doing: Plena.getDefaultView()
        cat.rotateTo(rotation)
        cat.render()
    }

    export function run() {
        //some random 700 by 700 screen colored gray slate light
        Plena.init(setup, render, update, 700, 700, Color.Gray.GRAY_SLATE_LIGHT);
    }
}

//clean version without comments
module GrixTransformationsClean {
    let cat: ImgGrix
    let rotation: number = 0

    function setup() {
        cat = Grix.fromTexture(Assets.loadImg("/scripts/tutorials/cat.png"))
    }

    function update(delta: number) {
        rotation += 0.001 * delta
    }

    function render(delta: number) {
        cat.setPivotMove(0.5, 0.5)
        cat.scaleWidthToSize(200)
        cat.moveTo(350, 350)
        cat.rotateTo(rotation)

        cat.render()
    }

    //Plena.init(setup, render, update, 700, 700, Color.Gray.GRAY_SLATE_LIGHT);
}

/*
 * ID : persp
 */

//some stuff about keysbindings input etc.. and perspective (in this example the keys s, up, down, left and right do stuff)
module PerspectiveAndInput {
    let cat: ImgGrix

    let rotation: number = 0

    let rotDir: number = 1
    let rotSpeed: number = 1

    function setup() {
        cat = Grix.fromTexture(Assets.loadImg("/scripts/tutorials/cat.png"))

        //defining everything in pixels is not handy, it will cause probelsm and akwarness when computer screens do not all have the same resolutions, or
        //the screen is resizes etc..

        //we can define a fixed resolution for either the width or the height for a view. That view will then always have that specific size.
        //So for example when we set the height to a fixed value of 1000, setting the height of an image to 200 it will then always be 1/5th of the screen.
        //So we no longer work in pixels
        Plena.getDefaultView().fixedResolutionH(1000) // try making the screen very small in height, you can see everything still looks as intended, in contrast to the last examples
        //refresh after resizing though

        Keyboard.addPressedEvent(clockwise, Keyboard.KEY_RIGHT) //binding a fucntion to the perssing of a key, this means function clockwise is called if we press the right arrow key
        Keyboard.addPressedEvent(counterClockwise, Keyboard.KEY_LEFT) //same as above, differnet function and differnent key though
        Keyboard.addPressedEvent(increaseSpeed, Keyboard.KEY_UP) //same as above, differnet function and differnent key though, try increasing the speed for a long time, it has curious effects
        Keyboard.addPressedEvent(decreaseSpeed, Keyboard.KEY_DOWN) //same as above, differnet function and differnent key though
        //these functions can be done is a more efficient way than to write new functions, but this is more clear for an example
    }

    function update(delta: number) {
        rotation += rotDir * rotSpeed * 0.001 * delta
    }

    function render(delta: number) {
        let view = Plena.getDefaultView()

        cat.setPivotMove(0.5, 0.5)
        if (Keyboard.isDown(Keyboard.KEY_S)) cat.scaleWidthToSize(200) //0.2 of the height, only if we old s
        else cat.scaleWidthToSize(500)//half the height
        cat.moveTo(view.getWidth() / 2, view.getHeight() / 2) //best way to center things, we could have used 500 for the width though.
        cat.rotateTo(rotation)

        cat.render()
    }

    export function run() {
        //we are in fullscreen mode indeed
        Plena.init(setup, render, update, Color.Gray.GRAY_SLATE_LIGHT);
    }

    function clockwise(event: KeyboardEvent) {
        rotDir = 1
    }

    function counterClockwise(event: KeyboardEvent) {
        rotDir = -1
    }

    function increaseSpeed(event: KeyboardEvent) {
        rotSpeed += 100
    }

    function decreaseSpeed(event: KeyboardEvent) {
        if (rotSpeed > 0) rotSpeed -= 100
    }
}

//clean version
module PerspectiveAndInputClean {
    let cat: ImgGrix

    let rotation: number = 0

    let rotDir: number = 1
    let rotSpeed: number = 1

    function setup() {
        cat = Grix.fromTexture(Assets.loadImg("/scripts/tutorials/cat.png"))

        Plena.getDefaultView().fixedResolutionH(1000)

        Keyboard.addPressedEvent(clockwise, Keyboard.KEY_RIGHT)
        Keyboard.addPressedEvent(counterClockwise, Keyboard.KEY_LEFT)
        Keyboard.addPressedEvent(increaseSpeed, Keyboard.KEY_UP)
        Keyboard.addPressedEvent(decreaseSpeed, Keyboard.KEY_DOWN)
    }

    function update(delta: number) {
        rotation += rotDir * rotSpeed * 0.001 * delta
    }

    function render(delta: number) {
        let view = Plena.getDefaultView()

        cat.setPivotMove(0.5, 0.5)
        cat.scaleWidthToSize((Keyboard.isDown(Keyboard.KEY_S))? 200:500)
        cat.scaleWidthToSize(500)
        cat.moveTo(view.getWidth() / 2, view.getHeight() / 2)
        cat.rotateTo(rotation)

        cat.render()
    }

    function clockwise(event: KeyboardEvent) {
        rotDir = 1
    }
    function counterClockwise(event: KeyboardEvent) {
        rotDir = -1
    }
    function increaseSpeed(event: KeyboardEvent) {
        rotSpeed += 100
    }
    function decreaseSpeed(event: KeyboardEvent) {
        if (rotSpeed > 0) rotSpeed -= 100
    }

    //Plena.init(setup, render, update, Color.Gray.GRAY_SLATE_LIGHT);
}

/*
 * ID : assets
 */

//some more assets example, this might be a tad hard to run for your pc, but it will
//probabely do just fine. In this example we will render 266664 verticies (or +3333300 if you go crazy).
//the below example can also be done much more efficient by not rnedering all those verticies
//sepperate, but bunderd as a texture, verticies can be reduced to about 160 (1666 times more efficient!).
//But it is fun to render them sepperate to test pcs :). Also becuase of doing this sepperate, it
//would be possible to animate every single vertici sepperate (so having them all do differnet things, rotating, moving or so)
//as well, which is not possible if they are bundered in a texture. Not that I did that for this example though.
//well, just forget this text and go through the example, you will see what I meant.
module MoreAssets {
    let text: ImgGrix
    let music: AudioObj
    let shape: ShapeGrix
    let crazy: ShapeGrix
    let view: Views.View

    let rotate = 0;
    let random = (Math.random() * 12387) //making sure the spiral has different colors every time

    function setup() {
        let calibri = Assets.getFont(Font.CALIBRI, 48) //the number defines resolution, not size per so, since we can scale
        //it is possible to add custom fonts, but I won't go into that, more a html/css thing. But once the font is added it can be used as follows:
        //let myFont = Assets.getFont("MY_COSTOME_FONT_NAME", 48)

        calibri.fill(Color.Gray.BLACK)//set the fill color of the font, can also use own colors with Color.mkColor, it also accepts alpha colors
        //another option for fonts is FONT.stroke(COLOR) which creates a colored outline.

        //creates an image of text
        let hello = Assets.mkTextImg("Flight of the Bumblebee!", calibri) //also possible to set things such as max width (so you get new lines) and background color

        text = Grix.fromTexture(hello)
        view = Plena.getDefaultView()

        //loads some music
        music = Assets.loadAudio("/scripts/tutorials/musics.mp3")
        //crate a grix from a shape you can arbitrarely define, you can add tris, quads
        //circles and polygons however much you want to one grix and draw them as a group
        shape = Grix.shape()
            .quad(15, 100)
            .quad(50, 15, 15, 40)
            .quad(15, 100, 65, 0)
            .quad(15, 70, 95, 0)
            .quad(15, 15, 95, 85)
            .setColor(Color.Gray.BLACK)
            .populate()

        //;)
        crazy = Grix.shape()
        for (var i = 0; i < 5000; i++) {
            if (i % 3 == 0) crazy.quad(5, 5, (i % 50) * 10, Math.floor(i / 50) * 10);
        }
        crazy.populate()

        Plena.getDefaultView().fixedResolutionH(1000)
    }

    function render(delta: number) {
        //render the intro during first 2 seconds of the music
        //during other part... I sugest you see what happens :)
        if (music.currentTime() > 2) {
            for (var i = 0; i < 20; i++) drawSpiral(i) //increase the 20 in there to
            //mkae stuff even more crazy, my pc could handle 250 before starting to lag
            //slightly (that are 3333300 verticies!!!). I have found 50 to give pretty
            //nice effects as well
        } else drawIntro()
    }

    function drawSpiral(offset: number) {
        MMath.setRandomSeed(offset * random)//making the next random based on the offset
        //is used to make the colors

        crazy.setColor(Color.mkAlphaColor(MMath.random(0, 255), MMath.random(0, 255), MMath.random(0, 255), Math.min(music.currentTime() - 2, 1)))
        crazy.setPivotMove(0.5, 0.5)
        crazy.moveTo(view.getWidth() / 2, view.getHeight() / 2)
        crazy.rotateDeg(rotate * Math.min(music.currentTime() / 10, 15))
        crazy.render();
    }

    function drawIntro() {
        text.setPivotMove(0.5, 0.5)
        text.moveTo(view.getWidth() / 2, view.getHeight() / 2)
        text.render()

        shape.moveTo(20, 20);
        shape.render();
        shape.setPivotMove(1, 0);
        shape.moveTo(view.getWidth() - 20, 20)
        shape.render()
        shape.setPivotMove(0, 1);
        shape.moveTo(20, view.getHeight() - 20);
        shape.render();
        shape.setPivotMove(1, 1);
        shape.moveTo(view.getWidth() - 20, view.getHeight() - 20)
        shape.render()
    }

    function update(delta: number) {
        //plays the music if it is not running
        if (!music.isRunning()) music.play()

        rotate += delta * 0.002
    }

    export function run() {
        Plena.init(setup, render, update)
    }
}

//clean version
module MoreAssetsClean {
    let text: ImgGrix
    let music: AudioObj
    let shape: ShapeGrix
    let crazy: ShapeGrix
    let view: Views.View

    let rotate = 0;
    let random = Math.random() * 12387

    function setup() {
        let calibri = Assets.getFont(Font.CALIBRI, 48).fill(Color.Gray.BLACK)

        view = Plena.getDefaultView()
        text = Grix.fromTexture(Assets.mkTextImg("Flight of the Bumblebee!", calibri))
        music = Assets.loadAudio("/scripts/tutorials/musics.mp3")
        shape = Grix.shape()
            .quad(15, 100)
            .quad(50, 15, 15, 40)
            .quad(15, 100, 65, 0)
            .quad(15, 70, 95, 0)
            .quad(15, 15, 95, 85)
            .setColor(Color.Gray.BLACK)
            .populate()

        crazy = Grix.shape()
        for (var i = 0; i < 5000; i++) {
            if (i % 3 == 0) crazy.quad(5, 5, (i % 50) * 10, Math.floor(i / 50) * 10);
        }
        crazy.populate()

        Plena.getDefaultView().fixedResolutionH(1000)
    }

    function render(delta: number) {
        if (music.currentTime() > 2) {
            for (var i = 0; i < 20; i++) drawSpiral(i)
        } else drawIntro()
    }

    function drawSpiral(offset:number) {
        MMath.setRandomSeed(offset * random)

        crazy.setColor(Color.mkAlphaColor(MMath.random(0, 255), MMath.random(0, 255), MMath.random(0, 255), Math.min(music.currentTime() - 2, 1)))
        crazy.setPivotMove(0.5, 0.5)
        crazy.moveTo(view.getWidth() / 2, view.getHeight() / 2)
        crazy.rotateDeg(rotate * Math.min(music.currentTime() / 10, 15))
        crazy.render();
    }

    function drawIntro() {
        text.setPivotMove(0.5, 0.5)
        text.moveTo(view.getWidth() / 2, view.getHeight() / 2)
        text.render()

        shape.moveTo(20, 20);
        shape.render();
        shape.setPivotMove(1, 0);
        shape.moveTo(view.getWidth() - 20, 20)
        shape.render()
        shape.setPivotMove(0, 1);
        shape.moveTo(20, view.getHeight() - 20);
        shape.render();
        shape.setPivotMove(1, 1);
        shape.moveTo(view.getWidth() - 20, view.getHeight() - 20)
        shape.render()
    }

    function update(delta: number) {
        if (!music.isRunning()) music.play()

        rotate += delta * 0.002
    }

    //Plena.init(setup, render, update)
}

/*
 * ID : sprite
 */

module Sprites {
    let cat: SpriteGrix
    let view: Views.View

    //map of ids we use for animation, will become clear
    let cats = ["catBlack", "catBlue", "catWhite", "catOrange"]
    let dir = ["_back", "_left", "_right", "_top"]

    //variables we use to render, will become clear
    let currCat = 0;
    let animation = 0;
    let direction = 1;

    //the position of the cat, just something random. I could also have made this the middle.
    //In that case I would have set them in setup
    let x = 500
    let y = 500

    //the width and height of the cat, I just picked something arbetrary
    let catWidth = 100
    let catHeight = 100

    //this maps the direction the cat moves to how we loaded it in the sprite
    let dirMap = [2, 0, 1, 3]

    function setup() {
        //loading the sprite with assets module
        let catSprite = Assets.loadSprite("/scripts/tutorials/cats.png", { safe: true })
        //with any asset we load we can set options on how to render it, we did not see
        //this before. If no options are specified, teh default options are used.
        //safe basically means that this will be an animation and we want to cut a bit from
        //the edge of the texture (0.0001% or so) to avoid texture artifacts (random
        //texture pieces). Don't worry about other options, de defaults will suffice

        //setting up all the images in the sprite (please look at the function setupCats now, before continuing)
        setupCats(catSprite)

        //creating a grix from the sprite
        cat = Grix.fromSprite(catSprite)
        view = Plena.getDefaultView()

        //we wanna make the cat walk, and change color. To do so we bind some keys, this you have seen before. (note that you can indefenetly add more keys to
        //the function if you want to bind the function to more keys, also no keys means any key).
        Keyboard.addPressedEvent(top, Keyboard.KEY_W, Keyboard.KEY_UP)
        Keyboard.addPressedEvent(left, Keyboard.KEY_A, Keyboard.KEY_LEFT)
        Keyboard.addPressedEvent(right, Keyboard.KEY_D, Keyboard.KEY_RIGHT)
        Keyboard.addPressedEvent(back, Keyboard.KEY_S, Keyboard.KEY_DOWN)
        Keyboard.addPressedEvent(swich, Keyboard.KEY_SPACE)

        Plena.getDefaultView().fixedResolutionH(1000)
    }

    function setupCats(catSprite: Sprite) {
        //ok, this might seem complicated, but it is not. Just read/look carefully. Make sure to have cats.png open so you can actually see the image
        //so what is a sprite? A sprite contains multiple subimages. Sprites can be used to bundle textures together, to to create animations. We will
        //use the catSprite for both purposes all with one sprite grix.

        //In a Sprite (the object which we cretaed with Assets.loadSprite) we can define two sub Image types. Simple images, and animations. In the sprite we loaded
        //are five differnet colored cats (we will use the bottom four), all four have images to animate the movement in any direction. Look at the image!

        //So, what do we want to get from this image? We want 4 animations, one for every direction for every cat (the bottom ones). And we want one image for
        //every cat (just to show how to do images).
        for (let color = 0; color < 4; color++) {
            //first we add the cat image. The method is id, x, y, width, height. Everything is in pixels. So for the first cat (color = 0 [black one]).
            //we get an image on x=0, y=6*32, with width 32 * 32 (every cat image is 32 * 32), if you look at the image you see this is the right looking black
            //cat. For other colors this image gets shifted color * 3 * 32 to the right the get the right looking cat of other colors
            catSprite.addImg(cats[color], color * 3 * 32, 6 * 32, 32, 32)
                //if you are confsed by the . and not the catSprite. We can do this because addImage returns the sprite itself and typescript does not care about
                //new lines. But feel free to put catSprite in you mind before it.
                //the method for addAnimImages is id, x, y, with, height, count (and an optional parameter to say whether it goes vertical or horizontal (default))
                //so with these four lines we add all the animations for a cat, every line is for a differnet direction.
                .addAnimImgs(cats[color] + dir[0], color * 3 * 32, 4 * 32, 32, 32, 3)
                .addAnimImgs(cats[color] + dir[1], color * 3 * 32, 5 * 32, 32, 32, 3)
                .addAnimImgs(cats[color] + dir[2], color * 3 * 32, 6 * 32, 32, 32, 3)
                .addAnimImgs(cats[color] + dir[3], color * 3 * 32, 7 * 32, 32, 32, 3)

            //finally, we specified an id for every one so we can later get them back. A grix will need that id to know what to render as you will see below.
        }
    }

    function render(delta: number) {
        //drawing the four cat images
        for (var i = 0; i < 4; i++) {
            cat.moveTo(cat.getWidth() * i, 0); //here is a more dynamic way of getting the current width and height of an grix
            //this is now 32*32, the default size (pixel size), later we scale it to the arbetrarely defined size, so now we cannot use those.
            cat.activeImg(cats[i]) //we use the id of the image we used during loading to tell the grix what we want to draw.
            cat.render();
        }

        //we clean our transformations
        cat.clean();
        cat.setPivotMove(0, 0)
        cat.scaleToSize(catWidth, catHeight) //now the cat has the size we picked
        cat.moveTo(x, y)//rendering the cat at its position
        cat.activeAnime(cats[currCat] + dir[dirMap[direction]]) //we now put in the id we used during loading of the spirte for the animations.
        cat.animeStep(Math.floor(animation))//we are setting how far we are in the animation 0 = first image, 1 = second image, 2 = thrid image....
        cat.render();
    }

    function update(delta: number) {
        animation += delta * 0.005;

        //move the cat
        x += 0.2 * delta * Math.cos((Math.PI / 2) * direction);
        y += 0.2 * delta * Math.sin((Math.PI / 2) * direction);

        //if cat moves out of the screen, move it to the other side
        if (x > view.getWidth()) x = -catWidth
        else if (x < -catWidth) x = view.getWidth();
        if (y > view.getHeight()) y = -catHeight
        else if (y < -catHeight) y = view.getHeight();
    }

    function top() { direction = 3 }
    function left() { direction = 2 }
    function right() { direction = 0 }
    function back() { direction = 1 }
    function swich() { currCat = (currCat + 1) % 4 }

    export function run() {
        Plena.init(setup, render, update, Color.Gray.GRAY_SLATE_LIGHT)
    }

    //maybe a fun challenge? Try to make the cat smaller if it is closer to the top of the screen
    //so it look as if it moves away from us. Or maybe bigger in the center smaller to the sides,
    //to get the effect of an hill? (just a ranom thought, might be cool)
}

//clean version
module SpritesClean {
    let cat: SpriteGrix
    let view: Views.View

    let cats = ["catBlack", "catBlue", "catWhite", "catOrange"]
    let dir = ["_back", "_left", "_right", "_top"]

    let currCat = 0;
    let animation = 0;
    let direction = 1;

    let x = 500
    let y = 500

    let catWidth = 100
    let catHeight = 100

    let dirMap = [2, 0, 1, 3]

    function setup() {
        let catSprite = Assets.loadSprite("/scripts/tutorials/cats.png", { safe: true })

        setupCats(catSprite)

        cat = Grix.fromSprite(catSprite)
        view = Plena.getDefaultView()

        Keyboard.addPressedEvent(top, Keyboard.KEY_W, Keyboard.KEY_UP)
        Keyboard.addPressedEvent(left, Keyboard.KEY_A, Keyboard.KEY_LEFT)
        Keyboard.addPressedEvent(right, Keyboard.KEY_D, Keyboard.KEY_RIGHT)
        Keyboard.addPressedEvent(back, Keyboard.KEY_S, Keyboard.KEY_DOWN)
        Keyboard.addPressedEvent(swich, Keyboard.KEY_SPACE)

        Plena.getDefaultView().fixedResolutionH(1000)
    }

    function setupCats(catSprite: Sprite) {
        for (let color = 0; color < 4; color++) {
            catSprite.addImg(cats[color], color * 3 * 32, 6 * 32, 32, 32)
                .addAnimImgs(cats[color] + dir[0], color * 3 * 32, 4 * 32, 32, 32, 3)
                .addAnimImgs(cats[color] + dir[1], color * 3 * 32, 5 * 32, 32, 32, 3)
                .addAnimImgs(cats[color] + dir[2], color * 3 * 32, 6 * 32, 32, 32, 3)
                .addAnimImgs(cats[color] + dir[3], color * 3 * 32, 7 * 32, 32, 32, 3)
        }
    }

    function render(delta: number) {
        for (var i = 0; i < 4; i++) {
            cat.moveTo(cat.getWidth() * i, 0);
            cat.activeImg(cats[i])
            cat.render();
        }

        cat.clean();
        cat.setPivotMove(0, 0)
        cat.scaleToSize(catWidth, catHeight)
        cat.moveTo(x, y)
        cat.activeAnime(cats[currCat] + dir[dirMap[direction]])
        cat.animeStep(Math.floor(animation))
        cat.render();
    }

    function update(delta: number) {
        animation += delta * 0.005;

        x += 0.2 * delta * Math.cos((Math.PI / 2) * direction);
        y += 0.2 * delta * Math.sin((Math.PI / 2) * direction);

        if (x > view.getWidth()) x = -catWidth
        else if (x < -catWidth) x = view.getWidth();
        if (y > view.getHeight()) y = -catHeight
        else if (y < -catHeight) y = view.getHeight();
    }

    function top() { direction = 3 }
    function left() { direction = 2 }
    function right() { direction = 0 }
    function back() { direction = 1 }
    function swich() { currCat = (currCat + 1) % 4 }

    //Plena.init(setup, render, update, Color.Gray.GRAY_SLATE_LIGHT)
}

/*
some possible future examples (but I will probabely leave it at this)
although there is much more

maybe writable textures
maybe mutable text and fontmaps
maybe canvas textures
maybe custom shads, more input and views stuff
maybe advanced grix use with new GRIX_TYPEGrix(OPTIONS).FUNCTIONS.populate() instead of Grix.GRIX_TYPE(OPTIONS)
 */

//this last part is nothing for you to worry about, this will run the examples.
//but you can add your own to this if you feel like experimenting, I configured the webserver so that it will just work run the script with id: localhost:3000/examples/ID <- so that ID on a
//simple webpage
function runExample(example: string) {
    switch (example) {
        case "setup": DefaultPlanaSetup.run(); break
        case "texture": SimpleTextureDrawing.run(); break
        case "trans": GrixTransformations.run(); break
        case "persp": PerspectiveAndInput.run(); break
        case "assets": MoreAssets.run(); break
        case "sprite": Sprites.run(); break
    }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using PKStudio.ItemWrappers;
using System.Collections.ObjectModel;
using XsdInventoryFormatObject;

namespace PKStudio.TreeNodes
{
    class MFProjectTreeNode : MFTreeNodeBase
    {
        public MFProjectTreeNode()
        {
        }

        public ProjectWrapper Project { get; private set; }

        public MFProjectTreeNode(ProjectWrapper project)
            : base(project.Name, ImageKeysEnum.Project)
        {
            this.Project = project;
            this.Tag = project;

            #region Features

            MFTreeNodeBase FeaturesNode = new MFComponentsTreeNode("Features");//this.NewNode("Features", MFTreeNodeBase.TreeNodeType.Components, null, MFTreeNodeBase.ImageKeysEnum.Components);
            this.Nodes.Add(FeaturesNode);

            foreach (ComponentWrapper feat in this.Project.Features)
            {
                //FeatureWrapper f = PK.Wrapper.FindFeature(feat.Guid);
                MFTreeNodeBase FeatNode = new MFFeatureTreeNode(PK.Wrapper.FindFeature(feat.Guid));//this.NewNode(f.Name, MFTreeNodeBase.TreeNodeType.Feature, f, MFTreeNodeBase.ImageKeysEnum.Feature);
                FeaturesNode.Nodes.Add(FeatNode);
            }

            #endregion

            #region Library Categories

            MFTreeNodeBase LibraryCategoriesNode = new MFComponentsTreeNode("Library Categories");//this.NewNode("Library Categories", MFTreeNodeBase.TreeNodeType.Components, null, MFTreeNodeBase.ImageKeysEnum.Components);
            this.Nodes.Add(LibraryCategoriesNode);

            foreach (ComponentWrapper LibCat in this.Project.LibraryCategories)
            {
                MFTreeNodeBase LibCatNode = new MFLibCatTreeNode(PK.Wrapper.FindLibraryCategory(LibCat.Guid));//this.NewNode(lc.Name, MFTreeNodeBase.TreeNodeType.LibCat, lc, MFTreeNodeBase.ImageKeysEnum.LibraryCategory);
                LibraryCategoriesNode.Nodes.Add(LibCatNode);
            }

            #endregion

            #region Libraries
            MFTreeNodeBase LibraryesNode = new MFComponentsTreeNode("Libraries");//this.NewNode("Libraries", MFTreeNodeBase.TreeNodeType.Components, null, MFTreeNodeBase.ImageKeysEnum.Components);
            this.Nodes.Add(LibraryesNode);

            //Groups Libraries Dictionary
            SortedDictionary<string, TreeNode> LibGroupsDict = new SortedDictionary<string, TreeNode>();
            SortedList<string, TreeNode> LibVoidGroupsList = new SortedList<string, TreeNode>();

            foreach (ComponentWrapper l in this.Project.Libraries)
            {
                LibraryWrapper lib = PK.Wrapper.FindLibrary(l);

                if (lib != null)
                {
                    //MFTreeNodeBase LibNode = new MFLibraryTreeNode(lib, ref LibGroupsDict, ref LibVoidGroupsList);//this.NewNode(lib.Name, MFTreeNodeBase.TreeNodeType.Lib, lib, MFTreeNodeBase.ImageKeysEnum.Library);

                }
            }

            foreach (TreeNode tn in LibVoidGroupsList.Values)
            {
                LibraryesNode.Nodes.Add(tn);
            }

            foreach (TreeNode tn in LibGroupsDict.Values)
            {
                LibraryesNode.Nodes.Add(tn);
            }

            List<BuildFileWrapper> source_files = new List<BuildFileWrapper>(Project.SourceFiles);
            source_files.AddRange(Project.HeaderFiles);
            source_files.AddRange(Project.OtherFiles);
            source_files.Add(Project.ScatterFile);

            AddFileList(new CollectionWrapper<BuildFileWrapper, MFBuildFile>(source_files), this.Project.ProjectPath);

            #endregion
        }
    }
}


text:
* 实现了UICollectionViewDelegateFlowLayout协议方法.使用形式和系统Flowlayout相同.
* 支持多个section, 不同section标签流布局和固定有规则布局混合

<img src="https://github.com/ONECATYU/WSCollectionViewFlowLayout/blob/master/Demo.gif" width="200">

#### 使用
* 您可以通过实现UICollectionViewDelegateFlowLayout协议方法,来设置cell/header/footer.
* 也可以通过下面这种方式来设置
```objective-c
    WSCollectionViewFlowLayout *layout = [[WSCollectionViewFlowLayout alloc]init];
    layout.contentInset = UIEdgeInsetsMake(20, 8, 20, 8);
    layout.minimumLineSpacing = 8;
    layout.minimumInteritemSpacing = 8;
    layout.sectionInset = UIEdgeInsetsMake(8, 8, 8, 8);
    layout.itemSize = CGSizeMake(100, 100);
    layout.headerReferenceSize = CGSizeMake(CGRectGetWidth(self.view.frame) - 16, 40);
    layout.footerReferenceSize = CGSizeMake(CGRectGetWidth(self.view.frame) - 16, 40);

    UICollectionView *collectionView = [[UICollectionView alloc]initWithFrame:self.view.bounds collectionViewLayout:layout];
    collectionView.delegate = self;
    collectionView.dataSource = self;
    collectionView.backgroundColor = [UIColor whiteColor];
    [self.view addSubview:collectionView];
```


text:
#import "SoapActionsSwitchPower1.h"

#import "OrderedDictionary.h"

@implementation SoapActionsSwitchPower1

-(int)SetTargetWithnewTargetValue:(NSString*)newtargetvalue{
    int ret = 0;

    NSDictionary *parameters = nil;
    NSDictionary *output = nil;
    NSArray *parameterKeys = nil;
    NSArray *parameterObjects = nil;
    parameterKeys = @[@"newTargetValue"];
    parameterObjects = @[newtargetvalue];
    parameters = [OrderedDictionary dictionaryWithObjects:parameterObjects forKeys:parameterKeys];

    ret = [self action:@"SetTarget" parameters:parameters returnValues:output];
    return ret;
}

-(int)GetTargetWithOutRetTargetValue:(NSMutableString*)rettargetvalue{
    int ret = 0;

    NSDictionary *parameters = nil;
    NSDictionary *output = nil;
    NSArray *outputObjects = nil;
    NSArray *outputKeys = nil;
    outputKeys = @[@"RetTargetValue"];
    outputObjects = @[rettargetvalue];
    output = [NSDictionary dictionaryWithObjects:outputObjects forKeys:outputKeys];

    ret = [self action:@"GetTarget" parameters:parameters returnValues:output];
    return ret;
}

-(int)GetStatusWithOutResultStatus:(NSMutableString*)resultstatus{
    int ret = 0;

    NSDictionary *parameters = nil;
    NSDictionary *output = nil;
    NSArray *outputObjects = nil;
    NSArray *outputKeys = nil;
    outputKeys = @[@"ResultStatus"];
    outputObjects = @[resultstatus];
    output = [NSDictionary dictionaryWithObjects:outputObjects forKeys:outputKeys];

    ret = [self action:@"GetStatus" parameters:parameters returnValues:output];
    return ret;
}

@end


text:
SpreeCategoryAnalysis
=====================

Category analysis


text:
module.exports = {
  rawIssueTemplate: "[{{repository.name}}] {{sender.login}} {{action}} issue #{{issue.number}}: {{issue.title}}"
}


text:
package org.kie.server.remote.rest.common.util;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Variant;

import org.kie.server.api.ConversationId;
import org.kie.server.api.KieServerConstants;
import org.kie.server.api.KieServerEnvironment;
import org.kie.server.api.marshalling.MarshallingFormat;
import org.kie.server.api.model.KieContainerStatus;
import org.kie.server.api.model.ReleaseId;
import org.kie.server.api.model.instance.Aggregatable;
import org.kie.server.common.rest.RestEasy960Util;
import org.kie.server.remote.rest.common.Header;
import org.kie.server.services.api.KieServerRegistry;
import org.kie.server.services.impl.KieContainerInstanceImpl;
import org.kie.server.services.impl.marshal.MarshallerHelper;

public class RestUtils {

    private static MarshallerHelper marshallerHelper = new MarshallerHelper(null);
    private static Variant ERROR_VARIANT = new Variant(MediaType.TEXT_PLAIN_TYPE, (Locale) null, null);
    private static final String UNEXPECTED_ERROR = "Unexpected error during processing: {0}";
    private static final boolean INCLUDE_STACKTRACE = Boolean.parseBoolean(System.getProperty(KieServerConstants.KIE_SERVER_INCLUDE_STACKTRACE, "false"));

    public static Response createCorrectVariant(Object responseObj, HttpHeaders headers, Header... customHeaders) {
        return createCorrectVariant(responseObj, headers, null, customHeaders);
    }

    public static Response createCorrectVariant(Object responseObj, HttpHeaders headers, javax.ws.rs.core.Response.Status status, Header... customHeaders) {
        Response.ResponseBuilder responseBuilder = null;
        Variant v = getVariant(headers, responseObj);
        String contentType = getContentType(headers);

        if( status != null ) {
            responseBuilder = Response.status(status).entity(marshallerHelper.marshal(contentType, responseObj)).variant(v);
        } else {
            responseBuilder = Response.ok(marshallerHelper.marshal(contentType, responseObj), v);
        }
        applyCustomHeaders(responseBuilder, customHeaders);
        return responseBuilder.build();
    }

    public static Response createCorrectVariant(MarshallerHelper marshallerHelper, String containerId, Object responseObj, HttpHeaders headers, javax.ws.rs.core.Response.Status status, Header... customHeaders) {
        Response.ResponseBuilder responseBuilder = null;
        Variant v = getVariant(headers, responseObj);
        String contentType = getContentType(headers);

        String marshalledResponse;
        if (marshallerHelper.getRegistry().getContainer(containerId) == null) {
            marshalledResponse = marshallerHelper.marshal(contentType, responseObj);
        } else {
            marshalledResponse = marshallerHelper.marshal(containerId, contentType, responseObj);
        }
        if( status != null ) {
            responseBuilder = Response.status(status).entity(marshalledResponse).variant(v);
        } else {
            responseBuilder = Response.ok(marshalledResponse, v);
        }
        applyCustomHeaders(responseBuilder, customHeaders);
        return responseBuilder.build();
    }

    public static Response createResponse(Object responseObj, Variant v, javax.ws.rs.core.Response.Status status, Header... customHeaders) {
        Response.ResponseBuilder responseBuilder = null;
        if( status != null ) {
            responseBuilder = Response.status(status).entity(responseObj).variant(v);
        } else {
            responseBuilder = Response.ok(responseObj, v);
        }
        applyCustomHeaders(responseBuilder, customHeaders);
        return responseBuilder.build();
    }

    public static Variant getVariant(HttpHeaders headers) {
        return getVariant(headers, null);
    }

    public static Variant getVariant(HttpHeaders headers, Object obj) {
        Variant v = RestEasy960Util.getVariant(headers);
        if( v == null ) {
            v = Variant.mediaTypes(getMediaType(headers)).add().build().get(0);
        }

        if (!(shouldAggregate(obj))) {
            MediaType oldMediaType = v.getMediaType();
            MediaType aggregatableMediaType = new MediaType(oldMediaType.getType(), oldMediaType.getSubtype(),
                                                            Collections.singletonMap("aggregatable", "false"));
            v = Variant.mediaTypes(aggregatableMediaType).add().build().get(0);

        }
        return v;
    }

    private static boolean shouldAggregate(Object obj) {
        // by default true
        if (obj == null) {
            return true;
        }

        Aggregatable aggregatable = obj.getClass().getAnnotation(Aggregatable.class);
        if (aggregatable == null) {
            return true;
        }
        return aggregatable.value();
    }

    public static String getClassType(HttpHeaders headers) {
        String classType = null;

        List<String> header = headers.getRequestHeader(KieServerConstants.CLASS_TYPE_HEADER);
        if (header != null && !header.isEmpty()) {
            classType = header.get(0);
        }

        return classType;
    }

    public static String getContentType(HttpHeaders headers) {
        // default to application/xml
        String contentType = MediaType.APPLICATION_XML_TYPE.toString();
        // check variant that is based on accept header important in case of GET as then Content-Type might not be given
        Variant v = RestEasy960Util.getVariant(headers);
        if (v != null) {
            // set the default to selected variant
            contentType = v.getMediaType().toString();
        }
        // now look for actual Content-Type header
        List<String> contentTypeHeader = headers.getRequestHeader(HttpHeaders.CONTENT_TYPE);
        if (contentTypeHeader != null && !contentTypeHeader.isEmpty() && contentTypeHeader.get(0) != null) {
            contentType = contentTypeHeader.get(0);
        }
        List<String> kieContentTypeHeader = headers.getRequestHeader(KieServerConstants.KIE_CONTENT_TYPE_HEADER);
        if (kieContentTypeHeader != null && !kieContentTypeHeader.isEmpty()) {
            contentType = kieContentTypeHeader.get(0);
        }

        return contentType;
    }

    public static MediaType getMediaType(HttpHeaders httpHeaders) {
        String contentType = getContentType(httpHeaders);
        try {
            return MediaType.valueOf(contentType);
        } catch (IllegalArgumentException e) {
            MarshallingFormat format = MarshallingFormat.fromType(contentType);
            switch (format) {
                case JAXB:
                    return MediaType.APPLICATION_XML_TYPE;

                case XSTREAM:
                    return MediaType.APPLICATION_XML_TYPE;

                case JSON:
                    return MediaType.APPLICATION_JSON_TYPE;

                default:
                    return MediaType.APPLICATION_XML_TYPE;
            }
        }
    }

    public static Response permissionDenied(String message, Variant v, Header... customHeaders) {
        return createResponse(message, v, Response.Status.UNAUTHORIZED, customHeaders);
    }

    public static Response notFound(String message, Variant v, Header... customHeaders) {
        return createResponse("\"" +message + "\"", ERROR_VARIANT, Response.Status.NOT_FOUND, customHeaders);
    }

    public static Response internalServerError(String message, Variant v, Header... customHeaders) {
        return createResponse("\"" +message + "\"", ERROR_VARIANT, Response.Status.INTERNAL_SERVER_ERROR, customHeaders);
    }

    public static Response alreadyExists(String message, Variant v, Header... customHeaders) {
        return createResponse("\"" +message + "\"", ERROR_VARIANT, Response.Status.CONFLICT, customHeaders);
    }

    public static Response badRequest(String reason, Variant v, Header... customHeaders) {
        return createResponse("\"" +reason + "\"", ERROR_VARIANT, Response.Status.BAD_REQUEST, customHeaders);
    }

    public static Response forbidden(String reason, Variant v, Header... customHeaders) {
        return createResponse("\"" +reason + "\"", ERROR_VARIANT, Response.Status.FORBIDDEN, customHeaders);
    }

    public static Response noContent(Variant v, Header... customHeaders) {
        return createResponse("", v, Response.Status.NO_CONTENT, customHeaders);
    }

    public static Response serviceUnavailable(Header... customHeaders) {
        return createResponse("", ERROR_VARIANT, Response.Status.SERVICE_UNAVAILABLE, customHeaders);
    }

    protected static void applyCustomHeaders(Response.ResponseBuilder builder, Header... customHeaders) {
        if (customHeaders != null && customHeaders.length > 0) {
            for (Header header : customHeaders) {
                if (header != null) {
                    builder.header(header.getName(), header.getValue());
                }
            }
        }
    }

    public static Header buildConversationIdHeader(String containerId, KieServerRegistry registry, HttpHeaders headers) {
        List<String> conversationIdHeader = headers.getRequestHeader(KieServerConstants.KIE_CONVERSATION_ID_TYPE_HEADER);
        if (conversationIdHeader != null && !conversationIdHeader.isEmpty()) {
            return new Header(KieServerConstants.KIE_CONVERSATION_ID_TYPE_HEADER, conversationIdHeader.get(0));
        }

        KieContainerInstanceImpl container = registry.getContainer(containerId);
        if (container != null && KieContainerStatus.STARTED.equals(container.getStatus())) {
            ReleaseId releaseId = container.getResource().getResolvedReleaseId();
            if (releaseId == null) {
                releaseId = container.getResource().getReleaseId();
            }

            String conversationId = ConversationId.from(KieServerEnvironment.getServerId(), containerId, releaseId).toString();

            return new Header(KieServerConstants.KIE_CONVERSATION_ID_TYPE_HEADER, conversationId);
        }

        return null;
    }

    public static String errorMessage(Throwable e, String defaultMessage) {
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);

        pw.println(defaultMessage);

        if (INCLUDE_STACKTRACE) {
            e.printStackTrace(pw);
        }

        pw.close();
        return sw.toString();
    }

    public static String errorMessage(Throwable e) {
        return errorMessage(e, MessageFormat.format(UNEXPECTED_ERROR, e.getMessage()));
    }
}


text:
  Fill in one* of the following:

    <input type="file" name="file" label="CSV File to process" (change)="onFileChanged($event)"/>

    <button mat-button class="custom indigo main-form-search" (click)="search()">
      Submit
    </button>

    <button mat-button color="primary" [disabled]="downloadDisabled" (click)="Download()">Download</button>

        {{header}}

        {{person[header]}}


text:
import faker from 'faker'
import React from 'react'

import * as common from 'test/specs/commonTests'
import FeedLike from 'src/views/Feed/FeedLike'

describe('FeedLike', () => {
  common.isConformant(FeedLike)
  common.implementsIconProp(FeedLike)
  common.rendersChildren(FeedLike)

  it('renders text with like prop', () => {
    const text = faker.hacker.phrase()

    shallow(<FeedLike like={text} />).should.contain.text(text)
  })
})