<commit_before>/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
  title: "Gala",
  tagline: "Open tools for sustainability learning",
  url: "https://docs.learngala.com",
  baseUrl: "/",
  onBrokenLinks: "throw",
  onBrokenMarkdownLinks: "warn",
  favicon: "https://msc-gala.imgix.net/favicon_gala.png",
  organizationName: "galahq", // Usually your GitHub org/user name.
  projectName: "gala", // Usually your repo name.

  customFields: {
    fonts: {
      sansSerif: ["Tenso", "system-ui"]
    }
  },
  themeConfig: {
    sidebarCollapsible: false,
    navbar: {
      title: "",
      logo: {
        alt: "Gala",
        src: "img/gala-logo.svg"
      },
      items: [
        {
          to: "/",
          label: "About",
          position: "right"
        },
        {
          to: "docs/",
          activeBasePath: "docs",
          label: "Guides",
          position: "right"
        },
        { to: "blog", label: "Blog", position: "right" },
        {
          to: "/help",
          label: "Help",
          position: "right"
        },
        {
          href: "https://www.learngala.com",
          label: "Go to Gala",
          position: "right"
        }
      ]
    },
    colorMode: {
      disableSwitch: true
    },
    footer: {
      style: "dark",
      links: [
        {
          title: "About",
          items: [
            {
              label: "Publications",
              to: "publications"
            }
          ]
        },
        {
          title: "Guides",
          items: [
            {
              // Label of the link
              label: "Authoring",
              // Client-side routing, used for navigating within the website.
              // The baseUrl will be automatically prepended to this value.
              to: "docs/"
            },
            {
              label: "Teaching",
              to: "docs/teaching-getting-started"
            }
          ]
        },

        /*
        {
          title: 'Policies',
          items: [
            {
              // Label of the link
              label: 'Terms of Use',
              // Client-side routing, used for navigating within the website.
              // The baseUrl will be automatically prepended to this value.
              to: 'policies/#terms-of-use-agreement-for-the-gala-platform',
            },
            {
              label: 'Privacy',
              to: 'policies/#gala-privacy-policy',
            },
            {
              label: 'Copyright',
              to: 'policies/#intellectual-property-rights-policy',
            },
          ],
        }, */
        {
          title: "Community",
          items: [
            {
              label: "Twitter",
              href: "https://twitter.com/LearnMSC"
            },
            {
              label: "Github",
              // A full-page navigation, used for navigating outside of the website.
              href: "https://github.com/galahq/gala"
            }
          ]
        }
      ],
      copyright: "Copyright © 2021 Regents of the University of Michigan",
      logo: {
        src: "img/gala-logo.svg"
      }
    }
  },
  presets: [
    [
      "@docusaurus/preset-classic",
      {
        docs: {
          sidebarPath: require.resolve("./sidebars.js"),
          // Please change this to your repo.
          editUrl: "https://github.com/galahq/gala"
        },
        blog: {
          showReadingTime: false,
          // Please change this to your repo.
          editUrl: "https://github.com/galahq/gala"
        },
        theme: {
          customCss: require.resolve("./src/css/custom.css")
        }
      }
    ]
  ],
  scripts: ["static/js/typekit.js"]
};
<commit_msg>config formatting<commit_after>/** @type {import('@docusaurus/types').DocusaurusConfig} */
module.exports = {
  title: 'Gala',
  tagline: 'Open tools for sustainability learning',
  url: 'https://docs.learngala.com',
  baseUrl: '/',
  onBrokenLinks: 'throw',
  onBrokenMarkdownLinks: 'warn',
  favicon: 'https://msc-gala.imgix.net/favicon_gala.png',
  organizationName: 'galahq', // Usually your GitHub org/user name.
  projectName: 'gala', // Usually your repo name.

  customFields: {
    fonts: {
      sansSerif: ['Tenso', 'system-ui'],
    },
  },
  themeConfig: {
    sidebarCollapsible: false,
    navbar: {
      title: '',
      logo: {
        alt: 'Gala',
        src: 'img/gala-logo.svg',
      },
      items: [
        {
          to: '/',
          label: 'About',
          position: 'right',
        },
        {
          to: 'docs/',
          activeBasePath: 'docs',
          label: 'Guides',
          position: 'right',
        },
        { to: 'blog', label: 'Blog', position: 'right' },
        {
          to: '/help',
          label: 'Help',
          position: 'right',
        },
        {
          href: 'https://www.learngala.com',
          label: 'Go to Gala',
          position: 'right',
        },
      ],
    },
    colorMode: {
      disableSwitch: true,
    },
    footer: {
      style: 'dark',
      links: [
        {
          title: 'About',
          items: [
            {
              label: 'Publications',
              to: 'publications',
            },
          ],
        },
        {
          title: 'Guides',
          items: [
            {
              // Label of the link
              label: 'Authoring',
              // Client-side routing, used for navigating within the website.
              // The baseUrl will be automatically prepended to this value.
              to: 'docs/',
            },
            {
              label: 'Teaching',
              to: 'docs/teaching-getting-started',
            },
          ],
        },

        /*
        {
          title: 'Policies',
          items: [
            {
              // Label of the link
              label: 'Terms of Use',
              // Client-side routing, used for navigating within the website.
              // The baseUrl will be automatically prepended to this value.
              to: 'policies/#terms-of-use-agreement-for-the-gala-platform',
            },
            {
              label: 'Privacy',
              to: 'policies/#gala-privacy-policy',
            },
            {
              label: 'Copyright',
              to: 'policies/#intellectual-property-rights-policy',
            },
          ],
        }, */
        {
          title: 'Community',
          items: [
            {
              label: 'Twitter',
              href: 'https://twitter.com/LearnMSC',
            },
            {
              label: 'Github',
              // A full-page navigation, used for navigating outside of the website.
              href: 'https://github.com/galahq/gala',
            },
          ],
        },
      ],
      copyright: 'Copyright © 2021 Regents of the University of Michigan',
      logo: {
        src: 'img/gala-logo.svg',
      },
    },
  },
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        docs: {
          sidebarPath: require.resolve('./sidebars.js'),
          // Please change this to your repo.
          editUrl: 'https://github.com/galahq/gala',
        },
        blog: {
          showReadingTime: false,
          // Please change this to your repo.
          editUrl: 'https://github.com/galahq/gala',
        },
        theme: {
          customCss: require.resolve('./src/css/custom.css'),
        },
      },
    ],
  ],
  scripts: ['static/js/typekit.js'],
}
<|endoftext|>


<commit_before>/*Declaring Array */
var temp_array = [];
var input_arr = [];
var min_array = [];

function RatsPostions(input1,input2,input3)
	{

		temp_array = input2.split(',');

        /*Creating a 2 dimension array for the temprature*/
        for(var k=0;k<temp_array.length;k++)
        {

            temp_array.push(temp_array[0].split('#'));
            temp_array.shift();

        }

        /*Creating a 2 dimensional array for rat position*/

        input_arr = input1.split(',');

        for(var p=0;p<input_arr.length;p++)  // position array
        {
            input_arr.push(input_arr[0].split('#'));
            input_arr.shift();
        }

       /* console.log(input_arr);*/

        function findMin(pos1,pos2) {

          var  Min;
          var  obj  = [pos1,pos2];
          var count = 0;

            if( pos1-1 >= 0 && pos2 >= 0) {

                Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1-1][pos2]);
                obj[0]=pos1-1;
                obj[1]=pos2;

            }

            if(pos1 >= 0 && pos2+1 < 5) {

              if( Min != undefined ) {

                if(Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2+1]) < Min) {

                    Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2+1]);
                    obj[0]=pos1;
                    obj[1]=pos2+1;

                    }

                } else {

                    Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2+1]);
                    obj[0]=pos1;
                    obj[1]=pos2+1;

                }

            }

            if(pos1+1 < 6 && pos2 >= 0) {

                if(Min != undefined ) {

                if(Math.abs(temp_array[pos1][pos2] - temp_array[pos1+1][pos2]) < Min) {

                    Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1+1][pos2]);

                    obj[0]=pos1+1;
                    obj[1]=pos2;

                    }

                } else {

                    Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1+1][pos2]);
                    obj[0]=pos1+1;
                    obj[1]=pos2;

                }
            }

            if(pos1 >= 0 && pos2-1 >= 0 ) {

                if(Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2-1]) < Min) {

                   Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2-1]);
                   obj[0]=pos1;
                   obj[1]=pos2-1;
                }

            }

            return obj;

        }
            var count2=0;
            for(var x=0;x<input3;x++)
            {
                if(count2 === 0 ) {
                    for(var q=0;q<input_arr.length;q++)
                    {
                        input_arr[q][0] = input_arr[q][0] - 1;
                        input_arr[q][1] = input_arr[q][1] - 1;
                        min_array.push(findMin(input_arr[q][0],input_arr[q][1]));

                    }
                    count2++;
                } else {

                    for(var q=0;q<input_arr.length;q++)
                    {
                        min_array.push(findMin(input_arr[q][0],input_arr[q][1]));

                    }

                }

                input_arr = [];
                input_arr = min_array;
                min_array = []; /*or min_array.length=0*/
                console.log(input_arr);

            }

	}

RatsPostions("1#1,2#5,3#3,6#3","2#6#8#6#-7,2#5#-5#-5#0,-1#3#-8#8#7,3#2#0#6#9,2#1#-4#5#8,-5#6#7#4#7",3);

    <commit_msg>comments added into the code.<commit_after>/*Declaring Array */
var temp_array = [];  /*Array for storing the Temprature Values */
var input_arr = []; /*Array for storing the Rats positions*/
var min_array = []; /*Final Rats Positions*/

function RatsPostions(input1,input2,input3)
{
	temp_array = input2.split(',');

        /*Creating a 2 dimension array for the temprature*/
        for(var k=0;k<temp_array.length;k++)
        {
            temp_array.push(temp_array[0].split('#'));
            temp_array.shift();

        }

        /*Creating a 2 dimensional array for rat positions*/

        input_arr = input1.split(',');

        for(var p=0;p<input_arr.length;p++)  // position array
        {
            input_arr.push(input_arr[0].split('#'));
            input_arr.shift();
        }

       /*Function to find the Minimum Magnitude from the current rat position and that bricks's dimension.*/
        function findMin(pos1,pos2) {

          var  Min;
          var  obj  = [pos1,pos2];
          var count = 0;

            /* Checking Top position from current brick */
            if( pos1-1 >= 0 && pos2 >= 0) {

                Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1-1][pos2]);
                obj[0]=pos1-1;
                obj[1]=pos2;

            }

            /* Checking right position from current brick */
            if(pos1 >= 0 && pos2+1 < 5) {

              if( Min != undefined ) {

                if(Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2+1]) < Min) {

                    Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2+1]);
                    obj[0]=pos1;
                    obj[1]=pos2+1;

                    }

                } else {

                    Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2+1]);
                    obj[0]=pos1;
                    obj[1]=pos2+1;

                }
            }

	    /* Checking Bottom position from current brick */

            if(pos1+1 < 6 && pos2 >= 0) {

                if(Min != undefined ) {

                if(Math.abs(temp_array[pos1][pos2] - temp_array[pos1+1][pos2]) < Min) {

                    Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1+1][pos2]);

                    obj[0]=pos1+1;
                    obj[1]=pos2;

                    }

                } else {

                    Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1+1][pos2]);
                    obj[0]=pos1+1;
                    obj[1]=pos2;

                }
            }

           /* Checking left position from current brick */

            if(pos1 >= 0 && pos2-1 >= 0 ) {

                if(Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2-1]) < Min) {

                   Min = Math.abs(temp_array[pos1][pos2] - temp_array[pos1][pos2-1]);
                   obj[0]=pos1;
                   obj[1]=pos2-1;
                }

            }

            return obj; /*Returning a next position of rat as an array of rats */

        } /*End of findMin function*/

        var count2=0;

        /*No. of iteration need to perform to find the final rat position.*/
        /*Taking input3 for looping constraint which passed as argument when ratsPosition function is called. */
        for(var x=0;x<input3;x++)
            {
                if(count2 === 0 ) {
                    for(var q=0;q<input_arr.length;q++)
                    {
                    	/*Array start from 0th position so we need to change the input */
                        input_arr[q][0] = input_arr[q][0] - 1;
                        input_arr[q][1] = input_arr[q][1] - 1;
                        min_array.push(findMin(input_arr[q][0],input_arr[q][1]));

                    }
                    count2++;
                } else {

                    for(var q=0;q<input_arr.length;q++)
                    {
                        min_array.push(findMin(input_arr[q][0],input_arr[q][1]));

                    }

                }

                input_arr = []; /*flusing the input_array for the next iteration. */
                input_arr = min_array;
                min_array = []; /*or flusing the min_array for the next iteration. */

            }
	}

/*Calling a Function. */
RatsPostions("1#1,2#5,3#3,6#3","2#6#8#6#-7,2#5#-5#-5#0,-1#3#-8#8#7,3#2#0#6#9,2#1#-4#5#8,-5#6#7#4#7",3);

<|endoftext|>


<commit_before>declare interface $npm$mocha$SetupOptions {
  slow?: number;
  timeout?: number;
  ui?: string;
  globals?: Array<any>;
  reporter?: any;
  bail?: boolean;
  ignoreLeaks?: boolean;
  grep?: any;
}

declare type $npm$mocha$done = (error?: any) => any;

// declare interface $npm$mocha$SuiteCallbackContext {
//   timeout(ms: number): void;
//   retries(n: number): void;
//   slow(ms: number): void;
// }

// declare interface $npm$mocha$TestCallbackContext {
//   skip(): void;
//   timeout(ms: number): void;
//   retries(n: number): void;
//   slow(ms: number): void;
//   [index: string]: any;
// }

declare interface $npm$mocha$Suite {
  parent: $npm$mocha$Suite;
  title: string;
  fullTitle(): string;
}

declare interface $npm$mocha$ContextDefinition {
  (
    description: string,
    callback: () => /* this: $npm$mocha$SuiteCallbackContext */ void,
  ): $npm$mocha$Suite;
  only(
    description: string,
    callback: () => /* this: $npm$mocha$SuiteCallbackContext */ void,
  ): $npm$mocha$Suite;
  skip(
    description: string,
    callbac: () => /* this: $npm$mocha$SuiteCallbackContext */ void,
  ): void;
  timeout(ms: number): void;
}

declare interface $npm$mocha$TestDefinition {
  (
    expectation: string,
    callback?: (
      /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done,
    ) => mixed,
  ): $npm$mocha$Test;
  only(
    expectation: string,
    callback?: (
      /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done,
    ) => mixed,
  ): $npm$mocha$Test;
  skip(
    expectation: string,
    callback?: (
      /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done,
    ) => mixed,
  ): void;
  timeout(ms: number): void;
  state: 'failed' | 'passed';
}

declare interface $npm$mocha$Runner {}

declare class $npm$mocha$BaseReporter {
  stats: {
    suites: number,
    tests: number,
    passes: number,
    pending: number,
    failures: number,
    ...
  };

  constructor(runner: $npm$mocha$Runner): $npm$mocha$BaseReporter;
}

declare class $npm$mocha$DocReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$DotReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$HTMLReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$HTMLCovReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$JSONReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$JSONCovReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$JSONStreamReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$LandingReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$ListReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$MarkdownReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$MinReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$NyanReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$ProgressReporter extends $npm$mocha$BaseReporter {
  constructor(
    runner: $npm$mocha$Runner,
    options?: {
      open?: string,
      complete?: string,
      incomplete?: string,
      close?: string,
      ...
    },
  ): $npm$mocha$ProgressReporter;
}
declare class $npm$mocha$SpecReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$TAPReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$XUnitReporter extends $npm$mocha$BaseReporter {
  constructor(
    runner: $npm$mocha$Runner,
    options?: any,
  ): $npm$mocha$XUnitReporter;
}

declare class $npm$mocha$Mocha {
  currentTest: $npm$mocha$TestDefinition;
  constructor(options?: {
    grep?: RegExp,
    ui?: string,
    reporter?: string,
    timeout?: number,
    reporterOptions?: any,
    slow?: number,
    bail?: boolean,
    ...
  }): $npm$mocha$Mocha;
  setup(options: $npm$mocha$SetupOptions): this;
  bail(value?: boolean): this;
  addFile(file: string): this;
  reporter(name: string): this;
  reporter(reporter: (runner: $npm$mocha$Runner, options: any) => any): this;
  ui(value: string): this;
  grep(value: string): this;
  grep(value: RegExp): this;
  invert(): this;
  ignoreLeaks(value: boolean): this;
  checkLeaks(): this;
  throwError(error: Error): void;
  growl(): this;
  globals(value: string): this;
  globals(values: Array<string>): this;
  useColors(value: boolean): this;
  useInlineDiffs(value: boolean): this;
  timeout(value: number): this;
  slow(value: number): this;
  enableTimeouts(value: boolean): this;
  asyncOnly(value: boolean): this;
  noHighlighting(value: boolean): this;
  run(onComplete?: (failures: number) => void): $npm$mocha$Runner;

  static reporters: {
    Doc: $npm$mocha$DocReporter,
    Dot: $npm$mocha$DotReporter,
    HTML: $npm$mocha$HTMLReporter,
    HTMLCov: $npm$mocha$HTMLCovReporter,
    JSON: $npm$mocha$JSONReporter,
    JSONCov: $npm$mocha$JSONCovReporter,
    JSONStream: $npm$mocha$JSONStreamReporter,
    Landing: $npm$mocha$LandingReporter,
    List: $npm$mocha$ListReporter,
    Markdown: $npm$mocha$MarkdownReporter,
    Min: $npm$mocha$MinReporter,
    Nyan: $npm$mocha$NyanReporter,
    Progress: $npm$mocha$ProgressReporter,
    ...
  };
}

// declare interface $npm$mocha$HookCallbackContext {
//   skip(): void;
//   timeout(ms: number): void;
//   [index: string]: any;
// }

declare interface $npm$mocha$Runnable {
  title: string;
  fn: Function;
  async: boolean;
  sync: boolean;
  timedOut: boolean;
}

declare interface $npm$mocha$Test extends $npm$mocha$Runnable {
  parent: $npm$mocha$Suite;
  pending: boolean;
  state: 'failed' | 'passed' | void;
  fullTitle(): string;
  timeout(ms: number): void;
}

// declare interface $npm$mocha$BeforeAndAfterContext extends $npm$mocha$HookCallbackContext {
//   currentTest: $npm$mocha$Test;
// }

declare var mocha: $npm$mocha$Mocha;
declare var describe: $npm$mocha$ContextDefinition;
declare var xdescribe: $npm$mocha$ContextDefinition;
declare var context: $npm$mocha$ContextDefinition;
declare var suite: $npm$mocha$ContextDefinition;
declare var it: $npm$mocha$TestDefinition;
declare var xit: $npm$mocha$TestDefinition;
declare var test: $npm$mocha$TestDefinition;
declare var specify: $npm$mocha$TestDefinition;

declare function run(): void;

declare function setup(
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function teardown(
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function suiteSetup(
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function suiteTeardown(
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function before(
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function before(
  description: string,
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function after(
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function after(
  description: string,
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function beforeEach(
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function beforeEach(
  description: string,
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function afterEach(
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;
declare function afterEach(
  description: string,
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
): void;

declare module 'mocha' {
  declare export var mocha: typeof mocha;
  declare export var describe: typeof describe;
  declare export var xdescribe: typeof xdescribe;
  declare export var context: typeof context;
  declare export var suite: typeof suite;
  declare export var it: typeof it;
  declare export var xit: typeof xit;
  declare export var test: typeof test;
  declare export var specify: typeof specify;

  declare export var run: typeof run;

  declare export var setup: typeof setup;
  declare export var teardown: typeof teardown;
  declare export var suiteSetup: typeof suiteSetup;
  declare export var suiteTeardown: typeof suiteTeardown;
  declare export var before: typeof before;
  declare export var before: typeof before;
  declare export var after: typeof after;
  declare export var after: typeof after;
  declare export var beforeEach: typeof beforeEach;
  declare export var beforeEach: typeof beforeEach;
  declare export var afterEach: typeof afterEach;
  declare export var afterEach: typeof afterEach;

  declare export default $npm$mocha$Mocha;
}
<commit_msg>flow-typed: update Mocha typings (#2961)<commit_after>declare interface $npm$mocha$SetupOptions {
  slow?: number;
  timeout?: number;
  ui?: string;
  globals?: Array<any>;
  reporter?: any;
  bail?: boolean;
  ignoreLeaks?: boolean;
  grep?: any;
}

declare type $npm$mocha$done = (error?: any) => any;

// declare interface $npm$mocha$SuiteCallbackContext {
//   timeout(ms: number): void;
//   retries(n: number): void;
//   slow(ms: number): void;
// }

// declare interface $npm$mocha$TestCallbackContext {
//   skip(): void;
//   timeout(ms: number): void;
//   retries(n: number): void;
//   slow(ms: number): void;
//   [index: string]: any;
// }

declare interface $npm$mocha$Suite {
  parent: $npm$mocha$Suite;
  title: string;
  fullTitle(): string;
}

declare type $npm$mocha$ContextDefinition = {|
  (
    description: string,
    callback: () => /* this: $npm$mocha$SuiteCallbackContext */ void,
  ): $npm$mocha$Suite,
  only(
    description: string,
    callback: () => /* this: $npm$mocha$SuiteCallbackContext */ void,
  ): $npm$mocha$Suite,
  skip(
    description: string,
    callback: () => /* this: $npm$mocha$SuiteCallbackContext */ void,
  ): void,
  timeout(ms: number): void,
|};

declare type $npm$mocha$TestDefinition = {|
  (
    expectation: string,
    callback?: (
      /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done,
    ) => mixed,
  ): $npm$mocha$Test,
  only(
    expectation: string,
    callback?: (
      /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done,
    ) => mixed,
  ): $npm$mocha$Test,
  skip(
    expectation: string,
    callback?: (
      /* this: $npm$mocha$TestCallbackContext, */ done: $npm$mocha$done,
    ) => mixed,
  ): void,
  timeout(ms: number): void,
  state: 'failed' | 'passed',
|};

declare interface $npm$mocha$Runner {}

declare class $npm$mocha$BaseReporter {
  stats: {
    suites: number,
    tests: number,
    passes: number,
    pending: number,
    failures: number,
    ...
  };

  constructor(runner: $npm$mocha$Runner): $npm$mocha$BaseReporter;
}

declare class $npm$mocha$DocReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$DotReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$HTMLReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$HTMLCovReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$JSONReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$JSONCovReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$JSONStreamReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$LandingReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$ListReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$MarkdownReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$MinReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$NyanReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$ProgressReporter extends $npm$mocha$BaseReporter {
  constructor(
    runner: $npm$mocha$Runner,
    options?: {
      open?: string,
      complete?: string,
      incomplete?: string,
      close?: string,
      ...
    },
  ): $npm$mocha$ProgressReporter;
}
declare class $npm$mocha$SpecReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$TAPReporter extends $npm$mocha$BaseReporter {}
declare class $npm$mocha$XUnitReporter extends $npm$mocha$BaseReporter {
  constructor(
    runner: $npm$mocha$Runner,
    options?: any,
  ): $npm$mocha$XUnitReporter;
}

declare class $npm$mocha$Mocha {
  currentTest: $npm$mocha$TestDefinition;
  constructor(options?: {
    grep?: RegExp,
    ui?: string,
    reporter?: string,
    timeout?: number,
    reporterOptions?: any,
    slow?: number,
    bail?: boolean,
    ...
  }): $npm$mocha$Mocha;
  setup(options: $npm$mocha$SetupOptions): this;
  bail(value?: boolean): this;
  addFile(file: string): this;
  reporter(name: string): this;
  reporter(reporter: (runner: $npm$mocha$Runner, options: any) => any): this;
  ui(value: string): this;
  grep(value: string): this;
  grep(value: RegExp): this;
  invert(): this;
  ignoreLeaks(value: boolean): this;
  checkLeaks(): this;
  throwError(error: Error): void;
  growl(): this;
  globals(value: string): this;
  globals(values: Array<string>): this;
  useColors(value: boolean): this;
  useInlineDiffs(value: boolean): this;
  timeout(value: number): this;
  slow(value: number): this;
  enableTimeouts(value: boolean): this;
  asyncOnly(value: boolean): this;
  noHighlighting(value: boolean): this;
  run(onComplete?: (failures: number) => void): $npm$mocha$Runner;

  static reporters: {
    Doc: $npm$mocha$DocReporter,
    Dot: $npm$mocha$DotReporter,
    HTML: $npm$mocha$HTMLReporter,
    HTMLCov: $npm$mocha$HTMLCovReporter,
    JSON: $npm$mocha$JSONReporter,
    JSONCov: $npm$mocha$JSONCovReporter,
    JSONStream: $npm$mocha$JSONStreamReporter,
    Landing: $npm$mocha$LandingReporter,
    List: $npm$mocha$ListReporter,
    Markdown: $npm$mocha$MarkdownReporter,
    Min: $npm$mocha$MinReporter,
    Nyan: $npm$mocha$NyanReporter,
    Progress: $npm$mocha$ProgressReporter,
    ...
  };
}

// declare interface $npm$mocha$HookCallbackContext {
//   skip(): void;
//   timeout(ms: number): void;
//   [index: string]: any;
// }

declare interface $npm$mocha$Runnable {
  title: string;
  fn: Function;
  async: boolean;
  sync: boolean;
  timedOut: boolean;
}

declare interface $npm$mocha$Test extends $npm$mocha$Runnable {
  parent: $npm$mocha$Suite;
  pending: boolean;
  state: 'failed' | 'passed' | void;
  fullTitle(): string;
  timeout(ms: number): void;
}

// declare interface $npm$mocha$BeforeAndAfterContext extends $npm$mocha$HookCallbackContext {
//   currentTest: $npm$mocha$Test;
// }

declare var mocha: $npm$mocha$Mocha;
declare var describe: $npm$mocha$ContextDefinition;
declare var xdescribe: $npm$mocha$ContextDefinition;
declare var context: $npm$mocha$ContextDefinition;
declare var suite: $npm$mocha$ContextDefinition;
declare var it: $npm$mocha$TestDefinition;
declare var xit: $npm$mocha$TestDefinition;
declare var test: $npm$mocha$TestDefinition;
declare var specify: $npm$mocha$TestDefinition;

type Run = () => void;

declare var run: Run;

type Setup = (
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
) => void;
type Teardown = (
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
) => void;
type SuiteSetup = (
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
) => void;
type SuiteTeardown = (
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
) => void;
type Before = (
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
) =>
  | void
  | ((
      description: string,
      callback: (
        /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
      ) => mixed,
    ) => void);
type After = (
  callback: (
    /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
  ) => mixed,
) =>
  | void
  | ((
      description: string,
      callback: (
        /* this: $npm$mocha$HookCallbackContext, */ done: $npm$mocha$done,
      ) => mixed,
    ) => void);
type BeforeEach = (
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
) =>
  | void
  | ((
      description: string,
      callback: (
        /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
      ) => mixed,
    ) => void);
type AfterEach = (
  callback: (
    /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
  ) => mixed,
) =>
  | void
  | ((
      description: string,
      callback: (
        /* this: $npm$mocha$BeforeAndAfterContext, */ done: $npm$mocha$done,
      ) => mixed,
    ) => void);

declare var setup: Setup;
declare var teardown: Teardown;
declare var suiteSetup: SuiteSetup;
declare var suiteTeardown;
declare var before: Before;
declare var after: After;
declare var beforeEach: BeforeEach;
declare var afterEach: AfterEach;

declare module 'mocha' {
  declare export var mocha: $npm$mocha$TestDefinition;
  declare export var describe: $npm$mocha$ContextDefinition;
  declare export var xdescribe: $npm$mocha$ContextDefinition;
  declare export var context: $npm$mocha$ContextDefinition;
  declare export var suite: $npm$mocha$ContextDefinition;
  declare export var it: $npm$mocha$TestDefinition;
  declare export var xit: $npm$mocha$TestDefinition;
  declare export var test: $npm$mocha$TestDefinition;
  declare export var specify: $npm$mocha$TestDefinition;

  declare export var run: Run;

  declare export var setup: Setup;
  declare export var teardown: Teardown;
  declare export var suiteSetup: SuiteSetup;
  declare export var suiteTeardown: SuiteTeardown;
  declare export var before: Before;
  declare export var after: After;
  declare export var beforeEach: BeforeEach;
  declare export var afterEach: AfterEach;

  declare export default $npm$mocha$Mocha;
}
<|endoftext|>


<commit_before>//= require backbone_extensions/include
//= require underscore.string
(function(_, Backbone) {
  'use strict';
  function mixin(namespace) {
    namespace = namespace || {};

    function mergeAssociationOptions() {
      return _(arguments).chain().toArray().reduce(function(result, options) { return _(result).extend(options); }, {})
          .omit('class', 'className', 'inverseOf', 'parseName', 'through').value();
    }

    function buildAssociation(associationType, associationName, options) {
      function through() {
        function association() {
          var t = (_(options.through).isFunction() && options.through.call(this)) || _.str.camelize(options.through);
          return this[t] && this[t]() && this[t]()[associationName] && this[t]()[associationName]();
        }
        return options.through && association.call(this);
      }

      function throughCollection() {
        return (this.collection && this.collection[associationName] && this.collection[associationName]()) ||
            (this._options && this._options.collection && this._options.collection[associationName] && this._options.collection[associationName]());
      }

      function createAssociation() {
        var collectionName = _.str.classify(associationName), className = options.className && _.str.classify(options.className),
            newOptions = mergeAssociationOptions(options, this._options);

        if (options.inverseOf) {
          newOptions[_.str.camelize(options.inverseOf)] = _(function() { return this; }).bind(this);
        }

        return _((options['class'] && new options['class'](null, newOptions)) ||
            (className && namespace[className] && new namespace[className](null, newOptions)) ||
            (namespace[collectionName] && new namespace[collectionName](null, newOptions))).tap(_(function(association) {
              through.call(this, association);
            }).bind(this));
      }

      var associations = {
        hasMany: createAssociation,
        hasOne: function() { return throughCollection.call(this) || createAssociation.call(this); },
        belongsTo: function() { return throughCollection.call(this) || through.call(this); }
      };

      this.prototype[associationName] = function() {
        return (this._associations || (this._associations = {})) && this._associations[associationName] ||
            (this._associations[associationName] = (this._options && _(this._options).result(associationName)) || associations[associationType].call(this));
      };
    }

    function parseAssociation(associationType, associationName, options) {
      function parseResponseWith(key, response) {
        var camelized = _.str.camelize(key), underscored = _.str.underscored(key);
        if (response[camelized]) {
          return {key: camelized, response: response[camelized]};
        }
        else if (response[underscored]) {
          return {key: underscored, response: response[underscored]};
        }
        else {
          return {response: null};
        }
      }

      function through(response) {
        var t = parseResponseWith(_(options).result('through'), response).response,
            singularAssociationName = _.singularize && _(associationName).singularize(),
            p = options.parseName || singularAssociationName;
        return {response: t && p && _(t)[associationType === 'hasOne' ? 'result' : 'pluck'](p)};
      }

      if (options.parse) {
        var associations = {
          hasMany: function(assocResponse, association, newOptions) {
            association.add(assocResponse, newOptions);
          },
          hasOne: function(assocResponse, association, newOptions) {
            association.clear({silent: true}).set(assocResponse, newOptions);
          }
        };

        if (associations[associationType]) {
          var parseFunc = _(options.parse).isFunction() &&
                  function(response) { return {response: options.parse.call(this, response) }; } ||
                  function(response) {
                    return (options.through && through.call(this, response)) ||
                        (options.parseName && parseResponseWith(options.parseName, response)) ||
                        (options.className && parseResponseWith(options.className, response)) ||
                        parseResponseWith(associationName, response);
                  };

          if(!this._parsers) {
            var originalParse = this.prototype.parse,
                parsers = this._parsers = [];
            this.prototype.parse = function(response) {
              return _(originalParse.call(this, response)).tap(_(function(parsedResponse) {
                _(parsers)
                    .chain()
                    .map(function(parser) {
                      return _(parser.parseFn.call(this, parsedResponse)).tap(_(function(result) {
                        parser.associationFn.call(this, result.response);
                      }).bind(this)).key;
                    }, this)
                    .each(function(key) {
                      return key && delete parsedResponse[key];
                    });
              }).bind(this));
            };
          }

          this._parsers.push({
            parseFn: parseFunc,
            associationFn: function(assocResponse) {
              associations[associationType].call(this, assocResponse, this[associationName](), mergeAssociationOptions(options, this.options));
            }
          });
        }
      }
    }

    return {
      included: function(source) {
        var associations = _({
          belongsTo: {}, hasMany: {parse: true}, hasOne: {parse: true}
        }).reduce(function(associations, defaultOptions, associationType) {
          associations[associationType] = function(name, options) {
            var associationName = _.str.camelize(name);
            options = _({}).extend(defaultOptions, options);
            buildAssociation.call(this, associationType, associationName, options);
            parseAssociation.call(this, associationType, associationName, options);
            return this;
          };
          return associations;
        }, {});

        _(source).extend(associations, {
          associations: function() {
            _(arguments).chain().toArray().each(function(options) {
              _(associations).chain().keys().each(function(associationType) {
                if (options[associationType]) {
                  associations[associationType].call(source, options[associationType], _(options).omit(associationType));
                }
              });
            });
          },

          extend: _(source.extend).wrap(function(oldExtend, protoProps, classProps) {
            return _(oldExtend.call(this, protoProps, classProps)).tap(function() {
              source.associations((protoProps || {}).associations);
            });
          })
        });

        source.prototype.initialize = _(source.prototype.initialize).wrap(function(oldInitialize, attrsOrModels, options) {
          this._options = _(options).clone();
          oldInitialize.call(this, attrsOrModels, options);
        });
      }
    };
  }

  Backbone.extensions = _(Backbone.extensions || {}).extend({associations: mixin});
})(_, Backbone);
<commit_msg>only evaluate camelize and underscored if it does not find a match, default to null response<commit_after>//= require backbone_extensions/include
//= require underscore.string
(function(_, Backbone) {
  'use strict';
  function mixin(namespace) {
    namespace = namespace || {};

    function mergeAssociationOptions() {
      return _(arguments).chain().toArray().reduce(function(result, options) { return _(result).extend(options); }, {})
          .omit('class', 'className', 'inverseOf', 'parseName', 'through').value();
    }

    function buildAssociation(associationType, associationName, options) {
      function through() {
        function association() {
          var t = (_(options.through).isFunction() && options.through.call(this)) || _.str.camelize(options.through);
          return this[t] && this[t]() && this[t]()[associationName] && this[t]()[associationName]();
        }
        return options.through && association.call(this);
      }

      function throughCollection() {
        return (this.collection && this.collection[associationName] && this.collection[associationName]()) ||
            (this._options && this._options.collection && this._options.collection[associationName] && this._options.collection[associationName]());
      }

      function createAssociation() {
        var collectionName = _.str.classify(associationName), className = options.className && _.str.classify(options.className),
            newOptions = mergeAssociationOptions(options, this._options);

        if (options.inverseOf) {
          newOptions[_.str.camelize(options.inverseOf)] = _(function() { return this; }).bind(this);
        }

        return _((options['class'] && new options['class'](null, newOptions)) ||
            (className && namespace[className] && new namespace[className](null, newOptions)) ||
            (namespace[collectionName] && new namespace[collectionName](null, newOptions))).tap(_(function(association) {
              through.call(this, association);
            }).bind(this));
      }

      var associations = {
        hasMany: createAssociation,
        hasOne: function() { return throughCollection.call(this) || createAssociation.call(this); },
        belongsTo: function() { return throughCollection.call(this) || through.call(this); }
      };

      this.prototype[associationName] = function() {
        return (this._associations || (this._associations = {})) && this._associations[associationName] ||
            (this._associations[associationName] = (this._options && _(this._options).result(associationName)) || associations[associationType].call(this));
      };
    }

    function parseAssociation(associationType, associationName, options) {
      function parseResponseWith(key, response) {
        var parseKey;
        return _([_.str.camelize, _.str.underscored]).any(function(fn) {
          var k = fn(key);
          return (parseKey = response[k] && {key: k, response: response[k]});
        }) && parseKey || {response: null};
      }

      function through(response) {
        var t = parseResponseWith(_(options).result('through'), response).response,
            singularAssociationName = _.singularize && _(associationName).singularize(),
            p = options.parseName || singularAssociationName;
        return {response: t && p && _(t)[associationType === 'hasOne' ? 'result' : 'pluck'](p)};
      }

      if (options.parse) {
        var associations = {
          hasMany: function(assocResponse, association, newOptions) {
            association.add(assocResponse, newOptions);
          },
          hasOne: function(assocResponse, association, newOptions) {
            association.clear({silent: true}).set(assocResponse, newOptions);
          }
        };

        if (associations[associationType]) {
          var parseFunc = _(options.parse).isFunction() &&
                  function(response) { return {response: options.parse.call(this, response) }; } ||
                  function(response) {
                    return (options.through && through.call(this, response)) ||
                        (options.parseName && parseResponseWith(options.parseName, response)) ||
                        (options.className && parseResponseWith(options.className, response)) ||
                        parseResponseWith(associationName, response);
                  };

          if(!this._parsers) {
            var originalParse = this.prototype.parse,
                parsers = this._parsers = [];
            this.prototype.parse = function(response) {
              return _(originalParse.call(this, response)).tap(_(function(parsedResponse) {
                _(parsers)
                    .chain()
                    .map(function(parser) {
                      return _(parser.parseFn.call(this, parsedResponse)).tap(_(function(result) {
                        parser.associationFn.call(this, result.response);
                      }).bind(this)).key;
                    }, this)
                    .each(function(key) {
                      return key && delete parsedResponse[key];
                    });
              }).bind(this));
            };
          }

          this._parsers.push({
            parseFn: parseFunc,
            associationFn: function(assocResponse) {
              associations[associationType].call(this, assocResponse, this[associationName](), mergeAssociationOptions(options, this.options));
            }
          });
        }
      }
    }

    return {
      included: function(source) {
        var associations = _({
          belongsTo: {}, hasMany: {parse: true}, hasOne: {parse: true}
        }).reduce(function(associations, defaultOptions, associationType) {
          associations[associationType] = function(name, options) {
            var associationName = _.str.camelize(name);
            options = _({}).extend(defaultOptions, options);
            buildAssociation.call(this, associationType, associationName, options);
            parseAssociation.call(this, associationType, associationName, options);
            return this;
          };
          return associations;
        }, {});

        _(source).extend(associations, {
          associations: function() {
            _(arguments).chain().toArray().each(function(options) {
              _(associations).chain().keys().each(function(associationType) {
                if (options[associationType]) {
                  associations[associationType].call(source, options[associationType], _(options).omit(associationType));
                }
              });
            });
          },

          extend: _(source.extend).wrap(function(oldExtend, protoProps, classProps) {
            return _(oldExtend.call(this, protoProps, classProps)).tap(function() {
              source.associations((protoProps || {}).associations);
            });
          })
        });

        source.prototype.initialize = _(source.prototype.initialize).wrap(function(oldInitialize, attrsOrModels, options) {
          this._options = _(options).clone();
          oldInitialize.call(this, attrsOrModels, options);
        });
      }
    };
  }

  Backbone.extensions = _(Backbone.extensions || {}).extend({associations: mixin});
})(_, Backbone);
<|endoftext|>


<commit_before>const getUserPolyfills = (polyfills) => {
	return polyfills.reduce((userPolyfills, polyfill) => {
		if (polyfill.isNeeded) {
			userPolyfills.push(polyfill.bundle);
		}
		return userPolyfills;
	}, []);
};

const getPolyfillsURL = (polyfillBundles, { url }) => {
	return `${url}/polyfills.js?with=${polyfillBundles.join(',')}`;
};

const getScriptLoader = () => {
	const loadAsyncScript = (url) => {
		const tag = document.createElement('script');
		tag.src = url;
		tag.async = false;
		document.head.appendChild(tag);
	};

	const pendingScripts = [];
	const scriptStateChange = () => {
		while (pendingScripts[0] && pendingScripts[0].readyState === 'loaded') {
			const scriptToExecute = pendingScripts.shift();
			scriptToExecute.onreadystatechange = null;
			document.head.appendChild(scriptToExecute);
		}
	};
	const loadReadyStateScript = (url) => {
		const tag = document.createElement('script');
		pendingScripts.push(tag);
		tag.onreadystatechange = scriptStateChange;
		tag.src = url;
	};

	if ('async' in document.createElement('script')) {
		return {
			load: loadAsyncScript
		};
	} else {
		return {
			load: loadReadyStateScript
		};
	}
};

export default ({ polyfills, url }) => {
	const scriptLoader = getScriptLoader();
	const userPolyfills = getUserPolyfills(polyfills);
	if (userPolyfills.length > 0) {
		console.log('fetching polyfills : ', userPolyfills.join(', ')); //eslint-disable-line
		const polyfillURL = getPolyfillsURL(userPolyfills, { url });
		scriptLoader.load(polyfillURL);
	} else {
		console.log('you dont need no polyfill'); //eslint-disable-line
	}
	window.polyfilledScripts.forEach(scriptURL => {
		scriptLoader.load(scriptURL);
	});
};
<commit_msg>Allow polyfill bundle to be a function executed at runtime<commit_after>const getUserPolyfills = (polyfills) => {
	return polyfills.reduce((userPolyfills, polyfill) => {
		if (polyfill.isNeeded) {
			const bundle = typeof polyfill.bundle === 'function' ? polyfill.bundle() : polyfill.bundle;
			if (typeof bundle !== 'undefined') {
				userPolyfills.push(bundle);
			}
		}
		return userPolyfills;
	}, []);
};

const getPolyfillsURL = (polyfillBundles, { url }) => {
	return `${url}/polyfills.js?with=${polyfillBundles.join(',')}`;
};

const getScriptLoader = () => {
	const loadAsyncScript = (url) => {
		const tag = document.createElement('script');
		tag.src = url;
		tag.async = false;
		document.head.appendChild(tag);
	};

	const pendingScripts = [];
	const scriptStateChange = () => {
		while (pendingScripts[0] && pendingScripts[0].readyState === 'loaded') {
			const scriptToExecute = pendingScripts.shift();
			scriptToExecute.onreadystatechange = null;
			document.head.appendChild(scriptToExecute);
		}
	};
	const loadReadyStateScript = (url) => {
		const tag = document.createElement('script');
		pendingScripts.push(tag);
		tag.onreadystatechange = scriptStateChange;
		tag.src = url;
	};

	if ('async' in document.createElement('script')) {
		return {
			load: loadAsyncScript
		};
	} else {
		return {
			load: loadReadyStateScript
		};
	}
};

export default ({ polyfills, url }) => {
	const scriptLoader = getScriptLoader();
	const userPolyfills = getUserPolyfills(polyfills);
	if (userPolyfills.length > 0) {
		console.log('fetching polyfills : ', userPolyfills.join(', ')); //eslint-disable-line
		const polyfillURL = getPolyfillsURL(userPolyfills, { url });
		scriptLoader.load(polyfillURL);
	} else {
		console.log('you dont need no polyfill'); //eslint-disable-line
	}
	window.polyfilledScripts.forEach(scriptURL => {
		scriptLoader.load(scriptURL);
	});
};
<|endoftext|>


<commit_before>//= require active_admin/utils

(function(scope, $) {
  'use strict';

  function CepInput(input) {
    this.input = input;
    this.form = input.closest('form');
    this.scope = this.input.data('scope');
    this.url = this.input.data('url');
    this.fields = this.input.data('fields').reduce(function(fields, field) {
      fields[field] = this.findField(field);
      return fields;
    }.bind(this), {});
    this.cepRegex = new RegExp(this.input.data('cepRegex'));
    this.onChange = scope.Utils.debounce(this.onChange.bind(this), 300);
    this.lastValue = null;
    this.lastQuery = null;
    this.attachEvents();
  }

  CepInput.attach = function(selector) {
    $(selector).each(function() {
      var self = $(this);
      self.data('cepInput', new CepInput(self));
    });
  };

  CepInput.prototype = {
    attachEvents: function() {
      this.input.on('keypress', this.onChange);
    },

    findField: function(field) {
      return $('#' + this.scope + '_' + field);
    },

    onChange: function(e) {
      var value = e.delegateTarget.value;

      if (this.isValid(value) && this.hasChanged(value)) {
        this.query(value);
      }
    },

    isValid: function(value) {
      return !!value.match(this.cepRegex);
    },

    hasChanged: function(value) {
      return this.lastValue !== value;
    },

    query: function(value) {
      if (this.lastQuery !== null) {
        this.lastQuery.abort();
      }

      this.lockFields();
      this.lastValue = value;
      this.lastQuery = $.get(this.url, { cep: value })
        .then(function(data) {
          this.render(data);
          this.lastQuery = null;
          this.unlockFields();
        }.bind(this))
        .fail(function() {
          this.renderEmpty();
          this.lastQuery = null;
          this.unlockFields();
        }.bind(this));
    },

    render: function(data) {
      $.each(this.fields, function(field, element) {
        var value = data[field];
        element.val(value);
        element.trigger('change');
        element.trigger('active_admin:cep_auto_complete', [value, data, this]);
      }.bind(this));
    },

    renderEmpty: function() {
      $.each(this.fields, function(field, element) {
        element.val(null);
        element.trigger('change');
        element.trigger('active_admin:cep_auto_complete', [null, null, this]);
      }.bind(this));
    },

    lockFields: function() {
      this.toggleFields(true);
    },

    unlockFields: function() {
      this.toggleFields(false);
    },

    toggleFields: function(disabled) {
      $.each(this.fields, function(field, element) {
        element.prop('disabled', disabled);
      });
    }
  };

  $(document).ready(function() {
    CepInput.attach('.cep-auto-complete');
  });

  scope.CepInput = CepInput;
}(window.ActiveAdmin, jQuery));
<commit_msg>Fix for has many fields<commit_after>//= require active_admin/utils

(function(scope, $) {
  'use strict';

  function CepInput(input) {
    this.input = input;
    this.form = input.closest('form');
    this.scope = this.input.data('scope');
    this.url = this.input.data('url');
    this.fields = this.input.data('fields').reduce(function(fields, field) {
      fields[field] = this.findField(field);
      return fields;
    }.bind(this), {});
    this.cepRegex = new RegExp(this.input.data('cepRegex'));
    this.onChange = scope.Utils.debounce(this.onChange.bind(this), 300);
    this.lastValue = null;
    this.lastQuery = null;
    this.attachEvents();
  }

  CepInput.attach = function(selector) {
    $(selector).each(function() {
      var self = $(this);
      self.data('cepInput', new CepInput(self));
    });
  };

  CepInput.prototype = {
    attachEvents: function() {
      this.input.on('keypress', this.onChange);
    },

    findField: function(field) {
      return $('#' + this.scope + '_' + field);
    },

    onChange: function(e) {
      var value = e.delegateTarget.value;

      if (this.isValid(value) && this.hasChanged(value)) {
        this.query(value);
      }
    },

    isValid: function(value) {
      return !!value.match(this.cepRegex);
    },

    hasChanged: function(value) {
      return this.lastValue !== value;
    },

    query: function(value) {
      if (this.lastQuery !== null) {
        this.lastQuery.abort();
      }

      this.lockFields();
      this.lastValue = value;
      this.lastQuery = $.get(this.url, { cep: value })
        .then(function(data) {
          this.render(data);
          this.lastQuery = null;
          this.unlockFields();
        }.bind(this))
        .fail(function() {
          this.renderEmpty();
          this.lastQuery = null;
          this.unlockFields();
        }.bind(this));
    },

    render: function(data) {
      $.each(this.fields, function(field, element) {
        var value = data[field];
        element.val(value);
        element.trigger('change');
        element.trigger('active_admin:cep_auto_complete', [value, data, this]);
      }.bind(this));
    },

    renderEmpty: function() {
      $.each(this.fields, function(field, element) {
        element.val(null);
        element.trigger('change');
        element.trigger('active_admin:cep_auto_complete', [null, null, this]);
      }.bind(this));
    },

    lockFields: function() {
      this.toggleFields(true);
    },

    unlockFields: function() {
      this.toggleFields(false);
    },

    toggleFields: function(disabled) {
      $.each(this.fields, function(field, element) {
        element.prop('disabled', disabled);
      });
    }
  };

  $(document).ready(function() {
    CepInput.attach('.cep-auto-complete');

    $('.has_many_add').each(function() {
      var self = $(this);
      var parent = self.parent('.has_many_container');

      parent.on('has_many_add:after', function(e, fieldset) {
        CepInput.attach($(fieldset).find('.cep-auto-complete'));
      });
    });
  });

  scope.CepInput = CepInput;
}(window.ActiveAdmin, jQuery));
<|endoftext|>


<commit_before>(function($) {
	/**
	 * This plugin autocompletes by using data from predefined URL.
	 *
	 * @author: Marcin Konicki, ahwayakchih@neoni.net
	 * @source: http://github.com/ahwayakchih/autocompleter
	 */

	$(document).ready(function() {
		var params = Symphony.Context.get('autocompleter'),
			env = Symphony.Context.get('env'),
			lastID = null,
			cache = {};

		$('div.autocompleter-popup li.item')
			.live('confirm.autocompleter', function(){
				var item = $(this),
					id = item.attr('data-value'),
					select = item.attr('data-select-in');

				if (!id || id == '' || !select || select == '') return;
				select = select.match(/[^,]+/g);

				$.each(select, function(index, value){
					var field = $('div.field *[name^="fields\\['+value+'\\]"]').parents('div.field');

					if (field.is('.field-subsectionmanager')) {
						var stage = field.find('div.stage'),
							selection = stage.find('ul.selection');

						// Ignore if item is already selected
						if (selection.find('li[data-value="'+id+'"]').length > 0) return;

						// Get item order
						// For some reason, this will not find new items.
						// So we get "old" items first, and then add new ones below.
						var sortorder = selection.find('li').map(function() {
							return $(this).attr('data-value');
						}).get().join(',');

						// Add item
						var uploadeditem = $('

').appendTo(selection),
							fakeframe = $('

<form action="dummy://'+id+'">dummy</form>

');
						if (stage.is('.destructable')) {
							$('×').appendTo(uploadeditem);
						}
						stage.trigger('edit', [uploadeditem, fakeframe]);

						sortorder += (sortorder == '' ? '' : ',') + id;

						// Save sortorder
						field.find('input[name*="sort_order"]').val(sortorder);

						if (sortorder != '') {
							selection.find('li.empty.message').remove();
						}
					}
				});

				//if (stage) {
				//	stage.find('li[data-value="'+$(this).attr('data-value')+'"]:not(.selected)').trigger('click.stage');
				//}
			});

		$('div.autocompleter-popup')
			.live('autocomplete.autocompleter', function(event, word){
				var popup = $(this),
					id = popup.attr('id').replace('-autocompleter', ''),
					input = $('#'+id),
					url = input.attr('data-autocompleterurl'),
					name = input.attr('name').replace('fields[', '').replace(']', '');

				if (!url) return;

				if (url[0] == '/') url = Symphony.Context.get('root') + '/' + url;

				if (lastID == name+'|'+url) {
					if (cache[word]) {
						popup.append(cache[word]);

						var item = popup.find('li.item:first'),
							text = item.attr('data-preview');
						if (text && text.indexOf(word) == 0)
							popup.trigger('highlightitem', [item]);

						return;
					}
				}
				lastID = name+'|'+url;

				popup.append('
...
');

				// Allow other scripts to override our request.
				var options = {
					'url': url,
					'q': word,
					'field': name,
					'section': env['section_handle']
				}
				if (env['entry_id']) options['entry_id'] = env['entry_id'].toString();
				popup.trigger('preautocomplete', [options]);

				var data = '';
				$.each(options, function(key, value){
					if (key == 'url') return true;
					data += key + '=' + value.replace(' ', '+') + '&';
				});

				$.ajax({
					async: true,
					type: 'GET',
					dataType: 'html',
					url: options.url,
					// We build string ourselves, otherwise slashes and other "special" characters will end up double-encoded :(
					data: data,
					processData: false,
					success: function(data) {
						cache[word] = data;
						popup.find('p.loading.autocompleter-url').replaceWith(data);

						// Do not highlight if query was empty
						if (options.q.length < 1) return;

						var item = popup.find('li.item:first'),
							text = item.attr('data-preview');
						if (text && text.indexOf(word) == 0)
							popup.trigger('highlightitem', [item]);
					}
				});
			})
			.live('stop.autocompleter', function(){
			//	if (stage) {
			//		stage.trigger('browsestop');
			//		stage = null;
			//	}
			});
		});
})(jQuery.noConflict());
<commit_msg>Fixed `autocompleter.url.js` to prevent duplicated items in SubsectionManager Queue.<commit_after>(function($) {
	/**
	 * This plugin autocompletes by using data from predefined URL.
	 *
	 * @author: Marcin Konicki, ahwayakchih@neoni.net
	 * @source: http://github.com/ahwayakchih/autocompleter
	 */

	$(document).ready(function() {
		var params = Symphony.Context.get('autocompleter'),
			env = Symphony.Context.get('env'),
			lastID = null,
			cache = {};

		$('div.autocompleter-popup li.item')
			.live('confirm.autocompleter', function(){
				var item = $(this),
					id = item.attr('data-value'),
					select = item.attr('data-select-in');

				if (!id || id == '' || !select || select == '') return;
				select = select.match(/[^,]+/g);

				$.each(select, function(index, value){
					var field = $('div.field *[name^="fields\\['+value+'\\]"]').parents('div.field');

					if (field.is('.field-subsectionmanager')) {
						var stage = field.find('div.stage'),
							selection = stage.find('ul.selection');

						// Ignore if item is already selected
						if (selection.find('li[data-value="'+id+'"]').length > 0) return;

						// Get item order
						// For some reason, this will not find new items.
						// So we get "old" items first, and then add new ones below.
						var sortorder = selection.find('li').map(function() {
							return $(this).attr('data-value');
						}).get().join(',');

						// If Queue is empty, try to make SubsectionManager load it.
						// This is needed because SubsectionManager appends items to queue,
						// no matter if they already are there or not. So if we add item before
						// Queue was not loaded, it will be duplicated after Queue is loaded
						// (for example, after user starts browsing it).
						// TODO: remove this if/when SubsectionManager starts appending only new items.
						if ($('div.queue ul li', stage).length < 1) {
							stage.trigger('browsestart');
							stage.trigger('browsestop');
						}

						// Add item
						var uploadeditem = $('

').appendTo(selection),
							fakeframe = $('

<form action="dummy://'+id+'">dummy</form>

');
						if (stage.is('.destructable')) {
							$('×').appendTo(uploadeditem);
						}
						stage.trigger('edit', [uploadeditem, fakeframe]);

						sortorder += (sortorder == '' ? '' : ',') + id;

						// Save sortorder
						field.find('input[name*="sort_order"]').val(sortorder);

						if (sortorder != '') {
							selection.find('li.empty.message').remove();
						}
					}
				});

				//if (stage) {
				//	stage.find('li[data-value="'+$(this).attr('data-value')+'"]:not(.selected)').trigger('click.stage');
				//}
			});

		$('div.autocompleter-popup')
			.live('autocomplete.autocompleter', function(event, word){
				var popup = $(this),
					id = popup.attr('id').replace('-autocompleter', ''),
					input = $('#'+id),
					url = input.attr('data-autocompleterurl'),
					name = input.attr('name').replace('fields[', '').replace(']', '');

				if (!url) return;

				if (url[0] == '/') url = Symphony.Context.get('root') + '/' + url;

				if (lastID == name+'|'+url) {
					if (cache[word]) {
						popup.append(cache[word]);

						var item = popup.find('li.item:first'),
							text = item.attr('data-preview');
						if (text && text.indexOf(word) == 0)
							popup.trigger('highlightitem', [item]);

						return;
					}
				}
				lastID = name+'|'+url;

				popup.append('
...
');

				// Allow other scripts to override our request.
				var options = {
					'url': url,
					'q': word,
					'field': name,
					'section': env['section_handle']
				}
				if (env['entry_id']) options['entry_id'] = env['entry_id'].toString();
				popup.trigger('preautocomplete', [options]);

				var data = '';
				$.each(options, function(key, value){
					if (key == 'url') return true;
					data += key + '=' + value.replace(' ', '+') + '&';
				});

				$.ajax({
					async: true,
					type: 'GET',
					dataType: 'html',
					url: options.url,
					// We build string ourselves, otherwise slashes and other "special" characters will end up double-encoded :(
					data: data,
					processData: false,
					success: function(data) {
						cache[word] = data;
						popup.find('p.loading.autocompleter-url').replaceWith(data);

						// Do not highlight if query was empty
						if (options.q.length < 1) return;

						var item = popup.find('li.item:first'),
							text = item.attr('data-preview');
						if (text && text.indexOf(word) == 0)
							popup.trigger('highlightitem', [item]);
					}
				});
			})
			.live('stop.autocompleter', function(){
			//	if (stage) {
			//		stage.trigger('browsestop');
			//		stage = null;
			//	}
			});
		});
})(jQuery.noConflict());
<|endoftext|>


<commit_before>'use strict';

/* globals define */

define('composer/drafts', function() {

	var drafts = {};
	var	saveThrottleId;
	var saving = false;

	drafts.init = function(postContainer, postData) {
		var bodyEl = postContainer.find('textarea');
		var draftIconEl = postContainer.find('.draft-icon');

		bodyEl.on('keyup', function() {
			resetTimeout();

			saveThrottleId = setTimeout(function() {
				saveDraft(postContainer, draftIconEl, postData);
			}, 1000);
		});
	};

	function resetTimeout() {
		if (saveThrottleId) {
			clearTimeout(saveThrottleId);
			saveThrottleId = 0;
		}
	}

	// deprecated, for removal v1.14.x
	drafts.getDraft = function(save_id) {
		console.warn('[composer/drafts] drafts.getDraft is deprecated! Use drafts.get() instead.');
		return localStorage.getItem(save_id);
	};

	drafts.get = function(save_id) {
		return {
			title: localStorage.getItem(save_id + ':title'),
			text: localStorage.getItem(save_id),
		}
	}

	function saveDraft(postContainer, draftIconEl, postData) {
		var raw;
		var title;

		if (canSave() && postData && postData.save_id && postContainer.length) {
			title = postContainer.find('input.title').val();
			raw = postContainer.find('textarea').val();
			if (raw.length) {
				localStorage.setItem(postData.save_id, raw);
				localStorage.setItem(postData.save_id + ':title', title);
				draftIconEl.removeClass('active');
				setTimeout(function () {
					draftIconEl.addClass('active');
				});
			} else {
				drafts.removeDraft(postData.save_id);
			}
		}
	}

	drafts.removeDraft = function(save_id) {
		if (!save_id) {
			return;
		}
		resetTimeout();
		// Remove save_id from list of open and available drafts
		drafts.updateVisibility('available', save_id);
		drafts.updateVisibility('open', save_id);

		localStorage.removeItem(save_id);
		localStorage.removeItem(save_id + ':title');
		return;
	};

	drafts.updateVisibility =  function (set, save_id, add) {
		if (!canSave() || !save_id) {
			return;
		}

		try {
			var open = localStorage.getItem('drafts:' + set);
			open = open ? JSON.parse(open) : [];
		} catch (e) {
			console.warn('[composer/drafts] Could not read list of open drafts');
			var open = [];
		}
		var idx = open.indexOf(save_id);

		if (add && idx === -1) {
			open.push(save_id);
		} else if (!add && idx !== -1) {
			open.splice(idx, 1);
		}	// otherwise do nothing

		localStorage.setItem('drafts:' + set, JSON.stringify(open));
	};

	function canSave() {
		if (saving) {
			return saving;
		}

		try {
			localStorage.setItem('test', 'test');
			localStorage.removeItem('test');
			saving = true;
			return true;
		} catch(e) {
			saving = false;
			return false;
		}
	}

	return drafts;
});<commit_msg>fix: draft save icon only shows up once, and never again<commit_after>'use strict';

/* globals define */

define('composer/drafts', function() {

	var drafts = {};
	var	saveThrottleId;
	var saving = false;

	drafts.init = function(postContainer, postData) {
		var bodyEl = postContainer.find('textarea');
		var draftIconEl = postContainer.find('.draft-icon');

		bodyEl.on('keyup', function() {
			resetTimeout();

			saveThrottleId = setTimeout(function() {
				saveDraft(postContainer, draftIconEl, postData);
			}, 1000);
		});

		draftIconEl.on('animationend', function () {
			$(this).toggleClass('active', false);
		});
	};

	function resetTimeout() {
		if (saveThrottleId) {
			clearTimeout(saveThrottleId);
			saveThrottleId = 0;
		}
	}

	// deprecated, for removal v1.14.x
	drafts.getDraft = function(save_id) {
		console.warn('[composer/drafts] drafts.getDraft is deprecated! Use drafts.get() instead.');
		return localStorage.getItem(save_id);
	};

	drafts.get = function(save_id) {
		return {
			title: localStorage.getItem(save_id + ':title'),
			text: localStorage.getItem(save_id),
		}
	}

	function saveDraft(postContainer, draftIconEl, postData) {
		var raw;
		var title;

		if (canSave() && postData && postData.save_id && postContainer.length) {
			title = postContainer.find('input.title').val();
			raw = postContainer.find('textarea').val();
			if (raw.length) {
				localStorage.setItem(postData.save_id, raw);
				localStorage.setItem(postData.save_id + ':title', title);
				draftIconEl.toggleClass('active', true);
			} else {
				drafts.removeDraft(postData.save_id);
			}
		}
	}

	drafts.removeDraft = function(save_id) {
		if (!save_id) {
			return;
		}
		resetTimeout();
		// Remove save_id from list of open and available drafts
		drafts.updateVisibility('available', save_id);
		drafts.updateVisibility('open', save_id);

		localStorage.removeItem(save_id);
		localStorage.removeItem(save_id + ':title');
		return;
	};

	drafts.updateVisibility =  function (set, save_id, add) {
		if (!canSave() || !save_id) {
			return;
		}

		try {
			var open = localStorage.getItem('drafts:' + set);
			open = open ? JSON.parse(open) : [];
		} catch (e) {
			console.warn('[composer/drafts] Could not read list of open drafts');
			var open = [];
		}
		var idx = open.indexOf(save_id);

		if (add && idx === -1) {
			open.push(save_id);
		} else if (!add && idx !== -1) {
			open.splice(idx, 1);
		}	// otherwise do nothing

		localStorage.setItem('drafts:' + set, JSON.stringify(open));
	};

	function canSave() {
		if (saving) {
			return saving;
		}

		try {
			localStorage.setItem('test', 'test');
			localStorage.removeItem('test');
			saving = true;
			return true;
		} catch(e) {
			saving = false;
			return false;
		}
	}

	return drafts;
});<|endoftext|>


<commit_before>'use strict';

var fuse = require('fusing');

/**
 * Setup in-process memory layer.
 *
 * @Constructor
 * @param {Dynamis} dynamis layer instance.
 * @param {Object} persistence Object where we store everything in.
 * @api private
 */
function Memory(dynamis, persistence) {
  this.fuse();

  this.database = persistence || Object.create(null);
  this.timers = Object.create(null);

  //
  // Add API functionality to the dynamis layer.
  //
  this.api(dynamis);
}

//
// Add emit capacities and fusing helper methods.
//
fuse(Memory, require('eventemitter3'));

/**
 * Extend the API of Dynamis.
 *
 * @param {Dynamis} dynamis API
 * @return {Memory} fluent interface
 */
Memory.readable('api', function api(dynamis) {
  var memory = this;

  /**
   * Get an item from the database.
   *
   * @param {String} key Key we need to look up.
   * @param {Function} fn Completion callback.
   * @api private
   */
  function get(key, fn) {
    fn(undefined, memory[key]);
  }

  /**
   * Set an item in the database.
   *
   * @param {String} key Key we need to look up.
   * @param {Mixed} value Thing that needs to be set as value.
   * @param {Number} ttl Time to Life of the item.
   * @param {Function} fn Completion callback.
   * @api private
   */
  function set(key, value, ttl, fn) {
    del(key);

    memory.database[key] = value;

    if (+ttl >= 0) expire(key, ttl);
  }

  /**
   * Set the expire of an item.
   *
   * @param {String} key Key we need to look up.
   * @param {Number} ttl Time to Life of the item.
   * @param {Function} fn Completion callback.
   * @api private
   */
  function expire(key, ttl, fn) {
    memory.timers[key] = setTimeout(function timeout() {
      del(key);
    }, ttl);

    if (fn) fn();
  }

  /**
   * Nuke an item from the database.
   *
   * @param {String} key Key we need to look up.
   * @param {Function} fn Completion callback.
   * @api private
   */
  function del(key, fn) {
    clearTimeout(memory.timers[key]);

    delete memory.database[key];
    delete memory.timers[key];

    if (fn) fn();
  }

  /**
   * Nuke all items from the database.
   *
   * @param {Function} fn Completion callback.
   * @api private
   */
  function flush(fn) {
    Object.keys(memory.database).forEach(function each(key) {
      del(key);
    });

    fn();
  }

  /**
   * Flush the entire dataset, flush everything.
   *
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('flush', function flushapi(done) {
    dynamis.execute(flush, flush, done);
  });

  /**
   * Get the key from memory.
   *
   * @param {String} key of value
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('get', function getapi(key, done) {
    dynamis.execute(get, get, key, done);
  });

  /**
   * Store value with key in memory.
   *
   * @param {String} key of value
   * @param {Mixed} value content to store
   * @param {Number} ttl optional time to live
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('set', function setapi(key, value, ttl, done) {
    if ('function' === typeof ttl) {
      done = ttl;
      ttl = 0;
    }

    dynamis.execute(set, set, key, value, ttl, done);
  });

  /**
   * Set the time to live for the key.
   *
   * @param {String} key of value
   * @param {Number} ttl optional time to live
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('expire', function expireapi(key, ttl, done) {
    dynamis.execute(expire, expire, key, ttl, done);
  });

  /**
   * Remove the value from memory.
   *
   * @param {String} key to delete
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('del', function delapi(key, done) {
    dynamis.execute(del, del, key, done);
  });

  return memory;
});

//
// Expose the module.
//
module.exports = Memory;
<commit_msg>[minor] Make sure that the memory adapter follows the same pattern as redis<commit_after>'use strict';

var fuse = require('fusing')
  , has = Object.prototype.hasOwnProperty;

/**
 * Setup in-process memory layer.
 *
 * @Constructor
 * @param {Dynamis} dynamis layer instance.
 * @param {Object} persistence Object where we store everything in.
 * @api private
 */
function Memory(dynamis, persistence) {
  this.fuse();

  this.database = persistence || Object.create(null);
  this.timers = Object.create(null);

  //
  // Add API functionality to the dynamis layer.
  //
  this.api(dynamis);
}

//
// Add emit capacities and fusing helper methods.
//
fuse(Memory, require('eventemitter3'));

/**
 * Extend the API of Dynamis.
 *
 * @param {Dynamis} dynamis API
 * @return {Memory} fluent interface
 */
Memory.readable('api', function api(dynamis) {
  var memory = this;

  /**
   * Get an item from the database.
   *
   * @param {String} key Key we need to look up.
   * @param {Function} fn Completion callback.
   * @api private
   */
  function get(key, fn) {
    fn(undefined, memory.database[key]);
  }

  /**
   * Set an item in the database.
   *
   * @param {String} key Key we need to look up.
   * @param {Mixed} value Thing that needs to be set as value.
   * @param {Number} ttl Time to Life of the item.
   * @param {Function} fn Completion callback.
   * @api private
   */
  function set(key, value, ttl, fn) {
    del(key);

    memory.database[key] = value;

    if (+ttl > 0) expire(key, ttl);
    if (fn) fn(undefined, 'OK');
  }

  /**
   * Set the expire of an item.
   *
   * @param {String} key Key we need to look up.
   * @param {Number} ttl Time to Life of the item.
   * @param {Function} fn Completion callback.
   * @api private
   */
  function expire(key, ttl, fn) {
    var exists = has.call(memory.database, key);

    if (exists) memory.timers[key] = setTimeout(function timeout() {
      del(key);
    }, ttl * 1000);

    //
    // Follow the same argument pattern as redis, which returns 1 / 0 as
    // indication if key existed in the dabase and was deleted.
    //
    if (fn) fn(undefined, exists ? 1 : 0);
  }

  /**
   * Nuke an item from the database.
   *
   * @param {String} key Key we need to look up.
   * @param {Function} fn Completion callback.
   * @api private
   */
  function del(key, fn) {
    var exists = has.call(memory.database, key);

    clearTimeout(memory.timers[key]);

    delete memory.database[key];
    delete memory.timers[key];

    //
    // Follow the same argument pattern as redis, which returns 1 / 0 as
    // indication if key existed in the dabase and was deleted.
    //
    if (fn) fn(undefined, exists ? 1 : 0);
  }

  /**
   * Nuke all items from the database.
   *
   * @param {Function} fn Completion callback.
   * @api private
   */
  function flush(fn) {
    Object.keys(memory.database).forEach(function each(key) {
      del(key);
    });

    fn(undefined, 'OK');
  }

  /**
   * Flush the entire dataset, flush everything.
   *
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('flush', function flushapi(done) {
    dynamis.execute(flush, flush, done);
  });

  /**
   * Get the key from memory.
   *
   * @param {String} key of value
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('get', function getapi(key, done) {
    dynamis.execute(get, get, key, done);
  });

  /**
   * Store value with key in memory.
   *
   * @param {String} key of value
   * @param {Mixed} value content to store
   * @param {Number} ttl optional time to live
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('set', function setapi(key, value, ttl, done) {
    if ('function' === typeof ttl) {
      done = ttl;
      ttl = 0;
    }

    dynamis.execute(set, set, key, value, ttl, done);
  });

  /**
   * Set the time to live for the key.
   *
   * @param {String} key of value
   * @param {Number} ttl optional time to live
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('expire', function expireapi(key, ttl, done) {
    dynamis.execute(expire, expire, key, ttl, done);
  });

  /**
   * Remove the value from memory.
   *
   * @param {String} key to delete
   * @param {Function} done completion callback
   * @api public
   */
  dynamis.api('del', function delapi(key, done) {
    dynamis.execute(del, del, key, done);
  });

  return memory;
});

//
// Expose the module.
//
module.exports = Memory;
<|endoftext|>