<commit_before>var elixir = require('laravel-elixir');
require('laravel-elixir-eslint');

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Less
 | file for our application, as well as publishing vendor resources.
 |
 */
var paths = {
	'bower': './vendor/bower_components/',
	'jquery': './vendor/bower_components/jquery/',
	'bootstrap': './vendor/bower_components/bootstrap-sass-official/assets/',
	'fontawesome': './vendor/bower_components/fontawesome/',
	'dropzone': './vendor/bower_components/dropzone/dist/',
	'jasny': './vendor/bower_components/jasny-bootstrap/dist/',
	'swipebox': './vendor/bower_components/swipebox/src/',
	'sortable': './vendor/bower_components/Sortable/'
}

elixir(function(mix) {
	mix.sass('**/*', 'public/css/', {includePaths: [paths.bootstrap + 'stylesheets', paths.fontawesome + 'scss']})
		.copy(paths.bootstrap + 'fonts/bootstrap/**', 'public/fonts/bootstrap')
		.copy(paths.fontawesome + 'fonts/**', 'public/fonts/fontawesome')
		.copy(paths.swipebox + 'img/**', 'public/images')
		.scripts([
			paths.jquery + "dist/jquery.js",
			paths.bootstrap + "javascripts/bootstrap.js",
			paths.bower + "select2/dist/js/select2.js",
			paths.bower + "fancybox/source/jquery.fancybox.js",
			paths.bower + "moment/moment.js",
			paths.bower + "moment-range/lib/moment-range.js",
			paths.bower + "jcrop/js/jquery.Jcrop.js",
			paths.bower + "slick-carousel/slick/slick.js",
			paths.dropzone + "dropzone.js",
			paths.jasny + "js/jasny-bootstrap.js",
			paths.sortable + "Sortable.js",
			paths.sortable + "jquery.binding.js",
			paths.swipebox + "js/jquery.swipebox.js",
		], 'public/js/vendor.js', './')
		.eslint(['resources/assets/js/*.js'])
		.browserify('app.js', './public/js/app.js')
		.version([
			'css/app.css',
			'css/admin/app.css',
			'js/vendor.js',
			'js/app.js',
		])
});

<commit_msg>fix for front and backend app sass files<commit_after>var elixir = require('laravel-elixir');
require('laravel-elixir-eslint');

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Less
 | file for our application, as well as publishing vendor resources.
 |
 */
var paths = {
	'bower': './vendor/bower_components/',
	'jquery': './vendor/bower_components/jquery/',
	'bootstrap': './vendor/bower_components/bootstrap-sass-official/assets/',
	'fontawesome': './vendor/bower_components/fontawesome/',
	'dropzone': './vendor/bower_components/dropzone/dist/',
	'jasny': './vendor/bower_components/jasny-bootstrap/dist/',
	'swipebox': './vendor/bower_components/swipebox/src/',
	'sortable': './vendor/bower_components/Sortable/'
}

elixir(function(mix) {
	mix.sass('app.scss', 'public/css/app.css', {includePaths: [paths.bootstrap + 'stylesheets', paths.fontawesome + 'scss']})
		.sass('admin/app.scss', 'public/css/admin/app.css', {includePaths: [paths.bootstrap + 'stylesheets', paths.fontawesome + 'scss']})
		.copy(paths.bootstrap + 'fonts/bootstrap/**', 'public/fonts/bootstrap')
		.copy(paths.fontawesome + 'fonts/**', 'public/fonts/fontawesome')
		.copy(paths.swipebox + 'img/**', 'public/images')
		.scripts([
			paths.jquery + "dist/jquery.js",
			paths.bootstrap + "javascripts/bootstrap.js",
			paths.bower + "select2/dist/js/select2.js",
			paths.bower + "fancybox/source/jquery.fancybox.js",
			paths.bower + "moment/moment.js",
			paths.bower + "moment-range/lib/moment-range.js",
			paths.bower + "jcrop/js/jquery.Jcrop.js",
			paths.bower + "slick-carousel/slick/slick.js",
			paths.dropzone + "dropzone.js",
			paths.jasny + "js/jasny-bootstrap.js",
			paths.sortable + "Sortable.js",
			paths.sortable + "jquery.binding.js",
			paths.swipebox + "js/jquery.swipebox.js",
		], 'public/js/vendor.js', './')
		.eslint(['resources/assets/js/*.js'])
		.browserify('app.js', './public/js/app.js')
		.version([
			'css/app.css',
			'css/admin/app.css',
			'js/vendor.js',
			'js/app.js',
		])
});

<|endoftext|>


<commit_before>/*
Copyright 2017 Vector Creations Ltd
Copyright 2018 New Vector Ltd
Copyright 2020 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import {logger} from '../../logger';
import * as utils from "../../utils";

/**
 * Internal module. in-memory storage for e2e.
 *
 * @module
 */

/**
 * @implements {module:crypto/store/base~CryptoStore}
 */
export class MemoryCryptoStore {
    constructor() {
        this._outgoingRoomKeyRequests = [];
        this._account = null;
        this._crossSigningKeys = null;

        // Map of {devicekey -> {sessionId -> session pickle}}
        this._sessions = {};
        // Map of {devicekey -> array of problems}
        this._sessionProblems = {};
        // Map of {userId -> deviceId -> true}
        this._notifiedErrorDevices = {};
        // Map of {senderCurve25519Key+'/'+sessionId -> session data object}
        this._inboundGroupSessions = {};
        this._inboundGroupSessionsWithheld = {};
        // Opaque device data object
        this._deviceData = null;
        // roomId -> Opaque roomInfo object
        this._rooms = {};
        // Set of {senderCurve25519Key+'/'+sessionId}
        this._sessionsNeedingBackup = {};
    }

    /**
     * Delete all data from this store.
     *
     * @returns {Promise} Promise which resolves when the store has been cleared.
     */
    deleteAllData() {
        return Promise.resolve();
    }

    /**
     * Look for an existing outgoing room key request, and if none is found,
     * add a new one
     *
     * @param {module:crypto/store/base~OutgoingRoomKeyRequest} request
     *
     * @returns {Promise} resolves to
     *    {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the
     *    same instance as passed in, or the existing one.
     */
    getOrAddOutgoingRoomKeyRequest(request) {
        const requestBody = request.requestBody;

        return utils.promiseTry(() => {
            // first see if we already have an entry for this request.
            const existing = this._getOutgoingRoomKeyRequest(requestBody);

            if (existing) {
                // this entry matches the request - return it.
                logger.log(
                    `already have key request outstanding for ` +
                    `${requestBody.room_id} / ${requestBody.session_id}: ` +
                    `not sending another`,
                );
                return existing;
            }

            // we got to the end of the list without finding a match
            // - add the new request.
            logger.log(
                `enqueueing key request for ${requestBody.room_id} / ` +
                requestBody.session_id,
            );
            this._outgoingRoomKeyRequests.push(request);
            return request;
        });
    }

    /**
     * Look for an existing room key request
     *
     * @param {module:crypto~RoomKeyRequestBody} requestBody
     *    existing request to look for
     *
     * @return {Promise} resolves to the matching
     *    {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
     *    not found
     */
    getOutgoingRoomKeyRequest(requestBody) {
        return Promise.resolve(this._getOutgoingRoomKeyRequest(requestBody));
    }

    /**
     * Looks for existing room key request, and returns the result synchronously.
     *
     * @internal
     *
     * @param {module:crypto~RoomKeyRequestBody} requestBody
     *    existing request to look for
     *
     * @return {module:crypto/store/base~OutgoingRoomKeyRequest?}
     *    the matching request, or null if not found
     */
    _getOutgoingRoomKeyRequest(requestBody) {
        for (const existing of this._outgoingRoomKeyRequests) {
            if (utils.deepCompare(existing.requestBody, requestBody)) {
                return existing;
            }
        }
        return null;
    }

    /**
     * Look for room key requests by state
     *
     * @param {Array<Number>} wantedStates list of acceptable states
     *
     * @return {Promise} resolves to the a
     *    {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
     *    there are no pending requests in those states
     */
    getOutgoingRoomKeyRequestByState(wantedStates) {
        for (const req of this._outgoingRoomKeyRequests) {
            for (const state of wantedStates) {
                if (req.state === state) {
                    return Promise.resolve(req);
                }
            }
        }
        return Promise.resolve(null);
    }

    getOutgoingRoomKeyRequestsByTarget(userId, deviceId, wantedStates) {
        const results = [];

        for (const req of this._outgoingRoomKeyRequests) {
            for (const state of wantedStates) {
                if (req.state === state && req.recipients.includes({userId, deviceId})) {
                    results.push(req);
                }
            }
        }
        return Promise.resolve(results);
    }

    /**
     * Look for an existing room key request by id and state, and update it if
     * found
     *
     * @param {string} requestId      ID of request to update
     * @param {number} expectedState  state we expect to find the request in
     * @param {Object} updates        name/value map of updates to apply
     *
     * @returns {Promise} resolves to
     *    {@link module:crypto/store/base~OutgoingRoomKeyRequest}
     *    updated request, or null if no matching row was found
     */
    updateOutgoingRoomKeyRequest(requestId, expectedState, updates) {
        for (const req of this._outgoingRoomKeyRequests) {
            if (req.requestId !== requestId) {
                continue;
            }

            if (req.state != expectedState) {
                logger.warn(
                    `Cannot update room key request from ${expectedState} ` +
                    `as it was already updated to ${req.state}`,
                );
                return Promise.resolve(null);
            }
            Object.assign(req, updates);
            return Promise.resolve(req);
        }

        return Promise.resolve(null);
    }

    /**
     * Look for an existing room key request by id and state, and delete it if
     * found
     *
     * @param {string} requestId      ID of request to update
     * @param {number} expectedState  state we expect to find the request in
     *
     * @returns {Promise} resolves once the operation is completed
     */
    deleteOutgoingRoomKeyRequest(requestId, expectedState) {
        for (let i = 0; i < this._outgoingRoomKeyRequests.length; i++) {
            const req = this._outgoingRoomKeyRequests[i];

            if (req.requestId !== requestId) {
                continue;
            }

            if (req.state != expectedState) {
                logger.warn(
                    `Cannot delete room key request in state ${req.state} `
                    + `(expected ${expectedState})`,
                );
                return Promise.resolve(null);
            }

            this._outgoingRoomKeyRequests.splice(i, 1);
            return Promise.resolve(req);
        }

        return Promise.resolve(null);
    }

    // Olm Account

    getAccount(txn, func) {
        func(this._account);
    }

    storeAccount(txn, newData) {
        this._account = newData;
    }

    getCrossSigningKeys(txn, func) {
        func(this._crossSigningKeys);
    }

    storeCrossSigningKeys(txn, keys) {
        this._crossSigningKeys = keys;
    }

    // Olm Sessions

    countEndToEndSessions(txn, func) {
        return Object.keys(this._sessions).length;
    }

    getEndToEndSession(deviceKey, sessionId, txn, func) {
        const deviceSessions = this._sessions[deviceKey] || {};
        func(deviceSessions[sessionId] || null);
    }

    getEndToEndSessions(deviceKey, txn, func) {
        func(this._sessions[deviceKey] || {});
    }

    getAllEndToEndSessions(txn, func) {
        for (const deviceSessions of Object.values(this._sessions)) {
            for (const sess of Object.values(deviceSessions)) {
                func(sess);
            }
        }
    }

    storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
        let deviceSessions = this._sessions[deviceKey];
        if (deviceSessions === undefined) {
            deviceSessions = {};
            this._sessions[deviceKey] = deviceSessions;
        }
        deviceSessions[sessionId] = sessionInfo;
    }

    async storeEndToEndSessionProblem(deviceKey, type, fixed) {
        const problems = this._sessionProblems[deviceKey]
              = this._sessionProblems[deviceKey] || [];
        problems.push({type, fixed, time: Date.now()});
        problems.sort((a, b) => {
            return a.time - b.time;
        });
    }

    async getEndToEndSessionProblem(deviceKey, timestamp) {
        const problems = this._sessionProblems[deviceKey] || [];
        if (!problems.length) {
            return null;
        }
        const lastProblem = problems[problems.length - 1];
        for (const problem of problems) {
            if (problem.time > timestamp) {
                return Object.assign({}, problem, {fixed: lastProblem.fixed});
            }
        }
        if (lastProblem.fixed) {
            return null;
        } else {
            return lastProblem;
        }
    }

    async filterOutNotifiedErrorDevices(devices) {
        const notifiedErrorDevices = this._notifiedErrorDevices;
        const ret = [];

        for (const device of devices) {
            const {userId, deviceInfo} = device;
            if (userId in notifiedErrorDevices) {
                if (!(deviceInfo.deviceId in notifiedErrorDevices[userId])) {
                    ret.push(device);
                    notifiedErrorDevices[userId][deviceInfo.deviceId] = true;
                }
            } else {
                ret.push(device);
                notifiedErrorDevices[userId] = {[deviceInfo.deviceId]: true };
            }
        }

        return ret;
    }

    // Inbound Group Sessions

    getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func) {
        const k = senderCurve25519Key+'/'+sessionId;
        func(
            this._inboundGroupSessions[k] || null,
            this._inboundGroupSessionsWithheld[k] || null,
        );
    }

    getAllEndToEndInboundGroupSessions(txn, func) {
        for (const key of Object.keys(this._inboundGroupSessions)) {
            // we can't use split, as the components we are trying to split out
            // might themselves contain '/' characters. We rely on the
            // senderKey being a (32-byte) curve25519 key, base64-encoded
            // (hence 43 characters long).

            func({
                senderKey: key.substr(0, 43),
                sessionId: key.substr(44),
                sessionData: this._inboundGroupSessions[key],
            });
        }
        func(null);
    }

    addEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
        const k = senderCurve25519Key+'/'+sessionId;
        if (this._inboundGroupSessions[k] === undefined) {
            this._inboundGroupSessions[k] = sessionData;
        }
    }

    storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
        this._inboundGroupSessions[senderCurve25519Key+'/'+sessionId] = sessionData;
    }

    storeEndToEndInboundGroupSessionWithheld(
        senderCurve25519Key, sessionId, sessionData, txn,
    ) {
        const k = senderCurve25519Key+'/'+sessionId;
        this._inboundGroupSessionsWithheld[k] = sessionData;
    }

    // Device Data

    getEndToEndDeviceData(txn, func) {
        func(this._deviceData);
    }

    storeEndToEndDeviceData(deviceData, txn) {
        this._deviceData = deviceData;
    }

    // E2E rooms

    storeEndToEndRoom(roomId, roomInfo, txn) {
        this._rooms[roomId] = roomInfo;
    }

    getEndToEndRooms(txn, func) {
        func(this._rooms);
    }

    getSessionsNeedingBackup(limit) {
        const sessions = [];
        for (const session in this._sessionsNeedingBackup) {
            if (this._inboundGroupSessions[session]) {
                sessions.push({
                    senderKey: session.substr(0, 43),
                    sessionId: session.substr(44),
                    sessionData: this._inboundGroupSessions[session],
                });
                if (limit && session.length >= limit) {
                    break;
                }
            }
        }
        return Promise.resolve(sessions);
    }

    countSessionsNeedingBackup() {
        return Promise.resolve(Object.keys(this._sessionsNeedingBackup).length);
    }

    unmarkSessionsNeedingBackup(sessions) {
        for (const session of sessions) {
            const sessionKey = session.senderKey + '/' + session.sessionId;
            delete this._sessionsNeedingBackup[sessionKey];
        }
        return Promise.resolve();
    }

    markSessionsNeedingBackup(sessions) {
        for (const session of sessions) {
            const sessionKey = session.senderKey + '/' + session.sessionId;
            this._sessionsNeedingBackup[sessionKey] = true;
        }
        return Promise.resolve();
    }

    // Session key backups

    doTxn(mode, stores, func) {
        return Promise.resolve(func(null));
    }
}
<commit_msg>fix output of getAllEndToEndSessions<commit_after>/*
Copyright 2017 Vector Creations Ltd
Copyright 2018 New Vector Ltd
Copyright 2020 The Matrix.org Foundation C.I.C.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

import {logger} from '../../logger';
import * as utils from "../../utils";

/**
 * Internal module. in-memory storage for e2e.
 *
 * @module
 */

/**
 * @implements {module:crypto/store/base~CryptoStore}
 */
export class MemoryCryptoStore {
    constructor() {
        this._outgoingRoomKeyRequests = [];
        this._account = null;
        this._crossSigningKeys = null;

        // Map of {devicekey -> {sessionId -> session pickle}}
        this._sessions = {};
        // Map of {devicekey -> array of problems}
        this._sessionProblems = {};
        // Map of {userId -> deviceId -> true}
        this._notifiedErrorDevices = {};
        // Map of {senderCurve25519Key+'/'+sessionId -> session data object}
        this._inboundGroupSessions = {};
        this._inboundGroupSessionsWithheld = {};
        // Opaque device data object
        this._deviceData = null;
        // roomId -> Opaque roomInfo object
        this._rooms = {};
        // Set of {senderCurve25519Key+'/'+sessionId}
        this._sessionsNeedingBackup = {};
    }

    /**
     * Delete all data from this store.
     *
     * @returns {Promise} Promise which resolves when the store has been cleared.
     */
    deleteAllData() {
        return Promise.resolve();
    }

    /**
     * Look for an existing outgoing room key request, and if none is found,
     * add a new one
     *
     * @param {module:crypto/store/base~OutgoingRoomKeyRequest} request
     *
     * @returns {Promise} resolves to
     *    {@link module:crypto/store/base~OutgoingRoomKeyRequest}: either the
     *    same instance as passed in, or the existing one.
     */
    getOrAddOutgoingRoomKeyRequest(request) {
        const requestBody = request.requestBody;

        return utils.promiseTry(() => {
            // first see if we already have an entry for this request.
            const existing = this._getOutgoingRoomKeyRequest(requestBody);

            if (existing) {
                // this entry matches the request - return it.
                logger.log(
                    `already have key request outstanding for ` +
                    `${requestBody.room_id} / ${requestBody.session_id}: ` +
                    `not sending another`,
                );
                return existing;
            }

            // we got to the end of the list without finding a match
            // - add the new request.
            logger.log(
                `enqueueing key request for ${requestBody.room_id} / ` +
                requestBody.session_id,
            );
            this._outgoingRoomKeyRequests.push(request);
            return request;
        });
    }

    /**
     * Look for an existing room key request
     *
     * @param {module:crypto~RoomKeyRequestBody} requestBody
     *    existing request to look for
     *
     * @return {Promise} resolves to the matching
     *    {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
     *    not found
     */
    getOutgoingRoomKeyRequest(requestBody) {
        return Promise.resolve(this._getOutgoingRoomKeyRequest(requestBody));
    }

    /**
     * Looks for existing room key request, and returns the result synchronously.
     *
     * @internal
     *
     * @param {module:crypto~RoomKeyRequestBody} requestBody
     *    existing request to look for
     *
     * @return {module:crypto/store/base~OutgoingRoomKeyRequest?}
     *    the matching request, or null if not found
     */
    _getOutgoingRoomKeyRequest(requestBody) {
        for (const existing of this._outgoingRoomKeyRequests) {
            if (utils.deepCompare(existing.requestBody, requestBody)) {
                return existing;
            }
        }
        return null;
    }

    /**
     * Look for room key requests by state
     *
     * @param {Array<Number>} wantedStates list of acceptable states
     *
     * @return {Promise} resolves to the a
     *    {@link module:crypto/store/base~OutgoingRoomKeyRequest}, or null if
     *    there are no pending requests in those states
     */
    getOutgoingRoomKeyRequestByState(wantedStates) {
        for (const req of this._outgoingRoomKeyRequests) {
            for (const state of wantedStates) {
                if (req.state === state) {
                    return Promise.resolve(req);
                }
            }
        }
        return Promise.resolve(null);
    }

    getOutgoingRoomKeyRequestsByTarget(userId, deviceId, wantedStates) {
        const results = [];

        for (const req of this._outgoingRoomKeyRequests) {
            for (const state of wantedStates) {
                if (req.state === state && req.recipients.includes({userId, deviceId})) {
                    results.push(req);
                }
            }
        }
        return Promise.resolve(results);
    }

    /**
     * Look for an existing room key request by id and state, and update it if
     * found
     *
     * @param {string} requestId      ID of request to update
     * @param {number} expectedState  state we expect to find the request in
     * @param {Object} updates        name/value map of updates to apply
     *
     * @returns {Promise} resolves to
     *    {@link module:crypto/store/base~OutgoingRoomKeyRequest}
     *    updated request, or null if no matching row was found
     */
    updateOutgoingRoomKeyRequest(requestId, expectedState, updates) {
        for (const req of this._outgoingRoomKeyRequests) {
            if (req.requestId !== requestId) {
                continue;
            }

            if (req.state != expectedState) {
                logger.warn(
                    `Cannot update room key request from ${expectedState} ` +
                    `as it was already updated to ${req.state}`,
                );
                return Promise.resolve(null);
            }
            Object.assign(req, updates);
            return Promise.resolve(req);
        }

        return Promise.resolve(null);
    }

    /**
     * Look for an existing room key request by id and state, and delete it if
     * found
     *
     * @param {string} requestId      ID of request to update
     * @param {number} expectedState  state we expect to find the request in
     *
     * @returns {Promise} resolves once the operation is completed
     */
    deleteOutgoingRoomKeyRequest(requestId, expectedState) {
        for (let i = 0; i < this._outgoingRoomKeyRequests.length; i++) {
            const req = this._outgoingRoomKeyRequests[i];

            if (req.requestId !== requestId) {
                continue;
            }

            if (req.state != expectedState) {
                logger.warn(
                    `Cannot delete room key request in state ${req.state} `
                    + `(expected ${expectedState})`,
                );
                return Promise.resolve(null);
            }

            this._outgoingRoomKeyRequests.splice(i, 1);
            return Promise.resolve(req);
        }

        return Promise.resolve(null);
    }

    // Olm Account

    getAccount(txn, func) {
        func(this._account);
    }

    storeAccount(txn, newData) {
        this._account = newData;
    }

    getCrossSigningKeys(txn, func) {
        func(this._crossSigningKeys);
    }

    storeCrossSigningKeys(txn, keys) {
        this._crossSigningKeys = keys;
    }

    // Olm Sessions

    countEndToEndSessions(txn, func) {
        return Object.keys(this._sessions).length;
    }

    getEndToEndSession(deviceKey, sessionId, txn, func) {
        const deviceSessions = this._sessions[deviceKey] || {};
        func(deviceSessions[sessionId] || null);
    }

    getEndToEndSessions(deviceKey, txn, func) {
        func(this._sessions[deviceKey] || {});
    }

    getAllEndToEndSessions(txn, func) {
        Object.entries(this._sessions).forEach(([deviceKey, deviceSessions]) => {
            Object.entries(deviceSessions).forEach(([sessionId, session]) => {
                func({
                    ...session,
                    deviceKey,
                    sessionId,
                });
            });
        });
    }

    storeEndToEndSession(deviceKey, sessionId, sessionInfo, txn) {
        let deviceSessions = this._sessions[deviceKey];
        if (deviceSessions === undefined) {
            deviceSessions = {};
            this._sessions[deviceKey] = deviceSessions;
        }
        deviceSessions[sessionId] = sessionInfo;
    }

    async storeEndToEndSessionProblem(deviceKey, type, fixed) {
        const problems = this._sessionProblems[deviceKey]
              = this._sessionProblems[deviceKey] || [];
        problems.push({type, fixed, time: Date.now()});
        problems.sort((a, b) => {
            return a.time - b.time;
        });
    }

    async getEndToEndSessionProblem(deviceKey, timestamp) {
        const problems = this._sessionProblems[deviceKey] || [];
        if (!problems.length) {
            return null;
        }
        const lastProblem = problems[problems.length - 1];
        for (const problem of problems) {
            if (problem.time > timestamp) {
                return Object.assign({}, problem, {fixed: lastProblem.fixed});
            }
        }
        if (lastProblem.fixed) {
            return null;
        } else {
            return lastProblem;
        }
    }

    async filterOutNotifiedErrorDevices(devices) {
        const notifiedErrorDevices = this._notifiedErrorDevices;
        const ret = [];

        for (const device of devices) {
            const {userId, deviceInfo} = device;
            if (userId in notifiedErrorDevices) {
                if (!(deviceInfo.deviceId in notifiedErrorDevices[userId])) {
                    ret.push(device);
                    notifiedErrorDevices[userId][deviceInfo.deviceId] = true;
                }
            } else {
                ret.push(device);
                notifiedErrorDevices[userId] = {[deviceInfo.deviceId]: true };
            }
        }

        return ret;
    }

    // Inbound Group Sessions

    getEndToEndInboundGroupSession(senderCurve25519Key, sessionId, txn, func) {
        const k = senderCurve25519Key+'/'+sessionId;
        func(
            this._inboundGroupSessions[k] || null,
            this._inboundGroupSessionsWithheld[k] || null,
        );
    }

    getAllEndToEndInboundGroupSessions(txn, func) {
        for (const key of Object.keys(this._inboundGroupSessions)) {
            // we can't use split, as the components we are trying to split out
            // might themselves contain '/' characters. We rely on the
            // senderKey being a (32-byte) curve25519 key, base64-encoded
            // (hence 43 characters long).

            func({
                senderKey: key.substr(0, 43),
                sessionId: key.substr(44),
                sessionData: this._inboundGroupSessions[key],
            });
        }
        func(null);
    }

    addEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
        const k = senderCurve25519Key+'/'+sessionId;
        if (this._inboundGroupSessions[k] === undefined) {
            this._inboundGroupSessions[k] = sessionData;
        }
    }

    storeEndToEndInboundGroupSession(senderCurve25519Key, sessionId, sessionData, txn) {
        this._inboundGroupSessions[senderCurve25519Key+'/'+sessionId] = sessionData;
    }

    storeEndToEndInboundGroupSessionWithheld(
        senderCurve25519Key, sessionId, sessionData, txn,
    ) {
        const k = senderCurve25519Key+'/'+sessionId;
        this._inboundGroupSessionsWithheld[k] = sessionData;
    }

    // Device Data

    getEndToEndDeviceData(txn, func) {
        func(this._deviceData);
    }

    storeEndToEndDeviceData(deviceData, txn) {
        this._deviceData = deviceData;
    }

    // E2E rooms

    storeEndToEndRoom(roomId, roomInfo, txn) {
        this._rooms[roomId] = roomInfo;
    }

    getEndToEndRooms(txn, func) {
        func(this._rooms);
    }

    getSessionsNeedingBackup(limit) {
        const sessions = [];
        for (const session in this._sessionsNeedingBackup) {
            if (this._inboundGroupSessions[session]) {
                sessions.push({
                    senderKey: session.substr(0, 43),
                    sessionId: session.substr(44),
                    sessionData: this._inboundGroupSessions[session],
                });
                if (limit && session.length >= limit) {
                    break;
                }
            }
        }
        return Promise.resolve(sessions);
    }

    countSessionsNeedingBackup() {
        return Promise.resolve(Object.keys(this._sessionsNeedingBackup).length);
    }

    unmarkSessionsNeedingBackup(sessions) {
        for (const session of sessions) {
            const sessionKey = session.senderKey + '/' + session.sessionId;
            delete this._sessionsNeedingBackup[sessionKey];
        }
        return Promise.resolve();
    }

    markSessionsNeedingBackup(sessions) {
        for (const session of sessions) {
            const sessionKey = session.senderKey + '/' + session.sessionId;
            this._sessionsNeedingBackup[sessionKey] = true;
        }
        return Promise.resolve();
    }

    // Session key backups

    doTxn(mode, stores, func) {
        return Promise.resolve(func(null));
    }
}
<|endoftext|>


<commit_before>var elixir = require('laravel-elixir');

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Less
 | file for our application, as well as publishing vendor resources.
 |
 */

elixir(function(mix) {
  mix.sass('application.scss');
});
<commit_msg>Added templates to gulp process<commit_after>var gulp = require('gulp')
  , elixir = require('laravel-elixir')

/*
 |--------------------------------------------------------------------------
 | Elixir Asset Management
 |--------------------------------------------------------------------------
 |
 | Elixir provides a clean, fluent API for defining some basic Gulp tasks
 | for your Laravel application. By default, we are compiling the Less
 | file for our application, as well as publishing vendor resources.
 |
 */

gulp.task("angular_templates", function() {
  gulp
    .src(['resources/js/angular/templates/**/*.html'])
    .pipe(gulp.dest('public/js/templates'))
})

elixir(function(mix) {
  mix
    .scripts([
      'angular/Preload.js',
      'angular/controllers/**/*.js',
      'angular/directives/**/*.js',
      'angular/factories/**/*.js',
      'angular/filters/**/*.js',
      'angular/services/**/*.js',
      'angular/App.js'
    ], 'public/js/prex.js')
    .sass('application.scss')

  mix.task('angular_templates', 'resources/js/angular/templates/**/*.html')
});
<|endoftext|>


<commit_before>var autoprefixer = require('gulp-autoprefixer'),
	coffee = require('gulp-coffee'),
	coffeelint = require('gulp-coffeelint'),
	gulp = require('gulp'),
	gutil = require('gulp-util'),
	jshint = require('gulp-jshint'),
	minifycss = require('gulp-minify-css'),
	nodemon = require('gulp-nodemon'),
	rename = require('gulp-rename'),
	sass = require('gulp-sass'),
	tinylr = require('tiny-lr')(),
	uglify = require('gulp-uglify');

gulp.task('livereload', function () {
	tinylr.listen(3001); // ./bin/www uses 3000
});

var notifyLiveReload = function (event) {
	var fileName = require('path').relative(__dirname, event.path);

	tinylr.changed({
		body: {
			files: [fileName]
		}
	});
}

gulp.task('start', function () {
	nodemon({
		script: './bin/www',
		env: {
			'NODE_ENV': 'development'
		}
	});
});

gulp.task('lintcoffee', function () {
    gulp.src('./lib/coffee/*.coffee')
        .pipe(coffeelint())
        .pipe(coffeelint.reporter())
});

gulp.task('lintjs', function () {
 	gulp.src('./lib/js/*.js')
    	.pipe(jshint())
    	.pipe(jshint.reporter('default'));
});

gulp.task('coffee', function () {
	// not working atm
	gulp.src('./lib/coffee/*.coffee')
    	.pipe(coffee({bare: true})
    		.on('error', gutil.log))
    	.pipe(gulp.dest('./dist/javascripts'))
});

gulp.task('js', function () {
	gulp.src('./lib/js/*.js')
		.pipe(uglify())
		.pipe(gulp.dest('./dist/javascripts'));
});

gulp.task('styles', function () {
	gulp.src('./lib/sass/resizive.scss')
		.pipe(sass({style: 'expanded'}))
		.pipe(autoprefixer('last 2 version'))
		.pipe(gulp.dest('./dist/stylesheets'))
		.pipe(rename({suffix: '.min'}))
		.pipe(minifycss())
		.pipe(gulp.dest('./dist/stylesheets'));
});

gulp.task('watch', function () {
	gulp.watch('./lib/sass/*.scss', ['styles']);
	gulp.watch('./lib/js/*.js', ['lintjs']);
	gulp.watch('./lib/coffee/*.coffee', ['lintcoffee']);
	gulp.watch('./lib/js/*.js', notifyLiveReload);
	gulp.watch('./lib/views/*.jade', notifyLiveReload);
	gulp.watch('dist/stylesheets/*.css', notifyLiveReload);
});

// to do: image compression

gulp.task('default', ['styles', 'js', 'coffee', 'start', 'livereload', 'watch'], function () {

});<commit_msg>alphabetize gulp tasks<commit_after>var autoprefixer = require('gulp-autoprefixer'),
	coffee = require('gulp-coffee'),
	coffeelint = require('gulp-coffeelint'),
	gulp = require('gulp'),
	gutil = require('gulp-util'),
	jade = require('gulp-jade'),
	jshint = require('gulp-jshint'),
	minifycss = require('gulp-minify-css'),
	nodemon = require('gulp-nodemon'),
	rename = require('gulp-rename'),
	sass = require('gulp-sass'),
	tinylr = require('tiny-lr')(),
	uglify = require('gulp-uglify');

var notifyLiveReload = function (event) {
	var fileName = require('path').relative(__dirname, event.path);

	tinylr.changed({
		body: {
			files: [fileName]
		}
	});
}

gulp.task('coffee', function () {
	// not working atm
	gulp.src('./lib/coffee/*.coffee')
    	.pipe(coffee({bare: true})
    		.on('error', gutil.log))
    	.pipe(gulp.dest('./dist/javascripts'))
});

gulp.task('html', function() {
	gulp.src('./lib/views/*.jade')
		.pipe(jade({pretty: true}))
		.pipe(gulp.dest('./dist/'))
});

gulp.task('js', function () {
	gulp.src('./lib/js/*.js')
		.pipe(uglify())
		.pipe(gulp.dest('./dist/javascripts'));
});

gulp.task('lintcoffee', function () {
    gulp.src('./lib/coffee/*.coffee')
        .pipe(coffeelint())
        .pipe(coffeelint.reporter())
});

gulp.task('lintjs', function () {
 	gulp.src('./lib/js/*.js')
    	.pipe(jshint())
    	.pipe(jshint.reporter('default'));
});

gulp.task('livereload', function () {
	tinylr.listen(3001); // ./bin/www uses 3000
});

gulp.task('start', function () {
	nodemon({
		script: './bin/www',
		env: {
			'NODE_ENV': 'development'
		}
	});
});

gulp.task('styles', function () {
	gulp.src('./lib/sass/resizive.scss')
		.pipe(sass({style: 'expanded'}))
		.pipe(autoprefixer('last 2 version'))
		.pipe(gulp.dest('./dist/stylesheets'))
});

gulp.task('styles-min', function () {
	gulp.src('./lib/sass/resizive.scss')
		.pipe(sass({style: 'compressed'}))
		.pipe(autoprefixer('last 2 version'))
		.pipe(rename({suffix: '.min'}))
		.pipe(minifycss())
		.pipe(gulp.dest('./dist/stylesheets'));
});

gulp.task('watch', function () {
	gulp.watch('./lib/sass/*.scss', ['styles']);
	gulp.watch('./lib/js/*.js', ['lintjs']);
	gulp.watch('./lib/coffee/*.coffee', ['lintcoffee']);
	gulp.watch('./lib/js/*.js', notifyLiveReload);
	gulp.watch('./lib/views/*.jade', notifyLiveReload);
	gulp.watch('./dist/stylesheets/*.css', notifyLiveReload);
});

// to do: image compression, html rendering in prod, jslin

gulp.task('default', ['styles', 'js', 'coffee', 'start', 'livereload', 'watch'], function () {

});

gulp.task('build', ['styles-min', 'html', 'lintjs', 'js', 'lintcoffee', 'coffee'], function () {

});<|endoftext|>


<commit_before>var gulp = require('gulp'),
  sass = require('gulp-sass'),
  sourcemaps = require('gulp-sourcemaps'),
  autoprefixer = require('gulp-autoprefixer');

var config = {
  paths: {
    boneless: {
      src: './scss/boneless.scss',
      dest: './lib'
    }
  },
  plugins: {
    sass: {
      outputStyle: 'nested',
      precision: 10,
      noCache: true,
    },
    autoprefixer: {
      browsers: ['> 1%', 'last 2 versions', 'Firefox ESR', 'Opera 12.1'],
      cascade: false
    }
  }
};

gulp.task('build', function () {
  return gulp.src(config.paths.boneless.src)
    .pipe(sourcemaps.init())
    .pipe(sass({
      outputStyle: config.plugins.sass.outputStyle,
      precision: config.plugins.sass.precision,
      noCache: config.plugins.sass.noCache
    }))
    .pipe(autoprefixer({
      browsers: config.plugins.autoprefixer.browsers,
      cascade: config.plugins.autoprefixer.cascade
    }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(config.paths.boneless.dest));
});
<commit_msg>Add watch task<commit_after>var gulp = require('gulp'),
  sass = require('gulp-sass'),
  sourcemaps = require('gulp-sourcemaps'),
  autoprefixer = require('gulp-autoprefixer');

var config = {
  paths: {
    boneless: {
      src: './scss/boneless.scss',
      dest: './lib',
      watch: './scss/**/**/*.scss'
    }
  },
  plugins: {
    sass: {
      outputStyle: 'nested',
      precision: 10,
      noCache: true,
    },
    autoprefixer: {
      browsers: ['> 1%', 'last 2 versions', 'Firefox ESR', 'Opera 12.1'],
      cascade: false
    }
  }
};

gulp.task('build', function () {
  return gulp.src(config.paths.boneless.src)
    .pipe(sourcemaps.init())
    .pipe(sass({
      outputStyle: config.plugins.sass.outputStyle,
      precision: config.plugins.sass.precision,
      noCache: config.plugins.sass.noCache
    }))
    .pipe(autoprefixer({
      browsers: config.plugins.autoprefixer.browsers,
      cascade: config.plugins.autoprefixer.cascade
    }))
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(config.paths.boneless.dest));
});

gulp.task('watch', function() {
    gulp.watch(config.paths.boneless.watch, ['build']);
});
<|endoftext|>


<commit_before>import React, { Component, PropTypes } from 'react';
import ReactDisqusComments from 'react-disqus-comments';

import Page from '../Page';

import styles from './index.scss';

const setOverflow = (overflow) => {
  const html = document.querySelector('html');
  const body = document.body;

  html.style.overflow = overflow;
  body.style.overflow = overflow;
}

class Post extends Component {
  static propTypes = {
    head: PropTypes.object.isRequired,
  };

  componentDidMount() {
    this.main.focus();
    setOverflow('auto');
  }

  componentWillUnmount() {
    setOverflow('hidden');
  }

  render() {
    const { props } = this;

    // it's up to you to choose what to do with this layout ;)
    const pageDate = props.head.date ? new Date(props.head.date) : null;
    const author = props.head.author;

    return (
       this.main = e}>

          <Page
            {...props}
            header={

                {author},
                <time key={pageDate.toISOString()}>
                  { pageDate.toDateString() }
                </time>

            }
          />
          <ReactDisqusComments
            shortname='makersden-io'
            title={props.head.title}
            identifier={props.head.title.replace(/\s/g, '') + pageDate}
          />

    );
  }
}

export default Post;
<commit_msg>Fix the focus jump in post.<commit_after>import React, { Component, PropTypes } from 'react';
import ReactDisqusComments from 'react-disqus-comments';

import Page from '../Page';

import styles from './index.scss';

const setOverflow = (overflow) => {
  const html = document.querySelector('html');
  const body = document.body;

  html.style.overflow = overflow;
  body.style.overflow = overflow;
}

class Post extends Component {
  static propTypes = {
    head: PropTypes.object.isRequired,
  };

  componentDidMount() {
    setOverflow('auto');
  }

  componentWillUnmount() {
    setOverflow('hidden');
  }

  render() {
    const { props } = this;

    // it's up to you to choose what to do with this layout ;)
    const pageDate = props.head.date ? new Date(props.head.date) : null;
    const author = props.head.author;

    return (
       this.main = e}>

          <Page
            {...props}
            header={

                {author},
                <time key={pageDate.toISOString()}>
                  { pageDate.toDateString() }
                </time>

            }
          />
          <ReactDisqusComments
            shortname='makersden-io'
            title={props.head.title}
            identifier={props.head.title.replace(/\s/g, '') + pageDate}
          />

    );
  }
}

export default Post;
<|endoftext|>


<commit_before>'use strict'

var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var opn = require('opn');

var server = {
  host: 'localhost',
  port: '3000'
};

var basePaths = {
  src: 'client/app/',
  assets: 'client/assets/',
  deploy: 'dist/public/',
  build: 'client/app/'
}

var paths = {
  scripts: {
    src: basePaths.src +  'components/**/*.js',
    build: basePaths.build + 'scripts/',
    dest: basePaths.deploy + 'scripts/'
  },
  html: {
    src: basePaths.src + 'components/**/*.html',
    dest: basePaths.deploy + 'html/'
  },
  styles: {
    src: basePaths.assets + 'stylesheets/*.css',
    dest: basePaths.deploy + 'css/'
  },
  images: {
    src: basePaths.src + 'images/',
    dest: basePaths.deploy + 'images/'
  }
}

gulp.task('css', function() {
  return gulp.src(paths.styles.src)
  //  .pipe($.csslint({
  //    ids: false // allow ids in CSS selectors
  //  }))
  //  .pipe($.csslint.reporter())
    .pipe(gulp.dest(paths.styles.dest));
 });

gulp.task('jshint', function() {
  return gulp.src(paths.scripts.src)
    .pipe($.jshint())
    .pipe($.jshint.reporter($.jshintStylish));
});

gulp.task('traceur', function() {
  var runtimePath = $.traceur.RUNTIME_PATH;
  var filter = $.filter('!traceur-runtime.js');

  return gulp.src([runtimePath, paths.scripts.src])
    .pipe($.order([
      'traceur-runtime.js',
      paths.scripts.src
      ]))
      .pipe(filter)
      .pipe($.traceur({
        sourceMap: true
      }))
      .pipe(filter.restore())
      .pipe($.concat('app.js'))
      .pipe($.insert.append('System.get("grendel" + "");'))
      .pipe(gulp.dest(paths.scripts.build));
});

gulp.task('javascript', function() {
  gulp.src(paths.scripts.build + '**/*.js')
    .pipe($.sourcemaps.init())
    .pipe($.concat('grendelall.js'))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest(paths.scripts.dest));
});

gulp.task('html', function() {
  gulp.src(paths.html.src)
    .pipe(gulp.dest(paths.html.dest));
})

gulp.task('clean', function() {
  return gulp.src([paths.scripts.build, basePaths.deploy], {read: false})
    .pipe($.rimraf());
});

gulp.task('webserver', function() {
  gulp.src(basePaths.deploy)
    .pipe($.webserver({
      host: server.host,
      port: server.port,
      livereload: true,
      directoryListing: true
    }));
});

gulp.task('openbrowser', function() {
  var options = {
    url: 'http://' + server.host + ':' + server.port + 'html/index.html'
  }

  opn(options.url);
});

gulp.task('watch', ['webserver', 'openbrowser'], function() {
    gulp.watch([paths.styles.src], ['csslint']);
    gulp.watch(paths.html.src, ['html']);
    gulp.watch([paths.scripts.src], ['jshint', 'traceur'])
});

gulp.task('default', ['css', 'html', 'jshint', 'traceur', 'javascript', 'webserver', 'watch', 'openbrowser']);
<commit_msg>reorg<commit_after>'use strict'

var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var opn = require('opn');

var server = {
  host: 'localhost',
  port: '3000'
};

var basePaths = {
  src: 'client/app/',
  assets: 'client/assets/',
  deploy: 'dist/public/',
  build: 'client/app/'
}

var paths = {
  scripts: {
    src: basePaths.src +  'components/**/*.js',
    build: basePaths.build + 'scripts/',
    dest: basePaths.deploy + 'scripts/'
  },
  html: {
    src: basePaths.src + 'components/**/*.html',
    dest: basePaths.deploy + 'html/'
  },
  styles: {
    src: basePaths.assets + 'stylesheets/*.css',
    dest: basePaths.deploy + 'css/'
  },
  images: {
    src: basePaths.src + 'images/',
    dest: basePaths.deploy + 'images/'
  }
}

gulp.task('css', function() {
  return gulp.src(paths.styles.src)
  //  .pipe($.csslint({
  //    ids: false // allow ids in CSS selectors
  //  }))
  //  .pipe($.csslint.reporter())
    .pipe(gulp.dest(paths.styles.dest));
 });

gulp.task('jshint', function() {
  return gulp.src(paths.scripts.src)
    .pipe($.jshint())
    .pipe($.jshint.reporter($.jshintStylish));
});

gulp.task('traceur', function() {
  var runtimePath = $.traceur.RUNTIME_PATH;
  var filter = $.filter('!traceur-runtime.js');

  return gulp.src([runtimePath, paths.scripts.src])
    .pipe($.order([
      'traceur-runtime.js',
      paths.scripts.src
      ]))
      .pipe(filter)
      .pipe($.traceur({
        sourceMap: true
      }))
      .pipe(filter.restore())
      .pipe($.concat('app.js'))
      .pipe($.insert.append('System.get("grendel" + "");'))
      .pipe(gulp.dest(paths.scripts.build));
});

gulp.task('javascript', function() {
  gulp.src(paths.scripts.build + '**/*.js')
    .pipe($.sourcemaps.init())
    .pipe($.concat('grendelall.js'))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest(paths.scripts.dest));
});

gulp.task('html', function() {
  gulp.src(paths.html.src)
    .pipe(gulp.dest(paths.html.dest));
})

gulp.task('clean', function() {
  return gulp.src([paths.scripts.build, basePaths.deploy], {read: false})
    .pipe($.rimraf());
});

gulp.task('webserver', function() {
  gulp.src(basePaths.deploy)
    .pipe($.webserver({
      host: server.host,
      port: server.port,
      livereload: true,
      directoryListing: true
    }));
});

gulp.task('openbrowser', function() {
  var options = {
    url: 'http://' + server.host + ':' + server.port + '/index.html'
  }

  opn(options.url);
});

gulp.task('watch', ['webserver', 'openbrowser'], function() {
    gulp.watch([paths.styles.src], ['csslint']);
    gulp.watch(paths.html.src, ['html']);
    gulp.watch([paths.scripts.src], ['jshint', 'traceur'])
});

gulp.task('default', ['css', 'html', 'jshint', 'traceur', 'javascript', 'webserver', 'watch', 'openbrowser']);
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */

'use strict';

const path = require('path');
const gulp = require('gulp');
const gulpif = require('gulp-if');
const gutil = require('gulp-util');
const argv = require('yargs').argv;

// const $ = {
//   useref: require('gulp-useref'),
//   replace: require('gulp-replace')
// }

// Got problems? Try logging 'em
// use -l to activate plylogs
if (argv.l) {
  const logging = require('plylog');
  logging.setVerbose();
}

// !!! IMPORTANT !!! //
// Keep the global.config above any of the gulp-tasks that depend on it
global.config = {
  // Name of your app
  appName: 'app',
  polymerJsonPath: path.join(process.cwd(), 'polymer.json'),
  build: {
    rootDirectory: 'build/pmp',
    bundledDirectory: 'bundled',
    unbundledDirectory: 'unbundled',
    // Accepts either 'bundled', 'unbundled', or 'both'
    // A bundled version will be vulcanized and sharded. An unbundled version
    // will not have its files combined (this is for projects using HTTP/2
    // server push). Using the 'both' option will create two output projects,
    // one for bundled and one for unbundled
    bundleType: 'bundled' // We will only be using a bundled build
  },
  // Path to your service worker, relative to the build root directory
  serviceWorkerPath: 'service-worker.js',
  // Service Worker precache options based on
  // https://github.com/GoogleChrome/sw-precache#options-parameter
  swPrecacheConfig: {
    replacePrefix: '/pmp/',
    navigateFallback: '/index.html'
  },
  sourceCodeDirectory: './pmp'
};

// Change global config if building into eTools
const etoolsBuild = require('./gulp-tasks/etoolsBuild.js');
if (argv._[0] === 'fullBuild') {
  etoolsBuild.config();
}

// Add your own custom gulp tasks to the gulp-tasks directory
// A few sample tasks are provided for you
// A task should return either a WriteableStream or a Promise
const clean = require('./gulp-tasks/clean.js');
const images = require('./gulp-tasks/images.js');         //Any processing on images
const javascript = require('./gulp-tasks/javascript.js'); //Any processing on javascript
const html = require('./gulp-tasks/html.js');             //Any processing on html
const css = require('./gulp-tasks/css.js');               //Any processing on css
const project = require('./gulp-tasks/project.js');
const polylint = require('gulp-polylint');

// Log task end messages
var log = function (message) {
  return function () {
    gutil.log(message);
  }
}

// The source task will split all of your source files into one
// big ReadableStream. Source files are those in src/** as well as anything
// added to the sourceGlobs property of polymer.json.
// Because most HTML Imports contain inline CSS and JS, those inline resources
// will be split out into temporary files. You can use gulpif to filter files
// out of the stream and run them through specific tasks. An example is provided
// which filters all images and runs them through imagemin

function source() {
  return project.splitSource()
  // // Add your own build tasks here!
    //.pipe(gulpif('**/*index*.js', html.productionBasePath())).on('end', log('Replaced Base'))
    .pipe(gulpif('**/*.html', html.lint()))
    .on('end', log('Linted HTML'))
    .pipe(gulpif('**/*.html', html.minify())).on('end', log('Minified HTML'))

    // lint CSS not working correctly. Not seeing temporary css files
    // .pipe(gulpif('**/*.{css,html}', css.lint()))              .on('end', log('Linted CSS'))
    .pipe(gulpif('**/*.{html,css}', css.minify())).on('end', log('Minified CSS'))

    .pipe(gulpif('**/*.js', javascript.lint())).on('end', log('Linted Javascript'))
    .pipe(gulpif('**/*.js', javascript.minify())).on('end', log('Minified Javascript'))

    .pipe(gulpif('**/*.{gif,jpg,svg}', images.minify())).on('end', log('Minified Images'))

    .pipe(project.rejoin()); // Call rejoin when you're finished
}

// The runPolylint task will run each individual source file through polylint
// Checks for polymer specific errors in the html and javascript parts of the
// source code
function runPolylint() {
  return project.getSources()
    .pipe(gulpif('**/*.html', polylint({noRecursion: true})))
    .pipe(polylint.reporter(polylint.reporter.stylishlike));
}

// The dependencies task will split all of your bower_components files into one
// big ReadableStream
// You probably don't need to do anything to your dependencies but it's here in
// case you need it :)
function dependencies() {
  return project.splitDependencies()
    .pipe(project.rejoin());
}

// Clean the build directory, split all source and dependency files into streams
// and process them, and output bundled and unbundled versions of the project
// with their own service workers

// By default: just lint and minify
// No building into eTools
// hint: good for testing build efficiency
gulp.task('default', gulp.series([
  clean.build,
  project.merge(source, dependencies),
  project.serviceWorker
]));

// Run polylint,
// split all source and dependency files into streams and lint them individually uning polylint
gulp.task('lint', gulp.series([
  // because 'source' splits the sources and lints them individually, we need to clean
  // the build directory
  runPolylint,
  clean.build,
  source
]));

// DO NOT RUN
// Fully builds project
// Minifying, linting, and building into eTools
// TODO: This task is on hold
gulp.task('fullBuild', gulp.series([
  clean.fullBuild,
  project.merge(source, dependencies),
  project.serviceWorker,
  etoolsBuild.buildTemplate
]));
<commit_msg>feature(misc-updates): - Removed clean step from gulp lint task<commit_after>/**
 * @license
 * Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
 * This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
 * The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
 * The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
 * Code distributed by Google as part of the polymer project is also
 * subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
 */

'use strict';

const path = require('path');
const gulp = require('gulp');
const gulpif = require('gulp-if');
const gutil = require('gulp-util');
const argv = require('yargs').argv;

// const $ = {
//   useref: require('gulp-useref'),
//   replace: require('gulp-replace')
// }

// Got problems? Try logging 'em
// use -l to activate plylogs
if (argv.l) {
  const logging = require('plylog');
  logging.setVerbose();
}

// !!! IMPORTANT !!! //
// Keep the global.config above any of the gulp-tasks that depend on it
global.config = {
  // Name of your app
  appName: 'app',
  polymerJsonPath: path.join(process.cwd(), 'polymer.json'),
  build: {
    rootDirectory: 'build/pmp',
    bundledDirectory: 'bundled',
    unbundledDirectory: 'unbundled',
    // Accepts either 'bundled', 'unbundled', or 'both'
    // A bundled version will be vulcanized and sharded. An unbundled version
    // will not have its files combined (this is for projects using HTTP/2
    // server push). Using the 'both' option will create two output projects,
    // one for bundled and one for unbundled
    bundleType: 'bundled' // We will only be using a bundled build
  },
  // Path to your service worker, relative to the build root directory
  serviceWorkerPath: 'service-worker.js',
  // Service Worker precache options based on
  // https://github.com/GoogleChrome/sw-precache#options-parameter
  swPrecacheConfig: {
    replacePrefix: '/pmp/',
    navigateFallback: '/index.html'
  },
  sourceCodeDirectory: './pmp'
};

// Change global config if building into eTools
const etoolsBuild = require('./gulp-tasks/etoolsBuild.js');
if (argv._[0] === 'fullBuild') {
  etoolsBuild.config();
}

// Add your own custom gulp tasks to the gulp-tasks directory
// A few sample tasks are provided for you
// A task should return either a WriteableStream or a Promise
const clean = require('./gulp-tasks/clean.js');
const images = require('./gulp-tasks/images.js');         //Any processing on images
const javascript = require('./gulp-tasks/javascript.js'); //Any processing on javascript
const html = require('./gulp-tasks/html.js');             //Any processing on html
const css = require('./gulp-tasks/css.js');               //Any processing on css
const project = require('./gulp-tasks/project.js');
const polylint = require('gulp-polylint');

// Log task end messages
var log = function (message) {
  return function () {
    gutil.log(message);
  }
}

// The source task will split all of your source files into one
// big ReadableStream. Source files are those in src/** as well as anything
// added to the sourceGlobs property of polymer.json.
// Because most HTML Imports contain inline CSS and JS, those inline resources
// will be split out into temporary files. You can use gulpif to filter files
// out of the stream and run them through specific tasks. An example is provided
// which filters all images and runs them through imagemin

function source() {
  return project.splitSource()
  // // Add your own build tasks here!
    //.pipe(gulpif('**/*index*.js', html.productionBasePath())).on('end', log('Replaced Base'))
    .pipe(gulpif('**/*.html', html.lint()))
    .on('end', log('Linted HTML'))
    .pipe(gulpif('**/*.html', html.minify())).on('end', log('Minified HTML'))

    // lint CSS not working correctly. Not seeing temporary css files
    // .pipe(gulpif('**/*.{css,html}', css.lint()))              .on('end', log('Linted CSS'))
    .pipe(gulpif('**/*.{html,css}', css.minify())).on('end', log('Minified CSS'))

    .pipe(gulpif('**/*.js', javascript.lint())).on('end', log('Linted Javascript'))
    .pipe(gulpif('**/*.js', javascript.minify())).on('end', log('Minified Javascript'))

    .pipe(gulpif('**/*.{gif,jpg,svg}', images.minify())).on('end', log('Minified Images'))

    .pipe(project.rejoin()); // Call rejoin when you're finished
}

// The runPolylint task will run each individual source file through polylint
// Checks for polymer specific errors in the html and javascript parts of the
// source code
function runPolylint() {
  return project.getSources()
    .pipe(gulpif('**/*.html', polylint({noRecursion: true})))
    .pipe(polylint.reporter(polylint.reporter.stylishlike));
}

// The dependencies task will split all of your bower_components files into one
// big ReadableStream
// You probably don't need to do anything to your dependencies but it's here in
// case you need it :)
function dependencies() {
  return project.splitDependencies()
    .pipe(project.rejoin());
}

// Clean the build directory, split all source and dependency files into streams
// and process them, and output bundled and unbundled versions of the project
// with their own service workers

// By default: just lint and minify
// No building into eTools
// hint: good for testing build efficiency
gulp.task('default', gulp.series([
  clean.build,
  project.merge(source, dependencies),
  project.serviceWorker
]));

// Run polylint,
// split all source and dependency files into streams and lint them individually uning polylint
gulp.task('lint', gulp.series([
  runPolylint,
  source
]));

// DO NOT RUN
// Fully builds project
// Minifying, linting, and building into eTools
// TODO: This task is on hold
gulp.task('fullBuild', gulp.series([
  clean.fullBuild,
  project.merge(source, dependencies),
  project.serviceWorker,
  etoolsBuild.buildTemplate
]));
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var tslint = require('gulp-tslint');
var childProcess = require('child_process');
var sourcemaps = require('gulp-sourcemaps');
var del = require('del');
var karma = require('karma').server;
var coveralls = require('gulp-coveralls');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var wrap = require('gulp-wrap-umd');
var runSequence = require('run-sequence');
var gutil = require('gulp-util');
var notifier = require('node-notifier');
var path = require('path');

var tsConfig = require('./tsconfig.json');
var tslintConfig = require('./tslint.json');

var spawn = childProcess.spawn;
var tscPath = path.join(__dirname, 'node_modules', 'typescript', 'bin', 'tsc.js');
var mainFileName = 'prouter';
var mainFile = 'src/' + mainFileName + '.js';

var tsArr = [tscPath];

for (var prop in tsConfig.compilerOptions) {
    tsArr.push('--' + prop);
    var val = tsConfig.compilerOptions[prop];
    if (Object.prototype.toString.call(val) === '[object String]') {
        tsArr.push(val);
    }
}

var _runTask = gulp.Gulp.prototype._runTask;

gulp.Gulp.prototype._runTask = function (task) {
    this.currentTask = task;
    _runTask.call(this, task);
};

function reportError(error, taskName) {
    if (this.currentTask) {
        taskName = this.currentTask.name;
    }
    var title = "Gulp task failed '" + taskName + "'";
    var message = error.toString();
    var report = gutil.colors.red.bold(title) + gutil.colors.red(': ' + message);
    console.error(report);
    notifier.notify({
        title: title,
        message: message,
        sound: true
    }, function (err, response) {
      process.exit();
    });
    if (this.emit) {
        this.emit('end');
    }
}

function compileTs(srcFiles, callback) {
    var self = this;
    var args = tsArr.concat(srcFiles);
    var tsc = spawn('node', args);
    tsc.stdout.on('data', function(data) {
        reportError.call(self, data);
    });
    tsc.stderr.on('data', function(data) {
        reportError.call(self, data);
    });
    tsc.on('close', function(code) {
        callback(code);
    });
}

/*** Tasks ***/

/**
 * Run tests once and exit.
 */
gulp.task('test', function (done) {
    karma.start({
        configFile: __dirname + '/karma.conf.js',
        action: 'run',
        autoWatch: false,
        singleRun: true
    }, done);
});

gulp.task('test:watch', ['build'], function () {
    gulp.watch([mainFile, 'test/*.spec.js'], ['build']);
});

gulp.task('coveralls', ['test'], function () {
    return gulp.src('build/reports/coverage/**/lcov.info')
        .pipe(coveralls());
});

gulp.task('clean', function (done) {
    del(['dist/**/*', 'src/*', '!src/*.ts'], done);
});

gulp.task('script', function () {
    return gulp.src(mainFile)
        .pipe(sourcemaps.init({
        loadMaps: true
    }))
        .pipe(wrap({ namespace: 'Router', exports: 'Router' }))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('dist'));
});

gulp.task('script:minify', ['script'], function () {
    return gulp.src('dist/' + mainFileName + '.js')
        .pipe(uglify())
        .on('error', reportError)
        .pipe(rename(mainFileName + '.min.js'))
        .pipe(gulp.dest('dist'));
});

gulp.task('lint', function () {
    return gulp.src(tsConfig.filesGlob)
        .pipe(tslint({ configuration: tslintConfig }))
        .pipe(tslint.report('full'));
});

gulp.task('compile', function (done) {
    compileTs.call(this, 'src/' + mainFileName + '.ts', done);
});

gulp.task('build', function (done) {
    runSequence(['lint', 'compile'], ['script:minify', 'test'], done);
});

gulp.task('dev', ['build'], function () {
    gulp.watch(['src/' + mainFileName + '.ts'], ['build']);
});

gulp.task('default', ['build']);
<commit_msg>Improved gulpfile.js<commit_after>'use strict';

var gulp = require('gulp');
var tslint = require('gulp-tslint');
var childProcess = require('child_process');
var sourcemaps = require('gulp-sourcemaps');
var del = require('del');
var karma = require('karma').server;
var coveralls = require('gulp-coveralls');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var wrap = require('gulp-wrap-umd');
var runSequence = require('run-sequence');
var gutil = require('gulp-util');
var notifier = require('node-notifier');
var path = require('path');

var tsConfig = require('./tsconfig.json');
var tslintConfig = require('./tslint.json');

var spawn = childProcess.spawn;
var tscPath = path.join(__dirname, 'node_modules', 'typescript', 'bin', 'tsc.js');
var mainFileName = 'prouter';
var mainFile = 'src/' + mainFileName + '.js';

var tsArr = [tscPath];

for (var prop in tsConfig.compilerOptions) {
    tsArr.push('--' + prop);
    var val = tsConfig.compilerOptions[prop];
    if (Object.prototype.toString.call(val) === '[object String]') {
        tsArr.push(val);
    }
}

var _runTask = gulp.Gulp.prototype._runTask;

gulp.Gulp.prototype._runTask = function (task) {
    this.currentTask = task;
    _runTask.call(this, task);
};

function reportError(error, taskName) {
    if (this.currentTask) {
        taskName = this.currentTask.name;
    }
    var title = "Gulp task failed '" + taskName + "'";
    var message = error.toString();
    var report = gutil.colors.red.bold(title) + gutil.colors.red(': ' + message);
    console.error(report);
    notifier.notify({
        title: title,
        message: message,
        sound: true
    });
    if (this.emit) {
        this.emit('end');
    }
}

function compileTs(srcFiles, callback) {
    var self = this;
    var args = tsArr.concat(srcFiles);
    var tsc = spawn('node', args);
    tsc.stdout.on('data', function(data) {
        reportError.call(self, data);
    });
    tsc.stderr.on('data', function(data) {
        reportError.call(self, data);
    });
    tsc.on('close', function(code) {
        callback(code);
    });
}

/*** Tasks ***/

/**
 * Run tests once and exit.
 */
gulp.task('test', function (done) {
    karma.start({
        configFile: __dirname + '/karma.conf.js',
        action: 'run',
        autoWatch: false,
        singleRun: true
    }, done);
});

gulp.task('test:watch', ['build'], function () {
    gulp.watch([mainFile, 'test/*.spec.js'], ['build']);
});

gulp.task('coveralls', ['test'], function () {
    return gulp.src('build/reports/coverage/**/lcov.info')
        .pipe(coveralls());
});

gulp.task('clean', function (done) {
    del(['dist/**/*', 'src/*', '!src/*.ts'], done);
});

gulp.task('script', function () {
    return gulp.src(mainFile)
        .pipe(sourcemaps.init({
        loadMaps: true
    }))
        .pipe(wrap({ namespace: 'Router', exports: 'Router' }))
        .pipe(sourcemaps.write('.'))
        .pipe(gulp.dest('dist'));
});

gulp.task('script:minify', ['script'], function () {
    return gulp.src('dist/' + mainFileName + '.js')
        .pipe(uglify())
        .on('error', reportError)
        .pipe(rename(mainFileName + '.min.js'))
        .pipe(gulp.dest('dist'));
});

gulp.task('lint', function () {
    return gulp.src(tsConfig.filesGlob)
        .pipe(tslint({ configuration: tslintConfig }))
        .pipe(tslint.report('full'));
});

gulp.task('compile', function (done) {
    compileTs.call(this, 'src/' + mainFileName + '.ts', done);
});

gulp.task('build', function (done) {
    runSequence(['lint', 'compile'], ['script:minify', 'test'], done);
});

gulp.task('dev', ['build'], function () {
    gulp.watch(['src/' + mainFileName + '.ts'], ['build']);
});

gulp.task('default', ['build']);
<|endoftext|>


<commit_before>/*global -$ */
'use strict';
// generated on 2015-06-05 using generator-gulp-webapp 0.3.0
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var del = require('del');
var mainBowerFiles = require('main-bower-files');
var fs = require('fs');
var semver = require('semver');
var pkg = (function () {
  return JSON.parse(fs.readFileSync('./package.json', 'utf8'));
})();

gulp.task('styles', function () {
  return gulp.src('app/styles/main.scss')
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      outputStyle: 'nested', // libsass doesn't support expanded yet
      precision: 10,
      includePaths: ['.'],
      onError: console.error.bind(console, 'Sass error:')
    }))
    .pipe($.postcss([
      require('autoprefixer-core')({browsers: ['last 4 versions']})
    ]))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/styles'))
    .pipe(reload({stream: true}));
});

gulp.task('jshint', function () {
  return gulp.src('app/scripts/**/*.js')
    .pipe(reload({stream: true, once: true}))
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

gulp.task('html', ['styles'], function () {
  var assets = $.useref.assets({searchPath: ['.tmp', 'app', '.']});

  return gulp.src('app/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.csso()))
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.if('*.html', $.minifyHtml({conditionals: true, loose: true})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true,
      // don't remove IDs from SVGs, they are often used
      // as hooks for embedding and styling
      svgoPlugins: [{cleanupIDs: false}]
    })))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('fonts', function () {
  return gulp.src(mainBowerFiles({
    filter: '**/*.{eot,svg,ttf,woff,woff2}',
    debugging: false
  }).concat('app/fonts/**/*'))
    .pipe(gulp.dest('.tmp/fonts'))
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('extras', function () {
  return gulp.src([
    'app/*.*',
    'app/CNAME',
    '!app/*.html'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});

gulp.task('clean', del.bind(null, ['.tmp', 'dist']));

gulp.task('serve', ['styles', 'fonts'], function () {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  // watch for changes
  gulp.watch([
    'app/*.html',
    'app/scripts/**/*.js',
    'app/images/**/*',
    '.tmp/fonts/**/*'
  ]).on('change', reload);

  gulp.watch('app/styles/**/*.scss', ['styles']);
  gulp.watch('app/fonts/**/*', ['fonts']);
  gulp.watch('bower.json', ['wiredep', 'fonts']);
});

// inject bower components
gulp.task('wiredep', function () {
  var wiredep = require('wiredep').stream;

  gulp.src('app/styles/*.scss')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)+/
    }))
    .pipe(gulp.dest('app/styles'));

  gulp.src('app/*.html')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)*\.\./
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('build', ['jshint', 'html', 'images', 'fonts', 'extras'], function () {
  return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});

gulp.task('default', ['clean'], function () {
  gulp.start('build');
});

gulp.task('gitSemverCommit', function () {

  return gulp.src(['app/manifest.json', 'bower.json', 'package.json'])
    .pipe($.exec('git commit <%= file.path %> -m "Update semver to v'+pkg.version+'"'));
});

gulp.task('gitCommitDist', function () {

  return gulp.src('./dist')
    .pipe($.exec('git add <%= file.path %> && git commit <%= file.path %> -m "Update dist folder to v'+pkg.version+'"'));
});

gulp.task('gitPush', function () {

  $.exec('git push origin master');
});

// bump versions on package/bower/manifest
gulp.task('bump', function () {

  // increment version
  var newVer = semver.inc(pkg.version, 'patch');

  pkg.version = newVer;

  // uses gulp-filter
  var manifestFilter = $.filter(['manifest.json']);
  var regularJsons = $.filter(['*', '!manifest.json']);

  return gulp.src(['./bower.json', './package.json', './app/manifest.json'])
    .pipe($.bump({
      version: newVer
    }))
    .pipe(manifestFilter)
    .pipe(gulp.dest('./app'))
    .pipe(manifestFilter.restore())
    .pipe(regularJsons)
    .pipe(gulp.dest('./'));
});

gulp.task('upstream', ['gitSemverCommit', 'gitCommitDist'], function () {

  return gulp.src('./dist')
    .pipe($.exec('git subtree push --prefix=dist upstream master', function(){

      // gutil.log('Resetting ./dist temporary commit');

      $.exec('git push origin master', function () {

        gutil.log('Resetting ./dist temporary commit');
        $.exec('git reset HEAD^');
      });
    }))
    .pipe($.clean());
});

gulp.task('deploy', ['default', 'bump'], function () {
  gulp.start('upstream');
});
<commit_msg>last exp<commit_after>/*global -$ */
'use strict';
// generated on 2015-06-05 using generator-gulp-webapp 0.3.0
var gulp = require('gulp');
var $ = require('gulp-load-plugins')();
var browserSync = require('browser-sync');
var reload = browserSync.reload;
var del = require('del');
var mainBowerFiles = require('main-bower-files');
var fs = require('fs');
var semver = require('semver');
var pkg = (function () {
  return JSON.parse(fs.readFileSync('./package.json', 'utf8'));
})();

gulp.task('styles', function () {
  return gulp.src('app/styles/main.scss')
    .pipe($.sourcemaps.init())
    .pipe($.sass({
      outputStyle: 'nested', // libsass doesn't support expanded yet
      precision: 10,
      includePaths: ['.'],
      onError: console.error.bind(console, 'Sass error:')
    }))
    .pipe($.postcss([
      require('autoprefixer-core')({browsers: ['last 4 versions']})
    ]))
    .pipe($.sourcemaps.write())
    .pipe(gulp.dest('.tmp/styles'))
    .pipe(reload({stream: true}));
});

gulp.task('jshint', function () {
  return gulp.src('app/scripts/**/*.js')
    .pipe(reload({stream: true, once: true}))
    .pipe($.jshint())
    .pipe($.jshint.reporter('jshint-stylish'))
    .pipe($.if(!browserSync.active, $.jshint.reporter('fail')));
});

gulp.task('html', ['styles'], function () {
  var assets = $.useref.assets({searchPath: ['.tmp', 'app', '.']});

  return gulp.src('app/*.html')
    .pipe(assets)
    .pipe($.if('*.js', $.uglify()))
    .pipe($.if('*.css', $.csso()))
    .pipe(assets.restore())
    .pipe($.useref())
    .pipe($.if('*.html', $.minifyHtml({conditionals: true, loose: true})))
    .pipe(gulp.dest('dist'));
});

gulp.task('images', function () {
  return gulp.src('app/images/**/*')
    .pipe($.cache($.imagemin({
      progressive: true,
      interlaced: true,
      // don't remove IDs from SVGs, they are often used
      // as hooks for embedding and styling
      svgoPlugins: [{cleanupIDs: false}]
    })))
    .pipe(gulp.dest('dist/images'));
});

gulp.task('fonts', function () {
  return gulp.src(mainBowerFiles({
    filter: '**/*.{eot,svg,ttf,woff,woff2}',
    debugging: false
  }).concat('app/fonts/**/*'))
    .pipe(gulp.dest('.tmp/fonts'))
    .pipe(gulp.dest('dist/fonts'));
});

gulp.task('extras', function () {
  return gulp.src([
    'app/*.*',
    'app/CNAME',
    '!app/*.html'
  ], {
    dot: true
  }).pipe(gulp.dest('dist'));
});

gulp.task('clean', del.bind(null, ['.tmp', 'dist']));

gulp.task('serve', ['styles', 'fonts'], function () {
  browserSync({
    notify: false,
    port: 9000,
    server: {
      baseDir: ['.tmp', 'app'],
      routes: {
        '/bower_components': 'bower_components'
      }
    }
  });

  // watch for changes
  gulp.watch([
    'app/*.html',
    'app/scripts/**/*.js',
    'app/images/**/*',
    '.tmp/fonts/**/*'
  ]).on('change', reload);

  gulp.watch('app/styles/**/*.scss', ['styles']);
  gulp.watch('app/fonts/**/*', ['fonts']);
  gulp.watch('bower.json', ['wiredep', 'fonts']);
});

// inject bower components
gulp.task('wiredep', function () {
  var wiredep = require('wiredep').stream;

  gulp.src('app/styles/*.scss')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)+/
    }))
    .pipe(gulp.dest('app/styles'));

  gulp.src('app/*.html')
    .pipe(wiredep({
      ignorePath: /^(\.\.\/)*\.\./
    }))
    .pipe(gulp.dest('app'));
});

gulp.task('build', ['jshint', 'html', 'images', 'fonts', 'extras'], function () {
  return gulp.src('dist/**/*').pipe($.size({title: 'build', gzip: true}));
});

gulp.task('default', ['clean'], function () {
  gulp.start('build');
});

gulp.task('gitSemverCommit', ['bump'], function () {

  return gulp.src(['app/manifest.json', 'bower.json', 'package.json'])
    .pipe($.exec('git commit <%= file.path %> -m "Update semver to v'+pkg.version+'"'));
});

gulp.task('gitCommitDist', ['build'], function () {

  return gulp.src('./dist')
    .pipe($.exec('git add <%= file.path %> && git commit <%= file.path %> -m "Update dist folder to v'+pkg.version+'"'));
});

gulp.task('gitPush', function () {

  $.exec('git push origin master');
});

// bump versions on package/bower/manifest
gulp.task('bump', function () {

  // increment version
  var newVer = semver.inc(pkg.version, 'patch');

  pkg.version = newVer;

  // uses gulp-filter
  var manifestFilter = $.filter(['manifest.json']);
  var regularJsons = $.filter(['*', '!manifest.json']);

  return gulp.src(['./bower.json', './package.json', './app/manifest.json'])
    .pipe($.bump({
      version: newVer
    }))
    .pipe(manifestFilter)
    .pipe(gulp.dest('./app'))
    .pipe(manifestFilter.restore())
    .pipe(regularJsons)
    .pipe(gulp.dest('./'));
});

gulp.task('upstream', ['gitCommitDist'], function () {

  return gulp.src('./dist')
    .pipe($.exec('git subtree push --prefix=dist upstream master', function(){

      // gutil.log('Resetting ./dist temporary commit');

      $.exec('git push origin master', function () {

        gutil.log('Resetting ./dist temporary commit');
        $.exec('git reset HEAD^');
      });
    }))
    .pipe($.clean());
});

gulp.task('deploy', ['clean', 'gitSemverCommit'], function () {
  gulp.start('upstream');
});
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');
var del = require('del');

var path = require('path');

// Load plugins
var $ = require('gulp-load-plugins')();
var browserify = require('browserify');
var watchify = require('watchify');
var source = require('vinyl-source-stream'),

    sourceFile = './app/scripts/app.js',

    destFolder = './dist/scripts',
    destFileName = 'app.js';

// Styles
gulp.task('styles', function () {
    return gulp.src('app/styles/main.scss')
        .pipe($.rubySass({
            style: 'expanded',
            precision: 10,
            loadPath: ['app/bower_components']
        }))
        .pipe($.autoprefixer('last 1 version'))
        .pipe(gulp.dest('dist/styles'))
        .pipe($.size());
});

// Scripts
gulp.task('scripts', function () {
    var bundler =browserify({
        entries: [sourceFile],
        insertGlobals: true,
        cache: {},
        packageCache: {},
        fullPaths: true
    });

    return bundler.bundle()
      // log errors if they happen
      .on('error', $.util.log.bind($.util, 'Browserify Error'))
      .pipe(source(destFileName))
      .pipe(gulp.dest(destFolder));

});

// Scripts
gulp.task('scripts_debug', function () {
  var bundler = watchify(browserify({
    entries: [sourceFile],
    insertGlobals: true,
    cache: {},
    packageCache: {},
    fullPaths: true,
    debug: true
  }));

  function rebundle() {
    return bundler.bundle()
      // log errors if they happen
      .on('error', $.util.log.bind($.util, 'Browserify Error'))
      .pipe(source(destFileName))
      .pipe(gulp.dest(destFolder));
  }

  bundler.on('update', rebundle);

  return rebundle();
});

gulp.task('jade', function () {
    return gulp.src('app/template/*.jade')
        .pipe($.jade({ pretty: true }))
        .pipe(gulp.dest('dist'));
});

// HTML
gulp.task('html', function () {
    return gulp.src('app/*.html')
        .pipe($.useref())
        .pipe(gulp.dest('dist'))
        .pipe($.size());
});

// Images
gulp.task('images', function () {
    return gulp.src('app/images/**/*')
        .pipe($.cache($.imagemin({
            optimizationLevel: 3,
            progressive: true,
            interlaced: true
        })))
        .pipe(gulp.dest('dist/images'))
        .pipe($.size());
});

gulp.task('jest', function () {
    var nodeModules = path.resolve('./node_modules');
    return gulp.src('app/scripts/**/__tests__')
        .pipe($.jest({
            scriptPreprocessor: nodeModules + '/gulp-jest/preprocessor.js',
            unmockedModulePathPatterns: [nodeModules + '/react']
        }));
});

// Clean
gulp.task('clean', function (cb) {
    cb(del.sync(['dist/styles', 'dist/scripts', 'dist/images']));
});

// Bundle
gulp.task('bundle', ['styles', 'scripts', 'bower', 'worker'], function(){
    return gulp.src('./app/*.html')
               .pipe($.useref.assets())
               .pipe($.useref.restore())
               .pipe($.useref())
               .pipe(gulp.dest('dist'));
});

// Bundle
gulp.task('bundle_debug', ['styles', 'scripts_debug', 'bower', 'worker'], function(){
  return gulp.src('./app/*.html')
    .pipe($.useref.assets())
    .pipe($.useref.restore())
    .pipe($.useref())
    .pipe(gulp.dest('dist'));
});

// Webserver
gulp.task('serve', function () {
    gulp.src('./dist')
        .pipe($.webserver({
            port: 9000
        }));
});

// Bower helper
gulp.task('bower', function() {
    gulp.src('app/bower_components/**/*.js', {base: 'app/bower_components'})
        .pipe(gulp.dest('dist/bower_components/'));

});

gulp.task('worker', function() {
  gulp.src('app/scripts/worker/**/*.js', {base: 'app/scripts/worker'})
    .pipe(gulp.dest('dist/worker'));
});

gulp.task('json', function() {
    gulp.src('app/scripts/json/**/*.json', {base: 'app/scripts'})
        .pipe(gulp.dest('dist/scripts/'));
});

// Robots.txt and favicon.ico
gulp.task('extras', function () {
    return gulp.src(['app/*.txt', 'app/*.ico'])
        .pipe(gulp.dest('dist/'))
        .pipe($.size());
});

// Watch
gulp.task('watch', ['html', 'bundle_debug', 'serve'], function () {

    // Watch .json files
    gulp.watch('app/scripts/**/*.json', ['json']);

    // Watch .html files
    gulp.watch('app/*.html', ['html']);

    // Watch .scss files
    gulp.watch('app/styles/**/*.scss', ['styles']);

    // Watch .jade files
    gulp.watch('app/template/**/*.jade', ['jade', 'html']);

    // Watch image files
    gulp.watch('app/images/**/*', ['images']);
});

// Build
gulp.task('build', ['html', 'bundle', 'images', 'extras']);

// Default task
gulp.task('default', ['clean', 'build', 'jest' ]);
<commit_msg>fix watch images<commit_after>'use strict';

var gulp = require('gulp');
var del = require('del');

var path = require('path');

// Load plugins
var $ = require('gulp-load-plugins')();
var browserify = require('browserify');
var watchify = require('watchify');
var source = require('vinyl-source-stream'),

    sourceFile = './app/scripts/app.js',

    destFolder = './dist/scripts',
    destFileName = 'app.js';

// Styles
gulp.task('styles', function () {
    return gulp.src('app/styles/main.scss')
        .pipe($.rubySass({
            style: 'expanded',
            precision: 10,
            loadPath: ['app/bower_components']
        }))
        .pipe($.autoprefixer('last 1 version'))
        .pipe(gulp.dest('dist/styles'))
        .pipe($.size());
});

// Scripts
gulp.task('scripts', function () {
    var bundler =browserify({
        entries: [sourceFile],
        insertGlobals: true,
        cache: {},
        packageCache: {},
        fullPaths: true
    });

    return bundler.bundle()
      // log errors if they happen
      .on('error', $.util.log.bind($.util, 'Browserify Error'))
      .pipe(source(destFileName))
      .pipe(gulp.dest(destFolder));

});

// Scripts
gulp.task('scripts_debug', function () {
  var bundler = watchify(browserify({
    entries: [sourceFile],
    insertGlobals: true,
    cache: {},
    packageCache: {},
    fullPaths: true,
    debug: true
  }));

  function rebundle() {
    return bundler.bundle()
      // log errors if they happen
      .on('error', $.util.log.bind($.util, 'Browserify Error'))
      .pipe(source(destFileName))
      .pipe(gulp.dest(destFolder));
  }

  bundler.on('update', rebundle);

  return rebundle();
});

gulp.task('jade', function () {
    return gulp.src('app/template/*.jade')
        .pipe($.jade({ pretty: true }))
        .pipe(gulp.dest('dist'));
});

// HTML
gulp.task('html', function () {
    return gulp.src('app/*.html')
        .pipe($.useref())
        .pipe(gulp.dest('dist'))
        .pipe($.size());
});

// Images
gulp.task('images', function () {
    return gulp.src('app/images/**/*')
        .pipe($.cache($.imagemin({
            optimizationLevel: 3,
            progressive: true,
            interlaced: true
        })))
        .pipe(gulp.dest('dist/images'))
        .pipe($.size());
});

gulp.task('jest', function () {
    var nodeModules = path.resolve('./node_modules');
    return gulp.src('app/scripts/**/__tests__')
        .pipe($.jest({
            scriptPreprocessor: nodeModules + '/gulp-jest/preprocessor.js',
            unmockedModulePathPatterns: [nodeModules + '/react']
        }));
});

// Clean
gulp.task('clean', function (cb) {
    cb(del.sync(['dist/styles', 'dist/scripts', 'dist/images']));
});

// Bundle
gulp.task('bundle', ['styles', 'scripts', 'bower', 'worker'], function(){
    return gulp.src('./app/*.html')
               .pipe($.useref.assets())
               .pipe($.useref.restore())
               .pipe($.useref())
               .pipe(gulp.dest('dist'));
});

// Bundle
gulp.task('bundle_debug', ['styles', 'scripts_debug', 'bower', 'worker'], function(){
  return gulp.src('./app/*.html')
    .pipe($.useref.assets())
    .pipe($.useref.restore())
    .pipe($.useref())
    .pipe(gulp.dest('dist'));
});

// Webserver
gulp.task('serve', function () {
    gulp.src('./dist')
        .pipe($.webserver({
            port: 9000
        }));
});

// Bower helper
gulp.task('bower', function() {
    gulp.src('app/bower_components/**/*.js', {base: 'app/bower_components'})
        .pipe(gulp.dest('dist/bower_components/'));

});

gulp.task('worker', function() {
  gulp.src('app/scripts/worker/**/*.js', {base: 'app/scripts/worker'})
    .pipe(gulp.dest('dist/worker'));
});

gulp.task('json', function() {
    gulp.src('app/scripts/json/**/*.json', {base: 'app/scripts'})
        .pipe(gulp.dest('dist/scripts/'));
});

// Robots.txt and favicon.ico
gulp.task('extras', function () {
    return gulp.src(['app/*.txt', 'app/*.ico'])
        .pipe(gulp.dest('dist/'))
        .pipe($.size());
});

// Watch
gulp.task('watch', ['html', 'bundle_debug', 'images', 'serve'], function () {

    // Watch .json files
    gulp.watch('app/scripts/**/*.json', ['json']);

    // Watch .html files
    gulp.watch('app/*.html', ['html']);

    // Watch .scss files
    gulp.watch('app/styles/**/*.scss', ['styles']);

    // Watch .jade files
    gulp.watch('app/template/**/*.jade', ['jade', 'html']);

    // Watch image files
    gulp.watch('app/images/**/*', ['images']);
});

// Build
gulp.task('build', ['html', 'bundle', 'images', 'extras']);

// Default task
gulp.task('default', ['clean', 'build', 'jest' ]);
<|endoftext|>


<commit_before>var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();

var buffer = require('vinyl-buffer');
var del = require('del');
var merge = require('merge-stream');
var path = require('path');
var runSequence = require('run-sequence');

const SRC = './src';
const DEST = './dist';
const PACKAGES = './modules';

function sass()
{
    var sass = gulp.src(SRC + '/assets/scss/totem.scss')
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.sassGlob({
        ignorePaths: [
            '**/__*.scss'
        ]
    }))
    .pipe(plugins.sass().on('error', plugins.sass.logError))
    .pipe(plugins.sourcemaps.write('./'))
    .pipe(gulp.dest(DEST + '/assets/css'));

    return sass.pipe(plugins.connect.reload());
}

function spritesmith()
{
    var spritesmith = gulp.src(SRC + '/assets/img/layout/sprite/**.png')
    .pipe(plugins.plumber())
    .pipe(plugins.spritesmith({
        padding: 4,
        imgName: 'sprite.png',
        cssName: 'totem.sprite.css',
        cssTemplate: SRC + '/assets/img/layout/sprite/config.handlebars',
        cssHandlebarsHelpers : {
            outputSprite : function(image)
            {
                return '/assets/img/layout/sprite.png';
            },
            divideRetina : function(value) {
                return parseInt(value) / 2;
            }
        }
    }));

    var img = spritesmith.img
    .pipe(buffer())
    .pipe(gulp.dest(DEST + '/assets/img/layout/'));

    var css = spritesmith.css
    .pipe(gulp.dest(DEST + '/assets/css/'));

    return merge(img, css).pipe(plugins.connect.reload());
}

gulp.task('sass', function() {
   return sass();
});

gulp.task('spritesmith', function() {
   return spritesmith();
});

gulp.task('stylesheets', function(callback) {
    runSequence(
        'sass',
        'spritesmith',
        callback
    );
});

gulp.task('default', function(callback) {
    return;
});<commit_msg>Clean task<commit_after>var gulp = require('gulp');
var plugins = require('gulp-load-plugins')();

var buffer = require('vinyl-buffer');
var del = require('del');
var merge = require('merge-stream');
var path = require('path');
var runSequence = require('run-sequence');

const SRC = './src';
const DEST = './dist';
const PACKAGES = './modules';
function clean()
{
    return del([DEST]);
}

function sass()
{
    var sass = gulp.src(SRC + '/assets/scss/totem.scss')
    .pipe(plugins.sourcemaps.init())
    .pipe(plugins.sassGlob({
        ignorePaths: [
            '**/__*.scss'
        ]
    }))
    .pipe(plugins.sass().on('error', plugins.sass.logError))
    .pipe(plugins.sourcemaps.write('./'))
    .pipe(gulp.dest(DEST + '/assets/css'));

    return sass.pipe(plugins.connect.reload());
}

function spritesmith()
{
    var spritesmith = gulp.src(SRC + '/assets/img/layout/sprite/**.png')
    .pipe(plugins.plumber())
    .pipe(plugins.spritesmith({
        padding: 4,
        imgName: 'sprite.png',
        cssName: 'totem.sprite.css',
        cssTemplate: SRC + '/assets/img/layout/sprite/config.handlebars',
        cssHandlebarsHelpers : {
            outputSprite : function(image)
            {
                return '/assets/img/layout/sprite.png';
            },
            divideRetina : function(value) {
                return parseInt(value) / 2;
            }
        }
    }));

    var img = spritesmith.img
    .pipe(buffer())
    .pipe(gulp.dest(DEST + '/assets/img/layout/'));

    var css = spritesmith.css
    .pipe(gulp.dest(DEST + '/assets/css/'));

    return merge(img, css).pipe(plugins.connect.reload());
}

gulp.task('sass', function() {
   return sass();
});

gulp.task('spritesmith', function() {
   return spritesmith();
});

gulp.task('stylesheets', function(callback) {
    runSequence(
        'sass',
        'spritesmith',
        callback
    );
});

gulp.task('default', function(callback) {
    return;
});<|endoftext|>