<commit_before>/**
 * Accessing Parsoid output
 */

'use strict';

const domino = require('domino');
const sUtil = require('./util');
const api = require('./api-util');
const mwapi = require('./mwapi');
const parseProperty = require('./parseProperty');
const parseDefinitions = require('./parseDefinitions');
const parsoidSections = require('./parsoidSections');
const transforms = require('./transforms');
const HTTPError = sUtil.HTTPError;

const PARSOID_ACCEPT_HEADER
    = 'text/html; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/HTML/1.6.0"';

/**
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @return {!promise} a Promise, which if fulfilled, will return the Parsoid content
 *          of the given page.
 */
function getParsoidHtml(app, req) {
    const rev = req.params.revision;
    let suffix = '';
    if (rev) {
        suffix = `/${rev}`;
        const tid = req.params.tid;
        if (tid) {
            suffix += `/${tid}`;
        }
    }
    const domain = req.params.domain.replace(/^(\w+\.)m\./, '$1');

    return mwapi.getDbTitle(app, req, req.params.title)
    .then((title) => {
        const path = `page/html/${encodeURIComponent(title)}${suffix}`;
        const restReq = { headers: { accept: PARSOID_ACCEPT_HEADER } };

        return api.restApiGet(app, domain, path, restReq);
    });
}

/**
 * Retrieves the revision from the etag emitted by Parsoid.
 * Note it currently has an extra double quote at the beginning and at the end.
 * @param {?object} headers an object of header name/values
 * @return {?*}
 */
function getRevisionFromEtag(headers) {
    let revision;
    if (headers && headers.etag) {
        revision = headers.etag.split('/').shift();
        revision = revision.replace(/^"/, '');
        // Uncomment the following line if you need to see tid values from Parsoid in the console:
        // console.log(`headers.etag = ${headers.etag}`);
    }
    return revision;
}

function getRevAndTidFromEtag(headers) {
    if (headers && headers.etag) {
        const etagComponents = headers.etag.replace(/"/g, '').split('/');
        return {
            revision: etagComponents[0],
            tid: etagComponents[1]
        };
    }
}

/**
 * <meta property="dc:modified" content="2015-10-05T21:35:32.000Z"/>
 * @param {!document} doc
 */
function getModified(doc) {
    return doc.querySelector('head > meta[property="dc:modified"]').getAttribute('content')
        .replace(/\.000Z$/, 'Z');
}

/**
 * Gets the base URI from a Parsoid document
 * <base href="//en.wikipedia.org/wiki/"/>
 * @param {!document} doc
 */
function getBaseUri(doc) {
    return doc.querySelector('html > head > base').getAttribute('href');
}

/**
 * Gets the title of the current page from a Parsoid document. This title string usually differs
 * from normalized titles in that it has spaces replaced with underscores.
 * Example: given a Parsoid document with
 * <link rel="dc:isVersionOf" href="//en.wikipedia.org/wiki/Hope_(painting)"/> and
 * <base href="//en.wikipedia.org/wiki/"/> this function returns the string 'Hope_(painting)'.
 * @param {!document} doc
 */
function getParsoidLinkTitle(doc) {
    const href = doc.querySelector('html > head > link[rel="dc:isVersionOf"]').getAttribute('href');
    const baseUri = getBaseUri(doc);
    return decodeURIComponent(href.replace(new RegExp(`^${baseUri}`), ''));
}

/**
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @param {?Boolean} [legacy] if enabled will apply additional transformations
 * including a legacy version of relocation of first paragraph
 * and hiding IPA via an inline style rather than clas.
 * @return {!promise} Returns a promise to retrieve the page content from Parsoid
 */
function pageJsonPromise(app, req, legacy) {
    return getParsoidHtml(app, req)
        .then((response) => {
            const page = getRevAndTidFromEtag(response.headers);
            const doc = domino.createDocument(response.body);

            // Note: these properties must be obtained before stripping markup
            page.lastmodified = getModified(doc);
            parseProperty.parsePronunciation(doc, page);
            parseProperty.parseSpokenWikipedia(doc, page);

            if (legacy) {
                transforms.shortenPageInternalLinks(doc, getParsoidLinkTitle(doc));
                transforms.addRequiredMarkup(doc);
            }
            transforms.stripUnneededMarkup(doc, legacy);
            parsoidSections.addSectionDivs(doc);

            page.sections = parsoidSections.getSectionsText(doc, req.logger);
            return page;
        });
}

/**
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @param {?Boolean} [optimized] if true will apply additional transformations
 * to reduce the payload
 * @return {!promise} Returns a promise to retrieve the page content from Parsoid
 */
function pageHtmlPromise(app, req, optimized) {
    return getParsoidHtml(app, req)
        .then((response) => {
            const meta = getRevAndTidFromEtag(response.headers);
            const doc = domino.createDocument(response.body);

            if (optimized) {
                transforms.stripReferenceListContent(doc);
                transforms.stripUnneededMarkup(doc, false);
            }

            parsoidSections.addSectionDivs(doc);

            const html = doc.outerHTML;
            return { meta, html };
        });
}

/**
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @return {!promise} Returns a promise to retrieve the page content from Parsoid
 */
function pageHtmlPromiseForReferences(app, req) {
    return getParsoidHtml(app, req)
        .then((response) => {
            const meta = getRevAndTidFromEtag(response.headers);
            const doc = domino.createDocument(response.body);

            transforms.stripUnneededReferenceMarkup(doc);
            return { meta, doc };
        });
}

/*
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @return {!promise} a promise to retrieve a set of definitions from Wiktionary.
 */
function definitionPromise(app, req) {
    if (req.params.domain.indexOf('wiktionary.org') === -1) {
        throw new HTTPError({
            status: 400,
            type: 'invalid_domain',
            title: 'Invalid domain',
            detail: 'Definition requests only supported for wiktionary.org domains.'
        });
    }
    if (req.params.domain.indexOf('en') !== 0) {
        throw new HTTPError({
            status: 501,
            type: 'unsupported_language',
            title: 'Language not supported',
            detail: 'The language you have requested is not yet supported.'
        });
    }
    return getParsoidHtml(app, req)
        .then((response) => {
            const doc = domino.createDocument(response.body);
            transforms.stripUnneededMarkup(doc);
            transforms.stripWiktionarySpecificMarkup(doc);
            transforms.rmElementsWithSelector(doc, 'sup');
            transforms.addRequiredMarkup(doc);
            return {
                payload: parseDefinitions(doc, req.params.domain, req.params.title),
                meta: {
                    revision: getRevisionFromEtag(response.headers)
                }
            };
        });
}

module.exports = {
    pageJsonPromise,
    pageHtmlPromise,
    pageHtmlPromiseForReferences,
    definitionPromise,
    getParsoidHtml,
    getRevisionFromEtag,
    getRevAndTidFromEtag,

    // VisibleForTesting
    _getBaseUri: getBaseUri,
    _getParsoidLinkTitle: getParsoidLinkTitle,
};
<commit_msg>Stop getting dc:lastmodified<commit_after>/**
 * Accessing Parsoid output
 */

'use strict';

const domino = require('domino');
const sUtil = require('./util');
const api = require('./api-util');
const mwapi = require('./mwapi');
const parseProperty = require('./parseProperty');
const parseDefinitions = require('./parseDefinitions');
const parsoidSections = require('./parsoidSections');
const transforms = require('./transforms');
const HTTPError = sUtil.HTTPError;

const PARSOID_ACCEPT_HEADER
    = 'text/html; charset=utf-8; profile="https://www.mediawiki.org/wiki/Specs/HTML/1.6.0"';

/**
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @return {!promise} a Promise, which if fulfilled, will return the Parsoid content
 *          of the given page.
 */
function getParsoidHtml(app, req) {
    const rev = req.params.revision;
    let suffix = '';
    if (rev) {
        suffix = `/${rev}`;
        const tid = req.params.tid;
        if (tid) {
            suffix += `/${tid}`;
        }
    }
    const domain = req.params.domain.replace(/^(\w+\.)m\./, '$1');

    return mwapi.getDbTitle(app, req, req.params.title)
    .then((title) => {
        const path = `page/html/${encodeURIComponent(title)}${suffix}`;
        const restReq = { headers: { accept: PARSOID_ACCEPT_HEADER } };

        return api.restApiGet(app, domain, path, restReq);
    });
}

/**
 * Retrieves the revision from the etag emitted by Parsoid.
 * Note it currently has an extra double quote at the beginning and at the end.
 * @param {?object} headers an object of header name/values
 * @return {?*}
 */
function getRevisionFromEtag(headers) {
    let revision;
    if (headers && headers.etag) {
        revision = headers.etag.split('/').shift();
        revision = revision.replace(/^"/, '');
        // Uncomment the following line if you need to see tid values from Parsoid in the console:
        // console.log(`headers.etag = ${headers.etag}`);
    }
    return revision;
}

function getRevAndTidFromEtag(headers) {
    if (headers && headers.etag) {
        const etagComponents = headers.etag.replace(/"/g, '').split('/');
        return {
            revision: etagComponents[0],
            tid: etagComponents[1]
        };
    }
}

/**
 * Gets the base URI from a Parsoid document
 * <base href="//en.wikipedia.org/wiki/"/>
 * @param {!document} doc
 */
function getBaseUri(doc) {
    return doc.querySelector('html > head > base').getAttribute('href');
}

/**
 * Gets the title of the current page from a Parsoid document. This title string usually differs
 * from normalized titles in that it has spaces replaced with underscores.
 * Example: given a Parsoid document with
 * <link rel="dc:isVersionOf" href="//en.wikipedia.org/wiki/Hope_(painting)"/> and
 * <base href="//en.wikipedia.org/wiki/"/> this function returns the string 'Hope_(painting)'.
 * @param {!document} doc
 */
function getParsoidLinkTitle(doc) {
    const href = doc.querySelector('html > head > link[rel="dc:isVersionOf"]').getAttribute('href');
    const baseUri = getBaseUri(doc);
    return decodeURIComponent(href.replace(new RegExp(`^${baseUri}`), ''));
}

/**
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @param {?Boolean} [legacy] if enabled will apply additional transformations
 * including a legacy version of relocation of first paragraph
 * and hiding IPA via an inline style rather than clas.
 * @return {!promise} Returns a promise to retrieve the page content from Parsoid
 */
function pageJsonPromise(app, req, legacy) {
    return getParsoidHtml(app, req)
        .then((response) => {
            const page = getRevAndTidFromEtag(response.headers);
            const doc = domino.createDocument(response.body);

            // Note: these properties must be obtained before stripping markup
            parseProperty.parsePronunciation(doc, page);
            parseProperty.parseSpokenWikipedia(doc, page);

            if (legacy) {
                transforms.shortenPageInternalLinks(doc, getParsoidLinkTitle(doc));
                transforms.addRequiredMarkup(doc);
            }
            transforms.stripUnneededMarkup(doc, legacy);
            parsoidSections.addSectionDivs(doc);

            page.sections = parsoidSections.getSectionsText(doc, req.logger);
            return page;
        });
}

/**
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @param {?Boolean} [optimized] if true will apply additional transformations
 * to reduce the payload
 * @return {!promise} Returns a promise to retrieve the page content from Parsoid
 */
function pageHtmlPromise(app, req, optimized) {
    return getParsoidHtml(app, req)
        .then((response) => {
            const meta = getRevAndTidFromEtag(response.headers);
            const doc = domino.createDocument(response.body);

            if (optimized) {
                transforms.stripReferenceListContent(doc);
                transforms.stripUnneededMarkup(doc, false);
            }

            parsoidSections.addSectionDivs(doc);

            const html = doc.outerHTML;
            return { meta, html };
        });
}

/**
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @return {!promise} Returns a promise to retrieve the page content from Parsoid
 */
function pageHtmlPromiseForReferences(app, req) {
    return getParsoidHtml(app, req)
        .then((response) => {
            const meta = getRevAndTidFromEtag(response.headers);
            const doc = domino.createDocument(response.body);

            transforms.stripUnneededReferenceMarkup(doc);
            return { meta, doc };
        });
}

/*
 * @param {!Object} app the application object
 * @param {!Object} req the request object
 * @return {!promise} a promise to retrieve a set of definitions from Wiktionary.
 */
function definitionPromise(app, req) {
    if (req.params.domain.indexOf('wiktionary.org') === -1) {
        throw new HTTPError({
            status: 400,
            type: 'invalid_domain',
            title: 'Invalid domain',
            detail: 'Definition requests only supported for wiktionary.org domains.'
        });
    }
    if (req.params.domain.indexOf('en') !== 0) {
        throw new HTTPError({
            status: 501,
            type: 'unsupported_language',
            title: 'Language not supported',
            detail: 'The language you have requested is not yet supported.'
        });
    }
    return getParsoidHtml(app, req)
        .then((response) => {
            const doc = domino.createDocument(response.body);
            transforms.stripUnneededMarkup(doc);
            transforms.stripWiktionarySpecificMarkup(doc);
            transforms.rmElementsWithSelector(doc, 'sup');
            transforms.addRequiredMarkup(doc);
            return {
                payload: parseDefinitions(doc, req.params.domain, req.params.title),
                meta: {
                    revision: getRevisionFromEtag(response.headers)
                }
            };
        });
}

module.exports = {
    pageJsonPromise,
    pageHtmlPromise,
    pageHtmlPromiseForReferences,
    definitionPromise,
    getParsoidHtml,
    getRevisionFromEtag,
    getRevAndTidFromEtag,

    // VisibleForTesting
    _getBaseUri: getBaseUri,
    _getParsoidLinkTitle: getParsoidLinkTitle,
};
<|endoftext|>


<commit_before>/**
 * This module defines all the arguments that may be passed to a message.
 *
 * Each argument may contain a field `__argName`, if the name of the field
 * should be different when sent to the server.
 *
 * The argument may also contain a field `__argType`, if the given
 * argument must be of that type. The types are the strings resulting from
 * calling `typeof <arg>` where `<arg>` is the argument.
 *
 * Other than that, the arguments are expected to follow the indicated
 * structure.
 */

module.exports = {
	collapseKey: {
        __argName: "collapse_key",
        __argType: "string"
    },
    //priority (number),
    //content_available (boolean),
	delayWhileIdle: {
        __argName: "content_available",
        __argType: "boolean"
    },
    timeToLive: {
        __argName: "time_to_live",
        __argType: "number"
    },
    //restricted_package_name (string),
    dryRun: {
        __argName: "dry_run",
        __argType: "boolean"
    },
    data: {
        __argType: "object"
    },
    notification: {
        __argType: "object"
        //TODO: There are a lot of very specific arguments that could
        //      be indicated here.
    }
};
<commit_msg>Fix typo: delayWhileIdle should be delay_while_idle<commit_after>/**
 * This module defines all the arguments that may be passed to a message.
 *
 * Each argument may contain a field `__argName`, if the name of the field
 * should be different when sent to the server.
 *
 * The argument may also contain a field `__argType`, if the given
 * argument must be of that type. The types are the strings resulting from
 * calling `typeof <arg>` where `<arg>` is the argument.
 *
 * Other than that, the arguments are expected to follow the indicated
 * structure.
 */

module.exports = {
	collapseKey: {
        __argName: "collapse_key",
        __argType: "string"
    },
    //priority (number),
    //content_available (boolean),
	delayWhileIdle: {
        __argName: "delay_while_idle",
        __argType: "boolean"
    },
    timeToLive: {
        __argName: "time_to_live",
        __argType: "number"
    },
    //restricted_package_name (string),
    dryRun: {
        __argName: "dry_run",
        __argType: "boolean"
    },
    data: {
        __argType: "object"
    },
    notification: {
        __argType: "object"
        //TODO: There are a lot of very specific arguments that could
        //      be indicated here.
    }
};
<|endoftext|>


<commit_before>/**
 * Copyright 2015-2016, Google, Inc.
 * 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.
 */

'use strict';

const gcloud = require('gcloud');
const config = require('../config/config');

const ds = gcloud.datastore({
  projectId: config.get('GCLOUD_PROJECT')
});

// Translates from Datastore's entity format to
// the format expected by the application.
//
// Datastore format:
//   {
//     key: [kind, id],
//     data: {
//       property: value
//     }
//   }
//
// Application format:
//   {
//     id: id,
//     property: value
//   }
function fromDatastore(obj) {
  obj.data.id = obj.key.id;
  return obj.data;
}

// Translates from the application's format to the datastore's
// extended entity property format. It also handles marking any
// specified properties as non-indexed. Does not translate the key.
//
// Application format:
//   {
//     id: id,
//     property: value,
//     unindexedProperty: value
//   }
//
// Datastore extended format:
//   [
//     {
//       name: property,
//       value: value
//     },
//     {
//       name: unindexedProperty,
//       value: value,
//       excludeFromIndexes: true
//     }
//   ]
function toDatastore(obj, nonIndexed) {
  nonIndexed = nonIndexed || [];
  const results = [];
  Object.keys(obj).forEach(function(k) {
    if (obj[k] === undefined) {
      return;
    }
    results.push({
      name: k,
      value: obj[k],
      excludeFromIndexes: nonIndexed.indexOf(k) !== -1
    });
  });
  return results;
}

// Lists all Entities in the Datastore sorted alphabetically by title.
// The ``limit`` argument determines the maximum amount of results to
// return per page. The ``token`` argument allows requesting additional
// pages. The callback is invoked with ``(err, Entities, nextPageToken)``.
function list(kind, limit, token, cb) {
  const q = ds.createQuery([kind])
    .limit(limit)
    .start(token);

  ds.runQuery(q, function(err, entities, nextQuery) {
    if (err) {
      return cb(err);
    }
    const hasMore = entities.length === limit ? nextQuery.startVal : false;
    cb(null, entities.map(fromDatastore), hasMore);
  });
}

// Creates a new Entity or updates an existing Entity with new data. The provided
// data is automatically translated into Datastore format. The Entity will be
// queued for background processing.
function update(kind, id, data, cb) {
  let key;
  if (id) {
    key = ds.key([kind, parseInt(id, 10)]);
  } else {
    key = ds.key(kind);
  }

  const entity = {
    key: key,
    data: toDatastore(data, ['description'])
  };

  ds.save(
    entity,
    function(err) {
      data.id = entity.key.id;
      cb(err, err ? null : data);
    }
  );
}

function read(kind, id, cb) {
  const key = ds.key([kind, parseInt(id, 10)]);
  ds.get(key, function(err, entity) {
    if (err) {
      return cb(err);
    }
    if (!entity) {
      return cb({
        code: 404,
        message: 'Not found'
      });
    }
    cb(null, fromDatastore(entity));
  });
}

function _delete(kind, id, cb) {
  const key = ds.key([kind, parseInt(id, 10)]);
  ds.delete(key, cb);
}

module.exports = {
  create: function(kind, data, cb) {
    update(kind, null, data, cb);
  },
  read: read,
  update: update,
  delete: _delete,
  list: list
};
<commit_msg>cb isn't always passed<commit_after>/**
 * Copyright 2015-2016, Google, Inc.
 * 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.
 */

'use strict';

const gcloud = require('gcloud');
const config = require('../config/config');

const ds = gcloud.datastore({
  projectId: config.get('GCLOUD_PROJECT')
});

// Translates from Datastore's entity format to
// the format expected by the application.
//
// Datastore format:
//   {
//     key: [kind, id],
//     data: {
//       property: value
//     }
//   }
//
// Application format:
//   {
//     id: id,
//     property: value
//   }
function fromDatastore(obj) {
  obj.data.id = obj.key.id;
  return obj.data;
}

// Translates from the application's format to the datastore's
// extended entity property format. It also handles marking any
// specified properties as non-indexed. Does not translate the key.
//
// Application format:
//   {
//     id: id,
//     property: value,
//     unindexedProperty: value
//   }
//
// Datastore extended format:
//   [
//     {
//       name: property,
//       value: value
//     },
//     {
//       name: unindexedProperty,
//       value: value,
//       excludeFromIndexes: true
//     }
//   ]
function toDatastore(obj, nonIndexed) {
  nonIndexed = nonIndexed || [];
  const results = [];
  Object.keys(obj).forEach(function(k) {
    if (obj[k] === undefined) {
      return;
    }
    results.push({
      name: k,
      value: obj[k],
      excludeFromIndexes: nonIndexed.indexOf(k) !== -1
    });
  });
  return results;
}

// Lists all Entities in the Datastore sorted alphabetically by title.
// The ``limit`` argument determines the maximum amount of results to
// return per page. The ``token`` argument allows requesting additional
// pages. The callback is invoked with ``(err, Entities, nextPageToken)``.
function list(kind, limit, token, cb) {
  const q = ds.createQuery([kind])
    .limit(limit)
    .start(token);

  ds.runQuery(q, function(err, entities, nextQuery) {
    if (err) {
      return cb(err);
    }
    const hasMore = entities.length === limit ? nextQuery.startVal : false;
    cb(null, entities.map(fromDatastore), hasMore);
  });
}

// Creates a new Entity or updates an existing Entity with new data. The provided
// data is automatically translated into Datastore format. The Entity will be
// queued for background processing.
function update(kind, id, data, cb) {
  let key;
  if (id) {
    key = ds.key([kind, parseInt(id, 10)]);
  } else {
    key = ds.key(kind);
  }

  const entity = {
    key: key,
    data: toDatastore(data, ['description'])
  };

  ds.save(
    entity,
    function(err) {
      data.id = entity.key.id;
      if (cb) {
        cb(err, err ? null : data);
      }
    }
  );
}

function read(kind, id, cb) {
  const key = ds.key([kind, parseInt(id, 10)]);
  ds.get(key, function(err, entity) {
    if (err) {
      return cb(err);
    }
    if (!entity) {
      return cb({
        code: 404,
        message: 'Not found'
      });
    }
    cb(null, fromDatastore(entity));
  });
}

function _delete(kind, id, cb) {
  const key = ds.key([kind, parseInt(id, 10)]);
  ds.delete(key, cb);
}

module.exports = {
  create: function(kind, data, cb) {
    update(kind, null, data, cb);
  },
  read: read,
  update: update,
  delete: _delete,
  list: list
};
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2016 Singular Studios (a.k.a Atom Tecnologia) - www.opensingular.com
 *
 * 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.
 */

(function () {

    const FILE_REGEX_PATTERN = /.*\.(.*)/;
    const SUPPORTED_EXTENSIONS = ['pdf', 'jpg', 'gif', 'png'];

    "use strict";
    if (window.DownloadSupportedBehavior == undefined) {
        window.DownloadSupportedBehavior = function () {
        };
        window.DownloadSupportedBehavior.ajaxDownload = function (url, fileId, filename) {
            $.ajax({
                type: "POST",
                dataType: 'json',
                url: url + '&fileId=' + fileId + '&fileName=' + filename,
                success: function (response, status, request) {
                    if (window.DownloadSupportedBehavior.isContentTypeBrowserFriendly(filename)) {
                        window.open(response.url);
                    } else {
                        var form = $('<form method="GET" action="' + response.url + '">');
                        $('body').append(form);
                        form.submit();
                        form.remove();
                    }
                }
            });
            return false;
        };
        window.DownloadSupportedBehavior.resolveUrl = function (url, fileId, filename, callback) {
            $.ajax({
                type: "POST",
                dataType: 'json',
                url: url + '&fileId=' + fileId + '&fileName=' + filename,
                success: function (response, status, request) {
                    callback(response.url);
                }
            });
            return false;
        };
        window.DownloadSupportedBehavior.isContentTypeBrowserFriendly = function (filename) {
            return FILE_REGEX_PATTERN.test(filename) && SUPPORTED_EXTENSIONS.indexOf(FILE_REGEX_PATTERN.exec(filename)[1]) >= 0;
        }
    }
})();

<commit_msg>ajuste na visualização de arquivo em nova aba<commit_after>/*
 * Copyright (C) 2016 Singular Studios (a.k.a Atom Tecnologia) - www.opensingular.com
 *
 * 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.
 */

(function () {

    const FILE_REGEX_PATTERN = /.*\.(.*)/;
    const SUPPORTED_EXTENSIONS = ['pdf', 'jpg', 'gif', 'png'];

    "use strict";
    if (window.DownloadSupportedBehavior == undefined) {
        window.DownloadSupportedBehavior = function () {
        };
        window.DownloadSupportedBehavior.ajaxDownload = function (url, fileId, filename) {
            var newWindow;
            if (window.DownloadSupportedBehavior.isContentTypeBrowserFriendly(filename)) {
                newWindow = window.open();
            }
            $.ajax({
                type: "POST",
                dataType: 'json',
                url: url + '&fileId=' + fileId + '&fileName=' + filename,
                success: function (response, status, request) {
                    if (typeof newWindow != "undefined") {
                        newWindow.location = location.protocol + "//" + location.host + response.url;
                    } else {
                        var form = $('<form method="GET" action="' + response.url + '">');
                        $('body').append(form);
                        form.submit();
                        form.remove();
                    }
                }
            });
            return false;
        };
        window.DownloadSupportedBehavior.resolveUrl = function (url, fileId, filename, callback) {
            $.ajax({
                type: "POST",
                dataType: 'json',
                url: url + '&fileId=' + fileId + '&fileName=' + filename,
                success: function (response, status, request) {
                    callback(response.url);
                }
            });
            return false;
        };
        window.DownloadSupportedBehavior.isContentTypeBrowserFriendly = function (filename) {
            return FILE_REGEX_PATTERN.test(filename) && SUPPORTED_EXTENSIONS.indexOf(FILE_REGEX_PATTERN.exec(filename)[1]) >= 0;
        }
    }
})();

<|endoftext|>


<commit_before>// render
wn.doclistviews['Support Ticket'] = wn.views.ListView.extend({
	init: function(d) {
		this._super(d)
		this.fields = this.fields.concat([
			"`tabSupport Ticket`.status",
			"`tabSupport Ticket`.subject",
			"`tabSupport Ticket`.description"
		]);
		this.stats = this.stats.concat(['status']);
	},

	prepare_data: function(data) {
		this._super(data);
		if(data.status=='Open' || data.status=='To Reply') {
			data.label_type = 'important'
		}
		else if(data.status=='Closed') {
			data.label_type = 'success'
		}
		else if(data.status=='Hold') {
			data.label_type = 'info'
		}
		else if(data.status=='Waiting for Customer') {
			data.label_type = 'info'
		}
		data.status_html = repl('%(status)s', data);

		// description
		if(data.description && data.description.length > 30) {
			data.description = '' + data.description.substr(0,30) + '...';
		}
	},

	columns: [
		{width: '5%', content:'avatar'},
		{width: '3%', content:'docstatus'},
		{width: '12%', content:'name'},
		{width: '8%', content:'status_html'},
		{width: '62%', content:'tags+subject+description', css: {color:'#aaa'}},
		{width: '10%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
	]

});
<commit_msg>support ticket listview<commit_after>// render
wn.doclistviews['Support Ticket'] = wn.views.ListView.extend({
	init: function(d) {
		this._super(d)
		this.fields = this.fields.concat([
			"`tabSupport Ticket`.status",
			"`tabSupport Ticket`.subject",
			"`tabSupport Ticket`.description"
		]);
		this.stats = this.stats.concat(['status']);
	},

	prepare_data: function(data) {
		this._super(data);
		if(data.status=='Open' || data.status=='To Reply') {
			data.label_type = 'important'
		}
		else if(data.status=='Closed') {
			data.label_type = 'success'
		}
		else if(data.status=='Hold') {
			data.label_type = 'info'
		}
		else if(data.status=='Waiting for Customer') {
			data.label_type = 'info'
			data.status = 'Waiting'
		}
		data.status_html = repl('%(status)s', data);

		// description
		if(data.description && data.description.length > 30) {
			data.description = '' + data.description.substr(0,30) + '...';
		}
	},

	columns: [
		{width: '5%', content:'avatar'},
		{width: '3%', content:'docstatus'},
		{width: '15%', content:'name'},
		{width: '8%', content:'status_html'},
		{width: '60%', content:'tags+subject+description', css: {color:'#aaa'}},
		{width: '10%', content:'modified', css: {'text-align': 'right', 'color':'#777'}}
	]

});
<|endoftext|>


<commit_before>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

import assert from 'assert';
import bunyan from 'bunyan';
import lodash from 'lodash';

const defaultLevel = 'info';
const levels = ['debug', 'info', 'warn', 'error'];
const extraLevels = ['state', 'digest', 'child'];
const allLevels = levels.concat(extraLevels);
const digestLimit = 100;
const state = {
   limit: 10,
   stats: {},
   logging: {
      error: [],
      warn: [],
      info: [],
      debug: [],
      digest: []
   }
};

function getStats(name) {
   let stats = state.stats[name];
   if (!stats) {
      stats = {
         counters: {},
         peaks: {},
      };
      state.stats[name] = stats;
   }
   return stats;
}

function increment(name, prop) {
   let stats = getStats(name);
   let value = stats.counters[prop] || 0;
   value += 1;
   stats.counters[prop] = value;
   return value;
}

function peak(name, prop, value) {
   increment(name, prop);
   let stats = getStats(name);
   if (!stats.peaks.hasOwnProperty(prop)) {
      stats.peaks[prop] = value;
      return value;
   }
   let peak = stats.peaks[prop];
   if (value > peak) {
      stats.peaks[prop] = value;
      peak = value;
   }
   return peak;
}

function basename(file) {
   var matcher = file.match(/([^\/]+)\.[a-z]+$/);
   if (matcher) {
      return matcher[1];
   } else {
      return file;
   }
}

module.exports = {
   pub() {
      return Object.assign({}, state.stats, state.logging);
   },
   counters() {
      return state.counters;
   },
   create(name, level) {
      name = basename(name);
      level = level || global.loggerLevel || process.env.loggerLevel || defaultLevel;
      if (lodash.includes(levels, level)) {
         let logger = bunyan.createLogger({name, level});
         return decorate(logger, name, level);
      } else {
         assert(lodash.includes(extraLevels, level), 'level: ' + level);
         return decorate(null, name, level);
      }
   }
};

function logging(logger, name, loggerLevel, context, level, args, count) {
   increment(name, level);
   args = [].slice.call(args); // convert arguments to array
   if (!lodash.isEmpty(context)) {
      if (lodash.isArray(context)) {
         args = context.concat(args);
      }
   }
   if (!state.logging.hasOwnProperty(level)) {
      args.splice(0, 0, 'Invalid level: ' + level);
      level = 'warn';
   }
   if (logger) {
      if (level === 'digest') {
         if (count < digestLimit/10 && count % digestLimit === 0) {
            logger.info('digest', count, ...args);
         }
      } else if (lodash.includes(levels, level)) {
         if (levels.indexOf(level) >= levels.indexOf(loggerLevel)) {
            logger[level].call(logger, ...args);
            let error = findArgsError(args);
            if (error) {
               if (error.code && error.code === 'ETIMEOUT') {
               } else {
                  logger[level].call(logger, error);
               }
            }
         }
      } else {
      }
   }
   let message = [name, new Date().toISOString(), ...args];
   state.logging[level].splice(0, 0, message);
   if (state.logging[level].length > state.limit) { // trim
      state.logging[level].length = state.limit;
   }
}

function findArgsError(args) {
   if (lodash.isError(args[0])) {
      return args[0];
   } else if (lodash.isError(args[1])) {
      return args[1];
   } else if (lodash.isError(args[args.length - 1])) {
      return args[args.length - 1];
   }
}

function decorate(logger, name, level) {
   let count = 0;
   let context = [];
   const those = {
      get name() {
         return name;
      },
      verbose() {
      },
      vdebug() {
      },
      debug() {
         if (level === 'debug') {
            logging(logger, name, level, context, 'debug', arguments);
         }
      },
      info() {
         if (level !== 'warn') {
            logging(logger, name, level, context, 'info', arguments);
         }
      },
      dev() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      wverbose() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      wdebug() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      winfo() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      dverbose() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      ddebug() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      dinfo() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      tdebug() {
         if (process.env.envType === 'test') {
            logging(logger, name, level, context, 'info', arguments);
         }
      },
      warn() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      error() {
         logging(logger, name, level, context, 'error', arguments);
      },
      state() {
         logging(logger, name, level, context, 'state', arguments);
      },
      digest() {
         if (level === 'debug') {
            count += 1;
            logging(logger, name, level, context, 'digest', arguments, count);
         }
      },
      context() {
         context = [].slice.call(arguments);
      },
      child() {
         let childName = [name].concat([].slice.call(arguments)).join('.');
         return Loggers.create(childName, level);
      },
      increment(prop) {
         return increment(name, prop);
      },
      peak(prop, value) {
         return peak(name, prop, value);
      }
   };
   return those;
}
<commit_msg>loggers peak<commit_after>// Copyright (c) 2015, Evan Summers (twitter.com/evanxsummers)
// ISC license, see http://github.com/evanx/redexutil/LICENSE

import assert from 'assert';
import bunyan from 'bunyan';
import lodash from 'lodash';

const defaultLevel = 'info';
const levels = ['debug', 'info', 'warn', 'error'];
const extraLevels = ['state', 'digest', 'child'];
const allLevels = levels.concat(extraLevels);
const digestLimit = 100;
const state = {
   limit: 10,
   stats: {},
   logging: {
      error: [],
      warn: [],
      info: [],
      debug: [],
      digest: []
   }
};

function getStats(name) {
   let stats = state.stats[name];
   if (!stats) {
      stats = {
         counters: {},
         peaks: {},
      };
      state.stats[name] = stats;
   }
   return stats;
}

function increment(name, prop) {
   let stats = getStats(name);
   let value = stats.counters[prop] || 0;
   value += 1;
   stats.counters[prop] = value;
   return value;
}

function peak(name, prop, value) {
   increment(name, prop);
   let stats = getStats(name);
   if (!stats.peaks.hasOwnProperty(prop)) {
      stats.peaks[prop] = value;
      return value;
   }
   let peak = stats.peaks[prop];
   if (value > peak) {
      stats.peaks[prop] = value;
      peak = value;
   }
   return peak;
}

function basename(file) {
   var matcher = file.match(/([^\/]+)\.[a-z]+$/);
   if (matcher) {
      return matcher[1];
   } else {
      return file;
   }
}

module.exports = {
   pub() {
      return Object.assign({}, state.stats, state.logging);
   },
   counters() {
      return state.counters;
   },
   create(name, level) {
      name = basename(name);
      level = level || global.loggerLevel || process.env.loggerLevel || defaultLevel;
      if (lodash.includes(levels, level)) {
         let logger = bunyan.createLogger({name, level});
         return decorate(logger, name, level);
      } else {
         assert(lodash.includes(extraLevels, level), 'level: ' + level);
         return decorate(null, name, level);
      }
   }
};

function logging(logger, name, loggerLevel, context, level, args, count) {
   increment(name, level);
   args = [].slice.call(args); // convert arguments to array
   if (!lodash.isEmpty(context)) {
      if (lodash.isArray(context)) {
         args = context.concat(args);
      }
   }
   if (!state.logging.hasOwnProperty(level)) {
      args.splice(0, 0, 'Invalid level: ' + level);
      level = 'warn';
   }
   if (logger) {
      if (level === 'digest') {
         if (count < digestLimit/10 && count % digestLimit === 0) {
            logger.info('digest', count, ...args);
         }
      } else if (lodash.includes(levels, level)) {
         if (levels.indexOf(level) >= levels.indexOf(loggerLevel)) {
            logger[level].call(logger, ...args);
            let error = findArgsError(args);
            if (error) {
               if (error.code && error.code === 'ETIMEOUT') {
               } else {
                  logger[level].call(logger, error);
               }
            }
         }
      } else {
      }
   }
   let date = new Date().toISOString().substring(0, 16);
   let message = [date, name, ...args];
   state.logging[level].splice(0, 0, message);
   if (state.logging[level].length > state.limit) { // trim
      state.logging[level].length = state.limit;
   }
}

function findArgsError(args) {
   if (lodash.isError(args[0])) {
      return args[0];
   } else if (lodash.isError(args[1])) {
      return args[1];
   } else if (lodash.isError(args[args.length - 1])) {
      return args[args.length - 1];
   }
}

function decorate(logger, name, level) {
   let count = 0;
   let context = [];
   const those = {
      get name() {
         return name;
      },
      verbose() {
      },
      vdebug() {
      },
      debug() {
         if (level === 'debug') {
            logging(logger, name, level, context, 'debug', arguments);
         }
      },
      info() {
         if (level !== 'warn') {
            logging(logger, name, level, context, 'info', arguments);
         }
      },
      dev() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      wverbose() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      wdebug() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      winfo() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      dverbose() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      ddebug() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      dinfo() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      tdebug() {
         if (process.env.envType === 'test') {
            logging(logger, name, level, context, 'info', arguments);
         }
      },
      warn() {
         logging(logger, name, level, context, 'warn', arguments);
      },
      error() {
         logging(logger, name, level, context, 'error', arguments);
      },
      state() {
         logging(logger, name, level, context, 'state', arguments);
      },
      digest() {
         if (level === 'debug') {
            count += 1;
            logging(logger, name, level, context, 'digest', arguments, count);
         }
      },
      context() {
         context = [].slice.call(arguments);
      },
      child() {
         let childName = [name].concat([].slice.call(arguments)).join('.');
         return Loggers.create(childName, level);
      },
      increment(prop) {
         return increment(name, prop);
      },
      peak(prop, value) {
         return peak(name, prop, value);
      }
   };
   return those;
}
<|endoftext|>


<commit_before>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var AddToDOM = require('../dom/AddToDOM');

var CreateDOMContainer = function (game)
{
    var config = game.config;

    if (!config.parent || !config.domCreateContainer)
    {
        return;
    }

    //  DOM Element Container
    var div = document.createElement('div');

    div.style = [
        'display: block;',
        'width: ' + game.canvas.width + 'px;',
        'height: ' + game.canvas.height + 'px;',
        'padding: 0; margin: 0;',
        'position: absolute;',
        'overflow: hidden;',
        'pointer-events: none;'
    ].join();

    game.domContainer = div;

    AddToDOM(div, config.parent);
};

module.exports = CreateDOMContainer;
<commit_msg>Fixed style join<commit_after>/**
 * @author       Richard Davey <rich@photonstorm.com>
 * @copyright    2018 Photon Storm Ltd.
 * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
 */

var AddToDOM = require('../dom/AddToDOM');

var CreateDOMContainer = function (game)
{
    var config = game.config;

    if (!config.parent || !config.domCreateContainer)
    {
        return;
    }

    //  DOM Element Container
    var div = document.createElement('div');

    div.style = [
        'display: block;',
        'width: ' + game.canvas.width + 'px;',
        'height: ' + game.canvas.height + 'px;',
        'padding: 0; margin: 0;',
        'position: absolute;',
        'overflow: hidden;',
        'pointer-events: none;'
    ].join(' ');

    game.domContainer = div;

    AddToDOM(div, config.parent);
};

module.exports = CreateDOMContainer;
<|endoftext|>


<commit_before>var gulp = require('gulp');
var request = require('request');
var runSequence = require('run-sequence');
var typedoc = require('gulp-typedoc');
var paths = require('../paths');
var typedocExtractor = require('gulp-typedoc-extractor');
var vinylPaths = require('vinyl-paths');
var fs = require('fs');
var source = require('vinyl-source-stream')

gulp.task('bindables:download', function () {
  return request('https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/master/types/kendo-ui/index.d.ts')
  .pipe(source('kendo-ui.d.ts'))
  .pipe(gulp.dest('./temp'));
});

gulp.task('bindables:typedoc', function(){
    console.log("NOTE: The 'jquery.d.ts' not found error is expected");

    return gulp.src(['./temp/kendo-ui.d.ts'])
    .pipe(typedoc({
      target: 'es6',
      includeDeclarations: true,
      json: './temp/kendo-api.json',
      name: paths.packageName + '-docs',
      mode: 'modules',
      excludeExternals: true,
      ignoreCompilerErrors: true,
      version: true
    }));
});

gulp.task('bindables:extract', function (cb) {
  var json = JSON.parse(fs.readFileSync('./temp/kendo-api.json', 'utf-8'));

  var jsObj = {};
  extractOptions(jsObj, json);
  extractInterfaces(jsObj, json);

  var content = "export let bindables = " + JSON.stringify(jsObj);

  // write the js file to the file system
  fs.writeFile("./src/common/bindables.js", content, function (err) {
    if(err) {
      return console.log(err);
    }

    console.log("Bindables saved to ./src/common/bindables.js")
    cb();
  });
});

function extractOptions(jsObj, json) {
  var optionClasses = [];

  // the first child contains typedoc information about Kendo
  var kendo = json.children[0];

  // get the kendo module
  var kendoModule = kendo.children.find(function(i) { return i.name === "kendo" });
  var jQueryInterface = kendo.children.find(function(i) { return i.name === "JQuery" && i.kindString === "Interface" });
  var kendoMethods = jQueryInterface.children;

  // loop over all kendo methods declarations:
  // kendoAutoComplete(options: kendo.ui.AutoCompleteOptions): JQuery;
  // kendoDraggable(options: kendo.ui.DraggableOptions): JQuery;
  // and for each kendo method, find the id of the Options class (DraggableOptions, AutoCompleteOptions)
  kendoMethods.forEach(function (method) {
    if(method.name.startsWith('kendo')) {
      var signatures = method.signatures;
      signatures.forEach(function (signature) {
        if(signature.parameters && signature.parameters.length > 0) {
          optionClasses.push({
            method: method.name, // kendoButton, kendoGrid
            id: signature.parameters[0].type.id // id of the options class
          });
        }
      });
    }
  });

  // iterate over all modules and classes
  // of every class matching an id we found above, add the properties to an array
  kendoModule.children.forEach(function (module) {
    // loop through all classes such as kendo.data.DataSource
    iterativeOptionsLookup(module, optionClasses);
  });

  // sort a-z on method name (for readability)
  optionClasses.sort(function(a,b) {
    return (a.method > b.method) ? 1 : ((b.method > a.method) ? -1 : 0);
  });

  // create a flatter object so it can be easily read out by the plugin
  optionClasses.forEach(function (optionClass) {
    jsObj[optionClass.method] = optionClass.properties;
  });
}

function extractInterfaces(jsObj, json) {
  var findInterfaces = ["GridColumn", "TreeListColumn", "ToolBarItem", "GanttColumn", "ToolBarItemButton", "GridToolbarItem", "GridColumnCommandItem"];

  var kendo = json.children[0];
  var kendoModule = kendo.children.find(function(i) { return i.name === "kendo" && i.kindString === "Module" });
  var kendoUI = kendoModule.children.find(function(i) { return i.name === "ui" && i.kindString === "Module" });
  var interfaces = kendoUI.children.filter(function(i) { return findInterfaces.indexOf(i.name) > -1 && i.kindString === "Interface"});

  interfaces.forEach(function (interface) {
    jsObj[interface.name] = [];

    interface.children.forEach(function (property) {
      if(property.kindString === "Property" || property.kindString === "Method") {
        jsObj[interface.name].push(property.name);
      }
    });
  });
}

// iterate over all modules and classes
// of every class matching an id we found earlier, add the properties to an array
function iterativeOptionsLookup(_class, optionClasses) {
  // if the kind is a module, iterate over all classes and modudules in there as well
  if(_class.kindString === "Module") {
    if(_class.children) {
      _class.children.forEach(function (item) {
        iterativeOptionsLookup(item, optionClasses)
      });
    }
  }

  // these are classes/interfaces etc
  // find an interface matching the id of an Options class we collected earlier
  // of that interface, put all the propertynames of that interface into an array
   if(_class.children) {
     _class.children.forEach(function (item) {
       optionClasses.forEach(function (optionClass) {
         if(item.id === optionClass.id && item.kindString === "Interface") {

           optionClass.properties = [];

           item.children.forEach(function (property) {
             if(property.kindString === "Property") {
               optionClass.properties.push(property.name);
             }
           });
         }
       });
     });
   }
}

gulp.task('bindables', function (cb) {
  return runSequence(
    // 'bindables:download',
    'bindables:typedoc',
    'bindables:extract',
    cb);
});
<commit_msg>chore(gulp): gulp<commit_after><|endoftext|>


<commit_before>const toc = require('html-toc');
const _ = require('lodash');
const GithubSlugger = require('github-slugger');

const githubSlugger = new GithubSlugger();
const slugger = text => githubSlugger.slug(text);
const anchorTemplate = id => `<a class="anchor" href="#${id}"></a>`;

module.exports = (context) => {
  if (!_.isPlainObject(context)) throw Error('expect context to be a Object');
  if (!_.isString(context.data)) throw Error('expect context.data to be a String');
  if (!_.isPlainObject(context.site)) throw Error('expect context.site to be a Object');
  if (!_.isPlainObject(context.page)) throw Error('expect context.page to be a Object');
  if (!context.page.toc) return context;

  githubSlugger.reset();

  const opts = Object.assign(
    {},
    {
      selectors: 'h1, h2',
      minLength: 0,
      header: '',
      id: '#toc',
      addID: true,
      parentLink: false,
    },
    context.site.toc,
    {
      slugger,
      anchorTemplate,
    }
  );

  const data = toc(context.data, opts);
  return Object.assign(context, { data });
};
<commit_msg>feat(addTOC): able to set slugger and template<commit_after>const toc = require('html-toc');
const _ = require('lodash');
const GithubSlugger = require('github-slugger');

const githubSlugger = new GithubSlugger();
const slugger = text => githubSlugger.slug(text);
const anchorTemplate = id => `<a class="anchor" href="#${id}"></a>`;

module.exports = (context) => {
  if (!_.isPlainObject(context)) throw Error('expect context to be a Object');
  if (!_.isString(context.data)) throw Error('expect context.data to be a String');
  if (!_.isPlainObject(context.site)) throw Error('expect context.site to be a Object');
  if (!_.isPlainObject(context.page)) throw Error('expect context.page to be a Object');
  if (!context.page.toc) return context;

  githubSlugger.reset();

  const opts = Object.assign(
    {},
    {
      selectors: 'h1, h2',
      minLength: 0,
      header: '',
      id: '#toc',
      addID: true,
      parentLink: false,
      slugger,
      anchorTemplate,
    },
    context.site.toc
  );

  const data = toc(context.data, opts);
  return Object.assign(context, { data });
};
<|endoftext|>


<commit_before>var path = require('path'),
  coffeeBin = path.join(process.execPath, '..', 'coffee');

module.exports = function coffeePlugin(carapace) {
  if (!carapace.coffee) {
    carapace.coffee = function (value, done) {
      //
      // This will be immediately called when this plugin is passed to `.use()`
      //
      // Should change `process.argv[1]` to coffee and then rewrite the CLI arguments
      // as necessary so that the .coffee is handled correctly by the `coffee` binary.
      //
      var script = carapace.script;
      if (value == 'true' || script.match(/\.coffee$/)) {
        carapace.script = coffeeBin;
        carapace.argv.unshift(script);
      }
      done();
    };
  }
};
<commit_msg>[fix] realpath `coffee`<commit_after>var path = require('path'),
  fs = require('fs'),
  coffeeBin = fs.realpathSync(path.join(process.execPath, '..', 'coffee'));

module.exports = function coffeePlugin(carapace) {
  if (!carapace.coffee) {
    carapace.coffee = function (value, done) {
      //
      // This will be immediately called when this plugin is passed to `.use()`
      //
      // Should change `process.argv[1]` to coffee and then rewrite the CLI arguments
      // as necessary so that the .coffee is handled correctly by the `coffee` binary.
      //
      var script = carapace.script;
      function replaceWithCoffee() {
        carapace.script = coffeeBin;
        carapace.argv.unshift(script);
      }
      if (value == 'true' || /\.coffee$/.test(script)) {
        replaceWithCoffee();
        done();
      }
      else {
        //
        // Check shebang ... ugg, needed for executables
        //
        var file = fs.createReadStream(script);
        var line = '';
        var shebangLine = /^#!.*coffee$/;
        file.on('error', function () {
          done();
        })
        file.on('data', function (data) {
          data = data + '';
          var lines = data.split(/\r?\n/);
          if (lines.length > 1) {
            file.destroy();
            line += lines[0];
            if (shebangLine.test(line)) {
              replaceWithCoffee();
            }
            done();
            return;
          }
          line += lines[0];
        });
        file.on('end', function () {
          done();
        });
      }
    };
  }
};
<|endoftext|>


<commit_before>'use strict';

var nch = require('noncharacters');
var through = require('through2');

module.exports = function () {
  return function (options) {
    return through.obj(function (file, enc, cb) {
      var str = file.contents.toString();
      str = str.replace(/\{%%[=-]?(\s*)([\s\S]*?)(\s*)=%}/g, '\uFFFF$1$2$3\uFFFE');

      file.contents = new Buffer(str);
      this.push(file);
      cb();
    });
  }
};<commit_msg>use non-characters<commit_after>'use strict';

var nch = require('noncharacters');
var through = require('through2');

module.exports = function () {
  return function (options) {
    return through.obj(function (file, enc, cb) {
      var str = file.contents.toString();
      str = str.replace(/\{%%[=-]?(\s*)([\s\S]*?)(\s*)=%}/g, nch[0] + '$1$2$3' + nch[1]);

      file.contents = new Buffer(str);
      this.push(file);
      cb();
    });
  };
};<|endoftext|>


<commit_before>'use strict';

var Jingle = require('jingle');

module.exports = function (client) {

    var jingle = client.jingle = new Jingle();

    jingle.capabilities.forEach(function (cap) {
        client.disco.addFeature(cap);
    });

    var mappedEvents = [
        'outgoing', 'incoming', 'accepted', 'terminated',
        'ringing', 'mute', 'unmute', 'hold', 'resumed'
    ];
    mappedEvents.forEach(function (event) {
        jingle.on(event, function (session, arg1) {
            client.emit('jingle:' + event, session, arg1);
        });
    });

    jingle.on('createdSession', function (session) {
        client.emit('jingle:created', session);
    });

    jingle.on('peerStreamAdded', function (session, stream) {
        client.emit('jingle:remotestream:added', session, stream);
    });

    jingle.on('peerStreamRemoved', function (session, stream) {
        client.emit('jingle:remotestream:removed', session, stream);
    });

    jingle.on('send', function (data) {
        client.sendIq(data, function (err) {
            if (err) {
                client.emit('jingle:error', err);
            }
        });
    });

    client.on('session:bound', function (jid) {
        jingle.jid = jid;
        jingle.selfID = jid.full;
    });

    client.on('iq:set:jingle', function (data) {
        jingle.process(data);
    });

    client.on('unavailable', function (pres) {
        var peer = pres.from.full;
        jingle.endPeerSessions(peer, true);
    });

    client.discoverICEServers = function (cb) {
        return this.getServices(client.config.server).then(function (res) {
            var services = res.services.services;
            var discovered = [];

            for (var i = 0; i < services.length; i++) {
                var service = services[i];
                var ice = {};
                if (service.type === 'stun' || service.type === 'stuns') {
                    ice.url = service.type + ':' + service.host;
                    if (service.port) {
                        ice.url += ':' + service.port;
                    }
                    discovered.push(ice);
                    client.jingle.addICEServer(ice);
                } else if (service.type === 'turn' || service.type === 'turns') {
                    ice.url = service.type + ':' + service.host;
                    if (service.port) {
                        ice.url += ':' + service.port;
                    }
                    if (service.transport && service.transport !== 'udp') {
                        ice.url += '?transport=' + service.transport;
                    }

                    if (service.username) {
                        ice.username = service.username;
                    }
                    if (service.password) {
                        ice.credential = service.password;
                    }
                    discovered.push(ice);
                    client.jingle.addICEServer(ice);
                }
            }

            return discovered;
        }).then(function (result) {
            if (cb) {
                cb(null, result);
            }
            return result;
        }, function (err) {
            if (cb) {
                cb(err);
            } else {
                throw err;
            }
        });
    };
};
<commit_msg>xep-0215: use urls syntax<commit_after>'use strict';

var Jingle = require('jingle');

module.exports = function (client) {

    var jingle = client.jingle = new Jingle();

    jingle.capabilities.forEach(function (cap) {
        client.disco.addFeature(cap);
    });

    var mappedEvents = [
        'outgoing', 'incoming', 'accepted', 'terminated',
        'ringing', 'mute', 'unmute', 'hold', 'resumed'
    ];
    mappedEvents.forEach(function (event) {
        jingle.on(event, function (session, arg1) {
            client.emit('jingle:' + event, session, arg1);
        });
    });

    jingle.on('createdSession', function (session) {
        client.emit('jingle:created', session);
    });

    jingle.on('peerStreamAdded', function (session, stream) {
        client.emit('jingle:remotestream:added', session, stream);
    });

    jingle.on('peerStreamRemoved', function (session, stream) {
        client.emit('jingle:remotestream:removed', session, stream);
    });

    jingle.on('send', function (data) {
        client.sendIq(data, function (err) {
            if (err) {
                client.emit('jingle:error', err);
            }
        });
    });

    client.on('session:bound', function (jid) {
        jingle.jid = jid;
        jingle.selfID = jid.full;
    });

    client.on('iq:set:jingle', function (data) {
        jingle.process(data);
    });

    client.on('unavailable', function (pres) {
        var peer = pres.from.full;
        jingle.endPeerSessions(peer, true);
    });

    client.discoverICEServers = function (cb) {
        return this.getServices(client.config.server).then(function (res) {
            var services = res.services.services;
            var discovered = [];

            for (var i = 0; i < services.length; i++) {
                var service = services[i];
                var ice = {};
                if (service.type === 'stun' || service.type === 'stuns') {
                    ice.urls = service.type + ':' + service.host;
                    if (service.port) {
                        ice.urls += ':' + service.port;
                    }
                    discovered.push(ice);
                    client.jingle.addICEServer(ice);
                } else if (service.type === 'turn' || service.type === 'turns') {
                    ice.urls = service.type + ':' + service.host;
                    if (service.port) {
                        ice.urls += ':' + service.port;
                    }
                    if (service.transport && service.transport !== 'udp') {
                        ice.urls += '?transport=' + service.transport;
                    }

                    if (service.username) {
                        ice.username = service.username;
                    }
                    if (service.password) {
                        ice.credential = service.password;
                    }
                    discovered.push(ice);
                    client.jingle.addICEServer(ice);
                }
            }

            return discovered;
        }).then(function (result) {
            if (cb) {
                cb(null, result);
            }
            return result;
        }, function (err) {
            if (cb) {
                cb(err);
            } else {
                throw err;
            }
        });
    };
};
<|endoftext|>


<commit_before>const { dirname, extname } = require('path');
const postcss = require('postcss');

const findRetinaImage = require('./find-retina-image');
const {
  distributeQueryAcrossQuery,
  queryCoversRange,
  nodeIsMediaQuery
} = require('./utils/media-query');
const { isFullUrlPath } = require('./utils/image-url');

const UNNECESSARY_RETINA_IMAGE_WARNING =
  'Unncessary retina image provided; the same will be generated automatically';
const DEFAULT_MEDIA_QUERY =
  '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)';
const DEFAULT_RETINA_SUFFIX = '@2x';
const IMAGE_PROPERTY_REGEX = new RegExp(
  /^(background(-image))|(list-style-image)?$/
);
const URL_EXTRACT_REGEX = new RegExp(/url\((?:'|")?(.*?)(?:'|")?\)/);
const PROPERTY_TRANSLATIONS = {
  background: 'background-image',
  'background-image': 'background-image',
  'list-style-image': 'list-style-image'
};
const INCLUDE_FILE_EXT = ['.png', '.jpeg', '.jpg'];

function backgroundImagePath(decl) {
  const { value } = decl;
  const backgroundPropertyPath = URL_EXTRACT_REGEX.exec(value);

  return backgroundPropertyPath && backgroundPropertyPath[1];
}

function missingRetinaImageWarning(image) {
  return `Could not find retina version for \`${image}\``;
}

function retinaBackgroundImage(options) {
  return function(root, result) {
    const ruleSource = root.source.input.file;
    const retinaSuffix = options.retinaSuffix || DEFAULT_RETINA_SUFFIX;
    const mediaQueryOption = options.mediaQuery || DEFAULT_MEDIA_QUERY;
    const includeFileExt = options.includeFileExtensions || INCLUDE_FILE_EXT;
    const ruleBlacklist = {};
    let assetDirectory = options.assetDirectory;
    let newMediaQueries = [];

    if (!Array.isArray(includeFileExt)) {
      throw new Error(
        'Option `includeFileExtensions` must be an array. You passed: ' +
          includeFileExt
      );
    }

    if (!assetDirectory) {
      if (typeof ruleSource === 'string') {
        assetDirectory = dirname(ruleSource);
      } else {
        throw new Error('You must provide an asset directory');
      }
    }

    root.walkAtRules('media', function(atRule) {
      const { params } = atRule;

      if (!queryCoversRange(mediaQueryOption, params)) {
        return;
      }

      atRule.walkRules(function(rule) {
        const { selector } = rule;

        rule.walkDecls(IMAGE_PROPERTY_REGEX, function(decl) {
          const imgPath = backgroundImagePath(decl);

          if (imgPath) {
            ruleBlacklist[params] = ruleBlacklist[params] || {};
            ruleBlacklist[params][selector] = { imgPath, decl };
          }
        });
      });
    });

    root.walkRules(function(rule) {
      const { selector } = rule;
      const { parent: parentRule } = rule;
      let mediaQuery = mediaQueryOption;

      // The rule to add the new media query after
      let anchor = rule;

      // If the rule is inside a media query...
      if (parentRule && nodeIsMediaQuery(parentRule)) {
        // Short-circuit if the rule is already inside a retina media query
        if (queryCoversRange(mediaQueryOption, parentRule.params)) {
          return;
        }

        // Add the new media query after the parent one
        anchor = parentRule;
        mediaQuery = distributeQueryAcrossQuery(mediaQuery, parentRule.params);
      }

      // Create the media query and rule that we'll attach declarations to
      const mq = postcss.atRule({ name: 'media', params: mediaQuery });
      const ruleInMediaQuery = postcss.rule({ selector: rule.selector });
      mq.append(ruleInMediaQuery);

      rule.walkDecls(IMAGE_PROPERTY_REGEX, function(decl) {
        const { prop, value } = decl;

        if (value.indexOf(',') > -1) {
          var backgroundsList = value.split(',');
          var newBackgroundsList = [];
          for (var i = 0; i < backgroundsList.length; i++) {
            let backgroundPropertyPath = URL_EXTRACT_REGEX.exec(
              backgroundsList[i]
            );
            if (!(backgroundPropertyPath && backgroundPropertyPath[1])) {
              return;
            }
            const relativeImagePath = backgroundPropertyPath[1];
            if (isFullUrlPath(relativeImagePath)) {
              return;
            }
            const fileExtension = extname(relativeImagePath);
            if (includeFileExt.indexOf(fileExtension) === -1) {
              return;
            }
            let retinaImagePath = findRetinaImage(
              relativeImagePath,
              assetDirectory,
              retinaSuffix
            );
            if (!retinaImagePath) {
              retinaImagePath = backgroundPropertyPath[i];
            }
            if (
              ruleBlacklist[mediaQuery] &&
              ruleBlacklist[mediaQuery][selector]
            ) {
              const { imgPath, decl: existingDecl } = ruleBlacklist[mediaQuery][
                selector
              ];

              if (imgPath === retinaImagePath) {
                existingDecl.warn(result, UNNECESSARY_RETINA_IMAGE_WARNING);
              }

              return;
            }
            newBackgroundsList.push(retinaImagePath);
          }
          let newDecl = newBackgroundsList.map(function(bkg) {
            return `url('${bkg}')`;
          });
          const retinaImageDecl = postcss.decl({
            prop: PROPERTY_TRANSLATIONS[prop],
            value: `${newDecl.join(', ')};`
          });

          ruleInMediaQuery.append(retinaImageDecl);

          return;
        }

        const backgroundPropertyPath = URL_EXTRACT_REGEX.exec(value);

        // Abort if we couldn't parse the image URL from the property
        if (!(backgroundPropertyPath && backgroundPropertyPath[1])) {
          return;
        }

        const relativeImagePath = backgroundPropertyPath[1];

        // Short-circuit if the image path goes to a full URL that we can't check
        if (isFullUrlPath(relativeImagePath)) {
          return;
        }

        const fileExtension = extname(relativeImagePath);

        // If the file extension is not in the whitelist then skip
        if (includeFileExt.indexOf(fileExtension) === -1) {
          return;
        }

        const retinaImagePath = findRetinaImage(
          relativeImagePath,
          assetDirectory,
          retinaSuffix
        );

        // Abort if we couldn't find the retina version of the image
        if (!retinaImagePath) {
          decl.warn(result, missingRetinaImageWarning(relativeImagePath));
          return;
        }

        // Prune out instances where the rule has been defined explicitly; no need to generate a new media query
        if (ruleBlacklist[mediaQuery] && ruleBlacklist[mediaQuery][selector]) {
          const { imgPath, decl: existingDecl } = ruleBlacklist[mediaQuery][
            selector
          ];

          if (imgPath === retinaImagePath) {
            existingDecl.warn(result, UNNECESSARY_RETINA_IMAGE_WARNING);
          }

          return;
        }

        // Create the new property
        const retinaImageDecl = postcss.decl({
          prop: PROPERTY_TRANSLATIONS[prop],
          value: `url('${retinaImagePath}');`
        });

        ruleInMediaQuery.append(retinaImageDecl);
      });

      // Only add the media query to the page if there are declarations in it
      if (ruleInMediaQuery.nodes.length > 0) {
        newMediaQueries.push({ anchor, mq });
      }
    });

    // Insert the media query after the rule in the root
    newMediaQueries.forEach(function({ anchor, mq }) {
      root.insertAfter(anchor, mq);
    });
  };
}

module.exports = postcss.plugin('postcss-retina-bg-img', retinaBackgroundImage);
module.exports.DEFAULT_MEDIA_QUERY = DEFAULT_MEDIA_QUERY;
<commit_msg>Refactoring and eliminiating redundancy<commit_after>const { dirname, extname } = require('path');
const postcss = require('postcss');

const findRetinaImage = require('./find-retina-image');
const {
  distributeQueryAcrossQuery,
  queryCoversRange,
  nodeIsMediaQuery
} = require('./utils/media-query');
const { isFullUrlPath } = require('./utils/image-url');

const UNNECESSARY_RETINA_IMAGE_WARNING =
  'Unncessary retina image provided; the same will be generated automatically';
const DEFAULT_MEDIA_QUERY =
  '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)';
const DEFAULT_RETINA_SUFFIX = '@2x';
const IMAGE_PROPERTY_REGEX = new RegExp(
  /^(background(-image))|(list-style-image)?$/
);
const URL_EXTRACT_REGEX = new RegExp(/url\((?:'|")?(.*?)(?:'|")?\)/);
const PROPERTY_TRANSLATIONS = {
  background: 'background-image',
  'background-image': 'background-image',
  'list-style-image': 'list-style-image'
};
const INCLUDE_FILE_EXT = ['.png', '.jpeg', '.jpg'];

function backgroundImagePath(decl) {
  const { value } = decl;
  const backgroundPropertyPath = URL_EXTRACT_REGEX.exec(value);

  return backgroundPropertyPath && backgroundPropertyPath[1];
}

function missingRetinaImageWarning(image) {
  return `Could not find retina version for \`${image}\``;
}

function retinaBackgroundImage(options) {
  return function(root, result) {
    const ruleSource = root.source.input.file;
    const retinaSuffix = options.retinaSuffix || DEFAULT_RETINA_SUFFIX;
    const mediaQueryOption = options.mediaQuery || DEFAULT_MEDIA_QUERY;
    const includeFileExt = options.includeFileExtensions || INCLUDE_FILE_EXT;
    const ruleBlacklist = {};
    let assetDirectory = options.assetDirectory;
    let newMediaQueries = [];

    if (!Array.isArray(includeFileExt)) {
      throw new Error(
        'Option `includeFileExtensions` must be an array. You passed: ' +
          includeFileExt
      );
    }

    if (!assetDirectory) {
      if (typeof ruleSource === 'string') {
        assetDirectory = dirname(ruleSource);
      } else {
        throw new Error('You must provide an asset directory');
      }
    }

    root.walkAtRules('media', function(atRule) {
      const { params } = atRule;

      if (!queryCoversRange(mediaQueryOption, params)) {
        return;
      }

      atRule.walkRules(function(rule) {
        const { selector } = rule;

        rule.walkDecls(IMAGE_PROPERTY_REGEX, function(decl) {
          const imgPath = backgroundImagePath(decl);

          if (imgPath) {
            ruleBlacklist[params] = ruleBlacklist[params] || {};
            ruleBlacklist[params][selector] = { imgPath, decl };
          }
        });
      });
    });

    root.walkRules(function(rule) {
      const { selector } = rule;
      const { parent: parentRule } = rule;
      let mediaQuery = mediaQueryOption;

      // The rule to add the new media query after
      let anchor = rule;

      // If the rule is inside a media query...
      if (parentRule && nodeIsMediaQuery(parentRule)) {
        // Short-circuit if the rule is already inside a retina media query
        if (queryCoversRange(mediaQueryOption, parentRule.params)) {
          return;
        }

        // Add the new media query after the parent one
        anchor = parentRule;
        mediaQuery = distributeQueryAcrossQuery(mediaQuery, parentRule.params);
      }

      // Create the media query and rule that we'll attach declarations to
      const mq = postcss.atRule({ name: 'media', params: mediaQuery });
      const ruleInMediaQuery = postcss.rule({ selector: rule.selector });
      mq.append(ruleInMediaQuery);

      rule.walkDecls(IMAGE_PROPERTY_REGEX, function(decl) {
        const { prop, value } = decl;

        let backgroundsList = value.split(',');
        let newBackgroundsList = [];
        let retinaImagesFound = false;

        for (let i = 0; i < backgroundsList.length; i++) {
          let backgroundPropertyPath = URL_EXTRACT_REGEX.exec(
            backgroundsList[i]
          );
          if (!(backgroundPropertyPath && backgroundPropertyPath[1])) {
            return;
          }
          const relativeImagePath = backgroundPropertyPath[1];
          if (isFullUrlPath(relativeImagePath)) {
            return;
          }
          const fileExtension = extname(relativeImagePath);
          if (includeFileExt.indexOf(fileExtension) === -1) {
            return;
          }
          let retinaImagePath = findRetinaImage(
            relativeImagePath,
            assetDirectory,
            retinaSuffix
          );
          if (!retinaImagePath) {
            decl.warn(result, missingRetinaImageWarning(relativeImagePath));
            retinaImagePath = backgroundPropertyPath[i];
          } else {
            retinaImagesFound = true;
          }
          if (
            ruleBlacklist[mediaQuery] &&
            ruleBlacklist[mediaQuery][selector]
          ) {
            const { imgPath, decl: existingDecl } = ruleBlacklist[mediaQuery][
              selector
            ];

            if (imgPath === retinaImagePath) {
              existingDecl.warn(result, UNNECESSARY_RETINA_IMAGE_WARNING);
            }

            return;
          }
          newBackgroundsList.push(retinaImagePath);
        }

        let newDecl = newBackgroundsList.map(function(bkg) {
          return `url('${bkg}')`;
        });

        if (retinaImagesFound) {
          const retinaImageDecl = postcss.decl({
            prop: PROPERTY_TRANSLATIONS[prop],
            value: `${newDecl.join(', ')};`
          });
          ruleInMediaQuery.append(retinaImageDecl);
        }
      });

      // Only add the media query to the page if there are declarations in it
      if (ruleInMediaQuery.nodes.length > 0) {
        newMediaQueries.push({ anchor, mq });
      }
    });

    // Insert the media query after the rule in the root
    newMediaQueries.forEach(function({ anchor, mq }) {
      root.insertAfter(anchor, mq);
    });
  };
}

module.exports = postcss.plugin('postcss-retina-bg-img', retinaBackgroundImage);
module.exports.DEFAULT_MEDIA_QUERY = DEFAULT_MEDIA_QUERY;
<|endoftext|>