text:
function sucuriscan_alert_close(id){
    var element = document.getElementById('sucuriscan-alert-'+id);
    element.parentNode.removeChild(element);
}

jQuery(document).ready(function($){
    $('.sucuriscan-modal-btn').on('click', function(ev){
        ev.preventDefault();
        var modalid = $(this).data('modalid');
        $('div.' + modalid).removeClass('sucuriscan-hidden');
    });

    $('.sucuriscan-overlay, .sucuriscan-modal-close').on('click', function(ev){
        ev.preventDefault();
        $('.sucuriscan-overlay').addClass('sucuriscan-hidden');
        $('.sucuriscan-modal').addClass('sucuriscan-hidden');
    });

    if( $('.sucuriscan-tabs').length ){
        var hidden_class = 'sucuriscan-hidden';
        var active_class = 'sucuriscan-tab-active';
        var anchor = location.href.split('#')[1];

        $('.sucuriscan-tabs > ul a').on('click', function(e){
            e.preventDefault();

            var button = $(this);
            var container_id = button.data('tabname');
            var container = $('.sucuriscan-tab-containers > #sucuriscan-'+container_id);

            if( container.length ){
                var current_href = location.href.replace(location.hash, '');
                var new_location_href = current_href + '#' + container_id;
                window.history.pushState( {}, document.title, new_location_href );

                $('.sucuriscan-tabs > ul a').removeClass(active_class);
                $('.sucuriscan-tab-containers > div').addClass(hidden_class);
                button.addClass(active_class);
                container.removeClass(hidden_class)
            }
        });

        $('.sucuriscan-tab-containers > div').addClass(hidden_class);

        if( anchor != undefined ){
            $('.sucuriscan-tabs > ul li a').each(function(i, el){
                if( $(el).data('tabname') == anchor ){
                    $(el).trigger('click');
                }
            });
        } else {
            $('.sucuriscan-tabs > ul li:first-child a').trigger('click');
        }
    }

    $('#sucuriscan-corefiles-show').on('click', function(e){
        e.preventDefault();

        var this_button = $(this);
        var action = this_button.data('action');

        if( action == 'show' ){
            $('.sucuriscan-corefiles thead tr:last-child, .sucuriscan-corefiles tbody > tr').removeClass('sucuriscan-hidden');
            this_button.html('Hide files').data('action', 'hide');
        } else {
            $('.sucuriscan-corefiles thead tr:last-child, .sucuriscan-corefiles tbody > tr').addClass('sucuriscan-hidden');
            this_button.html('Show files').data('action', 'show');
        }
    });

    $('#sucuriscan_last_days').on('change', function(){
        $(this).closest('form').submit();
    });
});


text:
layout: post
title:  "Share Files with Others on ownCloud"
date:   2015-12-10 13:46:32
readtime: 3
category: How-to
tags:
- ownCloud
author: Frank Jumawan
materials: ownCloud account, ownCloud Client 2.0, A file or folder to share in ownCloud
blurb: "How to share your files to COE members through ownCloud."
published: true
---

1. Begin by clicking on the ownCloud icon and selecting **Open ownCloud in browser**.

    ![]({{ site.pathname }}/img/2015-12-10-share-files-with-others-on-owncloud/image03.png)

2. Locate the file you want to share, then hover your mouse over the file and click on **Share**.

    ![]({{ site.pathname }}/img/2015-12-10-share-files-with-others-on-owncloud/image02.png)

3. Enter the name of the COE member or COE group you would like to share the file with. The name of the person or group should populate as you type.

    ![]({{ site.pathname }}/img/2015-12-10-share-files-with-others-on-owncloud/image04.png)

4. Choose the sharing access level (can share, can edit) by checking the appropriate sharing boxes.

    ![]({{ site.pathname }}/img/2015-12-10-share-files-with-others-on-owncloud/image00.png)

    Tip: When sharing a folder, you can allow shared users to add and delete files or folders within the shared folder by checking the 'can edit' box.

5. To verify that you have shared your file, click on **Shared with others** tab.

    ![]({{ site.pathname }}/img/2015-12-10-share-files-with-others-on-owncloud/image05.png)

6. You can also share folders to others the same way you share a file.

    ![]({{ site.pathname }}/img/2015-12-10-share-files-with-others-on-owncloud/image01.png)

    Tip: It is recommended that you uncheck the delete box to prevent anyone from accidentally deleting your shared folder. Click on the black triangle to expand and view the delete box.

redpajama_set_name: RedPajamaGithub


text:
package models;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Shape;

public abstract class Board {

	private int numRows;
	private int numColumns;
	private Pane myBoardPane;
	protected Patch[][] myPatches;
	protected Map<int[], Patch> myMapGraph;
	private static final int WINDOW_SIZE = 400;
	protected Map<Integer, Color> stateToColorMap;
	protected int cellDim;
	private int numStates;
	private Map<Integer, ArrayList<Patch>> myStateMap;
//	protected int[] myXDelta = { 1, 1, 0, -1, -1, 0 };
//	protected int[] myYDelta = { 0, -1, -1, 0, 1, 1 };
	 protected int[] myXDelta = { -1, 0, 1, -1, 1, -1, 0, 1 }; //8
	 protected int[] myYDelta = { -1, -1, -1, 0, 0, 1, 1, 1 }; //8
//	 protected int[] myXDelta = { 0, 0, 1, -1 }; //4
//	 protected int[] myYDelta = { 1, -1, 0, 0 }; //4
//	 protected int[] myXDelta = { 1, 1, 0, -1, -1, 0 }; //6
//	 protected int[] myYDelta = { 0, -1, -1, 0, 1, 1 }; //6

	public Board (int row, int column, Pane boardPane, int states) {
		numRows = row;
		numColumns = column;
		myBoardPane = boardPane;
		myPatches = new Patch[row][column];
		myMapGraph = new HashMap<int[], Patch>();
		numStates = states;
		cellDim = WINDOW_SIZE / Math.max(row, column);
	}

	public void addPatch (Patch patch) {
		myPatches[patch.getRow()][patch.getColumn()] = patch;
		int[] coordinates = new int[2];
		coordinates[0]= (patch.getRow());
		coordinates[1] = (patch.getColumn());
		myMapGraph.put(coordinates, patch);
	}

	public void updatePatchViews() {
		for(int[] coordinate : myMapGraph.keySet()) {
			putShapedPatch(myMapGraph.get(coordinate));
		}
	}

	public void putShapedPatch (Patch patch) {
		if(patch.getCell()!=null) {
			Cell cell = patch.getCell();
			patch.updateFill(stateToColorMap.get(cell.getState()));
		}
		else {
			patch.updateFill(stateToColorMap.get(0));
		}
		myBoardPane.getChildren().add(patch.getShape());
	}

	public Map<int[], Patch> getPatches () {
		return myMapGraph;
	}

	public void generateMyStateMap () {
		myStateMap = genericStateMap(numStates);
		for (int[] coordinate : myMapGraph.keySet()) {
			Patch patch = myMapGraph.get(coordinate);
			if(patch.getCell() != null) {
				myStateMap.get(patch.getCell().getState()).add(patch);
			}
			else {
				myStateMap.get(0).add(patch);
			}
		}
	}

	public int getNumStates () {
		return numStates;
	}

	public Map<Integer, ArrayList<Patch>> getStateMap () {
		return myStateMap;
	}

	public HashMap<Integer, ArrayList<Patch>> genericStateMap (int n) {

		HashMap<Integer, ArrayList<Patch>> toReturn = new HashMap<>();
		for (int i = 0; i < n; i++) {
			toReturn.put(i, new ArrayList<Patch>());
		}
		return toReturn;
	}

	public void createNeighborhoods() {
		for(Patch[] row : myPatches) {
			for(Patch patch : row) {
				saveNeighbors(patch, myXDelta, myYDelta);
			}
		}
	}

	public void setXDeltaYDelta(int[] xDelta, int[] yDelta) {
		myXDelta = xDelta;
		myYDelta = yDelta;
	}

	public void saveNeighbors (Patch patch, int[] xDelta, int[] yDelta) {

		List<Patch> neighborPatches = new ArrayList<Patch>();
		for (int i = 0; i < xDelta.length; i++) {
			if (!isOutOfBounds(patch, xDelta[i], yDelta[i])) {
				Patch neighborPatch =
						myPatches[patch.getRow() + xDelta[i]][patch.getColumn() + yDelta[i]];
				neighborPatches.add(neighborPatch);
			}
		}
		patch.setNeighborPatches(neighborPatches);
	}

	private boolean isOutOfBounds (Patch patch, int xDelta, int yDelta) {

		return (patch.getRow() + xDelta < 0 || patch.getRow() + xDelta > myPatches.length - 1)
				||
				(patch.getColumn() + yDelta < 0 || patch.getColumn() + yDelta > myPatches[0].length - 1);
	}

	public int getNumRows () {
		return numRows;
	}

	public int getColumns () {
		return numColumns;
	}

	public void setColorMap (Map<Integer, Color> colorMap) {
		stateToColorMap = colorMap;
	}

}


text:
<input class="form-control" type="text" data-bind="css: classes('analysis-name', 'analysis-name-input'), textInput: $component.analysis.description, attr: {disabled: !isEditPermitted()}" />

                        <input placeholder="YYYY-MM-DD" class="form-control dateField" data-bind="datepicker: $component.studyStartDate, datepickerOptions: { defaultDate: new Date(), dateFormat: 'yy-mm-dd' }">

                    <label data-bind="html: ko.i18n('ple.spec.studyPopulationPanel.endDate', 'Study end date - a calendar date specifying the maximum date that a cohort index can appear (leave blank to use all time). Important: the study end date is also used to truncate risk windows, meaning no outcomes beyond the study end date will be considered.')">

                        <input placeholder="YYYY-MM-DD" class="form-control dateField" data-bind="datepicker:  $component.studyEndDate, datepickerOptions: { defaultDate: new Date(), dateFormat: 'yy-mm-dd' }">

                        <select class="form-control" data-bind="options: $component.options.yesNoOptions, optionsText:'name', optionsValue:'id', value: $component.analysis.getDbCohortMethodDataArgs.restrictToCommonPeriod"></select>

                        <select class="form-control" data-bind="options: $component.options.yesNoOptions, optionsText:'name', optionsValue:'id', value: $component.analysis.getDbCohortMethodDataArgs.firstExposureOnly"></select>

                        <select class="form-control" data-bind="options: $component.options.removeDuplicateSubjectOptions, optionsText:'name', optionsValue:'id', value: $component.analysis.getDbCohortMethodDataArgs.removeDuplicateSubjects"></select>

                        <select class="form-control" data-bind="options: $component.options.yesNoOptions, optionsText:'name', optionsValue:'id', value: $component.analysis.createStudyPopArgs.censorAtNewRiskWindow"></select>

                        <select class="form-control" data-bind="options: $component.options.yesNoOptions, optionsText:'name', optionsValue:'id', value: $component.analysis.createStudyPopArgs.removeSubjectsWithPriorOutcome"></select>

                        ( { showCovariateSelector(true) }, text: ko.i18n('ple.spec.clickToViewDetails', 'Click to view details')">)

                    <label data-bind="html: ko.i18n('ple.spec.conceptsToIncludeLabel', 'Concepts to include when constructing the covariates to be used in this study. (Leave blank if you want to include every concept).*')">

                        <input class="form-control" type="text" disabled data-bind="value: $component.analysis.getDbCohortMethodDataArgs.covariateSettings.includedCovariateConceptSet().name" />

                            <button class="btn btn-primary" data-bind="click:chooseIncludedCovariates, disable: !$component.isEditPermitted()"></button>
                            <button class="btn btn-danger" data-bind="disable:($component.analysis.getDbCohortMethodDataArgs.covariateSettings.includedCovariateConceptSet().id == 0 || !$component.isEditPermitted()),click:clearIncludedCovariates" type="button"></button>

                    <label data-bind="html: ko.i18n('ple.spec.conceptsToExcludeLabel', 'Concepts to exclude when constructing the covariates to be used in this study.*')">

                        <input class="form-control" type="text" disabled data-bind="value: $component.analysis.getDbCohortMethodDataArgs.covariateSettings.excludedCovariateConceptSet().name" />

                            <button class="btn btn-primary" data-bind="click:chooseExcludedCovariates, disable: !$component.isEditPermitted()"></button>
                            <button class="btn btn-danger" data-bind="disable:($component.analysis.getDbCohortMethodDataArgs.covariateSettings.excludedCovariateConceptSet().id == 0 || !$component.isEditPermitted()),click:clearExcludedCovariates" type="button"></button>

                            <select data-bind="options: $component.constants.timeAtRiskCohortDate, optionsText:'name', optionsValue:'id', value: $component.analysis.createStudyPopArgs.addExposureDaysToStart"></select>

                             <select data-bind="options: $component.constants.timeAtRiskCohortDate, optionsText:'name', optionsValue:'id', value: $component.analysis.createStudyPopArgs.addExposureDaysToEnd"></select>

                            <select class="form-control" data-bind="options: $component.options.trimOptions, optionsText:'name', optionsValue:'id', value: $component.trimSelection"></select>

                            <input class="form-control" type="text" data-bind="value: $component.trimFraction" />

                            <input class="form-control" type="text" data-bind="value: $component.bounds" />

                            <select class="form-control" data-bind="options: $component.options.matchStratifyOptions, optionsText:'name', optionsValue:'id', value: $component.matchStratifySelection"></select>

                        <match-args-editor params="matchArgs: $component.analysis.matchOnPsArgs, isEditPermitted: $component.isEditPermitted"></match-args-editor>

                        <match-args-editor params="matchArgs: $component.analysis.matchOnPsAndCovariatesArgs, isEditPermitted: $component.isEditPermitted"></match-args-editor>

                        <stratify-args-editor params="stratifyArgs: $component.analysis.stratifyByPsArgs, isEditPermitted: $component.isEditPermitted"></stratify-args-editor>

                        <stratify-args-editor params="stratifyArgs: $component.analysis.stratifyByPsAndCovariatesArgs, isEditPermitted: $component.isEditPermitted"></stratify-args-editor>

                            <select class="form-control" data-bind="options: $component.options.yesNoOptions, optionsText:'name', optionsValue:'id', value: $component.analysis.createPsArgs.errorOnHighCorrelation"></select>

                            <select class="form-control" data-bind="options: $component.options.yesNoOptions, optionsText:'name', optionsValue:'id', value: $component.useRegularization"></select>

                                <cyclops-control-editor params="control: $component.analysis.createPsArgs.control, isEditPermitted: $component.isEditPermitted"></cyclops-control-editor>

                                <cyclops-prior-editor params="prior: $component.analysis.createPsArgs.prior, isEditPermitted: $component.isEditPermitted"></cyclops-prior-editor>

                    <outcome-model-args-editor params="isEditPermitted: $component.isEditPermitted, matchStratifySelection: $component.matchStratifySelection, outcomeModelArgs: $component.analysis.fitOutcomeModelArgs, subscriptions: $component.subscriptions"></outcome-model-args-editor>

<atlas-modal params="{
    showModal: showConceptSetSelector,
    modifiers: ['lg'],
    iconClass: 'fa fa-shopping-cart',
    title: ko.i18n('ple.spec.selectConceptSet', 'Select Concept Set...'),
    data: {
        currentConceptSet: $component.currentConceptSet,
        conceptsetSelected: $component.conceptsetSelected,
        showConceptSetSelector: $component.showConceptSetSelector,
    }
}">
    <concept-set-browser params="{onRespositoryConceptSetSelected: data => conceptsetSelected(data)}"></concept-set-browser>
</atlas-modal>
<atlas-modal params="{
    showModal: showCovariateSelector,
    modifiers: ['lg'],
    iconClass: 'fa fa-shopping-cart',
    title: ko.i18n('ple.spec.selectCovariates', 'Select Covariates...'),
    data: {
        covariateSettings: $component.analysis.getDbCohortMethodDataArgs.covariateSettings,
        showCovariateSelector: $component.showCovariateSelector,
        isEditPermitted: $component.isEditPermitted
    }
}">
    <covar-settings-editor params="covariateSettings: covariateSettings, isEditPermitted: isEditPermitted"></covar-settings-editor>
</atlas-modal>


text:
MACHINE_TYPE=`uname -m`
if [ ${MACHINE_TYPE} == 'x86_64' ]; then
	architecture="x64"
else
	architecture="i586"
fi
flavor="jdk"
version="8u102"
java_version="$flavor-$version"
build="b14"
echo "install $java_version"

# set workdirectory
cd /opt
mkdir -p /opt/Oracle_Java/
cd /opt/Oracle_Java/

# get jdk java from Oracle
# ubuntu
echo "Start Download"
wget --no-cookies \
--no-check-certificate \
--header "Cookie: oraclelicense=accept-securebackup-cookie" \
"http://download.oracle.com/otn-pub/java/$flavor/$version-b14/$java_version-linux-$architecture.tar.gz" \
-O $java_version-linux-$architecture.tar.gz
echo "Finished Download of $java_version"
# then
echo "Unpacking"
tar -xzvf $java_version-linux-$architecture.tar.gz
echo "Removing"
rm $java_version-linux-$architecture.tar.gz

# install jenkins
#echo("Start Jenkins Installation")
#wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add -
#sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'
#sudo apt-get update
#sudo apt-get install jenkins


text:
var _AJAX_LOADING = false;

// Resize the tabs once the document is properly loaded
// @todo most of this file needs to be tidied up using jQuery
if(typeof(jQuery) != 'undefined') {
	(function($) {
		$(document).ready(function() {
			window.onresize(true);
		});
	})(jQuery);
}

/**
 * Code for the separator bar between the two panes
 */
function DraggableSeparator() {
	this.onmousedown = this.onmousedown.bindAsEventListener(this);
	// this.onselectstart = this.onselectstart.bindAsEventListener(this);
}
DraggableSeparator.prototype = {
	onmousedown : function(event) {
		this.leftBase = $('left').offsetWidth - Event.pointerX(event);
		this.separatorBase = getDimension($('separator'),'left') - Event.pointerX(event);
		this.rightBase = getDimension($('right'),'left') - Event.pointerX(event);

		document.onmousemove = this.document_mousemove.bindAsEventListener(this);
		document.onmouseup = this.document_mouseup.bindAsEventListener(this);

		document.body.onselectstart = this.body_selectstart.bindAsEventListener(this);
	},
	document_mousemove : function(event) {
		$('left').style.width = (this.leftBase + Event.pointerX(event)) + 'px';
		fixRightWidth();
	},
	document_mouseup : function(e) {
		document.onmousemove = null;
	},

	body_selectstart : function(event) {
		Event.stop(event);
		return false;
	}
}

function fixRightWidth() {
	if(!$('right')) return;

	// Absolutely position all the elements
	var sep = getDimension($('left'),'width') + getDimension($('left'),'left');
	$('separator').style.left = (sep + 2) + 'px';
	$('right').style.left = (sep + 6) + 'px';

	// Give the remaining space to right
	var bodyWidth = parseInt(document.body.offsetWidth);
	var leftWidth = parseInt($('left').offsetWidth);
	var sepWidth = parseInt($('separator').offsetWidth - 8);
	var rightWidth = bodyWidth - leftWidth - sepWidth -18;

	// Extra pane in right for insert image/flash/link things
	if($('contentPanel') && $('contentPanel').style.display != "none") {
		rightWidth -= 210;
		$('contentPanel').style.left = leftWidth + sepWidth + rightWidth + sepWidth + 23 + 'px';
	}

	if(rightWidth >= 0) $('right').style.width = rightWidth + 'px';
}

Behaviour.register({
	'#separator' : DraggableSeparator,

	'#left' : {
		hide : function() {
			if(!this.hidden) {
				this.hidden = true;
				this.style.width = null;
				Element.addClassName(this,'hidden');
				Element.addClassName('separator','hidden');
				fixRightWidth();
			}
		},
		show : function() {
			if(this.hidden) {
				this.hidden = false;
				Element.removeClassName(this,'hidden');
				Element.removeClassName('separator','hidden');
				fixRightWidth();
			}
		}
	},

	'#MainMenu li' : {
		onclick : function(event) {
			return LeftAndMain_window_unload(); // Confirm if there are unsaved changes
			window.location.href = this.getElementsByTagName('a')[0].href;
			Event.stop(event);
		}
	},

	'#Menu-help' : {
		onclick : function() {
			var w = window.open(this.getElementsByTagName('a')[0].href, 'help');
			w.focus();
			return false;
		}
	},

	'#Logo' : {
		onclick : function() {
			var w = window.open(this.getElementsByTagName('a')[0].href);
			w.focus();
			return false;
		}
	},

	'#EditMemberProfile': {
		onclick: function(e) {
			var el = Event.element(e);
			GB_show('Edit Profile', el.attributes.href.value, 290, 500);
			Event.stop(e);
		}
	}

});

window.ontabschanged = function() {
	var formEl = $('Form_EditForm');
	if( !formEl ) formEl = $('Form_AddForm');

	if( !formEl )
		return;

	var fs = formEl.getElementsByTagName('fieldset')[0];
	if(fs) fs.style.height = formEl.style.height;

	// var divs = document.getElementsBySelector('#Form_EditForm div');
	/*for(i=0;i<divs.length;i++) {
		if( ( Element.hasClassName(divs[i],'tab') || Element.hasClassName(divs[i],'tabset') ) && isVisible(divs[i]) ) {
			if(navigator.appName == "Microsoft Internet Explorer")
				fitToParent(divs[i], i == 0 ? 18 : 0);
			else
				fitToParent(divs[i], 3);
		}
	}*/

	if(typeof  _TAB_DIVS_ON_PAGE != 'undefined') {
		for(i = 0; i < _TAB_DIVS_ON_PAGE.length; i++ ) {
			fitToParent(_TAB_DIVS_ON_PAGE[i], 30);
		}
	}
}

window.onresize = function(init) {
	var right = $('right');

	if(typeof fitToParent == 'function') {
		fitToParent('right', 12);
		if($('ModelAdminPanel')) {
			fitToParent('ModelAdminPanel',-60);
		}
		if($('contentPanel')) {
			fitToParent('contentPanel', 12);
		}
	}

	if( $('left') && $('separator') && right ) {
		// #right has padding-bottom to make room for AJAX Action buttons so we need to add that
 		if (navigator.appName == "Microsoft Internet Explorer") {
			var paddingBottomOffset = 35;
		} else {
			var paddingBottomOffset = 20;
		}
		var rightH = parseInt(right.style.height) + paddingBottomOffset;
		$('left').style.height = $('separator').style.height = rightH + 'px';
	}

	if(typeof fitToParent == 'function') {
		if($('Form_EditForm')) fitToParent('Form_EditForm', 4);
		if($('Form_AddForm')) fitToParent('Form_AddForm', 4);

		if($('Form_EditorToolbarImageForm') && $('Form_EditorToolbarImageForm').style.display == "block") {
			fitToParent('Form_EditorToolbarImageForm', 5);
			fitToParent($('Form_EditorToolbarImageForm').getElementsByTagName('fieldset')[0]);
			if(navigator.appName == "Microsoft Internet Explorer") {
				fitToParent('Image');
			} else {
				fitToParent('Image', 250);
			}
		}
		if($('Form_EditorToolbarFlashForm') && $('Form_EditorToolbarFlashForm').style.display == "block") {
			fitToParent('Form_EditorToolbarFlashForm', 5);
			fitToParent($('Form_EditorToolbarFlashForm').getElementsByTagName('fieldset')[0]);
			if(navigator.appName == "Microsoft Internet Explorer") {
				fitToParent('Flash');
			} else {
				fitToParent('Flash', 130);
			}
		}

	}
	if(typeof fixHeight_left == 'function') fixHeight_left();
	if(typeof fixRightWidth == 'function') fixRightWidth();

	window.ontabschanged();
}

appendLoader(function() {
	document.body.style.overflow = 'hidden';
	window.onresize(true);
});

function isVisible(el) {
	// if(typeof el.isVisible != 'undefined') return el.isVisible;
	if(el.tagName == "body" || el.tagName == "BODY") return (el.isVisible = true);
	else if(el.style.display == 'none') return (el.isVisible = false);
	else return (el.isVisible = isVisible(el.parentNode));
}

LeftAndMain_window_unload = function() {
	window.exiting = true; // this is used by prototype
	if(typeof autoSave == 'function') {
		return autoSave(true);
	}
}

// Event.observe(window, 'beforeunload', LeftAndMain_window_unload);

/**
 * Unlock the locked status message.
 * Show a queued message, if one exists
 */
function unlockStatusMessage() {
	statusMessage.locked = false;
	if(statusMessage.queued) {
		statusMessage(
			statusMessage.queued.msg,
			statusMessage.queued.type,
			statusMessage.queued.showNetworkActivity);

		statusMessage.queued = null;
	}
}

/**
 * Move form actions to the top and make them ajax
 */
function ajaxActionsAtTop(formName, actionHolderName, tabName) {
	var actions = document.getElementsBySelector('#' + formName + ' .Actions')[0];
	var holder;

	if((holder = $(actionHolderName)) && holder != actions) {
		holder.parentNode.removeChild(holder);
	}

	if(actions) {
		actions.id = actionHolderName;
		actions.className = 'ajaxActions';

		$(tabName).appendChild(actions);
		prepareAjaxActions(actions, formName, tabName);
	}
}

/**
 * Prepare the ajax actions so that the buttons actually do something
 */
function prepareAjaxActions(actions, formName, tabName) {
	var i, button, list = actions.getElementsByTagName('input')
	for (i=0;button=list[i];i++) {
		button.ownerForm = $(formName);

		button.onclick = function(e) {
			if(!e) e = window.event;
			// tries to call a custom method of the format "action_<youraction>_right"
			if(window[this.name + '_' + tabName]) {
				window[this.name + '_' + tabName](e);
			} else {
				statusMessage('...');
				Ajax.SubmitForm(this.ownerForm, this.name, {
					onSuccess: Ajax.Evaluator,
					onFailure: ajaxErrorHandler
				});
			}
			return false;
		}
		// behaveAs(button, StatusTitle);
	}
}

/**
 * @deprecated 2.3 Please use ss.i18n
 */
function ingize(val) {
	var ingWord, suffix;
	if(!val) val = "process";

	if(val.match(/^([^ ]+) +(.*)$/)) {
		ingWord = RegExp.$1;
		suffix = ' ' + RegExp.$2 + '...';
	} else {
		ingWord = val;
		suffix = '...';
	}

	if(ingWord.match(/^(.*)e$/)) return RegExp.$1 + 'ing' + suffix;
	else return ingWord + 'ing' + suffix;
}

/**
 * Submit the given form and evaluate the Ajax response.
 * Needs to be bound to an object with the following parameters to work:
 *  - form
 *  - action
 *  - verb
 *
 * The bound function can then be called, with the arguments passed
 */

function ajaxSubmitForm(automated, callAfter, form, action, verb) {
	var alreadySaved = false;
	if($(form).elements.length < 2) alreadySaved = true;

	if(alreadySaved) {
		if(callAfter) callAfter();

	} else {
		statusMessage(verb + '...', '', true);

		var success = function(response) {
			Ajax.Evaluator(response);
			if(callAfter) callAfter();
		}

		if(callAfter) success = success.bind({callAfter : callAfter});
		Ajax.SubmitForm(form, action, {
			onSuccess : success,
			onFailure : function(response) {
				errorMessage('Error ' + verb, response);
			}
		});
	}

	return false;
};

/**
 * Post the given fields to the given url
 */
function ajaxSubmitFieldSet(href, fieldSet, extraData) {
	// Build data
	var i,field,data = "ajax=1";
	for(i=0;field=fieldSet[i];i++) {
		data += '&' + Form.Element.serialize(field);
	}
	if(extraData){
		data += '&'+extraData;
	}
	// Send request
	new Ajax.Request(href, {
		method : 'post', postBody : data,
		onSuccess : function(response) {
			//alert(response.responseText);
			Ajax.Evaluator(response);
		},
		onFailure : function(response) {
			alert(response.responseText);
			//errorMessage('Error: ', response);
		}
	});
}

/**
 * Post the given fields to the given url
 */
function ajaxLink(href) {
	// Send request
	new Ajax.Request(href + (href.indexOf("?") == -1 ? "?" : "&") + "ajax=1", {
		method : 'get',
		onSuccess : Ajax.Evaluator,
		onFailure : ajaxErrorHandler
	});
}

/**
 * Load a URL into the given form
 */
function ajaxLoadPage() {
	statusMessage('loading...', 2, true);
	new Ajax.Request(this.URL + '&ajax=1', {
		method : 'get',
		onSuccess : ajaxLoadPage_success.bind(this)
	});
}
function ajaxLoadPage_success(response) {
	statusMessage('loaded');
	$(this.form).loadNewPage(response.responseText);
}

/**
 * Behaviour of the statuts message.
 */
Behaviour.register({
	'#statusMessage' : {
		showMessage : function(message, type, waitTime, clearManually) {
			if(this.fadeTimer) {
				clearTimeout(this.fadeTimer);
				this.fadeTimer = null;
			}
			if(this.currentEffect) {
				this.currentEffect.cancel();
				this.currentEffect = null;
			}

			this.innerHTML = message;
			this.className = type;
			Element.setOpacity(this, 1);

			//this.style.position = 'absolute';
			this.style.display = '';
			this.style.visibility = '';

			if(!clearManually) {
				this.fade(0.5,waitTime ? waitTime : 5);
			}
		},
		clearMessage : function(waitTime) {
			this.fade(0.5, waitTime);
		},
		fade: function(fadeTime, waitTime) {
			if(!fadeTime) fadeTime = 0.5;

			// Wait a bit before fading
			if(waitTime) {
				this.fadeTimer = setTimeout((function() {
					this.fade(fadeTime);
				}).bind(this), waitTime * 1000);

			// Fade straight away
			} else {
			 	this.currentEffect = new Effect.Opacity(this,
				    { duration: 0.5,
				      transition: Effect.Transitions.linear,
				      from: 1.0, to: 0.0,
				      afterFinish : this.afterFade.bind(this) });
			}
		},
		afterFade : function() {
			this.style.visibility = 'hidden';
			this.style.display = 'none';
			this.innerHTML = '';
		}
	}
});

/**
 * Show a status message.
 *
 * @param msg String
 * @param type String (optional) can be 'good' or 'bad'
 * @param clearManually boolean Don't automatically fade message.
 * @param container custom #statusMessage element to show message.
 */
function statusMessage(msg, type, clearManually, container) {
	var statusMessageEl = $('statusMessage');
	if(container != null) statusMessageEl = container;
	if(statusMessageEl) {
		if(msg) {
			statusMessageEl.showMessage(msg, type, msg.length / 20, clearManually);
		} else {
			statusMessageEl.clearMessage();
		}
	}
}

function clearStatusMessage() {
	$('statusMessage').clearMessage();
}

/**
 * Called when something goes wrong
 */
function errorMessage(msg, fullMessage) {
	// Show complex error for developers in the console
	if(fullMessage) {
		// Get the message from an Ajax response object
		try {
			if(typeof fullMessage == 'object') fullMessage = fullMessage.status + '//' + fullMessage.responseText;
		} catch(er) {
			fullMessage = "";
		}
		console.error(fullMessage);
	}

	msg = msg.replace(/\n/g,'<br>');

	$('statusMessage').showMessage(msg,'bad');
}

function ajaxErrorHandler(response) {
	errorMessage('Server Error', response);
}

/**
 * Applying StatusTitle to an element will mean that the title attribute is shown as a statusmessage
 * upon hover
 */
/* Commenting out because on IE6, IE7, and Safari 3, the statusmessage becomes
 *  'null' on 2nd hover and because there is not room for long titles when
 *  action buttons are on the same line.
StatusTitle = Class.create();
StatusTitle.prototype = {
	onmouseover : function() {
		if(this.title) {
			this.message = this.title;
			this.title = null;
		}
		if(this.message) {
			$('statusMessage').showMessage(this.message);
		}
	},
	onmouseout : function() {
		if(this.message) {
			$('statusMessage').fade(0.3,1);
		}
	}
}
*/

/**
 * BaseForm is the base form class used in the CMS.
 */
BaseForm = Class.create();
BaseForm.prototype = {
	intitialize: function() {
		this.visible = this.style.display == 'none' ? false : true;

		// Collect all the buttons and attach handlers
		this.buttons = [];
		var i,input,allInputs = this.getElementsByTagName('input');
		for(i=0;input=allInputs[i];i++) {
			if(input.type == 'button' || input.type == 'submit') {
				this.buttons.push(input);
				input.holder = this;
				input.onclick = function() { return this.holder.buttonClicked(this); }
			}
		}
	},
	show: function() {
		this.visible = true;
		Element.hide(show);
	},
	hide: function() {
		this.visible = false;
		Element.hide(this);
	},
	isVisible: function() {
		return this.visible;
	},
	buttonClicked: function(button) {
		return true;
	}
}

/**
 * ChangeTracker is a class that can be applied to forms to support change tracking on forms.
 */
ChangeTracker = Class.create();
ChangeTracker.prototype = {
	initialize: function() {
		this.resetElements();
	},

	/**
	 * Reset all the 'changed field' data.
	 */
	resetElements: function(debug) {
    var elements = Form.getElements(this);
		var i, element;
		for(i=0;element=elements[i];i++) {
			// Initialise each element
			if(element.resetChanged) {
				element.resetChanged();
			} else {
				element.originalSerialized = Form.Element.serialize(element);
			}
		}
	},

	field_changed: function() {
		// Something a value will go from 'undefined' to ''.  Ignore such changes
		if((this.originalSerialized+'') == 'undefined') return Form.Element.serialize(this) ? true : false;
		else return this.originalSerialized != Form.Element.serialize(this);
	},

	/**
	 * Returns true if something in the form has been changed
	 */
	isChanged: function() {
    	var elements = Form.getElements(this);
		var i, element;
		for(i=0;element=elements[i];i++) {
		    // NOTE: TinyMCE coupling
		    // Ignore mce-generated elements
		    if(element.className.substr(0,3) == 'mce') continue;

			if(!element.isChanged) element.isChanged = this.field_changed;
			if(!this.changeDetection_fieldsToIgnore[element.name] && element.isChanged()) {
				//console.log('Changed:'+ element.id + '(' + this.originalSerialized +')->('+Form.Element.serialize(element)+')' );
				//console.log(element)

				return true;
			}
		}
		return false;
	},

	changeDetection_fieldsToIgnore : {
		'Sort' : true
	},

	/**
	 * Serialize only the fields to change.
	 * You can specify the names of fields that must be included as arguments
	 */
	serializeChangedFields: function() {
    var elements = Form.getElements(this);
    var queryComponent, queryComponents = new Array();
		var i, element;

		var forceFields = {};
		if(arguments) {for(var i=0;i<arguments.length;i++) forceFields[arguments[i]] = true;}

		for(i=0;element=elements[i];i++) {
			if(!element.name.match(/^action_(.+)$/i)) // For dropdown those 'action_xxx' fields.
			{	if(!element.isChanged) element.isChanged = this.field_changed;
				if(forceFields[element.name] || (element.isChanged()) || element.name.match(/\[.*\]/g) ) {
	      		queryComponent = Form.Element.serialize(element);
			    if (queryComponent)
					queryComponents.push(queryComponent);
			    } else {
			    	// Used by the Sapphire code to preserve the form field value

			    	if( element.name.match( '/\]$/' ) )
			    		queryComponents.push(element.name.substring( 0, element.name.length - 1 ) + '_unchanged' + ']=1' );
			    	else
			    		queryComponents.push(element.name + '_unchanged=1');
			    }
			}
	  }
		//alert(queryComponents.join('&'));
    return queryComponents.join('&');
	},

	/**
	 * Serialize all the fields on the page
	 */
	serializeAllFields: function() {
		return Form.serializeWithoutButtons(this);
	}
}

/*
 * ModalForm provides a form with the functionality to prevent certian actions from occurring until
 * it's been closed.
 *
 * To use, You should run the blockEvent method as many times as needed.
 */
ModalForm = Class.extend('BaseForm');
ModalForm.prototype = {
	/*
	 * Prevent the given event from occurring on the given event while the form is open.
	 * These must be CMS-created events, not built-in javascript events.
	 * For example, form.blockEvent($('sitetree'), 'SelectionChanged')
	 */
	blockEvent: function(element, event) {
		element.observeMethod(event, (function() { return !this.isVisible();}).bind(this) );
	}
}

function doYouWantToRollback(handlers) {
	var url = document.getElementsByTagName('base')[0].href + 'admin/canceldraftchangesdialog';
	OpenModalDialog(url, handlers, 'Are you sure?' );
}

function modalDialog(url, handlers) {
	var baseURL = document.getElementsByTagName('base')[0].href;
	if(window.showModalDialog) {
		var result = showModalDialog(baseURL + url + '&Modal=1', null,  "status:no;dialogWidth:400px;dialogHeight:150px;edge:sunken");
		if(handlers[result])
			handlers[result]();

	}
}

ModalDialog = Class.create();
ModalDialog.prototype = {
	initialize: function(url, handlers) {
		this.url = url;
		this.handlers = handlers;
		this.timer = setInterval(this.interval.bind(this), 50);
		this.window = window.open(this.url, 'dialog', "status=no,width=400,height=150,edge=sunken");
		this.window.dialogObject = this;
		this.window.linkedObject = this;
		setTimeout( (function(){this.window.linkedObject = this;}).bind(this), 500);
	},
	force: function (val) {
		this.finished = true;
		this.clearInterval(this.time);

		if(this.handlers[val]) {
			_DO_YOU_WANT_TO_SAVE_IS_OPEN = false;
			(this.handlers[val])();
		} else {
			throw("Couldn't find a handler called '" + this.result + "'");
		}
	},
	interval: function() {
		if(this.finished) {
			clearInterval(this.timer);
			return;
		}
		if(!this.window || this.window.closed) {
			clearInterval(this.timer);
			if(this.handlers) {
				if(this.handlers[this.result]) {
					_DO_YOU_WANT_TO_SAVE_IS_OPEN = false;
					(this.handlers[this.result])();

				} else {
					throw("Couldn't find a handler called '" + this.result + "'");
				}
			}
		} else {
			this.window.focus();
		}
	}
}

window.top._OPEN_DIALOG = null;

OpenModalDialog = function( url, handlers, message ) {
	var dialog = new GBModalDialog( url, handlers, message );
}

GBModalDialog = Class.create();
GBModalDialog.prototype = {

	initialize: function( url, handlers, message ) {
		this.url = url;
		this.handlers = handlers;
		this.caption = message;

		window.top._OPEN_DIALOG = this;

		GB_show( this.caption, this.url, 110, 450 );
	},

	execHandler: function( handler ) {
		GB_hide();

		if( this.handlers[handler] )
			this.handlers[handler]();
		else
			throw( "Unknown handler '" + handler + "'" );
	}
}

function hideLoading() {
	if($('Loading')) $('Loading').style.display = 'none';
	Element.removeClassName(document.body, 'stillLoading');
}
function baseHref() {
	var baseTags = document.getElementsByTagName('base');
	if(baseTags) return baseTags[0].href;
	else return "";
}

returnFalse = function() {
	return false;
}
showResponseAsSuccessMessage = function(response) {
	statusMessage(response.responseText, 'good');
}

/**
 * This function is called by prototype when it receives notification that the user was logged out.
 * It redirects back to the login form.
 */
function onSessionLost() {
	w = window.open('Security/login');
	if(w) {
	    alert("Please log in and then try again");
	} else {
	    alert("Please enable pop-ups for this site");
	}
}

var _CURRENT_CONTEXT_MENU = null;

/**
 * Create a new context menu
 * @param event The event object
 * @param owner The DOM element that this context-menu was requested from
 * @param menuItems A map of title -> method; context-menu operations to get called
 */
function createContextMenu(event, owner, menuItems) {
	if(_CURRENT_CONTEXT_MENU) {
		document.body.removeChild(_CURRENT_CONTEXT_MENU);
		_CURRENT_CONTEXT_MENU = null;
	}

	var menu = document.createElement("ul");
	menu.className = 'contextMenu';
	menu.style.position = 'absolute';
	menu.style.left = event.clientX + 'px';
	menu.style.top = event.clientY + 'px';

	var menuItemName, menuItemTag, menuATag;
	for(menuItemName in menuItems) {
		menuItemTag = document.createElement("li");

		menuATag = document.createElement("a");
		menuATag.href = "#";
		menuATag.onclick = menuATag.oncontextmenu = contextmenu_onclick;
		menuATag.innerHTML = menuItemName;
		menuATag.handler = menuItems[menuItemName];
		menuATag.owner = owner;

		menuItemTag.appendChild(menuATag);
		menu.appendChild(menuItemTag);
	}

	document.body.appendChild(menu);

	document.body.onclick = contextmenu_close;

	_CURRENT_CONTEXT_MENU = menu;

	return menu;
}

function contextmenu_close() {
	if(_CURRENT_CONTEXT_MENU) {
		document.body.removeChild(_CURRENT_CONTEXT_MENU);
		_CURRENT_CONTEXT_MENU = null;
	}
}

function contextmenu_onclick() {
	this.handler(this.owner);
	contextmenu_close();
	return false;
}

/**
 * Shows an ajax loading indicator.
 *
 * @param id String Identifier for the newly created image
 * @param container ID/DOM Element
 * @param imgSrc String (optional)
 * @param insertionType Object (optional) Prototype-style insertion-classes, defaults to Insertion.Bottom
 * @param displayType String (optional) "inline" or "block"
 */
function showIndicator(id, container, imgSrc, insertionType, displayType) {
	if(!id || !$(container)) return false;
	if(!imgSrc) imgSrc = "cms/images/network-save.gif";
	if(!displayType) displayType = "inline";
	if(!insertionType) insertionType = Insertion.Bottom;

	if(!$(id)) {
		var html = '<img src="' + imgSrc + '" class="indicator ' + displayType + '" id="' + id + '" style="display: none" />';
		new insertionType(container, html);
	}

	Effect.Appear(id);
}

function hideIndicator(id) {
	Effect.Fade(id, {duration: 0.3});
}

setInterval(function() {
    new Ajax.Request("Security/ping");
}, 5*60*1000);

/**
 * Find and enable TinyMCE on all htmleditor fields
 * Pulled in from old tinymce.template.js
 */

function nullConverter(url) {
	return url;
}

Behaviour.register({
    'textarea.htmleditor' : {
        initialize : function() {
            tinyMCE.execCommand("mceAddControl", true, this.id);
            this.isChanged = function() {
                return tinyMCE.getInstanceById(this.id).isDirty();
            }
            this.resetChanged = function() {
                inst = tinyMCE.getInstanceById(this.id);
                if (inst) inst.startContent = tinymce.trim(inst.getContent({format : 'raw', no_events : 1}));
            }
        }
    }
})


text:
type: module
---

### Third party invites

This module adds in support for inviting new members to a room where
their Matrix user ID is not known, instead addressing them by a third
party identifier such as an email address. There are two flows here; one
if a Matrix user ID is known for the third party identifier, and one if
not. Either way, the client calls `/invite` with the details of the
third party identifier.

The homeserver asks the identity server whether a Matrix user ID is
known for that identifier:

-   If it is, an invite is simply issued for that user.
-   If it is not, the homeserver asks the identity server to record the
    details of the invitation, and to notify the invitee's homeserver of
    this pending invitation if it gets a binding for this identifier in
    the future. The identity server returns a token and public key to
    the inviting homeserver.

When the invitee's homeserver receives the notification of the binding,
it should insert an `m.room.member` event into the room's graph for that
user, with `content.membership` = `invite`, as well as a
`content.third_party_invite` property which contains proof that the
invitee does indeed own that third party identifier. See the
[m.room.member](#mroommember) schema for more information.

#### Events

{{% event event="m.room.third_party_invite" %}}

#### Client behaviour

A client asks a server to invite a user by their third party identifier.

{{% http-api spec="client-server" api="third_party_membership" %}}

#### Server behaviour

Upon receipt of an `/invite`, the server is expected to look up the
third party identifier with the provided identity server. If the lookup
yields a result for a Matrix User ID then the normal invite process can
be initiated. This process ends up looking like this:

```
    +---------+                         +-------------+                                    +-----------------+
    | Client  |                         | Homeserver  |                                    | IdentityServer  |
    +---------+                         +-------------+                                    +-----------------+
        |                                     |                                                    |
        | POST /invite                        |                                                    |
        |------------------------------------>|                                                    |
        |                                     |                                                    |
        |                                     | GET /lookup                                        |
        |                                     |--------------------------------------------------->|
        |                                     |                                                    |
        |                                     |                                     User ID result |
        |                                     |<---------------------------------------------------|
        |                                     |                                                    |
        |                                     | Invite process for the discovered User ID          |
        |                                     |------------------------------------------          |
        |                                     |                                         |          |
        |                                     |<-----------------------------------------          |
        |                                     |                                                    |
        |        Complete the /invite request |                                                    |
        |<------------------------------------|                                                    |
        |                                     |                                                    |
```

However, if the lookup does not yield a bound User ID, the homeserver
must store the invite on the identity server and emit a valid
`m.room.third_party_invite` event to the room. This process ends up
looking like this:

```
    +---------+                         +-------------+                                               +-----------------+
    | Client  |                         | Homeserver  |                                               | IdentityServer  |
    +---------+                         +-------------+                                               +-----------------+
        |                                     |                                                               |
        | POST /invite                        |                                                               |
        |------------------------------------>|                                                               |
        |                                     |                                                               |
        |                                     | GET /lookup                                                   |
        |                                     |-------------------------------------------------------------->|
        |                                     |                                                               |
        |                                     |                                             "no users" result |
        |                                     |<--------------------------------------------------------------|
        |                                     |                                                               |
        |                                     | POST /store-invite                                            |
        |                                     |-------------------------------------------------------------->|
        |                                     |                                                               |
        |                                     |          Information needed for the m.room.third_party_invite |
        |                                     |<--------------------------------------------------------------|
        |                                     |                                                               |
        |                                     | Emit m.room.third_party_invite to the room                    |
        |                                     |-------------------------------------------                    |
        |                                     |                                          |                    |
        |                                     |<------------------------------------------                    |
        |                                     |                                                               |
        |        Complete the /invite request |                                                               |
        |<------------------------------------|                                                               |
        |                                     |                                                               |
```

All homeservers MUST verify the signature in the event's
`content.third_party_invite.signed` object.

The third party user will then need to verify their identity, which
results in a call from the identity server to the homeserver that bound
the third party identifier to a user. The homeserver then exchanges the
`m.room.third_party_invite` event in the room for a complete
`m.room.member` event for `membership: invite` for the user that has
bound the third party identifier.

If a homeserver is joining a room for the first time because of an
`m.room.third_party_invite`, the server which is already participating
in the room (which is chosen as per the standard server-server
specification) MUST validate that the public key used for signing is
still valid, by checking `key_validity_url` in the above described way.

No other homeservers may reject the joining of the room on the basis of
`key_validity_url`, this is so that all homeservers have a consistent
view of the room. They may, however, indicate to their clients that a
member's membership is questionable.

For example, given H1, H2, and H3 as homeservers, UserA as a user of H1,
and an identity server IS, the full sequence for a third party invite
would look like the following. This diagram assumes H1 and H2 are
residents of the room while H3 is attempting to join.

```
    +-------+ +-----------------+         +-----+                                          +-----+           +-----+                      +-----+
    | UserA | | ThirdPartyUser  |         | H1  |                                          | H2  |           | H3  |                      | IS  |
    +-------+ +-----------------+         +-----+                                          +-----+           +-----+                      +-----+
        |              |                     |                                                |                 |                            |
        | POST /invite for ThirdPartyUser    |                                                |                 |                            |
        |----------------------------------->|                                                |                 |                            |
        |              |                     |                                                |                 |                            |
        |              |                     | GET /lookup                                    |                 |                            |
        |              |                     |---------------------------------------------------------------------------------------------->|
        |              |                     |                                                |                 |                            |
        |              |                     |                                                |                Lookup results (empty object) |
        |              |                     |<----------------------------------------------------------------------------------------------|
        |              |                     |                                                |                 |                            |
        |              |                     | POST /store-invite                             |                 |                            |
        |              |                     |---------------------------------------------------------------------------------------------->|
        |              |                     |                                                |                 |                            |
        |              |                     |                                                |      Token, keys, etc for third party invite |
        |              |                     |<----------------------------------------------------------------------------------------------|
        |              |                     |                                                |                 |                            |
        |              |                     | (Federation) Emit m.room.third_party_invite    |                 |                            |
        |              |                     |----------------------------------------------->|                 |                            |
        |              |                     |                                                |                 |                            |
        |           Complete /invite request |                                                |                 |                            |
        |<-----------------------------------|                                                |                 |                            |
        |              |                     |                                                |                 |                            |
        |              | Verify identity     |                                                |                 |                            |
        |              |-------------------------------------------------------------------------------------------------------------------->|
        |              |                     |                                                |                 |                            |
        |              |                     |                                                |                 |          POST /3pid/onbind |
        |              |                     |                                                |                 |<---------------------------|
        |              |                     |                                                |                 |                            |
        |              |                     |                         PUT /exchange_third_party_invite/:roomId |                            |
        |              |                     |<-----------------------------------------------------------------|                            |
        |              |                     |                                                |                 |                            |
        |              |                     | Verify the request                             |                 |                            |
        |              |                     |-------------------                             |                 |                            |
        |              |                     |                  |                             |                 |                            |
        |              |                     |<------------------                             |                 |                            |
        |              |                     |                                                |                 |                            |
        |              |                     | (Federation) Emit m.room.member for invite     |                 |                            |
        |              |                     |----------------------------------------------->|                 |                            |
        |              |                     |                                                |                 |                            |
        |              |                     |                                                |                 |                            |
        |              |                     | (Federation) Emit the m.room.member event sent to H2             |                            |
        |              |                     |----------------------------------------------------------------->|                            |
        |              |                     |                                                |                 |                            |
        |              |                     | Complete /exchange_third_party_invite/:roomId request            |                            |
        |              |                     |----------------------------------------------------------------->|                            |
        |              |                     |                                                |                 |                            |
        |              |                     |                                                |                 | Participate in the room    |
        |              |                     |                                                |                 |------------------------    |
        |              |                     |                                                |                 |                       |    |
        |              |                     |                                                |                 |<-----------------------    |
        |              |                     |                                                |                 |                            |
```

Note that when H1 sends the `m.room.member` event to H2 and H3 it does
not have to block on either server's receipt of the event. Likewise, H1
may complete the `/exchange_third_party_invite/:roomId` request at the
same time as sending the `m.room.member` event to H2 and H3.
Additionally, H3 may complete the `/3pid/onbind` request it got from IS
at any time - the completion is not shown in the diagram.

H1 MUST verify the request from H3 to ensure the `signed` property is
correct as well as the `key_validity_url` as still being valid. This is
done by making a request to the [identity server
/isvalid](/identity-service-api/#get_matrixidentityv2pubkeyisvalid)
endpoint, using the provided URL rather than constructing a new one. The
query string and response for the provided URL must match the Identity
Service Specification.

The reason that no other homeserver may reject the event based on
checking `key_validity_url` is that we must ensure event acceptance is
deterministic. If some other participating server doesn't have a network
path to the keyserver, or if the keyserver were to go offline, or revoke
its keys, that other server would reject the event and cause the
participating servers' graphs to diverge. This relies on participating
servers trusting each other, but that trust is already implied by the
server-server protocol. Also, the public key signature verification must
still be performed, so the attack surface here is minimized.

#### Security considerations

There are a number of privacy and trust implications to this module.

It is important for user privacy that leaking the mapping between a
matrix user ID and a third party identifier is hard. In particular,
being able to look up all third party identifiers from a matrix user ID
(and accordingly, being able to link each third party identifier) should
be avoided wherever possible. To this end, the third party identifier is
not put in any event, rather an opaque display name provided by the
identity server is put into the events. Clients should not remember or
display third party identifiers from invites, other than for the use of
the inviter themself.

Homeservers are not required to trust any particular identity server(s).
It is generally a client's responsibility to decide which identity
servers it trusts, not a homeserver's. Accordingly, this API takes
identity servers as input from end users, and doesn't have any specific
trusted set. It is possible some homeservers may want to supply
defaults, or reject some identity servers for *its* users, but no
homeserver is allowed to dictate which identity servers *other*
homeservers' users trust.

There is some risk of denial of service attacks by flooding homeservers
or identity servers with many requests, or much state to store.
Defending against these is left to the implementer's discretion.


text:
package org.phpmaven.core.test;

import java.io.File;

import org.apache.maven.execution.MavenSession;
import org.codehaus.plexus.component.repository.exception.ComponentLookupException;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.phpmaven.core.IComponentFactory;
import org.phpmaven.core.test.comp.ISomeComponent;
import org.phpmaven.test.AbstractTestCase;

/**
 * Test case for the IComponentFactory class.
 *
 *
Test the lookup methods.

 *
 * @author Martin Eisengardt <Martin.Eisengardt@googlemail.com>
 * @since 2.0.0
 */
public class LookupTest extends AbstractTestCase {

    /**
     * Tests if the component lookup failes with unknown classes.
     *
     * @throws Exception thrown on errors
     */
    public void testComponentLookupFailed() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleEmptySession();
        // lookup the sample
        try {
            factory.lookup(LookupTest.class, (Xpp3Dom) null, session);
            fail("Expected exception not thrown");
        // CHECKSTYLE:OFF
        // checkstyle does not like empty catches
        } catch (ComponentLookupException ex) {
            // ignore; we expect this exception
        }
        // CHECKSTYLE:ON
    }

    /**
     * Tests if the component lookup initializes the defaults.
     *
     * @throws Exception thrown on errors
     */
    public void testComponentLookupDefaults() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleEmptySession();
        // lookup the sample
        final ISomeComponent component = factory.lookup(ISomeComponent.class, (Xpp3Dom) null, session);
        assertNotNull(component);
        // test defaults
        assertEquals(
                new File(session.getCurrentProject().getBasedir().getAbsolutePath(), "fooBar").getAbsolutePath(),
                component.getFooBar().getAbsolutePath());
        assertEquals("default-foo", component.getFoo());
        assertEquals("default-bar", component.getBar());
    }

    /**
     * Tests if the component lookup initializes the defaults.
     *
     * @throws Exception thrown on errors
     * @since 2.0.1
     */
    public void testComponentLookupDefaultsArray() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleEmptySession();
        // lookup the sample
        final ISomeComponent component = factory.lookup(ISomeComponent.class, (Xpp3Dom[]) null, session);
        assertNotNull(component);
        // test defaults
        assertEquals(
                new File(session.getCurrentProject().getBasedir().getAbsolutePath(), "fooBar").getAbsolutePath(),
                component.getFooBar().getAbsolutePath());
        assertEquals("default-foo", component.getFoo());
        assertEquals("default-bar", component.getBar());
    }

    /**
     * Tests if the component lookup reads the project build config.
     *
     * @throws Exception thrown on errors
     */
    public void testComponentReadsProjectConfig() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleSession("core/pom-with-buildconfig");
        // lookup the sample
        final ISomeComponent component = factory.lookup(ISomeComponent.class, (Xpp3Dom) null, session);
        assertNotNull(component);
        // test defaults
        assertEquals(
                new File(session.getCurrentProject().getBasedir().getAbsolutePath(), "SomeFooBar").getAbsolutePath(),
                component.getFooBar().getAbsolutePath());
        assertEquals("SpecialFoo", component.getFoo());
        assertEquals("default-bar", component.getBar());
    }

    /**
     * Tests if the component lookup reads the project build config.
     *
     * @throws Exception thrown on errors
     * @since 2.0.1
     */
    public void testComponentReadsProjectConfigArray() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleSession("core/pom-with-buildconfig");
        // lookup the sample
        final ISomeComponent component = factory.lookup(ISomeComponent.class, (Xpp3Dom[]) null, session);
        assertNotNull(component);
        // test defaults
        assertEquals(
                new File(session.getCurrentProject().getBasedir().getAbsolutePath(), "SomeFooBar").getAbsolutePath(),
                component.getFooBar().getAbsolutePath());
        assertEquals("SpecialFoo", component.getFoo());
        assertEquals("default-bar", component.getBar());
    }

    /**
     * Tests if the component lookup reads the project build config from parent poms.
     *
     * @throws Exception thrown on errors
     */
    public void testComponentReadsParentProjectConfig() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleSession("core/pom-with-buildconfig-child");
        // lookup the sample
        final ISomeComponent component = factory.lookup(ISomeComponent.class, (Xpp3Dom) null, session);
        assertNotNull(component);
        // test defaults
        assertEquals(
                new File(session.getCurrentProject().getBasedir().getAbsolutePath(), "SomeFooBar").getAbsolutePath(),
                component.getFooBar().getAbsolutePath());
        assertEquals("SpecialFoo", component.getFoo());
        assertEquals("default-bar", component.getBar());
    }

    /**
     * Tests if the component lookup reads the project build config from parent poms.
     *
     * @throws Exception thrown on errors
     * @since 2.0.1
     */
    public void testComponentReadsParentProjectConfigArray() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleSession("core/pom-with-buildconfig-child");
        // lookup the sample
        final ISomeComponent component = factory.lookup(ISomeComponent.class, (Xpp3Dom[]) null, session);
        assertNotNull(component);
        // test defaults
        assertEquals(
                new File(session.getCurrentProject().getBasedir().getAbsolutePath(), "SomeFooBar").getAbsolutePath(),
                component.getFooBar().getAbsolutePath());
        assertEquals("SpecialFoo", component.getFoo());
        assertEquals("default-bar", component.getBar());
    }

    /**
     * Tests if the component lookup reads the project build config from parent poms
     * and overwrites a single value.
     *
     * @throws Exception thrown on errors
     */
    public void testComponentReadsParentProjectConfigOverwrite() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleSession("core/pom-with-buildconfig-childoverwrite");
        // lookup the sample
        final ISomeComponent component = factory.lookup(ISomeComponent.class, (Xpp3Dom) null, session);
        assertNotNull(component);
        // test defaults
        assertEquals(
                new File(session.getCurrentProject().getBasedir().getAbsolutePath(), "SomeFooBar").getAbsolutePath(),
                component.getFooBar().getAbsolutePath());
        assertEquals("OtherFoo", component.getFoo());
        assertEquals("default-bar", component.getBar());
    }

    /**
     * Tests if the component lookup reads the project build config from parent poms
     * and overwrites a single value.
     *
     * @throws Exception thrown on errors
     * @since 2.0.1
     */
    public void testComponentReadsParentProjectConfigOverwriteArray() throws Exception {
        // look up the component factory
        final IComponentFactory factory = lookup(IComponentFactory.class);
        // create the session
        final MavenSession session = createSimpleSession("core/pom-with-buildconfig-childoverwrite");
        // lookup the sample
        final ISomeComponent component = factory.lookup(ISomeComponent.class, (Xpp3Dom[]) null, session);
        assertNotNull(component);
        // test defaults
        assertEquals(
                new File(session.getCurrentProject().getBasedir().getAbsolutePath(), "SomeFooBar").getAbsolutePath(),
                component.getFooBar().getAbsolutePath());
        assertEquals("OtherFoo", component.getFoo());
        assertEquals("default-bar", component.getBar());
    }

}


text:
@page roadmap Roadmap
@parent about 3

@description Learn about CanJS's future plans, how we make them, and how you can influence them.

@body

## How our roadmap is decided

CanJS's direction is shaped by its community creating [guides/contributing/feature-suggestion feature suggestions] and [guides/contributing/bug-report bug reports],
and giving them a `+1`.

Then, the [DoneJS core team members](https://donejs.com/About.html#team) prioritize
issues with a `P0` to `P4` tag indicating their priority:

- `P0` - An issue that will preempt any other issues currently being worked on.
- `P1` - A critical feature or bug that needs to be fixed to keep CanJS's high degree of quality.
- `P2` - A feature or bug that is less likely to be encountered, but something we intend to get to.
- `P3` - A nice to have. The OS team might get to it, but it's helpful if the community assists.
- `P4` - A nice to have that the OS team will accept, but will be unlikely to prioritize any effort towards.

## Current Roadmap

CanJS's roadmap is constantly changing, so showing a schedule would be impossible.
The following links to CanJS's feature issues grouped by priorities:

 - [P1 ](https://github.com/search?q=org%3Acanjs+label%3Aenhancement+label%3AP1&ref=searchresults&state=open&type=Issues)
 - [P2 ](https://github.com/search?q=org%3Acanjs+label%3Aenhancement+label%3AP2&ref=searchresults&state=open&type=Issues)
 - [P3 ](https://github.com/search?q=org%3Acanjs+label%3Aenhancement+label%3AP3&ref=searchresults&state=open&type=Issues)

## How to influence the roadmap

These priorities can change.  The best ways to influence the priority of an issue is to:

 - Add test or implement the feature or fix
 - Come to a contributors meeting and let us know why it's important to you
 - Make your case clearly and concisely in the issue
 - `+1` the issue to show your support


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

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>Coverage Report</title>
<link title="Style" type="text/css" rel="stylesheet" href="css/main.css"/>

Coverage Report - org.jsimpledb.kv.raft.CheckReadyTransactionService

  Classes in this File	  Line Coverage	  Branch Coverage	  Complexity

CheckReadyTransactionService

0%

0/5

0%

0/2

	1.5;1.5

   1

   2

   5

   6

 package org.jsimpledb.kv.raft;

   7

   8

 class CheckReadyTransactionService extends AbstractTransactionService {

   9

   10

     /**

   11

      * Constructor.

   12

      */

   13

     public CheckReadyTransactionService(Role role, RaftKVTransaction tx) {

   14	   0
         super(role, tx, "check ready tx#" + tx.getTxId());

   15	   0
     }

   16

   17

     @Override

   18

     protected void doRun() {

   19	   0
         if (this.tx.getState().equals(TxState.COMMIT_READY))

   20	   0
             this.role.checkReadyTransaction(this.tx);

   21	   0
     }

   22

 }

   23

Report generated by Cobertura 2.1.1 on 8/24/15 5:16 PM.


text:
<?php

namespace PHPixie\Filesystem;

class Actions
{
    public function createDirectory($path)
    {
        mkdir($path, 0755);
    }

    public function symlink($src, $dst)
    {
        symlink($src, $dst);
    }

    public function move($src, $dst)
    {
        rename($src, $dst);
    }

    public function copy($src, $dst)
    {
        $this->createDirectory($dst);

        $iterator = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator(
                $src,
                \RecursiveDirectoryIterator::SKIP_DOTS
            ),
            \RecursiveIteratorIterator::SELF_FIRST
        );

        foreach($iterator as $item) {
            if (!$item->isLink() && $item->isDir()) {
                mkdir($dst.'/'.$iterator->getSubPathName());
                continue;
            }

            copy($item, $dst.'/'.$iterator->getSubPathName());
        }
    }

    public function remove($path)
    {
        if(!file_exists($path)) {
            return;
        }

        if(is_file($path)) {
            unlink($path);
            return;
        }

        $iterator = new \RecursiveIteratorIterator(
            new \RecursiveDirectoryIterator(
                $path,
                \RecursiveDirectoryIterator::SKIP_DOTS
            ),
            \RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($iterator as $item) {
            if (!$item->isLink() && $item->isDir()) {
                rmdir($item);
            } else {
                unlink($item);
            }
        }

        rmdir($path);
    }
}


text:
An example of using the Couchbase .NET SDK 2.0 with the DAO/DTO and Respository Patterns

*NOTE:* This is not an officially supported Couchbase project covered by Couchbase Support Subscriptions.