<commit_before>"use strict";

const expect = require("chai").expect;
const parse = require("../../../../../client/js/libs/handlebars/parse");

describe("parse Handlebars helper", () => {
	it("should not introduce xss", () => {
		const testCases = [{
			input: "",
			expected: "<img onerror='location.href="//youtube.com"'>",
		}, {
			input: '#&">bug',
			expected: '#&">bug',
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should skip control codes", () => {
		const testCases = [{
			input: "text\x01with\x04control\x05codes",
			expected: "textwithcontrolcodes",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should find urls", () => {
		const testCases = [{
			input: "irc://freenode.net/thelounge",
			expected:
				'' +
					"irc://freenode.net/thelounge" +
				"",
		}, {
			input: "www.nooooooooooooooo.com",
			expected:
				'' +
					"www.nooooooooooooooo.com" +
				"",
		}, {
			input: "look at https://thelounge.github.io/ for more information",
			expected:
				"look at " +
				'' +
					"https://thelounge.github.io/" +
				"" +
				" for more information",
		}, {
			input: "use www.duckduckgo.com for privacy reasons",
			expected:
				"use " +
				'' +
					"www.duckduckgo.com" +
				"" +
				" for privacy reasons",
		}, {
			input: "svn+ssh://example.org",
			expected:
				'' +
					"svn+ssh://example.org" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("url with a dot parsed correctly", () => {
		const input =
			"bonuspunkt: your URL parser misparses this URL: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx";
		const correctResult =
				"bonuspunkt: your URL parser misparses this URL: " +
				'' +
					"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" +
				"";

		const actual = parse(input);

		expect(actual).to.deep.equal(correctResult);
	});

	it("should balance brackets", () => {
		const testCases = [{
			input: "<https://theos.kyriasis.com/~kyrias/stats/archlinux.html>",
			expected:
				"<" +
				'' +
					"https://theos.kyriasis.com/~kyrias/stats/archlinux.html" +
				"" +
				">",
		}, {
			input: "abc (www.example.com)",
			expected:
				"abc (" +
				'' +
					"www.example.com" +
				"" +
				")",
		}, {
			input: "http://example.com/Test_(Page)",
			expected:
				'' +
					"http://example.com/Test_(Page)" +
				"",
		}, {
			input: "www.example.com/Test_(Page)",
			expected:
				'' +
					"www.example.com/Test_(Page)" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not find urls", () => {
		const testCases = [{
			input: "text www. text",
			expected: "text www. text",
		}, {
			input: "http://.",
			expected: "http://.",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should find channels", () => {
		const testCases = [{
			input: "#a",
			expected:
				'' +
					"#a" +
				"",
		}, {
			input: "#test",
			expected:
				'' +
					"#test" +
				"",
		}, {
			input: "#äöü",
			expected:
				'' +
					"#äöü" +
				"",
		}, {
			input: "inline #channel text",
			expected:
				"inline " +
				'' +
					"#channel" +
				"" +
				" text",
		}, {
			input: "#1,000",
			expected:
				'' +
					"#1,000" +
				"",
		}, {
			input: "@#a",
			expected:
				"@" +
				'' +
					"#a" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not find channels", () => {
		const testCases = [{
			input: "hi#test",
			expected: "hi#test",
		}, {
			input: "#",
			expected: "#",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should style like mirc", () => {
		const testCases = [{
			input: "\x02bold",
			expected: 'bold',
		}, {
			input: "\x038yellowText",
			expected: 'yellowText',
		}, {
			input: "\x030,0white,white",
			expected: 'white,white',
		}, {
			input: "\x034,8yellowBGredText",
			expected: 'yellowBGredText',
		}, {
			input: "\x1ditalic",
			expected: 'italic',
		}, {
			input: "\x1funderline",
			expected: 'underline',
		}, {
			input: "\x02bold\x038yellow\x02nonBold\x03default",
			expected:
				'bold' +
				'yellow' +
				'nonBold' +
				"default",
		}, {
			input: "\x02bold\x02 \x02bold\x02",
			expected:
				'bold' +
				" " +
				'bold',
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should find nicks", () => {
		const testCases = [{
			users: ["MaxLeiter"],
			input: "test, MaxLeiter",
			expected:
				"test, " +
				"" +
					"MaxLeiter" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input, testCase.users));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not find nicks", () => {
		const testCases = [{
			users: ["MaxLeiter, test"],
			input: "#test-channelMaxLeiter",
			expected:
				"" +
					"#test-channelMaxLeiter" +
				"",
		},
		{
			users: ["MaxLeiter, test"],
			input: "https://www.MaxLeiter.com/test",
			expected:
				"" +
					"https://www.MaxLeiter.com/test" +
				"",
		},

		];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should go bonkers like mirc", () => {
		const testCases = [{
			input: "\x02irc\x0f://\x1dfreenode.net\x0f/\x034,8thelounge",
			expected:
				'' +
					'irc' +
					"://" +
					'freenode.net' +
					"/" +
					'thelounge' +
				"",
		}, {
			input: "\x02#\x038,9thelounge",
			expected:
				'' +
					'#' +
					'thelounge' +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should optimize generated html", () => {
		const testCases = [{
			input: 'test \x0312#\x0312\x0312"te\x0312st\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312a',
			expected:
			"test " +
				'' +
				'#"testa' +
			"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should trim common protocols", () => {
		const testCases = [{
			input: "like..http://example.com",
			expected:
				"like.." +
				'' +
					"http://example.com" +
				"",
		}, {
			input: "like..HTTP://example.com",
			expected:
				"like.." +
				'' +
					"HTTP://example.com" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not find channel in fragment", () => {
		const testCases = [{
			input: "http://example.com/#hash",
			expected:
				'' +
					"http://example.com/#hash" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not overlap parts", () => {
		const input = "Url: http://example.com/path Channel: ##channel";
		const actual = parse(input);

		expect(actual).to.equal(
			'Url: http://example.com/path ' +
			'Channel: ##channel'
		);
	});

	it("should handle overlapping parts by using first starting", () => {
		const input = "#test-https://example.com";
		const actual = parse(input);

		expect(actual).to.equal(
			'' +
				"#test-https://example.com" +
			""
		);
	});
});
<commit_msg>Avoid escaping quotes whenever possible (again)<commit_after>"use strict";

const expect = require("chai").expect;
const parse = require("../../../../../client/js/libs/handlebars/parse");

describe("parse Handlebars helper", () => {
	it("should not introduce xss", () => {
		const testCases = [{
			input: "",
			expected: "<img onerror='location.href="//youtube.com"'>",
		}, {
			input: '#&">bug',
			expected: '#&">bug',
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should skip control codes", () => {
		const testCases = [{
			input: "text\x01with\x04control\x05codes",
			expected: "textwithcontrolcodes",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should find urls", () => {
		const testCases = [{
			input: "irc://freenode.net/thelounge",
			expected:
				'' +
					"irc://freenode.net/thelounge" +
				"",
		}, {
			input: "www.nooooooooooooooo.com",
			expected:
				'' +
					"www.nooooooooooooooo.com" +
				"",
		}, {
			input: "look at https://thelounge.github.io/ for more information",
			expected:
				"look at " +
				'' +
					"https://thelounge.github.io/" +
				"" +
				" for more information",
		}, {
			input: "use www.duckduckgo.com for privacy reasons",
			expected:
				"use " +
				'' +
					"www.duckduckgo.com" +
				"" +
				" for privacy reasons",
		}, {
			input: "svn+ssh://example.org",
			expected:
				'' +
					"svn+ssh://example.org" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("url with a dot parsed correctly", () => {
		const input =
			"bonuspunkt: your URL parser misparses this URL: https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx";
		const correctResult =
				"bonuspunkt: your URL parser misparses this URL: " +
				'' +
					"https://msdn.microsoft.com/en-us/library/windows/desktop/ms644989(v=vs.85).aspx" +
				"";

		const actual = parse(input);

		expect(actual).to.deep.equal(correctResult);
	});

	it("should balance brackets", () => {
		const testCases = [{
			input: "<https://theos.kyriasis.com/~kyrias/stats/archlinux.html>",
			expected:
				"<" +
				'' +
					"https://theos.kyriasis.com/~kyrias/stats/archlinux.html" +
				"" +
				">",
		}, {
			input: "abc (www.example.com)",
			expected:
				"abc (" +
				'' +
					"www.example.com" +
				"" +
				")",
		}, {
			input: "http://example.com/Test_(Page)",
			expected:
				'' +
					"http://example.com/Test_(Page)" +
				"",
		}, {
			input: "www.example.com/Test_(Page)",
			expected:
				'' +
					"www.example.com/Test_(Page)" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not find urls", () => {
		const testCases = [{
			input: "text www. text",
			expected: "text www. text",
		}, {
			input: "http://.",
			expected: "http://.",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should find channels", () => {
		const testCases = [{
			input: "#a",
			expected:
				'' +
					"#a" +
				"",
		}, {
			input: "#test",
			expected:
				'' +
					"#test" +
				"",
		}, {
			input: "#äöü",
			expected:
				'' +
					"#äöü" +
				"",
		}, {
			input: "inline #channel text",
			expected:
				"inline " +
				'' +
					"#channel" +
				"" +
				" text",
		}, {
			input: "#1,000",
			expected:
				'' +
					"#1,000" +
				"",
		}, {
			input: "@#a",
			expected:
				"@" +
				'' +
					"#a" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not find channels", () => {
		const testCases = [{
			input: "hi#test",
			expected: "hi#test",
		}, {
			input: "#",
			expected: "#",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should style like mirc", () => {
		const testCases = [{
			input: "\x02bold",
			expected: 'bold',
		}, {
			input: "\x038yellowText",
			expected: 'yellowText',
		}, {
			input: "\x030,0white,white",
			expected: 'white,white',
		}, {
			input: "\x034,8yellowBGredText",
			expected: 'yellowBGredText',
		}, {
			input: "\x1ditalic",
			expected: 'italic',
		}, {
			input: "\x1funderline",
			expected: 'underline',
		}, {
			input: "\x02bold\x038yellow\x02nonBold\x03default",
			expected:
				'bold' +
				'yellow' +
				'nonBold' +
				"default",
		}, {
			input: "\x02bold\x02 \x02bold\x02",
			expected:
				'bold' +
				" " +
				'bold',
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should find nicks", () => {
		const testCases = [{
			users: ["MaxLeiter"],
			input: "test, MaxLeiter",
			expected:
				"test, " +
				'' +
					"MaxLeiter" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input, testCase.users));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not find nicks", () => {
		const testCases = [{
			users: ["MaxLeiter, test"],
			input: "#test-channelMaxLeiter",
			expected:
				'' +
					"#test-channelMaxLeiter" +
				"",
		},
		{
			users: ["MaxLeiter, test"],
			input: "https://www.MaxLeiter.com/test",
			expected:
				'' +
					"https://www.MaxLeiter.com/test" +
				"",
		},

		];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should go bonkers like mirc", () => {
		const testCases = [{
			input: "\x02irc\x0f://\x1dfreenode.net\x0f/\x034,8thelounge",
			expected:
				'' +
					'irc' +
					"://" +
					'freenode.net' +
					"/" +
					'thelounge' +
				"",
		}, {
			input: "\x02#\x038,9thelounge",
			expected:
				'' +
					'#' +
					'thelounge' +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should optimize generated html", () => {
		const testCases = [{
			input: 'test \x0312#\x0312\x0312"te\x0312st\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312\x0312a',
			expected:
			"test " +
				'' +
				'#"testa' +
			"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should trim common protocols", () => {
		const testCases = [{
			input: "like..http://example.com",
			expected:
				"like.." +
				'' +
					"http://example.com" +
				"",
		}, {
			input: "like..HTTP://example.com",
			expected:
				"like.." +
				'' +
					"HTTP://example.com" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not find channel in fragment", () => {
		const testCases = [{
			input: "http://example.com/#hash",
			expected:
				'' +
					"http://example.com/#hash" +
				"",
		}];

		const actual = testCases.map((testCase) => parse(testCase.input));
		const expected = testCases.map((testCase) => testCase.expected);

		expect(actual).to.deep.equal(expected);
	});

	it("should not overlap parts", () => {
		const input = "Url: http://example.com/path Channel: ##channel";
		const actual = parse(input);

		expect(actual).to.equal(
			'Url: http://example.com/path ' +
			'Channel: ##channel'
		);
	});

	it("should handle overlapping parts by using first starting", () => {
		const input = "#test-https://example.com";
		const actual = parse(input);

		expect(actual).to.equal(
			'' +
				"#test-https://example.com" +
			""
		);
	});
});
<|endoftext|>


<commit_before>const expect = require('chai').expect;
const React = require('react');
import { mount } from 'enzyme';

import RecipeContainer from '../../client/components/RecipeContainer.js';
import RecipeEntry from '../../client/components/RecipeEntry.js';

const fakeRecipes = [
  { name: 'Fake Recipe 1' },
  { name: 'Fake Recipe 2' },
  { name: 'Fake Recipe 3' },
];

const fakeTitle = 'This is the title.';

describe('<RecipeContainer />', () => {

  it('should render without problems', () => {
    const wrapper = mount(<RecipeContainer recipes={fakeRecipes} />);
    expect(wrapper.find(RecipeContainer)).to.have.length(1);
  });

  it('should render the recipe container title', () => {
    const wrapper = mount(<RecipeContainer type={fakeTitle} recipes={fakeRecipes} />);
    expect(wrapper.find('h1').text()).to.equal(fakeTitle);
  });

  it('should render all <RecipeEntry /> child components', () => {
    const wrapper = mount(<RecipeContainer recipes={fakeRecipes} />);
    expect(wrapper.find(RecipeEntry)).to.have.length(3);
  });

});
<commit_msg>fix recipecontainer test to look for h2 values<commit_after>const expect = require('chai').expect;
const React = require('react');
import { mount } from 'enzyme';

import RecipeContainer from '../../client/components/RecipeContainer.js';
import RecipeEntry from '../../client/components/RecipeEntry.js';

const fakeRecipes = [
  { name: 'Fake Recipe 1' },
  { name: 'Fake Recipe 2' },
  { name: 'Fake Recipe 3' },
];

const fakeTitle = 'This is the title.';

describe('<RecipeContainer />', () => {

  it('should render without problems', () => {
    const wrapper = mount(<RecipeContainer recipes={fakeRecipes} />);
    expect(wrapper.find(RecipeContainer)).to.have.length(1);
  });

  it('should render the recipe container title', () => {
    const wrapper = mount(<RecipeContainer type={fakeTitle} recipes={fakeRecipes} />);
    expect(wrapper.find('h2').text()).to.equal(fakeTitle);
  });

  it('should render all <RecipeEntry /> child components', () => {
    const wrapper = mount(<RecipeContainer recipes={fakeRecipes} />);
    expect(wrapper.find(RecipeEntry)).to.have.length(3);
  });

});
<|endoftext|>


<commit_before>/*
 *  Manifest - organize a program of songs for an ensemble
 */

function Manifest(manifest) {

	var manifest = manifest ;

	var __Manifest = function(that) {
		that.manifest = this.manifest ;
		console.log('Creating manifest ', that.manifest) ;
	}(this) ;

	this.getBaseUrl = function(song) {

		if ( song.hasOwnProperty('baseUrl') && song.baseUrl !== '' ) {
			return song.baseUrl ;
		}
		if ( this.manifest.hasOwnProperty('baseUrl') && this.manifest.baseUrl !== '' ) {
			return this.manifest.baseUrl ;
		}
		return '' ;
	} ;

    this.displaySong = function(song) {

		var scoreIndex,
		    songIndex,
		    score,
		    part,
		    href,
			webDir = this.getBaseUrl(song) + song.fileLocation + '/pdf/',
		    html = '
' + song.title + '
' +
				"
Composed by " + song.composer ;

		if ( song.hasOwnProperty('arranger') &&
			 song.arranger !== '' &&
			 song.composer !== song.arranger ) {
			html += ', Arranged by ' + song.arranger ;
		}

		html += "
\n" ;

		if ( song.hasOwnProperty('recordings') ) {
			html += this.displayRecordings(song) ;
		}

		html += this.displayScoresAndParts(song) ;

		return html ;
	} ;

	this.displayRecordings = function(song) {

		var name,
			recording,
			href,
			html = "
Recordings
\n
\n" ;

		for ( name in song.recordings ) {
	 		recording = song.recordings[name] ;
			href = song.recordings[name] ;
			html += '
' + name + "
\n" ;
		};

		html += "
\n" ;

		return html ;
	} ;

	this.displayScoresAndParts = function(song) {

		var name,
			score,
			href,
			html = "
Scores
\n
\n" ;

		for ( name in song.scores ) {
	 		score = song.scores[name] ;
			href = this.getBaseUrl(song) + song.filePrefix + score.fileSuffix + '.pdf' ;
			html += '
' + name + "
\n" ;
		}

		html += "
\n
Parts
\n" ;

		for ( name in song.parts ) {
			part = song.parts[name] ;
			href = this.getBaseUrl(song) + song.filePrefix + part.fileSuffix + '.pdf' ;
			html += '
' + name + "
\n" ;
		};
		html += "
\n" ;

		return html ;
	} ;

	this.displayProgram = function() {

		console.log('in displayProgram with' +
			"\n    this", this,
		    "\n    and this.manifest", this.manifest,
		    "\n    and this.manifest.songs ", this.manifest.songs,
		    "\n    and this.manifest.programOrder ", this.manifest.programOrder,
		    "\n    and this.manifest.programOrder.length ", this.manifest.programOrder.length ) ;

		var programIndex, number, songIndex, song, baseUrl, html ;
		for ( programIndex = 0 ; programIndex < this.manifest.programOrder.length ; programIndex++ ) {

			number = this.manifest.programOrder[programIndex] ;
			songIndex = this.manifest.program[number] ;
			song = this.manifest.songs[songIndex] ;
			html += this.displaySong(song) ;
		}

		return html ;
	} ;

	this.displayPartsInBook = function(chair, partsLists) {

		var songId,
			song,
			partsList,
			partIndex,
			part,
			href,
			html = '
' + chair + '
' +
				"\n\n
\n" ;

		Object.keys(partsLists).forEach(function(songId) {

	    	song = this.manifest.songs[songId] ;
			partsList = partsLists[songId] ;
			html += '
' + song.title ;
			for ( partIndex = 0 ; partIndex < partsList.length ; partIndex++ ) {
				part = partsList[partIndex] ;
				console.log('    this', this, 'this.getBaseUrl', this.getBaseUrl);
				href = this.getBaseUrl(song) + song.filePrefix + song.parts[part].fileSuffix + '.pdf' ;
				html += ' ' + part + '' ;
				if ( partIndex+1 < partsList.length ) {
					html += ',' ;
				}
			}
			html += "
\n" ;
		});

		html += "
\n" ;

		return html ;
	} ;

	this.displayPartsInBooks = function() {

		var html, key,
			books = this.manifest.partsInBooks ;

		for ( key in books ) {

			if ( books.hasOwnProperty(key) ) {

				html += this.displayPartsInBook( key, books[key] ) ;

			}
		}
	} ;

	this.displayManifest = function() {
		this.displayProgram() ;
		this.displayPartsInBooks() ;
	}
}

<commit_msg>incremental edits<commit_after>/*
 *  Manifest - organize a program of songs for an ensemble
 */

function Manifest(manifest) {

	var manifest = manifest ;

	var __Manifest = function(that) {
		that.manifest = this.manifest ;
		console.log('Creating manifest ', that.manifest) ;
	}(this) ;

	this.getBaseUrl = function(song) {

		if ( song.hasOwnProperty('baseUrl') && song.baseUrl !== '' ) {
			return song.baseUrl ;
		}
		if ( this.manifest.hasOwnProperty('baseUrl') && this.manifest.baseUrl !== '' ) {
			return this.manifest.baseUrl ;
		}
		return '' ;
	} ;

    this.displaySong = function(manifest, song) {

		var scoreIndex,
		    songIndex,
		    score,
		    part,
		    href,
			webDir = manifest.getBaseUrl(song) + song.fileLocation + '/pdf/',
		    html = '
' + song.title + '
' +
				"
Composed by " + song.composer ;

		if ( song.hasOwnProperty('arranger') &&
			 song.arranger !== '' &&
			 song.composer !== song.arranger ) {
			html += ', Arranged by ' + song.arranger ;
		}

		html += "
\n" ;

		if ( song.hasOwnProperty('recordings') ) {
			html += this.displayRecordings(song) ;
		}

		html += this.displayScoresAndParts(song) ;

		return html ;
	} ;

	this.displayRecordings = function(song) {

		var name,
			recording,
			href,
			html = "
Recordings
\n
\n" ;

		for ( name in song.recordings ) {
	 		recording = song.recordings[name] ;
			href = song.recordings[name] ;
			html += '
' + name + "
\n" ;
		};

		html += "
\n" ;

		return html ;
	} ;

	this.displayScoresAndParts = function(song) {

		var name,
			score,
			href,
			html = "
Scores
\n
\n" ;

		for ( name in song.scores ) {
	 		score = song.scores[name] ;
			href = this.getBaseUrl(song) + song.filePrefix + score.fileSuffix + '.pdf' ;
			html += '
' + name + "
\n" ;
		}

		html += "
\n
Parts
\n" ;

		for ( name in song.parts ) {
			part = song.parts[name] ;
			href = this.getBaseUrl(song) + song.filePrefix + part.fileSuffix + '.pdf' ;
			html += '
' + name + "
\n" ;
		};
		html += "
\n" ;

		return html ;
	} ;

	this.displayProgram = function() {

		console.log('in displayProgram with' +
			"\n    this", this,
		    "\n    and this.manifest", this.manifest,
		    "\n    and this.manifest.songs ", this.manifest.songs,
		    "\n    and this.manifest.programOrder ", this.manifest.programOrder,
		    "\n    and this.manifest.programOrder.length ", this.manifest.programOrder.length ) ;

		var programIndex, number, songIndex, song, baseUrl, html ;
		for ( programIndex = 0 ; programIndex < this.manifest.programOrder.length ; programIndex++ ) {

			number = this.manifest.programOrder[programIndex] ;
			songIndex = this.manifest.program[number] ;
			song = this.manifest.songs[songIndex] ;
			html += this.displaySong(this, song) ;
		}

		return html ;
	} ;

	this.displayPartsInBook = function(manifest, chair, partsLists) {

		var songId,
			song,
			partsList,
			partIndex,
			part,
			href,
			html = '
' + chair + '
' +
				"\n\n
\n" ;

		Object.keys(partsLists).forEach(function(songId) {

	    	song = this.manifest.songs[songId] ;
			partsList = partsLists[songId] ;
			html += '
' + song.title ;
			for ( partIndex = 0 ; partIndex < partsList.length ; partIndex++ ) {
				part = partsList[partIndex] ;
				console.log('    manifest', manifest, 'manifest.getBaseUrl', manifest.getBaseUrl);
				href = manifest.getBaseUrl(song) + song.filePrefix + song.parts[part].fileSuffix + '.pdf' ;
				html += ' ' + part + '' ;
				if ( partIndex+1 < partsList.length ) {
					html += ',' ;
				}
			}
			html += "
\n" ;
		});

		html += "
\n" ;

		return html ;
	} ;

	this.displayPartsInBooks = function() {

		var html, key,
			books = this.manifest.partsInBooks ;

		for ( key in books ) {

			if ( books.hasOwnProperty(key) ) {

				html += this.displayPartsInBook( this, key, books[key] ) ;

			}
		}
	} ;

	this.displayManifest = function() {
		this.displayProgram() ;
		this.displayPartsInBooks() ;
	}
}

<|endoftext|>


<commit_before>/** Accusativ - винительный падеж. Кого? Что?
* turn <left/right> on <streetName>  * поверните <направо/налево> на <улицу>
* exit <left/right> on <streetName> * съезд <справа/слева> на <улицу>
* keep <left/right> on <streetName> * держитесь <левее/правее> на <улицу>
* make u-turn on <streetName> * развернитесь на <улицу>
* @customfunction
*/
function Accusativ(text) {
    text = text.replace(/(.*\bна\b)(.*?)\b(улица|набережная|дорога|линия|аллея|площадь|просека|автодорога|эстакада|магистраль|дамба|хорда|коса|деревня|переправа|площадка|дорожка|трасса)\b/, // feminine

      function (onFullName,on,streetName,streetStatus) {
        streetName = streetName.replace(/ая\b/g,"ую"); // Пушкинская -> Пушкинскую
        streetName = streetName.replace(/яя\b/g,"юю"); // Зимняя -> Зимнюю
        streetName = streetName.replace(/ья\b/,"ью"); // третья -> третью, Казачья -> Казачью
        streetName = streetName.replace(/а\b/,"у"); // Репищева -> Репищеву
        streetName = streetName.replace(/-я\b/,"-ю"); // 1-я -> 1-ю
        switch (streetStatus) {
          case 'улица': streetStatus = 'улицу'; break;
          case 'набережная': streetStatus = 'набережную'; break;
          case 'дорога': streetStatus = 'дорогу'; break;
          case 'линия': streetStatus = 'линию'; break;
          case 'аллея': streetStatus = 'аллею'; break;
          case 'просека': streetStatus = 'просеку'; break;
          case 'автодорога': streetStatus = 'автодорогу'; break;
          case 'эстакада': streetStatus = 'эстакаду'; break;
          case 'дамба': streetStatus = 'дамбу'; break;
          case 'хорда': streetStatus = 'хорду'; break;
          case 'коса': streetStatus = 'косу'; break;
          case 'деревня': streetStatus = 'деревню'; break;
          case 'переправа': streetStatus = 'переправу'; break;
          case 'площадка': streetStatus = 'площадку'; break;
          case 'дорожка': streetStatus = 'дорожку'; break;
          case 'трасса': streetStatus = 'трассу'; break;
        }
        return on + streetName + streetStatus;
      });
  return text;
} // Accusativ

/** Genitiv - родительный падеж. Кого? Чего?
* continue straight for X minutes to <streetName>.
* продолжайте движение около X мин. до <улицы>
* @customfunction
*/
function Genitiv(text) {
      result = text.replace(/(\bдо\b)(.*?)\b(улица|набережная|дорога|линия|аллея|площадь|просека|автодорога|эстакада|магистраль|дамба)\b/, // feminine
        function (onFullName,to__until,streetName,streetStatus) {
          streetName = streetName.replace(/ая\b/g,"ой"); // Пушкинская -> Пушкинской, Садовая-Спасская -> Садовой-Спасской
          streetName = streetName.replace(/яя\b/g,"ей"); // Зимняя -> Зимней
          streetName = streetName.replace(/ья\b/,"ьей"); // третья -> третьей, Казачья -> Казачьей
          streetName = streetName.replace(/а\b/,"ой"); // Репищева -> Репищевой
          streetName = streetName.replace(/3-я\b/,"3-ей"); // 3-я -> 3-ей
          streetName = streetName.replace(/-я\b/,"-ой"); // 1-я -> 1-ой
          switch (streetStatus) {
            case 'улица': streetStatus = 'улицы'; break;
            case 'набережная': streetStatus = 'набережной'; break;
            case 'дорога': streetStatus = 'дороги'; break;
            case 'линия': streetStatus = 'линии'; break;
            case 'аллея': streetStatus = 'аллеи'; break;
            case 'площадь': streetStatus = 'площади'; break;
            case 'просека': streetStatus = 'просеки'; break;
            case 'автодорога': streetStatus = 'автодороги'; break;
            case 'эстакада': streetStatus = 'эстакады'; break;
            case 'магистраль': streetStatus = 'магистрали'; break;
            case 'дамба': streetStatus = 'дамбы'; break;
          }
          return to__until + streetName + streetStatus;
        });
      if (text !== result) { return result }
      result = text.replace(/(\bдо\b)(.*?)\b(проспект|переулок|проезд|тупик|бульвар|тракт|объезд|заезд|съезд|просек|микрорайон|взвоз|спуск|переезд|квартал|путепровод|мост|обвод|поселок|городок|разворот|шлагбаум|обход|подъезд)\b/, // masculine
        function (onFullName,to__until,streetName,streetStatus) {
          streetName = streetName.replace(/чий\b/,"чьего"); // Заячий -> Заячьего
          streetName = streetName.replace(/тий\b/,"тьего"); // третий -> третьего
          streetName = streetName.replace(/ний\b/,"него"); // Верхний -> Верхнего
          streetName = streetName.replace(/(ой|ий|ый)\b/g,"ого"); // Большой Смоленский -> Большого Смоленского, Зелёный -> Зелёного
          streetName = streetName.replace(/ов\b/,"ова"); // Агатов -> Агатова
          streetName = streetName.replace(/ин\b/,"ина"); // Апраксин -> Апраксина
          streetName = streetName.replace(/-й\b/,"-го"); // 1-й -> 1-го
          switch (streetStatus) {
            case 'проспект': streetStatus = 'проспекта'; break;
            case 'переулок': streetStatus = 'переулка'; break;
            case 'проезд': streetStatus = 'проезда'; break;
            case 'тупик': streetStatus = 'тупика'; break;
            case 'бульвар': streetStatus = 'бульвара'; break;
            case 'тракт': streetStatus = 'тракта'; break;
            case 'объезд': streetStatus = 'объезда'; break;
            case 'заезд': streetStatus = 'заезда'; break;
            case 'съезд': streetStatus = 'съезда'; break;
            case 'просек': streetStatus = 'просека'; break;
            case 'микрорайон': streetStatus = 'микрорайона'; break;
            case 'взвоз': streetStatus = 'взвоза'; break;
            case 'спуск': streetStatus = 'спуска'; break;
            case 'переезд': streetStatus = 'переезда'; break;
            case 'квартал': streetStatus = 'квартала'; break;
            case 'путепровод': streetStatus = 'путепровода'; break;
            case 'мост': streetStatus = 'моста'; break;
            case 'обвод': streetStatus = 'обвода'; break;
            case 'поселок': streetStatus = 'поселка'; break;
            case 'городок': streetStatus = 'городка'; break;
            case 'разворот': streetStatus = 'разворота'; break;
            case 'шлагбаум': streetStatus = 'шлагбаума'; break;
            case 'обход': streetStatus = 'обхода'; break;
            case 'подъезд': streetStatus = 'подъезда'; break;
            case 'кольцо': streetStatus = 'кольца'; break;
          }
          return to__until + streetName + streetStatus;
        });
      if (text !== result) { return result }
      result = text.replace(/(\bдо\b)(.*?)\b(шоссе|кольцо)\b/, // neuter gender
        function (onFullName,to__until,streetName,streetStatus) {
          streetName = streetName.replace(/ое\b/g,"ого"); // Нефтеюганское -> Нефтеюганского
          streetName = streetName.replace(/ье\b/,"ьего"); // третье -> третьего, Казачье -> Казачьего
          streetName = streetName.replace(/-е\b/,"-го"); // 1-е -> 1-го
          switch (streetStatus) {
            case 'кольцо': streetStatus = 'кольца'; break;
          }
          return to__until + streetName + streetStatus;
        });
      return result;
} // Genitiv

/** Dative - дательный падеж. Кому? Чему?
* Let's take <streetName>  * Поедем по <улице>
* @customfunction
*/
function Dative(text) {
  result = text;
  return result;
} // Dative

if ( text.match(/(поверните|съезд|держитесь|развернитесь).* на/i) )
{
  text = Accusativ(text);
};

if ( text.match(/продолжайте движение/i) )
{
  text = Genitiv(text);
};
<commit_msg>add feminine status Genitiv<commit_after>/** Accusativ - винительный падеж. Кого? Что?
* turn <left/right> on <streetName>  * поверните <направо/налево> на <улицу>
* exit <left/right> on <streetName> * съезд <справа/слева> на <улицу>
* keep <left/right> on <streetName> * держитесь <левее/правее> на <улицу>
* make u-turn on <streetName> * развернитесь на <улицу>
* @customfunction
*/
function Accusativ(text) {
    text = text.replace(/(.*\bна\b)(.*?)\b(улица|набережная|дорога|линия|аллея|площадь|просека|автодорога|эстакада|магистраль|дамба|хорда|коса|деревня|переправа|площадка|дорожка|трасса)\b/, // feminine

      function (onFullName,on,streetName,streetStatus) {
        streetName = streetName.replace(/ая\b/g,"ую"); // Пушкинская -> Пушкинскую
        streetName = streetName.replace(/яя\b/g,"юю"); // Зимняя -> Зимнюю
        streetName = streetName.replace(/ья\b/,"ью"); // третья -> третью, Казачья -> Казачью
        streetName = streetName.replace(/а\b/,"у"); // Репищева -> Репищеву
        streetName = streetName.replace(/-я\b/,"-ю"); // 1-я -> 1-ю
        switch (streetStatus) {
          case 'улица': streetStatus = 'улицу'; break;
          case 'набережная': streetStatus = 'набережную'; break;
          case 'дорога': streetStatus = 'дорогу'; break;
          case 'линия': streetStatus = 'линию'; break;
          case 'аллея': streetStatus = 'аллею'; break;
          case 'просека': streetStatus = 'просеку'; break;
          case 'автодорога': streetStatus = 'автодорогу'; break;
          case 'эстакада': streetStatus = 'эстакаду'; break;
          case 'дамба': streetStatus = 'дамбу'; break;
          case 'хорда': streetStatus = 'хорду'; break;
          case 'коса': streetStatus = 'косу'; break;
          case 'деревня': streetStatus = 'деревню'; break;
          case 'переправа': streetStatus = 'переправу'; break;
          case 'площадка': streetStatus = 'площадку'; break;
          case 'дорожка': streetStatus = 'дорожку'; break;
          case 'трасса': streetStatus = 'трассу'; break;
        }
        return on + streetName + streetStatus;
      });
  return text;
} // Accusativ

/** Genitiv - родительный падеж. Кого? Чего?
* continue straight for X minutes to <streetName>.
* продолжайте движение около X мин. до <улицы>
* @customfunction
*/
function Genitiv(text) {
      result = text.replace(/(\bдо\b)(.*?)\b(улица|набережная|дорога|линия|аллея|площадь|просека|автодорога|эстакада|магистраль|дамба|хорда|коса|деревня|переправа|площадка|дорожка|трасса)\b/, // feminine
        function (onFullName,to__until,streetName,streetStatus) {
          streetName = streetName.replace(/ая\b/g,"ой"); // Пушкинская -> Пушкинской, Садовая-Спасская -> Садовой-Спасской
          streetName = streetName.replace(/яя\b/g,"ей"); // Зимняя -> Зимней
          streetName = streetName.replace(/ья\b/,"ьей"); // третья -> третьей, Казачья -> Казачьей
          streetName = streetName.replace(/а\b/,"ой"); // Репищева -> Репищевой
          streetName = streetName.replace(/3-я\b/,"3-ей"); // 3-я -> 3-ей
          streetName = streetName.replace(/-я\b/,"-ой"); // 1-я -> 1-ой
          switch (streetStatus) {
            case 'улица': streetStatus = 'улицы'; break;
            case 'набережная': streetStatus = 'набережной'; break;
            case 'дорога': streetStatus = 'дороги'; break;
            case 'линия': streetStatus = 'линии'; break;
            case 'аллея': streetStatus = 'аллеи'; break;
            case 'площадь': streetStatus = 'площади'; break;
            case 'просека': streetStatus = 'просеки'; break;
            case 'автодорога': streetStatus = 'автодороги'; break;
            case 'эстакада': streetStatus = 'эстакады'; break;
            case 'магистраль': streetStatus = 'магистрали'; break;
            case 'дамба': streetStatus = 'дамбы'; break;
            case 'хорда': streetStatus = 'хорды'; break;
            case 'коса': streetStatus = 'косы'; break;
            case 'деревня': streetStatus = 'деревни'; break;
            case 'переправа': streetStatus = 'переправы'; break;
            case 'площадка': streetStatus = 'площадки'; break;
            case 'дорожка': streetStatus = 'дорожки'; break;
            case 'трасса': streetStatus = 'трассы'; break;
          }
          return to__until + streetName + streetStatus;
        });
      if (text !== result) { return result }
      result = text.replace(/(\bдо\b)(.*?)\b(проспект|переулок|проезд|тупик|бульвар|тракт|объезд|заезд|съезд|просек|микрорайон|взвоз|спуск|переезд|квартал|путепровод|мост|обвод|поселок|городок|разворот|шлагбаум|обход|подъезд)\b/, // masculine
        function (onFullName,to__until,streetName,streetStatus) {
          streetName = streetName.replace(/чий\b/,"чьего"); // Заячий -> Заячьего
          streetName = streetName.replace(/тий\b/,"тьего"); // третий -> третьего
          streetName = streetName.replace(/ний\b/,"него"); // Верхний -> Верхнего
          streetName = streetName.replace(/(ой|ий|ый)\b/g,"ого"); // Большой Смоленский -> Большого Смоленского, Зелёный -> Зелёного
          streetName = streetName.replace(/ов\b/,"ова"); // Агатов -> Агатова
          streetName = streetName.replace(/ин\b/,"ина"); // Апраксин -> Апраксина
          streetName = streetName.replace(/-й\b/,"-го"); // 1-й -> 1-го
          switch (streetStatus) {
            case 'проспект': streetStatus = 'проспекта'; break;
            case 'переулок': streetStatus = 'переулка'; break;
            case 'проезд': streetStatus = 'проезда'; break;
            case 'тупик': streetStatus = 'тупика'; break;
            case 'бульвар': streetStatus = 'бульвара'; break;
            case 'тракт': streetStatus = 'тракта'; break;
            case 'объезд': streetStatus = 'объезда'; break;
            case 'заезд': streetStatus = 'заезда'; break;
            case 'съезд': streetStatus = 'съезда'; break;
            case 'просек': streetStatus = 'просека'; break;
            case 'микрорайон': streetStatus = 'микрорайона'; break;
            case 'взвоз': streetStatus = 'взвоза'; break;
            case 'спуск': streetStatus = 'спуска'; break;
            case 'переезд': streetStatus = 'переезда'; break;
            case 'квартал': streetStatus = 'квартала'; break;
            case 'путепровод': streetStatus = 'путепровода'; break;
            case 'мост': streetStatus = 'моста'; break;
            case 'обвод': streetStatus = 'обвода'; break;
            case 'поселок': streetStatus = 'поселка'; break;
            case 'городок': streetStatus = 'городка'; break;
            case 'разворот': streetStatus = 'разворота'; break;
            case 'шлагбаум': streetStatus = 'шлагбаума'; break;
            case 'обход': streetStatus = 'обхода'; break;
            case 'подъезд': streetStatus = 'подъезда'; break;
            case 'кольцо': streetStatus = 'кольца'; break;
          }
          return to__until + streetName + streetStatus;
        });
      if (text !== result) { return result }
      result = text.replace(/(\bдо\b)(.*?)\b(шоссе|кольцо)\b/, // neuter gender
        function (onFullName,to__until,streetName,streetStatus) {
          streetName = streetName.replace(/ое\b/g,"ого"); // Нефтеюганское -> Нефтеюганского
          streetName = streetName.replace(/ье\b/,"ьего"); // третье -> третьего, Казачье -> Казачьего
          streetName = streetName.replace(/-е\b/,"-го"); // 1-е -> 1-го
          switch (streetStatus) {
            case 'кольцо': streetStatus = 'кольца'; break;
          }
          return to__until + streetName + streetStatus;
        });
      return result;
} // Genitiv

/** Dative - дательный падеж. Кому? Чему?
* Let's take <streetName>  * Поедем по <улице>
* @customfunction
*/
function Dative(text) {
  result = text;
  return result;
} // Dative

if ( text.match(/(поверните|съезд|держитесь|развернитесь).* на/i) )
{
  text = Accusativ(text);
};

if ( text.match(/продолжайте движение/i) )
{
  text = Genitiv(text);
};
<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

/**
 * @constructor
 */
var SilexJS = function() {
  this._readConfig();
  this._route();
  this._initializeApp();
  this.HTTP = require('./http');
};

/**
 * @method _route
 * @private
 */
SilexJS.prototype._route = function() {
  var Router = require('./router');
  this.Router = new Router();
};

/**
 * @method _initializeApp
 * @private
 */
SilexJS.prototype._initializeApp = function() {
  var App = require('./app');
  this.App = new App(this.Router);
};

/**
 * @method _readConfig
 * @private
 */
SilexJS.prototype._readConfig = function() {
  var path = require('path');
  this.config = require(path.dirname(module.parent.filename) + '/config.json');
};

/**
 * @method start
 * @public
 */
SilexJS.prototype.start = function () {
  var http = require('http');
  var self = this;

  http.createServer(function (req, res) {
    self.Router.dispatch(req, res);
  }).listen(this.config.port);

};

module.exports = new SilexJS();
<commit_msg>Activating default configuration.<commit_after>/*jslint node: true */
'use strict';

/**
 * @constructor
 */
var SilexJS = function() {
  this._readConfig();
  this._route();
  this._initializeApp();
  this.HTTP = require('./http');
};

/**
 * @method _route
 * @private
 */
SilexJS.prototype._route = function() {
  var Router = require('./router');
  this.Router = new Router();
};

/**
 * @method _initializeApp
 * @private
 */
SilexJS.prototype._initializeApp = function() {
  var App = require('./app');
  this.App = new App(this.Router);
};

/**
 * @method _readConfig
 * @private
 */
SilexJS.prototype._readConfig = function() {
  try {
    var path = require('path');
    this.config = require(path.dirname(module.parent.filename) + '/config.json');
  } catch (e) {
    // Loading default configuration
    console.log('configuration fallback');
    this.config = require('./config/default.json');
  }
};

/**
 * @method start
 * @public
 */
SilexJS.prototype.start = function () {
  var http = require('http');
  var self = this;

  http.createServer(function (req, res) {
    self.Router.dispatch(req, res);
  }).listen(this.config.port);

};

module.exports = new SilexJS();
<|endoftext|>


<commit_before>/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
/*global module, require, __dirname, document*/
/**
 * Sinon core utilities. For internal use only.
 *
 * @author Christian Johansen (christian@cjohansen.no)
 * @license BSD
 *
 * Copyright (c) 2010-2011 Christian Johansen
 */
"use strict";

var sinon = (function (buster) {
    var div = typeof document != "undefined" && document.createElement("div");
    var hasOwn = Object.prototype.hasOwnProperty;

    function isDOMNode(obj) {
        var success = false;

        try {
            obj.appendChild(div);
            success = div.parentNode == obj;
        } catch (e) {
            return false;
        } finally {
            try {
                obj.removeChild(div);
            } catch (e) {
                // Remove failed, not much we can do about that
            }
        }

        return success;
    }

    function isElement(obj) {
        return div && obj && obj.nodeType === 1 && isDOMNode(obj);
    }

    function isFunction(obj) {
    	return !!(obj && obj.constructor && obj.call && obj.apply);
    }

    function mirrorProperties(target, source) {
        for (var prop in source) {
            if (!hasOwn.call(target, prop)) {
                target[prop] = source[prop];
            }
        }
    }

    var sinon = {
        wrapMethod: function wrapMethod(object, property, method) {
            if (!object) {
                throw new TypeError("Should wrap property of object");
            }

            if (typeof method != "function") {
                throw new TypeError("Method wrapper should be function");
            }

            var wrappedMethod = object[property];

            if (!isFunction(wrappedMethod)) {
                throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
                                    property + " as function");
            }

            if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
                throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
            }

            if (wrappedMethod.calledBefore) {
                var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
                throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
            }

            // IE 8 does not support hasOwnProperty on the window object.
            var owned = hasOwn.call(object, property);
            object[property] = method;
            method.displayName = property;

            method.restore = function () {
                if(owned) {
                    object[property] = wrappedMethod;
                } else {
                    delete object[property];
                }
            };

            method.restore.sinon = true;
            mirrorProperties(method, wrappedMethod);

            return method;
        },

        extend: function extend(target) {
            for (var i = 1, l = arguments.length; i < l; i += 1) {
                for (var prop in arguments[i]) {
                    if (arguments[i].hasOwnProperty(prop)) {
                        target[prop] = arguments[i][prop];
                    }

                    // DONT ENUM bug, only care about toString
                    if (arguments[i].hasOwnProperty("toString") &&
                        arguments[i].toString != target.toString) {
                        target.toString = arguments[i].toString;
                    }
                }
            }

            return target;
        },

        create: function create(proto) {
            var F = function () {};
            F.prototype = proto;
            return new F();
        },

        deepEqual: function deepEqual(a, b) {
            if (typeof a != "object" || typeof b != "object") {
                return a === b;
            }

            if (isElement(a) || isElement(b)) {
                return a === b;
            }

            if (a === b) {
                return true;
            }

            var aString = Object.prototype.toString.call(a);
            if (aString != Object.prototype.toString.call(b)) {
                return false;
            }

            if (aString == "[object Array]") {
                if (a.length !== b.length) {
                    return false;
                }

                for (var i = 0, l = a.length; i < l; i += 1) {
                    if (!deepEqual(a[i], b[i])) {
                        return false;
                    }
                }

                return true;
            }

            var prop, aLength = 0, bLength = 0;

            for (prop in a) {
                aLength += 1;

                if (!deepEqual(a[prop], b[prop])) {
                    return false;
                }
            }

            for (prop in b) {
                bLength += 1;
            }

            if (aLength != bLength) {
                return false;
            }

            return true;
        },

        functionName: function functionName(func) {
            var name = func.displayName || func.name;

            // Use function decomposition as a last resort to get function
            // name. Does not rely on function decomposition to work - if it
            // doesn't debugging will be slightly less informative
            // (i.e. toString will say 'spy' rather than 'myFunc').
            if (!name) {
                var matches = func.toString().match(/function ([^\s\(]+)/);
                name = matches && matches[1];
            }

            return name;
        },

        functionToString: function toString() {
            if (this.getCall && this.callCount) {
                var thisValue, prop, i = this.callCount;

                while (i--) {
                    thisValue = this.getCall(i).thisValue;

                    for (prop in thisValue) {
                        if (thisValue[prop] === this) {
                            return prop;
                        }
                    }
                }
            }

            return this.displayName || "sinon fake";
        },

        getConfig: function (custom) {
            var config = {};
            custom = custom || {};
            var defaults = sinon.defaultConfig;

            for (var prop in defaults) {
                if (defaults.hasOwnProperty(prop)) {
                    config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
                }
            }

            return config;
        },

        format: function (val) {
            return "" + val;
        },

        defaultConfig: {
            injectIntoThis: true,
            injectInto: null,
            properties: ["spy", "stub", "mock", "clock", "server", "requests"],
            useFakeTimers: true,
            useFakeServer: true
        },

        timesInWords: function timesInWords(count) {
            return count == 1 && "once" ||
                count == 2 && "twice" ||
                count == 3 && "thrice" ||
                (count || 0) + " times";
        },

        calledInOrder: function (spies) {
            for (var i = 1, l = spies.length; i < l; i++) {
                if (!spies[i - 1].calledBefore(spies[i])) {
                    return false;
                }
            }

            return true;
        },

        orderByFirstCall: function (spies) {
            return spies.sort(function (a, b) {
                // uuid, won't ever be equal
                var aCall = a.getCall(0);
                var bCall = b.getCall(0);
                var aId = aCall && aCall.callId || -1;
                var bId = bCall && bCall.callId || -1;

                return aId < bId ? -1 : 1;
            });
        },

        log: function () {},

        logError: function (label, err) {
            var msg = label + " threw exception: "
            sinon.log(msg + "[" + err.name + "] " + err.message);
            if (err.stack) { sinon.log(err.stack); }

            setTimeout(function () {
                err.message = msg + err.message;
                throw err;
            }, 0);
        }
    };

    var isNode = typeof module == "object" && typeof require == "function";

    if (isNode) {
        try {
            buster = { format: require("buster-format") };
        } catch (e) {}
        module.exports = sinon;
        module.exports.spy = require("./sinon/spy");
        module.exports.stub = require("./sinon/stub");
        module.exports.mock = require("./sinon/mock");
        module.exports.collection = require("./sinon/collection");
        module.exports.assert = require("./sinon/assert");
        module.exports.sandbox = require("./sinon/sandbox");
        module.exports.test = require("./sinon/test");
        module.exports.testCase = require("./sinon/test_case");
        module.exports.assert = require("./sinon/assert");
    }

    if (buster) {
        var formatter = sinon.create(buster.format);
        formatter.quoteStrings = false;
        sinon.format = function () {
            return formatter.ascii.apply(formatter, arguments);
        };
    } else if (isNode) {
        try {
            var util = require("util");
            sinon.format = function (value) {
                return typeof value == "object" ? util.inspect(value) : value;
            };
        } catch (e) {
            /* Node, but no util module - would be very old, but better safe than
               sorry */
        }
    }

    return sinon;
}(typeof buster == "object" && buster));
<commit_msg>Another go at the formatting problem ... <commit_after>/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
/*global module, require, __dirname, document*/
/**
 * Sinon core utilities. For internal use only.
 *
 * @author Christian Johansen (christian@cjohansen.no)
 * @license BSD
 *
 * Copyright (c) 2010-2011 Christian Johansen
 */
"use strict";

var sinon = (function (buster) {
    var div = typeof document != "undefined" && document.createElement("div");
    var hasOwn = Object.prototype.hasOwnProperty;

    function isDOMNode(obj) {
        var success = false;

        try {
            obj.appendChild(div);
            success = div.parentNode == obj;
        } catch (e) {
            return false;
        } finally {
            try {
                obj.removeChild(div);
            } catch (e) {
                // Remove failed, not much we can do about that
            }
        }

        return success;
    }

    function isElement(obj) {
        return div && obj && obj.nodeType === 1 && isDOMNode(obj);
    }

    function isFunction(obj) {
        return !!(obj && obj.constructor && obj.call && obj.apply);
    }

    function mirrorProperties(target, source) {
        for (var prop in source) {
            if (!hasOwn.call(target, prop)) {
                target[prop] = source[prop];
            }
        }
    }

    var sinon = {
        wrapMethod: function wrapMethod(object, property, method) {
            if (!object) {
                throw new TypeError("Should wrap property of object");
            }

            if (typeof method != "function") {
                throw new TypeError("Method wrapper should be function");
            }

            var wrappedMethod = object[property];

            if (!isFunction(wrappedMethod)) {
                throw new TypeError("Attempted to wrap " + (typeof wrappedMethod) + " property " +
                                    property + " as function");
            }

            if (wrappedMethod.restore && wrappedMethod.restore.sinon) {
                throw new TypeError("Attempted to wrap " + property + " which is already wrapped");
            }

            if (wrappedMethod.calledBefore) {
                var verb = !!wrappedMethod.returns ? "stubbed" : "spied on";
                throw new TypeError("Attempted to wrap " + property + " which is already " + verb);
            }

            // IE 8 does not support hasOwnProperty on the window object.
            var owned = hasOwn.call(object, property);
            object[property] = method;
            method.displayName = property;

            method.restore = function () {
                if(owned) {
                    object[property] = wrappedMethod;
                } else {
                    delete object[property];
                }
            };

            method.restore.sinon = true;
            mirrorProperties(method, wrappedMethod);

            return method;
        },

        extend: function extend(target) {
            for (var i = 1, l = arguments.length; i < l; i += 1) {
                for (var prop in arguments[i]) {
                    if (arguments[i].hasOwnProperty(prop)) {
                        target[prop] = arguments[i][prop];
                    }

                    // DONT ENUM bug, only care about toString
                    if (arguments[i].hasOwnProperty("toString") &&
                        arguments[i].toString != target.toString) {
                        target.toString = arguments[i].toString;
                    }
                }
            }

            return target;
        },

        create: function create(proto) {
            var F = function () {};
            F.prototype = proto;
            return new F();
        },

        deepEqual: function deepEqual(a, b) {
            if (typeof a != "object" || typeof b != "object") {
                return a === b;
            }

            if (isElement(a) || isElement(b)) {
                return a === b;
            }

            if (a === b) {
                return true;
            }

            var aString = Object.prototype.toString.call(a);
            if (aString != Object.prototype.toString.call(b)) {
                return false;
            }

            if (aString == "[object Array]") {
                if (a.length !== b.length) {
                    return false;
                }

                for (var i = 0, l = a.length; i < l; i += 1) {
                    if (!deepEqual(a[i], b[i])) {
                        return false;
                    }
                }

                return true;
            }

            var prop, aLength = 0, bLength = 0;

            for (prop in a) {
                aLength += 1;

                if (!deepEqual(a[prop], b[prop])) {
                    return false;
                }
            }

            for (prop in b) {
                bLength += 1;
            }

            if (aLength != bLength) {
                return false;
            }

            return true;
        },

        functionName: function functionName(func) {
            var name = func.displayName || func.name;

            // Use function decomposition as a last resort to get function
            // name. Does not rely on function decomposition to work - if it
            // doesn't debugging will be slightly less informative
            // (i.e. toString will say 'spy' rather than 'myFunc').
            if (!name) {
                var matches = func.toString().match(/function ([^\s\(]+)/);
                name = matches && matches[1];
            }

            return name;
        },

        functionToString: function toString() {
            if (this.getCall && this.callCount) {
                var thisValue, prop, i = this.callCount;

                while (i--) {
                    thisValue = this.getCall(i).thisValue;

                    for (prop in thisValue) {
                        if (thisValue[prop] === this) {
                            return prop;
                        }
                    }
                }
            }

            return this.displayName || "sinon fake";
        },

        getConfig: function (custom) {
            var config = {};
            custom = custom || {};
            var defaults = sinon.defaultConfig;

            for (var prop in defaults) {
                if (defaults.hasOwnProperty(prop)) {
                    config[prop] = custom.hasOwnProperty(prop) ? custom[prop] : defaults[prop];
                }
            }

            return config;
        },

        format: function (val) {
            return "" + val;
        },

        defaultConfig: {
            injectIntoThis: true,
            injectInto: null,
            properties: ["spy", "stub", "mock", "clock", "server", "requests"],
            useFakeTimers: true,
            useFakeServer: true
        },

        timesInWords: function timesInWords(count) {
            return count == 1 && "once" ||
                count == 2 && "twice" ||
                count == 3 && "thrice" ||
                (count || 0) + " times";
        },

        calledInOrder: function (spies) {
            for (var i = 1, l = spies.length; i < l; i++) {
                if (!spies[i - 1].calledBefore(spies[i])) {
                    return false;
                }
            }

            return true;
        },

        orderByFirstCall: function (spies) {
            return spies.sort(function (a, b) {
                // uuid, won't ever be equal
                var aCall = a.getCall(0);
                var bCall = b.getCall(0);
                var aId = aCall && aCall.callId || -1;
                var bId = bCall && bCall.callId || -1;

                return aId < bId ? -1 : 1;
            });
        },

        log: function () {},

        logError: function (label, err) {
            var msg = label + " threw exception: "
            sinon.log(msg + "[" + err.name + "] " + err.message);
            if (err.stack) { sinon.log(err.stack); }

            setTimeout(function () {
                err.message = msg + err.message;
                throw err;
            }, 0);
        }
    };

    var isNode = typeof module == "object" && typeof require == "function";

    if (isNode) {
        try {
            buster = { format: require("buster-format") };
        } catch (e) {}
        module.exports = sinon;
        module.exports.spy = require("./sinon/spy");
        module.exports.stub = require("./sinon/stub");
        module.exports.mock = require("./sinon/mock");
        module.exports.collection = require("./sinon/collection");
        module.exports.assert = require("./sinon/assert");
        module.exports.sandbox = require("./sinon/sandbox");
        module.exports.test = require("./sinon/test");
        module.exports.testCase = require("./sinon/test_case");
        module.exports.assert = require("./sinon/assert");
    }

    if (buster) {
        var formatter = sinon.create(buster.format);
        formatter.quoteStrings = false;
        sinon.format = function () {
            return formatter.ascii.apply(formatter, arguments);
        };
    } else if (isNode) {
        try {
            var util = require("util");
            sinon.format = function (value) {
                return typeof value == "object" ? util.inspect(value) : value;
            };
        } catch (e) {
            /* Node, but no util module - would be very old, but better safe than
               sorry */
        }
    }

    return sinon;
}(typeof buster == "object" && buster));
<|endoftext|>


<commit_before>/**
 * Library methods for styles and css tasks
 *
 * @author Nikhil Modak
 */

'use strict';
var SKIN_FILES_PATTERN = '**/*(*.css|*.scss|*.sass|*.ftl|*.png|*.svg|*.jpg|*.jpeg|skin.properties)';
var lazyReq = require('lazy-req')(require);
var sass = lazyReq('gulp-sass');
var connect = lazyReq('gulp-connect');
var sourcemaps = lazyReq('gulp-sourcemaps');
var rename = lazyReq('gulp-rename');
var plumber = lazyReq('gulp-plumber');
var replace = lazyReq('gulp-replace');
var concat = lazyReq('gulp-concat');
var gulpif = lazyReq('gulp-if');
var newer = lazyReq('gulp-newer');
var fs = lazyReq('fs');
var fsExtra = lazyReq('fs-extra');
var del = lazyReq('del');
var putils = require('./plugin-utils');
var streamSync = require('./stream-sync');
var url = require('url');
var path = require('path');
var request = require('request');

module.exports = function (gulp, gutil) {
  var server;
  var responsiveOptions;
  var pluginExport;
  var skinLib = require('./skin')(gulp, gutil);
  var baseSassPath = 'res/skins/bootstrap_base/sass/';
  var peakSassPath = 'res/skins/responsive_peak/sass/';

  function getServer() {
    return server ? server : server = require('./server.js')(gulp, gutil);
  }

  function getResponsiveOptions() {
    return responsiveOptions ? responsiveOptions : responsiveOptions = require('./responsive-options.js')(gulp, gutil);
  }

  function getPluginExport() {
    return pluginExport ? pluginExport : pluginExport = require('./plugin-export.js')(gulp, gutil);
  }

  /**
   * Util method for downloading url to a file specified in dest. The method copies content to a tmp file and renames
   * the file once download is finished.
   * @param url Url for download
   * @param options Request options
   * @param dest file path to destination
   * @param cb Callback function for success or error.
     */
  function downloadFile(url, options, dest, cb) {
    var file = fs().createWriteStream(dest + ".tmp");
    var sendReq = request.get(url, options);
    var errorOnDownload = false;
    // verify response code
    sendReq.on('response', function(response) {
      if (response.statusCode !== 200) {
        errorOnDownload = true;
        return cb('Response status was ' + response.statusCode);
      }
    });
    // check for request errors
    sendReq.on('error', function (err) {
      fs().unlink(file.path);
      if (cb) {
        return cb(err.message);
      }
    });
    sendReq.pipe(file);
    file.on('finish', function() {
      file.close();
      if (!errorOnDownload) {
        fs().renameSync(dest + ".tmp", dest);
        cb("Successfully downloaded asset = " + dest);
      } else{
        fs().unlinkSync(dest + ".tmp");
      }
    });
    file.on('error', function(err) { // Handle errors
      fs().unlink(dest); // Delete the tmp file
      if (cb) {
        return cb(err.message);
      }
    });
  }

  var cors = function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Headers', '*');
    next();
  };

  /**
   * Filter for downloading mostly image assets right before they are served from local server.
   */
  var downloadAssets = function (req, res, next) {

    var assetUrl = req.originalUrl;
    var matches = assetUrl.match(/\/html\/(\S+)/);
    //Ignore urls not matching asset endpoints
    if (!matches) {
      next();
      return;
    }

    if (matches.length < 2) {
      //Url does not match
      putils.logDebug(gutil, "No file path specified in asset url. Ignoring download for "+assetUrl);
      next();
      return;
    }
    var assetPath = path().join(matches[1]);
    var fileSystemAssetPath = path().join("web/html", assetPath);
    var pathExists = fs().existsSync(fileSystemAssetPath);
    if (pathExists) {
      //File already served from web/html
      next();
      return;
    }

    var server = getServer();
    var tmpFilePath = path().join(server.localServerDir(), "html", assetPath);
    pathExists = fs().existsSync(tmpFilePath);
    if (pathExists && fs().statSync(tmpFilePath)["size"] > 0) {
      //File already downloaded to tmp.
      next();
      return;
    }

    var tmpDirPath = path().join(server.localServerDir(), "html", path().dirname(assetPath));
    fsExtra().mkdirsSync(tmpDirPath);
    var options = {
      rejectUnauthorized: false
    };
    var urlBld = putils.urlBldr(server.serverUrl());
    var serverAssetUrl = urlBld.add(assetUrl).build();
    downloadFile(serverAssetUrl, options, tmpFilePath, function(message) {
      putils.logDebug(gutil, message);
      next();
    });
  }

  function doCompile(opts) {
    var skinPath = opts.includePathsPrefix + 'res/feature/' + opts.feature + '/' + opts.version + '/res/skins/' + opts.skin + '/sass/skin.scss';
    if (opts.skin != 'responsive_peak' && opts.skin != 'responsive_base') {
      skinPath = opts.skinPathPrefix + 'res/skins/' + opts.skin + '/sass/skin.scss';
    }
    if (opts.debugMode) {
      putils.logDebug(gutil, 'skinPath: ' + skinPath);
      putils.logDebug(gutil, 'includePaths: ' + opts.includePaths);
    }

    var lr = opts.lr;
    return gulp.src(skinPath)
      .pipe(lr ? plumber()() : gutil.noop())
      .pipe(sourcemaps().init())
      .pipe(sass()({
        includePaths: opts.includePaths,
        precision: 10
      }))
      .pipe(sourcemaps().write())
      .pipe(rename()(opts.skin + '.css'))
      .pipe(gulp.dest(opts.dest))
      .pipe(lr ? lr() : gutil.noop());
  }

  function debug(opts, msg) {
    if (opts.debugMode) {
      putils.logDebug(gutil, msg);
    }
  }

  function findCoreSkin(skin) {
    if (skin) {
      var responsiveSkin = skinLib.lookupResponsiveSkin(skin);
      if (responsiveSkin) {
        return responsiveSkin.getResponsiveCoreId();
      }
    }
    return null;
  }

  function setOptionsFromConfig(config, opts) {
    if (config.dev_skin) {
      opts.skin = config.dev_skin.id;
      debug(opts, 'found skin: ' + opts.skin);
      var coreSkin = findCoreSkin(opts.skin);
      debug(opts, 'coreSkin: ' + coreSkin);
      if (config.skin[coreSkin]) {
        opts.feature = config.skin[coreSkin].feature_id;
        debug(opts, 'found feature: ' + opts.feature);
        if (config.feature[opts.feature]) {
          opts.version = config.feature[opts.feature].fq_version;
          debug(opts, 'found version: ' + opts.version);
        }
      }
      opts.localServerPort = url.parse(config.dev_skin.url).port;
    }

    return opts;
  }

  function getDefaultOptions(server) {
    var version = server.localSkinCompileVersion();
    return {
      debugMode: gutil.env['debug'],
      verboseMode: gutil.env['verbose'],
      configDir: server.configDir(),
      version: version,
      feature: server.localSkinCompileFeature(),
      skin: server.localSkinCompileSkin(),
      dest: server.localSkinCompileDest(),
      localServerDir: server.localServerDir(),
      localServerPort: server.localServerPort(),
      includePathsPrefix: '',
      skinPathPrefix: '',
      includePaths: [
        skinLib.peakFeaturePath + version + '/' + skinLib.skinsBaseDir,
        skinLib.baseFeaturePath + version + '/' + skinLib.skinsBaseDir,
        skinLib.baseFeaturePath+ '/common/res/skins/'
      ],
      doClear: false
    };
  }

  /**
   * Creates a brand new skin directory structure. If responsive skin, copies sass files from parent.
   * If non responsive skin, copies skin properties to desktop and mobile sub structures.
   * Initializes empty components dirs.
   */
  function createNewSkin(skinInfo) {
    //Create a dir with the skinId
    var skinDir = path.resolve(skinLib.skinsBaseDir, skinInfo.name);
    var fileSystem = fs();
    fileSystem.mkdirSync(skinDir, skinInfo.errorCb);

    //Create skin properties
    var propertiesPath = path.resolve(skinDir, 'skin.properties');
    var skinProperties = {};
    skinProperties['title'] = skinInfo.name;
    skinProperties['parent'] = skinInfo.parentSkin.getId();

    var sassFilesToCopy = skinInfo.parentSkin.lookupProperty(skinLib.skinPropertyCopySass);

    var stream = fileSystem.createWriteStream(propertiesPath);
    stream.once('open', function(fd) {
      Object.keys(skinProperties).forEach(function (key) {
        stream.write(key + ' = ' + skinProperties[key] + '\n');
      });
      if (sassFilesToCopy) {
        sassFilesToCopy.forEach(function (key) {
          stream.write( skinLib.skinPropertyCopySass + ' += ' + key + '\n');
        });
      }
      stream.end();
    });

    var createSkinDirectoryStructure = function() {
        if (skinInfo.isResponsive) {
          //Create sass folder
          fileSystem.mkdirSync(path.join(skinDir, skinLib.sassDir), skinInfo.errorCb);
          //Copy all sass files - wait until copy
          if (sassFilesToCopy) {
            sassFilesToCopy.forEach(function (key) {
              fileSystem.writeFileSync(path.resolve(skinDir, skinLib.sassDir, key),
                  fileSystem.readFileSync(path.resolve(skinInfo.parentSkin.getDir(), skinLib.sassDir, key)));
            });
          } else {
            putils.logWarning(gutil, "No sass properties read from responsive parent for skin="+skinInfo.name+". This will not copy " +
                " any sass assets for your new skin!");
          }
          //Create a component dir
          fileSystem.mkdirSync(path.join(skinDir, skinLib.componentsDir), skinInfo.errorCb);
        } else {
          //Create desktop and mobile subsections
          //Copy all skin property files - wait until copy
          skinLib.skinSubFolder.forEach(function(folder) {
            fileSystem.mkdirSync(path.join(skinDir, folder), skinInfo.errorCb);
            fileSystem.writeFileSync(path.resolve(skinDir, folder, skinLib.skinPropertiesFileName),
                fileSystem.readFileSync(path.resolve(skinDir, skinLib.skinPropertiesFileName)));
            //Create a components dir
            fileSystem.mkdirSync(path.join(skinDir, folder, skinLib.componentsDir), skinInfo.errorCb);
            fileSystem.mkdirSync(path.join(skinDir, folder, skinLib.cssDir), skinInfo.errorCb);
          });
        }
    };
    stream.on('finish', function() {
      try {
        createSkinDirectoryStructure();
        skinInfo.cb();
      } catch (err) {
        skinInfo.errorCb(err);
      }
    });
    return stream;
  }

  return {
    process: function (patterns, dest, files) {
      return gulp.src(patterns)
        .pipe(gutil.env.filterFiles(files))
        .pipe(gulp.dest(dest));
    },
    compile: function (delCoreOutputDir, lr) {
      var server = getServer();
      var opts = getDefaultOptions(server);
      opts.lr = lr;
      opts.coreOutputDir = gutil.env['todir'] || server.coreOutputDir();

      if (server.useResponsiveConfigsFromServer()) {
        var responsiveOptions = function() {
          return getResponsiveOptions().getOptions(server, opts, function (err, config) {
            if (err) throw err;
            opts = setOptionsFromConfig(config, opts);
            opts.coreOutputDir = gutil.env['todir'] || server.coreOutputDir();
            opts.includePathsPrefix = opts.coreOutputDir + '/';
            opts.includePaths = [
              opts.includePathsPrefix + 'res/feature/responsivepeak/' + opts.version + '/res/skins/',
              opts.includePathsPrefix + 'res/feature/responsivebase/' + opts.version + '/res/skins/',
              opts.includePathsPrefix + 'res/feature/responsivebase/common/res/skins/',
              'res/skins'
            ];

            return doCompile(opts);
          });
        };

        var corePluginFiles = function() {
          return getPluginExport().exportCorePlugin(server, opts, undefined, function () {});
        };

        var fileSystem = fs();

        var coreOutputDirExists = fileSystem.existsSync(opts.coreOutputDir);

        if (coreOutputDirExists && gutil.env['force'] && delCoreOutputDir) {
          del().sync(opts.coreOutputDir, { force: true });
          coreOutputDirExists = false;
        }

        if (!coreOutputDirExists) {
          return streamSync([corePluginFiles, responsiveOptions]);
        } else {
          return responsiveOptions();
        }
      } else {
        return doCompile(opts);
      }
    },
    doCompile: doCompile,
    server: function () {
      var server = getServer();
      var opts = getDefaultOptions(server);

      var runServer = function() {
        connect().server({
          root: [
            opts.localServerDir,
            'web'
          ],
          port: opts.localServerPort,
          middleware: function () {
            return [cors, downloadAssets];
          }
        });
      };

      if (server.useResponsiveConfigsFromServer()) {
        var setOptsFromConfig = function() {
          return getResponsiveOptions().getOptions(server, opts, function (err, config) {
            if (err) throw err;
            opts = setOptionsFromConfig(config, opts);
            return runServer();
          });
        };

        return setOptsFromConfig();
      } else {
        return runServer();
      }
    },
    vars: function () {
      var server = getServer();

      var varsPath = 'codebook/_variables-*.scss';

      function getSkinVersions(dir) {
        try {
          fs().accessSync(dir, fs().F_OK);
          return fs().readdirSync(dir)
            .filter(function (file) {
              return fs().statSync(path().join(dir, file)).isDirectory();
            });
        } catch (e) {
          if (!server.useResponsiveConfigsFromServer()) {
            gutil.log(gutil.colors.red('Warning: Skin feature path not found (this is expected for <= 15.11): ', dir));
          }
          return [];
        }
      }

      var peakVars = getSkinVersions(skinLib.peakFeaturePath).map(function (version) {
        return gulp.src([path().join(skinLib.baseFeaturePath, version, '**', varsPath),
          path().join(skinLib.peakFeaturePath, version, '**', varsPath)])
          .pipe(newer()(path().join(skinLib.peakFeaturePath, version, peakSassPath, '_variables.scss')))
          .pipe(replace()('!default', ''))
          .pipe(replace()(/^\s*(\$.*)/gm, '//$1'))
          .pipe(replace()(/(\s*);/gm, ';'))
          .pipe(rename()('_variables.scss'))
          .pipe(gulpif()(function (file) {
              return file.path.indexOf(skinLib.baseFeaturePath) >= 0;
            },
            gulp.dest(path().join(skinLib.baseFeaturePath, version, baseSassPath))))
          .pipe(concat()('_variables.scss'))
          .pipe(gulp.dest(path().join(skinLib.peakFeaturePath, version, peakSassPath)));
      });
      return peakVars;
    },
    FILES_PATTERN: SKIN_FILES_PATTERN,
    createNewSkin: function(skinInfo) {
      return createNewSkin(skinInfo);
    },
    downloadFile: downloadFile
  };
};
<commit_msg>Fix path references to use non-lazyReq version.<commit_after>/**
 * Library methods for styles and css tasks
 *
 * @author Nikhil Modak
 */

'use strict';
var SKIN_FILES_PATTERN = '**/*(*.css|*.scss|*.sass|*.ftl|*.png|*.svg|*.jpg|*.jpeg|skin.properties)';
var lazyReq = require('lazy-req')(require);
var sass = lazyReq('gulp-sass');
var connect = lazyReq('gulp-connect');
var sourcemaps = lazyReq('gulp-sourcemaps');
var rename = lazyReq('gulp-rename');
var plumber = lazyReq('gulp-plumber');
var replace = lazyReq('gulp-replace');
var concat = lazyReq('gulp-concat');
var gulpif = lazyReq('gulp-if');
var newer = lazyReq('gulp-newer');
var fs = lazyReq('fs');
var fsExtra = lazyReq('fs-extra');
var del = lazyReq('del');
var putils = require('./plugin-utils');
var streamSync = require('./stream-sync');
var url = require('url');
var path = require('path');
var request = require('request');

module.exports = function (gulp, gutil) {
  var server;
  var responsiveOptions;
  var pluginExport;
  var skinLib = require('./skin')(gulp, gutil);
  var baseSassPath = 'res/skins/bootstrap_base/sass/';
  var peakSassPath = 'res/skins/responsive_peak/sass/';

  function getServer() {
    return server ? server : server = require('./server.js')(gulp, gutil);
  }

  function getResponsiveOptions() {
    return responsiveOptions ? responsiveOptions : responsiveOptions = require('./responsive-options.js')(gulp, gutil);
  }

  function getPluginExport() {
    return pluginExport ? pluginExport : pluginExport = require('./plugin-export.js')(gulp, gutil);
  }

  /**
   * Util method for downloading url to a file specified in dest. The method copies content to a tmp file and renames
   * the file once download is finished.
   * @param url Url for download
   * @param options Request options
   * @param dest file path to destination
   * @param cb Callback function for success or error.
     */
  function downloadFile(url, options, dest, cb) {
    var file = fs().createWriteStream(dest + ".tmp");
    var sendReq = request.get(url, options);
    var errorOnDownload = false;
    // verify response code
    sendReq.on('response', function(response) {
      if (response.statusCode !== 200) {
        errorOnDownload = true;
        return cb('Response status was ' + response.statusCode);
      }
    });
    // check for request errors
    sendReq.on('error', function (err) {
      fs().unlink(file.path);
      if (cb) {
        return cb(err.message);
      }
    });
    sendReq.pipe(file);
    file.on('finish', function() {
      file.close();
      if (!errorOnDownload) {
        fs().renameSync(dest + ".tmp", dest);
        cb("Successfully downloaded asset = " + dest);
      } else{
        fs().unlinkSync(dest + ".tmp");
      }
    });
    file.on('error', function(err) { // Handle errors
      fs().unlink(dest); // Delete the tmp file
      if (cb) {
        return cb(err.message);
      }
    });
  }

  var cors = function (req, res, next) {
    res.setHeader('Access-Control-Allow-Origin', '*');
    res.setHeader('Access-Control-Allow-Headers', '*');
    next();
  };

  /**
   * Filter for downloading mostly image assets right before they are served from local server.
   */
  var downloadAssets = function (req, res, next) {

    var assetUrl = req.originalUrl;
    var matches = assetUrl.match(/\/html\/(\S+)/);
    //Ignore urls not matching asset endpoints
    if (!matches) {
      next();
      return;
    }

    if (matches.length < 2) {
      //Url does not match
      putils.logDebug(gutil, "No file path specified in asset url. Ignoring download for "+assetUrl);
      next();
      return;
    }
    var assetPath = path.join(matches[1]);
    var fileSystemAssetPath = path.join("web/html", assetPath);
    var pathExists = fs().existsSync(fileSystemAssetPath);
    if (pathExists) {
      //File already served from web/html
      next();
      return;
    }

    var server = getServer();
    var tmpFilePath = path.join(server.localServerDir(), "html", assetPath);
    pathExists = fs().existsSync(tmpFilePath);
    if (pathExists && fs().statSync(tmpFilePath)["size"] > 0) {
      //File already downloaded to tmp.
      next();
      return;
    }

    var tmpDirPath = path.join(server.localServerDir(), "html", path.dirname(assetPath));
    fsExtra().mkdirsSync(tmpDirPath);
    var options = {
      rejectUnauthorized: false
    };
    var urlBld = putils.urlBldr(server.serverUrl());
    var serverAssetUrl = urlBld.add(assetUrl).build();
    downloadFile(serverAssetUrl, options, tmpFilePath, function(message) {
      putils.logDebug(gutil, message);
      next();
    });
  }

  function doCompile(opts) {
    var skinPath = opts.includePathsPrefix + 'res/feature/' + opts.feature + '/' + opts.version + '/res/skins/' + opts.skin + '/sass/skin.scss';
    if (opts.skin != 'responsive_peak' && opts.skin != 'responsive_base') {
      skinPath = opts.skinPathPrefix + 'res/skins/' + opts.skin + '/sass/skin.scss';
    }
    if (opts.debugMode) {
      putils.logDebug(gutil, 'skinPath: ' + skinPath);
      putils.logDebug(gutil, 'includePaths: ' + opts.includePaths);
    }

    var lr = opts.lr;
    return gulp.src(skinPath)
      .pipe(lr ? plumber()() : gutil.noop())
      .pipe(sourcemaps().init())
      .pipe(sass()({
        includePaths: opts.includePaths,
        precision: 10
      }))
      .pipe(sourcemaps().write())
      .pipe(rename()(opts.skin + '.css'))
      .pipe(gulp.dest(opts.dest))
      .pipe(lr ? lr() : gutil.noop());
  }

  function debug(opts, msg) {
    if (opts.debugMode) {
      putils.logDebug(gutil, msg);
    }
  }

  function findCoreSkin(skin) {
    if (skin) {
      var responsiveSkin = skinLib.lookupResponsiveSkin(skin);
      if (responsiveSkin) {
        return responsiveSkin.getResponsiveCoreId();
      }
    }
    return null;
  }

  function setOptionsFromConfig(config, opts) {
    if (config.dev_skin) {
      opts.skin = config.dev_skin.id;
      debug(opts, 'found skin: ' + opts.skin);
      var coreSkin = findCoreSkin(opts.skin);
      debug(opts, 'coreSkin: ' + coreSkin);
      if (config.skin[coreSkin]) {
        opts.feature = config.skin[coreSkin].feature_id;
        debug(opts, 'found feature: ' + opts.feature);
        if (config.feature[opts.feature]) {
          opts.version = config.feature[opts.feature].fq_version;
          debug(opts, 'found version: ' + opts.version);
        }
      }
      opts.localServerPort = url.parse(config.dev_skin.url).port;
    }

    return opts;
  }

  function getDefaultOptions(server) {
    var version = server.localSkinCompileVersion();
    return {
      debugMode: gutil.env['debug'],
      verboseMode: gutil.env['verbose'],
      configDir: server.configDir(),
      version: version,
      feature: server.localSkinCompileFeature(),
      skin: server.localSkinCompileSkin(),
      dest: server.localSkinCompileDest(),
      localServerDir: server.localServerDir(),
      localServerPort: server.localServerPort(),
      includePathsPrefix: '',
      skinPathPrefix: '',
      includePaths: [
        skinLib.peakFeaturePath + version + '/' + skinLib.skinsBaseDir,
        skinLib.baseFeaturePath + version + '/' + skinLib.skinsBaseDir,
        skinLib.baseFeaturePath+ '/common/res/skins/'
      ],
      doClear: false
    };
  }

  /**
   * Creates a brand new skin directory structure. If responsive skin, copies sass files from parent.
   * If non responsive skin, copies skin properties to desktop and mobile sub structures.
   * Initializes empty components dirs.
   */
  function createNewSkin(skinInfo) {
    //Create a dir with the skinId
    var skinDir = path.resolve(skinLib.skinsBaseDir, skinInfo.name);
    var fileSystem = fs();
    fileSystem.mkdirSync(skinDir, skinInfo.errorCb);

    //Create skin properties
    var propertiesPath = path.resolve(skinDir, 'skin.properties');
    var skinProperties = {};
    skinProperties['title'] = skinInfo.name;
    skinProperties['parent'] = skinInfo.parentSkin.getId();

    var sassFilesToCopy = skinInfo.parentSkin.lookupProperty(skinLib.skinPropertyCopySass);

    var stream = fileSystem.createWriteStream(propertiesPath);
    stream.once('open', function(fd) {
      Object.keys(skinProperties).forEach(function (key) {
        stream.write(key + ' = ' + skinProperties[key] + '\n');
      });
      if (sassFilesToCopy) {
        sassFilesToCopy.forEach(function (key) {
          stream.write( skinLib.skinPropertyCopySass + ' += ' + key + '\n');
        });
      }
      stream.end();
    });

    var createSkinDirectoryStructure = function() {
        if (skinInfo.isResponsive) {
          //Create sass folder
          fileSystem.mkdirSync(path.join(skinDir, skinLib.sassDir), skinInfo.errorCb);
          //Copy all sass files - wait until copy
          if (sassFilesToCopy) {
            sassFilesToCopy.forEach(function (key) {
              fileSystem.writeFileSync(path.resolve(skinDir, skinLib.sassDir, key),
                  fileSystem.readFileSync(path.resolve(skinInfo.parentSkin.getDir(), skinLib.sassDir, key)));
            });
          } else {
            putils.logWarning(gutil, "No sass properties read from responsive parent for skin="+skinInfo.name+". This will not copy " +
                " any sass assets for your new skin!");
          }
          //Create a component dir
          fileSystem.mkdirSync(path.join(skinDir, skinLib.componentsDir), skinInfo.errorCb);
        } else {
          //Create desktop and mobile subsections
          //Copy all skin property files - wait until copy
          skinLib.skinSubFolder.forEach(function(folder) {
            fileSystem.mkdirSync(path.join(skinDir, folder), skinInfo.errorCb);
            fileSystem.writeFileSync(path.resolve(skinDir, folder, skinLib.skinPropertiesFileName),
                fileSystem.readFileSync(path.resolve(skinDir, skinLib.skinPropertiesFileName)));
            //Create a components dir
            fileSystem.mkdirSync(path.join(skinDir, folder, skinLib.componentsDir), skinInfo.errorCb);
            fileSystem.mkdirSync(path.join(skinDir, folder, skinLib.cssDir), skinInfo.errorCb);
          });
        }
    };
    stream.on('finish', function() {
      try {
        createSkinDirectoryStructure();
        skinInfo.cb();
      } catch (err) {
        skinInfo.errorCb(err);
      }
    });
    return stream;
  }

  return {
    process: function (patterns, dest, files) {
      return gulp.src(patterns)
        .pipe(gutil.env.filterFiles(files))
        .pipe(gulp.dest(dest));
    },
    compile: function (delCoreOutputDir, lr) {
      var server = getServer();
      var opts = getDefaultOptions(server);
      opts.lr = lr;
      opts.coreOutputDir = gutil.env['todir'] || server.coreOutputDir();

      if (server.useResponsiveConfigsFromServer()) {
        var responsiveOptions = function() {
          return getResponsiveOptions().getOptions(server, opts, function (err, config) {
            if (err) throw err;
            opts = setOptionsFromConfig(config, opts);
            opts.coreOutputDir = gutil.env['todir'] || server.coreOutputDir();
            opts.includePathsPrefix = opts.coreOutputDir + '/';
            opts.includePaths = [
              opts.includePathsPrefix + 'res/feature/responsivepeak/' + opts.version + '/res/skins/',
              opts.includePathsPrefix + 'res/feature/responsivebase/' + opts.version + '/res/skins/',
              opts.includePathsPrefix + 'res/feature/responsivebase/common/res/skins/',
              'res/skins'
            ];

            return doCompile(opts);
          });
        };

        var corePluginFiles = function() {
          return getPluginExport().exportCorePlugin(server, opts, undefined, function () {});
        };

        var fileSystem = fs();

        var coreOutputDirExists = fileSystem.existsSync(opts.coreOutputDir);

        if (coreOutputDirExists && gutil.env['force'] && delCoreOutputDir) {
          del().sync(opts.coreOutputDir, { force: true });
          coreOutputDirExists = false;
        }

        if (!coreOutputDirExists) {
          return streamSync([corePluginFiles, responsiveOptions]);
        } else {
          return responsiveOptions();
        }
      } else {
        return doCompile(opts);
      }
    },
    doCompile: doCompile,
    server: function () {
      var server = getServer();
      var opts = getDefaultOptions(server);

      var runServer = function() {
        connect().server({
          root: [
            opts.localServerDir,
            'web'
          ],
          port: opts.localServerPort,
          middleware: function () {
            return [cors, downloadAssets];
          }
        });
      };

      if (server.useResponsiveConfigsFromServer()) {
        var setOptsFromConfig = function() {
          return getResponsiveOptions().getOptions(server, opts, function (err, config) {
            if (err) throw err;
            opts = setOptionsFromConfig(config, opts);
            return runServer();
          });
        };

        return setOptsFromConfig();
      } else {
        return runServer();
      }
    },
    vars: function () {
      var server = getServer();

      var varsPath = 'codebook/_variables-*.scss';

      function getSkinVersions(dir) {
        try {
          fs().accessSync(dir, fs().F_OK);
          return fs().readdirSync(dir)
            .filter(function (file) {
              return fs().statSync(path.join(dir, file)).isDirectory();
            });
        } catch (e) {
          if (!server.useResponsiveConfigsFromServer()) {
            gutil.log(gutil.colors.red('Warning: Skin feature path not found (this is expected for <= 15.11): ', dir));
          }
          return [];
        }
      }

      var peakVars = getSkinVersions(skinLib.peakFeaturePath).map(function (version) {
        return gulp.src([path.join(skinLib.baseFeaturePath, version, '**', varsPath),
          path.join(skinLib.peakFeaturePath, version, '**', varsPath)])
          .pipe(newer()(path.join(skinLib.peakFeaturePath, version, peakSassPath, '_variables.scss')))
          .pipe(replace()('!default', ''))
          .pipe(replace()(/^\s*(\$.*)/gm, '//$1'))
          .pipe(replace()(/(\s*);/gm, ';'))
          .pipe(rename()('_variables.scss'))
          .pipe(gulpif()(function (file) {
              return file.path.indexOf(skinLib.baseFeaturePath) >= 0;
            },
            gulp.dest(path.join(skinLib.baseFeaturePath, version, baseSassPath))))
          .pipe(concat()('_variables.scss'))
          .pipe(gulp.dest(path.join(skinLib.peakFeaturePath, version, peakSassPath)));
      });
      return peakVars;
    },
    FILES_PATTERN: SKIN_FILES_PATTERN,
    createNewSkin: function(skinInfo) {
      return createNewSkin(skinInfo);
    },
    downloadFile: downloadFile
  };
};
<|endoftext|>


<commit_before>'use strict';

var Botkit = require('botkit');
var token = '' || process.env.SLACK_API_TOKEN;
var staff_token = process.env.STAFF_SLACK_API_TOKEN;
var opspark_token = process.env.OPSPARK_SLACK_API_TOKEN;
var hr_token = process.env.HR_SLACK_API_TOKEN;

var controller = Botkit.slackbot({
  debug: false
});

controller.spawn({
  token: token
}).startRTM();

var staffController = Botkit.slackbot({
  debug: false
});

staffController.spawn({
  token: staff_token
}).startRTM();

var hrController = Botkit.slackbot({
  debug: false
});

hrController.spawn({
  token: hr_token
}).startRTM();

var opSparkController = Botkit.slackbot({
  debug: false
});

opSparkController.spawn({
  token: opspark_token
}).startRTM();

exports.controller = controller;
exports.staffController = staffController;
exports.opSparkController = opSparkController;
exports.hrController = hrController;
<commit_msg>Add RPT Controller<commit_after>'use strict';

var Botkit = require('botkit');
var token = '' || process.env.SLACK_API_TOKEN;
var staff_token = process.env.STAFF_SLACK_API_TOKEN;
var opspark_token = process.env.OPSPARK_SLACK_API_TOKEN;
var hr_token = process.env.HR_SLACK_API_TOKEN;
var rpt_token = process.env.RPT_SLACK_API_TOKEN;

var controller = Botkit.slackbot({
  debug: false
});

controller.spawn({
  token: token
}).startRTM();

var staffController = Botkit.slackbot({
  debug: false
});

staffController.spawn({
  token: staff_token
}).startRTM();

var hrController = Botkit.slackbot({
  debug: false
});

hrController.spawn({
  token: hr_token
}).startRTM();

var opSparkController = Botkit.slackbot({
  debug: false
});

opSparkController.spawn({
  token: opspark_token
}).startRTM();

var rptController = Botkit.slackbot({
  debug: false
});

rptkController.spawn({
  token: rpt_token
}).startRTM();

exports.controller = controller;
exports.staffController = staffController;
exports.opSparkController = opSparkController;
exports.hrController = hrController;
exports.rptController = rptController;
<|endoftext|>