<commit_before>import React, { useState } from "react";
import Button from "@agir/front/genericComponents/Button";
import TextField from "@agir/front/formComponents/TextField";

import logoDesktop from "../genericComponents/logos/action-populaire.svg";
import logoMobile from "../genericComponents/logos/action-populaire_mini.svg";
import bgDesktop from "../genericComponents/images/login_bg_desktop.svg";
import bgMobile from "../genericComponents/images/login_bg_mobile.svg";
import facebookImg from "../genericComponents/images/facebook_circle.svg";
import arrowRight from "../genericComponents/images/arrow-right.svg";
import chevronDown from "../genericComponents/images/chevron-down.svg";

import styled from "styled-components";
import style from "@agir/front/genericComponents/_variables.scss";

const LeftBlock = styled.div`
  width: 40%;
  height: 100vh;
  background-color: ${style.secondary100};
  position: relative;
  @media (max-width: ${style.collapse}px) {
    display: none;
  }
`;

const MainBlock = styled.div`
  width: 60%;
  height: 100vh;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  h1 {
    margin: 0px;
    font-weight: 700;
    font-size: 40px;
  }

  .mobile-only {
    display: none;
  }

  .button-facebook {
    max-width: 100%;
    width: 400px;
    justify-content: center;
    font-weight: normal;
    background-color: white;
    border: 1px solid #C4C4C4;
  }

  @media (max-width: ${style.collapse}px) {
    width: 100%;
    display: block;
    text-align: center;

    h1 {
      font-size: 28px;
    }

    .mobile-only {
      display: block;
    }

    .mobile-center {
      text-align: center;
    }
  }
`;

// const FacebookButton = styled.Button`
//   &:hover{
//     background-color: #eee;
//   }
// `;

const InlineBlock = styled.span`
  display: inline-block;
  text-align: left;
`;

//const mockMails = ["mgoaziou@gmail.com", "test@franceinsoumise.org"];
const mockMails = ["mgoaziou@gmail.com"];

const Login = () => {
  return (
    <>

      <TextField
        error=""
        id="field"
        label="Adresse e-mail"
        placeholder="Adresse e-mail"
        onChange={() => {}}
        value=""
      />

    <Button
      color="primary"
      style={{
        marginTop: "0.5rem",
        maxWidth: "100%",
        width: "400px",
        justifyContent: "center",
      }}
    >
      Me connecter
    </Button>
    </>
  )
};

const FacebookLogin = () => {
  return (
    <Button className="button-facebook">

        Connexion avec Facebook
    </Button>
  );
};

const ToastNotConnected = () => {
  return (

    Vous devez vous connecter pour accéder à cette page

);
};

const Connexion = () => {

  const [existantMails, setExistantMails] = useState(mockMails);
  const [showMore, setShowMore] = useState(false);

  const handleShowMore = () => {
    setShowMore(true);
  };

  return (
    <>

        <LeftBlock>

              <InlineBlock
                style={{
                  maxWidth: "350px",
                  lineHeight: "21px",
                  textAlign: "left",
                }}
              >
                Le réseau social d’action pour la candidature de Jean-Luc
                Mélenchon <InlineBlock>pour 2022</InlineBlock>
              </InlineBlock>

          {/*  */}

          <div
            style={{
              position: "absolute",
              bottom: "0px",
              left: "0px",
              width: "100%",
              height: "450px",
              backgroundImage: `url(${bgDesktop})`,
              backgroundSize: "cover",
              backgroundRepeat: "no-repeat",
            }}
          >

        </LeftBlock>

        <MainBlock>

          <InlineBlock style={{ width: "400px", maxWidth: "100%", paddingLeft: "32px", paddingRight: "32px" }}>

Je me connecte

            <InlineBlock style={{ marginTop: "8px" }}>
              Pas encore de compte ?

                Je m'inscris

            </InlineBlock>

            <ToastNotConnected />

            {/* EXISTANT MAILS */}
            {(existantMails.length > 0) &&

              À mon compte :

              {existantMails.map((mail, id) => (
              <Button
                key={id}
                color="primary"
                style={{
                  marginTop: "0.5rem",
                  marginLeft: "0px",
                  maxWidth: "100%",
                  width: "400px",
                  justifyContent: "space-between",
                }}
              >
                {mail}

              </Button>
              ))}

}

            {!showMore && <InlineBlock onClick={handleShowMore}
                style={{fontWeight: "700", color: style.primary500, marginTop: "21px", cursor: "pointer" }}>
                Afficher tout
            </InlineBlock>}

            {showMore &&

              OU

}

            {(showMore || !(existantMails.length > 0)) && <>
            <Login />

OU

            <FacebookLogin />
            </>}

            {showMore &&

              Pas encore de compte ?

              <InlineBlock style={{fontWeight: "700", color: style.primary500}}>
                  Rejoignez Action Populaire
              </InlineBlock>

}

          </InlineBlock>

          <div
            className="mobile-only"
            style={{
              width: "100%",
              height: "150px",
              backgroundImage: `url(${bgMobile})`,
              backgroundSize: "cover",
              backgroundRepeat: "no-repeat",
            }}
          >

        </MainBlock>

    </>
  );
};

export default Connexion;
<commit_msg>fix lint<commit_after>import React, { useState } from "react";
import Button from "@agir/front/genericComponents/Button";
import TextField from "@agir/front/formComponents/TextField";

import logoDesktop from "../genericComponents/logos/action-populaire.svg";
import logoMobile from "../genericComponents/logos/action-populaire_mini.svg";
import bgDesktop from "../genericComponents/images/login_bg_desktop.svg";
import bgMobile from "../genericComponents/images/login_bg_mobile.svg";
import facebookImg from "../genericComponents/images/facebook_circle.svg";
import arrowRight from "../genericComponents/images/arrow-right.svg";
import chevronDown from "../genericComponents/images/chevron-down.svg";

import styled from "styled-components";
import style from "@agir/front/genericComponents/_variables.scss";

const LeftBlock = styled.div`
  width: 40%;
  height: 100vh;
  background-color: ${style.secondary100};
  position: relative;
  @media (max-width: ${style.collapse}px) {
    display: none;
  }
`;

const MainBlock = styled.div`
  width: 60%;
  height: 100vh;
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;

  h1 {
    margin: 0px;
    font-weight: 700;
    font-size: 40px;
  }

  .mobile-only {
    display: none;
  }

  .button-facebook {
    max-width: 100%;
    width: 400px;
    justify-content: center;
    font-weight: normal;
    background-color: white;
    border: 1px solid #c4c4c4;
  }

  @media (max-width: ${style.collapse}px) {
    width: 100%;
    display: block;
    text-align: center;

    h1 {
      font-size: 28px;
    }

    .mobile-only {
      display: block;
    }

    .mobile-center {
      text-align: center;
    }
  }
`;

// const FacebookButton = styled.Button`
//   &:hover{
//     background-color: #eee;
//   }
// `;

const InlineBlock = styled.span`
  display: inline-block;
  text-align: left;
`;

//const mockMails = ["mgoaziou@gmail.com", "test@franceinsoumise.org"];
const mockMails = ["mgoaziou@gmail.com"];

const Login = () => {
  return (
    <>

        <TextField
          error=""
          id="field"
          label="Adresse e-mail"
          placeholder="Adresse e-mail"
          onChange={() => {}}
          value=""
        />

      <Button
        color="primary"
        style={{
          marginTop: "0.5rem",
          maxWidth: "100%",
          width: "400px",
          justifyContent: "center",
        }}
      >
        Me connecter
      </Button>
    </>
  );
};

const FacebookLogin = () => {
  return (
    <Button className="button-facebook">

        Connexion avec Facebook
    </Button>
  );
};

const ToastNotConnected = () => {
  return (

      Vous devez vous connecter pour accéder à cette page

  );
};

const Connexion = () => {
  const [existantMails, setExistantMails] = useState(mockMails);
  const [showMore, setShowMore] = useState(false);

  const handleShowMore = () => {
    setShowMore(true);
  };

  return (
    <>

        <LeftBlock>

              <InlineBlock
                style={{
                  maxWidth: "350px",
                  lineHeight: "21px",
                  textAlign: "left",
                }}
              >
                Le réseau social d’action pour la candidature de Jean-Luc
                Mélenchon <InlineBlock>pour 2022</InlineBlock>
              </InlineBlock>

          {/*  */}

          <div
            style={{
              position: "absolute",
              bottom: "0px",
              left: "0px",
              width: "100%",
              height: "450px",
              backgroundImage: `url(${bgDesktop})`,
              backgroundSize: "cover",
              backgroundRepeat: "no-repeat",
            }}
          >

        </LeftBlock>

        <MainBlock>
          <InlineBlock
            style={{
              width: "400px",
              maxWidth: "100%",
              paddingLeft: "32px",
              paddingRight: "32px",
            }}
          >

Je me connecte

            <InlineBlock style={{ marginTop: "8px" }}>
              Pas encore de compte ?

                Je m'inscris

            </InlineBlock>

            <ToastNotConnected />

            {/* EXISTANT MAILS */}
            {existantMails.length > 0 && (

                À mon compte :

                {existantMails.map((mail, id) => (
                  <Button
                    key={id}
                    color="primary"
                    style={{
                      marginTop: "0.5rem",
                      marginLeft: "0px",
                      maxWidth: "100%",
                      width: "400px",
                      justifyContent: "space-between",
                    }}
                  >
                    {mail}

                  </Button>
                ))}

            )}

            {!showMore && (
              <InlineBlock
                onClick={handleShowMore}
                style={{
                  fontWeight: "700",
                  color: style.primary500,
                  marginTop: "21px",
                  cursor: "pointer",
                }}
              >
                Afficher tout
              </InlineBlock>
            )}

            {showMore && (

                OU

            )}

            {(showMore || !(existantMails.length > 0)) && (
              <>
                <Login />

                  OU

                <FacebookLogin />
              </>
            )}

            {showMore && (

                Pas encore de compte ?

                <InlineBlock
                  style={{ fontWeight: "700", color: style.primary500 }}
                >
                  Rejoignez Action Populaire
                </InlineBlock>

            )}
          </InlineBlock>

          <div
            className="mobile-only"
            style={{
              width: "100%",
              height: "150px",
              backgroundImage: `url(${bgMobile})`,
              backgroundSize: "cover",
              backgroundRepeat: "no-repeat",
            }}
          >

        </MainBlock>

    </>
  );
};

export default Connexion;
<|endoftext|>


<commit_before>/*
# jquery.imuplo.js v0.7.15
# HTML5 file uploader plugin for jQuery - released under MIT License
# Author: Alexandr Kabanov <alex.k.isdg@gmail.com>
# http://github.com/buffk/imuplo.js
# Copyright (c) 2015 Alexandr Kabanov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# o use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
*/

(function ( $ ) {
	$.fn.Imuplo = function ( opt ) {
		if (typeof(opt) !== 'object') opt = {};
		var $options = $.extend( {}, $.fn.Imuplo.defaults, opt ),
			$files,
			$fileObj = {},
			$elCounter = 0,
			$error = '',
			$locked = false,
			$publicStatus = 'Image is not selected';

		$.each( ['onChange','onReadyForUpload','onError'], function( i, e ) {
			if ( typeof( $options[e] ) !== 'function' ) $options[e] = function () {};
		});

		$(this).each(function ( ) {
			var $this = $(this);
			if ( $this.data( 'Imuplo' ) ) return;
			$elCounter ++;
			$this.data( 'Imuplo', $elCounter );
			$this.click(function ( ) {
				if ( $locked ) return;
				var $parentContainer = $this.parent(  ),
					fileInputID = 'imuplo-input-file' + $elCounter;
				if ( isElExist( fileInputID ) ) {
					$( '#' + fileInputID ).remove();
				}
					$parentContainer.append( '<input type="file" id="' + fileInputID + '" accept="' + $options.acceptFileTypes + '" multiple="' + $options.multiple + '" style="display: none;" />' );

					$( '#' + fileInputID ).click ( );

					$( '#' + fileInputID ).bind({
						change: function( ) {
							if ( $options.multiple && false) // FIX: not multiple at this version
								$files = this.files;
							else
								$files = this.files[0];

							if ( isValidFiles ( $files ) ) {
								$publicStatus = $files.name + ' selected for upload';
								$options.onChange.call( $this, $publicStatus );
								if ( window.File && window.FileReader && window.FileList && window.Blob ) {
									getFileData( $files, $parentContainer ); // load $fileObj
									$parentContainer.bind( 'dataReady', function () {
										$parentContainer.unbind( 'dataReady' );
										if ( $options.previewContainerID !== false ) {
											showImage( $options.previewContainerID, $fileObj.src );
										}
										$options.onReadyForUpload.call( this, $fileObj );
									});
								} else {
									$error = 'The File APIs are not supported in your browser';
									$options.onError.call( $this, $error );
									$options.onReadyForUpload.call( $this, {
										size: $files.size,
										name: $files.name,
										type: $files.type,
										src: null,
										width: null,
										height: null,
										blob: $files
									} );
								}
							} else {
								$publicStatus = 'Image is not selected';
								$options.onError.call( $this, $error );
							}
							$( '#' + fileInputID ).remove();
						}
					});
			});
		});

		// internal functions
		// - - - - - - - - - -
		function isElExist( id ) {
			var el =  document.getElementById( id );
			if ( typeof(el) != 'undefined' && el != null ) {
				return true;
			}
			return false;
		}

		function getFileData( f, el ) {
			var reader = new FileReader( );
			reader.onload = function( event ) {
				var img = new Image;
				img.src = event.target.result;
				img.onload = function( ) {
					var fileObj = {
							size: f.size,
							name: f.name,
							type: f.type,
							src: img.src,
							width: img.width,
							height: img.height,
							blob: f
						}
					$fileObj = fileObj;
					el.trigger( 'dataReady' );
				}
			}
			reader.readAsDataURL( f );
		}

		function showImage( c, src ) {
			if ( isElExist( c ) ) {
				$( '#' + c ).html('');
				$( '#' + c + '-img' ).ready( function() {
					$( '#' + c + '-img' ).css( 'max-width', $( '#' + c ).css('width') );
					$( '#' + c + '-img' ).css( 'max-height', $( '#' + c ).css('height') );
				});
				$( '#' + c ).show();
			}
		}

		function isValidFiles( f ) {
			if ( $options.maxFileSize > 0 )
				if ( f.size > $options.maxFileSize ) {
					$error = 'File too big';
					return false;
				}
			var ftypes = $options.acceptFileTypes,
				ftype = f.type,
				imageTypeRX = /^image\//;
			if ( ftypes.indexOf(ftype) === -1 || !imageTypeRX.test( ftype ) ) {
				$error = 'Wrong type of file';
				return false;
			}
			return true;
		}
		// - - - - - - - - - -
	}

	$.fn.Imuplo.defaults = {

		acceptFileTypes: 'image/jpeg,image/png',
		maxFileSize: 0,
		multiple: false,
		previewContainerID: false,
		resize: false,
		resizeMethod: 'crop',
		maxImageSize: [480, 480],
		minImageSize: [120, 120],

		onChange: function () {},
		onReadyForUpload: function () {},
		onError: function () {}

	};
})( jQuery );
<commit_msg>update 0.07.15.02<commit_after>/*
# jquery.imuplo.js v0.7.15.02
# HTML5 file uploader plugin for jQuery - released under MIT License
# Author: Alexandr Kabanov <alex.k.isdg@gmail.com>
# http://github.com/buffk/imuplo.js
# Copyright (c) 2015 Alexandr Kabanov
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# o use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
*/

(function ( $ ) {
	$.fn.Imuplo = function ( opt ) {
		if (typeof(opt) !== 'object') opt = {};
		var $options = $.extend( {}, $.fn.Imuplo.defaults, opt ),
			$files,
			$fileObj = {},
			$elCounter = 0,
			$error = '',
			$locked = false,
			$publicStatus = 'Image is not selected';

		$.each( ['onChange','onReadyForUpload','onError'], function( i, e ) {
			if ( typeof( $options[e] ) !== 'function' ) $options[e] = function () {};
		});

		$(this).each(function ( ) {
			var $this = $(this);
			if ( $this.data( 'Imuplo' ) ) return;
			$elCounter ++;
			$this.data( 'Imuplo', $elCounter );
			$this.click(function ( ) {
				if ( $locked ) return;
				var $parentContainer = $this.parent(  ),
					fileInputID = 'imuplo-input-file' + $elCounter;
				if ( isElExist( fileInputID ) ) {
					$( '#' + fileInputID ).remove();
				}
					$parentContainer.append( '<input type="file" id="' + fileInputID + '" accept="' + $options.acceptFileTypes + '" multiple="' + $options.multiple + '" style="display: none;" />' );

					$( '#' + fileInputID ).click ( );

					$( '#' + fileInputID ).bind({
						change: function( ) {
							if ( $options.multiple && false) // FIX: not multiple at this version
								$files = this.files;
							else
								$files = this.files[0];

							if ( isValidFiles ( $files ) ) {
								$publicStatus = $files.name + ' selected for upload';
								$options.onChange.call( $this, $publicStatus );
								if ( window.File && window.FileReader && window.FileList && window.Blob ) {
									getFileData( $files, $parentContainer ); // load $fileObj
									$parentContainer.bind( 'dataReady', function ( ) {
										$parentContainer.unbind( 'dataReady' );
										if ( !isValidImage( [$fileObj.width, $fileObj.height] ) ) {
											killAll( $elCounter, $options.previewContainerID );
											$options.onError.call( this, $error );
											return;
										}
										if ( $options.resize && $options.resizeMethod !== false ) {
											var newImg;
											if ( newImg = imageResize( $fileObj, $options.resizeMethod, $parentContainer ) ) {
												$fileObj = newImg; // Does it need a new img obj?
											} else {
												$options.onError.call( this, $error );
											}
										}
										if ( $options.previewContainerID !== false ) {
											showImage( $options.previewContainerID, $fileObj.src );
										}
										$options.onReadyForUpload.call( this, $fileObj );
									});
								} else {
									$error = 'The File APIs are not supported in your browser';
									$options.onError.call( $this, $error );
									$options.onReadyForUpload.call( $this, {
										size: $files.size,
										name: $files.name,
										type: $files.type,
										src: null,
										width: null,
										height: null,
										blob: $files
									} );
								}
							} else {
								$publicStatus = 'Image is not selected';
								$options.onError.call( $this, $error );
							}
							$( '#' + fileInputID ).remove();
						}
					});
			});
		});

		// internal functions
		// - - - - - - - - - -
		function isElExist( id ) {
			var el =  document.getElementById( id );
			if ( typeof(el) != 'undefined' && el != null ) {
				return true;
			}
			return false;
		}

		function imageResize ( o, method, wrapper ) {
			var ob = {},
				wrapperId = wrapper.attr( 'id' ),
				w = o.width,
				h = o.height,
				sx = ( $options.scaleTo[0] ),
				sy = ( $options.scaleTo[1] ),
				aspectRX = 1,
				aspectRY = 1,
				nw = w,
				nh = h,
				centreX = 0,
				centreY = 0;
				if ( !sx || !sy ) {
					$error = 'Option "scaleTo" is undefined';
					return false;
				}

			if ( wrapperId == undefined ) {
				wrapperId = 'imuplo-tc-wrapper';
				wrapper.attr( 'id', wrapperId );
			} else {
				if ( wrapperId.length() < 1 ) {
					wrapperId = 'imuplo-tc-wrapper';
					wrapper.attr( 'id', wrapperId );
				}
			}
			switch (method) {
				case 'standart':
					aspectRX = w/sx;
					aspectRY = h/sy;
					if ( w >= h ) {
						nw = (sx*aspectRY) | 0;
						if (nw > w) nw = w;
						nh = h;
						centreX = (w/2 - nw/2) | 0;
						centreY = 0;
					} else {
						nw = w;
						nh = (sy*aspectRX) | 0;
						if (nh > h) nh = h;
						centreX = 0;
						centreY = (h/2 - nh/2) | 0;
					}
					wrapper.append('<canvas id="imuplo-tmp-canvas" style="display: none;"></canvas>');
					canv = document.getElementById('imuplo-tmp-canvas');
					canv.width = sx;
					canv.height = sy;
					canv.getContext('2d').drawImage( o.imobj, centreX, centreY, nw, nh, 0, 0, sx, sy);
					ob.src = canv.toDataURL( o.type, 0.8 );
					ob.width = sx;
					ob.height = sy;
					ob.blob = dataURItoBlob( ob.src );
					$( '#imuplo-tmp-canvas' ).remove();
				break;
				case 'Jcrop':
					// insert Jcrop plugin fty
				break;
				default:
					$error = 'Unknown resize method';
					return false;
			}

			return $.extend( o, ob );
		}

		function getFileData( f, el ) {
			var reader = new FileReader( );
			reader.onload = function( event ) {
				var img = new Image;
				img.src = event.target.result;
				img.onload = function( ) {
					var fileObj = {
							size: f.size,
							name: f.name,
							type: f.type,
							src: img.src,
							width: img.width,
							height: img.height,
							blob: dataURItoBlob( img.src ),
							imobj: img
						}
					$fileObj = fileObj;
					el.trigger( 'dataReady' );
				}
			}
			reader.readAsDataURL( f );
		}

		function dataURItoBlob( dataURI ) {
			var byteString;
			if ( dataURI.split(',')[0].indexOf('base64') >= 0 )
				byteString = atob( dataURI.split(',')[1] );
			else
			byteString = unescape( dataURI.split(',')[1] );
			var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
			var ia = new Uint8Array( byteString.length );
			for ( var i = 0; i < byteString.length; i++ ) {
				ia[i] = byteString.charCodeAt(i);
			}
			return new Blob([ia], {type:mimeString});
		}

		function showImage( c, src ) {
			if ( isElExist( c ) ) {
				$( '#' + c ).html('');
				$( '#' + c + '-img' ).ready( function() {
					$( '#' + c + '-img' ).css( 'max-width', $( '#' + c ).css('width') );
					$( '#' + c + '-img' ).css( 'max-height', $( '#' + c ).css('height') );
				});
				$( '#' + c ).show();
			}
		}

		function isValidFiles( f ) {
			if ( $options.maxFileSize > 0 )
				if ( f.size > $options.maxFileSize ) {
					$error = 'File too big';
					return false;
				}
			var ftypes = $options.acceptFileTypes,
				ftype = f.type,
				imageTypeRX = /^image\//;
			if ( ftypes.indexOf(ftype) === -1 || !imageTypeRX.test( ftype ) ) {
				$error = 'Wrong type of file';
				return false;
			}
			return true;
		}

		function isValidImage( img ) {
			if ( ($options.minImageSize[0] && img[0] < $options.minImageSize[0]) || ($options.minImageSize[1] && img[1] < $options.minImageSize[1]) ) {
				$error = 'Image too small';
				return false;
			}
			if ( ($options.maxImageSize[0] && img[0] > $options.maxImageSize[0]) || ($options.maxImageSize[1] && img[1] > $options.maxImageSize[1]) ) {
				$error = 'Image too big';
				return false;
			}
			return true;
		}

		function killAll( i, c ) {
			$fileObj = {};
			$publicStatus = 'Image is not selected';
			if ( isElExist( c + '-img' ) ) {
				$( '#' + c + '-img' ).remove();
				$( '#' + c ).hide();
			}
			if ( isElExist( 'imuplo-tmp-canvas' ) ) {
				$( '#imuplo-tmp-canvas' ).remove();
			}
			$options.onChange.call( this, $publicStatus );
		}
		// - - - - - - - - - -
	}

	$.fn.Imuplo.defaults = {

		acceptFileTypes: 'image/jpeg,image/png',
		maxFileSize: 0,
		multiple: false, // not supported
		previewContainerID: false,
		resize: false,
		resizeMethod: 'standart', // + Jcrop - next version
		maxImageSize: [],
		minImageSize: [],
		scaleTo: [],

		onChange: function () {},
		onReadyForUpload: function () {},
		onError: function () {}

	};
})( jQuery );
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(FILL_ME_IN);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(FILL_ME_IN);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = FILL_ME_IN;    /* try chaining range() and reduce() */

    expect(233168).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<commit_msg>37/38<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(0);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = 233168;    /* try chaining range() and reduce() */

    expect(233168).toBe(233168);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<|endoftext|>


<commit_before>"use strict";

let moment = require("moment");
let mongoose = require("mongoose");
let util = require("util");

let BetSchema = new mongoose.Schema({
  account: String,
  nick: String,
  season: Number,
  round: Number,
  points: Number,
  maximum: Boolean,
  bets: [{
    _id: false,
    firstName: String,
    lastName: String,
    code: String,
    points: Number,
  }],
  created: {
    type: Date,
    default: Date.now,
  },
});

BetSchema.statics.isBetWindowOpen = function() {
  return this.db.model("event").findNext("qualifying").then(event => {
    if (event) {
      let min = moment(event.start).startOf("isoweek");
      if (min.isBefore()) {
        return Promise.resolve(event.start);
      } else {
        let date = min.format("MMMM D, HH:mm UTC");
        let message = util.format("Bets will be allowed after %s, until qualifying!", date);
        throw new Error(message);
      }
    } else {
      throw new Error("Bets are not allowed");
    }
  });
};

BetSchema.statics.activeBetRound = function() {
  let max_date = moment().utc().isoWeekday(7).hour(23).minute(59).toDate();
  let season = max_date.getFullYear();
  return this.db.model("event").findOne({season: season, start: {$lte: max_date}}).sort("-start")
    .then(event => {
      if (event) {
        return event;
      } else {
        throw new Error("No active round found");
      }
    });
};

BetSchema.statics.userBets = function(nick, round) {
  return this.findOne({nick: nick, round: round, season: (new Date).getFullYear()});
};

BetSchema.statics.setUserBets = function(account, round, names) {
  return this.db.model("season").driversForNames(names).then(drivers => {
    drivers.forEach((driver, i) => {
      if (drivers.indexOf(driver) < i) {
        throw new Error(util.format("Duplicate driver '%s'", driver.code));
      }
    });

    let query = {
      account: account.account,
      season: (new Date).getFullYear(),
      round: round,
    };
    let values = {
      nick: account.nick,
      account: account.account,
      season: query.season,
      round: query.round,
      bets: drivers,
      created: new Date,
    };
    return this
      .update(query, values, {upsert: true})
      .then(status => drivers);
  });
};

BetSchema.statics.latestRound = function(season) {
  let query = {points: {$exists: true}};

  if (season) {
    query.season = season;
  }

  return this.findOne(query)
    .sort({season: -1, round: -1})
    .then(bet => bet || Promise.reject(new Error("No points data")))
    .then(bet => ({season: bet.season, round: bet.round}));
};

BetSchema.statics.pointsForRound = function(round) {
  if (round == "last") {
    round = 0;
  }
  return Promise.resolve(round == 0 ? this.latestRound() : {round: round, season: (new Date).getFullYear()})
    .then(entry => this.find({round: entry.round, season: entry.season, points: {$exists: true}}).sort("-points"))
    .then(bets => {
      if (!bets.length) {
        throw new Error(util.format("No results for round %d", round));
      }

      return this.model("event").findOne({type: "race", season: bets[0].season, round: bets[0].round}).then(event => ({
        season: event.season,
        round: event.round,
        name: event.name,
        bets: bets
      }));
    });
};

BetSchema.statics.pointsForSeason = function(season) {
  return this.latestRound(season)
    .then(entry => this.model("event").findOne({type: "race", season: entry.season, round: entry.round}))
    .then(event => new Promise((resolve, reject) => {
      let query = [
        {$match: {season: event.season, points: {$exists: true}}},
        {$group: {_id: "$nick", points: {$sum: "$points"}, nick: {$first: "$nick"}}},
        {$sort: {points: -1}}
      ];
      this.aggregate(query, (error, result) => {
        if (error) {
          throw error;
        }
        resolve({
          season: event.season,
          round: event.round,
          name: event.name,
          bets: result
        });
      })
    }));
}

class PointsCalculator {
  constructor(results) {
    this.results = results;
    this.scoring = [10, 5, 3, 1];
    this.bonus = 5;
  }

  process(bet) {
    return new Promise((resolve, reject) => {
      bet.points = this.scores(bet);
      resolve(bet);
    });
  }

  scores(bet) {
    let points = [...bet.bets].reduce((value, driver, i) => {
      if (driver.code == this.results[i].code) {
        driver.points = this.scoring[i];
        return value + driver.points;
      } else if (this.driverOnPodium(driver)) {
        driver.points = this.scoring[3];
        return value + driver.points;
      } else {
        driver.points = 0;
      }
      return value;
    }, 0);

    let max = this.scoring.slice(0, 3).reduce((sum, x) => sum + x, 0);

    if (points == max) {
      bet.maximum = true;
      points += this.bonus;
    } else {
      bet.maximum = false;
    }

    return points;
  }

  driverOnPodium(driver) {
    return this.results.slice(0, 3).map(d => d.code).indexOf(driver.code) != -1;
  }
}
exports.configure = services => {
  let database = services.get("database");
  let whois = services.get("whois");
  let commands = services.get("command.manager");
  let events = services.get("event.manager");
  let Bet = database.model("bet", BetSchema);
  let Event = database.model("event");
  let connection = services.get("connection");

  commands.add("bet", command => {
    let names = command.params;
    if (names.length == 0) {
      return Bet.userBets(command.nick, this.activeEvent.round).then(doc => {
        if (doc) {
          let names = doc.bets.map((d, i) => util.format("%d. %s %s", i+1, d.firstName, d.lastName));
          return util.format("%s: %s", command.nick, names.join(" "));
        } else {
          return Promise.resolve(util.format("%s: You have no bets for this round", command.nick));
        }
      });
    } else {
      return whois.auth(command.nick)
        .then(account => Bet.setUserBets(account, this.activeEvent.round, names))
        .then(drivers => {
          let names = drivers.map((d, i) => util.format("%d. %s %s", i+1, d.firstName, d.lastName));
          return util.format("%s: %s [OK]", command.nick, names.join(" "));
        });
    }
  })
  .validate(() => Bet.isBetWindowOpen())
  .validate((nick, ...names) => {
    if (names.length != 0 && names.length != 3) {
      return Promise.reject("Need three names to bet");
    }
  })
  .validate(() => {
    return Bet.activeBetRound().then(event => {
      // console.log("GOT EVENT", event);
      this.activeEvent = event;
    });
  });

  commands.add("top", command => {
    let round = command.params[0];
    if (round) {
      return Bet.pointsForRound(round).then(result => {
        let points = result.bets.map(bet => util.format("%s %d", bet.nick, bet.points));
        let message = util.format("Score for %s: %s", result.name, points.join("; "));
        return {type: "notice", content: message};
      });
    } else {
      return Bet.pointsForSeason().then(result => {
        let points = result.bets.map(bet => util.format("%s %d", bet.nick, bet.points));
        let message = util.format("Points after %s: %s", result.name, points.join("; "));
        return {type: "notice", content: message};
      });
    }
  });

  events.on("racecalendar.results", event => {
    let query = {season: event.event.season, round: event.event.round};
    let results = event.event.results;

    Bet.find(query)
      .then(bets => Promise.all(bets.map(bet => (new PointsCalculator(results)).process(bet))))
      .then(bets => Promise.all(bets.map(bet => bet.save())))
      .then(bets => {
        if (bets.length) {
          let winners = bets.sort((a, b) => b.points - a.points).filter((bet, i, bets) => {
            return i == 0 || bet.points == bets[0].points;
          });
          connection.amsg(util.format("Dudes! Bet scores are updated for the %s", event.event.name));
          connection.amsg(util.format("The highest score in this round was %d by %s", winners[0].points, winners.join(", ")));
        }
      })
      .then(() => console.log("Updated scores for round", event.event.round));
  });
};
<commit_msg>Rename lambda parameter to avoid confusion<commit_after>"use strict";

let moment = require("moment");
let mongoose = require("mongoose");
let util = require("util");

let BetSchema = new mongoose.Schema({
  account: String,
  nick: String,
  season: Number,
  round: Number,
  points: Number,
  maximum: Boolean,
  bets: [{
    _id: false,
    firstName: String,
    lastName: String,
    code: String,
    points: Number,
  }],
  created: {
    type: Date,
    default: Date.now,
  },
});

BetSchema.statics.isBetWindowOpen = function() {
  return this.db.model("event").findNext("qualifying").then(event => {
    if (event) {
      let min = moment(event.start).startOf("isoweek");
      if (min.isBefore()) {
        return Promise.resolve(event.start);
      } else {
        let date = min.format("MMMM D, HH:mm UTC");
        let message = util.format("Bets will be allowed after %s, until qualifying!", date);
        throw new Error(message);
      }
    } else {
      throw new Error("Bets are not allowed");
    }
  });
};

BetSchema.statics.activeBetRound = function() {
  let max_date = moment().utc().isoWeekday(7).hour(23).minute(59).toDate();
  let season = max_date.getFullYear();
  return this.db.model("event").findOne({season: season, start: {$lte: max_date}}).sort("-start")
    .then(event => {
      if (event) {
        return event;
      } else {
        throw new Error("No active round found");
      }
    });
};

BetSchema.statics.userBets = function(nick, round) {
  return this.findOne({nick: nick, round: round, season: (new Date).getFullYear()});
};

BetSchema.statics.setUserBets = function(account, round, names) {
  return this.db.model("season").driversForNames(names).then(drivers => {
    drivers.forEach((driver, i) => {
      if (drivers.indexOf(driver) < i) {
        throw new Error(util.format("Duplicate driver '%s'", driver.code));
      }
    });

    let query = {
      account: account.account,
      season: (new Date).getFullYear(),
      round: round,
    };
    let values = {
      nick: account.nick,
      account: account.account,
      season: query.season,
      round: query.round,
      bets: drivers,
      created: new Date,
    };
    return this
      .update(query, values, {upsert: true})
      .then(status => drivers);
  });
};

BetSchema.statics.latestRound = function(season) {
  let query = {points: {$exists: true}};

  if (season) {
    query.season = season;
  }

  return this.findOne(query)
    .sort({season: -1, round: -1})
    .then(bet => bet || Promise.reject(new Error("No points data")))
    .then(bet => ({season: bet.season, round: bet.round}));
};

BetSchema.statics.pointsForRound = function(round) {
  if (round == "last") {
    round = 0;
  }
  return Promise.resolve(round == 0 ? this.latestRound() : {round: round, season: (new Date).getFullYear()})
    .then(entry => this.find({round: entry.round, season: entry.season, points: {$exists: true}}).sort("-points"))
    .then(bets => {
      if (!bets.length) {
        throw new Error(util.format("No results for round %d", round));
      }

      return this.model("event").findOne({type: "race", season: bets[0].season, round: bets[0].round}).then(event => ({
        season: event.season,
        round: event.round,
        name: event.name,
        bets: bets
      }));
    });
};

BetSchema.statics.pointsForSeason = function(season) {
  return this.latestRound(season)
    .then(entry => this.model("event").findOne({type: "race", season: entry.season, round: entry.round}))
    .then(event => new Promise((resolve, reject) => {
      let query = [
        {$match: {season: event.season, points: {$exists: true}}},
        {$group: {_id: "$nick", points: {$sum: "$points"}, nick: {$first: "$nick"}}},
        {$sort: {points: -1}}
      ];
      this.aggregate(query, (error, result) => {
        if (error) {
          throw error;
        }
        resolve({
          season: event.season,
          round: event.round,
          name: event.name,
          bets: result
        });
      })
    }));
}

class PointsCalculator {
  constructor(results) {
    this.results = results;
    this.scoring = [10, 5, 3, 1];
    this.bonus = 5;
  }

  process(bet) {
    return new Promise((resolve, reject) => {
      bet.points = this.scores(bet);
      resolve(bet);
    });
  }

  scores(bet) {
    let points = [...bet.bets].reduce((value, driver, i) => {
      if (driver.code == this.results[i].code) {
        driver.points = this.scoring[i];
        return value + driver.points;
      } else if (this.driverOnPodium(driver)) {
        driver.points = this.scoring[3];
        return value + driver.points;
      } else {
        driver.points = 0;
      }
      return value;
    }, 0);

    let max = this.scoring.slice(0, 3).reduce((sum, x) => sum + x, 0);

    if (points == max) {
      bet.maximum = true;
      points += this.bonus;
    } else {
      bet.maximum = false;
    }

    return points;
  }

  driverOnPodium(driver) {
    return this.results.slice(0, 3).map(d => d.code).indexOf(driver.code) != -1;
  }
}
exports.configure = services => {
  let database = services.get("database");
  let whois = services.get("whois");
  let commands = services.get("command.manager");
  let events = services.get("event.manager");
  let Bet = database.model("bet", BetSchema);
  let Event = database.model("event");
  let connection = services.get("connection");

  commands.add("bet", command => {
    let names = command.params;
    if (names.length == 0) {
      return Bet.userBets(command.nick, this.activeEvent.round).then(doc => {
        if (doc) {
          let names = doc.bets.map((d, i) => util.format("%d. %s %s", i+1, d.firstName, d.lastName));
          return util.format("%s: %s", command.nick, names.join(" "));
        } else {
          return Promise.resolve(util.format("%s: You have no bets for this round", command.nick));
        }
      });
    } else {
      return whois.auth(command.nick)
        .then(account => Bet.setUserBets(account, this.activeEvent.round, names))
        .then(drivers => {
          let names = drivers.map((d, i) => util.format("%d. %s %s", i+1, d.firstName, d.lastName));
          return util.format("%s: %s [OK]", command.nick, names.join(" "));
        });
    }
  })
  .validate(() => Bet.isBetWindowOpen())
  .validate((nick, ...names) => {
    if (names.length != 0 && names.length != 3) {
      return Promise.reject("Need three names to bet");
    }
  })
  .validate(() => {
    return Bet.activeBetRound().then(event => {
      // console.log("GOT EVENT", event);
      this.activeEvent = event;
    });
  });

  commands.add("top", command => {
    let round = command.params[0];
    if (round) {
      return Bet.pointsForRound(round).then(result => {
        let points = result.bets.map(bet => util.format("%s %d", bet.nick, bet.points));
        let message = util.format("Score for %s: %s", result.name, points.join("; "));
        return {type: "notice", content: message};
      });
    } else {
      return Bet.pointsForSeason().then(result => {
        let points = result.bets.map(bet => util.format("%s %d", bet.nick, bet.points));
        let message = util.format("Points after %s: %s", result.name, points.join("; "));
        return {type: "notice", content: message};
      });
    }
  });

  events.on("racecalendar.results", event => {
    let query = {season: event.event.season, round: event.event.round};
    let results = event.event.results;

    Bet.find(query)
      .then(bets => Promise.all(bets.map(bet => (new PointsCalculator(results)).process(bet))))
      .then(bets => Promise.all(bets.map(bet => bet.save())))
      .then(bets => {
        if (bets.length) {
          let winners = bets.sort((a, b) => b.points - a.points).filter((bet, i, temp) => {
            return i == 0 || bet.points == temp[0].points;
          });
          connection.amsg(util.format("Dudes! Bet scores are updated for the %s", event.event.name));
          connection.amsg(util.format("The highest score in this round was %d by %s", winners[0].points, winners.join(", ")));
        }
      })
      .then(() => console.log("Updated scores for round", event.event.round));
  });
};
<|endoftext|>


<commit_before>/**
 * @module Typography
 * @submodule Loading & Displaying
 * @for p5
 * @requires core
 */
define(function (require) {

  'use strict';

  var p5 = require('core');

  require('helpers');

  /**
   * Draws text to the screen. Displays the information specified in the first
   * parameter on the screen in the position specified by the additional
   * parameters. A default font will be used unless a font is set with the
   * textFont() function and a default size will be used unless a font is set
   * with textSize(). Change the color of the text with the fill() function.
   * Change the outline of the text with the stroke() and strokeWeight()
   * functions.
   * The text displays in relation to the textAlign() function, which gives the
   * option to draw to the left, right, and center of the coordinates.
   *
   * The x2 and y2 parameters define a rectangular area to display within and
   * may only be used with string data. When these parameters are specified,
   * they are interpreted based on the current rectMode() setting. Text that
   * does not fit completely within the rectangle specified will not be drawn
   * to the screen.
   *
   * @method text
   * @param {String} str the alphanumeric symbols to be displayed
   * @param {Number} x   x-coordinate of text
   * @param {Number} y   y-coordinate of text
   * @param {Number} x2  by default, the width of the text box,
   *                     see rectMode() for more info
   * @param {Number} y2  by default, the height of the text box,
   *                     see rectMode() for more info
   * @example
   *

   *
   * textSize(32);
   * text("word", 10, 30);
   * fill(0, 102, 153);
   * text("word", 10, 60);
   * fill(0, 102, 153, 51);
   * text("word", 10, 90);
   *
   *

   *

   *
   * s = "The quick brown fox jumped over the lazy dog.";
   * fill(50);
   * text(s, 10, 10, 70, 80); // Text wraps within text box
   *
   *

   */
  p5.prototype.text = function(str, x, y, maxWidth, maxHeight) {
    if (typeof str !== 'string') {
      str=str.toString();
    }
    this._graphics.text.apply(this._graphics, arguments);
  };

  /**
   * Sets the current font that will be drawn with the text() function.
   *
   * @method textFont
   * @param {String} str name of font
   * @example
   *

   *
   * fill(0);
   * textSize(36);
   * textFont("Georgia");
   * text("Georgia", 12, 40);
   * textFont("Helvetica");
   * text("Helvetica", 12, 90);
   *
   *

   */
  p5.prototype.textFont = function(str) {
    this._setProperty('_textFont', str); //pend temp?
    this._applyTextProperties();
  };

  return p5;

});
<commit_msg>Restored text parameter checks.<commit_after>/**
 * @module Typography
 * @submodule Loading & Displaying
 * @for p5
 * @requires core
 */
define(function (require) {

  'use strict';

  var p5 = require('core');

  require('helpers');

  /**
   * Draws text to the screen. Displays the information specified in the first
   * parameter on the screen in the position specified by the additional
   * parameters. A default font will be used unless a font is set with the
   * textFont() function and a default size will be used unless a font is set
   * with textSize(). Change the color of the text with the fill() function.
   * Change the outline of the text with the stroke() and strokeWeight()
   * functions.
   * The text displays in relation to the textAlign() function, which gives the
   * option to draw to the left, right, and center of the coordinates.
   *
   * The x2 and y2 parameters define a rectangular area to display within and
   * may only be used with string data. When these parameters are specified,
   * they are interpreted based on the current rectMode() setting. Text that
   * does not fit completely within the rectangle specified will not be drawn
   * to the screen.
   *
   * @method text
   * @param {String} str the alphanumeric symbols to be displayed
   * @param {Number} x   x-coordinate of text
   * @param {Number} y   y-coordinate of text
   * @param {Number} x2  by default, the width of the text box,
   *                     see rectMode() for more info
   * @param {Number} y2  by default, the height of the text box,
   *                     see rectMode() for more info
   * @example
   *

   *
   * textSize(32);
   * text("word", 10, 30);
   * fill(0, 102, 153);
   * text("word", 10, 60);
   * fill(0, 102, 153, 51);
   * text("word", 10, 90);
   *
   *

   *

   *
   * s = "The quick brown fox jumped over the lazy dog.";
   * fill(50);
   * text(s, 10, 10, 70, 80); // Text wraps within text box
   *
   *

   */
  p5.prototype.text = function(str, x, y, maxWidth, maxHeight) {
    this._validateParameters(
      'text',
      arguments,
      [
        ['String', 'Number', 'Number'],
        ['String', 'Number', 'Number', 'Number', 'Number']
      ]
    );

    if (typeof str !== 'string') {
      str=str.toString();
    }
    this._graphics.text.apply(this._graphics, arguments);
  };

  /**
   * Sets the current font that will be drawn with the text() function.
   *
   * @method textFont
   * @param {String} str name of font
   * @example
   *

   *
   * fill(0);
   * textSize(36);
   * textFont("Georgia");
   * text("Georgia", 12, 40);
   * textFont("Helvetica");
   * text("Helvetica", 12, 90);
   *
   *

   */
  p5.prototype.textFont = function(str) {
    this._setProperty('_textFont', str); //pend temp?
    this._applyTextProperties();
  };

  return p5;

});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      productsICanEat = products.filter(
		for (var i=0 ; i<products.length; i+=1)
           {if (all(products[i].ingredients)!='mushrooms' and !products[i].containsNuts)
				{productsICanEat.push(products[i])}
			}

	  /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(1);
      expect(productsICanEat[0]).toBe(products[2]);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {
	_.reduce(_.range(1000), function(memo, num)
         {
		 if (num % 3 === 0 || num % 5 === 0) {return memo + num;}
		 else return memo;
		 }, 0)
    var sum = _.reduce(_.range(1000), function(memo, num)
         {
		 if (num % 3 === 0 || num % 5 === 0) {return memo + num;}
		 else return memo;
		 }, 0);    /* try chaining range() and reduce() */

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    //var ingredientCount = { "{ingredient name}": 0 };
	var ingredientCount = _.reduce(_.flatten(_.map(products, function(p) {return p.ingredients})), function(memo, item)
        {if (memo[item] > 0) {memo[item] += 1}
         else {
			memo[item] = 1;
			}
		return memo;
		 }, []);

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {   //This is not the most effecient way to do this...but it works.
  var returnLargestPrimeFactor = function(num) {
	var primes = createPrimeList(num);
	var factors = createFactorsList(num);
	for (var i = factors.length; i>0; i--)
		{for (var j = 0; j < primes.length; j++) {if (factors[i]==primes[j]) {return factors[i]}}}
	return 1;
  };
  });

  var createPrimeList = function(top) {
  if (top == 0) {return [];}
  if (top == 1) {return [1];}
  primes = [1, 2]
  for (var i = 3; i<top+1; i++) {
	var prime = true;
	for (var j = 1; j<primes.length; j++) {
		if (i % primes[j] === 0)
		{
		prime = false;
		j = primes.length;
		}
	}
	if (prime) {primes.push(i);}
  }
  return primes;
  }

  var createFactorsList = function(num) {
	var factors = []
	for (var i = 1; i < num+1; i++)
	{
		if (num % i === 0) {factors.push(i);}
	}
	return factors;
  };

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {
  var largestPalindrome = function() {}
  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
});
<commit_msg>finished ApplyingWhatWeHaveLearnedKoans, still need to check some answers<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      productsICanEat = products.filter(
		for (var i=0 ; i<products.length; i+=1)
           {if (all(products[i].ingredients)!='mushrooms' and !products[i].containsNuts)
				{productsICanEat.push(products[i])}
			}

	  /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(1);
      expect(productsICanEat[0]).toBe(products[2]);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {
	_.reduce(_.range(1000), function(memo, num)
         {
		 if (num % 3 === 0 || num % 5 === 0) {return memo + num;}
		 else return memo;
		 }, 0)
    var sum = _.reduce(_.range(1000), function(memo, num)
         {
		 if (num % 3 === 0 || num % 5 === 0) {return memo + num;}
		 else return memo;
		 }, 0);    /* try chaining range() and reduce() */

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    //var ingredientCount = { "{ingredient name}": 0 };
	var ingredientCount = _.reduce(_.flatten(_.map(products, function(p) {return p.ingredients})), function(memo, item)
        {if (memo[item] > 0) {memo[item] += 1}
         else {
			memo[item] = 1;
			}
		return memo;
		 }, []);

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {
  var returnLargestPrimeFactor = function(num) {
	var primes = createPrimeList(num);
	var factors =_.flatten(createFactorsList(num)).sort(function(a,b) {return a - b});
	for (var i = factors.length; i>0; i--)
		{for (var j = 0; j < primes.length; j++) {if (factors[i]==primes[j]) {return factors[i];}}}
	return 1;
  };
  });

  var createPrimeList = function(top) {
    if (top == 0) {return [];}
    if (top == 1) {return [1];}
    primes = [1, 2]
    for (var i = 3; i<top+1; i++) {
      var prime = true;
      for (var j = 1; j<primes.length; j++) {
        if (i % primes[j] === 0)
        {
          prime = false;
          j = primes.length;
        }
    }
  if (prime) {primes.push(i);}
  }
    return primes;
  }

  var createFactorsList = function(num) {
	var factors = [];
	var top = num;
	for (var i = 1; i < top; i++)
	{
		if (num % i === 0) {
		factors.push([i, num/i]);
		top = num/i;
		}
	}
	return factors;
  };

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {
  var largestPalindrome = function()
  {
    for (var i = 999*999; i>=100*100; i--)
    {
      var s = String(i);
      pal = true
      for (var j=0; j < s.length/2; j++)  //first check to see if number is a palindrome
      {
        if (s[j] != s[s.length-j-1])
        {
          pal = false;
        }
      }
      if (pal == true) //if it is a palindrome, need to check to make sure it's the product of 2 three digit numbers
      {
        console.log(i + "is a palindrome");
        factors = createFactorsList(i);
        for (var k = factors.length-1; k >= 0; k--)
          {
            if (factors[k][0] > 99 & factors[k][0] < 999 & factors[k][1] > 99 & factors[k][1] < 999)   //checks to make sure it's a 3 digit number
            {
              return i;  //returns answer of 906609
            }
          }
      }
    }
  };

);

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

var smallBy20 = function()
{
  var u = createPrimeList(20);
  var ans = _.reduce(u, function(memo, num) {return memo*num}, 1);
  return ans; //answer is 9699690
}

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

it("should find the 10001st prime", function () {

var find10001Prime = function() {
  primes = [1, 2]
  var i = 3;
  while (primes.length <= 10001)
  {
    var prime = true;
    for (var j = 1; j<primes.length; j++)
    {
      if (i % primes[j] === 0)
      {
        prime = false;
        j = primes.length;
      }
    }
    if (prime) {primes.push(i);}
    i = i + 1;
  }
  return primes.pop();  //answer is 104743
};
  });
});
<|endoftext|>


<commit_before>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(FILL_ME_IN);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */

      expect(productsICanEat.length).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(FILL_ME_IN);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = FILL_ME_IN;    /* try chaining range() and reduce() */

    expect(233168).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    /* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(FILL_ME_IN);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<commit_msg>Finished fixing AboutApplyingWhatWeHaveLearnt.js<commit_after>var _; //globals

describe("About Applying What We Have Learnt", function() {

  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {

    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {

      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _(products).filter(function(ob) {return (ob.containsNuts === false && _(ob.ingredients).all(function(ingr) {return ingr !== "mushrooms"}))});
      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {

    var sum = 0;
    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {

    var sum = _(_.range(1,1000))
                .chain()
                .filter(function(x) {return x%3===0 || x%5===0})
                .reduce(function(sum,n) {return sum + n})
                .value();    /* try chaining range() and reduce() */

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    ingredientCount = _.chain(products)
      .map(function(ob){return ob.ingredients})
      .flatten()
      .reduce(function(count,ingr) {
        count[ingr] = (count[ingr] || 0) + 1;
        return count;
      },{})
      .value();/* chain() together map(), flatten() and reduce() */

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */
  /*
  it("should find the largest prime factor of a composite number", function () {

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {

  });

  it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  });

  it("should find the difference between the sum of the squares and the square of the sums", function () {

  });

  it("should find the 10001st prime", function () {

  });
  */
});
<|endoftext|>


<commit_before>var expect = require('chai').expect;
var sinon = require('sinon');
var _shareFactory = require('../_share-factory');

describe('_shareFactory', function () {
  beforeEach(function () {
    this.href = sinon.stub().returns('http://example.com');
  });

  it('creates a function', function () {
    var share = _shareFactory(this.href);
    expect(share).to.be.a('function');
  });

  it('sets the href method', function () {
    var share = _shareFactory(this.href);
    expect(share.href).to.equal(this.href);
  });

  describe('created function', function () {
    beforeEach(function () {
      sinon.spy(window, 'open');
    });

    afterEach(function () {
      window.open.restore();
    });

    it('opens a resource returned by the href function', function () {
      _shareFactory(this.href)();
      expect(window.open.called).to.equal(true);
      expect(window.open.args[0][0]).to.equal('http://example.com');
    });

    it('passes the arguments to the href function', function () {
      _shareFactory(this.href)('http://foo.share');
      expect(this.href.args[0]).to.deep.equal(['http://foo.share']);
    });

    it('sets window features', function () {
      _shareFactory(this.href, 640, 480)();
      expect(window.open.args[0][2]).to.contain('location,resizable,scrollbars,toolbar=no');
    });

    it('sets window dimensions', function () {
      _shareFactory(this.href, 640, 480)();
      expect(window.open.args[0][2]).to.contain('width=640');
      expect(window.open.args[0][2]).to.contain('height=480');
    });

    it('centers the window', function () {
      screen.width = 1920;
      screen.height = 1080;

      _shareFactory(this.href, 640, 480)();
      expect(window.open.args[0][2]).to.contain('left=640');
      expect(window.open.args[0][2]).to.contain('top=300');
    });

    it('keeps the window below the top edge of the screen', function () {
      screen.width = 320;
      screen.height = 240;

      _shareFactory(this.href, 640, 480)();
      expect(window.open.args[0][2]).to.contain('top=0');
    });
  });
});
<commit_msg>Popup dimensions shouldn't be tested as they're optional<commit_after>var expect = require('chai').expect;
var sinon = require('sinon');
var _shareFactory = require('../_share-factory');

describe('_shareFactory', function () {
  beforeEach(function () {
    this.href = sinon.stub().returns('http://example.com');
  });

  it('creates a function', function () {
    var share = _shareFactory(this.href, 640, 480);
    expect(share).to.be.a('function');
  });

  it('sets the href method', function () {
    var share = _shareFactory(this.href, 640, 480);
    expect(share.href).to.equal(this.href);
  });

  describe('created function', function () {
    beforeEach(function () {
      sinon.spy(window, 'open');
    });

    afterEach(function () {
      window.open.restore();
    });

    it('opens a resource returned by the href function', function () {
      _shareFactory(this.href, 640, 480)();
      expect(window.open.called).to.equal(true);
      expect(window.open.args[0][0]).to.equal('http://example.com');
    });

    it('passes the arguments to the href function', function () {
      _shareFactory(this.href, 640, 480)('http://foo.share');
      expect(this.href.args[0]).to.deep.equal(['http://foo.share']);
    });

    it('sets window features', function () {
      _shareFactory(this.href, 640, 480)();
      expect(window.open.args[0][2]).to.contain('location,resizable,scrollbars,toolbar=no');
    });

    it('sets window dimensions', function () {
      _shareFactory(this.href, 640, 480)();
      expect(window.open.args[0][2]).to.contain('width=640');
      expect(window.open.args[0][2]).to.contain('height=480');
    });

    it('centers the window', function () {
      screen.width = 1920;
      screen.height = 1080;

      _shareFactory(this.href, 640, 480)();
      expect(window.open.args[0][2]).to.contain('left=640');
      expect(window.open.args[0][2]).to.contain('top=300');
    });

    it('keeps the window below the top edge of the screen', function () {
      screen.width = 320;
      screen.height = 240;

      _shareFactory(this.href, 640, 480)();
      expect(window.open.args[0][2]).to.contain('top=0');
    });
  });
});
<|endoftext|>


<commit_before>var _; // globals

describe("About Applying What We Have Learnt", function() {
  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {
    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {
      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _.filter(products,function(product){
        return !product.containsNuts && _.all(product.ingredients,function(ingredient) {
          return ingredient !== 'mushrooms'
        })
      })

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {
    var sum = 0;

    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {
    var sum = _.chain(1000).range().reduce(function(total,num){
      return (num % 3 === 0 || num % 5 === 0) ? total+num : total;
    },0).value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    var ingredientCount = _.chain(products)
      .map(function(product){
        return product.ingredients;
      })
      .flatten()
      .reduce(function(obj,ingredient) {
        obj[ingredient] = (obj[ingredient] || 0) + 1;
        return obj;
      },{})
      .value();

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {

    var findLargestPrime = function(num) {
      var i = num;

      while(--i) {
        if( num % i === 0 && i % 2 !== 0 ) return i;
      }

    };

    expect(findLargestPrime(485)).toBe(97);
    expect(findLargestPrime(9747)).toBe(3249);

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {
    var numericPalindrome = function() {
      var num = _.chain(arguments)
        .toArray(arguments)
        .reduce(function(total,num) {
          return total * num;
        })
        .value();

      var values = _.chain(num.toString().split(''))
        .map(function(val) {
          return +val;
        })
        .sortBy(function(num) {
          return num;
        })
        .value();

      var doubles = _.chain(values)
        .groupBy(function(num) {
          return num;
        })
        .filter(function(vals) {
          return vals.length % 2 === 0;
        })
        .map(function(arr) {
          return arr[0];
        })
        .sortBy(function(num) {
          return num;
        })
        .reverse()
        .value();

      var largest = _.without.apply(_,[values].concat(doubles))
        .pop().toString();

      var doublesStr = doubles.join('');

      return +(doublesStr + largest + doublesStr);
    }

    expect(numericPalindrome(937, 113)).toBe(81581);
    expect(numericPalindrome(657, 892)).toBe(484);
    expect(numericPalindrome(755, 223)).toBe(686);
  });

  // it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  // });

  // it("should find the difference between the sum of the squares and the square of the sums", function () {

  // });

  // it("should find the 10001st prime", function () {

  // });

});
<commit_msg>add more numericPalindrome tests<commit_after>var _; // globals

describe("About Applying What We Have Learnt", function() {
  var products;

  beforeEach(function () {
    products = [
       { name: "Sonoma", ingredients: ["artichoke", "sundried tomatoes", "mushrooms"], containsNuts: false },
       { name: "Pizza Primavera", ingredients: ["roma", "sundried tomatoes", "goats cheese", "rosemary"], containsNuts: false },
       { name: "South Of The Border", ingredients: ["black beans", "jalapenos", "mushrooms"], containsNuts: false },
       { name: "Blue Moon", ingredients: ["blue cheese", "garlic", "walnuts"], containsNuts: true },
       { name: "Taste Of Athens", ingredients: ["spinach", "kalamata olives", "sesame seeds"], containsNuts: true }
    ];
  });

  /*********************************************************************************/

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (imperative)", function () {
    var i,j,hasMushrooms, productsICanEat = [];

    for (i = 0; i < products.length; i+=1) {
        if (products[i].containsNuts === false) {
            hasMushrooms = false;
            for (j = 0; j < products[i].ingredients.length; j+=1) {
               if (products[i].ingredients[j] === "mushrooms") {
                  hasMushrooms = true;
               }
            }
            if (!hasMushrooms) productsICanEat.push(products[i]);
        }
    }

    expect(productsICanEat.length).toBe(1);
  });

  it("given I'm allergic to nuts and hate mushrooms, it should find a pizza I can eat (functional)", function () {
      var productsICanEat = [];

      /* solve using filter() & all() / any() */
      productsICanEat = _.filter(products,function(product){
        return !product.containsNuts && _.all(product.ingredients,function(ingredient) {
          return ingredient !== 'mushrooms'
        })
      })

      expect(productsICanEat.length).toBe(1);
  });

  /*********************************************************************************/

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (imperative)", function () {
    var sum = 0;

    for(var i=1; i<1000; i+=1) {
      if (i % 3 === 0 || i % 5 === 0) {
        sum += i;
      }
    }

    expect(sum).toBe(233168);
  });

  it("should add all the natural numbers below 1000 that are multiples of 3 or 5 (functional)", function () {
    var sum = _.chain(1000).range().reduce(function(total,num){
      return (num % 3 === 0 || num % 5 === 0) ? total+num : total;
    },0).value();

    expect(233168).toBe(sum);
  });

  /*********************************************************************************/
   it("should count the ingredient occurrence (imperative)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    for (i = 0; i < products.length; i+=1) {
        for (j = 0; j < products[i].ingredients.length; j+=1) {
            ingredientCount[products[i].ingredients[j]] = (ingredientCount[products[i].ingredients[j]] || 0) + 1;
        }
    }

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  it("should count the ingredient occurrence (functional)", function () {
    var ingredientCount = { "{ingredient name}": 0 };

    var ingredientCount = _.chain(products)
      .map(function(product){
        return product.ingredients;
      })
      .flatten()
      .reduce(function(obj,ingredient) {
        obj[ingredient] = (obj[ingredient] || 0) + 1;
        return obj;
      },{})
      .value();

    expect(ingredientCount['mushrooms']).toBe(2);
  });

  /*********************************************************************************/
  /* UNCOMMENT FOR EXTRA CREDIT */

  it("should find the largest prime factor of a composite number", function () {

    var findLargestPrime = function(num) {
      var i = num;

      while(--i) {
        if( num % i === 0 && i % 2 !== 0 ) return i;
      }

    };

    expect(findLargestPrime(485)).toBe(97);
    expect(findLargestPrime(9747)).toBe(3249);

  });

  it("should find the largest palindrome made from the product of two 3 digit numbers", function () {
    var numericPalindrome = function() {
      var num = _.chain(arguments)
        .toArray(arguments)
        .reduce(function(total,num) {
          return total * num;
        })
        .value();

      var values = _.chain(num.toString().split(''))
        .map(function(val) {
          return +val;
        })
        .sortBy(function(num) {
          return num;
        })
        .value();

      var doubles = _.chain(values)
        .groupBy(function(num) {
          return num;
        })
        .filter(function(vals) {
          return vals.length % 2 === 0;
        })
        .map(function(arr) {
          return arr[0];
        })
        .sortBy(function(num) {
          return num;
        })
        .reverse()
        .value();

      var largest = _.without.apply(_,[values].concat(doubles))
        .pop().toString();

      var doublesStr = doubles.join('');

      return +(doublesStr + largest + doublesStr);
    }

    expect(numericPalindrome(937,113)).toBe(81581);
    expect(numericPalindrome(657,892)).toBe(484);
    expect(numericPalindrome(755,223)).toBe(686);
    expect(numericPalindrome(57,62,23)).toBe(82182);
  });

  // it("should find the smallest number divisible by each of the numbers 1 to 20", function () {

  // });

  // it("should find the difference between the sum of the squares and the square of the sums", function () {

  // });

  // it("should find the 10001st prime", function () {

  // });

});
<|endoftext|>