<commit_before>Registrants = new Meteor.Collection("registrants");

/*
List of all monthly meetings and worship groups
used for registrant meeting options
*/
var meetingArray = [
    "Appleseed Meeting",
    "Berkeley Meeting",
    "Big Island Meeting",
    "Central Coast Meeting",
    "Conejo Valley Worship Group",
    "Chico Meeting",
    "Claremont Monthly Meeting",
    "Davis Meeting",
    "Delta Meeting",
    "Fresno Meeting",
    "Friends House Worship Group",
    "Friends of Soledad",
    "Grass Valley Meeting",
    "Guatemala Monthly Meeting",
    "Honolulu Meeting",
    "Humboldt Meeting",
    "Inland Valley Friends Meeting",
    "Kauai Worship Group",
    "La Jolla Monthly Meeting",
    "Lake County Worship Group",
    "Las Vegas Worship Group",
    "Live Oak Monthly Meeting",
    "Livermore",
    "Marin Meeting",
    "Marloma Long Beach Monthly Meeting",
    "Maui Worship Group",
    "Mendocino Meeting",
    "Mexico City Monthly Meeting",
    "Modesto Worship Group",
    "Molokai Worship Group",
    "Monterey Peninsula Meeting",
    "Napa Sonoma Meeting",
    "Oakland Worship Group",
    "Ojai Friends Worship Group",
    "Orange Grove Monthly Meeting",
    "Palo Alto Meeting",
    "Redding Meeting",
    "Redwood Forest Meeting",
    "Reno Meeting",
    "Sacramento Meeting",
    "San Diego Monthly Meeting",
    "San Francisco Meeting",
    "San Jose Meeting",
    "Santa Barbara Monthly Meeting",
    "Santa Cruz Meeting",
    "Santa Monica Monthly Meeting",
    "Southern Humboldt Worship Group",
    "Strawberry Creek Meeting",
    "Ukiah Worship Group",
    "Visalia Meeting",
    "Whitleaf Worship Group"
];

/*
Take a string and convert it to an object in the form:
{label: string, value: string}
Used by autoform select menu
*/
var createAutoformSelectObject = function (string) {
    var autoformSelectObject = {label: string, value: string};
    return autoformSelectObject;
};

/*
Meeting options list
created by mapping all meetings in meeting array
to objects conforming to the {label: label, value: value}
required by autoform
*/
var registrantMeetingOptions = meetingArray.map(createAutoformSelectObject);

Registrants.attachSchema(new SimpleSchema({
    'first_name' : {
        type: String,
        label: "First Name",
        max: 200
    },
    'last_name': {
        type: String,
        label: "Last Name",
        max: 200
    },
    'age': {
        label: "Age at time of event",
        type: Number,
        max: 115,
        min: 0
    },
    'ageGroup': {
        type: String,
        allowedValues: [
            'child',
            'youth',
            'teen',
            'youngAdult',
            'adult'
        ],
        optional: true,
        autoValue: function (doc) {
            // calculate age group based on age field
            return calculateAgeGroup(this.field("age").value);
        }
    },
    'registrationType': {
        type: String,
        allowedValues: [
            'commuter',
            'daily',
            'weekly'
        ]
    },
    'accommodations': {
        type: String,
        allowedValues: [
            'camping',
            'dorm',
            'semiprivate',
            'private',
            'jym',
            'yaf'
        ],
        optional: true,
        custom: function () {
            // Required if registration is daily or weekly
            if ( !this.isSet
                &&
                (
                this.field('registrationType').value === "daily"
                ||
                this.field('registrationType').value === "weekly")
               ) {
                return "required";
            }
        }
    },
    days: {
        type: [String],
        optional: true,
        autoform: {
            type: "select-checkbox-inline",
            options: function () {
                return [
                    {label: "Monday", value: "Monday"},
                    {label: "Tuesday", value: "Tuesday"},
                    {label: "Wednesday", value: "Wednesday"},
                    {label: "Thursday", value: "Thursday"},
                    {label: "Friday", value: "Friday"},
                    {label: "Saturday", value: "Saturday"}
                ];
            }
        }
    },
    'fee' : {
        type: Number,
        label: "Fee",
        optional: true,
        autoValue: function (doc) {
            // Set up an empty registration object
            // to hold values from the submitted registration
            var registration = {};

            // get values from submitted registration and
            // set attributes on the registration object
            registration.ageGroup = this.field("ageGroup").value;
            registration.type = this.field("registrationType").value;
            registration.accommodations = this.field("accommodations").value;
            registration.days =  this.field("days").value;
            registration.firstTimeAttender = this.field("firstTimeAttender").value;

            // calculate the registration fee
            // based on the submitted registration
            return calculateRegistrationPrice(registration);
        }
    },
    foodPreference: {
        type: [String],
        optional: true,
        autoform: {
            type: "select-checkbox-inline",
            allowedValues: [
                'Omnivore',
                'Vegetarian',
                'Vegan',
                'Gluten-free',
                'Dairy-free',
                'Sugar-free',
                'Soy-free',
                'Raw vegetables',
                'Low-salt'
            ],
            options: function () {
                return [
                    {label: "Omnivore", value: "Omnivore"},
                    {label: "Vegetarian", value: "Vegetarian"},
                    {label: "Vegan", value: "Vegan"},
                    {label: "Gluten-free", value: "Gluten-free"},
                    {label: "Dairy-free", value: "Dairy-free"},
                    {label: "Sugar-free", value: "Sugar-free"},
                    {label: "Soy-free", value: "Soy-free"},
                    {label: "Raw vegetables", value: "Raw vegetables"},
                    {label: "Low-salt", value: "Low-salt"}
                ];
            }
        }
    },
    'registrantEmail': {
        type: String,
        regEx: SimpleSchema.RegEx.Email,
        label: "Registrant E-mail address",
        optional: true
    },
    registrantMeeting: {
        type: String,
        optional: true,
        autoform: {
            type: "select",
            options: registrantMeetingOptions
        },
        label: "Registrant Meeting"
    },
    'firstTimeAttender': {
        type: Boolean,
        optional: true,
        defaultValue: false,
        label: "First time attender?"
    },
    'linens': {
        type: Boolean,
        optional: true,
        defaultValue: false,
        label: "Will you need linens? ($25 extra)"
    }
}));

Registrants.before.insert(function (userId, doc){
    // set registration created date to current date
    doc.createdAt = Date.now();

    //  Attach registration to Meteor user
    // for reporting, access control, etc
    doc.createdById = userId;

    // Add user email address to registration document
    doc.createdByEmail = Meteor.users.findOne(userId).emails[0].address;
});
<commit_msg>Moved fee to end of schema.<commit_after>Registrants = new Meteor.Collection("registrants");

/*
List of all monthly meetings and worship groups
used for registrant meeting options
*/
var meetingArray = [
    "Appleseed Meeting",
    "Berkeley Meeting",
    "Big Island Meeting",
    "Central Coast Meeting",
    "Conejo Valley Worship Group",
    "Chico Meeting",
    "Claremont Monthly Meeting",
    "Davis Meeting",
    "Delta Meeting",
    "Fresno Meeting",
    "Friends House Worship Group",
    "Friends of Soledad",
    "Grass Valley Meeting",
    "Guatemala Monthly Meeting",
    "Honolulu Meeting",
    "Humboldt Meeting",
    "Inland Valley Friends Meeting",
    "Kauai Worship Group",
    "La Jolla Monthly Meeting",
    "Lake County Worship Group",
    "Las Vegas Worship Group",
    "Live Oak Monthly Meeting",
    "Livermore",
    "Marin Meeting",
    "Marloma Long Beach Monthly Meeting",
    "Maui Worship Group",
    "Mendocino Meeting",
    "Mexico City Monthly Meeting",
    "Modesto Worship Group",
    "Molokai Worship Group",
    "Monterey Peninsula Meeting",
    "Napa Sonoma Meeting",
    "Oakland Worship Group",
    "Ojai Friends Worship Group",
    "Orange Grove Monthly Meeting",
    "Palo Alto Meeting",
    "Redding Meeting",
    "Redwood Forest Meeting",
    "Reno Meeting",
    "Sacramento Meeting",
    "San Diego Monthly Meeting",
    "San Francisco Meeting",
    "San Jose Meeting",
    "Santa Barbara Monthly Meeting",
    "Santa Cruz Meeting",
    "Santa Monica Monthly Meeting",
    "Southern Humboldt Worship Group",
    "Strawberry Creek Meeting",
    "Ukiah Worship Group",
    "Visalia Meeting",
    "Whitleaf Worship Group"
];

/*
Take a string and convert it to an object in the form:
{label: string, value: string}
Used by autoform select menu
*/
var createAutoformSelectObject = function (string) {
    var autoformSelectObject = {label: string, value: string};
    return autoformSelectObject;
};

/*
Meeting options list
created by mapping all meetings in meeting array
to objects conforming to the {label: label, value: value}
required by autoform
*/
var registrantMeetingOptions = meetingArray.map(createAutoformSelectObject);

Registrants.attachSchema(new SimpleSchema({
    'first_name' : {
        type: String,
        label: "First Name",
        max: 200
    },
    'last_name': {
        type: String,
        label: "Last Name",
        max: 200
    },
    'age': {
        label: "Age at time of event",
        type: Number,
        max: 115,
        min: 0
    },
    'ageGroup': {
        type: String,
        allowedValues: [
            'child',
            'youth',
            'teen',
            'youngAdult',
            'adult'
        ],
        optional: true,
        autoValue: function (doc) {
            // calculate age group based on age field
            return calculateAgeGroup(this.field("age").value);
        }
    },
    'registrationType': {
        type: String,
        allowedValues: [
            'commuter',
            'daily',
            'weekly'
        ]
    },
    'accommodations': {
        type: String,
        allowedValues: [
            'camping',
            'dorm',
            'semiprivate',
            'private',
            'jym',
            'yaf'
        ],
        optional: true,
        custom: function () {
            // Required if registration is daily or weekly
            if ( !this.isSet
                &&
                (
                this.field('registrationType').value === "daily"
                ||
                this.field('registrationType').value === "weekly")
               ) {
                return "required";
            }
        }
    },
    days: {
        type: [String],
        optional: true,
        autoform: {
            type: "select-checkbox-inline",
            options: function () {
                return [
                    {label: "Monday", value: "Monday"},
                    {label: "Tuesday", value: "Tuesday"},
                    {label: "Wednesday", value: "Wednesday"},
                    {label: "Thursday", value: "Thursday"},
                    {label: "Friday", value: "Friday"},
                    {label: "Saturday", value: "Saturday"}
                ];
            }
        }
    },
    foodPreference: {
        type: [String],
        optional: true,
        autoform: {
            type: "select-checkbox-inline",
            allowedValues: [
                'Omnivore',
                'Vegetarian',
                'Vegan',
                'Gluten-free',
                'Dairy-free',
                'Sugar-free',
                'Soy-free',
                'Raw vegetables',
                'Low-salt'
            ],
            options: function () {
                return [
                    {label: "Omnivore", value: "Omnivore"},
                    {label: "Vegetarian", value: "Vegetarian"},
                    {label: "Vegan", value: "Vegan"},
                    {label: "Gluten-free", value: "Gluten-free"},
                    {label: "Dairy-free", value: "Dairy-free"},
                    {label: "Sugar-free", value: "Sugar-free"},
                    {label: "Soy-free", value: "Soy-free"},
                    {label: "Raw vegetables", value: "Raw vegetables"},
                    {label: "Low-salt", value: "Low-salt"}
                ];
            }
        }
    },
    'registrantEmail': {
        type: String,
        regEx: SimpleSchema.RegEx.Email,
        label: "Registrant E-mail address",
        optional: true
    },
    registrantMeeting: {
        type: String,
        optional: true,
        autoform: {
            type: "select",
            options: registrantMeetingOptions
        },
        label: "Registrant Meeting"
    },
    'firstTimeAttender': {
        type: Boolean,
        optional: true,
        defaultValue: false,
        label: "First time attender?"
    },
    'linens': {
        type: Boolean,
        optional: true,
        defaultValue: false,
        label: "Will you need linens? ($25 extra)"
    },
    'fee' : {
        type: Number,
        label: "Fee",
        optional: true,
        autoValue: function (doc) {
            // Set up an empty registration object
            // to hold values from the submitted registration
            var registration = {};

            // get values from submitted registration and
            // set attributes on the registration object
            registration.ageGroup = this.field("ageGroup").value;
            registration.type = this.field("registrationType").value;
            registration.accommodations = this.field("accommodations").value;
            registration.days =  this.field("days").value;
            registration.firstTimeAttender = this.field("firstTimeAttender").value;

            // calculate the registration fee
            // based on the submitted registration
            return calculateRegistrationPrice(registration);
        }
    }
}));

Registrants.before.insert(function (userId, doc){
    // set registration created date to current date
    doc.createdAt = Date.now();

    //  Attach registration to Meteor user
    // for reporting, access control, etc
    doc.createdById = userId;

    // Add user email address to registration document
    doc.createdByEmail = Meteor.users.findOne(userId).emails[0].address;
});
<|endoftext|>


<commit_before>#!/usr/bin/env gjs
//
// Copyright (C) 2013 Colin Walters <walters@verbum.org>
//
// SPDX-License-Identifier: LGPL-2.0+
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.

const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const OSTree = imports.gi.OSTree;

function assertEquals(a, b) {
    if (a != b)
	throw new Error("assertion failed " + JSON.stringify(a) + " == " + JSON.stringify(b));
}

function assertGreater(a, b) {
    if (a <= b)
	throw new Error("assertion failed " + JSON.stringify(a) + " > " + JSON.stringify(b));
}

function assertGreaterEquals(a, b) {
    if (a < b)
	throw new Error("assertion failed " + JSON.stringify(a) + " >= " + JSON.stringify(b));
}

// Adapted from _ostree_read_varuint64()
function readVarint(buffer) {
    let result = 0;
    let count = 0;
    let len = buffer.length;
    let cur;

    do {
        assertGreater(len, 0);
        cur = buffer[count];
        result = result | ((cur & 0x7F) << (7 * count));
        count++;
        len--;
    } while (cur & 0x80);

    return [result, count];
}

// There have been various bugs with byte array unpacking in GJS, so
// just do it manually.
function unpackByteArray(variant) {
    let array = [];
    let nBytes = variant.n_children();
    for (let i = 0; i < nBytes; i++) {
        array.push(variant.get_child_value(i).get_byte());
    }
    return array;
}

function validateSizes(repo, commit, expectedFiles) {
    let [,commitVariant] = repo.load_variant(OSTree.ObjectType.COMMIT, commit);
    let metadata = commitVariant.get_child_value(0);
    let sizes = metadata.lookup_value('ostree.sizes', GLib.VariantType.new('aay'));
    let nSizes = sizes.n_children();
    let expectedNSizes = Object.keys(expectedFiles).length
    assertEquals(nSizes, expectedNSizes);

    for (let i = 0; i < nSizes; i++) {
        let sizeEntry = sizes.get_child_value(i);
        assertGreaterEquals(sizeEntry.n_children(), 34);
        let entryBytes = unpackByteArray(sizeEntry);
        let checksumBytes = entryBytes.slice(0, 32);
        let checksumString = OSTree.checksum_from_bytes(checksumBytes);
        print("checksum = " + checksumString);

        // Read the sizes from the next 2 varints
        let remainingBytes = entryBytes.slice(32);
        assertGreaterEquals(remainingBytes.length, 2);
        let varintRead;
        let compressedSize;
        let uncompressedSize;
        [compressedSize, varintRead] = readVarint(remainingBytes);
        remainingBytes = remainingBytes.slice(varintRead);
        assertGreaterEquals(remainingBytes.length, 1);
        [uncompressedSize, varintRead] = readVarint(remainingBytes);
        remainingBytes = remainingBytes.slice(varintRead);
        assertEquals(remainingBytes.length, 0);
        print("compressed = " + compressedSize);
        print("uncompressed = " + uncompressedSize);

        if (!(checksumString in expectedFiles)) {
            throw new Error("Checksum " + checksumString + " not in " +
                            JSON.stringify(expectedFiles));
        }
        let expectedSizes = expectedFiles[checksumString];
        let expectedCompressedSize = expectedSizes[0];
        let expectedUncompressedSize = expectedSizes[1];
        if (compressedSize != expectedCompressedSize) {
            throw new Error("Compressed size " + compressedSize +
                            " for checksum " + checksumString +
                            " does not match expected " + expectedCompressedSize);
        }
        if (uncompressedSize != expectedUncompressedSize) {
            throw new Error("Uncompressed size " + uncompressedSize +
                            " for checksum " + checksumString +
                            " does not match expected " + expectedUncompressedSize);
        }
    }
}

print('1..2')

let testDataDir = Gio.File.new_for_path('test-data');
testDataDir.make_directory(null);
testDataDir.get_child('some-file').replace_contents("hello world!", null, false, 0, null);
testDataDir.get_child('another-file').replace_contents("hello world again!", null, false, 0, null);

let repoPath = Gio.File.new_for_path('repo');
let repo = OSTree.Repo.new(repoPath);
repo.create(OSTree.RepoMode.ARCHIVE_Z2, null);

repo.open(null);

let commitModifierFlags = (OSTree.RepoCommitModifierFlags.GENERATE_SIZES |
                           OSTree.RepoCommitModifierFlags.SKIP_XATTRS |
                           OSTree.RepoCommitModifierFlags.CANONICAL_PERMISSIONS);
let commitModifier = OSTree.RepoCommitModifier.new(commitModifierFlags, null);

assertEquals(repo.get_mode(), OSTree.RepoMode.ARCHIVE_Z2);

repo.prepare_transaction(null);

let mtree = OSTree.MutableTree.new();
repo.write_directory_to_mtree(testDataDir, mtree, commitModifier, null);
let [,dirTree] = repo.write_mtree(mtree, null);
let [,commit] = repo.write_commit(null, 'Some subject', 'Some body', null, dirTree, null);
print("commit => " + commit);

repo.commit_transaction(null);

// Test the sizes metadata
let expectedFiles = {
    'f5ee222a21e2c96edbd6f2543c4bc8a039f827be3823d04777c9ee187778f1ad': [54, 18],
    'd35bfc50864fca777dbeead3ba3689115b76674a093210316589b1fe5cc3ff4b': [48, 12],
};
validateSizes(repo, commit, expectedFiles);

print("ok test-sizes");

// Repeat the commit now that all the objects are cached and ensure the
// metadata is still correct
repo.prepare_transaction(null);
mtree = OSTree.MutableTree.new();
repo.write_directory_to_mtree(testDataDir, mtree, commitModifier, null);
[,dirTree] = repo.write_mtree(mtree, null);
[,commit] = repo.write_commit(null, 'Another subject', 'Another body', null, dirTree, null);
print("commit => " + commit);
repo.commit_transaction(null);

validateSizes(repo, commit, expectedFiles);

print("ok test-sizes repeated");
<commit_msg>tests/sizes: Test that sizes metadata is not reused<commit_after>#!/usr/bin/env gjs
//
// Copyright (C) 2013 Colin Walters <walters@verbum.org>
//
// SPDX-License-Identifier: LGPL-2.0+
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the
// Free Software Foundation, Inc., 59 Temple Place - Suite 330,
// Boston, MA 02111-1307, USA.

const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const OSTree = imports.gi.OSTree;

function assertEquals(a, b) {
    if (a != b)
	throw new Error("assertion failed " + JSON.stringify(a) + " == " + JSON.stringify(b));
}

function assertGreater(a, b) {
    if (a <= b)
	throw new Error("assertion failed " + JSON.stringify(a) + " > " + JSON.stringify(b));
}

function assertGreaterEquals(a, b) {
    if (a < b)
	throw new Error("assertion failed " + JSON.stringify(a) + " >= " + JSON.stringify(b));
}

// Adapted from _ostree_read_varuint64()
function readVarint(buffer) {
    let result = 0;
    let count = 0;
    let len = buffer.length;
    let cur;

    do {
        assertGreater(len, 0);
        cur = buffer[count];
        result = result | ((cur & 0x7F) << (7 * count));
        count++;
        len--;
    } while (cur & 0x80);

    return [result, count];
}

// There have been various bugs with byte array unpacking in GJS, so
// just do it manually.
function unpackByteArray(variant) {
    let array = [];
    let nBytes = variant.n_children();
    for (let i = 0; i < nBytes; i++) {
        array.push(variant.get_child_value(i).get_byte());
    }
    return array;
}

function validateSizes(repo, commit, expectedFiles) {
    let [,commitVariant] = repo.load_variant(OSTree.ObjectType.COMMIT, commit);
    let metadata = commitVariant.get_child_value(0);
    let sizes = metadata.lookup_value('ostree.sizes', GLib.VariantType.new('aay'));
    let nSizes = sizes.n_children();
    let expectedNSizes = Object.keys(expectedFiles).length
    assertEquals(nSizes, expectedNSizes);

    for (let i = 0; i < nSizes; i++) {
        let sizeEntry = sizes.get_child_value(i);
        assertGreaterEquals(sizeEntry.n_children(), 34);
        let entryBytes = unpackByteArray(sizeEntry);
        let checksumBytes = entryBytes.slice(0, 32);
        let checksumString = OSTree.checksum_from_bytes(checksumBytes);
        print("checksum = " + checksumString);

        // Read the sizes from the next 2 varints
        let remainingBytes = entryBytes.slice(32);
        assertGreaterEquals(remainingBytes.length, 2);
        let varintRead;
        let compressedSize;
        let uncompressedSize;
        [compressedSize, varintRead] = readVarint(remainingBytes);
        remainingBytes = remainingBytes.slice(varintRead);
        assertGreaterEquals(remainingBytes.length, 1);
        [uncompressedSize, varintRead] = readVarint(remainingBytes);
        remainingBytes = remainingBytes.slice(varintRead);
        assertEquals(remainingBytes.length, 0);
        print("compressed = " + compressedSize);
        print("uncompressed = " + uncompressedSize);

        if (!(checksumString in expectedFiles)) {
            throw new Error("Checksum " + checksumString + " not in " +
                            JSON.stringify(expectedFiles));
        }
        let expectedSizes = expectedFiles[checksumString];
        let expectedCompressedSize = expectedSizes[0];
        let expectedUncompressedSize = expectedSizes[1];
        if (compressedSize != expectedCompressedSize) {
            throw new Error("Compressed size " + compressedSize +
                            " for checksum " + checksumString +
                            " does not match expected " + expectedCompressedSize);
        }
        if (uncompressedSize != expectedUncompressedSize) {
            throw new Error("Uncompressed size " + uncompressedSize +
                            " for checksum " + checksumString +
                            " does not match expected " + expectedUncompressedSize);
        }
    }
}

print('1..3')

let testDataDir = Gio.File.new_for_path('test-data');
testDataDir.make_directory(null);
testDataDir.get_child('some-file').replace_contents("hello world!", null, false, 0, null);
testDataDir.get_child('another-file').replace_contents("hello world again!", null, false, 0, null);

let repoPath = Gio.File.new_for_path('repo');
let repo = OSTree.Repo.new(repoPath);
repo.create(OSTree.RepoMode.ARCHIVE_Z2, null);

repo.open(null);

let commitModifierFlags = (OSTree.RepoCommitModifierFlags.GENERATE_SIZES |
                           OSTree.RepoCommitModifierFlags.SKIP_XATTRS |
                           OSTree.RepoCommitModifierFlags.CANONICAL_PERMISSIONS);
let commitModifier = OSTree.RepoCommitModifier.new(commitModifierFlags, null);

assertEquals(repo.get_mode(), OSTree.RepoMode.ARCHIVE_Z2);

repo.prepare_transaction(null);

let mtree = OSTree.MutableTree.new();
repo.write_directory_to_mtree(testDataDir, mtree, commitModifier, null);
let [,dirTree] = repo.write_mtree(mtree, null);
let [,commit] = repo.write_commit(null, 'Some subject', 'Some body', null, dirTree, null);
print("commit => " + commit);

repo.commit_transaction(null);

// Test the sizes metadata
let expectedFiles = {
    'f5ee222a21e2c96edbd6f2543c4bc8a039f827be3823d04777c9ee187778f1ad': [54, 18],
    'd35bfc50864fca777dbeead3ba3689115b76674a093210316589b1fe5cc3ff4b': [48, 12],
};
validateSizes(repo, commit, expectedFiles);

print("ok test-sizes");

// Remove a file to make sure that metadata is not reused from the
// previous commit
testDataDir.get_child('another-file').delete(null);
delete expectedFiles['f5ee222a21e2c96edbd6f2543c4bc8a039f827be3823d04777c9ee187778f1ad'];

repo.prepare_transaction(null);
mtree = OSTree.MutableTree.new();
repo.write_directory_to_mtree(testDataDir, mtree, commitModifier, null);
[,dirTree] = repo.write_mtree(mtree, null);
[,commit] = repo.write_commit(null, 'Some subject', 'Some body', null, dirTree, null);
print("commit => " + commit);
repo.commit_transaction(null);

validateSizes(repo, commit, expectedFiles);

print("ok test-sizes file deleted");

// Repeat the commit now that all the objects are cached and ensure the
// metadata is still correct
repo.prepare_transaction(null);
mtree = OSTree.MutableTree.new();
repo.write_directory_to_mtree(testDataDir, mtree, commitModifier, null);
[,dirTree] = repo.write_mtree(mtree, null);
[,commit] = repo.write_commit(null, 'Another subject', 'Another body', null, dirTree, null);
print("commit => " + commit);
repo.commit_transaction(null);

validateSizes(repo, commit, expectedFiles);

print("ok test-sizes repeated");
<|endoftext|>


<commit_before>/*jslint node: true, indent: 4, maxlen: 80 */
"use strict";

/**
 * ENVy
 *
 * Handle your project environment properties from a simple .json file.
 * Determine multiple environments and inherit properties between them.
 */
var envy = exports,

    /**
     * Checks for Object instances.
     */
    isObject = function (object) {
        return Object.prototype.toString.call(object) === "[object Object]";
    },

    /**
     * Deep copies the properties of the source object into the destination
     * object.
     */
    deepCopy = function (destination, source) {
        Object.keys(source).forEach(function (property) {
            if (destination[property] && isObject(destination[property])) {
                deepCopy(destination[property], source[property]);
            } else {
                destination[property] = source[property];
            }
        });
    };

/**
 * Loads the configuration .json file with the provided filename and returns an
 * object with the environment properties.
 * If no filename is providen then ./config.json will be loaded.
 */
envy.load = function (filename) {

    // filenames are relative to the execution path
    var configFile = require(process.env.PWD + "/" + (filename || "config")),
        config = configFile[configFile.environment];

    // Overwrite default configuration if the NODE_ENV environment variable is
    // defined
    if (process.env.NODE_ENV && configFile[process.env.NODE_ENV]) {
        deepCopy(config, configFile[process.env.NODE_ENV]);
    }

    return config;

};

/**
 * DEPRECATED
 *
 * envy.config can be replaced with envy.load(). Therefore it will
 * be deleted.
 */
// Load the default configuration file if it exists
try {
    envy.config = envy.load();
} catch (e) {
    // Ignore failure when loading default configuration file
}
<commit_msg>changed process.env.PWD to prorocess.cwd()<commit_after>/*jslint node: true, indent: 4, maxlen: 80 */
"use strict";

/**
 * ENVy
 *
 * Handle your project environment properties from a simple .json file.
 * Determine multiple environments and inherit properties between them.
 */
var envy = exports,

    /**
     * Checks for Object instances.
     */
    isObject = function (object) {
        return Object.prototype.toString.call(object) === "[object Object]";
    },

    /**
     * Deep copies the properties of the source object into the destination
     * object.
     */
    deepCopy = function (destination, source) {
        Object.keys(source).forEach(function (property) {
            if (destination[property] && isObject(destination[property])) {
                deepCopy(destination[property], source[property]);
            } else {
                destination[property] = source[property];
            }
        });
    };

/**
 * Loads the configuration .json file with the provided filename and returns an
 * object with the environment properties.
 * If no filename is providen then ./config.json will be loaded.
 */
envy.load = function (filename) {

    // filenames are relative to the execution path
    var configFile = require(process.cwd() + "/" + (filename || "config")),
        config = configFile[configFile.environment];

    // Overwrite default configuration if the NODE_ENV environment variable is
    // defined
    if (process.env.NODE_ENV && configFile[process.env.NODE_ENV]) {
        deepCopy(config, configFile[process.env.NODE_ENV]);
    }

    return config;

};

/**
 * DEPRECATED
 *
 * envy.config can be replaced with envy.load(). Therefore it will
 * be deleted.
 */
// Load the default configuration file if it exists
try {
    envy.config = envy.load();
} catch (e) {
    // Ignore failure when loading default configuration file
}
<|endoftext|>


<commit_before>$.jsonRPC.setup({
    endPoint: "/push/",
    namespace: "vo"
});

function vo(method, args, cb) {
    $.jsonRPC.request(method, {params: args, success: cb});
}

function vo_reload() {
    window.setInterval(function() {location.reload(true)}, 2500);
    vo("reload");
}

function vo_target(pid) {
    vo("target", [pid]);
    $("#targ_" + pid).effect("highlight", {color: "#424242"}, 1500);
}

$(function() {
    $("#tabs").tabs();

    $("#chat_msg").keypress(function(event) {
        var sel = null;
        if ((event.which == 103 && event.ctrlKey)) {
            event.preventDefault();
            sel = "GUILD";
        } else if ((event.which == 71 && event.ctrlKey)) {
            event.preventDefault();
            sel = "GROUP";
        } else if ((event.which == 99 && event.ctrlKey)) {
            event.preventDefault();
            sel = "CHANNEL";
        } else if ((event.which == 115 && event.ctrlKey)) {
            event.preventDefault();
            sel = "SECTOR";
        }

        if (sel != null) {
            $("#chat_dest").val(sel);
        }
    });

    $("#vo_reload").live("click", vo_reload);
    $("#chat_msg").inputHistory({size: 30});
    $("#chat_form").live("keydown", function(e) {
        var keyCode = e.keyCode || e.which;

        if (keyCode == 9) {
            e.preventDefault();
            var match = $("#chat_msg").val().match(/(\S+)$/);
            vo("tabcomplete", [match ? match[0] : ""], function(c) {
                if (c["result"] != null) {
                    var res = c["result"][0];

                    // Enclose names with spaces in ""
                    res = res.indexOf(" ") ? '"' + res + '"' : res;
                    $("#chat_msg").val($("#chat_msg").val().replace(/\w*$/, res));
                }
            });
        }
    });

    update();

    $("#chat_form").submit(function(e) {
        e.stopImmediatePropagation();
        e.preventDefault();
        if ($("#chat_msg").val() != "") {
            if ($("#chat_msg").val().charAt(0) == "/") {
                vo("processcmd", [$("#chat_msg").val().slice(1)]);
            } else {
                vo("chat", [$("#chat_msg").val(), $("#chat_dest").val()]);
            }
            $("#chat_msg").val("");
        }

        return false;
    });

    setInterval(function() {
        update();
    }, 2000);

});

var last_query = null;

function update() {
    $.getJSON("/pull/?last_query=" + last_query, function(queries) {
        last_query = queries[queries.length - 1]["timestamp"];
        $.each(queries, function(_, data) {
            $.each(data, function(key, value) {
                if (key == "sector") {
                    $("#sector").find("tr:gt(0)").remove();
                    $.each(data[key], function(_, p) {
                        $("#sector tr:last").after(
                          $.format(
                          "
{1} [{3}%]	{2}m
",
                          p));
                        $("#targ_" + p[0]).on("click", function() { vo_target(p[0]); } );
                    });
                } else if (key == "chat") {
                    $.each(data[key], function(_, m) {
                        var line = m["formatstring"].replace(/\<(\w+?)\>/g,
                            function(match, contents, offset, s) {
                                if (contents == "cname") {
                                    return "COL" + m["faction_color"] + m["name"] + "LOC";
                                } else {
                                    return m[contents];
                                }
                            });
                        line = line.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
                        line = "COL" + m["color"] + line + "LOC";
                        line = line.replace(/COL#(.{6})/g, "");
                        line = line.replace(/LOC/g, "");
                        $("#chat_box").append(line);
                        $("#chat_box").append("
");
                        $("#chat_box").scrollTop($("#chat_box")[0].scrollHeight);
                    });
                }
            });
        });
    });
}
<commit_msg>added map handler<commit_after>$.jsonRPC.setup({
    endPoint: "/push/",
    namespace: "vo"
});

function vo(method, args, cb) {
    $.jsonRPC.request(method, {params: args, success: cb});
}

function vo_reload() {
    window.setInterval(function() {location.reload(true)}, 2500);
    vo("reload");
}

function vo_target(pid) {
    vo("target", [pid]);
    $("#targ_" + pid).effect("highlight", {color: "#424242"}, 1500);
}

$(function() {
    $("#tabs").tabs();
    $("#tabs-3").tabs();

    $("#chat_msg").keypress(function(event) {
        var sel = null;
        if ((event.which == 103 && event.ctrlKey)) {
            event.preventDefault();
            sel = "GUILD";
        } else if ((event.which == 71 && event.ctrlKey)) {
            event.preventDefault();
            sel = "GROUP";
        } else if ((event.which == 99 && event.ctrlKey)) {
            event.preventDefault();
            sel = "CHANNEL";
        } else if ((event.which == 115 && event.ctrlKey)) {
            event.preventDefault();
            sel = "SECTOR";
        }

        if (sel != null) {
            $("#chat_dest").val(sel);
        }
    });
    /*
    $("#map_systems").on("click", "area", function(e) {
        alert($(this).attr("alt"));
    });
    */

    $("#vo_reload").live("click", vo_reload);
    $("#chat_msg").inputHistory({size: 30});
    $("#chat_form").live("keydown", function(e) {
        var keyCode = e.keyCode || e.which;

        if (keyCode == 9) {
            e.preventDefault();
            var match = $("#chat_msg").val().match(/(\S+)$/);
            vo("tabcomplete", [match ? match[0] : ""], function(c) {
                if (c["result"] != null) {
                    var res = c["result"][0];

                    // Enclose names with spaces in ""
                    res = res.indexOf(" ") ? '"' + res + '"' : res;
                    $("#chat_msg").val($("#chat_msg").val().replace(/\w*$/, res));
                }
            });
        }
    });

    update();

    $("#chat_form").submit(function(e) {
        e.stopImmediatePropagation();
        e.preventDefault();
        if ($("#chat_msg").val() != "") {
            if ($("#chat_msg").val().charAt(0) == "/") {
                vo("processcmd", [$("#chat_msg").val().slice(1)]);
            } else {
                vo("chat", [$("#chat_msg").val(), $("#chat_dest").val()]);
            }
            $("#chat_msg").val("");
        }

        return false;
    });

    setInterval(function() {
        update();
    }, 2000);

});

var last_query = null;

function update() {
    $.getJSON("/pull/?last_query=" + last_query, function(queries) {
        last_query = queries[queries.length - 1]["timestamp"];
        $.each(queries, function(_, data) {
            $.each(data, function(key, value) {
                if (key == "sector") {
                    $("#sector").find("tr:gt(0)").remove();
                    $.each(data[key], function(_, p) {
                        $("#sector tr:last").after(
                          $.format(
                          "
{1} [{3}%]	{2}m
",
                          p));
                        $("#targ_" + p[0]).on("click", function() { vo_target(p[0]); } );
                    });
                } else if (key == "chat") {
                    $.each(data[key], function(_, m) {
                        var line = m["formatstring"].replace(/\<(\w+?)\>/g,
                            function(match, contents, offset, s) {
                                if (contents == "cname") {
                                    return "COL" + m["faction_color"] + m["name"] + "LOC";
                                } else {
                                    return m[contents];
                                }
                            });
                        line = line.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
                        line = "COL" + m["color"] + line + "LOC";
                        line = line.replace(/COL#(.{6})/g, "");
                        line = line.replace(/LOC/g, "");
                        $("#chat_box").append(line);
                        $("#chat_box").append("
");
                        $("#chat_box").scrollTop($("#chat_box")[0].scrollHeight);
                    });
                }
            });
        });
    });
}
<|endoftext|>


<commit_before>////////////////////////////
// Site-wide JS utilities //
////////////////////////////
(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery', 'knockout', 'moment',
                'jquery-ui',
                'vendor/jquery-blockui/jquery.blockui',
                'vendor/knockout-sortable/knockout-sortable'], factory);
    } else {
        factory(jQuery, global.ko, global.moment);
    }
}(this, function($, ko, moment) {
    'use strict';

    // Namespace to put utility functions on
    $.osf = {};

    /**
     * Posts JSON data.
     *
     * Example:
     *     $.osf.postJSON('/foo', {'email': 'bar@baz.com'}, function(data) {...})
     *
     * @param  {String} url  The url to post to
     * @param  {Object} data JSON data to send to the endpoint
     * @param  {Function} done Success callback. Takes returned data as its first argument
     * @return {jQuery xhr}
     */
    $.osf.postJSON = function(url, data, done, error) {
        var ajaxOpts = {
            url: url, type: 'post',
            data: JSON.stringify(data),
            success: done,
            error: error,
            contentType: 'application/json', dataType: 'json'
        };
        return $.ajax(ajaxOpts);
    };

    /**
     * Puts JSON data.
     *
     * Example:
     *     $.osf.putJSON('/foo', {'email': 'bar@baz.com'}, function(data) {...})
     *
     * @param  {String} url  The url to put to
     * @param  {Object} data JSON data to send to the endpoint
     * @param  {Function} done Success callback. Takes returned data as its first argument
     * @return {jQuery xhr}
     */
    $.osf.putJSON = function(url, data, done, error) {
        var ajaxOpts = {
            url: url, type: 'put',
            data: JSON.stringify(data),
            success: done,
            error: error,
            contentType: 'application/json', dataType: 'json'
        };
        return $.ajax(ajaxOpts);
    };

    $.osf.block = function() {
        $.blockUI({
            css: {
                border: 'none',
                padding: '15px',
                backgroundColor: '#000',
                '-webkit-border-radius': '10px',
                '-moz-border-radius': '10px',
                opacity: .5,
                color: '#fff'
            },
            message: 'Please wait'
        });
    };

    $.osf.unblock = function() {
        $.unblockUI();
    };

    $.osf.joinPrompts = function(prompts, base) {
        var prompt = base || '';
        if (prompts) {
            prompt += '
';
            prompt += '
';
            for (var i=0; i<prompts.length; i++) {
                prompt += '
' + prompts[i] + '
';
            }
            prompt += '
';
        }
        return prompt;
    };

    $.osf.mapByProperty = function(list, attr) {
        return $.map(list, function(item) {
            return item[attr];
        });
    };

    /**
     * Return whether or not a value is an email address.
     * Adapted from Knockout-Validation.
     */
    $.osf.isEmail = function(value) {
        return  /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
    };

    /**
     * Get query string arguments as an object.
     * From getQueryParameters plugin by Nicholas Ortenzio.
     *
     */
    $.osf.urlParams = function(str) {
        return (str || document.location.search).replace(/(^\?)/,'').split('&')
            .map(function(n){return n = n.split('='),this[n[0]] = n[1],this}.bind({}))[0];
    };

    ///////////
    // Piwik //
    ///////////

    $.osf.trackPiwik = function(host, siteId, cvars, useCookies) {
        cvars = Array.isArray(cvars) ? cvars : [];
        useCookies = typeof(useCookies) !== 'undefined' ? useCookies : false;
        try {
            var piwikTracker = Piwik.getTracker(host + 'piwik.php', siteId);
            piwikTracker.enableLinkTracking(true);
            for(var i=0; i<cvars.length;i++)
            {
                piwikTracker.setCustomVariable.apply(null, cvars[i]);
            }
            if (!useCookies) {
                piwikTracker.disableCookies();
            }
            piwikTracker.trackPageView();

        } catch(err) { return false; }
        return true;
    };

    //////////////////
    // Data binders //
    //////////////////

    /**
     * Tooltip data binder. The value accessor should be an object containing
     * parameters for the tooltip.
     * Example:
     *
     */
    ko.bindingHandlers.tooltip = {
        init: function(elem, valueAccessor) {
            $(elem).tooltip(valueAccessor());
        }
    };

    // Patch sortable binding handler to preserve table row widths on drag.
    // See https://github.com/rniemeyer/knockout-sortable/pull/46
    // This can be removed if/when above PR is merged
    ko.bindingHandlers.sortable.options.helper = function(e, ui) {
        ui.children().each(function() {
            $(this).width($(this).width());
        });
        return ui;
    };

    /**
     * A thin wrapper around ko.applyBindings that ensures that a view model
     * is bound to the expected element. Also shows the element if it was
     * previously hidden.
     *
     * Takes a ViewModel and a selector (String).
     */
    $.osf.applyBindings = function(viewModel, selector) {
        var $elem = $(selector);
        if ($elem.length > 1) {
            throw "Can't bind ViewModel to multiple elements.";
        }
        // Ensure that the bound element is shown
        $elem.show();
        ko.applyBindings(viewModel, $elem[0]);
    };

    $.osf.handleJSONError = function (response) {
        bootbox.alert({
            title: response.responseJSON.message_short,
            message: response.responseJSON.message_long
        });
    };

    /**
     * A date object with two formats: local time or UTC time.
     * @param {String} date The original date as a string. Should be an standard
     *                      format such as RFC or ISO.
     */
    var LOCAL_DATEFORMAT = 'l h:mm A';
    var UTC_DATEFORMAT = 'l H:mm UTC';
    $.osf.FormattableDate = function(date) {
        this.date = date;
        this.local = moment(date).format(LOCAL_DATEFORMAT);
        this.utc = moment.utc(date).format(UTC_DATEFORMAT);
    };

    // Backwards compatibility
    window.FormattableDate = $.osf.FormattableDate;

    $.widget('custom.catcomplete', $.ui.autocomplete, {
        _renderMenu: function( ul, items ) {
            var that = this;
            var currentCategory = '';
            $.each( items, function( index, item ) {
                if (item.category !== currentCategory ) {
                    ul.append('
' + item.category + '
' );
                    currentCategory = item.category;
                }
            that._renderItemData( ul, item );
            });
        }
    });

    // TODO: move me to appropriate page-specific module
    $(document).ready(function(){

    //    TODO: Make this work with file GUIDs [jmc]
    //    // Highlight active tabs and nav labels
    //    if (typeof(nodeId) !== 'undefined' && nodeId) {
    //        // Works for project pages; code used below won't highlight wiki tab
    //        // on wiki pages because URLs (e.g. wiki/home) aren't contained in
    //        // tab URLs (e.g. wiki)
    //        var page = location.pathname.split(nodeId)[1]
    //            .split('/')[1];
    //        $('#projectSubnav a').filter(function() {
    //            return page == $(this).attr('href')
    //                .split(nodeId)[1]
    //                .replace(/\//g, '');
    //        }).parent().addClass('active');
    //    } else {
    //         // Works for user dashboard page
    //         $('.nav a[href="' + location.pathname + '"]').parent().addClass('active');
    //         $('.tabs a[href="' + location.pathname + '"]').parent().addClass('active');
    //    }

        // Build tooltips on user activity widgets
        $('.ua-meter').tooltip();
        $('[rel=tooltip]').tooltip({
            placement:'bottom'
        });
    });

}));
<commit_msg>Formattable date stores date property as a Date object<commit_after>////////////////////////////
// Site-wide JS utilities //
////////////////////////////
(function (global, factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery', 'knockout', 'moment',
                'jquery-ui',
                'vendor/jquery-blockui/jquery.blockui',
                'vendor/knockout-sortable/knockout-sortable'], factory);
    } else {
        factory(jQuery, global.ko, global.moment);
    }
}(this, function($, ko, moment) {
    'use strict';

    // Namespace to put utility functions on
    $.osf = {};

    /**
     * Posts JSON data.
     *
     * Example:
     *     $.osf.postJSON('/foo', {'email': 'bar@baz.com'}, function(data) {...})
     *
     * @param  {String} url  The url to post to
     * @param  {Object} data JSON data to send to the endpoint
     * @param  {Function} done Success callback. Takes returned data as its first argument
     * @return {jQuery xhr}
     */
    $.osf.postJSON = function(url, data, done, error) {
        var ajaxOpts = {
            url: url, type: 'post',
            data: JSON.stringify(data),
            success: done,
            error: error,
            contentType: 'application/json', dataType: 'json'
        };
        return $.ajax(ajaxOpts);
    };

    /**
     * Puts JSON data.
     *
     * Example:
     *     $.osf.putJSON('/foo', {'email': 'bar@baz.com'}, function(data) {...})
     *
     * @param  {String} url  The url to put to
     * @param  {Object} data JSON data to send to the endpoint
     * @param  {Function} done Success callback. Takes returned data as its first argument
     * @return {jQuery xhr}
     */
    $.osf.putJSON = function(url, data, done, error) {
        var ajaxOpts = {
            url: url, type: 'put',
            data: JSON.stringify(data),
            success: done,
            error: error,
            contentType: 'application/json', dataType: 'json'
        };
        return $.ajax(ajaxOpts);
    };

    $.osf.block = function() {
        $.blockUI({
            css: {
                border: 'none',
                padding: '15px',
                backgroundColor: '#000',
                '-webkit-border-radius': '10px',
                '-moz-border-radius': '10px',
                opacity: .5,
                color: '#fff'
            },
            message: 'Please wait'
        });
    };

    $.osf.unblock = function() {
        $.unblockUI();
    };

    $.osf.joinPrompts = function(prompts, base) {
        var prompt = base || '';
        if (prompts) {
            prompt += '
';
            prompt += '
';
            for (var i=0; i<prompts.length; i++) {
                prompt += '
' + prompts[i] + '
';
            }
            prompt += '
';
        }
        return prompt;
    };

    $.osf.mapByProperty = function(list, attr) {
        return $.map(list, function(item) {
            return item[attr];
        });
    };

    /**
     * Return whether or not a value is an email address.
     * Adapted from Knockout-Validation.
     */
    $.osf.isEmail = function(value) {
        return  /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
    };

    /**
     * Get query string arguments as an object.
     * From getQueryParameters plugin by Nicholas Ortenzio.
     *
     */
    $.osf.urlParams = function(str) {
        return (str || document.location.search).replace(/(^\?)/,'').split('&')
            .map(function(n){return n = n.split('='),this[n[0]] = n[1],this}.bind({}))[0];
    };

    ///////////
    // Piwik //
    ///////////

    $.osf.trackPiwik = function(host, siteId, cvars, useCookies) {
        cvars = Array.isArray(cvars) ? cvars : [];
        useCookies = typeof(useCookies) !== 'undefined' ? useCookies : false;
        try {
            var piwikTracker = Piwik.getTracker(host + 'piwik.php', siteId);
            piwikTracker.enableLinkTracking(true);
            for(var i=0; i<cvars.length;i++)
            {
                piwikTracker.setCustomVariable.apply(null, cvars[i]);
            }
            if (!useCookies) {
                piwikTracker.disableCookies();
            }
            piwikTracker.trackPageView();

        } catch(err) { return false; }
        return true;
    };

    //////////////////
    // Data binders //
    //////////////////

    /**
     * Tooltip data binder. The value accessor should be an object containing
     * parameters for the tooltip.
     * Example:
     *
     */
    ko.bindingHandlers.tooltip = {
        init: function(elem, valueAccessor) {
            $(elem).tooltip(valueAccessor());
        }
    };

    // Patch sortable binding handler to preserve table row widths on drag.
    // See https://github.com/rniemeyer/knockout-sortable/pull/46
    // This can be removed if/when above PR is merged
    ko.bindingHandlers.sortable.options.helper = function(e, ui) {
        ui.children().each(function() {
            $(this).width($(this).width());
        });
        return ui;
    };

    /**
     * A thin wrapper around ko.applyBindings that ensures that a view model
     * is bound to the expected element. Also shows the element if it was
     * previously hidden.
     *
     * Takes a ViewModel and a selector (String).
     */
    $.osf.applyBindings = function(viewModel, selector) {
        var $elem = $(selector);
        if ($elem.length > 1) {
            throw "Can't bind ViewModel to multiple elements.";
        }
        // Ensure that the bound element is shown
        $elem.show();
        ko.applyBindings(viewModel, $elem[0]);
    };

    $.osf.handleJSONError = function (response) {
        bootbox.alert({
            title: response.responseJSON.message_short,
            message: response.responseJSON.message_long
        });
    };

    /**
     * A date object with two formats: local time or UTC time.
     * @param {String} date The original date as a string. Should be an standard
     *                      format such as RFC or ISO.
     */
    var LOCAL_DATEFORMAT = 'l h:mm A';
    var UTC_DATEFORMAT = 'l H:mm UTC';
    $.osf.FormattableDate = function(date) {
        if (typeof date === 'string') {
            // The date as a Date object
            this.date = new Date(date);
        } else {
            this.date = date;
        }
        this.local = moment(date).format(LOCAL_DATEFORMAT);
        this.utc = moment.utc(date).format(UTC_DATEFORMAT);
    };

    // Backwards compatibility
    window.FormattableDate = $.osf.FormattableDate;

    $.widget('custom.catcomplete', $.ui.autocomplete, {
        _renderMenu: function( ul, items ) {
            var that = this;
            var currentCategory = '';
            $.each( items, function( index, item ) {
                if (item.category !== currentCategory ) {
                    ul.append('
' + item.category + '
' );
                    currentCategory = item.category;
                }
            that._renderItemData( ul, item );
            });
        }
    });

    // TODO: move me to appropriate page-specific module
    $(document).ready(function(){

    //    TODO: Make this work with file GUIDs [jmc]
    //    // Highlight active tabs and nav labels
    //    if (typeof(nodeId) !== 'undefined' && nodeId) {
    //        // Works for project pages; code used below won't highlight wiki tab
    //        // on wiki pages because URLs (e.g. wiki/home) aren't contained in
    //        // tab URLs (e.g. wiki)
    //        var page = location.pathname.split(nodeId)[1]
    //            .split('/')[1];
    //        $('#projectSubnav a').filter(function() {
    //            return page == $(this).attr('href')
    //                .split(nodeId)[1]
    //                .replace(/\//g, '');
    //        }).parent().addClass('active');
    //    } else {
    //         // Works for user dashboard page
    //         $('.nav a[href="' + location.pathname + '"]').parent().addClass('active');
    //         $('.tabs a[href="' + location.pathname + '"]').parent().addClass('active');
    //    }

        // Build tooltips on user activity widgets
        $('.ua-meter').tooltip();
        $('[rel=tooltip]').tooltip({
            placement:'bottom'
        });
    });

}));
<|endoftext|>


<commit_before>var lock = false;

function clear_board(table, game) {
    var board = setInterval(function() {
        for (var idx = 1; idx <= 6; ++idx) {
            var seat = get_seat(table.seats, idx);
            if (seat.player.bankroll != undefined) {
                if (seat.player.bankroll <= 0) {
                    console.log(seat.player.nickname + ' is Game Over!');
                    io.to(get_private_id(table.private_ids, seat.player.seat_nb)).emit('game over');
                }
            }
        }
        io.to(table.id).emit("remove board");
		io.to(table.id).emit("fold off");
        clearInterval(board);
        if (!lock)
            end_timer(table, game);
    }, 10000);
}

function end_timer(table, game) {
	lock = true;
    io.to(table.id).emit("chrono", 10, "The game is restarting ...");
    var timer = setInterval(function() {
        io.to(table.id).emit("chrono off");
        clearInterval(timer);
        remove_last_actions(table);
        if (table.playing_seats.length > 1 || table.players_nb > 1)
            reinit(table, game);
        else
            end_timer(table, game);
    }, 10000);
}

function end_game(table, game, winners, player) {
    var idx;

    table.game.pot_amount = 0;
    io.to(table.id).emit("pot modification", table.game.pot_amount);
    for (idx = 1; idx <= 6; ++idx) {
        io.to(table.id).emit("highlights", idx, "off");
        io.to(table.id).emit("bet", idx, "");
    }
    if (winners != 42) {
        idx = 0;
        while (idx < winners.length)
            io.to(table.id).emit("bet", winners[idx++].seat_nb, +game.pot_amount / winners.length);
    }
    if (winners.length === 1) {
        io.to(table.id).emit("winner", winners[0].seat_nb, winners[0].rank_name);
    } else if (winners != 42) {
        io.to(table.id).emit("winner", 42, 'null');
    }
    if (winners == 42) {
        for (var i = 1; i < 7; i++) {
            io.to(get_private_id(table.private_ids, i)).emit("cancel buttons", "hidden");
        }
        io.to(table.id).emit("winner", player.seat_nb, 'disconnected');
        for (idx = 1; idx <= 6; ++idx) {
            if ((player = get_seat(table.seats, idx).player) != -1) {
                io.to(table.id).emit("show down", player.card1, player.card2, idx);
            }
        }
        clear_board(table, game);
    } else
        clear_board(table, game);
}

function reinit(table, game) {
	lock = false;
    io.to(table.id).emit("win off", 42);
    for (var idx = 1; idx <= 6; ++idx) {
        var seat = get_seat(table.seats, idx);
        seat.player.card_1 = "undefined";
        seat.player.card_2 = "undefined";
        seat.player.rank_name = "undefined";
        seat.player.rank_value = 0;
        io.to(get_private_id(table.private_ids, idx)).emit("turn wait");
    }
    io.to(table.id).emit("remove emplacements");
    game.highlights_pos = "none"; // We don't need it anymore for now.
    game.board = new Array();
    ++game.d_pos;
    ++game.sb_pos;
    ++game.bb_pos;
    game.deck = new Array('2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', 'tc', 'jc', 'qc', 'kc', '1c',
        '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', 'ts', 'js', 'qs', 'ks', '1s',
        '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', 'td', 'jd', 'qd', 'kd', '1d',
        '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', 'th', 'jh', 'qh', 'kh', '1h');
    console.log("***END***");
    for (var i = 1; i < 7; i++) {
        io.to(get_private_id(table.private_ids, i)).emit("show buttons", "visible");
    }
    /* ADD NEW PLAYERS TO PLAYING SEATS ARRAY */
    for (idx = 1; idx <= 6; ++idx)
        if (get_seat(table.seats, idx).state === "busy")
            table.playing_seats.push(idx);
    for (var i = 0; i < table.playing_seats.length; i++)
        get_seat(table.seats, table.playing_seats[i]).state = "playing";
    if (table.playing_seats.length > 1) {
        console.log("Starting a new game...");
        new_cashgame(1, table);
    }
}
<commit_msg>save<commit_after>var lock = false;

function clear_board(table, game) {
	io.to(table.id).emit("fold off");
    var board = setInterval(function() {
        for (var idx = 1; idx <= 6; ++idx) {
            var seat = get_seat(table.seats, idx);
            if (seat.player.bankroll != undefined) {
                if (seat.player.bankroll <= 0) {
                    console.log(seat.player.nickname + ' is Game Over!');
                    io.to(get_private_id(table.private_ids, seat.player.seat_nb)).emit('game over');
                }
            }
        }
        io.to(table.id).emit("remove board");
        clearInterval(board);
        if (!lock)
            end_timer(table, game);
    }, 10000);
}

function end_timer(table, game) {
	lock = true;
    io.to(table.id).emit("chrono", 10, "The game is restarting ...");
    var timer = setInterval(function() {
        io.to(table.id).emit("chrono off");
        clearInterval(timer);
        remove_last_actions(table);
        if (table.playing_seats.length > 1 || table.players_nb > 1)
            reinit(table, game);
        else
            end_timer(table, game);
    }, 10000);
}

function end_game(table, game, winners, player) {
    var idx;

    table.game.pot_amount = 0;
    io.to(table.id).emit("pot modification", table.game.pot_amount);
    for (idx = 1; idx <= 6; ++idx) {
        io.to(table.id).emit("highlights", idx, "off");
        io.to(table.id).emit("bet", idx, "");
    }
    if (winners != 42) {
        idx = 0;
        while (idx < winners.length)
            io.to(table.id).emit("bet", winners[idx++].seat_nb, +game.pot_amount / winners.length);
    }
    if (winners.length === 1) {
        io.to(table.id).emit("winner", winners[0].seat_nb, winners[0].rank_name);
    } else if (winners != 42) {
        io.to(table.id).emit("winner", 42, 'null');
    }
    if (winners == 42) {
        for (var i = 1; i < 7; i++) {
            io.to(get_private_id(table.private_ids, i)).emit("cancel buttons", "hidden");
        }
        io.to(table.id).emit("winner", player.seat_nb, 'disconnected');
        for (idx = 1; idx <= 6; ++idx) {
            if ((player = get_seat(table.seats, idx).player) != -1) {
                io.to(table.id).emit("show down", player.card1, player.card2, idx);
            }
        }
        clear_board(table, game);
    } else
        clear_board(table, game);
}

function reinit(table, game) {
	lock = false;
    io.to(table.id).emit("win off", 42);
    for (var idx = 1; idx <= 6; ++idx) {
        var seat = get_seat(table.seats, idx);
        seat.player.card_1 = "undefined";
        seat.player.card_2 = "undefined";
        seat.player.rank_name = "undefined";
        seat.player.rank_value = 0;
        io.to(get_private_id(table.private_ids, idx)).emit("turn wait");
    }
    io.to(table.id).emit("remove emplacements");
    game.highlights_pos = "none"; // We don't need it anymore for now.
    game.board = new Array();
    ++game.d_pos;
    ++game.sb_pos;
    ++game.bb_pos;
    game.deck = new Array('2c', '3c', '4c', '5c', '6c', '7c', '8c', '9c', 'tc', 'jc', 'qc', 'kc', '1c',
        '2s', '3s', '4s', '5s', '6s', '7s', '8s', '9s', 'ts', 'js', 'qs', 'ks', '1s',
        '2d', '3d', '4d', '5d', '6d', '7d', '8d', '9d', 'td', 'jd', 'qd', 'kd', '1d',
        '2h', '3h', '4h', '5h', '6h', '7h', '8h', '9h', 'th', 'jh', 'qh', 'kh', '1h');
    console.log("***END***");
    for (var i = 1; i < 7; i++) {
        io.to(get_private_id(table.private_ids, i)).emit("show buttons", "visible");
    }
    /* ADD NEW PLAYERS TO PLAYING SEATS ARRAY */
    for (idx = 1; idx <= 6; ++idx)
        if (get_seat(table.seats, idx).state === "busy")
            table.playing_seats.push(idx);
    for (var i = 0; i < table.playing_seats.length; i++)
        get_seat(table.seats, table.playing_seats[i]).state = "playing";
    if (table.playing_seats.length > 1) {
        console.log("Starting a new game...");
        new_cashgame(1, table);
    }
}
<|endoftext|>


<commit_before>var util = require('../util/util');
var hosts = require('./hosts');
var http = require('http');
var https = require('https');
var url = require('url');
var EventEmitter = require('events').EventEmitter;
var Transform = require('stream').Transform;
var transformHttps = require('../https/transform.js');
var config = require('../package.json');

function transform(chunk, encoding, callback) {
	var data = {
			encoding: encoding,
			data: chunk
	};
	var self = this;

	self.emit('data', data);

	function execCallback() {
		self._setResponseTimeout && self._setResponseTimeout();
		callback(data.error, data.data);
	}

	self._clearResponseTimeout && self._clearResponseTimeout();

	if (data.delay > 0) {
		setTimeout(execCallback, data.delay);
	} else {
		execCallback();
	}
}

function getTransform(eventEmitter) {
	var ts = new Transform();
	ts._transform = transform.bind(eventEmitter);
	return ts;
}

function getPort(options) {
	if (options.port) {
		return options.port;
	}

	if (options.protocol == 'https:') {
		return 443;
	} else if (options.protocol == 'http:') {
		return 80;
	}
}

function getUIPort(options) {

	return options.protocol == 'https:' ? config.uisslport : config.uiport;
}

var RESET_COOKIE_RE = /secure;?|domain=([^;]+);?/ig;

function setWhistleHeaders(res, req, isHttp, isHttps) {
	var headers = res.headers;
	var options = req.options;
	var host = options.host.split(':')[0];
	options.host = host + (options.port ? ':' + options.port : '');

	headers['x-remote-ip'] = options.hosts[1] || '127.0.0.1';

	var matcher = options.rule && options.rule.matcher;
	if (matcher) {
		headers['x-' + config.name + '-rule'] = matcher;
	}

	if (matcher || isHttps) {
		headers['x-remote-url'] = isHttp ? url.format(options) : options.url;
	}

	if (!isHttps) {
		return;
	}

	var cookies = headers['set-cookie'];

	if (!Array.isArray(cookies)) {
		return;
	}

	var host = options.host.split('.');
	var len = host.length;
	if (host.length > 2) {
		host = host.slice(len - 2);
	}
	host = '.' + host.join('.');

	headers['set-cookie'] = cookies.map(function(cookie) {
		return cookie.replace(RESET_COOKIE_RE, '') + '; DOMAIN=' + host + ';';
	});
}

module.exports = function(req, res, next) {
	var self = this;
	var fullUrl = req.fullUrl = util.getFullUrl(req);
	var timeoutId, clientReq;

	function setResponseTimeout() {
		clearResponseTimeout();
		timeoutId = setTimeout(abort, config.timeout);
	}

	function clearResponseTimeout() {
		clearTimeout(timeoutId);
		timeoutId = null;
	}

	function abort() {
		clearResponseTimeout();
		if (clientReq) {
			clientReq.abort();
		}
		res.destroy();
	}

	setResponseTimeout();

	function handleResolve(err, options) {
		req.options = options;
		var request = new EventEmitter();
		var response = new EventEmitter();

		req.proxy = {
				url: fullUrl,
				util: util,
				hosts: hosts,
				request: request,
				response: response
		};

		var isUIRequest;
		var port = getPort(options);
		if (util.isLocalAddress(options.hosts[1])) {
			if (port == config.port) {
				res.redirect(302, options.protocol + '//' + options.hostname + ':'
						+ getUIPort(options) + options.path);
				return;
			}

			isUIRequest = port == config.uiport || port == config.uisslport;
		}

		if (!isUIRequest) {
			self.emit('proxy', req.proxy);
		}

		request.emit('request', req);
		bindErrorEvents(req);
		bindErrorEvents(res);

		req.on('end', function() {
			request.emit('end');
		});

		res.on('end', function() {
			clearResponseTimeout();
			response.emit('end');
		});

		req.request = function (options) {
			var _req = (options.protocol == 'https:' ? https : http).request(options, res.response);

			setResponseTimeout();
			clientReq = _req;
			bindErrorEvents(_req);
			request._setResponseTimeout = setResponseTimeout;
			request._clearResponseTimeout = clearResponseTimeout;
			req.pipe(getTransform(request)).pipe(_req);
		};

		var isResponded;
		res.response = function(_res) {
			if (isResponded) {
				return;
			}
			setResponseTimeout();
			bindErrorEvents(_res);
			isResponded = true;
			if (_res.headers && _res.headers.location) {
				//nodejs的url只支持ascii，对非ascii的字符要encodeURIComponent，否则传到浏览器是乱码
				_res.headers.location = util.toWhistleSsl(req, util.encodeNonAsciiChar(_res.headers.location));
			}

			setWhistleHeaders(_res, req, util.isWebProtocol(req.options.protocol), req.isHttps);
			response.emit('response', _res);
			res.writeHead(_res.statusCode || 0, _res.headers);
			response._setResponseTimeout = setResponseTimeout;
			response._clearResponseTimeout = clearResponseTimeout;

			var headers = _res.headers;
			_res = _res.pipe(getTransform(response));
			if (req.isHttps) {
				transformHttps(headers, _res).pipe(res);
			} else {
				_res.pipe(res);
			}
		};

		function bindErrorEvents(req) {
			req.on('error', function(err) {
				abort();
				if (isResponded) {
					if (EventEmitter.listenerCount(response, 'error') > 0) {
						response.emit('error', err);
					}
				} else if (EventEmitter.listenerCount(request, 'error') > 0) {
					request.emit('error', err);
				}
			});
		}

		if (err) {
			req.emit('error', err);
			return;
		}

		next();
	}

	if (req.headers.host == config.localUIHost) {
		var options = url.parse(fullUrl);
		options.hosts = ['127.0.0.1', '127.0.0.1'];
		options.port = getUIPort(options);
		options.url = fullUrl;
		handleResolve(null, options);
	} else {
		hosts.resolve(fullUrl, handleResolve);
	}
};<commit_msg>local.whistlejs.com<commit_after>var util = require('../util/util');
var hosts = require('./hosts');
var http = require('http');
var https = require('https');
var url = require('url');
var EventEmitter = require('events').EventEmitter;
var Transform = require('stream').Transform;
var transformHttps = require('../https/transform.js');
var config = require('../package.json');

function transform(chunk, encoding, callback) {
	var data = {
			encoding: encoding,
			data: chunk
	};
	var self = this;

	self.emit('data', data);

	function execCallback() {
		self._setResponseTimeout && self._setResponseTimeout();
		callback(data.error, data.data);
	}

	self._clearResponseTimeout && self._clearResponseTimeout();

	if (data.delay > 0) {
		setTimeout(execCallback, data.delay);
	} else {
		execCallback();
	}
}

function getTransform(eventEmitter) {
	var ts = new Transform();
	ts._transform = transform.bind(eventEmitter);
	return ts;
}

function getPort(options) {
	if (options.port) {
		return options.port;
	}

	if (options.protocol == 'https:') {
		return 443;
	}

	if (options.protocol == 'http:') {
		return 80;
	}
}

function getUIPort(options) {

	return options.protocol == 'https:' ? config.uisslport : config.uiport;
}

var RESET_COOKIE_RE = /secure;?|domain=([^;]+);?/ig;

function setWhistleHeaders(res, req, isHttp, isHttps) {
	var headers = res.headers;
	var options = req.options;
	var host = options.host.split(':')[0];
	options.host = host + (options.port ? ':' + options.port : '');

	headers['x-remote-ip'] = options.hosts[1] || '127.0.0.1';

	var matcher = options.rule && options.rule.matcher;
	if (matcher) {
		headers['x-' + config.name + '-rule'] = matcher;
	}

	if (matcher || isHttps) {
		headers['x-remote-url'] = isHttp ? url.format(options) : options.url;
	}

	if (!isHttps) {
		return;
	}

	var cookies = headers['set-cookie'];

	if (!Array.isArray(cookies)) {
		return;
	}

	var host = options.host.split('.');
	var len = host.length;
	if (host.length > 2) {
		host = host.slice(len - 2);
	}
	host = '.' + host.join('.');

	headers['set-cookie'] = cookies.map(function(cookie) {
		return cookie.replace(RESET_COOKIE_RE, '') + '; DOMAIN=' + host + ';';
	});
}

module.exports = function(req, res, next) {
	var self = this;
	var fullUrl = req.fullUrl = util.getFullUrl(req);
	var timeoutId, clientReq;

	function setResponseTimeout() {
		clearResponseTimeout();
		timeoutId = setTimeout(abort, config.timeout);
	}

	function clearResponseTimeout() {
		clearTimeout(timeoutId);
		timeoutId = null;
	}

	function abort() {
		clearResponseTimeout();
		if (clientReq) {
			clientReq.abort();
		}
		res.destroy();
	}

	setResponseTimeout();

	function handleResolve(err, options) {
		req.options = options;
		var request = new EventEmitter();
		var response = new EventEmitter();

		req.proxy = {
				url: fullUrl,
				util: util,
				hosts: hosts,
				request: request,
				response: response
		};

		var isUIRequest;
		var port = getPort(options);
		if (util.isLocalAddress(options.hosts[1])) {
			if (port == config.port) {
				res.redirect(302, options.protocol + '//' + options.hostname + ':'
						+ getUIPort(options) + options.path);
				return;
			}

			isUIRequest = port == config.uiport || port == config.uisslport;
		}

		if (!isUIRequest) {
			self.emit('proxy', req.proxy);
		}

		request.emit('request', req);
		bindErrorEvents(req);
		bindErrorEvents(res);

		req.on('end', function() {
			request.emit('end');
		});

		res.on('end', function() {
			clearResponseTimeout();
			response.emit('end');
		});

		req.request = function (options) {
			var _req = (options.protocol == 'https:' ? https : http).request(options, res.response);

			setResponseTimeout();
			clientReq = _req;
			bindErrorEvents(_req);
			request._setResponseTimeout = setResponseTimeout;
			request._clearResponseTimeout = clearResponseTimeout;
			req.pipe(getTransform(request)).pipe(_req);
		};

		var isResponded;
		res.response = function(_res) {
			if (isResponded) {
				return;
			}
			setResponseTimeout();
			bindErrorEvents(_res);
			isResponded = true;
			if (_res.headers && _res.headers.location) {
				//nodejs的url只支持ascii，对非ascii的字符要encodeURIComponent，否则传到浏览器是乱码
				_res.headers.location = util.toWhistleSsl(req, util.encodeNonAsciiChar(_res.headers.location));
			}

			setWhistleHeaders(_res, req, util.isWebProtocol(req.options.protocol), req.isHttps);
			response.emit('response', _res);
			res.writeHead(_res.statusCode || 0, _res.headers);
			response._setResponseTimeout = setResponseTimeout;
			response._clearResponseTimeout = clearResponseTimeout;

			var headers = _res.headers;
			_res = _res.pipe(getTransform(response));
			if (req.isHttps) {
				transformHttps(headers, _res).pipe(res);
			} else {
				_res.pipe(res);
			}
		};

		function bindErrorEvents(req) {
			req.on('error', function(err) {
				abort();
				if (isResponded) {
					if (EventEmitter.listenerCount(response, 'error') > 0) {
						response.emit('error', err);
					}
				} else if (EventEmitter.listenerCount(request, 'error') > 0) {
					request.emit('error', err);
				}
			});
		}

		if (err) {
			req.emit('error', err);
			return;
		}

		next();
	}

	if (req.headers.host == config.localUIHost) {
		var options = url.parse(fullUrl);
		options.hosts = ['127.0.0.1', '127.0.0.1'];
		options.port = getUIPort(options);
		options.url = fullUrl;
		handleResolve(null, options);
	} else {
		hosts.resolve(fullUrl, handleResolve);
	}
};<|endoftext|>


<commit_before>/**
 * A ROI instance constructor (Protected constructor. Don't use this constructor)
 * directly. Use Fetch method of Melown.Roi class or constructor of specific
 * Roi type.
 * @constructor
 */
Melown.Roi = function(config_, core_) {
    this.config_ = config_;
    this.core_ = core_;

    this.renderer_ = this.core_.renderer_;
    this.map_ = this.core_.map_;

    // state properties
    this.state_ = Melown.Roi.State.Created;
    this.develAtFinishRequested_ = false;
    this.leaveAtFinishRequested_ = false;
    this.enterPosition_ = null;             // filled by devel function
    this.refPosition_ = null;               // filled from config JSON
    this.currendPosition_ = null;           // changing by orientation accesor etc.

    // inti roi point
    this._init();
}

Melown.Roi.Fetch = function(config_, core_, clb_) {
    var done = function(json_) {
        if (typeof json_ === 'object' && json_ !== null && json_ !== undefined) {
            if (typeof json_.type === 'string'
                && typeof Melown.Roi.Type[json_.type] === 'function') {
                clb_(null, new Melown.Roi.Type[json_.type](json_, core_));
            } else {
                var err = new Error('Downloaded configuration JSON does not contain registered ROI type');
                console.error(err);
                clb(err);
                return;
            }
        }
        var err = new Error('Downloaded configuration is not JSON object');
        console.error(err);
        clb(err);
        return;
    }

    if (typeof config_ === 'string') {
        // async load of config at URL and call processConfig again (with object)
        // TODO - Vadstena.loadJSON should be replaced by Melown.*
        Vadstena.loadJSON(config_, done, function(error_) {
            var err = new Error('Unable to download configuration JSON');
            console.error(err);
            clb(err);
            return;
        });
    } else if (typeof config_ !== 'object'
        || config_ === null
        || config_ === undefined) {
        var err = new Error('Unknown configuration format passed to Pano browser')
        console.error(err);
        clb(err);
        return;
    }

    done(config_);
}

/**
 * To be fullfilled by specific roi types [type : class]
 */
Melown.Roi.Type = {}

/**
 * Roi object states.
 * @enum {number}
 */
Melown.Roi.State = {
    Created : 0,
    Ready : 1,
    FadingIn : 2,
    Presenting : 3,
    FadingOut : 4,
    Error : -1
}

// Public methods

Melown.Roi.delve = function(enterPosition_) {
    if (this.state_ === Melown.Roi.State.Created
        || this.state_ === Melown.Roi.State.FadingOut) {
        this.develAtFinishRequested_ = true;
    } else if (this.state_ === Melown.Roi.State.FadingIn) {
        this.leaveAtFinishRequested_ = false;
    } else if (this.state_ !== Melown.Roi.State.Ready) {
        return;
    }

    // TODO flight into roi position and blend with custom render
}

Melown.Roi.leave = function() {
    if (this.state_ === Melown.Roi.State.Created
        || this.state_ === Melown.Roi.State.FadingOut) {
        this.develAtFinishRequested_ = false;
    } else if (this.state_ === Melown.Roi.State.FadingIn) {
        this.leaveAtFinishRequested_ = true;
    } else if (this.state_ !== Melown.Roi.State.Ready) {
        return;
    }

    // TODO flight into roi position and blend with custom render
}

// Accessor methods

Melown.Roi.prototype.state = function() {
    return this.state_;
}

Melown.Roi.prototype.config = function() {
    return this.config_;
}

Melown.Roi.currentPosition = function(type_ = 'obj') {
    if (type_ === 'obj') {
        return this.currendPosition_;
    }
    return this.map_.convert(this.currendPosition_, type);
}

Melown.Roi.orientation = function(yaw, pitch) {
    if (yaw === undefined) {
        // TODO get current yaw and pitch
        return [0, 0];
    } else if (pitch === undefined) {
        if (yaw instanceof Array && yaw.length >= 2) {
            pitch = yaw[1];
            yaw = yaw[0];
        } else {
            pitch = this.orientation[1];
        }
    }
    // TODO set current position from given yaw and pitch
}

// Protected methods

Melown.Roi.prototype._init = function() {
    // Used mostly for subclassing
    this._loadConfig();
}

Melown.Roi.prototype._finalizeInit = function() {

}

Melown.Roi._deinit = function() {
    // Used mostly for subclassing
}

// Private methods

Melown.Roi.prototype._loadConfig = function() {
    if (typeof config_ === 'string') {
        // async load of config at URL and call processConfig again (with object)
        // TODO - Vadstena.loadJSON should be replaced by Melown.*
        Vadstena.loadJSON(config_, function(json_) {
            this.config_ = json_;
            this._processConfig();
        }, function(error_) {
            this.state_ = Melown.Roi.State.Error;
            console.error('Unable to download configuration JSON');
        });
    } else if (typeof config_ !== 'object'
        || config_ === null
        || config_ === undefined) {
        this.state_ = Melown.Roi.State.Error;
        console.error('Unknown configuration format passed to Pano browser');
    }

    // it's object - just process it
    this._processConfig();
}

Melown.Roi.prototype._processConfig = function() {
    if (this.config_.)
}

Melown.Roi.prototype._processConfig = function(config_) {
    if (typeof config_ === 'string') {
        // async load of config at URL and call processConfig again (with object)
        // TODO - Vadstena.loadJSON should be replaced by Melown.*
        Vadstena.loadJSON(config_, function(json_) {
            this._processConfig(json_);
        }, function(error_) {
            this.state_ = Melown.Roi.State.Error;
        });
    } else if (typeof config_ !== 'object'
        || config_ === null
        || config_ === undefined) {
        this.state_ = Melown.Roi.State.Error;
        console.error('Unknown configuration format passed to Pano browser');
    }

    this.config_ = config_;
}<commit_msg>Roi base class finalized.<commit_after>/**
 * A ROI instance constructor (Protected constructor. Don't use this constructor)
 * directly. Use Fetch method of Melown.Roi class or constructor of specific
 * Roi type.
 * @constructor
 */
Melown.Roi = function(config_, core_) {
    this.config_ = config_;
    this.core_ = core_;

    this.renderer_ = this.core_.renderer_;
    this.map_ = this.core_.map_;

    // state properties
    this.state_ = Melown.Roi.State.Created;
    this.develAtFinishRequested_ = false;
    this.leaveAtFinishRequested_ = false;
    this.enterPosition_ = null;             // filled by devel function
    this.refPosition_ = null;               // filled from config JSON
    this.currendPosition_ = null;           // changing by orientation accesor etc.

    // inti roi point
    this._init();
}

Melown.Roi.Fetch = function(config_, core_, clb_) {
    var done = function(json_) {
        if (typeof json_ === 'object' && json_ !== null) {
            if (typeof json_['type'] === 'string'
                && typeof Melown.Roi.Type[json_.type] === 'function') {
                clb_(null, new Melown.Roi.Type[json_['type']](json_, core_));
            } else {
                var err = new Error('Downloaded configuration JSON does not contain registered ROI type');
                console.error(err);
                clb(err);
                return;
            }
        }
        var err = new Error('Downloaded configuration is not JSON object');
        console.error(err);
        clb(err);
        return;
    }

    if (typeof config_ === 'string') {
        // async load of config at URL and call processConfig again (with object)
        // TODO - Vadstena.loadJSON should be replaced by Melown.*
        Vadstena.loadJSON(config_, done, function(error_) {
            var err = new Error('Unable to download configuration JSON');
            console.error(err);
            clb(err);
            return;
        });
    } else if (typeof config_ !== 'object'
        || config_ === null) {
        var err = new Error('Unknown configuration format passed to Pano browser')
        console.error(err);
        clb(err);
        return;
    }

    done(config_);
}

/**
 * To be fullfilled by specific roi types [type : class]
 */
Melown.Roi.Type = {}

/**
 * Roi object states.
 * @enum {number}
 */
Melown.Roi.State = {
    Created : 0,
    Ready : 1,
    FadingIn : 2,
    Presenting : 3,
    FadingOut : 4,
    Error : -1
}

// Public methods

Melown.Roi.delve = function(enterPosition_) {
    if (this.state_ === Melown.Roi.State.Created
        || this.state_ === Melown.Roi.State.FadingOut) {
        this.develAtFinishRequested_ = true;
    } else if (this.state_ === Melown.Roi.State.FadingIn) {
        this.leaveAtFinishRequested_ = false;
    } else if (this.state_ !== Melown.Roi.State.Ready) {
        return;
    }

    // TODO flight into roi position and blend with custom render
}

Melown.Roi.leave = function() {
    if (this.state_ === Melown.Roi.State.Created
        || this.state_ === Melown.Roi.State.FadingOut) {
        this.develAtFinishRequested_ = false;
    } else if (this.state_ === Melown.Roi.State.FadingIn) {
        this.leaveAtFinishRequested_ = true;
    } else if (this.state_ !== Melown.Roi.State.Ready) {
        return;
    }

    // TODO flight into roi position and blend with custom render
}

// Accessor methods

Melown.Roi.prototype.state = function() {
    return this.state_;
}

Melown.Roi.prototype.config = function() {
    return this.config_;
}

Melown.Roi.currentPosition = function(type_ = 'obj') {
    if (type_ === 'obj') {
        return this.currendPosition_;
    }
    return this.map_.convert(this.currendPosition_, type);
}

Melown.Roi.orientation = function(yaw, pitch) {
    if (yaw === undefined) {
        // TODO get current yaw and pitch
        return [0, 0];
    } else if (pitch === undefined) {
        if (yaw instanceof Array && yaw.length >= 2) {
            pitch = yaw[1];
            yaw = yaw[0];
        } else {
            pitch = this.orientation[1];
        }
    }
    // TODO set current position from given yaw and pitch
}

// Protected methods

/**
 * Parent class (this class) _init method MUST be caled from overidden method.
 */
Melown.Roi.prototype._init = function() {
    // Process configuration file
    if (typeof this.config_ !== 'object' || type.config_ === null) {
        this.state_ = Melown.Roi.State.Error;
        var err = new Error('Config passed to ROI constructor is not object');
        console.error(err);
        return;
    }
    this._processConfig();

    // If processing of configuration is successfull
    // (configuration JSON is valid) proceed to finalize initialization
    if (this.state_ != Melown.Roi.State.Error) {
        this._initFinalize();
    }
}

/**
 * Parent class (this class) _init method MUST be caled from overidden method.
 */
Melown.Roi.prototype._processConfig = function() {
    var err = null;
    if (typeof this.config_['id'] !== 'string') {
        err = new Error('Missing (or type error) ROI id in config JSON');
    } else if (this instanceof Melown.Roi.Type[this.config_['type']]) {
        err = new Error('ROI type in config JSON missing or is not registered');
    } else if (!this.config_['position'] instanceof Array
               || !this.core_.map_.positionSanity(this.config_['position'])) {
        err = new Error('ROI position in config JSON missing or is not valid');
    } else if (typeof this.config_['title'] !== 'string') {
        err = new Error('Missing (or type error) ROI title in config JSON');
    }

    if (err !== null) {
        this.state_ = Melown.Roi.State.Error;
    }
}

/**
 * Parent class (this class) _init method MUST be caled from overidden method.
 */
Melown.Roi.prototype._initFinalize = function() {
    // Change state and go ...
    this.state_ = Melown.Roi.State.Ready;

    if (this.develAtFinishRequested_) {
        this.develAtFinishRequested_ = false;
        this.devel();
    }
}
<|endoftext|>


<commit_before>const bookmarks = {
	add($scope, video) {
		let options = {
			id: video.snippet.resourceId.videoId,
			title: video.snippet.title,
			payload: `#/video/${video.snippet.resourceId.videoId}`,
			icon: video.snippet.thumbnails.default
		};
		let callback = (err, data) => {
			if (err) throw err;
			if ($scope.WidgetFeed) {
				$scope.WidgetFeed.videos.map(v => {
					const isBookmarked = v.snippet.resourceId.videoId === video.snippet.resourceId.videoId;
					if (isBookmarked) {
						v.bookmarked = true;
					}
				});
			} else if ($scope.WidgetSingle) {
				$scope.WidgetSingle.video.bookmarked = true;
			}
			if (!$scope.$$phase) {
				$scope.$apply();
			}
		};
		buildfire.bookmarks.add(options, callback);
	},
	delete($scope, video) {
		const callback = () => {
            if ($scope.WidgetFeed) {
				$scope.WidgetFeed.videos.map(v => {
					const isBookmarked = v.snippet.resourceId.videoId === video.snippet.resourceId.videoId;
					if (isBookmarked) {
						v.bookmarked = false;
					}
				});
			} else if ($scope.WidgetSingle) {
				$scope.WidgetSingle.video.bookmarked = false;
            }
            if (!$scope.$$phase) {
				$scope.$apply();
			}
		};
		buildfire.bookmarks.delete(video.snippet.resourceId.videoId, callback);
	},
	_getAll(callback) {
		const cb = (err, bookmarks) => {
			if (err) throw err;
			callback(bookmarks);
		};
		buildfire.bookmarks.getAll(cb);
	},
	findAndMarkAll($scope) {
		this._getAll(bookmarks => {
			console.log(bookmarks);

			const bookmarkIds = [];
			bookmarks.forEach(bookmark => {
				bookmarkIds.push(bookmark.id);
			});
			$scope.WidgetFeed.videos.map(video => {
				const isBookmarked = bookmarkIds.includes(video.snippet.resourceId.videoId);
				if (isBookmarked) {
					video.bookmarked = true;
				} else {
					video.bookmarked = false;
				}
			});
			if (!$scope.$$phase) {
				$scope.$apply();
			}
		});
	}
};
<commit_msg>fix imageurl in bookmark view<commit_after>const bookmarks = {
	add($scope, video) {
		let options = {
			id: video.snippet.resourceId.videoId,
			title: video.snippet.title,
			payload: `#/video/${video.snippet.resourceId.videoId}`,
			icon: video.snippet.thumbnails.default.url
		};
		let callback = (err, data) => {
			if (err) throw err;
			if ($scope.WidgetFeed) {
				$scope.WidgetFeed.videos.map(v => {
					const isBookmarked = v.snippet.resourceId.videoId === video.snippet.resourceId.videoId;
					if (isBookmarked) {
						v.bookmarked = true;
					}
				});
			} else if ($scope.WidgetSingle) {
				$scope.WidgetSingle.video.bookmarked = true;
			}
			if (!$scope.$$phase) {
				$scope.$apply();
			}
		};
		buildfire.bookmarks.add(options, callback);
	},
	delete($scope, video) {
		const callback = () => {
            if ($scope.WidgetFeed) {
				$scope.WidgetFeed.videos.map(v => {
					const isBookmarked = v.snippet.resourceId.videoId === video.snippet.resourceId.videoId;
					if (isBookmarked) {
						v.bookmarked = false;
					}
				});
			} else if ($scope.WidgetSingle) {
				$scope.WidgetSingle.video.bookmarked = false;
            }
            if (!$scope.$$phase) {
				$scope.$apply();
			}
		};
		buildfire.bookmarks.delete(video.snippet.resourceId.videoId, callback);
	},
	_getAll(callback) {
		const cb = (err, bookmarks) => {
			if (err) throw err;
			callback(bookmarks);
		};
		buildfire.bookmarks.getAll(cb);
	},
	findAndMarkAll($scope) {
		this._getAll(bookmarks => {
			console.log(bookmarks);

			const bookmarkIds = [];
			bookmarks.forEach(bookmark => {
				bookmarkIds.push(bookmark.id);
			});
			$scope.WidgetFeed.videos.map(video => {
				const isBookmarked = bookmarkIds.includes(video.snippet.resourceId.videoId);
				if (isBookmarked) {
					video.bookmarked = true;
				} else {
					video.bookmarked = false;
				}
			});
			if (!$scope.$$phase) {
				$scope.$apply();
			}
		});
	}
};
<|endoftext|>


<commit_before>command: 'echo ""',
refreshFrequency: 10000,

printerCount: 8,

style: [
	"left: 20vw",
	"bottom: 3vh",

	"height: 47vh",
	"width: 60%",

	"text-align: center",
	"font-size: 1.2em",

	".details",
	"	font-size: 1em",

	".title",
	"	margin-top: 1em",

	".heading",
	"	font-weight: 200",
	"	font-size: 1em",
	"	margin: .5em 0 0 0",

	".inner-list",
	"	color: black",

	".inner-list li",
	"	display: inline-block",
	"	padding-left: 0.35em",
	"	padding-right: 0.35em",
	"	background-color: rgba(255, 255, 255, 0.65)",
	"	border-radius: 0.25em",
	"	margin: 0.15em 0.15em",
].join('\n'),

render: function(output) {
	return [
		'
',
			'

',
			'
Printer Status
',
		'
',
	].join('')
},

update: function(output, domEl) {
	if (!window.sto)               return '';
	if (!window.sto.libs.lodash)   return '';
	if (!window.sto.data.printers) return '';

	var _ = window.sto.libs.lodash;

	var printers = _.cloneDeep(window.sto.data.printers);
	var printersInErrorState = _.chain(printers)
		.reject({'error': "No Error"})
		.reject({'error': "Paper Low"})
		.filter(function(printer) {
			return printer['Printer'] && _.contains(printer['Printer'].toLowerCase(), 'mfc-')
		})
		.groupBy('error')
		.value()

	printersInErrorState['Low Toner (< 10%)'] = _.chain(printers)
		.filter(function(printer) {
			return printer.toner < 10
		})
		.map(function(printer) {
			printer.name = printer.name + ' (' + printer.toner + '%)'
			if (printer.toner < 5)
				printer.className = 'bg-yellow'
			if (printer.toner <= 1)
				printer.className = 'bg-orange'
			return printer
		})
		.sortBy('Toner')
		.value()

	var details = domEl.querySelector('.details');

	var contentList = document.createElement('ul');
	contentList.className = 'list';

	var printerCount = this.printerCount;
	_.each(printersInErrorState, function(printers, key) {
		printers = _.first(printers, printerCount);

		var group = document.createElement('li');
		group.className = 'group';

		var title = document.createElement('h1');
		title.className = 'heading'
		title.textContent = key;
		group.appendChild(title);

		var printerList = document.createElement('ul');
		printerList.className = 'inner-list';
		_.each(printers, function(printer) {
			var printerAsElement = document.createElement('li');
			if (printer.className) printerAsElement.className = printer.className
			printerAsElement.textContent = printer.name;
			printerList.appendChild(printerAsElement);
		})

		group.appendChild(printerList)
		contentList.appendChild(group);
	})

	details.innerHTML = contentList.outerHTML
},
<commit_msg>Fix various problems with the printer-status widget<commit_after>command: 'echo ""',
refreshFrequency: 10000,

printerCount: 8,

style: [
	"left: 20vw",
	"bottom: 3vh",

	"height: 47vh",
	"width: 60%",

	"text-align: center",
	"font-size: 1.2em",

	".details",
	"	font-size: 1em",

	".title",
	"	margin-top: 1em",

	".heading",
	"	font-weight: 200",
	"	font-size: 1em",
	"	margin: .5em 0 0 0",

	".inner-list",
	"	color: black",

	".inner-list li",
	"	display: inline-block",
	"	padding-left: 0.35em",
	"	padding-right: 0.35em",
	"	background-color: rgba(255, 255, 255, 0.65)",
	"	border-radius: 0.25em",
	"	margin: 0.15em 0.15em",
].join('\n'),

render: function(output) {
	return [
		'
',
			'

',
			'
Printer Status
',
		'
',
	].join('')
},

update: function(output, domEl) {
	if (!window.sto)               return '';
	if (!window.sto.libs.lodash)   return '';
	if (!window.sto.data.printers) return '';

	var _ = window.sto.libs.lodash;

	var printers = _.cloneDeep(window.sto.data.printers);
	var printersInErrorState = _.chain(printers)
		.reject({'error': "No Error"})
		.reject({'error': "Paper Low"})
		.filter(function(printer) {
			return printer.name && _.contains(printer.name.toLowerCase(), 'mfc-')
		})
		.groupBy('error')
		.value();

	printersInErrorState['Low Toner (< 10%)'] = _.chain(printers)
		.filter(function(printer) {
			return printer.toner < 10
		})
		.map(function(printer) {
			printer.name = printer.name + ' (' + printer.toner + '%)'
			if (printer.toner < 5)
				printer.className = 'bg-yellow'
			if (printer.toner <= 1)
				printer.className = 'bg-orange'
			return printer
		})
		.sortBy('toner')
		.value();

	var details = domEl.querySelector('.details');

	var contentList = document.createElement('ul');
	contentList.className = 'list';

	var printerCount = this.printerCount;
	_.each(printersInErrorState, function(printers, key) {
		printers = _.first(printers, printerCount);

		var group = document.createElement('li');
		group.className = 'group';

		var title = document.createElement('h1');
		title.className = 'heading'
		title.textContent = key;
		group.appendChild(title);

		var printerList = document.createElement('ul');
		printerList.className = 'inner-list';
		_.each(printers, function(printer) {
			var printerAsElement = document.createElement('li');
			if (printer.className) printerAsElement.className = printer.className
			printerAsElement.textContent = printer.name;
			printerList.appendChild(printerAsElement);
		})

		group.appendChild(printerList)
		contentList.appendChild(group);
	})

	details.innerHTML = contentList.outerHTML
},
<|endoftext|>