<commit_before>import React from "react";
import { Dimensions, FlatList, StyleSheet, View } from "react-native";
import { withTrackScrollDepth } from "@times-components/tracking";
import ErrorView from "@times-components/error-view";
import AuthorProfileAuthorHead from "./author-profile-author-head";
import AuthorProfilePagination from "./author-profile-pagination";
import AuthorProfileItem from "./author-profile-item";
import AuthorProfileItemSeparator from "./author-profile-item-separator";
import { propTypes, defaultProps } from "./author-profile-content-prop-types";
import AuthorProfileListingError from "./author-profile-listing-error";
import { normaliseWidth } from "./utils";

const styles = StyleSheet.create({
  padding: {
    paddingLeft: 10,
    paddingRight: 10
  },
  errorContainer: {
    flex: 1,
    margin: 15
  }
});

const viewabilityConfig = {
  viewAreaCoveragePercentThreshold: 100,
  waitForInteraction: false
};

class AuthorProfileContent extends React.Component {
  constructor(props) {
    super(props);

    const { width } = Dimensions.get("window");

    this.state = {
      width: normaliseWidth(width)
    };
    this.onViewableItemsChanged = this.onViewableItemsChanged.bind(this);
  }

  componentWillUnmount() {
    global.cancelAnimationFrame(this.scrollAnimationFrame);
  }

  onViewableItemsChanged(info) {
    if (!info.changed.length) return [];

    return info.changed
      .filter(viewableItem => viewableItem.isViewable)
      .map(
        viewableItem =>
          this.props.onViewed &&
          this.props.onViewed(viewableItem.item, this.props.articles)
      );
  }

  render() {
    const {
      count,
      isLoading,
      articles,
      articlesLoading,
      biography,
      jobTitle,
      name,
      onArticlePress,
      onNext,
      onPrev,
      onTwitterLinkPress,
      page,
      pageSize,
      twitter,
      uri,
      imageRatio,
      showImages,
      error,
      refetch
    } = this.props;

    const AuthorHead = (
      <AuthorProfileAuthorHead
        isLoading={isLoading}
        name={name}
        bio={biography}
        uri={uri}
        title={jobTitle}
        twitter={twitter}
        onTwitterLinkPress={onTwitterLinkPress}
      />
    );

    if (error) {
      return (
        <View style={styles.errorContainer}>
          {AuthorHead}
          <AuthorProfileListingError refetch={refetch} />
        </View>
      );
    }

    const scrollToTopNextFrame = () => {
      this.scrollAnimationFrame = global.requestAnimationFrame(() => {
        this.listRef.scrollToOffset({
          offset: 0,
          animated: true
        });
      });
    };

    const paginationComponent = (
      { hideResults = false, autoScroll = false } = {}
    ) => (
      <AuthorProfilePagination
        count={count}
        hideResults={hideResults}
        onNext={(...args) => {
          onNext(...args);
          if (autoScroll) scrollToTopNextFrame();
        }}
        onPrev={(...args) => {
          onPrev(...args);
          if (autoScroll) scrollToTopNextFrame();
        }}
        page={page}
        pageSize={pageSize}
      />
    );

    const data = articlesLoading
      ? Array(pageSize)
          .fill()
          .map((number, indx) => ({
            id: indx,
            elementId: `empty.${indx}`,
            isLoading: true
          }))
      : articles.map((article, indx) => ({
          ...article,
          elementId: `${article.id}.${indx}`
        }));

    if (!articlesLoading) this.props.receiveChildList(data);

    return (
      <FlatList
        ref={list => {
          this.listRef = list;
        }}
        testID="scroll-view"
        accessibilityID="scroll-view"
        data={data}
        keyExtractor={item => item.id}
        renderItem={({ item, index }) => (
          <ErrorView>
            {({ hasError }) =>
              hasError ? null : (
                <AuthorProfileItem
                  {...item}
                  imageRatio={imageRatio}
                  imageSize={this.state.width}
                  showImage={showImages}
                  style={styles.padding}
                  testID={`articleList-${index}`}
                  onPress={e =>
                    onArticlePress(e, { id: item.id, url: item.url })
                  }
                />
              )
            }
          </ErrorView>
        )}
        initialListSize={pageSize}
        onViewableItemsChanged={this.onViewableItemsChanged}
        viewabilityConfig={viewabilityConfig}
        scrollRenderAheadDistance={2}
        pageSize={pageSize}
        ListHeaderComponent={
          <View>
            <AuthorProfileAuthorHead
              isLoading={isLoading}
              name={name}
              bio={biography}
              uri={uri}
              title={jobTitle}
              twitter={twitter}
              onTwitterLinkPress={onTwitterLinkPress}
            />
            {paginationComponent({ hideResults: false, autoScroll: false })}
          </View>
        }
        ListFooterComponent={paginationComponent({
          hideResults: true,
          autoScroll: true
        })}
        ItemSeparatorComponent={() => (
          <View style={styles.padding}>
            <AuthorProfileItemSeparator />
          </View>
        )}
      />
    );
  }
}

AuthorProfileContent.propTypes = propTypes;
AuthorProfileContent.defaultProps = defaultProps;

export default withTrackScrollDepth(AuthorProfileContent);
<commit_msg>fix: Fix the warning on Native devices when viewing Author Profile (#762)<commit_after>import React from "react";
import { Dimensions, FlatList, StyleSheet, View } from "react-native";
import { withTrackScrollDepth } from "@times-components/tracking";
import ErrorView from "@times-components/error-view";
import AuthorProfileAuthorHead from "./author-profile-author-head";
import AuthorProfilePagination from "./author-profile-pagination";
import AuthorProfileItem from "./author-profile-item";
import AuthorProfileItemSeparator from "./author-profile-item-separator";
import { propTypes, defaultProps } from "./author-profile-content-prop-types";
import AuthorProfileListingError from "./author-profile-listing-error";
import { normaliseWidth } from "./utils";

const styles = StyleSheet.create({
  padding: {
    paddingLeft: 10,
    paddingRight: 10
  },
  errorContainer: {
    flex: 1,
    margin: 15
  }
});

const viewabilityConfig = {
  viewAreaCoveragePercentThreshold: 100,
  waitForInteraction: false
};

class AuthorProfileContent extends React.Component {
  constructor(props) {
    super(props);

    const { width } = Dimensions.get("window");

    this.state = {
      width: normaliseWidth(width)
    };
    this.onViewableItemsChanged = this.onViewableItemsChanged.bind(this);
  }

  componentWillUnmount() {
    global.cancelAnimationFrame(this.scrollAnimationFrame);
  }

  onViewableItemsChanged(info) {
    if (!info.changed.length) return [];

    return info.changed
      .filter(viewableItem => viewableItem.isViewable)
      .map(
        viewableItem =>
          this.props.onViewed &&
          this.props.onViewed(viewableItem.item, this.props.articles)
      );
  }

  render() {
    const {
      count,
      isLoading,
      articles,
      articlesLoading,
      biography,
      jobTitle,
      name,
      onArticlePress,
      onNext,
      onPrev,
      onTwitterLinkPress,
      page,
      pageSize,
      twitter,
      uri,
      imageRatio,
      showImages,
      error,
      refetch
    } = this.props;

    const AuthorHead = (
      <AuthorProfileAuthorHead
        isLoading={isLoading}
        name={name}
        bio={biography}
        uri={uri}
        title={jobTitle}
        twitter={twitter}
        onTwitterLinkPress={onTwitterLinkPress}
      />
    );

    if (error) {
      return (
        <View style={styles.errorContainer}>
          {AuthorHead}
          <AuthorProfileListingError refetch={refetch} />
        </View>
      );
    }

    const scrollToTopNextFrame = () => {
      this.scrollAnimationFrame = global.requestAnimationFrame(() => {
        this.listRef.scrollToOffset({
          offset: 0,
          animated: true
        });
      });
    };

    const paginationComponent = (
      { hideResults = false, autoScroll = false } = {}
    ) => (
      <AuthorProfilePagination
        count={count}
        hideResults={hideResults}
        onNext={(...args) => {
          onNext(...args);
          if (autoScroll) scrollToTopNextFrame();
        }}
        onPrev={(...args) => {
          onPrev(...args);
          if (autoScroll) scrollToTopNextFrame();
        }}
        page={page}
        pageSize={pageSize}
      />
    );

    const data = articlesLoading
      ? Array(pageSize)
          .fill()
          .map((number, indx) => ({
            id: indx,
            elementId: `empty.${indx}`,
            isLoading: true
          }))
      : articles.map((article, indx) => ({
          ...article,
          elementId: `${article.id}.${indx}`
        }));

    if (!articlesLoading) this.props.receiveChildList(data);

    return (
      <FlatList
        ref={list => {
          this.listRef = list;
        }}
        testID="scroll-view"
        accessibilityID="scroll-view"
        data={data}
        keyExtractor={item => `${item.id}`}
        renderItem={({ item, index }) => (
          <ErrorView>
            {({ hasError }) =>
              hasError ? null : (
                <AuthorProfileItem
                  {...item}
                  imageRatio={imageRatio}
                  imageSize={this.state.width}
                  showImage={showImages}
                  style={styles.padding}
                  testID={`articleList-${index}`}
                  onPress={e =>
                    onArticlePress(e, { id: item.id, url: item.url })
                  }
                />
              )
            }
          </ErrorView>
        )}
        initialListSize={pageSize}
        onViewableItemsChanged={this.onViewableItemsChanged}
        viewabilityConfig={viewabilityConfig}
        scrollRenderAheadDistance={2}
        pageSize={pageSize}
        ListHeaderComponent={
          <View>
            <AuthorProfileAuthorHead
              isLoading={isLoading}
              name={name}
              bio={biography}
              uri={uri}
              title={jobTitle}
              twitter={twitter}
              onTwitterLinkPress={onTwitterLinkPress}
            />
            {paginationComponent({ hideResults: false, autoScroll: false })}
          </View>
        }
        ListFooterComponent={paginationComponent({
          hideResults: true,
          autoScroll: true
        })}
        ItemSeparatorComponent={() => (
          <View style={styles.padding}>
            <AuthorProfileItemSeparator />
          </View>
        )}
      />
    );
  }
}

AuthorProfileContent.propTypes = propTypes;
AuthorProfileContent.defaultProps = defaultProps;

export default withTrackScrollDepth(AuthorProfileContent);
<|endoftext|>


<commit_before>/**
 * conjoon
 * (c) 2002-2009 siteartwork.de/conjoon.org
 * licensing@conjoon.org
 *
 * $Author$
 * $Id$
 * $Date$
 * $Revision$
 * $LastChangedDate$
 * $LastChangedBy$
 * $URL$
 */

Ext.namespace('com.conjoon.groupware.feeds');

/**
 * @class com.conjoon.groupware.feeds.FeedRunner
 *
 */
com.conjoon.groupware.feeds.FeedRunner = function(){

    var commitId = Ext.data.Record.COMMIT;

    var store = new Ext.data.Store({
        autoLoad   : false,
        reader     : new Ext.data.JsonReader({
                          root: 'items',
                          id : 'id'
                      }, com.conjoon.groupware.feeds.ItemRecord),
        baseParams  : {
            removeold : false,
            timeout   : com.conjoon.groupware.feeds.AccountStore.getTimeoutSum()
        },
        proxy : new Ext.data.HttpProxy({
            url      : './groupware/feeds/get.feed.items/format/json',
            timeout  : com.conjoon.groupware.feeds.AccountStore.getTimeoutSum()
        })
    });

    var firstTimeLoaded = false;

    var task = null;

    var runnable = false;

    var updateInterval = Number.MAX_VALUE;

    var defaultUpdateInterval = 3600;

    var onStoreLoadException = function(proxy, options, response, jsError)
    {
        com.conjoon.groupware.ResponseInspector.handleFailure(response);
    };

    var onStoreLoad = function(store, records, options)
    {
        if (!records || (records && !records.length)) {
            return;
        }

        for (var i = 0, len = records.length; i < len; i++) {
            feedStore.addSorted(records[i].copy());
        }

        store.removeAll();
        if (len > 0) {
            notifyUser(len);
        }
    };

    var onStoreChange = function(store, record, operation)
    {
        if (operation && (typeof(operation) == 'string') && operation != commitId) {
            return;
        }

        stopRunning();

        var recs = store.getRange();

        for (var i = 0, len = recs.length; i < len; i++) {
            updateInterval = Math.min(recs[i].get('updateInterval'), updateInterval);
        }

        run();
    };

    var stopRunning = function()
    {
        runnable = false;
        if (task) {
            Ext.TaskMgr.stop(task);
        }
    };

    var run = function()
    {
        task = {
            run      : updateFeeds,
            interval : (updateInterval <= 0 ?
                        defaultUpdateInterval :
                        updateInterval)*1000
        }
        Ext.TaskMgr.start(task);
    };

    var updateFeeds = function()
    {
        if (!runnable) {
            runnable = true;
            return;
        }

        if (_reception.isLocked()) {
            return;
        }

        var timeout = com.conjoon.groupware.feeds.AccountStore.getTimeoutSum();

        store.baseParams.timeout = timeout;
        store.proxy.conn.timeout = timeout;

        if (!firstTimeLoaded) {
            store.load();
            firstTimeLoaded = true;
        } else {
            store.reload();
        }

    };

    /**
     *
     * @param {Number} feedCount any value > 0
     */
    var notifyUser = function(feedCount)
    {
        var text = String.format(
            com.conjoon.Gettext.ngettext("There is one new feed entry available", "There are {0} new feed entries available", feedCount),
            feedCount
        );

        new Ext.ux.ToastWindow({
            title   : com.conjoon.Gettext.ngettext("New feed entry available", "New feed entries available", feedCount),
            html    : text
        }).show(document);

    };

    // leave this here since listener only works if observer function gets defined before
    // (stopRunning, onStoreLoad)
    var feedStore = com.conjoon.groupware.feeds.FeedStore.getInstance();
    feedStore.on('beforeload', stopRunning, com.conjoon.groupware.feeds.FeedRunner);
    store.on('load', onStoreLoad, com.conjoon.groupware.feeds.FeedRunner);
    store.on('loadexception', onStoreLoadException, com.conjoon.groupware.feeds.FeedRunner);

    var _reception = com.conjoon.groupware.Reception;

    return {

        getListener : function()
        {
            return {
                add    : onStoreChange,
                remove : onStoreChange,
                update : onStoreChange,
                load   : onStoreChange
            };
        }

    };

}();<commit_msg> - fixed: task for periodically fetching new feed items would not work properly since a listener was not properly configured (closes CN-215)<commit_after>/**
 * conjoon
 * (c) 2002-2009 siteartwork.de/conjoon.org
 * licensing@conjoon.org
 *
 * $Author$
 * $Id$
 * $Date$
 * $Revision$
 * $LastChangedDate$
 * $LastChangedBy$
 * $URL$
 */

Ext.namespace('com.conjoon.groupware.feeds');

/**
 * @class com.conjoon.groupware.feeds.FeedRunner
 *
 */
com.conjoon.groupware.feeds.FeedRunner = function(){

    var commitId = Ext.data.Record.COMMIT;

    var store = new Ext.data.Store({
        autoLoad   : false,
        reader     : new Ext.data.JsonReader({
                          root: 'items',
                          id : 'id'
                      }, com.conjoon.groupware.feeds.ItemRecord),
        baseParams  : {
            removeold : false,
            timeout   : com.conjoon.groupware.feeds.AccountStore.getTimeoutSum()
        },
        proxy : new Ext.data.HttpProxy({
            url      : './groupware/feeds/get.feed.items/format/json',
            timeout  : com.conjoon.groupware.feeds.AccountStore.getTimeoutSum()
        })
    });

    var firstTimeLoaded = false;

    var task = null;

    var runnable = false;

    var updateInterval = Number.MAX_VALUE;

    var defaultUpdateInterval = 3600;

    var onStoreLoadException = function(proxy, options, response, jsError)
    {
        com.conjoon.groupware.ResponseInspector.handleFailure(response);
    };

    var onStoreLoad = function(store, records, options)
    {
        if (!records || (records && !records.length)) {
            return;
        }

        for (var i = 0, len = records.length; i < len; i++) {
            feedStore.addSorted(records[i].copy());
        }

        store.removeAll();
        if (len > 0) {
            notifyUser(len);
        }
    };

    var onStoreChange = function(store, record, operation)
    {
        if (operation && (typeof(operation) == 'string') && operation != commitId) {
            return;
        }

        stopRunning();

        var recs = store.getRange();

        for (var i = 0, len = recs.length; i < len; i++) {
            updateInterval = Math.min(recs[i].get('updateInterval'), updateInterval);
        }

        run();
    };

    var stopRunning = function()
    {
        runnable = false;
        if (task) {
            Ext.TaskMgr.stop(task);
        }
    };

    var run = function()
    {
        task = {
            run      : updateFeeds,
            interval : (updateInterval <= 0 ?
                        defaultUpdateInterval :
                        updateInterval)*1000
        }
        Ext.TaskMgr.start(task);
    };

    var updateFeeds = function()
    {
        if (!runnable) {
            runnable = true;
            return;
        }

        if (_reception.isLocked()) {
            return;
        }

        var timeout = com.conjoon.groupware.feeds.AccountStore.getTimeoutSum();

        store.baseParams.timeout = timeout;
        store.proxy.conn.timeout = timeout;

        if (!firstTimeLoaded) {
            store.load();
            firstTimeLoaded = true;
        } else {
            store.reload();
        }

    };

    /**
     *
     * @param {Number} feedCount any value > 0
     */
    var notifyUser = function(feedCount)
    {
        var text = String.format(
            com.conjoon.Gettext.ngettext("There is one new feed entry available", "There are {0} new feed entries available", feedCount),
            feedCount
        );

        new Ext.ux.ToastWindow({
            title   : com.conjoon.Gettext.ngettext("New feed entry available", "New feed entries available", feedCount),
            html    : text
        }).show(document);

    };

    // leave this here since listener only works if observer function gets defined before
    // (stopRunning, onStoreLoad)
    var feedStore = com.conjoon.groupware.feeds.FeedStore.getInstance();
    feedStore.on('load', function() {
        this.on('beforeload', stopRunning, com.conjoon.groupware.feeds.FeedRunner);
    }, feedStore, {single : true});

    store.on('load', onStoreLoad, com.conjoon.groupware.feeds.FeedRunner);
    store.on('loadexception', onStoreLoadException, com.conjoon.groupware.feeds.FeedRunner);

    var _reception = com.conjoon.groupware.Reception;

    return {

        getListener : function()
        {
            return {
                add    : onStoreChange,
                remove : onStoreChange,
                update : onStoreChange,
                load   : onStoreChange
            };
        }

    };

}();<|endoftext|>


<commit_before>define(function(require, exports, module) {
    "use strict";

    // eager-load StarUML module dependencies
    var Dialogs = app.getModule("dialogs/Dialogs");

    // eager-load SitecoreUML module dependencies
    var SitecorePreferencesLoader = require("SitecorePreferencesLoader");

    function executeConnectivityTest() {
        var sitecoreUrl = SitecorePreferencesLoader.getSitecoreUrl();
        var route = SitecorePreferencesLoader.getSitecoreTestConnectionRoute();

        sitecoreUrl = sitecoreUrl.lastIndexOf("/") == sitecoreUrl.length - 1
            ? sitecoreUrl.substr(0, sitecoreUrl.length - 1)
            : sitecoreUrl;
        route = route.indexOf("/") == 0
            ? route
            : "/" + route;

        var getUrl = sitecoreUrl + route;
        $.getJSON(getUrl, function(data) {
            if (!data.Success) {
                console.error("Connection Error Response: ", data);
                Dialogs.showErrorDialog("Uh oh! An error occurred while attempting to connect to the Sitecore instance. Confirm that you have configured the correct settings in Preferences and try again.");
                return;
            }

            Dialogs.showAlertDialog("Connection successful!");
        });
    }

    // command ID constant
    var CMD_TESTSITECORECONNECTION = "sitecore.testsitecoreconnection";

    exports.initialize = function() {
        // eager-load the requisite StarUML modules
        var CommandManager = app.getModule("command/CommandManager");

        // register the command
        CommandManager.register("Test Connection", CMD_TESTSITECORECONNECTION, executeConnectivityTest);
        // add the menu item for the command
        var SitecoreMenuLoader = require("SitecoreMenuLoader");
        SitecoreMenuLoader.sitecoreMenu.addMenuItem(CMD_TESTSITECORECONNECTION);
    };
    exports.executeConnectivityTest = executeConnectivityTest;
    exports.CMD_TESTSITECORECONNECTION = CMD_TESTSITECORECONNECTION;
});<commit_msg>Added deferred fail handler to AJAX request and set body to display an error message with help information, should the connection test fail<commit_after>define(function(require, exports, module) {
    "use strict";

    // eager-load StarUML module dependencies
    var Dialogs = app.getModule("dialogs/Dialogs");

    // eager-load SitecoreUML module dependencies
    var SitecorePreferencesLoader = require("SitecorePreferencesLoader");

    function executeConnectivityTest() {
        var sitecoreUrl = SitecorePreferencesLoader.getSitecoreUrl();
        var route = SitecorePreferencesLoader.getSitecoreTestConnectionRoute();

        sitecoreUrl = sitecoreUrl.lastIndexOf("/") == sitecoreUrl.length - 1
            ? sitecoreUrl.substr(0, sitecoreUrl.length - 1)
            : sitecoreUrl;
        route = route.indexOf("/") == 0
            ? route
            : "/" + route;

        var getUrl = sitecoreUrl + route;
        $.getJSON(getUrl, function(data) {
            if (!data.Success) {
                console.error("Connection Error Response: ", data);
                Dialogs.showErrorDialog("Uh oh! An error occurred while attempting to connect to the Sitecore instance. Confirm that you have configured the correct settings in Preferences and try again.");
                return;
            }

            Dialogs.showAlertDialog("Connection successful!");
        })
        .fail(function(jqxhr, statusText, error) {
            var errorObject = { statusText: statusText, error: error, jqxhr: jqxhr };
            console.error("Connection Test Failed:", errorObject);
            Dialogs.showErrorDialog("
Connection Test Failed!

Check that the Sitecore URL setting in File → Preferences → Sitecore is pointing at your instance.

See the DevTools console for more details.
");
        });
    }

    // command ID constant
    var CMD_TESTSITECORECONNECTION = "sitecore.testsitecoreconnection";

    exports.initialize = function() {
        // eager-load the requisite StarUML modules
        var CommandManager = app.getModule("command/CommandManager");

        // register the command
        CommandManager.register("Test Connection", CMD_TESTSITECORECONNECTION, executeConnectivityTest);
        // add the menu item for the command
        var SitecoreMenuLoader = require("SitecoreMenuLoader");
        SitecoreMenuLoader.sitecoreMenu.addMenuItem(CMD_TESTSITECORECONNECTION);
    };
    exports.executeConnectivityTest = executeConnectivityTest;
    exports.CMD_TESTSITECORECONNECTION = CMD_TESTSITECORECONNECTION;
});<|endoftext|>


<commit_before>const moment = require('moment');
const DiscordJS = require('discord.js');
const Command = require('../Command');
const pack = require('../../../package.json');

require('moment-duration-format');

const unit = ['', 'K', 'M', 'G', 'T', 'P'];
const GetUptime = bot => moment.duration(bot.uptime).format('d[ days], h[ hours], m[ minutes, and ]s[ seconds]');
const bytesToSize = (input, precision) => {
  let index = Math.floor(Math.log(input) / Math.log(1024));
  if (unit >= unit.length) return `${input} B`;
  let msg = `${(input / Math.pow(1024, index)).toFixed(precision)} ${unit[index]}B`;
  return msg;
};

class StatsCommand extends Command {
  constructor(bot) {
    super(bot);
    this.props.help = {
      name: 'stats',
      description: 'Shows some stats of the bot... what else?',
      usage: 'stats',
    };
    this.setConf({
      aliases: ['info'],
    });
  }
  run(msg) {
    let bot = this.bot;
    let MemoryUsage = bytesToSize(process.memoryUsage().heapUsed, 3);
    let Booted = bot.booted;
    let Channels = bot.channels;
    let TextChannels = Channels.filter(e => e.type !== 'voice').size;
    let VoiceChannels = Channels.filter(e => e.type === 'voice').size;

    const embed = {
      color: 0xFD9827,
      author: {
        name: bot.user.username,
        icon_url: bot.user.avatarURL,
      },
      description: '**Yappy, the Gitlab Monitor Stats**',
      fields: [
        {
          name: '❯ Uptime',
          value: GetUptime(bot),
          inline: true,
        },
        {
          name: '❯ Booted',
          value: `${Booted.date} ${Booted.time}`,
          inline: true,
        },
        {
          name: '❯ Memory Usage',
          value: MemoryUsage,
          inline: true,
        },
        {
          name: '\u200B',
          value: '\u200B',
          inline: false,
        },
        {
          name: '❯ Guilds',
          value: bot.guilds.size,
          inline: true,
        },
        {
          name: '❯ Channels',
          value: `${Channels.size} (${TextChannels} text, ${VoiceChannels} voice)`,
          inline: true,
        },
        {
          name: '❯ Users',
          value: bot.users.size,
          inline: true,
        },
        {
          name: '\u200B',
          value: '\u200B',
          inline: false,
        },
        {
          name: '❯ Author',
          value: pack.author.replace(/<\S+[@]\S+[.]\S+>/g, ''),
          inline: true,
        },
        {
          name: '❯ Version',
          value: pack.version,
          inline: true,
        },
        {
          name: '❯ DiscordJS',
          value: `v${DiscordJS.version}`,
          inline: true,
        },
      ],
    };

    return msg.channel.send({ embed });
  }
}

module.exports = StatsCommand;
<commit_msg>fix(discord: commands): fix stats' embed iconURL, and change to use footer<commit_after>const moment = require('moment');
const DiscordJS = require('discord.js');
const Command = require('../Command');
const pack = require('../../../package.json');

require('moment-duration-format');

const unit = ['', 'K', 'M', 'G', 'T', 'P'];
const GetUptime = bot => moment.duration(bot.uptime).format('d[ days], h[ hours], m[ minutes, and ]s[ seconds]');
const bytesToSize = (input, precision) => {
  let index = Math.floor(Math.log(input) / Math.log(1024));
  if (unit >= unit.length) return `${input} B`;
  let msg = `${(input / Math.pow(1024, index)).toFixed(precision)} ${unit[index]}B`;
  return msg;
};

class StatsCommand extends Command {
  constructor(bot) {
    super(bot);
    this.props.help = {
      name: 'stats',
      description: 'Shows some stats of the bot... what else?',
      usage: 'stats',
    };
    this.setConf({
      aliases: ['info'],
    });
  }
  run(msg) {
    const bot = this.bot;
    const MemoryUsage = bytesToSize(process.memoryUsage().heapUsed, 3);
    const Booted = bot.booted;
    const Channels = bot.channels;
    const TextChannels = Channels.filter(e => e.type !== 'voice').size;
    const VoiceChannels = Channels.filter(e => e.type === 'voice').size;

    const embed = {
      color: 0xFD9827,
      footer: {
        text: bot.user.username,
        iconURL: bot.user.avatarURL(),
      },
      description: '**Yappy, the Gitlab Monitor Stats**',
      fields: [
        {
          name: '❯ Uptime',
          value: GetUptime(bot),
          inline: true,
        },
        {
          name: '❯ Booted',
          value: `${Booted.date} ${Booted.time}`,
          inline: true,
        },
        {
          name: '❯ Memory Usage',
          value: MemoryUsage,
          inline: true,
        },
        {
          name: '\u200B',
          value: '\u200B',
          inline: false,
        },
        {
          name: '❯ Guilds',
          value: bot.guilds.size,
          inline: true,
        },
        {
          name: '❯ Channels',
          value: `${Channels.size} (${TextChannels} text, ${VoiceChannels} voice)`,
          inline: true,
        },
        {
          name: '❯ Users',
          value: bot.users.size,
          inline: true,
        },
        {
          name: '\u200B',
          value: '\u200B',
          inline: false,
        },
        {
          name: '❯ Author',
          value: pack.author.replace(/<\S+[@]\S+[.]\S+>/g, ''),
          inline: true,
        },
        {
          name: '❯ Version',
          value: pack.version,
          inline: true,
        },
        {
          name: '❯ DiscordJS',
          value: `v${DiscordJS.version}`,
          inline: true,
        },
      ],
    };

    return msg.channel.send({ embed });
  }
}

module.exports = StatsCommand;
<|endoftext|>


<commit_before>'use strict';
var mongoose = require('./mongo.js');
var handlebars = require('handlebars');
var data = require('./dataProxy.js');
var fs = require('fs');

//Define Models
var Page = mongoose.model('page', require('../schemas/page.js'));
var View = mongoose.model('view', require('../schemas/view.js'));

//Define empty object
var renderer = {};

renderer.renderPage = function (pageID) {
  Page
    .findOne({'_id': pageID})
    .populate("views")
    .exec(function (err, page) {
      if (err) {
        throw err;
      } else if (!page) {
        // how should we handle non-existing ids?
        throw null;
      } else {
        // Iterate properties for each language
        page.properties.forEach(function (elem) {

          var tempViewHTML = [];

          //Render HTML for each View
          page.views.forEach(function (view) {
            // render view with current page language
            renderer.renderView(view, elem.language, function (html) {
              tempViewHTML.push({'_id': view._id, 'html': html});
            });
          });

          //Fill template with HTML from Views (concat them)
          var html = tempViewHTML.reduce(function (iv, el) {
            return iv + el.html;
          }, "");

          //Read page template
          var handlebarsTemplate = data.readDerFuehrer();

          var pageHtml = handlebars.compile(handlebarsTemplate)({'content': html});

          fs.writeFile("rendered.html", pageHtml);

        });

      }
    });

  //1. Grab all views for this page
  //2. For each view, execute this.renderView
  //3. wait for the callback
  //4. Render the page by combining the view HTML files
  //5. Save the rendered page as HTML with timestamp

};

/**
 * Searches for the localized language string, and falls back to german if nothing is found.
 * @param view
 * @param language
 * @returns {*}
 */
renderer.getVariables = function (view, language) {
  return view.variables.reduce(function (iv, v) {
    iv[v.name] = (v.values.find(e => e.language === language) || v.values.find(e => e.language === 'de'))['value'];
    return iv;
  }, {});
};

renderer.renderView = function (view, language, cb) {
  //Read page template
  var handlebarsTemplate = data.readTemplateFile('partials', view.templateName);

  //Compile template to function
  var compiledTemplate = handlebars.compile(handlebarsTemplate);

  console.log(renderer.getVariables(view, language));

  //Callback with completed html
  cb(compiledTemplate());

  //1. Grab the template for this view
  //2. Combine the template with the vars from the view
  //3. Render the view and save as atomic HTML file with timestamp

};

module.exports = renderer;
<commit_msg>added comments<commit_after>'use strict';
var mongoose = require('./mongo.js');
var handlebars = require('handlebars');
var data = require('./dataProxy.js');
var fs = require('fs');

//Define Models
var Page = mongoose.model('page', require('../schemas/page.js'));
var View = mongoose.model('view', require('../schemas/view.js'));

//Define empty object
var renderer = {};

renderer.renderPage = function (pageID) {
  Page
    .findOne({'_id': pageID})
    .populate("views")
    .exec(function (err, page) {
      if (err) {
        throw err;
      } else if (!page) {
        // how should we handle non-existing ids?
        throw null;
      } else {
        // Iterate properties for each language
        page.properties.forEach(function (elem) {

          var tempViewHTML = [];

          //Render HTML for each View
          page.views.forEach(function (view) {
            // render view with current page language
            renderer.renderView(view, elem.language, function (html) {
              tempViewHTML.push({'_id': view._id, 'html': html});
            });
          });

          //Fill template with HTML from Views (concat them)
          var html = tempViewHTML.reduce(function (iv, el) {
            return iv + el.html;
          }, "");

          //Read page template
          var handlebarsTemplate = data.readDerFuehrer();

          var pageHtml = handlebars.compile(handlebarsTemplate)({'content': html});

          fs.writeFile("rendered.html", pageHtml);

        });

      }
    });

  //1. Grab all views for this page
  //2. For each view, execute this.renderView
  //3. wait for the callback
  //4. Render the page by combining the view HTML files
  //5. Save the rendered page as HTML with timestamp

};

/**
 * Searches for the localized language string, and falls back to german if nothing is found.
 * @param view
 * @param language
 * @returns {*}
 */
renderer.getVariables = function (view, language) {
  return view.variables.reduce(function (iv, v) {
    // search e.language === language, if this fails it falls back to e.language === 'de'
    iv[v.name] = (v.values.find(e => e.language === language) || v.values.find(e => e.language === 'de'))['value'];
    return iv;
  }, {});
};

renderer.renderView = function (view, language, cb) {
  //Read page template
  var handlebarsTemplate = data.readTemplateFile('partials', view.templateName);

  //Compile template to function
  var compiledTemplate = handlebars.compile(handlebarsTemplate);

  //Callback with completed html
  cb(compiledTemplate(renderer.getVariables(view, language)));

  //1. Grab the template for this view
  //2. Combine the template with the vars from the view
  //3. Render the view and save as atomic HTML file with timestamp

};

module.exports = renderer;
<|endoftext|>


<commit_before>// This file contains methods responsible for introspecting the current path for certain values.

import type NodePath from "./index";
import includes from "lodash/collection/includes";
import * as t from "babel-types";

/**
 * Match the current node if it matches the provided `pattern`.
 *
 * For example, given the match `React.createClass` it would match the
 * parsed nodes of `React.createClass` and `React["createClass"]`.
 */

export function matchesPattern(pattern: string, allowPartial?: boolean): boolean {
  // not a member expression
  if (!this.isMemberExpression()) return false;

  let parts = pattern.split(".");
  let search = [this.node];
  let i = 0;

  function matches(name) {
    let part = parts[i];
    return part === "*" || name === part;
  }

  while (search.length) {
    let node = search.shift();

    if (allowPartial && i === parts.length) {
      return true;
    }

    if (t.isIdentifier(node)) {
      // this part doesn't match
      if (!matches(node.name)) return false;
    } else if (t.isLiteral(node)) {
      // this part doesn't match
      if (!matches(node.value)) return false;
    } else if (t.isMemberExpression(node)) {
      if (node.computed && !t.isLiteral(node.property)) {
        // we can't deal with this
        return false;
      } else {
        search.unshift(node.property);
        search.unshift(node.object);
        continue;
      }
    } else if (t.isThisExpression(node)) {
      if (!matches("this")) return false;
    } else {
      // we can't deal with this
      return false;
    }

    // too many parts
    if (++i > parts.length) {
      return false;
    }
  }

  return i === parts.length;
}

/**
 * Check whether we have the input `key`. If the `key` references an array then we check
 * if the array has any items, otherwise we just check if it's falsy.
 */

export function has(key): boolean {
  let val = this.node && this.node[key];
  if (val && Array.isArray(val)) {
    return !!val.length;
  } else {
    return !!val;
  }
}

/**
 * Description
 */

export function isStatic() {
  return this.scope.isStatic(this.node);
}

/**
 * Alias of `has`.
 */

export let is = has;

/**
 * Opposite of `has`.
 */

export function isnt(key): boolean {
  return !this.has(key);
}

/**
 * Check whether the path node `key` strict equals `value`.
 */

export function equals(key, value): boolean {
  return this.node[key] === value;
}

/**
 * Check the type against our stored internal type of the node. This is handy when a node has
 * been removed yet we still internally know the type and need it to calculate node replacement.
 */

export function isNodeType(type: string): boolean {
  return t.isType(this.type, type);
}

/**
 * This checks whether or now we're in one of the following positions:
 *
 *   for (KEY in right);
 *   for (KEY;;);
 *
 * This is because these spots allow VariableDeclarations AND normal expressions so we need
 * to tell the path replacement that it's ok to replace this with an expression.
 */

 export function canHaveVariableDeclarationOrExpression() {
    return (this.key === "init" || this.key === "left") && this.parentPath.isFor();
 }

/**
 * Check whether the current path references a completion record
 */

export function isCompletionRecord(allowInsideFunction?) {
  let path = this;
  let first = true;

  do {
    let container = path.container;

    // we're in a function so can't be a completion record
    if (path.isFunction() && !first) {
      return !!allowInsideFunction;
    }

    first = false;

    // check to see if we're the last item in the container and if we are
    // we're a completion record!
    if (Array.isArray(container) && path.key !== container.length - 1) {
      return false;
    }
  } while ((path = path.parentPath) && !path.isProgram());

  return true;
}

/**
 * Check whether or not the current `key` allows either a single statement or block statement
 * so we can explode it if necessary.
 */

export function isStatementOrBlock() {
  if (this.parentPath.isLabeledStatement() || t.isBlockStatement(this.container)) {
    return false;
  } else {
    return includes(t.STATEMENT_OR_BLOCK_KEYS, this.key);
  }
}

/**
 * Check if the currently assigned path references the `importName` of `moduleSource`.
 */

export function referencesImport(moduleSource, importName) {
  if (!this.isReferencedIdentifier()) return false;

  let binding = this.scope.getBinding(this.node.name);
  if (!binding || binding.kind !== "module") return false;

  let path = binding.path;
  let parent = path.parentPath;
  if (!parent.isImportDeclaration()) return false;

  // check moduleSource
  if (parent.node.source.value === moduleSource) {
    if (!importName) return true;
  } else {
    return false;
  }

  if (path.isImportDefaultSpecifier() && importName === "default") {
    return true;
  }

  if (path.isImportNamespaceSpecifier() && importName === "*") {
    return true;
  }

  if (path.isImportSpecifier() && path.node.imported.name === importName) {
    return true;
  }

  return false;
}

/**
 * Get the source code associated with this node.
 */

export function getSource() {
  let node = this.node;
  if (node.end) {
    return this.hub.file.code.slice(node.start, node.end);
  } else {
    return "";
  }
}

export function willIMaybeExecuteBefore(target) {
  return this._guessExecutionStatusRelativeTo(target) !== "after";
}

/**
 * Given a `target` check the execution status of it relative to the current path.
 *
 * "Execution status" simply refers to where or not we **think** this will execuete
 * before or after the input `target` element.
 */

export function _guessExecutionStatusRelativeTo(target) {
  // check if the two paths are in different functions, we can't track execution of these
  let targetFuncParent = target.scope.getFunctionParent();
  let selfFuncParent = this.scope.getFunctionParent();

  if (targetFuncParent !== selfFuncParent) {
    let status = this._guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent);
    if (status) {
      return status;
    } else {
      target = targetFuncParent.path;
    }
  }

  let targetPaths = target.getAncestry();
  if (targetPaths.indexOf(this) >= 0) return "after";

  let selfPaths   = this.getAncestry();

  // get ancestor where the branches intersect
  let commonPath;
  let targetIndex;
  let selfIndex;
  for (selfIndex = 0; selfIndex < selfPaths.length; selfIndex++) {
    let selfPath = selfPaths[selfIndex];
    targetIndex = targetPaths.indexOf(selfPath);
    if (targetIndex >= 0) {
      commonPath = selfPath;
      break;
    }
  }
  if (!commonPath) {
    return "before";
  }

  // get the relationship paths that associate these nodes to their common ancestor
  let targetRelationship = targetPaths[targetIndex - 1];
  let selfRelationship   = selfPaths[selfIndex - 1];
  if (!targetRelationship || !selfRelationship) {
    return "before";
  }

  // container list so let's see which one is after the other
  if (targetRelationship.listKey && targetRelationship.container === selfRelationship.container) {
    return targetRelationship.key > selfRelationship.key ? "before" : "after";
  }

  // otherwise we're associated by a parent node, check which key comes before the other
  let targetKeyPosition = t.VISITOR_KEYS[targetRelationship.type].indexOf(targetRelationship.key);
  let selfKeyPosition   = t.VISITOR_KEYS[selfRelationship.type].indexOf(selfRelationship.key);
  return targetKeyPosition > selfKeyPosition ? "before" : "after";
}

export function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent) {
  let targetFuncPath = targetFuncParent.path;
  if (!targetFuncPath.isFunctionDeclaration()) return;

  // so we're in a completely different function, if this is a function declaration
  // then we can be a bit smarter and handle cases where the function is either
  // a. not called at all (part of an export)
  // b. called directly
  let binding = targetFuncPath.scope.getBinding(targetFuncPath.node.id.name);

  // no references!
  if (!binding.references) return "before";

  let referencePaths: Array<NodePath> = binding.referencePaths;

  // verify that all of the references are calls
  for (let path of referencePaths) {
    if (path.key !== "callee" || !path.parentPath.isCallExpression()) {
      return;
    }
  }

  let allStatus;

  // verify that all the calls have the same execution status
  for (let path of referencePaths) {
    // if a reference is a child of the function we're checking against then we can
    // safelty ignore it
    let childOfFunction = !!path.find(path => path.node === targetFuncPath.node);
    if (childOfFunction) continue;

    let status = this._guessExecutionStatusRelativeTo(path);

    if (allStatus) {
      if (allStatus !== status) return;
    } else {
      allStatus = status;
    }
  }

  return allStatus;
}

/**
 * Resolve a "pointer" `NodePath` to it's absolute path.
 */

export function resolve(dangerous, resolved) {
  return this._resolve(dangerous, resolved) || this;
}

export function _resolve(dangerous?, resolved?): ?NodePath {
  // detect infinite recursion
  // todo: possibly have a max length on this just to be safe
  if (resolved && resolved.indexOf(this) >= 0) return;

  // we store all the paths we've "resolved" in this array to prevent infinite recursion
  resolved = resolved || [];
  resolved.push(this);

  if (this.isVariableDeclarator()) {
    if (this.get("id").isIdentifier()) {
      return this.get("init").resolve(dangerous, resolved);
    } else {
      // otherwise it's a request for a pattern and that's a bit more tricky
    }
  } else if (this.isReferencedIdentifier()) {
    let binding = this.scope.getBinding(this.node.name);
    if (!binding) return;

    // reassigned so we can't really resolve it
    if (!binding.constant) return;

    // todo - lookup module in dependency graph
    if (binding.kind === "module") return;

    if (binding.path !== this) {
      let ret = binding.path.resolve(dangerous, resolved);
      if (this.find(parent => parent.node === ret.node)) return;
      return ret;
    }
  } else if (this.isTypeCastExpression()) {
    return this.get("expression").resolve(dangerous, resolved);
  } else if (dangerous && this.isMemberExpression()) {
    // this is dangerous, as non-direct target assignments will mutate it's state
    // making this resolution inaccurate

    let targetKey = this.toComputedKey();
    if (!t.isLiteral(targetKey)) return;

    let targetName = targetKey.value;

    let target = this.get("object").resolve(dangerous, resolved);

    if (target.isObjectExpression()) {
      let props = target.get("properties");
      for (let prop of (props: Array)) {
        if (!prop.isProperty()) continue;

        let key = prop.get("key");

        // { foo: obj }
        let match = prop.isnt("computed") && key.isIdentifier({ name: targetName });

        // { "foo": "obj" } or { ["foo"]: "obj" }
        match = match || key.isLiteral({ value: targetName });

        if (match) return prop.get("value").resolve(dangerous, resolved);
      }
    } else if (target.isArrayExpression() && !isNaN(+targetName)) {
      let elems = target.get("elements");
      let elem = elems[targetName];
      if (elem) return elem.resolve(dangerous, resolved);
    }
  }
}
<commit_msg>add comment<commit_after>// This file contains methods responsible for introspecting the current path for certain values.

import type NodePath from "./index";
import includes from "lodash/collection/includes";
import * as t from "babel-types";

/**
 * Match the current node if it matches the provided `pattern`.
 *
 * For example, given the match `React.createClass` it would match the
 * parsed nodes of `React.createClass` and `React["createClass"]`.
 */

export function matchesPattern(pattern: string, allowPartial?: boolean): boolean {
  // not a member expression
  if (!this.isMemberExpression()) return false;

  let parts = pattern.split(".");
  let search = [this.node];
  let i = 0;

  function matches(name) {
    let part = parts[i];
    return part === "*" || name === part;
  }

  while (search.length) {
    let node = search.shift();

    if (allowPartial && i === parts.length) {
      return true;
    }

    if (t.isIdentifier(node)) {
      // this part doesn't match
      if (!matches(node.name)) return false;
    } else if (t.isLiteral(node)) {
      // this part doesn't match
      if (!matches(node.value)) return false;
    } else if (t.isMemberExpression(node)) {
      if (node.computed && !t.isLiteral(node.property)) {
        // we can't deal with this
        return false;
      } else {
        search.unshift(node.property);
        search.unshift(node.object);
        continue;
      }
    } else if (t.isThisExpression(node)) {
      if (!matches("this")) return false;
    } else {
      // we can't deal with this
      return false;
    }

    // too many parts
    if (++i > parts.length) {
      return false;
    }
  }

  return i === parts.length;
}

/**
 * Check whether we have the input `key`. If the `key` references an array then we check
 * if the array has any items, otherwise we just check if it's falsy.
 */

export function has(key): boolean {
  let val = this.node && this.node[key];
  if (val && Array.isArray(val)) {
    return !!val.length;
  } else {
    return !!val;
  }
}

/**
 * Description
 */

export function isStatic() {
  return this.scope.isStatic(this.node);
}

/**
 * Alias of `has`.
 */

export let is = has;

/**
 * Opposite of `has`.
 */

export function isnt(key): boolean {
  return !this.has(key);
}

/**
 * Check whether the path node `key` strict equals `value`.
 */

export function equals(key, value): boolean {
  return this.node[key] === value;
}

/**
 * Check the type against our stored internal type of the node. This is handy when a node has
 * been removed yet we still internally know the type and need it to calculate node replacement.
 */

export function isNodeType(type: string): boolean {
  return t.isType(this.type, type);
}

/**
 * This checks whether or now we're in one of the following positions:
 *
 *   for (KEY in right);
 *   for (KEY;;);
 *
 * This is because these spots allow VariableDeclarations AND normal expressions so we need
 * to tell the path replacement that it's ok to replace this with an expression.
 */

 export function canHaveVariableDeclarationOrExpression() {
    return (this.key === "init" || this.key === "left") && this.parentPath.isFor();
 }

/**
 * Check whether the current path references a completion record
 */

export function isCompletionRecord(allowInsideFunction?) {
  let path = this;
  let first = true;

  do {
    let container = path.container;

    // we're in a function so can't be a completion record
    if (path.isFunction() && !first) {
      return !!allowInsideFunction;
    }

    first = false;

    // check to see if we're the last item in the container and if we are
    // we're a completion record!
    if (Array.isArray(container) && path.key !== container.length - 1) {
      return false;
    }
  } while ((path = path.parentPath) && !path.isProgram());

  return true;
}

/**
 * Check whether or not the current `key` allows either a single statement or block statement
 * so we can explode it if necessary.
 */

export function isStatementOrBlock() {
  if (this.parentPath.isLabeledStatement() || t.isBlockStatement(this.container)) {
    return false;
  } else {
    return includes(t.STATEMENT_OR_BLOCK_KEYS, this.key);
  }
}

/**
 * Check if the currently assigned path references the `importName` of `moduleSource`.
 */

export function referencesImport(moduleSource, importName) {
  if (!this.isReferencedIdentifier()) return false;

  let binding = this.scope.getBinding(this.node.name);
  if (!binding || binding.kind !== "module") return false;

  let path = binding.path;
  let parent = path.parentPath;
  if (!parent.isImportDeclaration()) return false;

  // check moduleSource
  if (parent.node.source.value === moduleSource) {
    if (!importName) return true;
  } else {
    return false;
  }

  if (path.isImportDefaultSpecifier() && importName === "default") {
    return true;
  }

  if (path.isImportNamespaceSpecifier() && importName === "*") {
    return true;
  }

  if (path.isImportSpecifier() && path.node.imported.name === importName) {
    return true;
  }

  return false;
}

/**
 * Get the source code associated with this node.
 */

export function getSource() {
  let node = this.node;
  if (node.end) {
    return this.hub.file.code.slice(node.start, node.end);
  } else {
    return "";
  }
}

export function willIMaybeExecuteBefore(target) {
  return this._guessExecutionStatusRelativeTo(target) !== "after";
}

/**
 * Given a `target` check the execution status of it relative to the current path.
 *
 * "Execution status" simply refers to where or not we **think** this will execuete
 * before or after the input `target` element.
 */

export function _guessExecutionStatusRelativeTo(target) {
  // check if the two paths are in different functions, we can't track execution of these
  let targetFuncParent = target.scope.getFunctionParent();
  let selfFuncParent = this.scope.getFunctionParent();

  if (targetFuncParent !== selfFuncParent) {
    let status = this._guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent);
    if (status) {
      return status;
    } else {
      target = targetFuncParent.path;
    }
  }

  let targetPaths = target.getAncestry();
  if (targetPaths.indexOf(this) >= 0) return "after";

  let selfPaths   = this.getAncestry();

  // get ancestor where the branches intersect
  let commonPath;
  let targetIndex;
  let selfIndex;
  for (selfIndex = 0; selfIndex < selfPaths.length; selfIndex++) {
    let selfPath = selfPaths[selfIndex];
    targetIndex = targetPaths.indexOf(selfPath);
    if (targetIndex >= 0) {
      commonPath = selfPath;
      break;
    }
  }
  if (!commonPath) {
    return "before";
  }

  // get the relationship paths that associate these nodes to their common ancestor
  let targetRelationship = targetPaths[targetIndex - 1];
  let selfRelationship   = selfPaths[selfIndex - 1];
  if (!targetRelationship || !selfRelationship) {
    return "before";
  }

  // container list so let's see which one is after the other
  if (targetRelationship.listKey && targetRelationship.container === selfRelationship.container) {
    return targetRelationship.key > selfRelationship.key ? "before" : "after";
  }

  // otherwise we're associated by a parent node, check which key comes before the other
  let targetKeyPosition = t.VISITOR_KEYS[targetRelationship.type].indexOf(targetRelationship.key);
  let selfKeyPosition   = t.VISITOR_KEYS[selfRelationship.type].indexOf(selfRelationship.key);
  return targetKeyPosition > selfKeyPosition ? "before" : "after";
}

export function _guessExecutionStatusRelativeToDifferentFunctions(targetFuncParent) {
  let targetFuncPath = targetFuncParent.path;
  if (!targetFuncPath.isFunctionDeclaration()) return;

  // so we're in a completely different function, if this is a function declaration
  // then we can be a bit smarter and handle cases where the function is either
  // a. not called at all (part of an export)
  // b. called directly
  let binding = targetFuncPath.scope.getBinding(targetFuncPath.node.id.name);

  // no references!
  if (!binding.references) return "before";

  let referencePaths: Array<NodePath> = binding.referencePaths;

  // verify that all of the references are calls
  for (let path of referencePaths) {
    if (path.key !== "callee" || !path.parentPath.isCallExpression()) {
      return;
    }
  }

  let allStatus;

  // verify that all the calls have the same execution status
  for (let path of referencePaths) {
    // if a reference is a child of the function we're checking against then we can
    // safelty ignore it
    let childOfFunction = !!path.find(path => path.node === targetFuncPath.node);
    if (childOfFunction) continue;

    let status = this._guessExecutionStatusRelativeTo(path);

    if (allStatus) {
      if (allStatus !== status) return;
    } else {
      allStatus = status;
    }
  }

  return allStatus;
}

/**
 * Resolve a "pointer" `NodePath` to it's absolute path.
 */

export function resolve(dangerous, resolved) {
  return this._resolve(dangerous, resolved) || this;
}

export function _resolve(dangerous?, resolved?): ?NodePath {
  // detect infinite recursion
  // todo: possibly have a max length on this just to be safe
  if (resolved && resolved.indexOf(this) >= 0) return;

  // we store all the paths we've "resolved" in this array to prevent infinite recursion
  resolved = resolved || [];
  resolved.push(this);

  if (this.isVariableDeclarator()) {
    if (this.get("id").isIdentifier()) {
      return this.get("init").resolve(dangerous, resolved);
    } else {
      // otherwise it's a request for a pattern and that's a bit more tricky
    }
  } else if (this.isReferencedIdentifier()) {
    let binding = this.scope.getBinding(this.node.name);
    if (!binding) return;

    // reassigned so we can't really resolve it
    if (!binding.constant) return;

    // todo - lookup module in dependency graph
    if (binding.kind === "module") return;

    if (binding.path !== this) {
      let ret = binding.path.resolve(dangerous, resolved);
      // If the identifier resolves to parent node then we can't really resolve it.
      if (this.find(parent => parent.node === ret.node)) return;
      return ret;
    }
  } else if (this.isTypeCastExpression()) {
    return this.get("expression").resolve(dangerous, resolved);
  } else if (dangerous && this.isMemberExpression()) {
    // this is dangerous, as non-direct target assignments will mutate it's state
    // making this resolution inaccurate

    let targetKey = this.toComputedKey();
    if (!t.isLiteral(targetKey)) return;

    let targetName = targetKey.value;

    let target = this.get("object").resolve(dangerous, resolved);

    if (target.isObjectExpression()) {
      let props = target.get("properties");
      for (let prop of (props: Array)) {
        if (!prop.isProperty()) continue;

        let key = prop.get("key");

        // { foo: obj }
        let match = prop.isnt("computed") && key.isIdentifier({ name: targetName });

        // { "foo": "obj" } or { ["foo"]: "obj" }
        match = match || key.isLiteral({ value: targetName });

        if (match) return prop.get("value").resolve(dangerous, resolved);
      }
    } else if (target.isArrayExpression() && !isNaN(+targetName)) {
      let elems = target.get("elements");
      let elem = elems[targetName];
      if (elem) return elem.resolve(dangerous, resolved);
    }
  }
}
<|endoftext|>


<commit_before>// Copyright (c) 2018, Compiler Explorer Authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

import fs from 'fs-extra';

import { BaseTool } from './base-tool';

export class LLVMMcaTool extends BaseTool {
    static get key() { return 'llvm-mca-tool'; }

    rewriteAsm(asm) {
        return asm
            .replace(/.hword\s/gim, '.short ')
            .replace(/offset flat:/gim, '')
            .replace(/ptr\s%fs/gim, 'PTR fs');
    }

    writeAsmFile(data, destination) {
        return fs.writeFile(destination, this.rewriteAsm(data));
    }

    async runTool(compilationInfo, inputFilepath, args) {
        if (compilationInfo.filters.binary) {
            return this.createErrorResponse('<cannot run analysis on binary>');
        }

        const rewrittenOutputFilename = compilationInfo.outputFilename + '.mca';
        await this.writeAsmFile(compilationInfo.asm, rewrittenOutputFilename);
        return super.runTool(compilationInfo, rewrittenOutputFilename, args);
    }
}
<commit_msg>Filter out some directives that seem to upset llvm-mca. Closes #1270<commit_after>// Copyright (c) 2018, Compiler Explorer Authors
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

import fs from 'fs-extra';

import { BaseTool } from './base-tool';

export class LLVMMcaTool extends BaseTool {
    static get key() {
        return 'llvm-mca-tool';
    }

    rewriteAsm(asm) {
        return asm
            .replace(/.hword\s/gim, '.short ')
            .replace(/offset flat:/gim, '')
            .replace(/ptr\s%fs/gim, 'PTR fs')
            .replace(/^\s*\.(fnstart|eabi_attribute|fpu).*/gim, ''); // https://github.com/compiler-explorer/compiler-explorer/issues/1270
    }

    writeAsmFile(data, destination) {
        return fs.writeFile(destination, this.rewriteAsm(data));
    }

    async runTool(compilationInfo, inputFilepath, args) {
        if (compilationInfo.filters.binary) {
            return this.createErrorResponse('<cannot run analysis on binary>');
        }

        const rewrittenOutputFilename = compilationInfo.outputFilename + '.mca';
        await this.writeAsmFile(compilationInfo.asm, rewrittenOutputFilename);
        return super.runTool(compilationInfo, rewrittenOutputFilename, args);
    }
}
<|endoftext|>


<commit_before>
function loadingSeeds(milestones, goals) {
  let mchildrens = milestones[0].children;
  let gchildrens = goals[0].children;
  let userId = null;
  let milestoneId = null;

  milestones.forEach(milestone => {
    const bounds = Milestones.boundsFor(milestone.period, milestone.type);
    milestoneData = _.extend(milestone, bounds, { userId });
    milestoneId = Milestones.insert(milestoneData);

    goals.forEach(goal => {
      goalData = _.extend(goal, {userId, milestoneId});
      Goals.insert(goalData);
    });

    if (mchildrens) loadingSeeds(mchildrens, gchildrens);
  });
}

Meteor.startup(function() {
  if (Milestones.find({userId: null}).count()) return;
  let milestones = YAML.eval(Assets.getText('introSeeds.yml')).seeds;
  let goals = YAML.eval(Assets.getText('introSeeds.yml')).seeds;
  loadingSeeds(milestones, goals);
});
<commit_msg>add parentId for timeline goals<commit_after>
function loadingSeeds(milestones, goals, parentGoal) {
  let mchildrens = milestones[0].children;
  let gchildrens = goals[0].children;
  let userId = null;
  let milestoneId = null;
  let gparent = null;

  milestones.forEach(milestone => {
    const bounds = Milestones.boundsFor(milestone.period, milestone.type);
    milestoneData = _.extend(milestone, bounds, { userId });
    milestoneId = Milestones.insert(milestoneData);

    goals.forEach(goal => {
      goalData = _.extend(goal, {userId, milestoneId, parentId: parentGoal});
      gparent = Goals.insert(goalData);
    });

    if (mchildrens) loadingSeeds(mchildrens, gchildrens, gparent);
  });
}

Meteor.startup(function() {
  if (Milestones.find({userId: null}).count()) return;
  let milestones = YAML.eval(Assets.getText('introSeeds.yml')).seeds;
  let goals = YAML.eval(Assets.getText('introSeeds.yml')).seeds;
  loadingSeeds(milestones, goals);
});
<|endoftext|>


<commit_before>'use strict'

var debug = require('debug')('iplocation')
var ipRegex = require('ip-regex')
var request = require('request')

var defaultProviders = [
  'https://ipapi.co/*/json/',
  'https://freegeoip.net/json/*',
  'http://ip-api.com/json/*'
]

module.exports = function () {
  var args = Array.prototype.slice.apply(arguments)

  if (args.length > 3) {
    throw new TypeError('Too many arguments.')
  }

  var ip = args[0]
  var alternativeProviders = (args[1] && Array.isArray(args[1]))
  var providers = defaultProviders.concat(alternativeProviders || [])

  var callback = alternativeProviders
    ? args[2]
    : args[1]

  if (!ipRegex().test(ip)) {
    var invalidIpError = new Error('Invalid IP address.')
    return callback
      ? callback(invalidIpError, null)
      : Promise.reject(invalidIpError)
  }

  function retry (i, callback) {
    if (!providers[i]) {
      var providerError = new Error('All providers failed.')
      return callback(providerError, null)
    }

    var url = providers[i].replace('*', ip)

    debug('trying: ' + url)

    request.get(url, function (err, response, body) {
      var json

      try {
        debug('got: ' + body)
        json = JSON.parse(body)
      } catch (ex) {
        return retry(++i, callback)
      }

      return callback(err, json)
    })
  }

  if (callback) {
    retry(0, callback)
  } else {
    return new Promise(function (resolve, reject) {
      retry(0, function (err, res) {
        if (err) return reject(err)
        else resolve(res)
      })
    })
  }
}
<commit_msg>Fix issue client side CORS issue with ipapi.co<commit_after>'use strict'

var debug = require('debug')('iplocation')
var ipRegex = require('ip-regex')
var request = require('request')

var defaultProviders = [
  'https://ipapi.co/*/json/',
  'https://freegeoip.net/json/*',
  'http://ip-api.com/json/*'
]

module.exports = function () {
  var args = Array.prototype.slice.apply(arguments)

  if (args.length > 3) {
    throw new TypeError('Too many arguments.')
  }

  var ip = args[0]
  var alternativeProviders = (args[1] && Array.isArray(args[1]))
  var providers = defaultProviders.concat(alternativeProviders || [])

  var callback = alternativeProviders
    ? args[2]
    : args[1]

  if (!ipRegex().test(ip)) {
    var invalidIpError = new Error('Invalid IP address.')
    return callback
      ? callback(invalidIpError, null)
      : Promise.reject(invalidIpError)
  }

  function retry (i, callback) {
    if (!providers[i]) {
      var providerError = new Error('All providers failed.')
      return callback(providerError, null)
    }

    var url = providers[i].replace('*', ip)

    debug('trying: ' + url)

    request.get(url, { withCredentials: false }, function (err, response, body) {
      var json

      try {
        debug('got: ' + body)
        json = JSON.parse(body)
      } catch (ex) {
        return retry(++i, callback)
      }

      return callback(err, json)
    })
  }

  if (callback) {
    retry(0, callback)
  } else {
    return new Promise(function (resolve, reject) {
      retry(0, function (err, res) {
        if (err) return reject(err)
        else resolve(res)
      })
    })
  }
}
<|endoftext|>


<commit_before>'use strict';
require('should');
const tmp = require('tmp');
const _ = require('lodash');
const fs = require('fs');
const winston = require('winston');

const helper = require('./helper');

const pingFile = require('../../src/pingfile');
const Ping = require('../../src/ping');

describe('Prompts', function() {
  winston.level = 'warning';
  this.timeout(10000);
  this.retries(3); // had an occasion where appveyor test transiently failed.

  var Application = require('spectron').Application;
  var app;
  var tmpPingFileName;
  var prevPing = new Ping(1234567890000, [ "previous", "tags" ], '');
  var prevPingEncoded = pingFile.encode(prevPing);

  beforeEach(function() {
    tmpPingFileName = tmp.tmpNameSync();
    fs.writeFileSync(tmpPingFileName, prevPingEncoded);
    var tmpLogFileName = tmp.tmpNameSync();
    winston.debug("Logging to " + tmpLogFileName);
    // As the pingfile changes for each test, need to recreate the app each test
    app = new Application({
      path : helper.electronPath,
      args : [
        helper.appPath, "--test", "prompt", "--pingfile", tmpPingFileName, "--logfile",
        tmpLogFileName, "--verbose", "--configdir", helper.createConfig()
      ]
    });

    return app.start();
  });

  afterEach(function() {
    // spectron struggles if the window has closed already
    // https://github.com/electron/spectron/issues/101
    // So we have the app quit when all the windows close in test mode, rather
    // than trying to stop it here.
  });

  it('should open a window', function() {
    app.client.waitUntilWindowLoaded().getWindowCount().should.eventually.equal(1);

    return app.stop();
  });

  var waitUntilSaved = async function() {
    // As the app is gone, verify the pingfile separately.
    // Note that writeSync doesn't do synchronous file i/o, so there's no
    // guarantee the pingfile exists yet! See
    // http://www.daveeddy.com/2013/03/26/synchronous-file-io-in-nodejs/

    // fs.watchFile looks like a solution, but what if the app has finished writing before the
    // watcher starts? So manually check to see if the file has more data in it than it started with
    await new Promise(function(resolve, _reject) {
      var check = function() {
        if (fs.statSync(tmpPingFileName).size > prevPingEncoded.length + 10) {
          resolve();
        } else {
          setTimeout(check, 200);
        }
      };
      setTimeout(check, 200);
    });
  };

  var saveInput = async function(tags, comment = null, button = '#save') {
    // There are two input elements in the div
    const tagsSelector = '.bootstrap-tagsinput input.tt-input';
    await app.client.waitUntil(function() { return app.client.hasFocus(tagsSelector); });
    await app.client.element(tagsSelector).setValue(tags);
    if (comment) {
      await app.client.element('#comment').setValue(comment);
    }
    if (button) {
      await app.client.click(button);
    }
  };

  var lastPingShouldEqual = function(tags, comment = null) {
    const pings = new pingFile(tmpPingFileName).pings;
    pings.length.should.equal(2);
    _.isEqual(pings[1].tags, new Set(tags)).should.equal(true);
    if (comment) {
      pings[1].comment.should.endWith(comment);
    }
  };

  it('should save a ping with tags separated by spaces and commas', async function() {
    await saveInput('tag1 tag2, tag3');
    await waitUntilSaved();
    lastPingShouldEqual([ 'tag1', 'tag2', 'tag3' ]);
  });

  it('should repeat pings when a " is entered', async function() {
    await saveInput('"');
    await waitUntilSaved();
    lastPingShouldEqual(prevPing.tags);
  });

  it('should repeat pings when the repeat button is pressed', async function() {
    await saveInput('', null, '#repeat');
    await waitUntilSaved();
    lastPingShouldEqual(prevPing.tags);
  });

  it('should save a comment', async function() {
    await saveInput('tag', 'Test comment', '#save');
    await waitUntilSaved();
    lastPingShouldEqual([ 'tag' ], 'Test comment');
  });

  it('should save on enter key', async function() {
    await saveInput('tag', null, null);
    app.client.addValue('#comment', "Enter");
    await waitUntilSaved();
    lastPingShouldEqual([ 'tag' ]);
  });
});
<commit_msg>Don't add to startup during tests<commit_after>'use strict';
require('should');
const tmp = require('tmp');
const _ = require('lodash');
const fs = require('fs');
const winston = require('winston');

const helper = require('./helper');

const pingFile = require('../../src/pingfile');
const Ping = require('../../src/ping');

describe('Prompts', function() {
  winston.level = 'warning';
  this.timeout(10000);
  this.retries(3); // had an occasion where appveyor test transiently failed.

  var Application = require('spectron').Application;
  var app;
  var tmpPingFileName;
  var prevPing = new Ping(1234567890000, [ "previous", "tags" ], '');
  var prevPingEncoded = pingFile.encode(prevPing);

  beforeEach(function() {
    tmpPingFileName = tmp.tmpNameSync();
    fs.writeFileSync(tmpPingFileName, prevPingEncoded);
    var tmpLogFileName = tmp.tmpNameSync();
    winston.debug("Logging to " + tmpLogFileName);
    // As the pingfile changes for each test, need to recreate the app each test
    app = new Application({
      path : helper.electronPath,
      args : [
        helper.appPath, "--test", "prompt", "--pingfile", tmpPingFileName, "--logfile",
        tmpLogFileName, "--verbose", "--configdir", helper.createConfig({runOnStartup : false})
      ]
    });

    return app.start();
  });

  afterEach(function() {
    // spectron struggles if the window has closed already
    // https://github.com/electron/spectron/issues/101
    // So we have the app quit when all the windows close in test mode, rather
    // than trying to stop it here.
  });

  it('should open a window', function() {
    app.client.waitUntilWindowLoaded().getWindowCount().should.eventually.equal(1);

    return app.stop();
  });

  var waitUntilSaved = async function() {
    // As the app is gone, verify the pingfile separately.
    // Note that writeSync doesn't do synchronous file i/o, so there's no
    // guarantee the pingfile exists yet! See
    // http://www.daveeddy.com/2013/03/26/synchronous-file-io-in-nodejs/

    // fs.watchFile looks like a solution, but what if the app has finished writing before the
    // watcher starts? So manually check to see if the file has more data in it than it started with
    await new Promise(function(resolve, _reject) {
      var check = function() {
        if (fs.statSync(tmpPingFileName).size > prevPingEncoded.length + 10) {
          resolve();
        } else {
          setTimeout(check, 200);
        }
      };
      setTimeout(check, 200);
    });
  };

  var saveInput = async function(tags, comment = null, button = '#save') {
    // There are two input elements in the div
    const tagsSelector = '.bootstrap-tagsinput input.tt-input';
    await app.client.waitUntil(function() { return app.client.hasFocus(tagsSelector); });
    await app.client.element(tagsSelector).setValue(tags);
    if (comment) {
      await app.client.element('#comment').setValue(comment);
    }
    if (button) {
      await app.client.click(button);
    }
  };

  var lastPingShouldEqual = function(tags, comment = null) {
    const pings = new pingFile(tmpPingFileName).pings;
    pings.length.should.equal(2);
    _.isEqual(pings[1].tags, new Set(tags)).should.equal(true);
    if (comment) {
      pings[1].comment.should.endWith(comment);
    }
  };

  it('should save a ping with tags separated by spaces and commas', async function() {
    await saveInput('tag1 tag2, tag3');
    await waitUntilSaved();
    lastPingShouldEqual([ 'tag1', 'tag2', 'tag3' ]);
  });

  it('should repeat pings when a " is entered', async function() {
    await saveInput('"');
    await waitUntilSaved();
    lastPingShouldEqual(prevPing.tags);
  });

  it('should repeat pings when the repeat button is pressed', async function() {
    await saveInput('', null, '#repeat');
    await waitUntilSaved();
    lastPingShouldEqual(prevPing.tags);
  });

  it('should save a comment', async function() {
    await saveInput('tag', 'Test comment', '#save');
    await waitUntilSaved();
    lastPingShouldEqual([ 'tag' ], 'Test comment');
  });

  it('should save on enter key', async function() {
    await saveInput('tag', null, null);
    app.client.addValue('#comment', "Enter");
    await waitUntilSaved();
    lastPingShouldEqual([ 'tag' ]);
  });
});
<|endoftext|>


<commit_before>'use strict';

/**
 * Requirements
 * @ignore
 */
const Base = require('../Base.js').Base;
const GlobalRepository = require('../model/GlobalRepository.js').GlobalRepository;
const BuildConfiguration = require('../model/configuration/BuildConfiguration.js').BuildConfiguration;
const DocumentationCallable = require('../model/documentation/DocumentationCallable.js').DocumentationCallable;
const EntityAspect = require('../model/entity/EntityAspect.js').EntityAspect;
const Parser = require('./Parser.js').Parser;
const Renderer = require('./Renderer.js').Renderer;
const Transformer = require('./Transformer.js').Transformer;
const assertParameter = require('../utils/assert.js').assertParameter;
const co = require('co');
const merge = require('lodash.merge');
const omit = require('lodash.omit');
const minimatch = require('minimatch');

/**
 * The configuration holds all macro specific settings needed
 * for exporting.
 *
 * @memberOf export
 * @extends Base
 */
class Configuration extends Base
{
    /**
     * @ignore
     */
    constructor(entity, macro, settings, parser, renderer, transformer, globalRepository, buildConfiguration)
    {
        super();

        // Check params
        assertParameter(this, 'entity', entity, false, EntityAspect);
        assertParameter(this, 'macro', macro, false, DocumentationCallable);
        assertParameter(this, 'parser', parser, false, Parser);
        assertParameter(this, 'renderer', renderer, false, Renderer);
        assertParameter(this, 'transformer', transformer, false, Transformer);
        assertParameter(this, 'globalRepository', globalRepository, true, GlobalRepository);
        assertParameter(this, 'buildConfiguration', buildConfiguration, true, BuildConfiguration);

        // Assign options
        this._macro = macro;
        this._entity = entity;
        this._settings = settings || {};
        this._parser = parser;
        this._renderer = renderer;
        this._transformer = transformer;
        this._globalRepository = globalRepository;
        this._buildConfiguration = buildConfiguration;
        this._identifier = 'default';
    }

    /**
     * @inheritDoc
     */
    static get className()
    {
        return 'export/Configuration';
    }

    /**
     * @type {model.configuration.BuildConfiguration}
     */
    get buildConfiguration()
    {
        return this._buildConfiguration;
    }

    /**
     * @type {model.GlobalRepository}
     */
    get globalRepository()
    {
        return this._globalRepository;
    }

    /**
     * The configuration identifier used to extract
     * settings from entity configurations.
     *
     * @type {String}
     */
    get identifier()
    {
        return this._identifier;
    }

    /**
     * The macro this context was created for.
     * Maybe empty.
     *
     * @type {DocumentationCallable}
     */
    get macro()
    {
        return this._macro;
    }

    /**
     * The entity this context was created for.
     *
     * @type {Entity}
     */
    get entity()
    {
        return this._entity;
    }

    /**
     * The site this context was created for.
     * Maybe empty.
     *
     * @type {Site}
     */
    get site()
    {
        return this._entity ? this._entity.site : undefined;
    }

    /**
     * The settings for this specific export.
     *
     * @type {Object}
     */
    get settings()
    {
        return this._settings;
    }

    /**
     * Access to the parser instance.
     *
     * @type {export.Parser}
     */
    get parser()
    {
        return this._parser;
    }

    /**
     * Access to the renderer instance.
     *
     * @type {export.Renderer}
     */
    get renderer()
    {
        return this._renderer;
    }

    /**
     * Access to the transformer instance.
     *
     * @type {export.Transformer}
     */
    get transformer()
    {
        return this._transformer;
    }

    /**
     * The default configurations used as a base
     * for specific configurations.
     *
     * @protected
     * @param {Object} configuration
     * @returns {Promise<Object>}
     */
    getDefaultConfiguration(configuration)
    {
        return Promise.resolve({});
    }

    /**
     * Template method to allow subclasses to make last minute changes to
     * configurations.
     *
     * @protected
     * @param {Object} configuration
     * @returns {Promise<Object>}
     */
    refineConfiguration(configuration)
    {
        return Promise.resolve(configuration);
    }

    /**
     * Resolves to the first macro that matches macroQuery.
     *
     * @protected
     * @param {String} [macroQuery]
     * @returns {Promise<model.documentation.DocumentationCallable>}
     */
    getMacro(macroQuery)
    {
        const scope = this;
        const promise = co(function *()
        {
            let macro;

            // Default is the main macro
            if (!macroQuery)
            {
                macroQuery = scope.macro;
            }

            // Get Macro
            if (macroQuery instanceof DocumentationCallable)
            {
                macro = macroQuery;
            }
            else
            {
                macro = yield scope.globalRepository.resolveMacro(scope.site, macroQuery);
            }
            if (!macro || !(macro instanceof DocumentationCallable))
            {
                return false;
            }

            return macro;
        });
        return promise;
    }

    /**
     * Resolves to the entity containing macro.
     *
     * @protected
     * @param {model.documentation.DocumentationCallable} [macro]
     * @returns {Promise<model.entity.Entity>}
     */
    getMacroEntity(macro)
    {
        return this.globalRepository.resolveEntityForMacro(this.site, macro);
    }

    /**
     * Resolves to a macro specific configuration based
     * on the default, the entity configuration and the refined.
     *
     * @param {String} [macroQuery]
     * @returns {Promise<Object>}
     */
    getMacroConfiguration(macroQuery)
    {
        if (!macroQuery)
        {
            console.trace('No Macro given!');
        }
        const scope = this;
        const promise = co(function *()
        {
            // Get macro
            const macro = yield scope.getMacro(macroQuery);
            if (!macro || !(macro instanceof DocumentationCallable))
            {
                /* istanbul ignore next */
                scope.logger.warn('getMacroConfiguration - could not find macro ' + macroQuery);
                return false;
            }

            // Get Entity
            const entity = yield scope.getMacroEntity(macro);
            if (!entity)
            {
                /* istanbul ignore next */
                scope.logger.warn('getMacroConfiguration - could not find entity for macro ' + macroQuery);
                return false;
            }

            // Basic configuration
            const basics = {};
            basics.macro = macro;
            basics.entity = entity;
            basics.site = entity.id.site;
            basics.filename = entity.pathString;
            basics.mode = 'default';

            // Extend
            const configurations = [];
            configurations.push(basics);

            // Add defaults
            configurations.push(yield scope.getDefaultConfiguration(basics));

            // Add global settings
            configurations.push(omit(basics.entity.properties.getByPath('export.settings.' + scope.identifier, {}), ['macros']));

            // Add global macro settings
            const globalMacros = basics.entity.properties.getByPath('export.settings.' + scope.identifier + '.macros', {});
            for (const match in globalMacros)
            {
                if (minimatch(basics.macro.name, match))
                {
                    configurations.push(globalMacros[match]);
                }
            }

            // Add local macro settings
            const localMacros = scope.settings.settings
                ? scope.settings.settings
                : {};
            for (const match in localMacros)
            {
                if (minimatch(basics.macro.name, match))
                {
                    configurations.push(localMacros[match]);
                }
            }

            // Add local settings
            if (scope.macro && scope.macro.name === macro.name)
            {
                configurations.push(omit(scope.settings, ['macros', 'macro']));
            }

            // Merge
            const configuration = merge(...configurations);

            // Refine
            const result = yield scope.refineConfiguration(configuration);

            // Okay
            return result;
        });
        return promise;
    }

    /**
     * Resolves to the export configuration based
     * on the default, the entity and the refined configuration.
     *
     * @returns {Promise<Object>}
     */
    getExportConfiguration()
    {
        const scope = this;
        const promise = co(function *()
        {
            // See if it's a macro export
            if (scope.macro)
            {
                const result = yield scope.getMacroConfiguration(scope.macro.name);
                return result;
            }

            // Basic configuration
            const basics = {};
            basics.entity = scope.entity;
            basics.site = scope.entity.id.site;
            basics.filename = scope.entity.pathString;

            // Extend
            const configurations = [];
            configurations.push(basics);

            // Add defaults
            configurations.push(yield scope.getDefaultConfiguration(basics));

            // Add global settings
            configurations.push(omit(basics.entity.properties.getByPath('export.settings.' + scope.identifier, {}), ['macros']));

            // Add local settings
            configurations.push(omit(scope.settings, ['macros', 'macro']));

            // Merge
            const configuration = merge(...configurations);

            // Refine
            const result = yield scope.refineConfiguration(configuration);

            // Okay
            return result;
        });
        return promise;
    }
}

// Exports
module.exports.Configuration = Configuration;
<commit_msg>style(export.Configuration): remove console calls<commit_after>'use strict';

/**
 * Requirements
 * @ignore
 */
const Base = require('../Base.js').Base;
const GlobalRepository = require('../model/GlobalRepository.js').GlobalRepository;
const BuildConfiguration = require('../model/configuration/BuildConfiguration.js').BuildConfiguration;
const DocumentationCallable = require('../model/documentation/DocumentationCallable.js').DocumentationCallable;
const EntityAspect = require('../model/entity/EntityAspect.js').EntityAspect;
const Parser = require('./Parser.js').Parser;
const Renderer = require('./Renderer.js').Renderer;
const Transformer = require('./Transformer.js').Transformer;
const assertParameter = require('../utils/assert.js').assertParameter;
const co = require('co');
const merge = require('lodash.merge');
const omit = require('lodash.omit');
const minimatch = require('minimatch');

/**
 * The configuration holds all macro specific settings needed
 * for exporting.
 *
 * @memberOf export
 * @extends Base
 */
class Configuration extends Base
{
    /**
     * @ignore
     */
    constructor(entity, macro, settings, parser, renderer, transformer, globalRepository, buildConfiguration)
    {
        super();

        // Check params
        assertParameter(this, 'entity', entity, false, EntityAspect);
        assertParameter(this, 'macro', macro, false, DocumentationCallable);
        assertParameter(this, 'parser', parser, false, Parser);
        assertParameter(this, 'renderer', renderer, false, Renderer);
        assertParameter(this, 'transformer', transformer, false, Transformer);
        assertParameter(this, 'globalRepository', globalRepository, true, GlobalRepository);
        assertParameter(this, 'buildConfiguration', buildConfiguration, true, BuildConfiguration);

        // Assign options
        this._macro = macro;
        this._entity = entity;
        this._settings = settings || {};
        this._parser = parser;
        this._renderer = renderer;
        this._transformer = transformer;
        this._globalRepository = globalRepository;
        this._buildConfiguration = buildConfiguration;
        this._identifier = 'default';
    }

    /**
     * @inheritDoc
     */
    static get className()
    {
        return 'export/Configuration';
    }

    /**
     * @type {model.configuration.BuildConfiguration}
     */
    get buildConfiguration()
    {
        return this._buildConfiguration;
    }

    /**
     * @type {model.GlobalRepository}
     */
    get globalRepository()
    {
        return this._globalRepository;
    }

    /**
     * The configuration identifier used to extract
     * settings from entity configurations.
     *
     * @type {String}
     */
    get identifier()
    {
        return this._identifier;
    }

    /**
     * The macro this context was created for.
     * Maybe empty.
     *
     * @type {DocumentationCallable}
     */
    get macro()
    {
        return this._macro;
    }

    /**
     * The entity this context was created for.
     *
     * @type {Entity}
     */
    get entity()
    {
        return this._entity;
    }

    /**
     * The site this context was created for.
     * Maybe empty.
     *
     * @type {Site}
     */
    get site()
    {
        return this._entity ? this._entity.site : undefined;
    }

    /**
     * The settings for this specific export.
     *
     * @type {Object}
     */
    get settings()
    {
        return this._settings;
    }

    /**
     * Access to the parser instance.
     *
     * @type {export.Parser}
     */
    get parser()
    {
        return this._parser;
    }

    /**
     * Access to the renderer instance.
     *
     * @type {export.Renderer}
     */
    get renderer()
    {
        return this._renderer;
    }

    /**
     * Access to the transformer instance.
     *
     * @type {export.Transformer}
     */
    get transformer()
    {
        return this._transformer;
    }

    /**
     * The default configurations used as a base
     * for specific configurations.
     *
     * @protected
     * @param {Object} configuration
     * @returns {Promise<Object>}
     */
    getDefaultConfiguration(configuration)
    {
        return Promise.resolve({});
    }

    /**
     * Template method to allow subclasses to make last minute changes to
     * configurations.
     *
     * @protected
     * @param {Object} configuration
     * @returns {Promise<Object>}
     */
    refineConfiguration(configuration)
    {
        return Promise.resolve(configuration);
    }

    /**
     * Resolves to the first macro that matches macroQuery.
     *
     * @protected
     * @param {String} [macroQuery]
     * @returns {Promise<model.documentation.DocumentationCallable>}
     */
    getMacro(macroQuery)
    {
        const scope = this;
        const promise = co(function *()
        {
            let macro;

            // Default is the main macro
            if (!macroQuery)
            {
                macroQuery = scope.macro;
            }

            // Get Macro
            if (macroQuery instanceof DocumentationCallable)
            {
                macro = macroQuery;
            }
            else
            {
                macro = yield scope.globalRepository.resolveMacro(scope.site, macroQuery);
            }
            if (!macro || !(macro instanceof DocumentationCallable))
            {
                return false;
            }

            return macro;
        });
        return promise;
    }

    /**
     * Resolves to the entity containing macro.
     *
     * @protected
     * @param {model.documentation.DocumentationCallable} [macro]
     * @returns {Promise<model.entity.Entity>}
     */
    getMacroEntity(macro)
    {
        return this.globalRepository.resolveEntityForMacro(this.site, macro);
    }

    /**
     * Resolves to a macro specific configuration based
     * on the default, the entity configuration and the refined.
     *
     * @param {String} [macroQuery]
     * @returns {Promise<Object>}
     */
    getMacroConfiguration(macroQuery)
    {
        const scope = this;
        const promise = co(function *()
        {
            // Get macro
            const macro = yield scope.getMacro(macroQuery);
            if (!macro || !(macro instanceof DocumentationCallable))
            {
                /* istanbul ignore next */
                scope.logger.warn('getMacroConfiguration - could not find macro ' + macroQuery);
                return false;
            }

            // Get Entity
            const entity = yield scope.getMacroEntity(macro);
            if (!entity)
            {
                /* istanbul ignore next */
                scope.logger.warn('getMacroConfiguration - could not find entity for macro ' + macroQuery);
                return false;
            }

            // Basic configuration
            const basics = {};
            basics.macro = macro;
            basics.entity = entity;
            basics.site = entity.id.site;
            basics.filename = entity.pathString;
            basics.mode = 'default';

            // Extend
            const configurations = [];
            configurations.push(basics);

            // Add defaults
            configurations.push(yield scope.getDefaultConfiguration(basics));

            // Add global settings
            configurations.push(omit(basics.entity.properties.getByPath('export.settings.' + scope.identifier, {}), ['macros']));

            // Add global macro settings
            const globalMacros = basics.entity.properties.getByPath('export.settings.' + scope.identifier + '.macros', {});
            for (const match in globalMacros)
            {
                if (minimatch(basics.macro.name, match))
                {
                    configurations.push(globalMacros[match]);
                }
            }

            // Add local macro settings
            const localMacros = scope.settings.settings
                ? scope.settings.settings
                : {};
            for (const match in localMacros)
            {
                if (minimatch(basics.macro.name, match))
                {
                    configurations.push(localMacros[match]);
                }
            }

            // Add local settings
            if (scope.macro && scope.macro.name === macro.name)
            {
                configurations.push(omit(scope.settings, ['macros', 'macro']));
            }

            // Merge
            const configuration = merge(...configurations);

            // Refine
            const result = yield scope.refineConfiguration(configuration);

            // Okay
            return result;
        });
        return promise;
    }

    /**
     * Resolves to the export configuration based
     * on the default, the entity and the refined configuration.
     *
     * @returns {Promise<Object>}
     */
    getExportConfiguration()
    {
        const scope = this;
        const promise = co(function *()
        {
            // See if it's a macro export
            if (scope.macro)
            {
                const result = yield scope.getMacroConfiguration(scope.macro.name);
                return result;
            }

            // Basic configuration
            const basics = {};
            basics.entity = scope.entity;
            basics.site = scope.entity.id.site;
            basics.filename = scope.entity.pathString;

            // Extend
            const configurations = [];
            configurations.push(basics);

            // Add defaults
            configurations.push(yield scope.getDefaultConfiguration(basics));

            // Add global settings
            configurations.push(omit(basics.entity.properties.getByPath('export.settings.' + scope.identifier, {}), ['macros']));

            // Add local settings
            configurations.push(omit(scope.settings, ['macros', 'macro']));

            // Merge
            const configuration = merge(...configurations);

            // Refine
            const result = yield scope.refineConfiguration(configuration);

            // Okay
            return result;
        });
        return promise;
    }
}

// Exports
module.exports.Configuration = Configuration;
<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'

const PageContainer = styled.div`{
  position: relative;
  padding: 32px 155px 0;
  background-color: ${props => props.bgColor || '#fff'};
}`

const PageContent = styled.div`{
  position: relative;
  display: flex;
  padding-top: 51px;
}`

const Page = ({ children, menuComponent: MenuComponent, bgColor }) => (
  <PageContainer bgColor={bgColor}>
    {MenuComponent && <MenuComponent />}
    <PageContent>
    {children}
    </PageContent>
  </PageContainer>
)

const { oneOfType, node, func, string } = PropTypes

Page.propTypes = {
  /** The content of the page. */
  children: oneOfType([node, func]),
  /** The menu component. */
  menuComponent: oneOfType([node, func]),
  /** The background color of the page. */
  bgColor: string
}

export default Page
<commit_msg>fix(styleguide): add min-height to page component<commit_after>import React from 'react'
import PropTypes from 'prop-types'
import styled from 'styled-components'

const PageContainer = styled.div`{
  position: relative;
  padding: 32px 155px 0;
  background-color: ${props => props.bgColor || '#fff'};
}`

const PageContent = styled.div`{
  position: relative;
  display: flex;
  min-height: 100vh;
}`

const Page = ({ children, menuComponent: MenuComponent, bgColor }) => (
  <PageContainer bgColor={bgColor}>
    {MenuComponent && <MenuComponent />}
    <PageContent>
    {children}
    </PageContent>
  </PageContainer>
)

const { oneOfType, node, func, string } = PropTypes

Page.propTypes = {
  /** The content of the page. */
  children: oneOfType([node, func]),
  /** The menu component. */
  menuComponent: oneOfType([node, func]),
  /** The background color of the page. */
  bgColor: string
}

export default Page
<|endoftext|>