<commit_before>(function(){

    var modules = [];

    var linkedObjectInstance = { };

    var linkedObject = function(name, linkedObj, params = {}) {
        if(linkedObj) {
            if(this.$$linkedObjects[name] !== undefined) muuvyte.throwError('linked object <' + name + '> already defined');
            return this.$$linkedObjects[name] = Object.create(linkedObjectInstance, {
                $$linkedObjectName: { value: name },
                $$linkedObject: { value: linkedObj },
                $$params: { value: params }
            });
        }

        if(!this.$$linkedModules) {
            this.$$linkedModules = linkedModules(this.$$moduleName);
        }

        var result;
        for(var propt in this.$$linkedModules) {
            result = this.$$linkedModules[propt].$$linkedObjects[name];
            if(result) return result;
        }
        muuvyte.throwError('linked object <' + name + '> undefined');
    }

    var linkedModules = function(name, list = []) {
        list.push(modules[name]);
        var requires = modules[name].$$moduleRequires;
        for(var propt in requires) {
            list = linkedModules(requires[propt], list);
        }
        return list;
    }

    var baseLinkedObject = function(baseObject) {
        this.$$baseObject = Object.assign(this.$$baseObject || {}, baseObject);
    };

    var moduleInstance = {
        linkedObject: linkedObject,
        baseLinkedObject: baseLinkedObject
    };

    var module = function(name, requires) {
        if(requires) {
            if(!Array.isArray(requires)) muuvyte.throwError('<requires> must be of type array');
            if(modules[name] !== undefined) muuvyte.throwError('module <' + name + '> already defined');
            modules[name] = Object.create(moduleInstance, {
                $$moduleName: { value: name },
                $$moduleRequires: { value: requires },
                $$linkedObjects: { value: [] }
            });
        }
        if(modules[name] === undefined) muuvyte.throwError('module <' + name + '> undefined');
        return modules[name];
    };

    var throwError = function(message) {
        throw message;
    }

    var muuvyte = {
        module: module,
        baseLinkedObject: baseLinkedObject,
        throwError: throwError
    };

    window['muuvyte'] = muuvyte;

})();

muuvyte.module('module1', ['module2', 'module3']);
muuvyte.module('module2', []);
muuvyte.module('module3', ['module4']);
muuvyte.module('module4', []);

var module1 = muuvyte.module('module1');
module1.linkedObject('object1', { name: 'Jeff' });

var module3 = muuvyte.module('module3');
module3.linkedObject('object2', { name: 'Susie' });

console.log(module1.linkedObject('object1'));
console.log(muuvyte.module('module3').linkedObject('object2'));

muuvyte.baseLinkedObject({item1: 'item1'});
console.log(muuvyte);
muuvyte.module('module1').baseLinkedObject({item2: 'item2'});
console.log(muuvyte.module('module1'));
//muuvyte.baseLinkedObject({item3: 'item3'});
//console.log(muuvyte);
<commit_msg>internal<commit_after>(function(){

    var modules = [];

    var linkedObjectInstance = { };

    var findLinkedObject = function(name, self, includeToBeLinked) {
        if(!self.$$linkedModules) {
            self.$$linkedModules = linkedModules(self.$$moduleName);
        }
        for(var propt in self.$$linkedModules) {
            result = self.$$linkedModules[propt].$$linkedObjects[name];
            var result = self.$$linkedModules[propt].$$linkedObjects[name];
            if(result) {
                if(result.$$params.internal && self.$$moduleName != result.$$moduleName) muuvyte.throwError('linked object <' + name + '> defined as internal');
                if(!includeToBeLinked && result.$$params.toBeLinked) muuvyte.throwError('linked object <' + name + '> must be linked');

                return result;
            }
        }
        muuvyte.throwError('linked object <' + name + '> undefined');
    };

    var linkedObject = function(name, linkedObj, params = {}) {
        if(linkedObj) {
            if(this.$$linkedObjects[name] !== undefined) muuvyte.throwError('linked object <' + name + '> already defined');
//            return this.$$linkedObjects[name] = Object.create(linkedObjectInstance, {
//                $$linkedObjectName: { value: name },
//                $$linkedObject: { value: linkedObj },
//                $$params: { value: params }
//            });

            this.$$linkedObjects[name] = {
                $$linkedObjectName: name,
                $$linkedObject: linkedObj,
                $$params: params,
                $$moduleName: this.$$moduleName
            };
        }

        return findLinkedObject(name, this);

//        for(var propt in this.$$linkedModules) {
//            result = this.$$linkedModules[propt].$$linkedObjects[name];
//            var result = this.$$linkedModules[propt].$$linkedObjects[name];
//            if(result) {
//                if(result.$$params.internal && this.$$moduleName != result.$$moduleName) muuvyte.throwError('linked object <' + name + '> defined as internal');
//                if(result.$$params.toBeLinked) muuvyte.throwError('linked object <' + name + '> must be linked');
//
//                return result;
//            }
//        }
//        muuvyte.throwError('linked object <' + name + '> undefined');
    }

    var linkedModules = function(name, list = []) {
        list.push(modules[name]);
        var requires = modules[name].$$moduleRequires;
        for(var propt in requires) {
            list = linkedModules(requires[propt], list);
        }
        return list;
    }

    var baseLinkedObject = function(baseObject) {
        this.$$baseObject = Object.assign(this.$$baseObject || {}, baseObject);
    };

    var moduleInstance = {
        linkedObject: linkedObject,
        baseLinkedObject: baseLinkedObject
    };

    var module = function(name, requires) {
        if(requires) {
            if(!Array.isArray(requires)) muuvyte.throwError('<requires> must be of type array');
            if(modules[name] !== undefined) muuvyte.throwError('module <' + name + '> already defined');
            modules[name] = Object.create(moduleInstance, {
                $$moduleName: { value: name },
                $$moduleRequires: { value: requires },
                $$linkedObjects: { value: [] }
            });
        }
        if(modules[name] === undefined) muuvyte.throwError('module <' + name + '> undefined');
        return modules[name];
    };

    var throwError = function(message) {
        throw message;
    }

    var muuvyte = {
        module: module,
        baseLinkedObject: baseLinkedObject,
        throwError: throwError
    };

    window['muuvyte'] = muuvyte;

})();

muuvyte.module('module1', ['module2', 'module3']);
muuvyte.module('module2', []);
muuvyte.module('module3', ['module4']);
muuvyte.module('module4', []);

var module1 = muuvyte.module('module1');
module1.linkedObject('object1', { name: 'Jeff' }, { internal: true });

var module3 = muuvyte.module('module3');
module3.linkedObject('object2', { name: 'Susie' }, {});

console.log(module1.linkedObject('object1'));
console.log(muuvyte.module('module1').linkedObject('object2'));

//muuvyte.baseLinkedObject({item1: 'item1'});
//console.log(muuvyte);
//muuvyte.module('module1').baseLinkedObject({item2: 'item2'});
//console.log(muuvyte.module('module1'));

<|endoftext|>


<commit_before>var RECIPES = {};

RECIPES.default = {
	tweakJson: {},
	webfontsJson: []
};

RECIPES.alfa = { // parallax header/footer - regular page (use as support page)
	tweakJson: {
		"altContentWidth": "100%",
		"altSpacingSide": "5%",
		"altSpacingTop": "20px",

		"mainContentWidth": "1100px",
		"mainSpacingSide": "5%",
		"mainSpacingTop": "20px",

		"bannerContentWidth": "800px",
		"bannerSpacingSide": "5%",
		"bannerSpacingTop": "220px",

		"main-bgColor": "#fff",
		"main-textColor": "#323639",
		"main-headingColor": "#000",

		"alt-bgColor": "#101113",
		"alt-textColor": "#909499",
		"alt-headingColor": "#fff",

		"banner-bgColor": "rgb(16,17,19)",
		"banner-textColor": "#fff"
	},
	webfontsJson: [

	]
};

RECIPES.bravo = { // sliding gallery - Index -
	tweakJson: {
		"mainMetaWidth": "47%",
		"mainSpacingTop": "20px",
		"logoContainerWidth": "70px",

		"mainContentWidth": "100%",
		"mainSpacingTop": "5%",
		"mainSpacingSide": "5%",

		"bannerContentWidth": "1100px",
		"bannerSpacingTop": "0",
		"bannerSpacingSide": "5%",

		"altContentWidth": "100%",
		"altSpacingTop": "0",
		"altSpacingSide": "5%",

		"body-font": "{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:20px;font-weight:300;line-height:1.5em;}",
		"heading2-font": "{font-family:inherit;font-size:36px;font-weight:700;line-height:1.2em;}",

		"banner-body-font": "{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:24px;font-weight:300;line-height:1.3em;}",
		"banner-heading1-font": "{font-family:inherit;font-size:40px;font-weight:700;line-height:1.2em;}",

		"main-bgColor": "#f3efee",
		// "main-linkColor": "#cf3f02",
		"main-metaColor": "rgba(15,15,15,0.5)",

		// "alt-bgColor": "#f5f5f5",
		// "alt-textColor": "#333",
	},
	webfontsJson: [
		"Open+Sans:300,300italic,700normal,700italic,500undefined"
	]
};

RECIPES.charlie = { // scrolling gallery - custom gallery - Katana
	tweakJson: {
		"main-bgColor": "#fff",
		"main-textColor": "#323639",
		"main-headingColor": "#000"
	},
	webfontsJson: [

	]
};

RECIPES.delta = { // fixed sliding gallery - Index -
	tweakJson: {
	},
	webfontsJson: [

	]
};

RECIPES.echo = { // product grid - Products
	tweakJson: {
		"main-bgColor": "#f3efee",
		"main-metaColor": "#767676",
		"mainMetaWidth": "40%",

		"body-font": "{font-family:'Raleway';font-size:16px;font-weight:400;line-height:1.5em;}",
		"heading1-font": "{font-family:'Brandon',Helvetica,Arial,sans-serif;font-size:42px;font-weight:500;line-height:1.3em;}",
		"heading2-font": "{font-family:'Brandon',Helvetica,Arial,sans-serif;font-size:24px;font-weight:500;line-height:1.3em;}",
		"heading3-font": "{font-family:'Brandon',Helvetica,Arial,sans-serif;font-size:18px;font-weight:500;line-height:1.3em;}",

		"Product Item Size": "2:3 Standard (Vertical)",
		"Product Image Auto Crop": "False",
	},
	webfontsJson: [
		"Brandon:300,500normal"
	]
};

RECIPES.foxtrot = { // support blog - custom Blog
	tweakJson: {
	},
	webfontsJson: [

	]
};

RECIPES.golf = { // medium blog - Blog
	tweakJson: {
	},
	webfontsJson: [

	]
};

RECIPES.hotel = { //
	tweakJson: {
	},
	webfontsJson: [

	]
};

RECIPES.india = { // blog map - Blog
	tweakJson: {
	},
	webfontsJson: [

	]
};

var mode = document.currentScript.getAttribute('src').split('mode=')[1];

if (!mode || !RECIPES[mode]) mode = 'default';

// process tweak names
var newObj = {};
for(var name in RECIPES[mode].tweakJson) {
	var newName = name.match(/\s/) ? name.replace(/\s/g,'-').toLowerCase() : name;
	newObj[newName] = RECIPES[mode].tweakJson[name];
}
RECIPES[mode].tweakJson = newObj;

Y.use('squarespace-util', function(Y) {

	Y.Data.post({
	        url: '/api/template/SetTemplateTweakSettings',
	        data: {
	          tweakJson: Y.JSON.stringify(RECIPES[mode]['tweakJson']),
	          webfontsJson: Y.JSON.stringify(RECIPES[mode]['webfontsJson'])
	        },
	        success: function() {
	        	alert('Recipe ' + mode.toUpperCase() + ' applied!');
	        	window.location.href = window.location.pathname + '?recipe='+mode;
	        }
	});
});

<commit_msg>try railway<commit_after>var RECIPES = {};

RECIPES.default = {
	tweakJson: {},
	webfontsJson: []
};

RECIPES.alfa = { // parallax header/footer - regular page (use as support page)
	tweakJson: {
		"altContentWidth": "100%",
		"altSpacingSide": "5%",
		"altSpacingTop": "20px",

		"mainContentWidth": "1100px",
		"mainSpacingSide": "5%",
		"mainSpacingTop": "20px",

		"bannerContentWidth": "800px",
		"bannerSpacingSide": "5%",
		"bannerSpacingTop": "220px",

		"main-bgColor": "#fff",
		"main-textColor": "#323639",
		"main-headingColor": "#000",

		"alt-bgColor": "#101113",
		"alt-textColor": "#909499",
		"alt-headingColor": "#fff",

		"banner-bgColor": "rgb(16,17,19)",
		"banner-textColor": "#fff"
	},
	webfontsJson: [

	]
};

RECIPES.bravo = { // sliding gallery - Index -
	tweakJson: {
		"mainMetaWidth": "47%",
		"mainSpacingTop": "20px",
		"logoContainerWidth": "70px",

		"mainContentWidth": "100%",
		"mainSpacingTop": "5%",
		"mainSpacingSide": "5%",

		"bannerContentWidth": "1100px",
		"bannerSpacingTop": "0",
		"bannerSpacingSide": "5%",

		"altContentWidth": "100%",
		"altSpacingTop": "0",
		"altSpacingSide": "5%",

		"body-font": "{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:20px;font-weight:300;line-height:1.5em;}",
		"heading2-font": "{font-family:inherit;font-size:36px;font-weight:700;line-height:1.2em;}",

		"banner-body-font": "{font-family:'Open Sans','Helvetica Neue',Helvetica,Arial,sans-serif;font-size:24px;font-weight:300;line-height:1.3em;}",
		"banner-heading1-font": "{font-family:inherit;font-size:40px;font-weight:700;line-height:1.2em;}",

		"main-bgColor": "#f3efee",
		// "main-linkColor": "#cf3f02",
		"main-metaColor": "rgba(15,15,15,0.5)",

		// "alt-bgColor": "#f5f5f5",
		// "alt-textColor": "#333",
	},
	webfontsJson: [
		"Open+Sans:300,300italic,700normal,700italic,500undefined"
	]
};

RECIPES.charlie = { // scrolling gallery - custom gallery - Katana
	tweakJson: {
		"main-bgColor": "#fff",
		"main-textColor": "#323639",
		"main-headingColor": "#000"
	},
	webfontsJson: [

	]
};

RECIPES.delta = { // fixed sliding gallery - Index -
	tweakJson: {
	},
	webfontsJson: [

	]
};

RECIPES.echo = { // product grid - Products
	tweakJson: {
		"main-bgColor": "#f3efee",
		"main-metaColor": "#767676",
		"mainMetaWidth": "40%",

		"body-font": "{font-family:'Raleway';font-size:15px;font-weight:400;line-height:1.6em;}",
		"heading1-font": "{font-family:'Brandon',Helvetica,Arial,sans-serif;font-size:42px;font-weight:500;line-height:1.3em;}",
		"heading2-font": "{font-family:'Brandon',Helvetica,Arial,sans-serif;font-size:24px;font-weight:500;line-height:1.3em;}",
		"heading3-font": "{font-family:'Brandon',Helvetica,Arial,sans-serif;font-size:18px;font-weight:500;line-height:1.3em;}",

		"Product Item Size": "2:3 Standard (Vertical)",
		"Product Image Auto Crop": "False",
	},
	webfontsJson: [
		"Brandon:300,500normal",
		"Raleway:400,400italic"
	]
};

RECIPES.foxtrot = { // support blog - custom Blog
	tweakJson: {
	},
	webfontsJson: [

	]
};

RECIPES.golf = { // medium blog - Blog
	tweakJson: {
	},
	webfontsJson: [

	]
};

RECIPES.hotel = { //
	tweakJson: {
	},
	webfontsJson: [

	]
};

RECIPES.india = { // blog map - Blog
	tweakJson: {
	},
	webfontsJson: [

	]
};

var mode = document.currentScript.getAttribute('src').split('mode=')[1];

if (!mode || !RECIPES[mode]) mode = 'default';

// process tweak names
var newObj = {};
for(var name in RECIPES[mode].tweakJson) {
	var newName = name.match(/\s/) ? name.replace(/\s/g,'-').toLowerCase() : name;
	newObj[newName] = RECIPES[mode].tweakJson[name];
}
RECIPES[mode].tweakJson = newObj;

Y.use('squarespace-util', function(Y) {

	Y.Data.post({
	        url: '/api/template/SetTemplateTweakSettings',
	        data: {
	          tweakJson: Y.JSON.stringify(RECIPES[mode]['tweakJson']),
	          webfontsJson: Y.JSON.stringify(RECIPES[mode]['webfontsJson'])
	        },
	        success: function() {
	        	alert('Recipe ' + mode.toUpperCase() + ' applied!');
	        	window.location.href = window.location.pathname + '?recipe='+mode;
	        }
	});
});

<|endoftext|>


<commit_before>/* tslint:disable: no-console */
const exec = require('shell-utils').exec;
const semver = require('semver');
const fs = require('fs');
const includes = require('lodash/includes');
const path = require('path');

// Workaround JS
const isRelease = process.env.RELEASE_BUILD === 'true';

const BRANCH = process.env.BRANCH;
let VERSION_TAG = process.env.NPM_TAG;
if (!VERSION_TAG) {
  VERSION_TAG = isRelease ? 'latest' : 'snapshot';
}
const VERSION_INC = 'patch';

function run() {
  if (!validateEnv()) {
    return;
  }
  setupGit();
  createNpmRc();
  versionTagAndPublish();
}

function validateEnv() {
  if (!process.env.JENKINS_CI) {
    throw new Error(`releasing is only available from CI`);
  }

  if (!process.env.JENKINS_MASTER) {
    console.log(`not publishing on a different build`);
    return false;
  }

  return true;
}

function setupGit() {
  exec.execSyncSilent(`git config --global push.default simple`);
  exec.execSyncSilent(`git config --global user.email "${process.env.GIT_EMAIL}"`);
  exec.execSyncSilent(`git config --global user.name "${process.env.GIT_USER}"`);
  const remoteUrl = new RegExp(`https?://(\\S+)`).exec(exec.execSyncRead(`git remote -v`))[1];
  exec.execSyncSilent(
    `git remote add deploy "https://${process.env.GIT_USER}:${process.env.GIT_TOKEN}@${remoteUrl}"`
  );
  // exec.execSync(`git checkout ${ONLY_ON_BRANCH}`);
}

function createNpmRc() {
  exec.execSync(`rm -f package-lock.json`);
  const content = `
email=\${NPM_EMAIL}
//registry.npmjs.org/:_authToken=\${NPM_TOKEN}
`;
  fs.writeFileSync(`.npmrc`, content);
}

function versionTagAndPublish() {
  const packageVersion = semver.clean(process.env.npm_package_version);
  console.log(`package version: ${packageVersion}`);

  const currentPublished = findCurrentPublishedVersion();
  console.log(`current published version: ${currentPublished}`);

  const version = isRelease
    ? process.env.VERSION
    : semver.gt(packageVersion, currentPublished)
      ? `${packageVersion}-snapshot.${process.env.BUILD_ID}`
      : `${currentPublished}-snapshot.${process.env.BUILD_ID}`;

  console.log(`Publishing version: ${version}`);

  tryPublishAndTag(version);
}

function findCurrentPublishedVersion() {
  return exec.execSyncRead(`npm view ${process.env.npm_package_name} dist-tags.latest`);
}

function tryPublishAndTag(version) {
  let theCandidate = version;
  for (let retry = 0; retry < 5; retry++) {
    try {
      tagAndPublish(theCandidate);
      console.log(`Released ${theCandidate}`);
      return;
    } catch (err) {
      const alreadyPublished = includes(
        err.toString(),
        'You cannot publish over the previously published version'
      );
      if (!alreadyPublished) {
        throw err;
      }
      console.log(`previously published. retrying with increased ${VERSION_INC}...`);
      theCandidate = semver.inc(theCandidate, VERSION_INC);
    }
  }
}

function tagAndPublish(newVersion) {
  console.log(`trying to publish ${newVersion}...`);
  exec.execSync(`npm --no-git-tag-version version ${newVersion}`);
  exec.execSync(`npm publish --tag ${VERSION_TAG}`);
  if (isRelease) {
    exec.execSync(`git tag -a ${newVersion} -m "${newVersion}"`);
    exec.execSyncSilent(`git push deploy ${newVersion} || true`);
    updatePackageJsonGit(newVersion);
  }
}

function getPackageJsonPath() {
  return `${process.cwd()}/package.json`;
}

function writePackageJson(packageJson) {
  fs.writeFileSync(getPackageJsonPath(), JSON.stringify(packageJson, null, 2));
}

function readPackageJson() {
  return JSON.parse(fs.readFileSync(getPackageJsonPath()));
}

function updatePackageJsonGit(version) {
  exec.execSync(`git checkout ${BRANCH}`);
  const packageJson = readPackageJson();
  packageJson.version = version;
  writePackageJson(packageJson);
  exec.execSync(`git add package.json`);
  exec.execSync(`git commit -m"Update package.json version to ${version} [ci skip]"`);
  exec.execSync(`git push deploy ${BRANCH}`);
  draftGitRelease(version);
}

function draftGitRelease(version) {
  exec.execSync(`sleep 1m`);
  exec.execSync(`npx gren release --tags=${version}`);
}

run();
<commit_msg>Add the option to bump docs version in jenkins (#6750)<commit_after>/* tslint:disable: no-console */
const exec = require('shell-utils').exec;
const semver = require('semver');
const fs = require('fs');
const includes = require('lodash/includes');
const path = require('path');

// Workaround JS
const isRelease = process.env.RELEASE_BUILD === 'true';
const bumpDocumentation = process.env.BUMP_DOCUMENTATION_VERSION === 'true';

const BRANCH = process.env.BRANCH;
let VERSION_TAG = process.env.NPM_TAG;
if (!VERSION_TAG) {
  VERSION_TAG = isRelease ? 'latest' : 'snapshot';
}
const VERSION_INC = 'patch';

function run() {
  if (!validateEnv()) {
    return;
  }
  setupGit();
  createNpmRc();
  versionTagAndPublish();
}

function validateEnv() {
  if (!process.env.JENKINS_CI) {
    throw new Error(`releasing is only available from CI`);
  }

  if (!process.env.JENKINS_MASTER) {
    console.log(`not publishing on a different build`);
    return false;
  }

  return true;
}

function setupGit() {
  exec.execSyncSilent(`git config --global push.default simple`);
  exec.execSyncSilent(`git config --global user.email "${process.env.GIT_EMAIL}"`);
  exec.execSyncSilent(`git config --global user.name "${process.env.GIT_USER}"`);
  const remoteUrl = new RegExp(`https?://(\\S+)`).exec(exec.execSyncRead(`git remote -v`))[1];
  exec.execSyncSilent(
    `git remote add deploy "https://${process.env.GIT_USER}:${process.env.GIT_TOKEN}@${remoteUrl}"`
  );
  // exec.execSync(`git checkout ${ONLY_ON_BRANCH}`);
}

function createNpmRc() {
  exec.execSync(`rm -f package-lock.json`);
  const content = `
email=\${NPM_EMAIL}
//registry.npmjs.org/:_authToken=\${NPM_TOKEN}
`;
  fs.writeFileSync(`.npmrc`, content);
}

function versionTagAndPublish() {
  const packageVersion = semver.clean(process.env.npm_package_version);
  console.log(`package version: ${packageVersion}`);

  const currentPublished = findCurrentPublishedVersion();
  console.log(`current published version: ${currentPublished}`);

  const version = isRelease
    ? process.env.VERSION
    : semver.gt(packageVersion, currentPublished)
      ? `${packageVersion}-snapshot.${process.env.BUILD_ID}`
      : `${currentPublished}-snapshot.${process.env.BUILD_ID}`;

  console.log(`Publishing version: ${version}`);

  tryPublishAndTag(version);
}

function findCurrentPublishedVersion() {
  return exec.execSyncRead(`npm view ${process.env.npm_package_name} dist-tags.latest`);
}

function tryPublishAndTag(version) {
  let theCandidate = version;
  for (let retry = 0; retry < 5; retry++) {
    try {
      tagAndPublish(theCandidate);
      console.log(`Released ${theCandidate}`);
      return;
    } catch (err) {
      const alreadyPublished = includes(
        err.toString(),
        'You cannot publish over the previously published version'
      );
      if (!alreadyPublished) {
        throw err;
      }
      console.log(`previously published. retrying with increased ${VERSION_INC}...`);
      theCandidate = semver.inc(theCandidate, VERSION_INC);
    }
  }
}

function tagAndPublish(newVersion) {
  console.log(`trying to publish ${newVersion}...`);
  exec.execSync(`npm --no-git-tag-version version ${newVersion}`);
  exec.execSync(`npm publish --tag ${VERSION_TAG}`);
  if (isRelease) {
    if (bumpDocumentation) {
      exec.execSync(`npm --prefix website/ run  docusaurus docs:version ${newVersion}`);
      exec.execSync(`git add website/`);
    }
    exec.execSync(`git tag -a ${newVersion} -m "${newVersion}"`);
    exec.execSyncSilent(`git push deploy ${newVersion} || true`);
    updatePackageJsonGit(newVersion);
  }
}

function getPackageJsonPath() {
  return `${process.cwd()}/package.json`;
}

function writePackageJson(packageJson) {
  fs.writeFileSync(getPackageJsonPath(), JSON.stringify(packageJson, null, 2));
}

function readPackageJson() {
  return JSON.parse(fs.readFileSync(getPackageJsonPath()));
}

function updatePackageJsonGit(version) {
  exec.execSync(`git checkout ${BRANCH}`);
  const packageJson = readPackageJson();
  packageJson.version = version;
  writePackageJson(packageJson);
  exec.execSync(`git add package.json`);
  exec.execSync(`git commit -m"Update package.json version to ${version} [ci skip]"`);
  exec.execSync(`git push deploy ${BRANCH}`);
  draftGitRelease(version);
}

function draftGitRelease(version) {
  exec.execSync(`sleep 1m`);
  exec.execSync(`npx gren release --tags=${version}`);
}

run();
<|endoftext|>


<commit_before>/**
 * Library release script.
 *
 * @module scripts/release.
 */

shelljs = require('shelljs');
var options = require('minimist')(process.argv.slice(1));
var logger = require('log-symbols');

if (!options.version) {
    console.log(logger.error, 'No --version=<version> argument defined!');
    process.exit(1);
}

// Python version file generator
var pyVersion = [
    '#!/usr/bin/env python',
    '# -*- coding: utf-8 -*-',
    "__version__ = '" + options.version + "'",
    "__author__ = 'Juha Ojanperä'",
    "__contact__ = 'juha.ojanpera@gmail.com'"
];

var cmds = [

    // Update python application version
    'echo \"' + pyVersion.join('\\n') + '\" > draalcore/__init__.py',

    // Update package.json version
    'npm version --no-git-tag-version ' + options.version,

    // Commit the new release
    'git add package.json',
    'git add draalcore/__init__.py',
    'git commit -m "Release ' + options.version + '"',
    'git tag -a ' + options.version,
    'git push origin master'
];

shelljs.exec(cmds.join(' && '), function(code) {
    process.exit(code);
});
<commit_msg>Tag release with message.<commit_after>/**
 * Library release script.
 *
 * @module scripts/release.
 */

shelljs = require('shelljs');
var options = require('minimist')(process.argv.slice(1));
var logger = require('log-symbols');

if (!options.version) {
    console.log(logger.error, 'No --version=<version> argument defined!');
    process.exit(1);
}

// Python version file generator
var pyVersion = [
    '#!/usr/bin/env python',
    '# -*- coding: utf-8 -*-',
    "__version__ = '" + options.version + "'",
    "__author__ = 'Juha Ojanperä'",
    "__contact__ = 'juha.ojanpera@gmail.com'"
];

var cmds = [

    // Update python application version
    'echo \"' + pyVersion.join('\\n') + '\" > draalcore/__init__.py',

    // Update package.json version
    'npm version --no-git-tag-version ' + options.version,

    // Commit the new release
    'git add package.json',
    'git add draalcore/__init__.py',
    'git commit -m "Release ' + options.version + '"',
    'git tag -a ' + options.version + ' -m "Release ' + options.version + '"',
    'git push origin master'
];

shelljs.exec(cmds.join(' && '), function(code) {
    process.exit(code);
});
<|endoftext|>


<commit_before>// @ts-check

const fs = require("fs")
const path = require("path")
const spawnSync = require("child_process").spawnSync
const chalk = require("chalk")

function sh(command, canFail = false) {
  console.log("$ " + command)
  const task = spawnSync(command, { shell: true, stdio: "inherit" })
  if (!canFail && task.status != 0) {
    console.log(String(task.stdout))
    console.error(chalk.red(String(task.stderr)))
    throw new Error("[!] " + command)
  }
}

function publishPodspec(podspec) {
  const podspecFilename = path.basename(podspec)
  const podspecDir = path.dirname(path.resolve(podspec))
  const packagePath = path.join(podspecDir, "package.json")

  const name = path.basename(podspec, ".podspec")
  const version = JSON.parse(fs.readFileSync(packagePath)).version

  const specRepo = path.join(process.env.HOME, ".cocoapods/repos/artsy")
  const relativeSpecPath = path.join(name, version, name + ".podspec.json")
  const specPath = path.join(specRepo, relativeSpecPath)

  if (!fs.existsSync(specPath)) {
    console.log("=> Pushing " + name + " podspec to spec-repo.")
    sh("mkdir -p " + path.dirname(specPath))
    sh("cd " + podspecDir + ' && INCLUDE_METADATA="true" pod ipc spec ' + podspecFilename + " > " + specPath)
    sh(
      "cd " +
        specRepo +
        " && git pull " +
        " && git add " +
        relativeSpecPath +
        ' && git commit -m "' +
        name +
        " " +
        version +
        '" && git push'
    )
  }
}

console.log(chalk.green("=> Validating your tools."))
sh("bundle --version")
sh("npm --version")

console.log(chalk.green("=> Creating release bundle."))
sh("npm run relay")
sh("npm run bundle")
sh("cd Example && bundle exec pod install")
sh('git add . && git commit -m "[Pod] Update release artefacts."', true)

sh("yarn run auto changelog")

console.log(chalk.green("=> Creating version bump commit and tag."))
sh("npm version $(npx auto version)")

sh("git push")
sh("git push --tags")

sh("yarn run auto release")

console.log(chalk.green("=> Pushing Podspec"))
publishPodspec("Emission.podspec")

console.log(chalk.green("=> Updating Metaphysics"))
sh("npm run merge-graphql-query-map")
<commit_msg>Attempt to use nvm in releases script<commit_after>// @ts-check

const fs = require("fs")
const path = require("path")
const spawnSync = require("child_process").spawnSync
const chalk = require("chalk")

function sh(command, canFail = false) {
  console.log("$ " + command)
  const task = spawnSync(command, { shell: true, stdio: "inherit" })
  if (!canFail && task.status != 0) {
    console.log(String(task.stdout))
    console.error(chalk.red(String(task.stderr)))
    throw new Error("[!] " + command)
  }
}

function publishPodspec(podspec) {
  const podspecFilename = path.basename(podspec)
  const podspecDir = path.dirname(path.resolve(podspec))
  const packagePath = path.join(podspecDir, "package.json")

  const name = path.basename(podspec, ".podspec")
  const version = JSON.parse(fs.readFileSync(packagePath)).version

  const specRepo = path.join(process.env.HOME, ".cocoapods/repos/artsy")
  const relativeSpecPath = path.join(name, version, name + ".podspec.json")
  const specPath = path.join(specRepo, relativeSpecPath)

  if (!fs.existsSync(specPath)) {
    console.log("=> Pushing " + name + " podspec to spec-repo.")
    sh("mkdir -p " + path.dirname(specPath))
    sh("cd " + podspecDir + ' && INCLUDE_METADATA="true" pod ipc spec ' + podspecFilename + " > " + specPath)
    sh(
      "cd " +
        specRepo +
        " && git pull " +
        " && git add " +
        relativeSpecPath +
        ' && git commit -m "' +
        name +
        " " +
        version +
        '" && git push'
    )
  }
}

console.log(chalk.green("=> Validating your tools."))
sh("bundle --version")
sh("npm --version")

console.log(chalk.green("=> Creating release bundle."))
sh("npm run relay")
sh("npm run bundle")
sh("cd Example && bundle exec pod install")
sh('git add . && git commit -m "[Pod] Update release artefacts."', true)

sh("yarn run auto changelog")

console.log(chalk.green("=> Creating version bump commit and tag."))
sh("nvm use 10.13 && npm version $(npx auto version)")

sh("git push")
sh("git push --tags")

sh("yarn run auto release")

console.log(chalk.green("=> Pushing Podspec"))
publishPodspec("Emission.podspec")

console.log(chalk.green("=> Updating Metaphysics"))
sh("npm run merge-graphql-query-map")
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const spawn = require('cross-spawn');
const args = process.argv;
const argsNum = args.length;
const manifest = './app/package.json';
const releasesDir = './releases';
const buildDir = `${releasesDir}/build`;
const allowed = ["app", "nwbuild"];
let name, version, releaseDir, settings;

/**
 * Gets the command settings.
 *
 * @param {string} releaseDir - the directory to save the release to
 * @return {object} settings - the command settings
 */
function getSettings(releaseDir) {
    let settings = {
        app: './app',
        nwbuild: [
            '-p',
            'win64,osx64,linux64',
            '-o',
            releaseDir
        ]
    };

    if (argsNum === 2) {
        return settings;
    }

    for (let i = 2; i < argsNum; i++) {
        let arg = args[i].split('=');
        let argKey = arg[0];
        let argValue = arg[1];

        switch (argKey) {
            case "app":
                settings.app = argValue;
                break;
            case "nwbuild":
                settings.nwbuild = argValue.split(' ');
                break;
        }
    }

    // ensure that output directory is always the release directory
    settings.nwBuild.push('-o');
    settings.nwBuild.push(releaseDir);

    return settings;
}

function setup(callback) {

    // read and write the manifest to the build directory
    fs.readJson(manifest, 'utf8', (err, contents) => {
        if (err) {
            die(chalk.bgRed('Unable to read manifest'))
        }

        name = contents.name;
        version = contents.version;
        releaseDir = `${releasesDir}/${version}`;
        settings = getSettings(releaseDir);

        // ensure that releases directory exists.
        fs.ensureDirSync(releasesDir);

        // ensure that a build directory is created.
        fs.ensureDirSync(buildDir);

        // copy the app contents to the build directory
        fs.copySync(settings.app, buildDir);

        // copy the manifest to the build directory
        fs.outputFileSync(`${buildDir}/package.json`, contents);

        // ensure the versioned release directory exists
        fs.ensureDirSync(releaseDir);

        callback(contents);
    });
}

function parseNwjsBuilderArgs() {
    if (!nwjsBuilderArgs) {
        return [
            '-p',
            'win64,osx64,linux64',
            '-o',
            releaseDir
        ];
    }

    return
}

function release() {

}
<commit_msg>Debugging this release script, getting some odd errors when trying to spawn the nw nwbuild process<commit_after>#!/usr/bin/env node

'use strict';

const fs = require('fs-extra');
const path = require('path');
const chalk = require('chalk');
const spawn = require('cross-spawn');
const shell = require('shelljs');
const args = process.argv;
const argsNum = args.length;
const manifest = './app/package.json';
const releasesDir = './releases';
const buildDir = `${releasesDir}/build`;
const allowed = ["app", "nwbuild"];
let name, version, releaseDir, settings;

/**
 * Gets the command settings.
 *
 * @param {string} releaseDir - the directory to save the release to
 * @return {object} settings - the command settings
 */
function getSettings(releaseDir) {
    let settings = {
        app: './app',
        nwbuild: [
            '-p',
            'win64,osx64,linux64',
            '-o',
            releaseDir
        ]
    };

    if (argsNum === 2) {
        return settings;
    }

    for (let i = 2; i < argsNum; i++) {
        let arg = args[i].split('=');
        let argKey = arg[0];
        let argValue = arg[1];

        switch (argKey) {
            case "app":
                settings.app = argValue;
                break;
            case "nwbuild":
                settings.nwbuild = argValue.split(' ');
                break;
        }
    }

    // ensure that output directory is always the release directory
    settings.nwBuild.push('-o');
    settings.nwBuild.push(releaseDir);

    return settings;
}

function readManifest(callback) {
    console.log(manifest);
    fs.readJson(manifest, 'utf8', (err, contents) => {
        callback(contents);
    });
}

function release(manifest) {
    name = manifest.name;
    version = manifest.version;
    releaseDir = `${releasesDir}/${version}`;
    settings = getSettings(releaseDir);

    // ensure that releases directory exists.
    fs.ensureDirSync(releasesDir);

    // ensure that a build directory is created.
    fs.ensureDirSync(buildDir);

    // copy the app contents to the build directory
    fs.copySync(settings.app, buildDir);

    // copy the manifest to the build directory
    fs.outputJsonSync(`${buildDir}/package.json`, manifest);

    // ensure the versioned release directory exists
    fs.ensureDirSync(releaseDir);

    console.log(['nwbuild', buildDir].concat(settings.nwbuild).join(" "));

    shell.exec(`
        nwb nwbuild ${[buildDir].concat(settings.nwbuild).join(" ")}
    `);

    // spawn.sync(
    //     'nwb',
    //     ['nwbuild', buildDir].concat(settings.nwbuild).join(" "),
    //     { stdio: 'inherit' }
    // );

    fs.remove(buildDir);
}

readManifest(manifest => release(manifest));
<|endoftext|>


<commit_before>/**
 * For lazy people.
 * Reference / Origin:
 * http://stackoverflow.com/questions/24883308/convert-birthday-to-age-in-angularjs
 */
+function(angular, undefined) {
  'use strict';
  angular
    .module('srph.age-filter', [])
    .filter('age', age);

  function age() {
    return function(input, current) {
      // Difference in milliseconds
      current = Date.parse(current) || Date.now();
      var ageDiff =  current - new Date(input).getTime();
      var ageDate = new Date(ageDiff);

      return Math.abs( ageDate.getUTCFullYear() - 1970 );
    }
  }
}(angular);<commit_msg>Updated doc<commit_after>/**
 * For lazy people.
 * Reference / Origin:
 * http://stackoverflow.com/questions/24883308/convert-birthday-to-age-in-angularjs
 */
+function(angular, undefined) {
  'use strict';
  angular
    .module('srph.age-filter', [])
    .filter('age', age);

  function age() {
    return function(input, current) {
      // This syntax is usable in this case
      // NaN || {whatever} evaluates to {whatever}
      current = Date.parse(current) || Date.now();

      // Difference in milliseconds
      var ageDiffMs =  current - new Date(input).getTime();
      var ageDate = new Date(ageDiffMs);

      return Math.abs( ageDate.getUTCFullYear() - 1970 );
    }
  }
}(angular);
<|endoftext|>


<commit_before>/* (C) 2014 Peter Cook */

(function() {

var animdata = window.animdata || {};
window.animdata = animdata;

animdata.d3 = animdata.d3 || {};
animdata.d3.quartersAxis = function() {

  /*----
  Configurable variables
  ----*/
  var config = {
    length: 500,
    numQuarters: 11,
    startQuarter: 1,
    startYear: 2010,
    label: 'Label',
    lineColor: '#aaa',
    fontSize: 11
  }

  /*----
  Internal variables
  ----*/
  var constructed = false;

  var d3elements = {
    container: null,
  }

  var axisComponent = null;
  var quarterFormat = null;

  /*----
  Chart building
  ----*/
  function construct() {
    quarterFormat = function(d) {
      return 'Q' + +((d - 1) % 4 + 1);
    };
  }

  /*----
  Update
  ----*/
  function update() {
    var scale = d3.scale.linear()
      .domain([0, config.numQuarters])
      .range([0, config.length]);

    var tickValues = [];
    for(var i=0; i<config.numQuarters; i++)
      tickValues.push(i+1);

    var xStep = config.length / config.numQuarters;

    var axisComponent = d3.svg.axis()
      .scale(scale)
      .orient('bottom')
      .tickValues(tickValues)
      .tickFormat(quarterFormat);
    d3elements.container
      .call(axisComponent);

    // Move tick label to center
    d3elements.container
      .selectAll('.tick text')
      .attr('x', -xStep * 0.5);

    // Styling
    d3elements.container
      .selectAll('line')
      .style('stroke-width', 1)
      .style('shape-rendering', 'crispEdges')
      .style('stroke', config.lineColor);
    d3elements.container
      .selectAll('path')
      .style('stroke-width', 1)
      .style('stroke', config.lineColor)
      .style('shape-rendering', 'crispEdges')
      .style('fill', 'none');
    d3elements.container
      .selectAll('text')
      .style('font-size', config.fontSize)

    // Years
    var years = [];
    for(var i=0; i<=Math.floor((config.numQuarters - 1) / 4); i++) {
      years.push(config.startYear + i);
    }
    d3elements.container
      .append('g')
      .classed('years', true)
      .attr('transform', animdata.svg.translate(0, 35))
      .selectAll('text')
      .data(years)
      .enter()
      .append('text')
      .attr('x', function(d, i) {return (i * 4 + 0.5) * xStep;})
      .style('font-size', config.fontSize)
      .style('text-anchor', 'middle')
      .style('font-weight', 'bold')
      .text(function(d) {return d;});
  }

  /*----
  Main chart function
  ----*/
  function chart(selection) {
    // console.log('selection', selection);

    // To make things simpler, we assume just one element in the selection
    d3elements.container = d3.select(selection[0][0]);

    // console.log(data);

    // Construct the chart if this is first call
    if(!constructed) {
      construct();
    }

    update();

    constructed = true;
  }

  /*----
  Configuration getters/setters
  -----*/
  d3.keys(config).forEach(function(a) {
    chart[a] = function(_) {
      if(!arguments.length) return config[a];
      config[a] = _;
      return chart;
    }
  });

  return chart;
}

})();<commit_msg>quartersAxis: add year to every tick<commit_after>/* (C) 2014 Peter Cook */

(function() {

var animdata = window.animdata || {};
window.animdata = animdata;

animdata.d3 = animdata.d3 || {};
animdata.d3.quartersAxis = function() {

  /*----
  Configurable variables
  ----*/
  var config = {
    axisLength: 500,
    numQuarters: 6,
    startQuarter: 4,
    startYear: 2010,
    label: 'Label',
    lineColor: '#aaa',
    fontSize: 11
  }

  /*----
  Internal variables
  ----*/
  var constructed = false;

  var d3elements = {
    container: null,
  }

  var axisComponent = null;
  var quarterFormat = null;

  /*----
  Chart building
  ----*/
  function construct() {
    quarterFormat = function(d) {
      return 'Q' + +((d - 1) % 4 + 1);
    };
  }

  /*----
  Update
  ----*/
  function update() {
    var scale = d3.scale.linear()
      .domain([config.startQuarter, config.startQuarter + config.numQuarters])
      .range([0, config.axisLength]);

    var tickValues = [];
    for(var i=0; i<config.numQuarters; i++)
      tickValues.push(config.startQuarter + i);

    var xStep = config.axisLength / config.numQuarters;

    var axisComponent = d3.svg.axis()
      .scale(scale)
      .orient('bottom')
      .tickValues(tickValues)
      .tickFormat(quarterFormat);
    d3elements.container
      .call(axisComponent);

    // Move tick label to center
    d3elements.container
      .selectAll('.tick text')
      .attr('x', xStep * 0.5);

    // Years
    var years = [];
    var year = config.startYear;
    var quarter = config.startQuarter;
    for(var i=0; i<config.numQuarters; i++) {
      years.push(year);
      quarter++;
      if(quarter === 5) {
        quarter = 1;
        year++;
      }
    }
    d3elements.container
      .selectAll('.tick')
      .append('text')
      .classed('year', true)
      .attr('x', function(d, i) {return 0.5 * xStep;})
      .attr('y', 30)
      .style('text-anchor', 'middle')
      .text(function(d, i) {return years[i];});

    // Years
    // var years = [];
    // for(var i=0; i<=Math.floor((config.numQuarters - 1) / 4); i++) {
    //   years.push(config.startYear + i);
    // }
    // d3elements.container
    //   .append('g')
    //   .classed('years', true)
    //   .attr('transform', animdata.svg.translate(0, 35))
    //   .selectAll('text')
    //   .data(years)
    //   .enter()
    //   .append('text')
    //   .attr('x', function(d, i) {return (i * 4 + 0.5) * xStep;})
    //   .style('font-size', config.fontSize)
    //   .style('text-anchor', 'middle')
    //   .style('font-weight', 'bold')
    //   .text(function(d) {return d;});

    // Styling
    d3elements.container
      .selectAll('line')
      .style('stroke-width', 1)
      .style('shape-rendering', 'crispEdges')
      .style('stroke', config.lineColor);
    d3elements.container
      .selectAll('path')
      .style('stroke-width', 1)
      .style('stroke', config.lineColor)
      .style('shape-rendering', 'crispEdges')
      .style('fill', 'none');
    d3elements.container
      .selectAll('text')
      .style('font-size', config.fontSize)
    d3elements.container
      .selectAll('.tick line')
      .style('stroke-width', function(d, i) {return (d - 1) % 4 === 0 ? 3 : 1;});
  }

  /*----
  Main chart function
  ----*/
  function chart(selection) {
    // console.log('selection', selection);

    // To make things simpler, we assume just one element in the selection
    d3elements.container = d3.select(selection[0][0]);

    // console.log(data);

    // Construct the chart if this is first call
    if(!constructed) {
      construct();
    }

    update();

    constructed = true;
  }

  /*----
  Configuration getters/setters
  -----*/
  d3.keys(config).forEach(function(a) {
    chart[a] = function(_) {
      if(!arguments.length) return config[a];
      config[a] = _;
      return chart;
    }
  });

  return chart;
}

})();<|endoftext|>


<commit_before>var ERR = require('async-stacktrace');
var _ = require('lodash');
var fs = require('fs');
var path = require('path');

var error = require('../lib/error');
var logger = require('../lib/logger');
var filePaths = require('../lib/file-paths');
var questionHelper = require('../lib/questionHelper.js');

module.exports = {
    renderExtraHeaders: function(question, course, locals, callback) {
        var extraHeaders = '<script type="text/javascript" src="/javascripts/require.js"></script>';
        callback(null, extraHeaders);
    },

    renderQuestion: function(variant, question, submission, course, locals, callback) {
        callback(null, "");
    },

    renderSubmission: function(variant, question, submission, course, locals, callback) {
        callback(null, "");
    },

    renderTrueAnswer: function(variant, question, course, locals, callback) {
        callback(null, "");
    },

    getData: function(question, course, variant_seed, callback) {
        var questionDir = path.join(course.path, 'questions', question.directory);
        questionHelper.loadServer(question, course, function(err, server) {
            if (ERR(err, callback)) return;
            var options = question.options || {};
            try {
                var vid = variant_seed;
                var questionData = server.getData(vid, options, questionDir);
            } catch (err) {
                var data = {
                    variant_seed: variant_seed,
                    question: question,
                    course: course,
                };
                err.status = 500;
                err = error.addData(err, data);
                return ERR(err, callback);
            }
            var data = {
                params: questionData.params,
                true_answer: questionData.trueAnswer,
                options: questionData.options,
            };
            callback(null, data);
        });
    },

    getFile: function(filename, variant, question, course, callback) {
        var that = this;
        questionHelper.loadServer(question, course, function(err, server) {
            if (ERR(err, callback)) return;
            var fileData;
            try {
                var vid = variant.variant_seed;
                var params = variant.params;
                var trueAnswer = variant.true_answer;
                var options = variant.options;
                var questionDir = path.join(course.path, 'questions', question.directory);
                fileData = server.getFile(filename, vid, params, trueAnswer, options, questionDir);
            } catch (err) {
                var data = {
                    variant: variant,
                    question: question,
                    course: course,
                };
                err.status = 500;
                err = error.addData(err, data);
                return ERR(err, callback);
            }
            callback(null, fileData);
        });
    },

    gradeSubmission: function(submission, variant, question, course, callback) {
        var that = this;
        questionHelper.loadServer(question, course, function(err, server) {
            if (ERR(err, callback)) return;
            var grading;
            try {
                var vid = variant.variant_seed;
                var params = variant.params;
                var trueAnswer = variant.true_answer;
                var submittedAnswer = submission.submitted_answer;
                var options = variant.options;
                var questionDir = path.join(course.path, 'questions', question.directory);
                grading = server.gradeAnswer(vid, params, trueAnswer, submittedAnswer, options, questionDir);
            } catch (err) {
                var data = {
                    submission: submission,
                    variant: variant,
                    question: question,
                    course: course,
                };
                err.status = 500;
                err = error.addData(err, data);
                return ERR(err, callback);
            }
            callback(null, grading);
        });
    },
};
<commit_msg>default variant.options to question.options if not overridden<commit_after>var ERR = require('async-stacktrace');
var _ = require('lodash');
var fs = require('fs');
var path = require('path');

var error = require('../lib/error');
var logger = require('../lib/logger');
var filePaths = require('../lib/file-paths');
var questionHelper = require('../lib/questionHelper.js');

module.exports = {
    renderExtraHeaders: function(question, course, locals, callback) {
        var extraHeaders = '<script type="text/javascript" src="/javascripts/require.js"></script>';
        callback(null, extraHeaders);
    },

    renderQuestion: function(variant, question, submission, course, locals, callback) {
        callback(null, "");
    },

    renderSubmission: function(variant, question, submission, course, locals, callback) {
        callback(null, "");
    },

    renderTrueAnswer: function(variant, question, course, locals, callback) {
        callback(null, "");
    },

    getData: function(question, course, variant_seed, callback) {
        var questionDir = path.join(course.path, 'questions', question.directory);
        questionHelper.loadServer(question, course, function(err, server) {
            if (ERR(err, callback)) return;
            var options = question.options || {};
            try {
                var vid = variant_seed;
                var questionData = server.getData(vid, options, questionDir);
            } catch (err) {
                var data = {
                    variant_seed: variant_seed,
                    question: question,
                    course: course,
                };
                err.status = 500;
                err = error.addData(err, data);
                return ERR(err, callback);
            }
            var data = {
                params: questionData.params,
                true_answer: questionData.trueAnswer,
                options: questionData.options || question.options || {},
            };
            callback(null, data);
        });
    },

    getFile: function(filename, variant, question, course, callback) {
        var that = this;
        questionHelper.loadServer(question, course, function(err, server) {
            if (ERR(err, callback)) return;
            var fileData;
            try {
                var vid = variant.variant_seed;
                var params = variant.params;
                var trueAnswer = variant.true_answer;
                var options = variant.options;
                var questionDir = path.join(course.path, 'questions', question.directory);
                fileData = server.getFile(filename, vid, params, trueAnswer, options, questionDir);
            } catch (err) {
                var data = {
                    variant: variant,
                    question: question,
                    course: course,
                };
                err.status = 500;
                err = error.addData(err, data);
                return ERR(err, callback);
            }
            callback(null, fileData);
        });
    },

    gradeSubmission: function(submission, variant, question, course, callback) {
        var that = this;
        questionHelper.loadServer(question, course, function(err, server) {
            if (ERR(err, callback)) return;
            var grading;
            try {
                var vid = variant.variant_seed;
                var params = variant.params;
                var trueAnswer = variant.true_answer;
                var submittedAnswer = submission.submitted_answer;
                var options = variant.options;
                var questionDir = path.join(course.path, 'questions', question.directory);
                grading = server.gradeAnswer(vid, params, trueAnswer, submittedAnswer, options, questionDir);
            } catch (err) {
                var data = {
                    submission: submission,
                    variant: variant,
                    question: question,
                    course: course,
                };
                err.status = 500;
                err = error.addData(err, data);
                return ERR(err, callback);
            }
            callback(null, grading);
        });
    },
};
<|endoftext|>


<commit_before>const { lighthouse, pa11y, prepareAudit } = require('cypress-audit');

module.exports = (on, config) => {
  require('cypress-terminal-report/src/installLogsPrinter')(on, {
    printLogsToConsole: 'onFail',
  });
  on('before:browser:launch', (browser = {}, launchOptions) => {
    prepareAudit(launchOptions);
  });

  on('task', {
    lighthouse: lighthouse(), // calling the function is important
    pa11y: pa11y(), // calling the function is important
  });
};
<commit_msg>chore: remove comments<commit_after>const { lighthouse, pa11y, prepareAudit } = require('cypress-audit');

module.exports = (on, config) => {
  require('cypress-terminal-report/src/installLogsPrinter')(on, {
    printLogsToConsole: 'onFail',
  });
  on('before:browser:launch', (browser = {}, launchOptions) => {
    prepareAudit(launchOptions);
  });

  on('task', {
    lighthouse: lighthouse(),
    pa11y: pa11y(),
  });
};
<|endoftext|>


<commit_before>function updateUserPage (user) {
	var name = user.get("name");
	var picUrl = user.get("picture");
	var friends = user.get("friends"); /* Array of strings (fb ids) */

	var profile = document.getElementById("my-profile-box");
	var scope = angular.element(profile).scope();

	scope.$apply(function() {scope.name = name});
	$("#my-picture").css("background-image", "url(" + picUrl + ")");

}

function updateSporklists (sporklists, position) {
    var sidebarList = document.getElementById("playlists");
    var scope = angular.element(sidebarList).scope();

    scope.$apply(function () {scope.playlists = sporklists});
}

function getFriends (friendIds) {
    var users = Parse.Object.extend("_User");
    var query = new Parse.Query(users);
    var resList = [ ];
    for(id in friendIds) {
        query.equalTo("facebook_id",id);
        query.find( {
            /* add info to some results */
            success: function (results) {
                resList.push(results);
            },
            error: function (error) {
                console.log("You have no friends :( " + error);
            }
        };

  scope.$apply(function () {scope.playlists = sporklists});
}

function updateSporklist(sporklist) {

    var friendList = resList[0:5].name;

    var friendListElem = document.getElementById("friend-name");
    var scope = angular.element(friendListElem).scope();

    scope.$apply(function() {scope.friendList = friendList}

}
<commit_msg>syntax error<commit_after>function updateUserPage (user) {
	var name = user.get("name");
	var picUrl = user.get("picture");
	var friends = user.get("friends"); /* Array of strings (fb ids) */

	var profile = document.getElementById("my-profile-box");
	var scope = angular.element(profile).scope();

	scope.$apply(function() {scope.name = name});
	$("#my-picture").css("background-image", "url(" + picUrl + ")");

}

function updateSporklists (sporklists, position) {
    var sidebarList = document.getElementById("playlists");
    var scope = angular.element(sidebarList).scope();

    scope.$apply(function () {scope.playlists = sporklists});
}

function getFriends (friendIds) {
    var users = Parse.Object.extend("_User");
    var query = new Parse.Query(users);
    var resList = [ ];
    for(id in friendIds) {
        query.equalTo("facebook_id",id);
        query.find( {
            /* add info to some results */
            success: function (results) {
                resList.push(results);
            },
            error: function (error) {
                console.log("You have no friends :( " + error);
            }
        };
    }

  scope.$apply(function () {scope.playlists = sporklists});
}

function updateSporklist(sporklist) {

    var friendList = resList[0:5].name;

    var friendListElem = document.getElementById("friend-name");
    var scope = angular.element(friendListElem).scope();

    scope.$apply(function() {scope.friendList = friendList}

}
<|endoftext|>


<commit_before>// Description:
//   answers with current temp
//
// Dependencies:
//   dotenv node module
//
// Configuration:
//   Add Open Weather Map API key to environment variable: HUBOT_OWM_APIKEY
//
// Commands:
//   hubot weather in CITY?  - returns current temp

var dotenv = require('dotenv');
dotenv.load();

module.exports = function(robot) {
  robot.hear(/weather in (.*)/i, function(msg) {
    var APIKEY;
    APIKEY = process.env.HUBOT_OWM_APIKEY || null;
    if (APIKEY === null) {
      msg.send("HUBOT_OWM_APIKEY environment variable is not provided for hubot-weather");
    } else {
      msg.http("http://api.openweathermap.org/data/2.5/weather?q=" + msg.match[1] + "&units=metric&APPID=" + APIKEY).header('Accept', 'application/json').get()(function(err, res, body) {
        var data;
        data = JSON.parse(body);
        if (data.cod == '200') {
          var currentTemp = Math.round(data.main.temp * 1.8 + 32) + "°F";
          msg.send("It is currently " + currentTemp + " in " + data.name + ".");
        }
      });
    }
  });
}<commit_msg>Changing send to reply<commit_after>// Description:
//   answers with current temp
//
// Dependencies:
//   dotenv node module
//
// Configuration:
//   Add Open Weather Map API key to environment variable: HUBOT_OWM_APIKEY
//
// Commands:
//   hubot weather in CITY?  - returns current temp

var dotenv = require('dotenv');
dotenv.load();

module.exports = function(robot) {
  robot.hear(/weather in (.*)/i, function(msg) {
    var APIKEY;
    APIKEY = process.env.HUBOT_OWM_APIKEY || null;
    if (APIKEY === null) {
      msg.reply("HUBOT_OWM_APIKEY environment variable is not provided for hubot-weather");
    } else {
      msg.http("http://api.openweathermap.org/data/2.5/weather?q=" + msg.match[1] + "&units=metric&APPID=" + APIKEY).header('Accept', 'application/json').get()(function(err, res, body) {
        var data;
        data = JSON.parse(body);
        if (data.cod == '200') {
          var currentTemp = Math.round(data.main.temp * 1.8 + 32) + "°F";
          msg.reply("It is currently " + currentTemp + " in " + data.name + ".");
        }
      });
    }
  });
}<|endoftext|>


<commit_before>/*jslint node: true, indent: 4 */
(function () {
    'use strict';
    var m_browser,
        summons = {},
        users = {},
        configuration;

    /**
     * @var {string} description Brief description of this module for Help Docs
     */
    exports.description = 'Allow Summoning of bot to play in certain threads';

    /**
     * @var {object} configuration Default Configuration settings for this sock_module
     */
    exports.configuration = {
        enabled: false,
        autoTimeout: 60 * 1000,
        userTimeout: 60 * 60 * 1000,
        messages: [
            '@%__username__% has summoned me, and so I appear.',
            'Yes master %__name__%, I shall appear as summoned.',
            'Yes mistress %__name__%, I shall appear as summoned.'
        ]
    };

    /**
     * @var {string} name The name of this sock_module
     */
    exports.name = "Summoner";

    /**
     * @var {number} priority If defined by a sock_module it is the priority of the module with respect to other modules.
     *
     * sock_modules **should not** define modules with negative permissions. Default value is 50 with lower numbers being higher priority.
     */
    exports.priority = 1000;

    /**
     * @var {string} version The version of this sock_module
     */
    exports.version = "1.1.0";

    exports.onNotify = function onNotify(type, notification, post, callback) {
        if (type === 'mentioned' && configuration.enabled && !(post.trust_level < 1 || post.primary_group_name === 'bots')) {
            var now = (new Date().getTime()),
                r = Math.floor(Math.random() * configuration.messages.length),
                s = configuration.messages[r],
                k;
            if (post.trust_level === 1 && (users[post.user_id] && now < users[post.user_id])) {
                return callback();
            }
            if (summons[notification.topic_id] && now < summons[notification.topic_id]) {
                return callback();
            }
            m_browser.log(notification.data.display_username + ' summoned me to play in ' + notification.slug);
            for (k in post) {
                if (post.hasOwnProperty(k)) {
                    s = s.replace(new RegExp('%__' + k + '__%', 'g'), post[k]);
                }
            }
            summons[notification.topic_id] = now + configuration.autoTimeout;
            if (post.trust_level === 1) {
                users[post.user_id] = now + configuration.userTimeout;
            }
            m_browser.reply_topic(notification.topic_id, notification.post_number, s, function () {
                callback(true);
            });
        } else {
            callback();
        }
    };
    exports.begin = function begin(browser, config) {
        configuration = config.modules[exports.name];
        m_browser = browser;
    };
}());<commit_msg>fix possible memoryt leak<commit_after>/*jslint node: true, indent: 4 */
(function () {
    'use strict';
    var m_browser,
        summons = {},
        users = {},
        configuration;

    /**
     * @var {string} description Brief description of this module for Help Docs
     */
    exports.description = 'Allow Summoning of bot to play in certain threads';

    /**
     * @var {object} configuration Default Configuration settings for this sock_module
     */
    exports.configuration = {
        enabled: false,
        autoTimeout: 60 * 1000,
        userTimeout: 60 * 60 * 1000,
        messages: [
            '@%__username__% has summoned me, and so I appear.',
            'Yes master %__name__%, I shall appear as summoned.',
            'Yes mistress %__name__%, I shall appear as summoned.'
        ]
    };

    /**
     * @var {string} name The name of this sock_module
     */
    exports.name = "Summoner";

    /**
     * @var {number} priority If defined by a sock_module it is the priority of the module with respect to other modules.
     *
     * sock_modules **should not** define modules with negative permissions. Default value is 50 with lower numbers being higher priority.
     */
    exports.priority = 1000;

    /**
     * @var {string} version The version of this sock_module
     */
    exports.version = "1.1.0";

    function purgeMemory() {
        var lastHour = (new Date().getTime()) - 60 * 60 * 1000, // an hour ago;
            k; //key
        for (k in users) {
            if (users.hasOwnProperty(k) && users[k] < lastHour) {
                delete users[k];
            }
        }
        for (k in summons) {
            if (summons.hasOwnProperty(k) && summons[k] < lastHour) {
                delete summons[k];
            }
        }
    }

    exports.onNotify = function onNotify(type, notification, post, callback) {
        if (type === 'mentioned' &&  !(post.trust_level < 1 || post.primary_group_name === 'bots')) {
            var now = (new Date().getTime()),
                r = Math.floor(Math.random() * configuration.messages.length),
                s = configuration.messages[r],
                k;
            if (post.trust_level === 1 && (users[post.user_id] && now < users[post.user_id])) {
                return callback();
            }
            if (summons[notification.topic_id] && now < summons[notification.topic_id]) {
                return callback();
            }
            m_browser.log(notification.data.display_username + ' summoned me to play in ' + notification.slug);
            for (k in post) {
                if (post.hasOwnProperty(k)) {
                    s = s.replace(new RegExp('%__' + k + '__%', 'g'), post[k]);
                }
            }
            summons[notification.topic_id] = now + configuration.autoTimeout;
            if (post.trust_level === 1) {
                users[post.user_id] = now + configuration.userTimeout;
            }
            m_browser.reply_topic(notification.topic_id, notification.post_number, s, function () {
                callback(true);
            });
        } else {
            callback();
        }
    };
    exports.begin = function begin(browser, config) {
        configuration = config.modules[exports.name];
        m_browser = browser;
        setInterval(purgeMemory, 30 * 60 * 1000);
    };
}());<|endoftext|>


<commit_before>/* ========================================================================
 * ScrollPos-Styler v0.5
 * https://github.com/acch/scrollpos-styler
 * ========================================================================
 * Copyright 2015 Achim Christ
 * Licensed under MIT (https://github.com/acch/scrollpos-styler/blob/master/LICENSE)
 * ======================================================================== */

// JSHint directives
/* exported ScrollPosStyler */

var ScrollPosStyler = (function(document, window) {
  "use strict";

  /* ====================
   * private variables
   * ==================== */
  var scrollPosY = 0,
      busy = false,
      onTop = true,

      // toggle style / class when scrolling below this position (in px)
      scrollOffsetY = 1,

      // choose elements to apply style / class to
      elements = document.getElementsByClassName("sps");

  /* ====================
   * private funcion to check scroll position
   * ==================== */
  function onScroll() {
    // ensure that events don't stack
    if (!busy) {
      // get current scroll position from window
      scrollPosY = window.pageYOffset;

      // if we were above, and are now below scroll position...
      if (onTop && scrollPosY > scrollOffsetY) {
        // suspend accepting scroll events
        busy = true;

        // remember that we are below scroll position
        onTop = false;

        // asynchronuously add style / class to elements
        window.requestAnimationFrame(belowScrollPos);

      // if we were below, and are now above scroll position...
      } else if (!onTop && scrollPosY <= scrollOffsetY) {
        // suspend accepting scroll events
        busy = true;

        // remember that we are above scroll position
        onTop = true;

        // asynchronuously add style / class to elements
        window.requestAnimationFrame(aboveScrollPos);
      }
    }
  }

  /* ====================
   * private function to style elements when above scroll position
   * ==================== */
  function aboveScrollPos() {
    // iterate over elements
    // for (var elem of elements) {
    for (var i = 0; elements[i]; ++i) { // chrome workaround
      // add style / class to element
      elements[i].classList.add("sps--abv");
      elements[i].classList.remove("sps--blw");
    }

    // resume accepting scroll events
    busy = false;
  }

  /* ====================
   * private function to style elements when below scroll position
   * ==================== */
  function belowScrollPos() {
    // iterate over elements
    // for (var elem of elements) {
    for (var i = 0; elements[i]; ++i) { // chrome workaround
      // add style / class to element
      elements[i].classList.add("sps--blw");
      elements[i].classList.remove("sps--abv");
    }

    // resume accepting scroll events
    busy = false;
  }

  /* ====================
   * public function to initially style elements based on scroll position
   * ==================== */
  var pub = {
    init: function() {
      // suspend accepting scroll events
      busy = true;

      // get current scroll position from window
      scrollPosY = window.pageYOffset;

      // if we are below scroll position...
      if (scrollPosY > scrollOffsetY) {
        // remember that we are below scroll position
        onTop = false;

        // asynchronuously add style / class to elements
        window.requestAnimationFrame(belowScrollPos);

      // if we are above scroll position...
      } else { // (scrollPosY <= scrollOffsetY)
        // remember that we are above scroll position
        onTop = true;

        // asynchronuously add style / class to elements
        window.requestAnimationFrame(aboveScrollPos);
      }
    }
  };

  /* ====================
   * main initialization
   * ==================== */
  // add initial style / class to elements when DOM is ready
  document.addEventListener("DOMContentLoaded", function() {
    // defer initialization to allow browser to restore scroll position
    window.setTimeout(pub.init, 1);
  });

  // register for window scroll events
  window.addEventListener("scroll", onScroll);

  return pub;
})(document, window);
<commit_msg>Changed version to v0.6<commit_after>/* ========================================================================
 * ScrollPos-Styler v0.6
 * https://github.com/acch/scrollpos-styler
 * ========================================================================
 * Copyright 2015 Achim Christ
 * Licensed under MIT (https://github.com/acch/scrollpos-styler/blob/master/LICENSE)
 * ======================================================================== */

// JSHint directives
/* exported ScrollPosStyler */

var ScrollPosStyler = (function(document, window) {
  "use strict";

  /* ====================
   * private variables
   * ==================== */
  var scrollPosY = 0,
      busy = false,
      onTop = true,

      // toggle style / class when scrolling below this position (in px)
      scrollOffsetY = 1,

      // choose elements to apply style / class to
      elements = document.getElementsByClassName("sps");

  /* ====================
   * private funcion to check scroll position
   * ==================== */
  function onScroll() {
    // ensure that events don't stack
    if (!busy) {
      // get current scroll position from window
      scrollPosY = window.pageYOffset;

      // if we were above, and are now below scroll position...
      if (onTop && scrollPosY > scrollOffsetY) {
        // suspend accepting scroll events
        busy = true;

        // remember that we are below scroll position
        onTop = false;

        // asynchronuously add style / class to elements
        window.requestAnimationFrame(belowScrollPos);

      // if we were below, and are now above scroll position...
      } else if (!onTop && scrollPosY <= scrollOffsetY) {
        // suspend accepting scroll events
        busy = true;

        // remember that we are above scroll position
        onTop = true;

        // asynchronuously add style / class to elements
        window.requestAnimationFrame(aboveScrollPos);
      }
    }
  }

  /* ====================
   * private function to style elements when above scroll position
   * ==================== */
  function aboveScrollPos() {
    // iterate over elements
    // for (var elem of elements) {
    for (var i = 0; elements[i]; ++i) { // chrome workaround
      // add style / class to element
      elements[i].classList.add("sps--abv");
      elements[i].classList.remove("sps--blw");
    }

    // resume accepting scroll events
    busy = false;
  }

  /* ====================
   * private function to style elements when below scroll position
   * ==================== */
  function belowScrollPos() {
    // iterate over elements
    // for (var elem of elements) {
    for (var i = 0; elements[i]; ++i) { // chrome workaround
      // add style / class to element
      elements[i].classList.add("sps--blw");
      elements[i].classList.remove("sps--abv");
    }

    // resume accepting scroll events
    busy = false;
  }

  /* ====================
   * public function to initially style elements based on scroll position
   * ==================== */
  var pub = {
    init: function() {
      // suspend accepting scroll events
      busy = true;

      // get current scroll position from window
      scrollPosY = window.pageYOffset;

      // if we are below scroll position...
      if (scrollPosY > scrollOffsetY) {
        // remember that we are below scroll position
        onTop = false;

        // asynchronuously add style / class to elements
        window.requestAnimationFrame(belowScrollPos);

      // if we are above scroll position...
      } else { // (scrollPosY <= scrollOffsetY)
        // remember that we are above scroll position
        onTop = true;

        // asynchronuously add style / class to elements
        window.requestAnimationFrame(aboveScrollPos);
      }
    }
  };

  /* ====================
   * main initialization
   * ==================== */
  // add initial style / class to elements when DOM is ready
  document.addEventListener("DOMContentLoaded", function() {
    // defer initialization to allow browser to restore scroll position
    window.setTimeout(pub.init, 1);
  });

  // register for window scroll events
  window.addEventListener("scroll", onScroll);

  return pub;
})(document, window);
<|endoftext|>


<commit_before>import { ShaderCache } from './Renderer/shader_cache.js';

import iblFiltering from './shaders/ibl_filtering.frag';
import panoramaToCubeMap from './shaders/panorama_to_cubemap.frag';
import debugOutput from './shaders/debug.frag';
import fullscreenShader from './shaders/fullscreen.vert';

// How to use:
// set canvas/context in constructor
// init(input: panorama image)
// filterAll()
// fetch texture IDs

class iblSampler
{
    constructor(view)
    {

        this.gl = view.context;

        this.textureSize = 256;
        this.sampleCount = 64;
        this.lodBias = 0.0;
        this.mipmapCount = undefined;

        this.lambertianTextureID = undefined;
        this.ggxTextureID = undefined;
        this.sheenTextureID = undefined;

        this.inputTextureID = undefined;
        this.cubemapTextureID = undefined;
        this.framebuffer = undefined;

        const shaderSources = new Map();

        shaderSources.set("fullscreen.vert", fullscreenShader);
        shaderSources.set("panorama_to_cubemap.frag", panoramaToCubeMap);
        shaderSources.set("ibl_filtering.frag", iblFiltering);
        shaderSources.set("debug.frag", debugOutput);

        this.shaderCache = new ShaderCache(shaderSources, view.renderer.webGl);

    }

    /////////////////////////////////////////////////////////////////////

    loadTextureHDR(image)
    {

        var texture = this.gl.createTexture();

        this.gl.bindTexture( this.gl.TEXTURE_2D,  texture);

        this.gl.bindTexture( this.gl.TEXTURE_2D, texture); // as this function is asynchronus, another texture could be set in between

        var internalFormat = this.gl.RGBA32F;
        var format = this.gl.RGBA;
        var type = this.gl.FLOAT;
        var data = image.dataFloat;

        this.gl.texImage2D(
            this.gl.TEXTURE_2D,
            0, //level
            internalFormat,
            image.width,
            image.height,
            0, //border
            format,
            type,
            data);

        this.gl.texParameteri( this.gl.TEXTURE_2D,  this.gl.TEXTURE_WRAP_S,  this.gl.MIRRORED_REPEAT);
        this.gl.texParameteri( this.gl.TEXTURE_2D,  this.gl.TEXTURE_WRAP_T,  this.gl.MIRRORED_REPEAT);
        this.gl.texParameteri( this.gl.TEXTURE_2D,  this.gl.TEXTURE_MIN_FILTER,  this.gl.LINEAR);
        this.gl.texParameteri( this.gl.TEXTURE_2D,  this.gl.TEXTURE_MAG_FILTER,  this.gl.LINEAR);

        return texture;
    }

    createCubemapTexture(withMipmaps)
    {
        var targetTexture =  this.gl.createTexture();
        this.gl.bindTexture( this.gl.TEXTURE_CUBE_MAP, targetTexture);

        // define size and format of level 0
        const level = 0;
        const internalFormat = this.use8bit ? this.gl.RGBA8 : this.gl.RGBA32F;
        const border = 0;
        const format = this.gl.RGBA;
        const type = this.use8bit ? this.gl.UNSIGNED_BYTE : this.gl.FLOAT;
        const data = null;

        for(var i = 0; i < 6; ++i)
        {
            this.gl.texImage2D(this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, internalFormat,
                this.textureSize, this.textureSize, border,
                format, type, data);

        }

        if(withMipmaps)
        {
            this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_MIN_FILTER,  this.gl.LINEAR_MIPMAP_LINEAR);
        }
        else
        {
            this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_MIN_FILTER,  this.gl.LINEAR);
        }

        this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_MAG_FILTER,  this.gl.LINEAR);
        this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_WRAP_S,  this.gl.CLAMP_TO_EDGE);
        this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_WRAP_T,  this.gl.CLAMP_TO_EDGE);

        return targetTexture;
    }

    init(panoramaImage)
    {
        if (!this.gl.getExtension('EXT_color_buffer_float'))
        {
            this.use8bit = true;
        }

        this.inputTextureID = this.loadTextureHDR(panoramaImage);

        this.cubemapTextureID = this.createCubemapTexture(true);

        this.framebuffer = this.gl.createFramebuffer();

        this.lambertianTextureID = this.createCubemapTexture(false);
        this.ggxTextureID = this.createCubemapTexture(true);
        this.sheenTextureID = this.createCubemapTexture(true);

        this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.ggxTextureID);
        this.gl.generateMipmap(this.gl.TEXTURE_CUBE_MAP);

        this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.sheenTextureID);
        this.gl.generateMipmap(this.gl.TEXTURE_CUBE_MAP);

        this.mipmapLevels = Math.floor(Math.log2(this.textureSize))+1;
    }

    filterAll()
    {
        this.panoramaToCubeMap();
        this.cubeMapToLambertian();
        this.cubeMapToGGX();
        this.cubeMapToSheen();

        this.gl.bindFramebuffer(  this.gl.FRAMEBUFFER, null);
    }

    panoramaToCubeMap()
    {
        for(var i = 0; i < 6; ++i)
        {
            this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer);
            var side = i;
            this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_CUBE_MAP_POSITIVE_X+side, this.cubemapTextureID, 0);

            this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.cubemapTextureID);

            this.gl.viewport(0, 0,  this.textureSize,  this.textureSize);

            this.gl.clearColor(1.0, 0.0, 0.0, 0.0);
            this.gl.clear(this.gl.COLOR_BUFFER_BIT| this.gl.DEPTH_BUFFER_BIT);

            const vertexHash = this.shaderCache.selectShader("fullscreen.vert", []);
            const fragmentHash = this.shaderCache.selectShader("panorama_to_cubemap.frag", []);

            var shader = this.shaderCache.getShaderProgram(fragmentHash, vertexHash);
            this.gl.useProgram(shader.program);

            //  TEXTURE0 = active.
            this.gl.activeTexture(this.gl.TEXTURE0+0);

            // Bind texture ID to active texture
            this.gl.bindTexture(this.gl.TEXTURE_2D, this.inputTextureID);

            // map shader uniform to texture unit (TEXTURE0)
            const location = this.gl.getUniformLocation(shader.program,"u_panorama");
            this.gl.uniform1i(location, 0); // texture unit 0 (TEXTURE0)

            shader.updateUniform("u_currentFace", i);

            //fullscreen triangle
            this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
        }

        this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.cubemapTextureID);
        this.gl.generateMipmap(this.gl.TEXTURE_CUBE_MAP);

    }

    applyFilter(
        distribution,
        roughness,
        targetMipLevel,
        targetTexture)
    {
        var currentTextureSize =  this.textureSize>>(targetMipLevel);

        for(var i = 0; i < 6; ++i)
        {

            this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer);
            var side = i;
            this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_CUBE_MAP_POSITIVE_X+side, targetTexture, targetMipLevel);

            this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, targetTexture);

            this.gl.viewport(0, 0, currentTextureSize, currentTextureSize);

            this.gl.clearColor(1.0, 0.0, 0.0, 0.0);
            this.gl.clear(this.gl.COLOR_BUFFER_BIT| this.gl.DEPTH_BUFFER_BIT);

            const vertexHash = this.shaderCache.selectShader("fullscreen.vert", []);
            const fragmentHash = this.shaderCache.selectShader("ibl_filtering.frag", []);

            var shader = this.shaderCache.getShaderProgram(fragmentHash, vertexHash);
            this.gl.useProgram(shader.program);

            //  TEXTURE0 = active.
            this.gl.activeTexture(this.gl.TEXTURE0+0);

            // Bind texture ID to active texture
            this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.cubemapTextureID);

            // map shader uniform to texture unit (TEXTURE0)
            const location = this.gl.getUniformLocation(shader.program,"u_cubemapTexture");
            this.gl.uniform1i(location, 0); // texture unit 0

            shader.updateUniform("u_roughness", roughness);
            shader.updateUniform("u_sampleCount", this.sampleCount)
            shader.updateUniform("u_width", this.textureSize);
            shader.updateUniform("u_lodBias", this.lodBias);
            shader.updateUniform("u_distribution", distribution);
            shader.updateUniform("u_currentFace", i);

            //fullscreen triangle
            this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);

        }

    }

    cubeMapToLambertian()
    {
        this.applyFilter(
            0,
            0.0,
            0,
            this.lambertianTextureID);
    }

    cubeMapToGGX()
    {
        for(var currentMipLevel = 0; currentMipLevel < this.mipmapLevels; ++currentMipLevel)
        {
            const roughness =  (currentMipLevel) /  (this.mipmapLevels - 1);
            this.applyFilter(
                1,
                roughness,
                currentMipLevel,
                this.ggxTextureID);
        }
    }

    cubeMapToSheen()
    {
        for(var currentMipLevel = 0; currentMipLevel < this.mipmapLevels; ++currentMipLevel)
        {
            const roughness =  (currentMipLevel) /  (this.mipmapLevels - 1);
            this.applyFilter(
                2,
                roughness,
                currentMipLevel,
                this.sheenTextureID);
        }
    }

    destroy()
    {
        this.shaderCache.destroy();
    }
}

export { iblSampler };
<commit_msg>use  RGB32F<commit_after>import { ShaderCache } from './Renderer/shader_cache.js';

import iblFiltering from './shaders/ibl_filtering.frag';
import panoramaToCubeMap from './shaders/panorama_to_cubemap.frag';
import debugOutput from './shaders/debug.frag';
import fullscreenShader from './shaders/fullscreen.vert';

// How to use:
// set canvas/context in constructor
// init(input: panorama image)
// filterAll()
// fetch texture IDs

class iblSampler
{
    constructor(view)
    {

        this.gl = view.context;

        this.textureSize = 256;
        this.sampleCount = 64;
        this.lodBias = 0.0;
        this.mipmapCount = undefined;

        this.lambertianTextureID = undefined;
        this.ggxTextureID = undefined;
        this.sheenTextureID = undefined;

        this.inputTextureID = undefined;
        this.cubemapTextureID = undefined;
        this.framebuffer = undefined;

        const shaderSources = new Map();

        shaderSources.set("fullscreen.vert", fullscreenShader);
        shaderSources.set("panorama_to_cubemap.frag", panoramaToCubeMap);
        shaderSources.set("ibl_filtering.frag", iblFiltering);
        shaderSources.set("debug.frag", debugOutput);

        this.shaderCache = new ShaderCache(shaderSources, view.renderer.webGl);

    }

    /////////////////////////////////////////////////////////////////////

    loadTextureHDR(image)
    {

        var texture = this.gl.createTexture();

        this.gl.bindTexture( this.gl.TEXTURE_2D,  texture);

        var internalFormat = this.gl.RGB32F;
        var format = this.gl.RGB;
        var type = this.gl.FLOAT;
        var data = image.dataFloat;

        this.gl.texImage2D(
            this.gl.TEXTURE_2D,
            0, //level
            internalFormat,
            image.width,
            image.height,
            0, //border
            format,
            type,
            data);

        this.gl.texParameteri( this.gl.TEXTURE_2D,  this.gl.TEXTURE_WRAP_S,  this.gl.MIRRORED_REPEAT);
        this.gl.texParameteri( this.gl.TEXTURE_2D,  this.gl.TEXTURE_WRAP_T,  this.gl.MIRRORED_REPEAT);
        this.gl.texParameteri( this.gl.TEXTURE_2D,  this.gl.TEXTURE_MIN_FILTER,  this.gl.LINEAR);
        this.gl.texParameteri( this.gl.TEXTURE_2D,  this.gl.TEXTURE_MAG_FILTER,  this.gl.LINEAR);

        return texture;
    }

    createCubemapTexture(withMipmaps)
    {
        var targetTexture =  this.gl.createTexture();
        this.gl.bindTexture( this.gl.TEXTURE_CUBE_MAP, targetTexture);

        // define size and format of level 0
        const level = 0;
        const internalFormat = this.use8bit ? this.gl.RGBA8 : this.gl.RGBA32F;
        const border = 0;
        const format = this.gl.RGBA;
        const type = this.use8bit ? this.gl.UNSIGNED_BYTE : this.gl.FLOAT;
        const data = null;

        for(var i = 0; i < 6; ++i)
        {
            this.gl.texImage2D(this.gl.TEXTURE_CUBE_MAP_POSITIVE_X + i, level, internalFormat,
                this.textureSize, this.textureSize, border,
                format, type, data);

        }

        if(withMipmaps)
        {
            this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_MIN_FILTER,  this.gl.LINEAR_MIPMAP_LINEAR);
        }
        else
        {
            this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_MIN_FILTER,  this.gl.LINEAR);
        }

        this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_MAG_FILTER,  this.gl.LINEAR);
        this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_WRAP_S,  this.gl.CLAMP_TO_EDGE);
        this.gl.texParameteri( this.gl.TEXTURE_CUBE_MAP,  this.gl.TEXTURE_WRAP_T,  this.gl.CLAMP_TO_EDGE);

        return targetTexture;
    }

    init(panoramaImage)
    {
        if (!this.gl.getExtension('EXT_color_buffer_float'))
        {
            this.use8bit = true;
        }

        this.inputTextureID = this.loadTextureHDR(panoramaImage);

        this.cubemapTextureID = this.createCubemapTexture(true);

        this.framebuffer = this.gl.createFramebuffer();

        this.lambertianTextureID = this.createCubemapTexture(false);
        this.ggxTextureID = this.createCubemapTexture(true);
        this.sheenTextureID = this.createCubemapTexture(true);

        this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.ggxTextureID);
        this.gl.generateMipmap(this.gl.TEXTURE_CUBE_MAP);

        this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.sheenTextureID);
        this.gl.generateMipmap(this.gl.TEXTURE_CUBE_MAP);

        this.mipmapLevels = Math.floor(Math.log2(this.textureSize))+1;
    }

    filterAll()
    {
        this.panoramaToCubeMap();
        this.cubeMapToLambertian();
        this.cubeMapToGGX();
        this.cubeMapToSheen();

        this.gl.bindFramebuffer(  this.gl.FRAMEBUFFER, null);
    }

    panoramaToCubeMap()
    {
        for(var i = 0; i < 6; ++i)
        {
            this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer);
            var side = i;
            this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_CUBE_MAP_POSITIVE_X+side, this.cubemapTextureID, 0);

            this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.cubemapTextureID);

            this.gl.viewport(0, 0,  this.textureSize,  this.textureSize);

            this.gl.clearColor(1.0, 0.0, 0.0, 0.0);
            this.gl.clear(this.gl.COLOR_BUFFER_BIT| this.gl.DEPTH_BUFFER_BIT);

            const vertexHash = this.shaderCache.selectShader("fullscreen.vert", []);
            const fragmentHash = this.shaderCache.selectShader("panorama_to_cubemap.frag", []);

            var shader = this.shaderCache.getShaderProgram(fragmentHash, vertexHash);
            this.gl.useProgram(shader.program);

            //  TEXTURE0 = active.
            this.gl.activeTexture(this.gl.TEXTURE0+0);

            // Bind texture ID to active texture
            this.gl.bindTexture(this.gl.TEXTURE_2D, this.inputTextureID);

            // map shader uniform to texture unit (TEXTURE0)
            const location = this.gl.getUniformLocation(shader.program,"u_panorama");
            this.gl.uniform1i(location, this.gl.TEXTURE0+0); // texture unit 0 (TEXTURE0)

            shader.updateUniform("u_currentFace", i);

            //fullscreen triangle
            this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
        }

        this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.cubemapTextureID);
        this.gl.generateMipmap(this.gl.TEXTURE_CUBE_MAP);

    }

    applyFilter(
        distribution,
        roughness,
        targetMipLevel,
        targetTexture)
    {
        var currentTextureSize =  this.textureSize>>(targetMipLevel);

        for(var i = 0; i < 6; ++i)
        {

            this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.framebuffer);
            var side = i;
            this.gl.framebufferTexture2D(this.gl.FRAMEBUFFER, this.gl.COLOR_ATTACHMENT0, this.gl.TEXTURE_CUBE_MAP_POSITIVE_X+side, targetTexture, targetMipLevel);

            this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, targetTexture);

            this.gl.viewport(0, 0, currentTextureSize, currentTextureSize);

            this.gl.clearColor(1.0, 0.0, 0.0, 0.0);
            this.gl.clear(this.gl.COLOR_BUFFER_BIT| this.gl.DEPTH_BUFFER_BIT);

            const vertexHash = this.shaderCache.selectShader("fullscreen.vert", []);
            const fragmentHash = this.shaderCache.selectShader("ibl_filtering.frag", []);

            var shader = this.shaderCache.getShaderProgram(fragmentHash, vertexHash);
            this.gl.useProgram(shader.program);

            //  TEXTURE0 = active.
            this.gl.activeTexture(this.gl.TEXTURE0+0);

            // Bind texture ID to active texture
            this.gl.bindTexture(this.gl.TEXTURE_CUBE_MAP, this.cubemapTextureID);

            // map shader uniform to texture unit (TEXTURE0)
            const location = this.gl.getUniformLocation(shader.program,"u_cubemapTexture");
            this.gl.uniform1i(location, 0); // texture unit 0

            shader.updateUniform("u_roughness", roughness);
            shader.updateUniform("u_sampleCount", this.sampleCount)
            shader.updateUniform("u_width", this.textureSize);
            shader.updateUniform("u_lodBias", this.lodBias);
            shader.updateUniform("u_distribution", distribution);
            shader.updateUniform("u_currentFace", i);

            //fullscreen triangle
            this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);

        }

    }

    cubeMapToLambertian()
    {
        this.applyFilter(
            0,
            0.0,
            0,
            this.lambertianTextureID);
    }

    cubeMapToGGX()
    {
        for(var currentMipLevel = 0; currentMipLevel < this.mipmapLevels; ++currentMipLevel)
        {
            const roughness =  (currentMipLevel) /  (this.mipmapLevels - 1);
            this.applyFilter(
                1,
                roughness,
                currentMipLevel,
                this.ggxTextureID);
        }
    }

    cubeMapToSheen()
    {
        for(var currentMipLevel = 0; currentMipLevel < this.mipmapLevels; ++currentMipLevel)
        {
            const roughness =  (currentMipLevel) /  (this.mipmapLevels - 1);
            this.applyFilter(
                2,
                roughness,
                currentMipLevel,
                this.sheenTextureID);
        }
    }

    destroy()
    {
        this.shaderCache.destroy();
    }
}

export { iblSampler };
<|endoftext|>