<commit_before>import _ from 'lodash';
import {
  isTwoDimensional,
  isTooBig,
} from './utilities';
import {
  enhance,
  existyValue,
} from '../../lib/helpers';
import cached from '../fields/cached';
import markdown from '../fields/markdown';
import Article from '../article';
import Artist from '../artist';
import Image, { getDefault } from '../image';
import Fair from '../fair';
import Sale from '../sale/index';
import PartnerShow from '../partner_show';
import Partner from '../partner';
import Context from './context';
import Meta from './meta';
import Highlight from './highlight';
import Dimensions from '../dimensions';
import EditionSet from '../edition_set';
import ArtworkLayer from '../artwork_layer';
import ArtworkLayers from '../artwork_layers';
import gravity from '../../lib/loaders/gravity';
import positron from '../../lib/loaders/positron';
import {
  GraphQLObjectType,
  GraphQLBoolean,
  GraphQLString,
  GraphQLNonNull,
  GraphQLList,
  GraphQLInt,
} from 'graphql';

const ArtworkType = new GraphQLObjectType({
  name: 'Artwork',
  fields: () => {
    return {
      cached,
      id: {
        type: GraphQLString,
      },
      _id: {
        type: GraphQLString,
      },
      to_s: {
        type: GraphQLString,
        resolve: ({ artist, title, date, partner }) => {
          return _.compact([
            (artist && artist.name),
            (title && `‘${title}’`),
            date,
            (partner && partner.name),
          ]).join(', ');
        },
      },
      href: {
        type: GraphQLString,
        resolve: ({ id }) => `/artwork/${id}`,
      },
      title: {
        type: GraphQLString,
      },
      category: {
        type: GraphQLString,
      },
      medium: {
        type: GraphQLString,
      },
      date: {
        type: GraphQLString,
      },
      image_rights: {
        type: GraphQLString,
      },
      website: {
        type: GraphQLString,
      },
      collecting_institution: {
        type: GraphQLString,
        resolve: ({ collecting_institution }) =>
          existyValue(collecting_institution),
      },
      partner: {
        type: Partner.type,
        args: {
          shallow: {
            type: GraphQLBoolean,
            description: 'Use whatever is in the original response instead of making a request',
          },
        },
        resolve: ({ partner }, { shallow }) => {
          if (shallow) return partner;
          return gravity(`partner/${partner.id}`);
        },
      },
      can_share_image: {
        type: GraphQLBoolean,
        deprecationReason: 'Favor `is_`-prefixed boolean attributes',
      },
      is_shareable: {
        type: GraphQLBoolean,
        resolve: ({ can_share_image }) => can_share_image,
      },
      is_hangable: {
        type: GraphQLBoolean,
        resolve: (artwork) => {
          return (
            !_.includes(artwork.category, 'sculpture', 'installation', 'design') &&
            isTwoDimensional(artwork) &&
            !isTooBig(artwork)
          );
        },
      },
      is_inquireable: {
        type: GraphQLBoolean,
        description: 'Do we want to encourage inquiries on this work?',
        resolve: ({ inquireable, acquireable }) => inquireable && !acquireable,
      },
      is_contactable: {
        type: GraphQLBoolean,
        description: 'Are we able to display a contact form on artwork pages?',
        deprecationReason: 'Prefer to use is_inquireable',
        resolve: (artwork) => {
          return gravity('related/sales', { size: 1, active: true, artwork: [artwork.id] })
            .then(sales => {
              return (
                artwork.forsale &&
                !_.isEmpty(artwork.partner) &&
                !artwork.acquireable &&
                !artwork.partner.has_limited_fair_partnership &&
                !sales.length
              );
            }).catch(() => false);
        },
      },
      is_in_auction: {
        type: GraphQLBoolean,
        description: 'Is this artwork part of an auction?',
        resolve: ({ id }) => {
          return gravity(`related/sales`, { size: 1, active: true, artwork: [id] })
            .then(sales => _.some(sales, 'is_auction'));
        },
      },
      is_in_show: {
        type: GraphQLBoolean,
        description: 'Is this artwork part of a current show',
        resolve: ({ id }) =>
          gravity('related/shows', { active: true, size: 1, artwork: [id] })
            .then(shows => shows.length > 0),
      },
      is_for_sale: {
        type: GraphQLBoolean,
        resolve: ({ forsale }) => forsale,
      },
      is_unique: {
        type: GraphQLBoolean,
        resolve: ({ unique }) => unique,
      },
      is_sold: {
        type: GraphQLBoolean,
        resolve: ({ sold }) => sold,
      },
      is_ecommerce: {
        type: GraphQLBoolean,
        deprecationReason: 'Should not be used to determine anything UI-level',
        resolve: ({ ecommerce }) => ecommerce,
      },
      is_acquireable: {
        type: GraphQLBoolean,
        description: 'Whether work can be purchased through e-commerce',
        resolve: ({ acquireable }) => acquireable,
      },
      is_comparable_with_auction_results: {
        type: GraphQLBoolean,
        resolve: ({ comparables_count, category }) => {
          return (
            comparables_count > 0 &&
            category !== 'Architecture'
          );
        },
      },
      is_downloadable: {
        type: GraphQLBoolean,
        resolve: ({ images }) => _.first(images).downloadable,
      },
      sale_message: {
        type: GraphQLString,
        resolve: ({ sold, availability, price_hidden, price, sale_message }) => {
          if (availability === 'for sale' && price_hidden) return 'Contact for price';
          if (sold) return 'Sold';
          if (sale_message !== 'Sold' && !price_hidden) return price;
          return sale_message;
        },
      },
      artist: {
        type: Artist.type,
        args: {
          shallow: {
            type: GraphQLBoolean,
            description: 'Use whatever is in the original response instead of making a request',
          },
        },
        resolve: ({ artist }, { shallow }) => {
          if (!artist) return null;
          if (shallow) return artist;
          return gravity(`artist/${artist.id}`)
            .catch(() => null);
        },
      },
      contact_label: {
        type: GraphQLString,
        resolve: ({ partner }) => {
          return (partner.type === 'Gallery') ? 'Gallery' : 'Seller';
        },
      },
      cultural_maker: {
        type: GraphQLString,
      },
      artists: {
        type: new GraphQLList(Artist.type),
        args: {
          shallow: {
            type: GraphQLBoolean,
            description: 'Use whatever is in the original response instead of making a request',
          },
        },
        resolve: ({ artists }, { shallow }) => {
          if (shallow) return artists;
          return Promise.all(
            artists.map(artist => gravity(`/artist/${artist.id}`))
          ).catch(() => []);
        },
      },
      dimensions: Dimensions,
      image: {
        type: Image.type,
        resolve: ({ images }) => {
          return Image.resolve(getDefault(images));
        },
      },
      images: {
        type: new GraphQLList(Image.type),
        args: {
          size: {
            type: GraphQLInt,
          },
        },
        resolve: ({ images }, { size }) => {
          const sorted = _.sortBy(images, 'position');
          return Image.resolve(size ? _.take(sorted, size) : sorted);
        },
      },
      context: Context,
      highlights: {
        type: new GraphQLList(Highlight),
        description: 'Returns the highlighted shows and articles',
        resolve: ({ id, _id }) =>
          Promise
            .all([
              gravity('related/shows', { artwork: [id], size: 1, at_a_fair: false }),
              positron('articles', { artwork_id: _id, published: true, limit: 1 })
                .then(({ results }) => results),
            ])
            .then(([shows, articles]) => {
              const highlightedShows = enhance(shows, { highlight_type: 'Show' });
              const highlightedArticles = enhance(articles, { highlight_type: 'Article' });
              return highlightedShows.concat(highlightedArticles);
            }),
      },
      articles: {
        type: new GraphQLList(Article.type),
        args: {
          size: {
            type: GraphQLInt,
          },
        },
        resolve: ({ _id }, { size }) =>
          positron('articles', { artwork_id: _id, published: true, limit: size })
            .then(({ results }) => results),
      },
      shows: {
        type: new GraphQLList(PartnerShow.type),
        args: {
          size: {
            type: GraphQLInt,
            defaultValue: 1,
          },
          active: {
            type: GraphQLBoolean,
            defaultValue: true,
          },
        },
        resolve: ({ id }, { size, active }) =>
          gravity('related/shows', { size, active, artwork: [id] }),
      },
      sale: {
        type: Sale.type,
        resolve: ({ id }) =>
          gravity('related/sales', { artwork: [id], active: true, size: 1 })
            .then(_.first),
      },
      fair: {
        type: Fair.type,
        resolve: ({ id }) =>
          gravity('related/fairs', { artwork: [id], active: true, size: 1 })
            .then(_.first),
      },
      edition_of: {
        type: GraphQLString,
        resolve: ({ unique, edition_sets }) => {
          if (unique) return 'Unique';
          if (edition_sets && edition_sets.length === 1) {
            return _.first(edition_sets).editions;
          }
        },
      },
      edition_sets: {
        type: new GraphQLList(EditionSet.type),
        resolve: ({ edition_sets }) => edition_sets,
      },
      description: markdown(({ blurb }) => blurb),
      exhibition_history: markdown(),
      provenance: markdown(({ provenance }) =>
        provenance.replace(/^provenance:\s+/i, '')
      ),
      signature: markdown(({ signature }) =>
        signature.replace(/^signature:\s+/i, '')
      ),
      additional_information: markdown(),
      literature: markdown(({ literature }) =>
        literature.replace(/^literature:\s+/i, '')
      ),
      publisher: markdown(),
      manufacturer: markdown(),
      series: markdown(),
      meta: Meta,
      layer: {
        type: ArtworkLayer.type,
        args: {
          id: {
            type: new GraphQLNonNull(GraphQLString),
          },
        },
        resolve: (artwork, { id }) =>
          // There's no route in Gravity for an actual layer, interestingly.
          gravity(`related/layers`, { artwork: [artwork.id] })
            .then(layers => {
              const layer = _.find(layers, { id });
              if (layer) return _.assign({ artwork_id: artwork.id }, layer);
            }),
      },
      layers: {
        type: ArtworkLayers.type,
        resolve: ({ id }) =>
          gravity(`related/layers`, { artwork: [id] })
            .then(layers => enhance(layers, { artwork_id: id })),
      },
    };
  },
});

const Artwork = {
  type: ArtworkType,
  description: 'An Artwork',
  args: {
    id: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'The slug or ID of the Artwork',
    },
  },
  resolve: (root, { id }) => gravity(`artwork/${id}`),
};

export default Artwork;
<commit_msg>Adds `is_price_hidden` and `availability`<commit_after>import _ from 'lodash';
import {
  isTwoDimensional,
  isTooBig,
} from './utilities';
import {
  enhance,
  existyValue,
} from '../../lib/helpers';
import cached from '../fields/cached';
import markdown from '../fields/markdown';
import Article from '../article';
import Artist from '../artist';
import Image, { getDefault } from '../image';
import Fair from '../fair';
import Sale from '../sale/index';
import PartnerShow from '../partner_show';
import Partner from '../partner';
import Context from './context';
import Meta from './meta';
import Highlight from './highlight';
import Dimensions from '../dimensions';
import EditionSet from '../edition_set';
import ArtworkLayer from '../artwork_layer';
import ArtworkLayers from '../artwork_layers';
import gravity from '../../lib/loaders/gravity';
import positron from '../../lib/loaders/positron';
import {
  GraphQLObjectType,
  GraphQLBoolean,
  GraphQLString,
  GraphQLNonNull,
  GraphQLList,
  GraphQLInt,
} from 'graphql';

const ArtworkType = new GraphQLObjectType({
  name: 'Artwork',
  fields: () => {
    return {
      cached,
      id: {
        type: GraphQLString,
      },
      _id: {
        type: GraphQLString,
      },
      to_s: {
        type: GraphQLString,
        resolve: ({ artist, title, date, partner }) => {
          return _.compact([
            (artist && artist.name),
            (title && `‘${title}’`),
            date,
            (partner && partner.name),
          ]).join(', ');
        },
      },
      href: {
        type: GraphQLString,
        resolve: ({ id }) => `/artwork/${id}`,
      },
      title: {
        type: GraphQLString,
      },
      category: {
        type: GraphQLString,
      },
      medium: {
        type: GraphQLString,
      },
      date: {
        type: GraphQLString,
      },
      image_rights: {
        type: GraphQLString,
      },
      website: {
        type: GraphQLString,
      },
      collecting_institution: {
        type: GraphQLString,
        resolve: ({ collecting_institution }) =>
          existyValue(collecting_institution),
      },
      partner: {
        type: Partner.type,
        args: {
          shallow: {
            type: GraphQLBoolean,
            description: 'Use whatever is in the original response instead of making a request',
          },
        },
        resolve: ({ partner }, { shallow }) => {
          if (shallow) return partner;
          return gravity(`partner/${partner.id}`);
        },
      },
      can_share_image: {
        type: GraphQLBoolean,
        deprecationReason: 'Favor `is_`-prefixed boolean attributes',
      },
      is_shareable: {
        type: GraphQLBoolean,
        resolve: ({ can_share_image }) => can_share_image,
      },
      is_hangable: {
        type: GraphQLBoolean,
        resolve: (artwork) => {
          return (
            !_.includes(artwork.category, 'sculpture', 'installation', 'design') &&
            isTwoDimensional(artwork) &&
            !isTooBig(artwork)
          );
        },
      },
      is_inquireable: {
        type: GraphQLBoolean,
        description: 'Do we want to encourage inquiries on this work?',
        resolve: ({ inquireable, acquireable }) => inquireable && !acquireable,
      },
      is_contactable: {
        type: GraphQLBoolean,
        description: 'Are we able to display a contact form on artwork pages?',
        deprecationReason: 'Prefer to use is_inquireable',
        resolve: (artwork) => {
          return gravity('related/sales', { size: 1, active: true, artwork: [artwork.id] })
            .then(sales => {
              return (
                artwork.forsale &&
                !_.isEmpty(artwork.partner) &&
                !artwork.acquireable &&
                !artwork.partner.has_limited_fair_partnership &&
                !sales.length
              );
            }).catch(() => false);
        },
      },
      is_in_auction: {
        type: GraphQLBoolean,
        description: 'Is this artwork part of an auction?',
        resolve: ({ id }) => {
          return gravity(`related/sales`, { size: 1, active: true, artwork: [id] })
            .then(sales => _.some(sales, 'is_auction'));
        },
      },
      is_in_show: {
        type: GraphQLBoolean,
        description: 'Is this artwork part of a current show',
        resolve: ({ id }) =>
          gravity('related/shows', { active: true, size: 1, artwork: [id] })
            .then(shows => shows.length > 0),
      },
      is_for_sale: {
        type: GraphQLBoolean,
        resolve: ({ forsale }) => forsale,
      },
      is_unique: {
        type: GraphQLBoolean,
        resolve: ({ unique }) => unique,
      },
      is_sold: {
        type: GraphQLBoolean,
        resolve: ({ sold }) => sold,
      },
      is_ecommerce: {
        type: GraphQLBoolean,
        deprecationReason: 'Should not be used to determine anything UI-level',
        resolve: ({ ecommerce }) => ecommerce,
      },
      is_acquireable: {
        type: GraphQLBoolean,
        description: 'Whether work can be purchased through e-commerce',
        resolve: ({ acquireable }) => acquireable,
      },
      is_comparable_with_auction_results: {
        type: GraphQLBoolean,
        resolve: ({ comparables_count, category }) => {
          return (
            comparables_count > 0 &&
            category !== 'Architecture'
          );
        },
      },
      is_downloadable: {
        type: GraphQLBoolean,
        resolve: ({ images }) => _.first(images).downloadable,
      },
      is_price_hidden: {
        type: GraphQLBoolean,
        resolve: ({ price_hidden }) => price_hidden,
      },
      availability: {
        type: GraphQLString,
      },
      sale_message: {
        type: GraphQLString,
        resolve: ({ sold, availability, price_hidden, price, sale_message }) => {
          if (availability === 'for sale' && price_hidden) return 'Contact for price';
          if (sold) return 'Sold';
          if (sale_message !== 'Sold' && !price_hidden) return price;
          return sale_message;
        },
      },
      artist: {
        type: Artist.type,
        args: {
          shallow: {
            type: GraphQLBoolean,
            description: 'Use whatever is in the original response instead of making a request',
          },
        },
        resolve: ({ artist }, { shallow }) => {
          if (!artist) return null;
          if (shallow) return artist;
          return gravity(`artist/${artist.id}`)
            .catch(() => null);
        },
      },
      contact_label: {
        type: GraphQLString,
        resolve: ({ partner }) => {
          return (partner.type === 'Gallery') ? 'Gallery' : 'Seller';
        },
      },
      cultural_maker: {
        type: GraphQLString,
      },
      artists: {
        type: new GraphQLList(Artist.type),
        args: {
          shallow: {
            type: GraphQLBoolean,
            description: 'Use whatever is in the original response instead of making a request',
          },
        },
        resolve: ({ artists }, { shallow }) => {
          if (shallow) return artists;
          return Promise.all(
            artists.map(artist => gravity(`/artist/${artist.id}`))
          ).catch(() => []);
        },
      },
      dimensions: Dimensions,
      image: {
        type: Image.type,
        resolve: ({ images }) => {
          return Image.resolve(getDefault(images));
        },
      },
      images: {
        type: new GraphQLList(Image.type),
        args: {
          size: {
            type: GraphQLInt,
          },
        },
        resolve: ({ images }, { size }) => {
          const sorted = _.sortBy(images, 'position');
          return Image.resolve(size ? _.take(sorted, size) : sorted);
        },
      },
      context: Context,
      highlights: {
        type: new GraphQLList(Highlight),
        description: 'Returns the highlighted shows and articles',
        resolve: ({ id, _id }) =>
          Promise
            .all([
              gravity('related/shows', { artwork: [id], size: 1, at_a_fair: false }),
              positron('articles', { artwork_id: _id, published: true, limit: 1 })
                .then(({ results }) => results),
            ])
            .then(([shows, articles]) => {
              const highlightedShows = enhance(shows, { highlight_type: 'Show' });
              const highlightedArticles = enhance(articles, { highlight_type: 'Article' });
              return highlightedShows.concat(highlightedArticles);
            }),
      },
      articles: {
        type: new GraphQLList(Article.type),
        args: {
          size: {
            type: GraphQLInt,
          },
        },
        resolve: ({ _id }, { size }) =>
          positron('articles', { artwork_id: _id, published: true, limit: size })
            .then(({ results }) => results),
      },
      shows: {
        type: new GraphQLList(PartnerShow.type),
        args: {
          size: {
            type: GraphQLInt,
            defaultValue: 1,
          },
          active: {
            type: GraphQLBoolean,
            defaultValue: true,
          },
        },
        resolve: ({ id }, { size, active }) =>
          gravity('related/shows', { size, active, artwork: [id] }),
      },
      sale: {
        type: Sale.type,
        resolve: ({ id }) =>
          gravity('related/sales', { artwork: [id], active: true, size: 1 })
            .then(_.first),
      },
      fair: {
        type: Fair.type,
        resolve: ({ id }) =>
          gravity('related/fairs', { artwork: [id], active: true, size: 1 })
            .then(_.first),
      },
      edition_of: {
        type: GraphQLString,
        resolve: ({ unique, edition_sets }) => {
          if (unique) return 'Unique';
          if (edition_sets && edition_sets.length === 1) {
            return _.first(edition_sets).editions;
          }
        },
      },
      edition_sets: {
        type: new GraphQLList(EditionSet.type),
        resolve: ({ edition_sets }) => edition_sets,
      },
      description: markdown(({ blurb }) => blurb),
      exhibition_history: markdown(),
      provenance: markdown(({ provenance }) =>
        provenance.replace(/^provenance:\s+/i, '')
      ),
      signature: markdown(({ signature }) =>
        signature.replace(/^signature:\s+/i, '')
      ),
      additional_information: markdown(),
      literature: markdown(({ literature }) =>
        literature.replace(/^literature:\s+/i, '')
      ),
      publisher: markdown(),
      manufacturer: markdown(),
      series: markdown(),
      meta: Meta,
      layer: {
        type: ArtworkLayer.type,
        args: {
          id: {
            type: new GraphQLNonNull(GraphQLString),
          },
        },
        resolve: (artwork, { id }) =>
          // There's no route in Gravity for an actual layer, interestingly.
          gravity(`related/layers`, { artwork: [artwork.id] })
            .then(layers => {
              const layer = _.find(layers, { id });
              if (layer) return _.assign({ artwork_id: artwork.id }, layer);
            }),
      },
      layers: {
        type: ArtworkLayers.type,
        resolve: ({ id }) =>
          gravity(`related/layers`, { artwork: [id] })
            .then(layers => enhance(layers, { artwork_id: id })),
      },
    };
  },
});

const Artwork = {
  type: ArtworkType,
  description: 'An Artwork',
  args: {
    id: {
      type: new GraphQLNonNull(GraphQLString),
      description: 'The slug or ID of the Artwork',
    },
  },
  resolve: (root, { id }) => gravity(`artwork/${id}`),
};

export default Artwork;
<|endoftext|>


<commit_before>(function () {
    'use strict';

    angular.module('LabApp').controller("HomeCtrl", HomeCtrl);

    HomeCtrl.$inject = ['$rootScope', '$scope', 'middleService', 'blockUI', 'initData'];

    function HomeCtrl($rootScope, $scope, middleService, blockUI, initData) {

        var self = this;

        self.findById = function (id) {
            return $scope.root.first(function (iterNode) {
                return iterNode.model.id === id;
            });
        };

        self.initializeCodeEditor = function (mode) {
            const CRIMSON_THEME = "ace/theme/crimson_editor";
            $scope.codeEditor = ace.edit("code-editor");
            $scope.codeEditor.$blockScrolling = Infinity;
            $scope.codeEditor.setTheme(CRIMSON_THEME);
            $scope.codeEditor.getSession().setMode(mode);
            $scope.codeEditor.getSession().setValue($scope.selected.code);
        };

        $scope.appModel = initData.data;

        $scope.$on('$routeChangeSuccess', function () {// initialization of main model
            $scope.root = new TreeModel().parse({"id": 0, "children": $scope.appModel.treedata});

            //tree data initialization
            $scope.treedata = $scope.appModel.treedata;
            $scope.expandedNodes = [self.findById(2).model, self.findById(21).model, self.findById(3).model, self.findById(31).model];
            $scope.selected = self.findById(211).model;

            //AutoCompletion
            $scope.javaClasses = $scope.appModel.initConfig.javaClasses;
            $scope.initialValue = $scope.appModel.initConfig.javaClasses[0];

            $rootScope.$broadcast('resize', {});

            self.initializeCodeEditor($scope.appModel.initConfig.language);
        });

        $scope.formatCode = function () {
            function formatCodeFor(editor) {
                editor.getSession().setUseWrapMode(false);
                var oldFormat = editor.getValue();
                if (oldFormat.trim().length > 0) {
                    var newFormat = js_beautify(oldFormat, {
                        'indent_size': 1,
                        'indent_char': '\t'
                    });
                    editor.setValue(newFormat);
                }
            }

            formatCodeFor($scope.codeEditor);
        };

        $scope.runCode = function () {
            if ($scope.appModel.runnableNode.id == undefined) {
                $scope.appModel.console = "Please select a class to run";
                return;
            }

            blockUI.start();
            $scope.selected.code = $scope.codeEditor.getValue();
            $scope.selected.cursor = $scope.codeEditor.getCursorPosition();
            $scope.appModel.runnableNode.mainClass = true;
            $scope.appModel.runnableNode.testClass = false;
            $scope.appModel.console = middleService.runCode($scope.appModel);
            blockUI.stop();
        };

        $scope.runTests = function () {
            if ($scope.appModel.runnableNode.id == undefined) {
                $scope.appModel.console = "Please select a test class";
                return;
            }

            $scope.appModel.console = "Running ALL Tests!";
            blockUI.start();
            $scope.selected.code = $scope.codeEditor.getValue();
            $scope.selected.cursor = $scope.codeEditor.getCursorPosition();
            $scope.appModel.runnableNode.mainClass = false;
            $scope.appModel.runnableNode.testClass = true;
            $scope.appModel.console = middleService.runTest($scope.appModel);
            blockUI.stop();
        };

        $scope.save = function () {
            blockUI.start();
            $scope.selected.code = $scope.codeEditor.getValue();
            $scope.selected.cursor = $scope.codeEditor.getCursorPosition();
            $scope.appModel.console = middleService.saveWorkspace($scope.appModel);
            blockUI.stop();
        };

        $scope.new = function () {
            blockUI.start();
            $scope.appModel.console = middleService.newWorkspace($scope.appModel);
            blockUI.stop();
        };

        /**
         * Tree manager
         */
        $scope.showSelected = function (node) {
            var oldNode = $scope.selected;
            if (oldNode !== undefined) {
                oldNode.code = $scope.codeEditor.getValue();
                oldNode.cursor = $scope.codeEditor.getCursorPosition();
            }

            $scope.selected = node;
            if (node.type === "file") {
                $scope.codeEditor.setValue(node.code, 1); // moves cursor to the end
                var cursor = node.cursor == undefined ? {column: 0, row: 0} : node.cursor;
                $scope.codeEditor.moveCursorToPosition(cursor);
                $scope.codeEditor.focus();
            }
        };

        self.pathAsString = function (node) {
            var path = "";
            var pathArray = node.getPath();
            for (var index = 2; index < pathArray.length; ++index) {
                if (pathArray[index].model.name != undefined) {
                    if (index === (pathArray.length - 1)) {
                        path += ".";
                    }

                    path += pathArray[index].model.name;
                }
            }
            return path.replace('.java','');
        };

        $scope.addNode = function (typeToCreate, node) {
            var nodeName = prompt("Enter " + typeToCreate + " name", typeToCreate + " name");
            if (nodeName == null || nodeName.trim() === "") {
                return;
            }

            function newNodeUUID() {
                return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
                    return v.toString(16);
                });
            }

            function createNewNode() {
                var newNode = new TreeModel().parse({
                    id: newNodeUUID(),
                    name: nodeName,
                    type: typeToCreate,
                    children: []
                });
                if (typeToCreate === "file") {
                    newNode.model.code = "";
                }
                return newNode;
            }

            var nodeFound = self.findById(node.id);
            var newNode = createNewNode();

            if (newNode.model.type === "file") {
                nodeFound.parent.addChild(newNode);
                if (nodeName.indexOf(".java") > -1) {
                    $scope.javaClasses.push({
                        id: newNode.model.id,
                        name: newNode.model.name,
                        path: self.pathAsString(newNode)
                    })
                }
            } else if (newNode.model.type === "folder") {
                nodeFound.addChild(newNode);
            }
        };

        $scope.editNode = function (node) {
            if (node.id === 1 || node.id === 2) {
                return;
            }

            var nodeName = prompt("Change name", node.name);
            if (nodeName == null || nodeName.trim() === "") {
                return;
            }

            var nodeFound = self.findById(node.id);
            nodeFound.model.name = nodeName;

            function updatePaths(node) {
                if (node.model.type === "file" && node.model.name.indexOf(".java") > -1) {
                    var classesArray = $scope.javaClasses;
                    for (var i = 0; i < classesArray.length; ++i) {
                        if (classesArray[i].id == node.model.id) {
                            classesArray[i].name = node.model.name;
                            classesArray[i].path = self.pathAsString(node);
                        }
                    }
                } else if (node.model.type === "folder") {
                    for (var j = 0; j < node.children.length; ++j) {
                        updatePaths(node.children[j]);
                    }
                }
            }

            updatePaths(nodeFound);

            var selectedNode = self.findById($scope.appModel.runnableNode.id);
            $scope.appModel.runnableNode.id = selectedNode.model.id;
            $scope.appModel.runnableNode.path = self.pathAsString(selectedNode);
        };

        $scope.removeNode = function (node) {
            if (node.id === 1 || node.id === 2) {
                return;
            }

            var confirmed = confirm("Delete " + node.type + " '" + node.name + "' ?");
            if (!confirmed) {
                return;
            }

            var nodeFound = self.findById(node.id);
            if (nodeFound.model.name.indexOf(".java") > -1) {
                var classesArray = $scope.javaClasses;
                for (var index = 0; index < classesArray.length; ++index) {
                    if (classesArray[index].id == nodeFound.model.id) {
                        classesArray.splice(index, 1);
                    }
                }
            }

            $scope.codeEditor.getSession().setValue("");
            $scope.selected = nodeFound.parent.model;
            nodeFound.drop();
        };

        $scope.treeOptions = {
            nodeChildren: "children",
            dirSelectable: true,
            allowDeselect: false,
            isLeaf: function (node) {
                return node.type === "file";
            },
            equality: function (node1, node2) {
                return (node1 === node2) && (angular.equals(node1, node2));
            }
        };

        /**
         * Autocompletion
         */
        $scope.selectedFile = function (selected) {
            if (selected == undefined) {
                $scope.appModel.runnableNode.id = undefined;
                return;
            }

            var nodeFound = self.findById(selected.originalObject.id);
            $scope.appModel.runnableNode.id = nodeFound.model.id;
            $scope.appModel.runnableNode.path = self.pathAsString(nodeFound);
        };

    }

})();<commit_msg>removed const declaration<commit_after>(function () {
    'use strict';

    angular.module('LabApp').controller("HomeCtrl", HomeCtrl);

    HomeCtrl.$inject = ['$rootScope', '$scope', 'middleService', 'blockUI', 'initData'];

    function HomeCtrl($rootScope, $scope, middleService, blockUI, initData) {

        var self = this;

        self.findById = function (id) {
            return $scope.root.first(function (iterNode) {
                return iterNode.model.id === id;
            });
        };

        self.initializeCodeEditor = function (mode) {
            var CRIMSON_THEME = "ace/theme/crimson_editor";
            $scope.codeEditor = ace.edit("code-editor");
            $scope.codeEditor.$blockScrolling = Infinity;
            $scope.codeEditor.setTheme(CRIMSON_THEME);
            $scope.codeEditor.getSession().setMode(mode);
            $scope.codeEditor.getSession().setValue($scope.selected.code);
        };

        $scope.appModel = initData.data;

        $scope.$on('$routeChangeSuccess', function () {// initialization of main model
            $scope.root = new TreeModel().parse({"id": 0, "children": $scope.appModel.treedata});

            //tree data initialization
            $scope.treedata = $scope.appModel.treedata;
            $scope.expandedNodes = [self.findById(2).model, self.findById(21).model, self.findById(3).model, self.findById(31).model];
            $scope.selected = self.findById(211).model;

            //AutoCompletion
            $scope.javaClasses = $scope.appModel.initConfig.javaClasses;
            $scope.initialValue = $scope.appModel.initConfig.javaClasses[0];

            $rootScope.$broadcast('resize', {});

            self.initializeCodeEditor($scope.appModel.initConfig.language);
        });

        $scope.formatCode = function () {
            function formatCodeFor(editor) {
                editor.getSession().setUseWrapMode(false);
                var oldFormat = editor.getValue();
                if (oldFormat.trim().length > 0) {
                    var newFormat = js_beautify(oldFormat, {
                        'indent_size': 1,
                        'indent_char': '\t'
                    });
                    editor.setValue(newFormat);
                }
            }

            formatCodeFor($scope.codeEditor);
        };

        $scope.runCode = function () {
            if ($scope.appModel.runnableNode.id == undefined) {
                $scope.appModel.console = "Please select a class to run";
                return;
            }

            blockUI.start();
            $scope.selected.code = $scope.codeEditor.getValue();
            $scope.selected.cursor = $scope.codeEditor.getCursorPosition();
            $scope.appModel.runnableNode.mainClass = true;
            $scope.appModel.runnableNode.testClass = false;
            $scope.appModel.console = middleService.runCode($scope.appModel);
            blockUI.stop();
        };

        $scope.runTests = function () {
            if ($scope.appModel.runnableNode.id == undefined) {
                $scope.appModel.console = "Please select a test class";
                return;
            }

            $scope.appModel.console = "Running ALL Tests!";
            blockUI.start();
            $scope.selected.code = $scope.codeEditor.getValue();
            $scope.selected.cursor = $scope.codeEditor.getCursorPosition();
            $scope.appModel.runnableNode.mainClass = false;
            $scope.appModel.runnableNode.testClass = true;
            $scope.appModel.console = middleService.runTest($scope.appModel);
            blockUI.stop();
        };

        $scope.save = function () {
            blockUI.start();
            $scope.selected.code = $scope.codeEditor.getValue();
            $scope.selected.cursor = $scope.codeEditor.getCursorPosition();
            $scope.appModel.console = middleService.saveWorkspace($scope.appModel);
            blockUI.stop();
        };

        $scope.new = function () {
            blockUI.start();
            $scope.appModel.console = middleService.newWorkspace($scope.appModel);
            blockUI.stop();
        };

        /**
         * Tree manager
         */
        $scope.showSelected = function (node) {
            var oldNode = $scope.selected;
            if (oldNode !== undefined) {
                oldNode.code = $scope.codeEditor.getValue();
                oldNode.cursor = $scope.codeEditor.getCursorPosition();
            }

            $scope.selected = node;
            if (node.type === "file") {
                $scope.codeEditor.setValue(node.code, 1); // moves cursor to the end
                var cursor = node.cursor == undefined ? {column: 0, row: 0} : node.cursor;
                $scope.codeEditor.moveCursorToPosition(cursor);
                $scope.codeEditor.focus();
            }
        };

        self.pathAsString = function (node) {
            var path = "";
            var pathArray = node.getPath();
            for (var index = 2; index < pathArray.length; ++index) {
                if (pathArray[index].model.name != undefined) {
                    if (index === (pathArray.length - 1)) {
                        path += ".";
                    }

                    path += pathArray[index].model.name;
                }
            }
            return path.replace('.java','');
        };

        $scope.addNode = function (typeToCreate, node) {
            var nodeName = prompt("Enter " + typeToCreate + " name", typeToCreate + " name");
            if (nodeName == null || nodeName.trim() === "") {
                return;
            }

            function newNodeUUID() {
                return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                    var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
                    return v.toString(16);
                });
            }

            function createNewNode() {
                var newNode = new TreeModel().parse({
                    id: newNodeUUID(),
                    name: nodeName,
                    type: typeToCreate,
                    children: []
                });
                if (typeToCreate === "file") {
                    newNode.model.code = "";
                }
                return newNode;
            }

            var nodeFound = self.findById(node.id);
            var newNode = createNewNode();

            if (newNode.model.type === "file") {
                nodeFound.parent.addChild(newNode);
                if (nodeName.indexOf(".java") > -1) {
                    $scope.javaClasses.push({
                        id: newNode.model.id,
                        name: newNode.model.name,
                        path: self.pathAsString(newNode)
                    })
                }
            } else if (newNode.model.type === "folder") {
                nodeFound.addChild(newNode);
            }
        };

        $scope.editNode = function (node) {
            if (node.id === 1 || node.id === 2) {
                return;
            }

            var nodeName = prompt("Change name", node.name);
            if (nodeName == null || nodeName.trim() === "") {
                return;
            }

            var nodeFound = self.findById(node.id);
            nodeFound.model.name = nodeName;

            function updatePaths(node) {
                if (node.model.type === "file" && node.model.name.indexOf(".java") > -1) {
                    var classesArray = $scope.javaClasses;
                    for (var i = 0; i < classesArray.length; ++i) {
                        if (classesArray[i].id == node.model.id) {
                            classesArray[i].name = node.model.name;
                            classesArray[i].path = self.pathAsString(node);
                        }
                    }
                } else if (node.model.type === "folder") {
                    for (var j = 0; j < node.children.length; ++j) {
                        updatePaths(node.children[j]);
                    }
                }
            }

            updatePaths(nodeFound);

            var selectedNode = self.findById($scope.appModel.runnableNode.id);
            $scope.appModel.runnableNode.id = selectedNode.model.id;
            $scope.appModel.runnableNode.path = self.pathAsString(selectedNode);
        };

        $scope.removeNode = function (node) {
            if (node.id === 1 || node.id === 2) {
                return;
            }

            var confirmed = confirm("Delete " + node.type + " '" + node.name + "' ?");
            if (!confirmed) {
                return;
            }

            var nodeFound = self.findById(node.id);
            if (nodeFound.model.name.indexOf(".java") > -1) {
                var classesArray = $scope.javaClasses;
                for (var index = 0; index < classesArray.length; ++index) {
                    if (classesArray[index].id == nodeFound.model.id) {
                        classesArray.splice(index, 1);
                    }
                }
            }

            $scope.codeEditor.getSession().setValue("");
            $scope.selected = nodeFound.parent.model;
            nodeFound.drop();
        };

        $scope.treeOptions = {
            nodeChildren: "children",
            dirSelectable: true,
            allowDeselect: false,
            isLeaf: function (node) {
                return node.type === "file";
            },
            equality: function (node1, node2) {
                return (node1 === node2) && (angular.equals(node1, node2));
            }
        };

        /**
         * Autocompletion
         */
        $scope.selectedFile = function (selected) {
            if (selected == undefined) {
                $scope.appModel.runnableNode.id = undefined;
                return;
            }

            var nodeFound = self.findById(selected.originalObject.id);
            $scope.appModel.runnableNode.id = nodeFound.model.id;
            $scope.appModel.runnableNode.path = self.pathAsString(nodeFound);
        };

    }

})();<|endoftext|>


<commit_before>/**
 * map tab shown in cartodb admin
 */

cdb.open.PublicMapTab = cdb.admin.MapTab.extend({

  className: 'map',

  initialize: function() {
    this.template = this.getTemplate('table_public/views/maptab_public');
    this.map_enabled = false;
  },

  /**
   * map can't be loaded from the beggining, it needs the DOM to be loaded
   * so we wait until is actually shown to create the mapview and show it
   */
  enableMap: function() {
    var self = this;
    if(!this.map_enabled) {
      var div = this.$('#map');
      var vis = new cdb.vis.Vis({ el: div });
      // remove header
      this.options.vizjson.overlays.splice(0, 1);
      vis.load(this.options.vizjson);
    }
  },

  clearMap: function() {
  },

  render: function() {
    this.$el.html(this.template());
    return this;
  }

});

<commit_msg>fixed multiple maps addition on public table view<commit_after>/**
 * map tab shown in cartodb admin
 */

cdb.open.PublicMapTab = cdb.admin.MapTab.extend({

  className: 'map',

  initialize: function() {
    this.template = this.getTemplate('table_public/views/maptab_public');
    this.map_enabled = false;
  },

  /**
   * map can't be loaded from the beggining, it needs the DOM to be loaded
   * so we wait until is actually shown to create the mapview and show it
   */
  enableMap: function() {

    var self = this;
    if(!this.map_enabled && !this.vis) {
      var div = this.$('#map');
      this.vis = new cdb.vis.Vis({ el: div });
      // remove header
      this.options.vizjson.overlays.splice(0, 1);
      this.vis.load(this.options.vizjson);
    }
  },

  clearMap: function() {
  },

  render: function() {
    this.$el.html(this.template());
    return this;
  }

});

<|endoftext|>


<commit_before>describe('mod.carto', function() {

  describe('panel', function() {
    var view;
    beforeEach(function() {
      var model = new cdb.geo.CartoDBLayer({
        tile_style: "#test { polygon-fill: #FFF; }"
      });

      var table = new cdb.admin.CartoDBTableMetadata({ name: 'test', geometry_types: ['st_polygon'] });

      view = new cdb.admin.mod.CartoCSS({
        el: $('<div>'),
        model: model,
        table: table
      });
      table.data().reset([
        {'test': null}
      ]);
      table.trigger('dataLoaded')

    });

    it("should enable wizard", function() {
      view.render();
      view.$('.wizard').trigger('click');
      expect(view.panels.activeTab).toEqual('wizard');
    });
    it("should enable editor", function() {
      view.render();
      view.$('.editor').trigger('click');
      expect(view.panels.activeTab).toEqual('editor');
    });
  });

  describe('editor', function() {
    var cartoMod;
    var layer;
    beforeEach(function() {
      layer = new cdb.geo.CartoDBLayer({
        tile_style: "#test { polygon-fill: #FFF; }"
      });
      cartoMod = new cdb.admin.mod.CartoCSSEditor({
        model: layer
      });
    });

    it("should render style from model", function() {
      cartoMod.render();
      expect(cartoMod.codeEditor.getValue()).toEqual(layer.get('tile_style'));

    });
    it("should update style from model", function() {
      cartoMod.render();
      layer.set({tile_style: "#test { polygon-fill: #F00; }"});
      expect(cartoMod.codeEditor.getValue()).toEqual(layer.get('tile_style'));

    });

    it("should parse errors", function() {
      var errors = [
        'style.mss:11:2 Invalid code: asdasd',
        'style.mss:7:2 Invalid code: asdasdasda',
        'style.mss:7:2 Invalid code: asdasdasda'
      ];

      var errParsed = cartoMod._parseError(errors);
      expect(errParsed).toEqual([
        { line: 7, error: 'Invalid code: asdasdasda'},
        { line: 11, error: 'Invalid code: asdasd'}
      ]);
    });
  });

});
<commit_msg>tests for cartocss editor<commit_after>describe('mod.carto', function() {

  describe('panel', function() {
    var view;
    beforeEach(function() {
      var model = new cdb.geo.CartoDBLayer({
        tile_style: "#test { polygon-fill: #FFF; }"
      });

      var table = new cdb.admin.CartoDBTableMetadata({ name: 'test', geometry_types: ['st_polygon'] });

      view = new cdb.admin.mod.CartoCSS({
        el: $('<div>'),
        model: model,
        table: table
      });
      table.data().reset([
        {'test': null}
      ]);
      table.trigger('dataLoaded')

    });

    it("should enable wizard", function() {
      view.render();
      view.$('.wizard').trigger('click');
      expect(view.panels.activeTab).toEqual('wizard');
    });
    it("should enable editor", function() {
      view.render();
      view.$('.editor').trigger('click');
      expect(view.panels.activeTab).toEqual('editor');
    });
  });

  describe('editor', function() {
    var cartoMod;
    var layer;
    beforeEach(function() {
      layer = new cdb.geo.CartoDBLayer({
        tile_style: "#test { polygon-fill: #FFF; }"
      });
      cartoMod = new cdb.admin.mod.CartoCSSEditor({
        model: layer
      });
    });

    it("should render style from model", function() {
      cartoMod.render();
      expect(cartoMod.codeEditor.getValue()).toEqual(layer.get('tile_style'));

    });
    it("should update style from model", function() {
      cartoMod.render();
      layer.set({tile_style: "#test { polygon-fill: #F00; }"});
      expect(cartoMod.codeEditor.getValue()).toEqual(layer.get('tile_style'));

    });

    it("should parse errors", function() {
      var errors = [
        'style.mss:11:2 Invalid code: asdasd',
        'style.mss:7:2 Invalid code: asdasdasda',
        'style.mss:7:2 Invalid code: asdasdasda'
      ];

      var errParsed = cartoMod._parseError(errors);
      expect(errParsed).toEqual([
        { line: 7, error: 'Invalid code: asdasdasda'},
        { line: 11, error: 'Invalid code: asdasd'}
      ]);
    });

    it("should detect when the cartocss hasn't changed", function() {
      cartoMod.render();
      layer.set({tile_style: "#test { polygon-fill: #F00; }"});
      expect(cartoMod.hasChanges()).toBeFalsy();
    })

    it("should detect when the cartocss has changed", function() {
      cartoMod.render();
      layer.set({tile_style: "#test { polygon-fill: #F00; }"});
      cartoMod.codeEditor.setValue('php sux')
      expect(cartoMod.hasChanges()).toBeTruthy();
    })

    it("should not save the editor when the cartocss hasn't changed", function() {
      var called = false;
      cartoMod.render();
      layer.set({tile_style: "#test { polygon-fill: #F00; }"});
      layer.save = function() {
        called = true;
      }
      cartoMod.applyStyle();
      expect(called).toBeFalsy();
    })

    it("should save the editor when the cartocss has changed", function() {
      var called = false;
      cartoMod.render();
      layer.set({tile_style: "#test { polygon-fill: #F00; }"});
      layer.save = function() {
        called = true;
      }
      cartoMod.codeEditor.setValue('php sux')
      cartoMod.applyStyle();
      expect(called).toBeTruthy();
    })

  });

});
<|endoftext|>


<commit_before>'use strict';

/**
* NOTE: the original C code, the long comment, copyright, license, and the constants are from [netlib]{http://www.netlib.org/fdlibm/s_log1p.c}.
*
* The implementation follows the original, but has been modified for JavaScript.
*/

/**
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/

/**
* double log1p(double x)
*
*  Method :
*    1. Argument Reduction: find k and f such that
*
*        1+x = 2^k * (1+f)
*
*      where  sqrt(2)/2 < 1+f < sqrt(2).
*
*      Note: if k=0, then f=x is exact. However, if k!=0, then f may not be representable exactly. In that case, a correction term is needed. Let u=1+x rounded. Let c = (1+x)-u, then
*
*        log(1+x) - log(u) ~ c/u
*
*      Thus, we proceed to compute log(u), and add back the correction term c/u.
*
*      Note: when x > 2**53, one can simply return log(x).
*
*   2. Approximation of log1p(f).
*     Let s = f/(2+f); based on
*
*        log(1+f) = log(1+s) - log(1-s)
*                 = 2s + 2/3 s**3 + 2/5 s**5 + ...
*                 = 2s + s*R
*
*     We use a special Reme algorithm on [0,0.1716] to generate a polynomial of degree 14 to approximate R. The maximum error of this polynomial approximation is bounded by 2**-58.45. In other words,
*
*                 2      4      6      8      10      12      14
*        R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s  +Lp6*s  +Lp7*s
*
*     (Note: the values of Lp1 to Lp7 are listed in the program.)
*
*     and
*
*        |      2          14          |     -58.45
*        | Lp1*s +...+Lp7*s    -  R(z) | <= 2
*        |                             |
*
*     Note that
*
*        2s = f - s*f
*           = f - hfsq + s*hfsq
*
*     where hfsq = f*f/2.
*
*     In order to guarantee error in log below 1 ulp, we compute log by
*
*        log1p(f) = f - (hfsq - s*(hfsq+R)).
*
*	3. Finally,
*
*        log1p(x) = k*ln2 + log1p(f).
*                 = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
*
*     Here ln2 is split into two floating point numbers:
*
*        ln2_hi + ln2_lo
*
*     where n*ln2_hi is always exact for |n| < 2000.
*
*   Special cases:
*     log1p(x) is NaN with signal if x < -1 (including -INF)
*     log1p(+INF) is +INF
*     log1p(-1) is -INF with signal
*     log1p(NaN) is NaN with no signal
*
*   Accuracy:
*     according to an error analysis, the error is always less than 1 ulp (unit in the last place).
*
*   Constants:
*     The hexadecimal values are the intended ones for the following constants. The decimal values may be used, provided that the compiler will convert from decimal to binary accurately enough to produce the hexadecimal values shown.
*
*   Note:
*     Assuming log() returns accurate answer, the following algorithm can be used to compute log1p(x) to within a few ULP:
*
*        u = 1+x;
*        if(u==1.0) return x;
*        else       return log(u)*(x/(u-1.0));
*
*     See HP-15C Advanced Functions Handbook, p.193.
*/

// MODULES //

var evalpoly = require( '@stdlib/math/base/tools/evalpoly' );
var highWord = require( 'math-float64-get-high-word' );
var setHighWord = require( 'math-float64-set-high-word' );

// CONSTANTS //

var PINF = require( '@stdlib/math/constants/float64-pinf' );
var NINF = require( '@stdlib/math/constants/float64-ninf' );

var BIAS = 1023;

// High and low words of ln(2):
var LN2_HI = 6.93147180369123816490e-01; // 0x3fe62e42 0xfee00000
var LN2_LO = 1.90821492927058770002e-10; // 0x3dea39ef 0x35793c76

// sqrt(2)-1:
var SQRT2M1 = 4.142135623730950488017e-01;  // 0x3fda8279 0x99fcef34

// sqrt(2)/2-1:
var SQRT2HALFM1 = -2.928932188134524755992e-01; // 0xbfd2bec3 0x33018866

// 2**-29:
var SMALL = 1.862645149230957e-09; // 0x3e200000 0x00000000

// 2**-54:
var TINY = 5.551115123125783e-17;

// Max unsafe integer => 2**53:
var TWO53 = 9007199254740992;

// 2/3:
var TWO_THIRDS = 6.666666666666666666e-01;

// Polynomial coefficients:
var Lp = [
	6.666666666666735130e-01, // 0x3FE55555 0x55555593
	3.999999999940941908e-01, // 0x3FD99999 0x9997FA04
	2.857142874366239149e-01, // 0x3FD24924 0x94229359
	2.222219843214978396e-01, // 0x3FCC71C5 0x1D8E78AF
	1.818357216161805012e-01, // 0x3FC74664 0x96CB03DE
	1.531383769920937332e-01, // 0x3FC39A09 0xD078C69F
	1.479819860511658591e-01, // 0x3FC2F112 0xDF3E5244
];

// FUNCTIONS //

var polyval = evalpoly.factory( Lp );

// LOG1P //

/**
* FUNCTION: log1p( x )
*	Computes the natural logarithm of `1+x`.
*
* @param {Number} x - input value
* @returns {Number} function value
*/
function log1p( x ) {
	var hfsq;
	var hu;
	var y;
	var f;
	var c;
	var s;
	var z;
	var R;
	var u;
	var k;

	if ( x < -1 || x !== x ) {
		return NaN;
	}
	if ( x === -1 ) {
		return NINF;
	}
	if ( x === PINF ) {
		return x;
	}
	if ( x === 0 ) {
		return x; // handle +-0 (IEEE 754-2008 spec)
	}
	// Set y = |x|:
	if ( x < 0 ) {
		y = -x;
	} else {
		y = x;
	}
	// Argument reduction...
	k = 1;

	// Check if argument reduction is needed and if we can just return a small value approximation requiring less computation but with equivalent accuracy...
	if ( y < SQRT2M1 ) { // if |x| < sqrt(2)-1 => ~0.41422
		if ( y < SMALL ) { // if |x| < 2**-29
			if( y < TINY ) { // if |x| < 2**-54
				return x;
			}
			// Use a simple two-term Taylor series...
			return x - x*x*0.5;
		}
		// Check if `f=x` can be represented exactly (no need for correction terms), allowing us to bypass argument reduction...
		if ( x > SQRT2HALFM1 ) { // if x > sqrt(2)/2-1 => ~-0.2929
			// => -0.2929 < x < 0.41422
			k = 0;
			f = x; // exact
			hu = 1;
		}
	}
	// Address case where `f` cannot be represented exactly...
	if ( k !== 0 ) {
		if ( y < TWO53 ) {
			u = 1.0 + x;
			hu = highWord( u );

			// Bit shift to isolate the exponent and then subtract the bias:
			k = (hu>>20) - BIAS;

			// Correction term...
			if ( k > 0 ) { // positive unbiased exponent
				c = 1.0 - (u-x);
			} else { // nonpositive unbiased exponent
				c = x - (u-1.0);
			}
			c /= u;
		} else {
			u = x;
			hu = highWord( u );

			// Bit shift to isolate the exponent and then subtract the bias:
			k = (hu>>20) - BIAS;

			// Correction term is zero:
			c = 0;
		}
		// Apply a bit mask (0 00000000000 11111111111111111111) to remove the exponent:
		hu &= 0x000fffff; // max value => 1048575

		// Check if u significand is less than sqrt(2) significand => 0x6a09e => 01101010000010011110
		if ( hu < 434334 ) {
			// Normalize u by setting the exponent to 1023 (bias) => 0x3ff00000 => 0 01111111111 00000000000000000000
			u = setHighWord( u, hu|0x3ff00000 );
		} else {
			k += 1;

			// Normalize u/2 by setting the exponent to 1022 (bias-1 => 2**-1 = 1/2) => 0x3fe00000 => 0 01111111110 00000000000000000000
			u = setHighWord( u, hu|0x3fe00000 );

			// Subtract hu significand from next largest hu => 0 00000000001 00000000000000000000 => 0x00100000 => 1048576
			hu = (1048576-hu)>>2;
		}
		f = u - 1.0;
	}
	// Approximation of log1p(f)...
	hfsq = 0.5 * f * f;
	if( hu === 0 ) { // if |f| < 2**-20
		if ( f === 0 ) {
			c += k * LN2_LO;
			return k * LN2_HI + c;
		}
		R = hfsq * (1.0 - TWO_THIRDS*f); // avoid division
		return k*LN2_HI - ( (R - (k*LN2_LO + c)) - f );
	}
	s = f / (2.0 + f);
	z = s * s;

	R = z * polyval( z );

	if ( k === 0 ) {
		return f - ( hfsq - s*(hfsq+R) );
	}
	return k*LN2_HI - ( (hfsq - (s*(hfsq+R) + (k*LN2_LO + c))) - f );
} // end FUNCTION log1p()

// EXPORTS //

module.exports = log1p;
<commit_msg>Add FIXME notes<commit_after>'use strict';

/**
* NOTE: the original C code, the long comment, copyright, license, and the constants are from [netlib]{http://www.netlib.org/fdlibm/s_log1p.c}.
*
* The implementation follows the original, but has been modified for JavaScript.
*/

/**
* ====================================================
* Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
*
* Developed at SunSoft, a Sun Microsystems, Inc. business.
* Permission to use, copy, modify, and distribute this
* software is freely granted, provided that this notice
* is preserved.
* ====================================================
*/

/**
* double log1p(double x)
*
*  Method :
*    1. Argument Reduction: find k and f such that
*
*        1+x = 2^k * (1+f)
*
*      where  sqrt(2)/2 < 1+f < sqrt(2).
*
*      Note: if k=0, then f=x is exact. However, if k!=0, then f may not be representable exactly. In that case, a correction term is needed. Let u=1+x rounded. Let c = (1+x)-u, then
*
*        log(1+x) - log(u) ~ c/u
*
*      Thus, we proceed to compute log(u), and add back the correction term c/u.
*
*      Note: when x > 2**53, one can simply return log(x).
*
*   2. Approximation of log1p(f).
*     Let s = f/(2+f); based on
*
*        log(1+f) = log(1+s) - log(1-s)
*                 = 2s + 2/3 s**3 + 2/5 s**5 + ...
*                 = 2s + s*R
*
*     We use a special Reme algorithm on [0,0.1716] to generate a polynomial of degree 14 to approximate R. The maximum error of this polynomial approximation is bounded by 2**-58.45. In other words,
*
*                 2      4      6      8      10      12      14
*        R(z) ~ Lp1*s +Lp2*s +Lp3*s +Lp4*s +Lp5*s  +Lp6*s  +Lp7*s
*
*     (Note: the values of Lp1 to Lp7 are listed in the program.)
*
*     and
*
*        |      2          14          |     -58.45
*        | Lp1*s +...+Lp7*s    -  R(z) | <= 2
*        |                             |
*
*     Note that
*
*        2s = f - s*f
*           = f - hfsq + s*hfsq
*
*     where hfsq = f*f/2.
*
*     In order to guarantee error in log below 1 ulp, we compute log by
*
*        log1p(f) = f - (hfsq - s*(hfsq+R)).
*
*	3. Finally,
*
*        log1p(x) = k*ln2 + log1p(f).
*                 = k*ln2_hi+(f-(hfsq-(s*(hfsq+R)+k*ln2_lo)))
*
*     Here ln2 is split into two floating point numbers:
*
*        ln2_hi + ln2_lo
*
*     where n*ln2_hi is always exact for |n| < 2000.
*
*   Special cases:
*     log1p(x) is NaN with signal if x < -1 (including -INF)
*     log1p(+INF) is +INF
*     log1p(-1) is -INF with signal
*     log1p(NaN) is NaN with no signal
*
*   Accuracy:
*     according to an error analysis, the error is always less than 1 ulp (unit in the last place).
*
*   Constants:
*     The hexadecimal values are the intended ones for the following constants. The decimal values may be used, provided that the compiler will convert from decimal to binary accurately enough to produce the hexadecimal values shown.
*
*   Note:
*     Assuming log() returns accurate answer, the following algorithm can be used to compute log1p(x) to within a few ULP:
*
*        u = 1+x;
*        if(u==1.0) return x;
*        else       return log(u)*(x/(u-1.0));
*
*     See HP-15C Advanced Functions Handbook, p.193.
*/

// MODULES //

var evalpoly = require( '@stdlib/math/base/tools/evalpoly' );
// FIXME
var highWord = require( 'math-float64-get-high-word' );
// FIXME
var setHighWord = require( 'math-float64-set-high-word' );

// CONSTANTS //

var PINF = require( '@stdlib/math/constants/float64-pinf' );
var NINF = require( '@stdlib/math/constants/float64-ninf' );

var BIAS = 1023;

// High and low words of ln(2):
var LN2_HI = 6.93147180369123816490e-01; // 0x3fe62e42 0xfee00000
var LN2_LO = 1.90821492927058770002e-10; // 0x3dea39ef 0x35793c76

// sqrt(2)-1:
var SQRT2M1 = 4.142135623730950488017e-01;  // 0x3fda8279 0x99fcef34

// sqrt(2)/2-1:
var SQRT2HALFM1 = -2.928932188134524755992e-01; // 0xbfd2bec3 0x33018866

// 2**-29:
var SMALL = 1.862645149230957e-09; // 0x3e200000 0x00000000

// 2**-54:
var TINY = 5.551115123125783e-17;

// Max unsafe integer => 2**53:
var TWO53 = 9007199254740992;

// 2/3:
var TWO_THIRDS = 6.666666666666666666e-01;

// Polynomial coefficients:
var Lp = [
	6.666666666666735130e-01, // 0x3FE55555 0x55555593
	3.999999999940941908e-01, // 0x3FD99999 0x9997FA04
	2.857142874366239149e-01, // 0x3FD24924 0x94229359
	2.222219843214978396e-01, // 0x3FCC71C5 0x1D8E78AF
	1.818357216161805012e-01, // 0x3FC74664 0x96CB03DE
	1.531383769920937332e-01, // 0x3FC39A09 0xD078C69F
	1.479819860511658591e-01, // 0x3FC2F112 0xDF3E5244
];

// FUNCTIONS //

var polyval = evalpoly.factory( Lp );

// LOG1P //

/**
* FUNCTION: log1p( x )
*	Computes the natural logarithm of `1+x`.
*
* @param {Number} x - input value
* @returns {Number} function value
*/
function log1p( x ) {
	var hfsq;
	var hu;
	var y;
	var f;
	var c;
	var s;
	var z;
	var R;
	var u;
	var k;

	if ( x < -1 || x !== x ) {
		return NaN;
	}
	if ( x === -1 ) {
		return NINF;
	}
	if ( x === PINF ) {
		return x;
	}
	if ( x === 0 ) {
		return x; // handle +-0 (IEEE 754-2008 spec)
	}
	// Set y = |x|:
	if ( x < 0 ) {
		y = -x;
	} else {
		y = x;
	}
	// Argument reduction...
	k = 1;

	// Check if argument reduction is needed and if we can just return a small value approximation requiring less computation but with equivalent accuracy...
	if ( y < SQRT2M1 ) { // if |x| < sqrt(2)-1 => ~0.41422
		if ( y < SMALL ) { // if |x| < 2**-29
			if( y < TINY ) { // if |x| < 2**-54
				return x;
			}
			// Use a simple two-term Taylor series...
			return x - x*x*0.5;
		}
		// Check if `f=x` can be represented exactly (no need for correction terms), allowing us to bypass argument reduction...
		if ( x > SQRT2HALFM1 ) { // if x > sqrt(2)/2-1 => ~-0.2929
			// => -0.2929 < x < 0.41422
			k = 0;
			f = x; // exact
			hu = 1;
		}
	}
	// Address case where `f` cannot be represented exactly...
	if ( k !== 0 ) {
		if ( y < TWO53 ) {
			u = 1.0 + x;
			hu = highWord( u );

			// Bit shift to isolate the exponent and then subtract the bias:
			k = (hu>>20) - BIAS;

			// Correction term...
			if ( k > 0 ) { // positive unbiased exponent
				c = 1.0 - (u-x);
			} else { // nonpositive unbiased exponent
				c = x - (u-1.0);
			}
			c /= u;
		} else {
			u = x;
			hu = highWord( u );

			// Bit shift to isolate the exponent and then subtract the bias:
			k = (hu>>20) - BIAS;

			// Correction term is zero:
			c = 0;
		}
		// Apply a bit mask (0 00000000000 11111111111111111111) to remove the exponent:
		hu &= 0x000fffff; // max value => 1048575

		// Check if u significand is less than sqrt(2) significand => 0x6a09e => 01101010000010011110
		if ( hu < 434334 ) {
			// Normalize u by setting the exponent to 1023 (bias) => 0x3ff00000 => 0 01111111111 00000000000000000000
			u = setHighWord( u, hu|0x3ff00000 );
		} else {
			k += 1;

			// Normalize u/2 by setting the exponent to 1022 (bias-1 => 2**-1 = 1/2) => 0x3fe00000 => 0 01111111110 00000000000000000000
			u = setHighWord( u, hu|0x3fe00000 );

			// Subtract hu significand from next largest hu => 0 00000000001 00000000000000000000 => 0x00100000 => 1048576
			hu = (1048576-hu)>>2;
		}
		f = u - 1.0;
	}
	// Approximation of log1p(f)...
	hfsq = 0.5 * f * f;
	if( hu === 0 ) { // if |f| < 2**-20
		if ( f === 0 ) {
			c += k * LN2_LO;
			return k * LN2_HI + c;
		}
		R = hfsq * (1.0 - TWO_THIRDS*f); // avoid division
		return k*LN2_HI - ( (R - (k*LN2_LO + c)) - f );
	}
	s = f / (2.0 + f);
	z = s * s;

	R = z * polyval( z );

	if ( k === 0 ) {
		return f - ( hfsq - s*(hfsq+R) );
	}
	return k*LN2_HI - ( (hfsq - (s*(hfsq+R) + (k*LN2_LO + c))) - f );
} // end FUNCTION log1p()

// EXPORTS //

module.exports = log1p;
<|endoftext|>


<commit_before>// MongoDB stuff
// Created by Fredrik A. Madsen-Malmo

// Imports
var mongo = require('mongodb').MongoClient;
var assert = require('assert');
var Promise = require('promise');

// Mongo config
var PORT = 27017 || process.env.MONGOPORT;
var HOST = 'localhost' || process.env.MONGOHOST;
var DB = 'serverstatus' || process.env.MONGODB;

var URL = 'mongodb://' + HOST + ':' + PORT + '/' + DB;

// Base function
var WEEKDAYS = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'
];

/**
 * Connects to the database and calls the anon function provided
 * @param  {Function}  Func Anon function to call
 * @return {null}      No return value
 */
var connect = function (func) {
    mongo.connect(URL, function (err, db) {
        if (err) {
            throw err;
        }

        assert.equal(null, err);
        func(db);
    });
};

// DB functions

/**
 * Callback used for the isert function
 * @param  {Object}   err     This is the Error object that describes the error encountered
 * @param  {Object}   result  This is the result, contains all info about the insert
 * @param  {Object}   db      The database object, here I use it to close the db
 * @param  {Function} resolve This is the function to be called when the script completes
 * @param  {Function} reject  This is the function to be called if the script fails
 * @return {Object}           Resolve or Reject
 */
function insertCallback (err, result, db, resolve, reject) {
    if (err) {
        reject(err);
    }

    assert.equal(err, null);

    db.close();
    resolve(result);
}

/**
 * Insert an entry into the db
 * @param  {String}   mode  either 'temp' or 'load'; what kind of entry
 * @param  {String}    value the value to insert.
 * @return {Function} A promise with the value passed in
 */
var insert = function (mode, value) {
    return new Promise(function (resolve, reject) {
        connect(function (db) {
            if (mode.toLowerCase() == 'temp') {
                db.collection('temp').insertOne({
                    "time": new Date(),
                    "temp": (parseFloat(value.replace(',', '.')))
                }, function(err, result){insertCallback(err, result, db, resolve, reject);});
                console.log(value);
            } else if (mode.toLowerCase() == 'load') {
                db.collection('load').insertOne({
                    "time": new Date(),
                    "load": ((parseFloat(value.replace(',', '.')) / 4) * 100)
                }, function(err, result){insertCallback(err, result, db, resolve, reject);});
                console.log(value);
            } else {
                db.close();
                reject('Invalid input');
            }
        });
    });
};

/**
 * Gets the 20 last entries of one mode
 * @param  {String} mode The type of entry to retrieve
 * @return {Function}    Returns either a resolve or reject function
 */
var realtime = function (mode) {
    var latest = [];

    return new Promise(function (resolve, reject) {
        connect(function (db) {
            var cursor = db.collection(mode).find({  }).limit(20).sort({time:-1});

            cursor.each(function (err, doc) {
                if (err) {
                    reject(err);
                }

                assert.equal(err, null);

                if (doc !== null) {
                    // Push [hh:mm:ss, temp|load] to latest
                    latest.push([doc.time.toTimeString().substr(0, 8),
                                 (doc.temp || doc.load)]);
                } else {
                    resolve(latest);
                    db.close();
                }
            });
        });
    });
};

/**
 * Get's the average temperature for the 20 last minutes
 * @param  {String} What type of entry to retrieve
 * @return {Array}  Two-dimentional array with HH:MM and temp|load:float
 */
var minute = function (mode) {
    var minutes = [];

    return new Promise(function (resolve, reject) {
        connect(function (db) {
            var count = -1;
            var prev = -1;
            var count_internal = 2;

            var cursor = db.collection(mode).find({}).sort({time:-1});

            cursor.each(function (err, doc) {
                if (err) {
                    reject(err);
                }

                assert.equal(err, null);

                if (doc !== null) {
                    if (count < 19 && doc.time.getMinutes() == prev) {
                        // Push [hh:mm:ss, temp|load] to minutes
                        minutes[count] = [doc.time.toTimeString().substr(0, 5),
                                          minutes[count][1] + (doc.temp || doc.load)];
                        count_internal++;
                    } else if (count < 19 && doc.time.getMinutes() != prev) {
                        count++;
                        prev = doc.time.getMinutes();
                        // Push [hh:mm:ss, temp|load] to minutes
                        minutes[count] = [doc.time.toTimeString().substr(0,5),
                                          0 + (doc.temp || doc.load)];
                        count_internal = 2;
                    } else {
                        resolve(minutes);
                        db.close();
                    }
                } else {
                    resolve(minutes);
                    db.close();
                }
            });
        });
    });
};

/**
 * Get's the average temperature for the last 10 hours
 * @param  {String} What type of entry to retrieve
 * @return {Array}  Two-dimentional array with Weekday date, hour:00
 */
var hour = function(mode) {
    var hours = [];

    return new Promise(function (resolve, reject) {
        connect(function (db) {
            var count = -1;
            var prev = -1;
            var count_internal = 2;

            var cursor = db.collection(mode).find({}).sort({time:-1});

            cursor.each(function (err, doc) {
                if (err) {
                    reject(err);
                }

                assert.equal(err, null);

                if (doc !== null) {
                    if (count < 9 && doc.time.getHours() == prev) {
                        // Push [hh:mm:ss, temp|load] to hours
                        hours[count] = [WEEKDAYS[doc.time.getDay()] + ' ' +
                                        doc.time.getDate() + ', ' +
                                        doc.time.toTimeString().substr(0,2) + ':00',
                                        hours[count][1] + (doc.temp || doc.load)];
                        count_internal++;
                    } else if (count < 9 && doc.time.getHours() != prev) {
                        count++;
                        prev = doc.time.getHours();
                        // Push [hh:mm:ss, temp|load] to hours
                        hours[count] = [WEEKDAYS[doc.time.getDay()] + ' ' +
                                        doc.time.getDate() + ', ' +
                                        doc.time.toTimeString().substr(0,2) + ':00',
                                        0 + (doc.temp || doc.load)];
                        count_internal = 2;
                    } else {
                        resolve(hours);
                        console.log(hours.length);
                        db.close();
                    }
                } else {
                    resolve(hours);
                    console.log(hours.length);
                    db.close();
                }
            });
        });
    });
};

/**
 * Get's the average temperature for the last week
 * @param  {String} What type of entry to retrieve
 * @return {Array}  Two-dimentional array with Weekday date/month
 */
var day = function(mode) {
    var days = [];

    return new Promise(function (resolve, reject) {
        connect(function (db) {
            var count = -1;
            var prev = -1;
            var count_internal = 2;

            var cursor = db.collection(mode).find({}).sort({time:-1});

            cursor.each(function (err, doc) {
                if (err) {
                    reject(err);
                }

                assert.equal(err, null);

                if (doc !== null) {
                    if (count < 6 && doc.time.getDate() == prev) {
                        // Push [hh:mm:ss, temp|load] to days
                        days[count] = [WEEKDAYS[doc.time.getDay()] + ' ' +
                                        doc.time.getDate() + '/' +
                                        (doc.time.getMonth() + 1),
                                        days[count][1] + (doc.temp || doc.load)];
                        count_internal++;
                    } else if (count < 6 && doc.time.getDate() != prev) {
                        count++;
                        prev = doc.time.getDate();
                        // Push [hh:mm:ss, temp|load] to days
                        days[count] = [WEEKDAYS[doc.time.getDay()] + ' ' +
                                        doc.time.getDate() + '/' +
                                        (doc.time.getMonth() + 1),
                                        0 + (doc.temp || doc.load)];
                        count_internal = 2;
                    } else {
                        resolve(days);
                        console.log(days);
                        db.close();
                    }
                } else {
                    resolve(days);
                    db.close();
                }
            });
        });
    });
};

// Exports

module.exports = {
    insert: insert,
    realtime: realtime,
    minute: minute,
    hour: hour,
    day: day
};
<commit_msg>remove debug from hour/day<commit_after>// MongoDB stuff
// Created by Fredrik A. Madsen-Malmo

// Imports
var mongo = require('mongodb').MongoClient;
var assert = require('assert');
var Promise = require('promise');

// Mongo config
var PORT = 27017 || process.env.MONGOPORT;
var HOST = 'localhost' || process.env.MONGOHOST;
var DB = 'serverstatus' || process.env.MONGODB;

var URL = 'mongodb://' + HOST + ':' + PORT + '/' + DB;

// Base function
var WEEKDAYS = [
    'Sunday',
    'Monday',
    'Tuesday',
    'Wednesday',
    'Thursday',
    'Friday',
    'Saturday'
];

/**
 * Connects to the database and calls the anon function provided
 * @param  {Function}  Func Anon function to call
 * @return {null}      No return value
 */
var connect = function (func) {
    mongo.connect(URL, function (err, db) {
        if (err) {
            throw err;
        }

        assert.equal(null, err);
        func(db);
    });
};

// DB functions

/**
 * Callback used for the isert function
 * @param  {Object}   err     This is the Error object that describes the error encountered
 * @param  {Object}   result  This is the result, contains all info about the insert
 * @param  {Object}   db      The database object, here I use it to close the db
 * @param  {Function} resolve This is the function to be called when the script completes
 * @param  {Function} reject  This is the function to be called if the script fails
 * @return {Object}           Resolve or Reject
 */
function insertCallback (err, result, db, resolve, reject) {
    if (err) {
        reject(err);
    }

    assert.equal(err, null);

    db.close();
    resolve(result);
}

/**
 * Insert an entry into the db
 * @param  {String}   mode  either 'temp' or 'load'; what kind of entry
 * @param  {String}    value the value to insert.
 * @return {Function} A promise with the value passed in
 */
var insert = function (mode, value) {
    return new Promise(function (resolve, reject) {
        connect(function (db) {
            if (mode.toLowerCase() == 'temp') {
                db.collection('temp').insertOne({
                    "time": new Date(),
                    "temp": (parseFloat(value.replace(',', '.')))
                }, function(err, result){insertCallback(err, result, db, resolve, reject);});
                console.log(value);
            } else if (mode.toLowerCase() == 'load') {
                db.collection('load').insertOne({
                    "time": new Date(),
                    "load": ((parseFloat(value.replace(',', '.')) / 4) * 100)
                }, function(err, result){insertCallback(err, result, db, resolve, reject);});
                console.log(value);
            } else {
                db.close();
                reject('Invalid input');
            }
        });
    });
};

/**
 * Gets the 20 last entries of one mode
 * @param  {String} mode The type of entry to retrieve
 * @return {Function}    Returns either a resolve or reject function
 */
var realtime = function (mode) {
    var latest = [];

    return new Promise(function (resolve, reject) {
        connect(function (db) {
            var cursor = db.collection(mode).find({  }).limit(20).sort({time:-1});

            cursor.each(function (err, doc) {
                if (err) {
                    reject(err);
                }

                assert.equal(err, null);

                if (doc !== null) {
                    // Push [hh:mm:ss, temp|load] to latest
                    latest.push([doc.time.toTimeString().substr(0, 8),
                                 (doc.temp || doc.load)]);
                } else {
                    resolve(latest);
                    db.close();
                }
            });
        });
    });
};

/**
 * Get's the average temperature for the 20 last minutes
 * @param  {String} What type of entry to retrieve
 * @return {Array}  Two-dimentional array with HH:MM and temp|load:float
 */
var minute = function (mode) {
    var minutes = [];
    var count = 1;

    return new Promise(function (resolve, reject) {
        connect(function (db) {
            var count = -1;
            var prev = -1;
            var count_internal = 2;

            var cursor = db.collection(mode).find({}).sort({time:-1});

            cursor.each(function (err, doc) {
                if (err) {
                    reject(err);
                }

                assert.equal(err, null);

                if (doc !== null) {
                    if (count < 19 && doc.time.getMinutes() == prev) {
                        // Push [hh:mm:ss, temp|load] to minutes
                        minutes[count] = [doc.time.toTimeString().substr(0, 5),
                                          minutes[count][1] + (doc.temp || doc.load)];
                        count++;
                    } else if (count < 19 && doc.time.getMinutes() != prev) {
                        count++;
                        prev = doc.time.getMinutes();
                        // Push [hh:mm:ss, temp|load] to minutes
                        minutes[count] = [doc.time.toTimeString().substr(0,5),
                                          0 + (doc.temp || doc.load)];
                        count_internal = 2;
                    } else {
                        resolve(minutes);
                        db.close();
                    }
                } else {
                    resolve(minutes);
                    db.close();
                }
            });
        });
    });
};

/**
 * Get's the average temperature for the last 10 hours
 * @param  {String} What type of entry to retrieve
 * @return {Array}  Two-dimentional array with Weekday date, hour:00
 */
var hour = function(mode) {
    var hours = [];

    return new Promise(function (resolve, reject) {
        connect(function (db) {
            var count = -1;
            var prev = -1;
            var count_internal = 2;

            var cursor = db.collection(mode).find({}).sort({time:-1});

            cursor.each(function (err, doc) {
                if (err) {
                    reject(err);
                }

                assert.equal(err, null);

                if (doc !== null) {
                    if (count < 9 && doc.time.getHours() == prev) {
                        // Push [hh:mm:ss, temp|load] to hours
                        hours[count] = [WEEKDAYS[doc.time.getDay()] + ' ' +
                                        doc.time.getDate() + ', ' +
                                        doc.time.toTimeString().substr(0,2) + ':00',
                                        hours[count][1] + (doc.temp || doc.load)];
                        count_internal++;
                    } else if (count < 9 && doc.time.getHours() != prev) {
                        count++;
                        prev = doc.time.getHours();
                        // Push [hh:mm:ss, temp|load] to hours
                        hours[count] = [WEEKDAYS[doc.time.getDay()] + ' ' +
                                        doc.time.getDate() + ', ' +
                                        doc.time.toTimeString().substr(0,2) + ':00',
                                        0 + (doc.temp || doc.load)];
                        count_internal = 2;
                    } else {
                        resolve(hours);
                        db.close();
                    }
                } else {
                    resolve(hours);
                    db.close();
                }
            });
        });
    });
};

/**
 * Get's the average temperature for the last week
 * @param  {String} What type of entry to retrieve
 * @return {Array}  Two-dimentional array with Weekday date/month
 */
var day = function(mode) {
    var days = [];

    return new Promise(function (resolve, reject) {
        connect(function (db) {
            var count = -1;
            var prev = -1;
            var count_internal = 2;

            var cursor = db.collection(mode).find({}).sort({time:-1});

            cursor.each(function (err, doc) {
                if (err) {
                    reject(err);
                }

                assert.equal(err, null);

                if (doc !== null) {
                    if (count < 6 && doc.time.getDate() == prev) {
                        // Push [hh:mm:ss, temp|load] to days
                        days[count] = [WEEKDAYS[doc.time.getDay()] + ' ' +
                                        doc.time.getDate() + '/' +
                                        (doc.time.getMonth() + 1),
                                        days[count][1] + (doc.temp || doc.load)];
                        count_internal++;
                    } else if (count < 6 && doc.time.getDate() != prev) {
                        count++;
                        prev = doc.time.getDate();
                        // Push [hh:mm:ss, temp|load] to days
                        days[count] = [WEEKDAYS[doc.time.getDay()] + ' ' +
                                        doc.time.getDate() + '/' +
                                        (doc.time.getMonth() + 1),
                                        0 + (doc.temp || doc.load)];
                        count_internal = 2;
                    } else {
                        resolve(days);
                        db.close();
                    }
                } else {
                    resolve(days);
                    db.close();
                }
            });
        });
    });
};

// Exports

module.exports = {
    insert: insert,
    realtime: realtime,
    minute: minute,
    hour: hour,
    day: day
};
<|endoftext|>


<commit_before>/*
 * Project: electron-is
 * Version: 2.0.2
 * Author: delvedor
 * Twitter: @delvedor
 * License: MIT
 * GitHub: https://github.com/delvedor/electron-is
 */

'use strict'

const { gt, lt } = require('semver')
const { release } = require('os')
const isDev = require('electron-is-dev')

// Constructor
function IsApi () {}

// Checks if we are in renderer process
IsApi.prototype.renderer = function () {
  return process.type === 'renderer'
}

// Checks if we are in main process
IsApi.prototype.main = function () {
  return process.type === 'browser'
}

// Checks if we are under Mac OS
IsApi.prototype.osx = function () {
  return process.platform === 'darwin'
}

// Checks if we are under Windows OS
IsApi.prototype.windows = function () {
  return process.platform === 'win32'
}

// Checks if we are under Linux OS
IsApi.prototype.linux = function () {
  return process.platform === 'linux'
}

// Checks if we are the processor's arch is x86
IsApi.prototype.x86 = function () {
  return process.arch === 'ia32'
}

// Checks if we are the processor's arch is x64
IsApi.prototype.x64 = function () {
  return process.arch === 'x64'
}

// Checks if the env is setted to 'production'
IsApi.prototype.production = function () {
  return !isDev
}

// Checks if the env is setted to 'dev'
IsApi.prototype.dev = function () {
  return isDev
}

// checks if all the 'is functions' passed as arguments are true
IsApi.prototype.all = function (...isFunctions) {
  if (!isFunctions.length) return
  for (let i = 0; i < isFunctions.length; i++) {
    if (!isFunctions[i]()) return false
  }
  return true
}

// checks if all the 'is functions' passed as arguments are false
IsApi.prototype.none = function (...isFunctions) {
  if (!isFunctions.length) return
  for (let i = 0; i < isFunctions.length; i++) {
    if (isFunctions[i]()) return false
  }
  return true
}

// returns true if one of the 'is functions' passed as argument is true
IsApi.prototype.one = function (...isFunctions) {
  if (!isFunctions.length) return
  for (let i = 0; i < isFunctions.length; i++) {
    if (isFunctions[i]()) return true
  }
  return false
}

// checks the if the given release is the same of the OS
IsApi.prototype.release = function (requested) {
  if (this.osx()) {
    return requested === osxRelease()
  } else if (this.windows()) {
    let requested = requested.split('.')
    let actual = release().split('.')
    if (requested.length === 2) {
      return `${actual[0]}.${actual[1]}` === `${requested[0]}.${requested[1]}`
    }
    return `${actual[0]}.${actual[1]}.${actual[2]}` === `${requested[0]}.${requested[1]}.${requested[2]}`
  } else {
    // Not implemented for Linux yet
    return null
  }
}

// checks if the given release is greater than the current OS release
IsApi.prototype.gtRelease = function (requested) {
  if (this.osx()) {
    return gt(requested, osxRelease())
  } else if (this.windows()) {
    let requested = requested.split('.')
    let actual = release().split('.')
    if (requested.length === 2) {
      return gt(`${requested[0]}.${requested[1]}.0`, `${actual[0]}.${actual[1]}.0`)
    }
    return gt(`${requested[0]}.${requested[1]}.${requested[2]}`, `${actual[0]}.${actual[1]}.${actual[2]}`)
  } else {
    // Not implemented for Linux yet
    return null
  }
}

// checks if the given release is less than the current OS release
IsApi.prototype.ltRelease = function (requested) {
  if (this.osx()) {
    return lt(requested, osxRelease())
  } else if (this.windows()) {
    let requested = requested.split('.')
    let actual = release().split('.')
    if (requested.length === 2) {
      return lt(`${requested[0]}.${requested[1]}.0`, `${actual[0]}.${actual[1]}.0`)
    }
    return lt(`${requested[0]}.${requested[1]}.${requested[2]}`, `${actual[0]}.${actual[1]}.${actual[2]}`)
  } else {
    // Not implemented for Linux yet
    return null
  }
}

// returns the current osx release
function osxRelease () {
  let actual = release().split('.')
  return `10.${actual[0] - 4}.${actual[1]}`
}

// new instace
function isBuilder () {
  if (!(this instanceof IsApi)) {
    return new IsApi()
  }
}

// exports
module.exports = isBuilder()
<commit_msg>Added is.macOS()<commit_after>/*
 * Project: electron-is
 * Version: 2.0.2
 * Author: delvedor
 * Twitter: @delvedor
 * License: MIT
 * GitHub: https://github.com/delvedor/electron-is
 */

'use strict'

const { gt, lt } = require('semver')
const { release } = require('os')
const isDev = require('electron-is-dev')

// Constructor
function IsApi () {}

// Checks if we are in renderer process
IsApi.prototype.renderer = function () {
  return process.type === 'renderer'
}

// Checks if we are in main process
IsApi.prototype.main = function () {
  return process.type === 'browser'
}

// Checks if we are under Mac OS
IsApi.prototype.osx = IsApi.prototype.macOS = function () {
  return process.platform === 'darwin'
}

// Checks if we are under Windows OS
IsApi.prototype.windows = function () {
  return process.platform === 'win32'
}

// Checks if we are under Linux OS
IsApi.prototype.linux = function () {
  return process.platform === 'linux'
}

// Checks if we are the processor's arch is x86
IsApi.prototype.x86 = function () {
  return process.arch === 'ia32'
}

// Checks if we are the processor's arch is x64
IsApi.prototype.x64 = function () {
  return process.arch === 'x64'
}

// Checks if the env is setted to 'production'
IsApi.prototype.production = function () {
  return !isDev
}

// Checks if the env is setted to 'dev'
IsApi.prototype.dev = function () {
  return isDev
}

// checks if all the 'is functions' passed as arguments are true
IsApi.prototype.all = function (...isFunctions) {
  if (!isFunctions.length) return
  for (let i = 0; i < isFunctions.length; i++) {
    if (!isFunctions[i]()) return false
  }
  return true
}

// checks if all the 'is functions' passed as arguments are false
IsApi.prototype.none = function (...isFunctions) {
  if (!isFunctions.length) return
  for (let i = 0; i < isFunctions.length; i++) {
    if (isFunctions[i]()) return false
  }
  return true
}

// returns true if one of the 'is functions' passed as argument is true
IsApi.prototype.one = function (...isFunctions) {
  if (!isFunctions.length) return
  for (let i = 0; i < isFunctions.length; i++) {
    if (isFunctions[i]()) return true
  }
  return false
}

// checks the if the given release is the same of the OS
IsApi.prototype.release = function (requested) {
  if (this.osx()) {
    return requested === osxRelease()
  } else if (this.windows()) {
    let requested = requested.split('.')
    let actual = release().split('.')
    if (requested.length === 2) {
      return `${actual[0]}.${actual[1]}` === `${requested[0]}.${requested[1]}`
    }
    return `${actual[0]}.${actual[1]}.${actual[2]}` === `${requested[0]}.${requested[1]}.${requested[2]}`
  } else {
    // Not implemented for Linux yet
    return null
  }
}

// checks if the given release is greater than the current OS release
IsApi.prototype.gtRelease = function (requested) {
  if (this.osx()) {
    return gt(requested, osxRelease())
  } else if (this.windows()) {
    let requested = requested.split('.')
    let actual = release().split('.')
    if (requested.length === 2) {
      return gt(`${requested[0]}.${requested[1]}.0`, `${actual[0]}.${actual[1]}.0`)
    }
    return gt(`${requested[0]}.${requested[1]}.${requested[2]}`, `${actual[0]}.${actual[1]}.${actual[2]}`)
  } else {
    // Not implemented for Linux yet
    return null
  }
}

// checks if the given release is less than the current OS release
IsApi.prototype.ltRelease = function (requested) {
  if (this.osx()) {
    return lt(requested, osxRelease())
  } else if (this.windows()) {
    let requested = requested.split('.')
    let actual = release().split('.')
    if (requested.length === 2) {
      return lt(`${requested[0]}.${requested[1]}.0`, `${actual[0]}.${actual[1]}.0`)
    }
    return lt(`${requested[0]}.${requested[1]}.${requested[2]}`, `${actual[0]}.${actual[1]}.${actual[2]}`)
  } else {
    // Not implemented for Linux yet
    return null
  }
}

// returns the current osx release
function osxRelease () {
  let actual = release().split('.')
  return `10.${actual[0] - 4}.${actual[1]}`
}

// new instace
function isBuilder () {
  if (!(this instanceof IsApi)) {
    return new IsApi()
  }
}

// exports
module.exports = isBuilder()
<|endoftext|>