<commit_before>/*!
 * ${copyright}
 */
/**
 * Defines miscellaneous support rules.
 */
sap.ui.define(["sap/ui/support/library", "./CoreHelper.support", "sap/ui/thirdparty/jquery", "sap/ui/dom/jquery/control"], // jQuery Plugin "control"
	function(SupportLib, CoreHelper, jQuery) {
	"use strict";

	// support rules can get loaded within a ui5 version which does not have module "sap/base/Log" yet
	// therefore load the jQuery.sap.log fallback if not available
	var Log = sap.ui.require("sap/base/Log");
	if (!Log) {
		Log = jQuery.sap.log;
	}

	// shortcuts
	var Categories = SupportLib.Categories; // Accessibility, Performance, Memory, ...
	var Severity = SupportLib.Severity; // Hint, Warning, Error
	var Audiences = SupportLib.Audiences; // Control, Internal, Application

	//**********************************************************
	// Rule Definitions
	//**********************************************************

	/***
	 * Checks for custom css files
	 */
	var oCssCheckCustomStyles = {
		id: "cssCheckCustomStyles",
		audiences: [Audiences.Application],
		categories: [Categories.Consistency],
		enabled: true,
		minversion: "1.38",
		title: "CSS modifications - List of custom styles",
		description: "Checks and report for custom CSS files/styles that overwrite standard UI5 control's CSS values ",
		resolution: "Avoid CSS manipulations with custom CSS values as this could lead to rendering issues ",
		resolutionurls: [{
			text: 'CSS Styling Issues',
			href: 'https://openui5.hana.ondemand.com/#/topic/9d87f925dfbb4e99b9e2963693aa00ef'
		}, {
			text: 'General Guidelines',
			href: 'https://openui5.hana.ondemand.com/#/topic/5e08ff90b7434990bcb459513d8c52c4'
		}],
		check: function (issueManager, oCoreFacade, oScope) {
			var cssFilesMessage = "Following stylesheet file(s) contain 'custom' CSS that could affects (overwrites) UI5 controls' own styles: \n",
				externalStyleSheets = CoreHelper.getExternalStyleSheets(),
				foundIssues = 0;

			externalStyleSheets.forEach(function (styleSheet) {
				var affectsUI5Controls = false;

				Array.from(styleSheet.rules).forEach(function (rule) {
					var selector = rule.selectorText,
						matchedNodes = document.querySelectorAll(selector);

					matchedNodes.forEach(function (node) {
						var hasUI5Parent = CoreHelper.nodeHasUI5ParentControl(node, oScope);
						if (hasUI5Parent) {
							affectsUI5Controls = true;
						}
					});
				});

				if (affectsUI5Controls) {
					cssFilesMessage += "- " + CoreHelper.getStyleSheetName(styleSheet) + "\n";
					foundIssues++;
				}
			});

			if (foundIssues > 0) {
				issueManager.addIssue({
					severity: Severity.Medium,
					details: cssFilesMessage,
					context: {
						id: "WEBPAGE"
					}
				});
			}
		}
	};

	/***
	 * Checks for custom styles applied on UI elements
	 */
	var oCssCheckCustomStylesThatAffectControls = {
		id: "cssCheckCustomStylesThatAffectControls",
		audiences: [Audiences.Application],
		categories: [Categories.Consistency],
		enabled: true,
		minversion: "1.38",
		title: "CSS modifications - List of affected controls",
		description: "Checks and report all overwritten standard control's CSS values ",
		resolution: "Avoid CSS manipulations with custom CSS values as this could lead to rendering issues ",
		resolutionurls: [{
			text: 'CSS Styling Issues',
			href: 'https://openui5.hana.ondemand.com/#/topic/9d87f925dfbb4e99b9e2963693aa00ef'
		}, {
			text: 'General Guidelines',
			href: 'https://openui5.hana.ondemand.com/#/topic/5e08ff90b7434990bcb459513d8c52c4'
		}],
		check: function (issueManager, oCoreFacade, oScope) {
			var controlCustomCssHashMap = {},
				externalStyleSheets = CoreHelper.getExternalStyleSheets();

			externalStyleSheets.forEach(function (styleSheet) {

				Array.from(styleSheet.rules).forEach(function (rule) {
					var selector = rule.selectorText,
						matchedNodes = document.querySelectorAll(selector);

					matchedNodes.forEach(function (node) {
						var hasUI5Parent = CoreHelper.nodeHasUI5ParentControl(node, oScope);
						if (hasUI5Parent) {
							// jQuery Plugin "control"
							var ui5Control = jQuery(node).control()[0];

							if (!controlCustomCssHashMap.hasOwnProperty(ui5Control.getId())) {
								controlCustomCssHashMap[ui5Control.getId()] =  "";
							}

							var cssSource = CoreHelper.getStyleSource(styleSheet);
							controlCustomCssHashMap[ui5Control.getId()] += "'" + selector + "'" + " from " + cssSource + ",\n";
						}
					});
				});
			});

			Object.keys(controlCustomCssHashMap).forEach(function(id) {
				issueManager.addIssue({
					severity: Severity.Low,
					details: "The following selector(s) " + controlCustomCssHashMap[id] + " affects standard style setting for control",
					context: {
						id: id
					}
				});

			});
		}
	};

	/***
	 * Checks for custom styles applied on UI elements
	 */
	var oCheckForLegacyParametersGet = {
		id: "checkForLegacyParametersGet",
		audiences: [Audiences.Control, Audiences.Application],
		categories: [Categories.Performance],
		enabled: true,
		minversion: "1.87",
		title: "Legacy sap.ui.core.theming.Parameters#get API",
		description: "Checks usage of the legecy variant of the Parameters.get API",
		resolution: "Use asynchronous variant of the Parameters.get API",
		resolutionurls: [{
			text: 'Parameters.get API Reference',
			href: 'https://openui5.hana.ondemand.com/api/sap.ui.core.theming.Parameters#methods/sap.ui.core.theming.Parameters.get'
		}],
		check: function (issueManager, oCoreFacade, oScope) {
			var oLoggedObjects = oScope.getLoggedObjects("LegacyParametersGet");
			oLoggedObjects.forEach(function(oLoggedObject) {
				issueManager.addIssue({
					severity: Severity.High,
					details: oLoggedObject.message,
					context: {
						id: "WEBPAGE"
					}
				});
			});
		}
	};

	return [
		oCheckForLegacyParametersGet,
		oCssCheckCustomStyles,
		oCssCheckCustomStylesThatAffectControls
	];
}, true);<commit_msg>[INTERNAL] support: LegacyParametersGet<commit_after>/*!
 * ${copyright}
 */
/**
 * Defines miscellaneous support rules.
 */
sap.ui.define(["sap/ui/support/library", "./CoreHelper.support", "sap/ui/thirdparty/jquery", "sap/ui/dom/jquery/control"], // jQuery Plugin "control"
	function(SupportLib, CoreHelper, jQuery) {
	"use strict";

	// support rules can get loaded within a ui5 version which does not have module "sap/base/Log" yet
	// therefore load the jQuery.sap.log fallback if not available
	var Log = sap.ui.require("sap/base/Log");
	if (!Log) {
		Log = jQuery.sap.log;
	}

	// shortcuts
	var Categories = SupportLib.Categories; // Accessibility, Performance, Memory, ...
	var Severity = SupportLib.Severity; // Hint, Warning, Error
	var Audiences = SupportLib.Audiences; // Control, Internal, Application

	//**********************************************************
	// Rule Definitions
	//**********************************************************

	/***
	 * Checks for custom css files
	 */
	var oCssCheckCustomStyles = {
		id: "cssCheckCustomStyles",
		audiences: [Audiences.Application],
		categories: [Categories.Consistency],
		enabled: true,
		minversion: "1.38",
		title: "CSS modifications - List of custom styles",
		description: "Checks and report for custom CSS files/styles that overwrite standard UI5 control's CSS values ",
		resolution: "Avoid CSS manipulations with custom CSS values as this could lead to rendering issues ",
		resolutionurls: [{
			text: 'CSS Styling Issues',
			href: 'https://openui5.hana.ondemand.com/#/topic/9d87f925dfbb4e99b9e2963693aa00ef'
		}, {
			text: 'General Guidelines',
			href: 'https://openui5.hana.ondemand.com/#/topic/5e08ff90b7434990bcb459513d8c52c4'
		}],
		check: function (issueManager, oCoreFacade, oScope) {
			var cssFilesMessage = "Following stylesheet file(s) contain 'custom' CSS that could affects (overwrites) UI5 controls' own styles: \n",
				externalStyleSheets = CoreHelper.getExternalStyleSheets(),
				foundIssues = 0;

			externalStyleSheets.forEach(function (styleSheet) {
				var affectsUI5Controls = false;

				Array.from(styleSheet.rules).forEach(function (rule) {
					var selector = rule.selectorText,
						matchedNodes = document.querySelectorAll(selector);

					matchedNodes.forEach(function (node) {
						var hasUI5Parent = CoreHelper.nodeHasUI5ParentControl(node, oScope);
						if (hasUI5Parent) {
							affectsUI5Controls = true;
						}
					});
				});

				if (affectsUI5Controls) {
					cssFilesMessage += "- " + CoreHelper.getStyleSheetName(styleSheet) + "\n";
					foundIssues++;
				}
			});

			if (foundIssues > 0) {
				issueManager.addIssue({
					severity: Severity.Medium,
					details: cssFilesMessage,
					context: {
						id: "WEBPAGE"
					}
				});
			}
		}
	};

	/***
	 * Checks for custom styles applied on UI elements
	 */
	var oCssCheckCustomStylesThatAffectControls = {
		id: "cssCheckCustomStylesThatAffectControls",
		audiences: [Audiences.Application],
		categories: [Categories.Consistency],
		enabled: true,
		minversion: "1.38",
		title: "CSS modifications - List of affected controls",
		description: "Checks and report all overwritten standard control's CSS values ",
		resolution: "Avoid CSS manipulations with custom CSS values as this could lead to rendering issues ",
		resolutionurls: [{
			text: 'CSS Styling Issues',
			href: 'https://openui5.hana.ondemand.com/#/topic/9d87f925dfbb4e99b9e2963693aa00ef'
		}, {
			text: 'General Guidelines',
			href: 'https://openui5.hana.ondemand.com/#/topic/5e08ff90b7434990bcb459513d8c52c4'
		}],
		check: function (issueManager, oCoreFacade, oScope) {
			var controlCustomCssHashMap = {},
				externalStyleSheets = CoreHelper.getExternalStyleSheets();

			externalStyleSheets.forEach(function (styleSheet) {

				Array.from(styleSheet.rules).forEach(function (rule) {
					var selector = rule.selectorText,
						matchedNodes = document.querySelectorAll(selector);

					matchedNodes.forEach(function (node) {
						var hasUI5Parent = CoreHelper.nodeHasUI5ParentControl(node, oScope);
						if (hasUI5Parent) {
							// jQuery Plugin "control"
							var ui5Control = jQuery(node).control()[0];

							if (!controlCustomCssHashMap.hasOwnProperty(ui5Control.getId())) {
								controlCustomCssHashMap[ui5Control.getId()] =  "";
							}

							var cssSource = CoreHelper.getStyleSource(styleSheet);
							controlCustomCssHashMap[ui5Control.getId()] += "'" + selector + "'" + " from " + cssSource + ",\n";
						}
					});
				});
			});

			Object.keys(controlCustomCssHashMap).forEach(function(id) {
				issueManager.addIssue({
					severity: Severity.Low,
					details: "The following selector(s) " + controlCustomCssHashMap[id] + " affects standard style setting for control",
					context: {
						id: id
					}
				});

			});
		}
	};

	/***
	 * Checks for custom styles applied on UI elements
	 */
	var oCheckForLegacyParametersGet = {
		id: "checkForLegacyParametersGet",
		audiences: [Audiences.Control],
		categories: [Categories.Performance],
		enabled: true,
		minversion: "1.87",
		title: "Legacy sap.ui.core.theming.Parameters#get API",
		description: "Checks usage of the legecy variant of the Parameters.get API",
		resolution: "Use asynchronous variant of the Parameters.get API",
		resolutionurls: [{
			text: 'Parameters.get API Reference',
			href: 'https://openui5.hana.ondemand.com/api/sap.ui.core.theming.Parameters#methods/sap.ui.core.theming.Parameters.get'
		}],
		check: function (issueManager, oCoreFacade, oScope) {
			var oLoggedObjects = oScope.getLoggedObjects("LegacyParametersGet");
			oLoggedObjects.forEach(function(oLoggedObject) {
				issueManager.addIssue({
					severity: Severity.Medium,
					details: oLoggedObject.message,
					context: {
						id: "WEBPAGE"
					}
				});
			});
		}
	};

	return [
		oCheckForLegacyParametersGet,
		oCssCheckCustomStyles,
		oCssCheckCustomStylesThatAffectControls
	];
}, true);<|endoftext|>


<commit_before>/**
 * Copyright (c) 2014, CKSource - Frederico Knabben. All rights reserved.
 * Licensed under the terms of the MIT License (see LICENSE.md).
 */

'use strict';

var path = require( 'path' ),
	_ = require( 'lodash' ),
	files = [
		path.join( __dirname, '/../node_modules/requirejs/require.js' ),
		path.join( __dirname, '/adapter.js' )
	],
	requireConfig = {};

module.exports = {
	name: 'bender-pagebuilder-amd',
	files: files,
	include: files,

	build: function( data ) {
		data.parts.push( '' );
		return data;
	},

	init: function( done ) {
		var config = this.conf.amd || this.conf[ 'bender-amd' ];

		if ( this.conf[ 'bender-amd' ] ) {
			this.logger.warn( '"bender-amd" config property is deprecated, please use "amd" instead' );
		}

		if ( config ) {
			_.extend( requireConfig, config );
		}

		done();
	}
};
<commit_msg>Fixed: Resolve the path to the RequireJS instead of hardcoding it.<commit_after>/**
 * Copyright (c) 2014, CKSource - Frederico Knabben. All rights reserved.
 * Licensed under the terms of the MIT License (see LICENSE.md).
 */

'use strict';

var path = require( 'path' ),
	_ = require( 'lodash' ),
	files = [
		path.join( require.resolve( 'requirejs' ), '../../require.js' ),
		path.join( __dirname, '/adapter.js' )
	],
	requireConfig = {};

module.exports = {
	name: 'bender-pagebuilder-amd',
	files: files,
	include: files,

	build: function( data ) {
		data.parts.push( '' );
		return data;
	},

	init: function( done ) {
		var config = this.conf.amd || this.conf[ 'bender-amd' ];

		if ( this.conf[ 'bender-amd' ] ) {
			this.logger.warn( '"bender-amd" config property is deprecated, please use "amd" instead' );
		}

		if ( config ) {
			_.extend( requireConfig, config );
		}

		done();
	}
};
<|endoftext|>


<commit_before>module('lively.persistence.BuildSpecMorphExtensions').requires("lively.morphic.Widgets", "lively.morphic.Serialization", "lively.morphic.AdditionalMorphs", "lively.morphic.Lists").toRun(function() {

lively.morphic.Morph.addMethods(
'UI builder', {

    buildSpecProperties: {
        name: {},
        doNotSerialize: {defaultValue: [], getter: function(morph, val) { if (!morph.hasOwnProperty("doNotSerialize")) return []; return val && val.reject(function(ea) { return !Object.isString(ea) || ea.startsWith('$$'); }) }},
        doNotCopyProperties: {defaultValue: [], getter: function(morph, val) { if (!morph.hasOwnProperty("doNotCopyProperties")) return []; return val && val.reject(function(ea) { return !Object.isString(ea) || ea.startsWith('$$'); }) }},
        grabbingEnabled: {defaultValue: undefined},
        draggingEnabled: {defaultValue: undefined},
        droppingEnabled: {defaultValue: undefined},
        halosEnabled: {defaultValue: true},
        _ClipMode: {defaultValue: 'visible'},
        _StyleSheet: {getter: function(morph, val) { return !val || Object.isString(val) ? val : val.getText(); }},
        _StyleClassNames: {},
        _Position: {defaultValue: lively.pt(0.0,0.0)},
        _Extent: {getter: function(morph) { return morph.getExtent(); }},
        _Fill: {defaultValue: null, getter: function(morph) { return morph.getFill(); }},
        _BorderColor: {defaultValue: Color.rgb(0,0,0), getter: function(morph) { return morph.getBorderColor(); }},
        _BorderWidth: {defaultValue: 0, getter: function(morph) { return morph.getBorderWidth(); }},
        _BorderStyle: {defaultValue: 'solid', getter: function(morph) { return morph.getBorderStyle(); }},
        _BorderRadius: {defaultValue: 0, getter: function(morph) { return morph.getBorderRadius(); }},
        _Opacity: {defaultValue: 1, getter: function(morph) { return morph.getOpacity(); }},
        _Rotation: {defaultValue: 0},
        _Scale: {defaultValue: 1},
        // excludes:
        submorphs: {exclude: true},
        showsHalos: {exclude: true},
        scripts: {exclude: true},
        id: {exclude: true},
        shape: {exclude: true},
        registeredForMouseEvents: {exclude: true},
        partsBinMetaInfo: {exclude: true},
        eventHandler: {exclude: true},
        derivationIds: {exclude: true},
        partTests: {exclude: true},
        moved: {exclude: true},
        _renderContext: {exclude: true},
        _isRendered: {exclude: true},
        owner: {exclude: true},
        cachedBounds: {exclude: true},
        isBeingDragged: {exclude: true},
        halos: {exclude: true},
        priorExtent: {exclude: true},
        distanceToDragEvent: {exclude: true},
        prevScroll: {exclude: true},
        _PreviousBorderWidth: {exclude: true},
        attributeConnections: {exclude: true},
        isLockOwner: {exclude: true},
        isInLayoutCycle: {exclude: true},
        modalMorph: {exclude: true},
        currentMenu: {exclude: true},
        layout: {
            defaultValue: {},
            getter: function(morph, val) {
                // FIXME this code should go into the layouter!
                var result = {};
                if (!val) return result;
                if (Object.isString(val)) { return val; }
                    Properties.forEachOwn(val, function(name, prop) {
                    if (name === "layouter" && prop.constructor) {
                        result.type = prop.constructor.type;
                        result.borderSize = prop.borderSize;
                        result.spacing = prop.spacing;
                        return;
                    }
                    result[name] = prop;
                });
                return result;
            },
            recreate: function(instance, spec) {
                var layout = instance.layout = {};
                if (!spec.layout) return;
                var layouterKlassName = Object.isString(spec.layout) ? spec.layout : spec.layout.type;
                if (layouterKlassName) {
                    var layouterKlass = lively.lookup(layouterKlassName);
                    layout.layouter = new layouterKlass();
                    layout.layouter.spacing = spec.layout.spacing;
                    layout.layouter.borderSize = spec.layout.borderSize;
                }
                var excludes = ['type', 'borderSize', 'spacing']
                Properties.forEachOwn(spec.layout, function(name, prop) {
                    if (!excludes.include(name)) layout[name] = prop; });
            }
        }
    },

    getBuildSpecProperties: function(rawProps) {
        rawProps = rawProps || Object.mergePropertyInHierarchy(this, "buildSpecProperties");
        var props = Object.keys(rawProps).groupBy(function(key) {
                return rawProps[key].exclude ? 'excludes' : 'includes'; }),
            scripts = Functions.own(this).select(function(sel) {
                return this[sel].hasLivelyClosure; }, this),
            ownProps = Properties.own(this)
                       .withoutAll(props.excludes)
                       .reject(function(key) { return key.startsWith('$$'); });
        return props.includes.concat(ownProps).concat(scripts).uniq();
    },

    buildSpec: function() {
        return lively.persistence.SpecObject.fromMorph(this);
    },

    onFromBuildSpecCreated: Functions.Null
});

lively.morphic.List.addMethods(
'UI builder', {
    buildSpecProperties: {
        itemList: {defaultValue: []},
        selectedIndexes: {defaultValue: []}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.setList(this.itemList || []);
    }
});

lively.morphic.OldList.addMethods(
'UI builder', {
    buildSpecProperties: {
        itemList: {defaultValue: []}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.setList(this.itemList || []);
    }
});

lively.morphic.Text.addMethods(
'UI builder', {

    buildSpecProperties: {
        textString: {
            defaultValue: '',
            getter: function(morph, val) { return val || '' },
            recreate: function(instance, spec) {
                instance.textString = spec.textString;
                // important: emphasis after textString!
                if (spec.emphasis) instance.emphasizeRanges(spec.emphasis);
            }
        },
        emphasis: {
            getter: function(morph, val) {
                var styles = morph.getChunkStyles(),
                    ranges = morph.getChunkRanges();
                return ranges.collect(function(range, i) {
                        return [range[0], range[1], styles[i].asSpec()]; });
            },
            recreate: function(instance, spec) { /*see textString*/ }
        },
        isLabel: {defaultValue: false, recreate: function(instance, spec) { if (spec.isLabel) instance.beLabel(); }},
        _FontSize: {defaultValue: 10},
        fixedWidth: {defaultValue: false},
        fixedHeight: {defaultValue: false},
        allowsInput: {defaultValue: true},
        _FontFamily: {defaultValue: 'Arial'},
        _MaxTextWidth: {defaultValue: null},
        _MaxTextHeight: {defaultValue: null},
        textColor: {defaultValue: Color.rgb(0,0,0)},
        _Padding: {defaultValue: lively.Rectangle.inset(0)},
        _WhiteSpaceHandling: {defaultValue: "pre-wrap"},
        _MinTextWidth: {defaultValue: null},
        _MinTextHeight: {defaultValue: null},
        _WordBreak: {defaultValue: 'normal'},
        // excludes:
        cachedTextString: {exclude: true},
        savedTextString: {exclude: true},
        charsReplaced: {exclude: true},
        charsTyped: {exclude: true},
        lastFindLoc: {exclude: true},
        parseErrors: {exclude: true},
        textChunks: {exclude: true},
        priorSelectionRange: {exclude: true},
        previousSelection: {exclude: true},
        undoSelectionRange: {exclude: true}
    }

});

(function setupCodeEditor() {
    require('lively.ide.CodeEditor').toRun(function() {
        lively.morphic.CodeEditor.addMethods(
            'UI builder', {
                buildSpecProperties: {
                    textString: {defaultValue: '', getter: function(morph) { return morph.textString }},
                    theme: {
                        defaultValue: 'chrome',
                        getter: function(morph) { return morph.getTheme(); },
                        recreate: function(morph, spec) { morph.setTheme(spec.theme); }
                    },
                    textMode: {
                        defaultValue: 'text',
                        getter: function(morph) { return morph.getTextMode(); },
                        recreate: function(morph, spec) { morph.setTextMode(spec.textMode); }
                    },
                    // excludes
                    _isFocused: {exclude: true},
                    savedTextString: {exclude: true},
                    aceEditor: {exclude: true}
                }
            });
    });
})();

lively.morphic.Button.addMethods(
'UI builder', {
    buildSpecProperties: {
        submorphs: {
            exclude: true,
            filter: function(morph, submorphs) { return submorphs.without(morph.label); }
        },
        isActive: {defaultValue: true},
        label: {
            defaultValue: '',
            getter: function(morph, val) { return val.textString || ''; },
            recreate: function(instance, spec) { instance.ensureLabel(spec.label); }
        },
        style: {defaultValue: lively.morphic.Button.prototype.style}
    }
});

lively.morphic.Window.addMethods(
'UI builder', {
    buildSpecProperties: {
        submorphs: {
            exclude: true,
            filter: function(morph, submorphs) {
                var handles = [morph.reframeHandle, morph.bottomReframeHandle, morph.rightReframeHandle];
                return submorphs.withoutAll(handles).without(morph.titleBar);
            }
        },
        titleBar: {
            getter: function(morph, val) { return val ? val.getTitle() : ''; },
            recreate: function(instance, spec) { instance.titleBar = instance.makeTitleBar(spec.titleBar, instance.getExtent().x); }
        },
        grabbingEnabled: {defaultValue: false},
        reframeHandle: {exclude: true},
        bottomReframeHandle: {exclude: true},
        rightReframeHandle: {exclude: true},
        targetMorph: {exclude: true}
    },

    onFromBuildSpecCreated: function($super) {
        $super();
        this.makeReframeHandles();
        this.addMorph(this.titleBar);
        this.targetMorph = this.submorphs[0];
    }

});

lively.morphic.MorphList.addMethods(
'buildspec', {
    onFromBuildSpecCreated: function() {
        this.setList(this.itemList || []);
    },
    buildSpecProperties: {
        itemList: {}
    }
});

lively.morphic.Tree.addMethods(
'buildSpec', {
    buildSpecProperties: {
        childNodes: {exclude: true},
        icon: {exclude: true},
        isInLayoutCycle: false,
        item: {exclude: true},
        label: {exclude: true},
        node: {exclude: true}
    },

    onBuildSpecCreated: function(buildSpec) {
        if (this.item && Object.isFunction(this.item.serializeExpr)) {
            buildSpec.item = item;
        }
    },

    onFromBuildSpecCreated: function() {
        this.initializeLayout();
        this.disableDragging();
        this.setItem(this.item || {name: "tree with no item"});
    }
});
lively.morphic.Image.addMethods(
'buildSpec', {
    buildSpecProperties: {
        url: {getter: function(morph) { return morph.getImageURL(); }},
        useNativeExtent: {defaultValue: false}
    },

    onFromBuildSpecCreated: function() {
        this.setImageURL(this.url, this.useNativeExtent);
    }
});

Object.extend(lively.morphic.Morph, {
    fromSpec: function(object) {
        return lively.persistence.SpecObject.fromPlainObject(object).createMorph();
    },

    fromSpecString: function(string) {
        return lively.persistence.SpecObject.fromString(string).createMorph();
    }
});

lively.morphic.TabBar.addMethods(
'UI builder', {
    buildSpecProperties: {
        tabContainer: {exclude: true},
        tabs: {exclude: true}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.tabContainer = this.owner;
        this.tabs = this.submorphs.clone();
    }
});
lively.morphic.TabContainer.addMethods(
'UI builder', {
    buildSpecProperties: {
        tabBarStrategy: {
            getter: function(morph, val) { return morph.tabBarStrategy.constructor.type; },
            recreate: function(instance, spec) { instance.tabBarStrategy = new (lively.lookup(spec.tabBarStrategy))(); }
        }
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.tabBar = this.submorphs.detect(function(ea) { return ea.isTabBar; });
    }
});
lively.morphic.Tab.addMethods(
'UI builder', {
    buildSpecProperties: {
        label: {
            defaultValue: '',
            getter: function(morph, val) { return val.textString || ''; },
            exclude: true
        },
        pane: { // index of the pane in tabContainer.submorphs
            defaultValue: -1,
            getter: function(morph, val) {
                return morph.tabContainer.submorphs.indexOf(val); }
        },
        tabBar: {exclude: true},
        tabContainer: {exclude: true}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.tabContainer = this.ownerChain().detect(function(ea) { return ea.isTabContainer; });
        this.pane = this.tabContainer.submorphs[this.pane];
        this.tabBar = this.tabContainer.tabBar
        this.initializeLabel(this.label);
    }
});
lively.morphic.TabPane.addMethods(
'UI builder', {
    buildSpecProperties: {
        tab: { // index of the tab in tabBar.submorphs
            defaultValue: -1,
            getter: function(morph, val) { return morph.tabBar.submorphs.indexOf(val); }
        },
        tabContainer: {exclude: true},
        tabBar: {exclude: true}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.tabContainer = this.ownerChain().detect(function(ea) { return ea.isTabContainer; })
        this.tabBar = this.tabContainer.getTabBar();
        this.tab = this.tabBar.submorphs[this.tab];
    }
});
lively.morphic.Slider.addMethods(
'UI builder', {
    onFromBuildSpecCreated: function($super) {
        $super();
        this.sliderKnob = this.submorphs.detect(function(ea) { return ea.isSliderKnob; });
    }
});
lively.morphic.SliderKnob.addMethods(
'UI builder', {
    onFromBuildSpecCreated: function($super) {
        $super();
        this.slider = this.ownerChain().detect(function(ea) { return ea.isSlider; });
    }
});

lively.morphic.HorizontalDivider.addMethods(
'buildSpec', {
    buildSpecProperties: {
        scalingAbove: {defaultValue: []},
        scalingBelow: {defaultValue: []}
    }
});

}) // end of moduled of module
<commit_msg>buildspec: fixes for windows<commit_after>module('lively.persistence.BuildSpecMorphExtensions').requires("lively.morphic.Widgets", "lively.morphic.Serialization", "lively.morphic.AdditionalMorphs", "lively.morphic.Lists").toRun(function() {

lively.morphic.Morph.addMethods(
'UI builder', {

    buildSpecProperties: {
        name: {},
        doNotSerialize: {defaultValue: [], getter: function(morph, val) { if (!morph.hasOwnProperty("doNotSerialize")) return []; return val && val.reject(function(ea) { return !Object.isString(ea) || ea.startsWith('$$'); }) }},
        doNotCopyProperties: {defaultValue: [], getter: function(morph, val) { if (!morph.hasOwnProperty("doNotCopyProperties")) return []; return val && val.reject(function(ea) { return !Object.isString(ea) || ea.startsWith('$$'); }) }},
        grabbingEnabled: {defaultValue: undefined},
        draggingEnabled: {defaultValue: undefined},
        droppingEnabled: {defaultValue: undefined},
        halosEnabled: {defaultValue: true},
        _ClipMode: {defaultValue: 'visible'},
        _StyleSheet: {getter: function(morph, val) { return !val || Object.isString(val) ? val : val.getText(); }},
        _StyleClassNames: {},
        _Position: {defaultValue: lively.pt(0.0,0.0)},
        _Extent: {getter: function(morph) { return morph.getExtent(); }},
        _Fill: {defaultValue: null, getter: function(morph) { return morph.getFill(); }},
        _BorderColor: {defaultValue: Color.rgb(0,0,0), getter: function(morph) { return morph.getBorderColor(); }},
        _BorderWidth: {defaultValue: 0, getter: function(morph) { return morph.getBorderWidth(); }},
        _BorderStyle: {defaultValue: 'solid', getter: function(morph) { return morph.getBorderStyle(); }},
        _BorderRadius: {defaultValue: 0, getter: function(morph) { return morph.getBorderRadius(); }},
        _Opacity: {defaultValue: 1, getter: function(morph) { return morph.getOpacity(); }},
        _Rotation: {defaultValue: 0},
        _Scale: {defaultValue: 1},
        // excludes:
        submorphs: {exclude: true},
        showsHalos: {exclude: true},
        scripts: {exclude: true},
        id: {exclude: true},
        shape: {exclude: true},
        registeredForMouseEvents: {exclude: true},
        partsBinMetaInfo: {exclude: true},
        eventHandler: {exclude: true},
        derivationIds: {exclude: true},
        partTests: {exclude: true},
        moved: {exclude: true},
        _renderContext: {exclude: true},
        _isRendered: {exclude: true},
        owner: {exclude: true},
        cachedBounds: {exclude: true},
        isBeingDragged: {exclude: true},
        halos: {exclude: true},
        priorExtent: {exclude: true},
        distanceToDragEvent: {exclude: true},
        prevScroll: {exclude: true},
        _PreviousBorderWidth: {exclude: true},
        attributeConnections: {exclude: true},
        isLockOwner: {exclude: true},
        isInLayoutCycle: {exclude: true},
        modalMorph: {exclude: true},
        currentMenu: {exclude: true},
        layout: {
            defaultValue: {},
            getter: function(morph, val) {
                // FIXME this code should go into the layouter!
                var result = {};
                if (!val) return result;
                if (Object.isString(val)) { return val; }
                    Properties.forEachOwn(val, function(name, prop) {
                    if (name === "layouter" && prop.constructor) {
                        result.type = prop.constructor.type;
                        result.borderSize = prop.borderSize;
                        result.spacing = prop.spacing;
                        return;
                    }
                    result[name] = prop;
                });
                return result;
            },
            recreate: function(instance, spec) {
                var layout = instance.layout = {};
                if (!spec.layout) return;
                var layouterKlassName = Object.isString(spec.layout) ? spec.layout : spec.layout.type;
                if (layouterKlassName) {
                    var layouterKlass = lively.lookup(layouterKlassName);
                    layout.layouter = new layouterKlass();
                    layout.layouter.spacing = spec.layout.spacing;
                    layout.layouter.borderSize = spec.layout.borderSize;
                }
                var excludes = ['type', 'borderSize', 'spacing']
                Properties.forEachOwn(spec.layout, function(name, prop) {
                    if (!excludes.include(name)) layout[name] = prop; });
            }
        }
    },

    getBuildSpecProperties: function(rawProps) {
        rawProps = rawProps || Object.mergePropertyInHierarchy(this, "buildSpecProperties");
        var props = Object.keys(rawProps).groupBy(function(key) {
                return rawProps[key].exclude ? 'excludes' : 'includes'; }),
            scripts = Functions.own(this).select(function(sel) {
                return this[sel].hasLivelyClosure; }, this),
            ownProps = Properties.own(this)
                       .withoutAll(props.excludes)
                       .reject(function(key) { return key.startsWith('$$'); });
        return props.includes.concat(ownProps).concat(scripts).uniq();
    },

    buildSpec: function() {
        return lively.persistence.SpecObject.fromMorph(this);
    },

    onFromBuildSpecCreated: Functions.Null
});

lively.morphic.List.addMethods(
'UI builder', {
    buildSpecProperties: {
        itemList: {defaultValue: []},
        selectedIndexes: {defaultValue: []}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.setList(this.itemList || []);
    }
});

lively.morphic.OldList.addMethods(
'UI builder', {
    buildSpecProperties: {
        itemList: {defaultValue: []}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.setList(this.itemList || []);
    }
});

lively.morphic.Text.addMethods(
'UI builder', {

    buildSpecProperties: {
        textString: {
            defaultValue: '',
            getter: function(morph, val) { return val || '' },
            recreate: function(instance, spec) {
                instance.textString = spec.textString;
                // important: emphasis after textString!
                if (spec.emphasis) instance.emphasizeRanges(spec.emphasis);
            }
        },
        emphasis: {
            getter: function(morph, val) {
                var styles = morph.getChunkStyles(),
                    ranges = morph.getChunkRanges();
                return ranges.collect(function(range, i) {
                        return [range[0], range[1], styles[i].asSpec()]; });
            },
            recreate: function(instance, spec) { /*see textString*/ }
        },
        isLabel: {defaultValue: false, recreate: function(instance, spec) { if (spec.isLabel) instance.beLabel(); }},
        _FontSize: {defaultValue: 10},
        fixedWidth: {defaultValue: false},
        fixedHeight: {defaultValue: false},
        allowsInput: {defaultValue: true},
        _FontFamily: {defaultValue: 'Arial'},
        _MaxTextWidth: {defaultValue: null},
        _MaxTextHeight: {defaultValue: null},
        textColor: {defaultValue: Color.rgb(0,0,0)},
        _Padding: {defaultValue: lively.Rectangle.inset(0)},
        _WhiteSpaceHandling: {defaultValue: "pre-wrap"},
        _MinTextWidth: {defaultValue: null},
        _MinTextHeight: {defaultValue: null},
        _WordBreak: {defaultValue: 'normal'},
        // excludes:
        cachedTextString: {exclude: true},
        savedTextString: {exclude: true},
        charsReplaced: {exclude: true},
        charsTyped: {exclude: true},
        lastFindLoc: {exclude: true},
        parseErrors: {exclude: true},
        textChunks: {exclude: true},
        priorSelectionRange: {exclude: true},
        previousSelection: {exclude: true},
        undoSelectionRange: {exclude: true}
    }

});

(function setupCodeEditor() {
    require('lively.ide.CodeEditor').toRun(function() {
        lively.morphic.CodeEditor.addMethods(
            'UI builder', {
                buildSpecProperties: {
                    textString: {defaultValue: '', getter: function(morph) { return morph.textString }},
                    theme: {
                        defaultValue: 'chrome',
                        getter: function(morph) { return morph.getTheme(); },
                        recreate: function(morph, spec) { morph.setTheme(spec.theme); }
                    },
                    textMode: {
                        defaultValue: 'text',
                        getter: function(morph) { return morph.getTextMode(); },
                        recreate: function(morph, spec) { morph.setTextMode(spec.textMode); }
                    },
                    // excludes
                    _isFocused: {exclude: true},
                    savedTextString: {exclude: true},
                    aceEditor: {exclude: true}
                }
            });
    });
})();

lively.morphic.Button.addMethods(
'UI builder', {
    buildSpecProperties: {
        submorphs: {
            exclude: true,
            filter: function(morph, submorphs) { return submorphs.without(morph.label); }
        },
        isActive: {defaultValue: true},
        label: {
            defaultValue: '',
            getter: function(morph, val) { return val.textString || ''; },
            recreate: function(instance, spec) { instance.ensureLabel(spec.label); }
        },
        style: {defaultValue: lively.morphic.Button.prototype.style}
    }
});

lively.morphic.Window.addMethods(
'UI builder', {
    buildSpecProperties: {
        submorphs: {
            exclude: true,
            filter: function(morph, submorphs) {
                var handles = [morph.reframeHandle, morph.bottomReframeHandle, morph.rightReframeHandle];
                return submorphs.withoutAll(handles).without(morph.titleBar);
            }
        },
        titleBar: {
            getter: function(morph, val) { return val ? val.getTitle() : ''; },
            recreate: function(instance, spec) { instance.titleBar = instance.makeTitleBar(spec.titleBar, instance.getExtent().x); }
        },
        grabbingEnabled: {defaultValue: false},
        reframeHandle: {exclude: true},
        bottomReframeHandle: {exclude: true},
        rightReframeHandle: {exclude: true},
        targetMorph: {exclude: true},
        cameForward: {exlcude: true},
        collapsedExtent: {exlcude: true},
        collapsedTransform: {exlcude: true},
        expandedExtent: {exlcude: true},
        expandedTransform: {exlcude: true},
        highlighted: {exlcude: true},
        ignoreEventsOnExpand: {exlcude: true},
        contentOffset: {exlcude: true}
    },

    onFromBuildSpecCreated: function($super) {
        $super();
        this.makeReframeHandles();
        this.addMorph(this.titleBar);
        this.targetMorph = this.submorphs[0];
    }

});

lively.morphic.MorphList.addMethods(
'buildspec', {
    onFromBuildSpecCreated: function() {
        this.setList(this.itemList || []);
    },
    buildSpecProperties: {
        itemList: {}
    }
});

lively.morphic.Tree.addMethods(
'buildSpec', {
    buildSpecProperties: {
        childNodes: {exclude: true},
        icon: {exclude: true},
        isInLayoutCycle: false,
        item: {exclude: true},
        label: {exclude: true},
        node: {exclude: true}
    },

    onBuildSpecCreated: function(buildSpec) {
        if (this.item && Object.isFunction(this.item.serializeExpr)) {
            buildSpec.item = item;
        }
    },

    onFromBuildSpecCreated: function() {
        this.initializeLayout();
        this.disableDragging();
        this.setItem(this.item || {name: "tree with no item"});
    }
});
lively.morphic.Image.addMethods(
'buildSpec', {
    buildSpecProperties: {
        url: {getter: function(morph) { return morph.getImageURL(); }},
        useNativeExtent: {defaultValue: false}
    },

    onFromBuildSpecCreated: function() {
        this.setImageURL(this.url, this.useNativeExtent);
    }
});

Object.extend(lively.morphic.Morph, {
    fromSpec: function(object) {
        return lively.persistence.SpecObject.fromPlainObject(object).createMorph();
    },

    fromSpecString: function(string) {
        return lively.persistence.SpecObject.fromString(string).createMorph();
    }
});

lively.morphic.TabBar.addMethods(
'UI builder', {
    buildSpecProperties: {
        tabContainer: {exclude: true},
        tabs: {exclude: true}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.tabContainer = this.owner;
        this.tabs = this.submorphs.clone();
    }
});
lively.morphic.TabContainer.addMethods(
'UI builder', {
    buildSpecProperties: {
        tabBarStrategy: {
            getter: function(morph, val) { return morph.tabBarStrategy.constructor.type; },
            recreate: function(instance, spec) { instance.tabBarStrategy = new (lively.lookup(spec.tabBarStrategy))(); }
        }
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.tabBar = this.submorphs.detect(function(ea) { return ea.isTabBar; });
    }
});
lively.morphic.Tab.addMethods(
'UI builder', {
    buildSpecProperties: {
        label: {
            defaultValue: '',
            getter: function(morph, val) { return val.textString || ''; },
            exclude: true
        },
        pane: { // index of the pane in tabContainer.submorphs
            defaultValue: -1,
            getter: function(morph, val) {
                return morph.tabContainer.submorphs.indexOf(val); }
        },
        tabBar: {exclude: true},
        tabContainer: {exclude: true}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.tabContainer = this.ownerChain().detect(function(ea) { return ea.isTabContainer; });
        this.pane = this.tabContainer.submorphs[this.pane];
        this.tabBar = this.tabContainer.tabBar
        this.initializeLabel(this.label);
    }
});
lively.morphic.TabPane.addMethods(
'UI builder', {
    buildSpecProperties: {
        tab: { // index of the tab in tabBar.submorphs
            defaultValue: -1,
            getter: function(morph, val) { return morph.tabBar.submorphs.indexOf(val); }
        },
        tabContainer: {exclude: true},
        tabBar: {exclude: true}
    },
    onFromBuildSpecCreated: function($super) {
        $super();
        this.tabContainer = this.ownerChain().detect(function(ea) { return ea.isTabContainer; })
        this.tabBar = this.tabContainer.getTabBar();
        this.tab = this.tabBar.submorphs[this.tab];
    }
});
lively.morphic.Slider.addMethods(
'UI builder', {
    onFromBuildSpecCreated: function($super) {
        $super();
        this.sliderKnob = this.submorphs.detect(function(ea) { return ea.isSliderKnob; });
    }
});
lively.morphic.SliderKnob.addMethods(
'UI builder', {
    onFromBuildSpecCreated: function($super) {
        $super();
        this.slider = this.ownerChain().detect(function(ea) { return ea.isSlider; });
    }
});

lively.morphic.HorizontalDivider.addMethods(
'buildSpec', {
    buildSpecProperties: {
        scalingAbove: {defaultValue: []},
        scalingBelow: {defaultValue: []}
    }
});

}) // end of moduled of module
<|endoftext|>


<commit_before>"use strict";

const _                 = require("lodash");
const fs                = require("fs");
const ruleSetValidator  = require('./ruleSetValidator');
const ruleSetNormalizer = require('./ruleSetNormalizer');

const readRules = _.memoize(
    pRuleSetFile => {
        let lRetval = JSON.parse(fs.readFileSync(pRuleSetFile, 'utf8'));

        ruleSetValidator(lRetval);
        return ruleSetNormalizer(lRetval);
    }
);

function propertyEquals(pTo, pRule, pProperty) {
    return pRule.to.hasOwnProperty(pProperty)
        ? pTo[pProperty] === pRule.to[pProperty]
        : true;
}

function matchRule(pFrom, pTo) {
    return pRule =>
        (!Boolean(pRule.from.path) || pFrom.match(pRule.from.path)) &&
        (!Boolean(pRule.from.pathNot) || !(pFrom.match(pRule.from.pathNot))) &&
        (!Boolean(pRule.to.path) || pTo.resolved.match(pRule.to.path)) &&
        (!Boolean(pRule.to.pathNot) || !(pTo.resolved.match(pRule.to.pathNot))) &&
        propertyEquals(pTo, pRule, "coreModule") &&
        propertyEquals(pTo, pRule, "couldNotResolve");
}

function validateAgainstRules(pRuleSet, pFrom, pTo) {
    let lMatchedRule = {};

    if (pRuleSet.hasOwnProperty("allowed")){
        lMatchedRule = pRuleSet.allowed.find(matchRule(pFrom, pTo));
        if (!Boolean(lMatchedRule)){
            return {
                valid: false,
                rule: {
                    severity: "warn",
                    name: "not-in-allowed"
                }
            };
        }
    }
    if (pRuleSet.hasOwnProperty("forbidden")){
        lMatchedRule = pRuleSet.forbidden.find(matchRule(pFrom, pTo));
        if (Boolean(lMatchedRule)){
            return {
                valid: false,
                rule: {
                    severity : lMatchedRule.severity,
                    name     : lMatchedRule.name
                }
            };
        }
    }
    return {valid:true};
}

function validate (pValidate, pRuleSetFile, pFrom, pTo) {
    if (!pValidate) {
        return {valid:true};
    }
    return validateAgainstRules(readRules(pRuleSetFile), pFrom, pTo);
}

exports.validate = validate;

/* ignore security/detect-object-injection because:
   - we only use it from within the module with two fixed values
   - the propertyEquals function is not exposed externaly
 */
/* eslint security/detect-object-injection: 0 */
<commit_msg>:nail_care:<commit_after>"use strict";

const _                 = require("lodash");
const fs                = require("fs");
const ruleSetValidator  = require('./ruleSetValidator');
const ruleSetNormalizer = require('./ruleSetNormalizer');

const readRules = _.memoize(
    pRuleSetFile => {
        let lRetval = JSON.parse(fs.readFileSync(pRuleSetFile, 'utf8'));

        ruleSetValidator(lRetval);
        return ruleSetNormalizer(lRetval);
    }
);

function propertyEquals(pTo, pRule, pProperty) {
    return pRule.to.hasOwnProperty(pProperty)
        ? pTo[pProperty] === pRule.to[pProperty]
        : true;
}

function matchRule(pFrom, pTo) {
    return pRule =>
        (!Boolean(pRule.from.path)    ||   pFrom.match(pRule.from.path)) &&
        (!Boolean(pRule.from.pathNot) || !(pFrom.match(pRule.from.pathNot))) &&
        (!Boolean(pRule.to.path)      ||   pTo.resolved.match(pRule.to.path)) &&
        (!Boolean(pRule.to.pathNot)   || !(pTo.resolved.match(pRule.to.pathNot))) &&
        propertyEquals(pTo, pRule, "coreModule") &&
        propertyEquals(pTo, pRule, "couldNotResolve");
}

function validateAgainstRules(pRuleSet, pFrom, pTo) {
    let lMatchedRule = {};

    if (pRuleSet.hasOwnProperty("allowed")){
        lMatchedRule = pRuleSet.allowed.find(matchRule(pFrom, pTo));
        if (!Boolean(lMatchedRule)){
            return {
                valid: false,
                rule: {
                    severity: "warn",
                    name: "not-in-allowed"
                }
            };
        }
    }
    if (pRuleSet.hasOwnProperty("forbidden")){
        lMatchedRule = pRuleSet.forbidden.find(matchRule(pFrom, pTo));
        if (Boolean(lMatchedRule)){
            return {
                valid: false,
                rule: {
                    severity : lMatchedRule.severity,
                    name     : lMatchedRule.name
                }
            };
        }
    }
    return {valid:true};
}

function validate (pValidate, pRuleSetFile, pFrom, pTo) {
    if (!pValidate) {
        return {valid:true};
    }
    return validateAgainstRules(readRules(pRuleSetFile), pFrom, pTo);
}

exports.validate = validate;

/* ignore security/detect-object-injection because:
   - we only use it from within the module with two fixed values
   - the propertyEquals function is not exposed externaly
 */
/* eslint security/detect-object-injection: 0 */
<|endoftext|>


<commit_before>/**
 * @file Contains mobilsøg specific middleware.
 */
'use strict';

import {has} from 'lodash';

function getKommuneConf(host, config) {
  let kommune = host.split('.')[0];
  kommune = has(config, kommune) ? kommune : process.env.CONFIG_NAME || 'aarhus'; // eslint-disable-line no-process-env

  let conf = config[kommune];

  return {
    kommune: kommune,
    bodyclass: kommune + '-kommune',
    config: conf,
    libraryId: conf.agency
  }
}

function libraryStyleWare(req, res, next) {
  let libdata = res.locals.libdata = getKommuneConf(req.get('host'), req.app.get('Configuration'));
  res.locals.title = libdata.config.applicationTitle;
  next();
}

function librarySocketWare(config, _socket, next) {
  _socket.libdata = getKommuneConf(_socket.handshake.headers.host, config);
  next();
}

const mobilsoegmiddleware = {
  libraryStyleWare: libraryStyleWare,
  librarySocketWare: librarySocketWare
};
export default mobilsoegmiddleware;
<commit_msg>us136: fix lint<commit_after>/**
 * @file Contains mobilsøg specific middleware.
 */
'use strict';

import {has} from 'lodash';

function getKommuneConf(host, config) {
  let kommune = host.split('.')[0];
  kommune = has(config, kommune) ? kommune : process.env.CONFIG_NAME || 'aarhus'; // eslint-disable-line no-process-env

  let conf = config[kommune];

  return {
    kommune: kommune,
    bodyclass: kommune + '-kommune',
    config: conf,
    libraryId: conf.agency
  };
}

function libraryStyleWare(req, res, next) {
  let libdata = res.locals.libdata = getKommuneConf(req.get('host'), req.app.get('Configuration'));
  res.locals.title = libdata.config.applicationTitle;
  next();
}

function librarySocketWare(config, _socket, next) {
  _socket.libdata = getKommuneConf(_socket.handshake.headers.host, config);
  next();
}

const mobilsoegmiddleware = {
  libraryStyleWare: libraryStyleWare,
  librarySocketWare: librarySocketWare
};
export default mobilsoegmiddleware;
<|endoftext|>


<commit_before>/* ------------------------------------------------------------------------
Class: freezeHeader
Use:freeze header row in html table
Example 1:  $('#tableid').freezeHeader();
Example 2:  $("#tableid").freezeHeader({ 'height': '300px' });
Author: Laerte Mercier Junior
Version: 1.0.3
-------------------------------------------------------------------------*/
(function ($) {
    $.fn.freezeHeader = function (params) {
        var copiedHeader = false;
        var idObj = this.selector.replace('#', '');
        var container;
        var grid;
        var conteudoHeader;
        var openDivScroll = '';
        var closeDivScroll = '';

        if (params && params.height !== undefined) {
            divScroll = '
';
            closeDivScroll = '
';
        }

        grid = $('table[id$="' + idObj + '"]');
        conteudoHeader = grid.find('thead');

        if (params && params.height !== undefined) {
            if ($('#hdScroll' + idObj).length == 0) {
                grid.wrapAll(divScroll);
            }
        }

        var obj = params && params.height !== undefined
           ? $('#hdScroll' + idObj)
           : $(window);

        if ($('#hd' + idObj).length == 0) {
            grid.before('

');
        }

        obj.scroll(function () { freezeHeader(); })

        function freezeHeader() {

            if ($('table[id$="' + idObj + '"]').length > 0) {

                container = $('#hd' + idObj);
                if (conteudoHeader.offset() != null) {
                    if (limiteAlcancado(params)) {
                        if (!copiedHeader) {
                            cloneHeaderRow(grid);
                            copiedHeader = true;
                        }
                    }
                    else {

                        if (($(document).scrollTop() > conteudoHeader.offset().top)) {
                            container.css("position", "absolute");
                            container.css("top", (grid.find("tr:last").offset().top - conteudoHeader.height()) + "px");
                        }
                        else {
                            container.css("visibility", "hidden");
                            container.css("top", "0px");
                            container.width(0);
                        }

                        copiedHeader = false;

                    }
                }
            }
        }

        function limiteAlcancado(params) {
            if (params && params.height !== undefined) {
                return (conteudoHeader.offset().top <= obj.offset().top);
            }
            else {
                return ($(document).scrollTop() > conteudoHeader.offset().top && $(document).scrollTop() < (grid.height() - conteudoHeader.height() - grid.find("tr:last").height()) + conteudoHeader.offset().top);
            }
        }

        function cloneHeaderRow() {
            container.html('');
            container.val('');
            var tabela = $('

');
            var atributos = grid.prop("attributes");

            $.each(atributos, function () {

                if (this.name != "id") {
                    tabela.attr(this.name, this.value);
                }
            });

            tabela.append('
' + conteudoHeader.html() + '
');

            container.append(tabela);
            container.width(conteudoHeader.width());
            container.height(conteudoHeader.height);
            container.find('th').each(function (index) {
                var cellWidth = grid.find('th').eq(index).width();
                $(this).css('width', cellWidth);
            });

            container.css("visibility", "visible");

            if (params && params.height !== undefined) {
                container.css("top", obj.offset().top + "px");
                container.css("position", "absolute");
            } else {
                container.css("top", "0px");
                container.css("position", "fixed");
            }
        }
    };
})(jQuery);
<commit_msg>adicionada nova forma de uso<commit_after>/* ------------------------------------------------------------------------
Class: freezeHeader
Use:freeze header row in html table
Example 1:  $('#tableid').freezeHeader();
Example 2:  $("#tableid").freezeHeader({ 'height': '300px' });
Example 3:  $("table").freezeHeader();
Example 4:  $(".table2").freezeHeader();
Author: Laerte Mercier Junior
Version: 1.0.4
-------------------------------------------------------------------------*/
(function ($) {
    var TABLE_ID = 0;
    $.fn.freezeHeader = function (params) {

        var copiedHeader = false;

        function freezeHeader(elem) {
            var idObj = elem.attr('id') || ('tbl-' + (++TABLE_ID));
            if (elem.length > 0 && elem[0].tagName.toLowerCase() == "table") {

                var obj = {
                    id: idObj,
                    grid: elem,
                    container: null,
                    header: null,
                    divScroll: null,
                    openDivScroll: null,
                    closeDivScroll: null,
                    scroller: null
                };

                if (params && params.height !== undefined) {
                    obj.divScroll = '
';
                    obj.closeDivScroll = '
';
                }

                obj.header = obj.grid.find('thead');

                if (params && params.height !== undefined) {
                    if ($('#hdScroll' + obj.id).length == 0) {
                        obj.grid.wrapAll(obj.divScroll);
                    }
                }

                obj.scroller = params && params.height !== undefined
				   ? $('#hdScroll' + obj.id)
				   : $(window);

                obj.scroller.on('scroll', function () {

                    if ($('#hd' + obj.id).length == 0) {
                        obj.grid.before('

');
                    }

                    obj.container = $('#hd' + obj.id);

                    if (obj.header.offset() != null) {
                        if (limiteAlcancado(obj, params)) {
                            if (!copiedHeader) {
                                cloneHeaderRow(obj);
                                copiedHeader = true;
                            }
                        }
                        else {

                            if (($(document).scrollTop() > obj.header.offset().top)) {
                                obj.container.css("position", "absolute");
                                obj.container.css("top", (obj.grid.find("tr:last").offset().top - obj.header.height()) + "px");
                            }
                            else {
                                obj.container.css("visibility", "hidden");
                                obj.container.css("top", "0px");
                                obj.container.width(0);
                            }
                            copiedHeader = false;
                        }
                    }

                });
            }
        }

        function limiteAlcancado(obj, params) {
            if (params && params.height !== undefined) {
                return (obj.header.offset().top <= obj.scroller.offset().top);
            }
            else {
                return ($(document).scrollTop() > obj.header.offset().top && $(document).scrollTop() < (obj.grid.height() - obj.header.height() - obj.grid.find("tr:last").height()) + obj.header.offset().top);
            }
        }

        function cloneHeaderRow(obj) {
            obj.container.html('');
            obj.container.val('');
            var tabela = $('

');
            var atributos = obj.grid.prop("attributes");

            $.each(atributos, function () {
                if (this.name != "id") {
                    tabela.attr(this.name, this.value);
                }
            });

            tabela.append('
' + obj.header.html() + '
');

            obj.container.append(tabela);
            obj.container.width(obj.header.width());
            obj.container.height(obj.header.height);
            obj.container.find('th').each(function (index) {
                var cellWidth = obj.grid.find('th').eq(index).width();
                $(this).css('width', cellWidth);
            });

            obj.container.css("visibility", "visible");

            if (params && params.height !== undefined) {
                obj.container.css("top", obj.scroller.offset().top + "px");
                obj.container.css("position", "absolute");
            } else {
                obj.container.css("top", "0px");
                obj.container.css("position", "fixed");
            }
        }

        return this.each(function (i, e) {
            freezeHeader($(e));
        });

    };
})(jQuery);
<|endoftext|>


<commit_before>var url = require('url'),
	https = require('https'),
	assert = require('assert');

exports.api = function(login, password, config) {
	"use strict";
	assert.equal(typeof(login), 'string', "argument 'login' must be a string");
	assert.equal(typeof(password), 'string', "argument 'password' must be a string");

	var SDK_VERSION = "1.1";

	// var LogAs types
	var loginAsTypes = {
		user: 'user.login',
		account: 'account.hash'
	}

	// allow api url to be changed
	this.apiUrl = "https://api.callr.com/json-rpc/v1.1/";

	// Callback class
	var Callback = function() {
		this.success = false;
		this.error = false;
	};

	// Set login As options
	this.setLoginAs = function (type, target) {
		if(config === undefined) config = {};
		config.loginas = {
			type: type,
			target: target
		}
	}

	// Send a request to THECALLR webservice
	this.call = function(method) {
		assert.equal(typeof(method), 'string', "argument 'method' must be a string");

		var args = Array.prototype.slice.call(arguments);
		return this.send(method, args.slice(1, args.length));
	};

	// Send a request to THECALLR webservice
	this.send = function(method, params, id) {
		assert.equal(typeof(method), 'string', "argument 'method' must be a string");
		assert.ok(params instanceof(Array), "argument 'params' must be an array");

		var json = JSON.stringify({
			id: id === undefined || isNaN(parseInt(id)) ? Math.floor(Math.random() * (999 - 100)) + 100 : id,
			jsonrpc: "2.0",
			method: method,
			params: params instanceof Array ? params : []
		});

		var options = url.parse(this.apiUrl);
		options.port = 443;
		options.method = "POST";
		options.auth = login + ':' + password;
		options.headers = {
			"Content-Type": "application/json-rpc; charset=utf-8",
			"User-Agent": "sdk=NODE; sdk-version="+SDK_VERSION+"; lang-version="+process.version+"; platform="+process.platform,
			"Content-Length": Buffer.byteLength(json)
		};

		// Login As support
		if (config && config.hasOwnProperty('loginas')) {
			assert.equal(typeof (config.loginas.type), 'string', "loginas.type must be a string");
			assert.ok(config.loginas.type.toLowerCase() in loginAsTypes, `loginas type must be one of "${Object.keys(loginAsTypes)}"`);
			assert.equal(typeof (config.loginas.target), 'string', "loginas.target must be a string")

			options.headers['CALLR-Login-As'] = `${loginAsTypes[config.loginas.type.toLowerCase()]} ${config.loginas.target}`;
		}

		// Proxy agent support
		if (config && config.hasOwnProperty('proxyAgent')) {
			options.agent = config.proxyAgent;
		}

		this.callback = new Callback();

		// Annonymous Closure to keep data untouched on successive call
		(function(options, json, callback) {
			// make new request
			var req = https.request(options, function(res) {
				var buf = "";
				if (res.statusCode != 200) {
					doCallback(callback.error, error("HTTP_CODE_ERROR", -1, {
						http_code: res.statusCode
					}));
				}
				res.on('data', function(data) {
					buf += data;
				});
				res.on('end', function() {
					parseData(buf.toString(), callback);
				});
			});

			req.on('error', function(e) {
				doCallback(callback.error, error("HTTP_EXCEPTION", -1, {
					exception: e
				}));
			}).on('end', function() {
				console.log('request end');
			}).end(json);
		})(options, json, this.callback);

		return this;
	};

	// set success callback
	this.success = function(cb) {
		this.callback.success = cb;
		return this;
	};

	// set error callback
	this.error = function(cb) {
		this.callback.error = cb;
		return this;
	};

	// Response analysis
	function parseData(json, callback) {
		try {
			var data = JSON.parse(json);
			if (data && data.hasOwnProperty('result'))
				doCallback(callback.success, data.result);
			else if (data && data.hasOwnProperty('error') && data.error)
				doCallback(callback.error, error(data.error.message, data.error.code, null));
			else
				doCallback(callback.error, error("INVALID_RESPONSE", -1, {
					responses: json.toString()
				}));
		}
		catch (e) {
			doCallback(callback.error, error("INVALID_RESPONSE", -1, {
				exception: e,
				response: json.toString()
			}));
		}
	}

	function doCallback(callback, result) {
		if (typeof(callback) == 'function')
			callback(result);
	}

	function error(msg, code, data) {
		var err = new Error(msg);
		err.code = code;
		err.data = data;
		return err;
	}
};
<commit_msg>feat: add api/session token login mechanism<commit_after>var url = require('url'),
	https = require('https'),
	assert = require('assert');

exports.loginPasswordAuth = function(login, password){
	assert.equal(typeof(login), 'string', "argument 'login' must be a string");
	assert.equal(typeof(password), 'string', "argument 'password' must be a string");
	let credentials = new Buffer(`${login}:${password}`);
	return `Basic ${credentials.toString('base64')}`;
}

exports.apiKeyAuth = function(apiKey){
	assert.equal(typeof(apiKey), 'string', "argument 'apiKey' must be a string");
	assert.equal(apiKey.length, 100, "incorrect api key length");
	return `Api-Key ${apiKey}`;
}

exports.userSessionAuth = function(sessionKey){
	assert.equal(typeof(sessionKey), 'string', "argument 'sessionKey' must be a string");
	assert.equal(sessionKey.length, 100, "incorrect api key length");
	return `Session ${sessionKey}`;
}

exports.api = function(authorization, config) {
	"use strict";

	var SDK_VERSION = "1.2";

	// var LogAs types
	var loginAsTypes = {
		user: 'user.login',
		account: 'account.hash'
	}

	// allow api url to be changed
	this.apiUrl = "https://api.callr.com/json-rpc/v1.1/";

	// Callback class
	var Callback = function() {
		this.success = false;
		this.error = false;
	};

	// Set login As options
	this.setLoginAs = function (type, target) {
		if(config === undefined) config = {};
		config.loginas = {
			type: type,
			target: target
		}
	}

	// Send a request to THECALLR webservice
	this.call = function(method) {
		assert.equal(typeof(method), 'string', "argument 'method' must be a string");

		var args = Array.prototype.slice.call(arguments);
		return this.send(method, args.slice(1, args.length));
	};

	// Send a request to THECALLR webservice
	this.send = function(method, params, id) {
		assert.equal(typeof(method), 'string', "argument 'method' must be a string");
		assert.ok(params instanceof(Array), "argument 'params' must be an array");

		var json = JSON.stringify({
			id: id === undefined || isNaN(parseInt(id)) ? Math.floor(Math.random() * (999 - 100)) + 100 : id,
			jsonrpc: "2.0",
			method: method,
			params: params instanceof Array ? params : []
		});

		var options = url.parse(this.apiUrl);
		options.port = 443;
		options.method = "POST";
		options.headers = {
			"Content-Type": "application/json-rpc; charset=utf-8",
			"User-Agent": "sdk=NODE; sdk-version="+SDK_VERSION+"; lang-version="+process.version+"; platform="+process.platform,
			"Content-Length": Buffer.byteLength(json),
			"Authorization": authorization
		};

		// Login As support
		if (config && config.hasOwnProperty('loginas')) {
			assert.equal(typeof (config.loginas.type), 'string', "loginas.type must be a string");
			assert.ok(config.loginas.type.toLowerCase() in loginAsTypes, `loginas type must be one of "${Object.keys(loginAsTypes)}"`);
			assert.equal(typeof (config.loginas.target), 'string', "loginas.target must be a string")

			options.headers['CALLR-Login-As'] = `${loginAsTypes[config.loginas.type.toLowerCase()]} ${config.loginas.target}`;
		}

		// Proxy agent support
		if (config && config.hasOwnProperty('proxyAgent')) {
			options.agent = config.proxyAgent;
		}

		this.callback = new Callback();

		// Annonymous Closure to keep data untouched on successive call
		(function(options, json, callback) {
			// make new request
			var req = https.request(options, function(res) {
				var buf = "";
				if (res.statusCode != 200) {
					doCallback(callback.error, error("HTTP_CODE_ERROR", -1, {
						http_code: res.statusCode
					}));
				}
				res.on('data', function(data) {
					buf += data;
				});
				res.on('end', function() {
					parseData(buf.toString(), callback);
				});
			});

			req.on('error', function(e) {
				doCallback(callback.error, error("HTTP_EXCEPTION", -1, {
					exception: e
				}));
			}).on('end', function() {
				console.log('request end');
			}).end(json);
		})(options, json, this.callback);

		return this;
	};

	// set success callback
	this.success = function(cb) {
		this.callback.success = cb;
		return this;
	};

	// set error callback
	this.error = function(cb) {
		this.callback.error = cb;
		return this;
	};

	// Response analysis
	function parseData(json, callback) {
		try {
			var data = JSON.parse(json);
			if (data && data.hasOwnProperty('result'))
				doCallback(callback.success, data.result);
			else if (data && data.hasOwnProperty('error') && data.error)
				doCallback(callback.error, error(data.error.message, data.error.code, null));
			else
				doCallback(callback.error, error("INVALID_RESPONSE", -1, {
					responses: json.toString()
				}));
		}
		catch (e) {
			doCallback(callback.error, error("INVALID_RESPONSE", -1, {
				exception: e,
				response: json.toString()
			}));
		}
	}

	function doCallback(callback, result) {
		if (typeof(callback) == 'function')
			callback(result);
	}

	function error(msg, code, data) {
		var err = new Error(msg);
		err.code = code;
		err.data = data;
		return err;
	}
};
<|endoftext|>


<commit_before>var alexa = require("alexa-app");
var search = require('youtube-search');
var fs = require('fs');
var request = require('request');

var app = new alexa.app("youtube");

var searchOpts = {
    maxResults: 1,
    type: 'video',
    key: process.env.YOUTUBE_API_KEY
};

var lastSearch;

app.pre = function(req, response, type) {
    if (req.applicationId !== process.env.ALEXA_APPLICATION_ID &&
        req.sessionDetails.application.applicationId !== process.env.ALEXA_APPLICATION_ID) {
        response.fail("Invalid application");
    }
};

app.intent("GetVideoIntent", {
        "slots": {
            "VideoQuery": "VIDEOS",
        },
        "utterances": [
            "search for {-|VideoQuery}",
            "find {-|VideoQuery}",
            "play {-|VideoQuery}",
            "start playing {-|VideoQuery}",
            "put on {-|VideoQuery}"
        ]
    },
    function(req, response) {
        var query = req.slot("VideoQuery");

        console.log('Searching ... ' + query);

        search(query, searchOpts, function(err, results) {
            if (err) {
                response.fail(err.message);
            } else if (results.length !== 1) {
                response.say('I could not complete your request at this moment.').send();
            } else {
                var metadata = results[0];
                if (metadata.id === undefined) {
                    response.say(query + ' did not return any results on YouTube.').send();
                } else {
                    response.say('I found a relevant video called ' + metadata.title + '.');

                    console.log('Found ... ' + metadata.title);

                    var id = metadata.id;
                    var externalDownload = 'https://dmhacker-youtube.herokuapp.com/alexa/' + id;

                    request(externalDownload, function(err, res, body) {
                        console.log('Processed.');

                        if (err) {
                            console.log(err);
                            console.log(body);
                            response.fail(err.message);
                        } else {
                            recursive_check(id, 1000, function(err) {
                                if (err) {
                                    response.fail(err.message);
                                }
                                else {
                                    lastSearch = JSON.parse(body).link;
                                    var stream = {
                                        'url': lastSearch,
                                        'token': metadata.id,
                                        'offsetInMilliseconds': 0
                                    };
                                    response.audioPlayerPlayStream('ENQUEUE', stream);
                                    response.card({
                                        'type': 'Simple',
                                        'title': 'Search for "' + query + '"',
                                        'content': 'Alexa found "' + metadata.title + '" at ' + metadata.link + '.'
                                    });
                                    response.send();
                                }
                            });
                        }
                    });
                }
            }
        });

        return false;
    }
);

function recursive_check(id, delay, callback) {
    var linkCheck = 'https://dmhacker-youtube.herokuapp.com/alexa-check/' + id;
    request(linkCheck, function (err, res, body) {
        if (err) {
            callback(err);
        }
        else {
            var metadata = JSON.parse(body).metadata;
            if (!metadata) {
                callback(err);
            }
            else {
                if (metadata.downloaded) {
                    callback(null);
                }
                else {
                    setTimeout(function () {
                        recursive_check(id, delay, callback);
                    }, delay);
                }
            }
        }
    });
}

app.audioPlayer("PlaybackStarted", function(request, response) {
    console.log('Now playing audio clip ...');
    console.dir(request);
});

app.intent("AMAZON.PauseIntent", {}, function(req, response) {
    response.audioPlayerStop();
});

app.intent("AMAZON.ResumeIntent", {}, function(req, response) {
    if (lastSearch === undefined) {
        response.say('You were not playing any video previously.');
    } else {
        response.audioPlayerPlayStream('ENQUEUE', {
            'url': lastSearch,
            'streamFormat': 'AUDIO_MPEG',
            'token': constants.token,
            'expectedPreviousToken': constants.expectedPreviousToken
        });
    }
});

app.intent("AMAZON.StopIntent", {}, function(req, response) {
    lastSearch = undefined;
    response.audioPlayerStop();
    response.audioPlayerClearQueue();
});

exports.handler = app.lambda();
<commit_msg>Undefined<commit_after>var alexa = require("alexa-app");
var search = require('youtube-search');
var fs = require('fs');
var request = require('request');

var app = new alexa.app("youtube");

var searchOpts = {
    maxResults: 1,
    type: 'video',
    key: process.env.YOUTUBE_API_KEY
};

var lastSearch;

app.pre = function(req, response, type) {
    if (req.sessionDetails.application.applicationId !== process.env.ALEXA_APPLICATION_ID) {
        response.fail("Invalid application");
    }
};

app.intent("GetVideoIntent", {
        "slots": {
            "VideoQuery": "VIDEOS",
        },
        "utterances": [
            "search for {-|VideoQuery}",
            "find {-|VideoQuery}",
            "play {-|VideoQuery}",
            "start playing {-|VideoQuery}",
            "put on {-|VideoQuery}"
        ]
    },
    function(req, response) {
        var query = req.slot("VideoQuery");

        console.log('Searching ... ' + query);

        search(query, searchOpts, function(err, results) {
            if (err) {
                response.fail(err.message);
            } else if (results.length !== 1) {
                response.say('I could not complete your request at this moment.').send();
            } else {
                var metadata = results[0];
                if (metadata.id === undefined) {
                    response.say(query + ' did not return any results on YouTube.').send();
                } else {
                    response.say('I found a relevant video called ' + metadata.title + '.');

                    console.log('Found ... ' + metadata.title);

                    var id = metadata.id;
                    var externalDownload = 'https://dmhacker-youtube.herokuapp.com/alexa/' + id;

                    request(externalDownload, function(err, res, body) {
                        console.log('Processed.');

                        if (err) {
                            console.log(err);
                            console.log(body);
                            response.fail(err.message);
                        } else {
                            recursive_check(id, 1000, function(err) {
                                if (err) {
                                    response.fail(err.message);
                                }
                                else {
                                    lastSearch = JSON.parse(body).link;
                                    var stream = {
                                        'url': lastSearch,
                                        'token': metadata.id,
                                        'offsetInMilliseconds': 0
                                    };
                                    response.audioPlayerPlayStream('ENQUEUE', stream);
                                    response.card({
                                        'type': 'Simple',
                                        'title': 'Search for "' + query + '"',
                                        'content': 'Alexa found "' + metadata.title + '" at ' + metadata.link + '.'
                                    });
                                    response.send();
                                }
                            });
                        }
                    });
                }
            }
        });

        return false;
    }
);

function recursive_check(id, delay, callback) {
    var linkCheck = 'https://dmhacker-youtube.herokuapp.com/alexa-check/' + id;
    request(linkCheck, function (err, res, body) {
        if (err) {
            callback(err);
        }
        else {
            var metadata = JSON.parse(body).metadata;
            if (!metadata) {
                callback(err);
            }
            else {
                if (metadata.downloaded) {
                    callback(null);
                }
                else {
                    setTimeout(function () {
                        recursive_check(id, delay, callback);
                    }, delay);
                }
            }
        }
    });
}

app.audioPlayer("PlaybackStarted", function(request, response) {
    console.log('Now playing audio clip ...');
    console.dir(request);
});

app.intent("AMAZON.PauseIntent", {}, function(req, response) {
    response.audioPlayerStop();
});

app.intent("AMAZON.ResumeIntent", {}, function(req, response) {
    if (lastSearch === undefined) {
        response.say('You were not playing any video previously.');
    } else {
        response.audioPlayerPlayStream('ENQUEUE', {
            'url': lastSearch,
            'streamFormat': 'AUDIO_MPEG',
            'token': constants.token,
            'expectedPreviousToken': constants.expectedPreviousToken
        });
    }
});

app.intent("AMAZON.StopIntent", {}, function(req, response) {
    lastSearch = undefined;
    response.audioPlayerStop();
    response.audioPlayerClearQueue();
});

exports.handler = app.lambda();
<|endoftext|>


<commit_before>'use strict';

var markdown = require('markdown-it')();
var _ = require('lodash');
var loader = require('./loader');

RewardCards = function RewardCards() {
    var self = this;
    self.deck = loader.load('cards.rewards');
    return self;
}

/**
 * get a random card
 *
 * @return {object} card - card object, (parsed json)
 */
RewardCards.prototype.getRandom = function getRandom() {
    var self = this;

    var deck = self.deck;
    var randomPick = _.random(0, (deck.length-1));
    var randomCard = deck[randomPick];

    return randomCard;
}

RewardCards.prototype.format = function format(cardJSON) {
    var self = this;

    var title = cardJSON.title || 'Untitled';
    var picture = cardJSON.picture || null;
    var description;

    // if there is markdown descrip, use it
    // else if there is descrip, use it
    // else undef

    var hasMarkdown = false;
    var hasPlaintext = false;

    if (typeof cardJSON.description_markdown !== 'undefined')
        hasMarkdown = true;
    else if (typeof cardJSON.description_plaintext !== 'undefined')
	hasPlaintext = true;

    // make sure we don't use an empty description
    if (hasMarkdown && cardJSON.description_markdown !== '')
        description = markdown.render(cardJSON.description_markdown);
    else if (hasPlaintext && cardJSON.description_plaintext !== '')
        description = cardJSON.description_plaintext;
    else
	description = 'Undescribed';

    if (!picture) {
	picture = 'http://placekitten.com/350/350';
    }
    else {
	picture = 'img/'+picture;
    }

    var formatted = {
        description: description,
        picture: picture,
        title: title
    }

    return formatted;

};

/**
 * get a card using its index in cards.json
 */
RewardCards.prototype.getCard = function getCard(index) {

}

module.exports = RewardCards
<commit_msg>divide cards into classes<commit_after><|endoftext|>