<commit_before>export { init, testCorrectness, disposeResources };

import * as Pool from "../util/Pool.js";
import * as Recyclable from "../util/Recyclable.js";
//import * as RandTools from "../util/RandTools.js";
import * as ValueDesc from "../Unpacker/ValueDesc.js";
import * as Weights from "../Unpacker/Weights.js";
import * as ActivationEscaping from "../Conv/ActivationEscaping.js";
import * as BoundsArraySet from "../Conv/BoundsArraySet.js";
import * as Embedding from "../Conv/Embedding.js";
import * as Embedding_Reference from "./Ref/Embedding_Reference.js";
import * as Embedding_TestParams from "./Ref/Embedding_TestParams.js";
import * as ImageSourceBag from "./Ref/ImageSourceBag.js";
import * as NumberImage from "./Ref/NumberImage.js";
import * as BatchIdCalculator from "./BatchIdCalculator.js";

/**
 * Test CNN Embedding.
 *
 * @see {@link https://www.measurethat.net/Benchmarks/Show/15055/249/colorfulcakechen-cnn-embedding-af287a20950912b74dc087705bab}
 */

/**
 * A test set.
 */
class HeightWidthDepth {

  /**
   * @param {number} height            image height
   * @param {number} width             image width
   * @param {number} depth             image channel count
   */
  constructor( height, width, depth ) {

    this.disposeResources();

    this.height = height;
    this.width = width;
    this.depth = depth;

    this.valueCount = height * width * depth;
  }

  disposeResources() {
    if ( this.dataTensor3dArray ) {
      tf.dispose( this.dataTensor3dArray );
      this.dataTensor3dArray = null;
    }

    this.embedding_PerformanceTest_release();
  }

  embedding_PerformanceTest_init() {

    // Release dataTensor3d too. Because perofrmance testing uses larger different input image from correctness testing.
    this.disposeResources();

    // Larger input image for performance testing.
    let inputTensorCount = 1;
    this.testPerformance_NumberImageArray = Recyclable.OwnerArray.Pool.get_or_create_by( inputTensorCount );
    this.dataTensor3dArray = tf.tidy( () => {
      const randomOffsetMin = 0, randomOffsetMax = 0, divisorForRemainder = 256;

//!!! (2022/07/26 Remarked) Use create_bySequenceRandom() instead.
//      let inputScaleBoundsArray = ActivationEscaping.ScaleBoundsArray.Pool.get_or_create_by( this.depth );

      let dataTensor3dArray = new Array( inputTensorCount );

      let shape = [ this.height, this.width, this.depth ];
      let elementCount = tf.util.sizeFromShape( shape );

      for ( let i = 0; i < dataTensor3dArray.length; ++i ) {

//!!! (2022/07/26 Remarked) Use create_bySequenceRandom() instead.
//         let numberBegin = ( i * elementCount );
//         let numberEnd = numberBegin + elementCount;
//
//         let image = this.testPerformance_NumberImageArray[ i ] = NumberImage.Base.Pool.get_or_create_by(
//           this.height, this.width, this.depth, undefined,
//           inputScaleBoundsArray, null, BoundsArraySet.InputsOutputs, Weights.Base.ValueBounds );
//
//         for ( let j = 0; j < elementCount; ++j ) {
//           image.dataArray[ j ] = numberBegin + j;
//         }

        let image = this.testPerformance_NumberImageArray[ i ] = NumberImage.Base.create_bySequenceRandom(
          this.height, this.width, this.depth,
          randomOffsetMin, randomOffsetMax, divisorForRemainder
        );

        dataTensor3dArray[ i ] = tf.tensor( image.dataArray, shape, "int32" );
      }

//!!! (2022/07/26 Remarked) Use create_bySequenceRandom() instead.
//      inputScaleBoundsArray.disposeResources_and_recycleToPool();
//      inputScaleBoundsArray = null;

      return dataTensor3dArray;
    });

    let vocabularyCountPerInputChannel = 256;
    let bEmbedVocabularyId = true;

    // input_height, input_width, input_channelCount,
    // channelMultiplier, vocabularyCountPerInputChannel, bEmbedVocabularyId,
    // bKeepInputTensor
    //
    // The embedding performance testing should:
    //   - ( bKeepInputTensor == true ). Otherwise, the this.dataTensor3d will be destroyed.
    //

    if ( this.testCaseMap )
      this.testCaseMap.clear();
    else
      this.testCaseMap = new Map();

    // Test Case 1: (AddGatherReshape, ( channelMultiplier == 1 ))
    this.testCaseMap.set( "AddGatherReshape_channelMultiplier_1", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 1,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 2: (SplitReshapeGatherConcat, ( channelMultiplier == 1 ))
    this.testCaseMap.set( "SplitReshapeGatherConcat_channelMultiplier_1", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 1,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 3: (AddGatherReshape, ( channelMultiplier == 2 ))
    this.testCaseMap.set( "AddGatherReshape_channelMultiplier_2", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 2,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 4: (SplitReshapeGatherConcat, ( channelMultiplier == 2 ))
    this.testCaseMap.set( "SplitReshapeGatherConcat_channelMultiplier_2", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 2,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 5: (AddGatherReshape, ( channelMultiplier == 4 ))
    this.testCaseMap.set( "AddGatherReshape_channelMultiplier_4", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 4,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 6: (SplitReshapeGatherConcat, ( channelMultiplier == 4 ))
    this.testCaseMap.set( "SplitReshapeGatherConcat_channelMultiplier_4", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 4,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 7: (AddGatherReshape, ( channelMultiplier == 8 ))
    this.testCaseMap.set( "AddGatherReshape_channelMultiplier_8", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 8,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 8: (SplitReshapeGatherConcat, ( channelMultiplier == 8 ))
    this.testCaseMap.set( "SplitReshapeGatherConcat_channelMultiplier_8", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 8,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Create the different Embedding objects for performance testing.
    {
      let i = 0;
      for ( let name_testCase of this.testCaseMap.entries() ) {
        let name = name_testCase[ 0 ];
        let testCase = name_testCase[ 1 ];
        try {
          if ( !testCase.embedding ) {
            let EmbeddingClass;
            {
              if ( ( i % 2 ) == 0 )
                EmbeddingClass = Embedding.AddGatherReshape;
              else
                EmbeddingClass = Embedding.SplitReshapeGatherConcat;
            }

            testCase.embedding = Embedding_Reference.Base.Embedding_create(
              EmbeddingClass, testCase.testParams,
              this.testPerformance_NumberImageArray[ 0 ].boundsArraySet.output0 );
          }
        } catch ( e ) {
          debugger;
          throw e;
        }

        console.log( `Embedding.${name}: tensorWeightCount = { Extracted: ${testCase.embedding.tensorWeightCountExtracted}, `
          + `Total: ${testCase.embedding.tensorWeightCountTotal} }` );

        ++i;
      }
    }
  }

  embedding_PerformanceTest_release() {
    if ( this.testCaseMap ) {
      for ( let name_testCase of this.testCaseMap.entries() ) {
        let name = name_testCase[ 0 ];
        let testCase = name_testCase[ 1 ];
        if ( testCase.embedding ) {
          testCase.embedding.disposeResources_and_recycleToPool();
        }
      }
      this.testCaseMap.clear();
    }

    if ( this.testPerformance_NumberImageArray ) {
      this.testPerformance_NumberImageArray.disposeResources_and_recycleToPool();
      this.testPerformance_NumberImageArray = null;
    }
  }

  /** Test apply by Xxx */
  testEmbedding_ByName( testCaseName ) {
    let testCase = this.testCaseMap.get( testCaseName );
    let embedding = testCase.embedding;
    let outputTensor3d = embedding.apply( this.dataTensor3dArray[ 0 ] );
    tf.dispose( outputTensor3d );
  }

  /** Testing whether the results of different implementation are the same. */
  * testCorrectness() {

    {
      let pool_all_issuedCount_before = Pool.All.issuedCount;

      yield;

      {
        let memoryInfo_testCorrectness_before = tf.memory(); // Test memory leakage of imageSourceBag.

        {
          // Note: imageSourceBag should not be created outside tidy() because tidy() will dispose tensors
          //       dynamically created in them.
          let imageSourceBag = ImageSourceBag.Base.Pool.get_or_create_by( "int32" );

          let testParams = Embedding_TestParams.Base.Pool.get_or_create_by();
          let testParamsGenerator = testParams.ParamsGenerator();
          let testReference = Embedding_Reference.Base.Pool.get_or_create_by();

          let batchIdCalculator = new BatchIdCalculator.Base( 100 * 1000 );

          try {
            for ( testParams of testParamsGenerator ) {
              let bDisplayed = batchIdCalculator.checkAndDisplay( testParams.id );
              if ( bDisplayed )
                yield; // Since just entering a new batch section, take a break so that memory garbage collector could be activated to work.

              testReference.testCorrectness( imageSourceBag, testParams );
            }

          } catch ( e ) {
            let backendName = tf.getBackend();
            let msg = `jsPerf_Embedding.js: testCorrectness(): backendName=${backendName}, `
              + `Embedding, (yieldCount == ${testParams.yieldCount}), testParams.id == ${testParams.id}`;

            console.log( msg );
            alert( `${msg}\n${e}` );

            //debugger;
            throw e;
          }

          batchIdCalculator.checkAndDisplay( testParams.id );

          testReference.disposeResources_and_recycleToPool(); testReference = null;
          testParams.disposeResources_and_recycleToPool(); testParams = null;
          imageSourceBag.disposeResources_and_recycleToPool(); imageSourceBag = null;
        }

        let memoryInfo_testCorrectness_after = tf.memory();

        if ( memoryInfo_testCorrectness_after.numTensors != memoryInfo_testCorrectness_before.numTensors )
          throw Error( `testCorrectness() memory leak. `
            + `result tensor count (${memoryInfo_testCorrectness_after.numTensors}) `
            + `should be (${memoryInfo_testCorrectness_before.numTensors} `
            + `` );
      }

      Pool.Asserter.assert_Pool_issuedCount( "jsPerf_Block.HeightWidthDepth.testCorrectness()", pool_all_issuedCount_before );
      yield;
    }

    try {
      // After correctness testing done, create all Embedding for performance testing.
      this.embedding_PerformanceTest_init();
    } catch ( e ) {
      debugger;
      throw e;
    }
  }

}

function init() {
  //console.log("jsPerf_Embedding.js, init()");

  disposeResources();

  let depth = 4;

  // Using mobile phone's resolution ( 1080 * 2160 ) will crash the computer.
  // Using ( 1 / 10 ) of computer screen ( 1080 * 1920 ).
  globalThis.testSet_108x192x4 = new HeightWidthDepth( 108, 192, depth ); // height, width, depth

  globalThis.testSet_All = [
    globalThis.testSet_108x192x4
  ];
}

function* testCorrectness() {
  for ( let i = 0; i < globalThis.testSet_All.length; ++i ) {
    let testSet = globalThis.testSet_All[ i ];
    yield* testSet.testCorrectness();
  }
}

function disposeResources() {
  if ( globalThis.testSet_All ) {
    for ( let i = 0; i < globalThis.testSet_All.length; ++i ) {
      let testSet = globalThis.testSet_All[ i ];
      if ( testSet )
        testSet.disposeResources();
    }

    globalThis.testSet_All = null;
  }

  globalThis.testSet_108x192x4
    = null;
}
<commit_msg>benchmark url<commit_after>export { init, testCorrectness, disposeResources };

import * as Pool from "../util/Pool.js";
import * as Recyclable from "../util/Recyclable.js";
//import * as RandTools from "../util/RandTools.js";
import * as ValueDesc from "../Unpacker/ValueDesc.js";
import * as Weights from "../Unpacker/Weights.js";
import * as ActivationEscaping from "../Conv/ActivationEscaping.js";
import * as BoundsArraySet from "../Conv/BoundsArraySet.js";
import * as Embedding from "../Conv/Embedding.js";
import * as Embedding_Reference from "./Ref/Embedding_Reference.js";
import * as Embedding_TestParams from "./Ref/Embedding_TestParams.js";
import * as ImageSourceBag from "./Ref/ImageSourceBag.js";
import * as NumberImage from "./Ref/NumberImage.js";
import * as BatchIdCalculator from "./BatchIdCalculator.js";

/**
 * Test CNN Embedding.
 *
 * @see {@link https://www.measurethat.net/Benchmarks/Show/11003/164/colorfulcakechen-cnn-embedding-dba952b508d00e7999049015}
 */

/**
 * A test set.
 */
class HeightWidthDepth {

  /**
   * @param {number} height            image height
   * @param {number} width             image width
   * @param {number} depth             image channel count
   */
  constructor( height, width, depth ) {

    this.disposeResources();

    this.height = height;
    this.width = width;
    this.depth = depth;

    this.valueCount = height * width * depth;
  }

  disposeResources() {
    if ( this.dataTensor3dArray ) {
      tf.dispose( this.dataTensor3dArray );
      this.dataTensor3dArray = null;
    }

    this.embedding_PerformanceTest_release();
  }

  embedding_PerformanceTest_init() {

    // Release dataTensor3d too. Because perofrmance testing uses larger different input image from correctness testing.
    this.disposeResources();

    // Larger input image for performance testing.
    let inputTensorCount = 1;
    this.testPerformance_NumberImageArray = Recyclable.OwnerArray.Pool.get_or_create_by( inputTensorCount );
    this.dataTensor3dArray = tf.tidy( () => {
      const randomOffsetMin = 0, randomOffsetMax = 0, divisorForRemainder = 256;

//!!! (2022/07/26 Remarked) Use create_bySequenceRandom() instead.
//      let inputScaleBoundsArray = ActivationEscaping.ScaleBoundsArray.Pool.get_or_create_by( this.depth );

      let dataTensor3dArray = new Array( inputTensorCount );

      let shape = [ this.height, this.width, this.depth ];
      let elementCount = tf.util.sizeFromShape( shape );

      for ( let i = 0; i < dataTensor3dArray.length; ++i ) {

//!!! (2022/07/26 Remarked) Use create_bySequenceRandom() instead.
//         let numberBegin = ( i * elementCount );
//         let numberEnd = numberBegin + elementCount;
//
//         let image = this.testPerformance_NumberImageArray[ i ] = NumberImage.Base.Pool.get_or_create_by(
//           this.height, this.width, this.depth, undefined,
//           inputScaleBoundsArray, null, BoundsArraySet.InputsOutputs, Weights.Base.ValueBounds );
//
//         for ( let j = 0; j < elementCount; ++j ) {
//           image.dataArray[ j ] = numberBegin + j;
//         }

        let image = this.testPerformance_NumberImageArray[ i ] = NumberImage.Base.create_bySequenceRandom(
          this.height, this.width, this.depth,
          randomOffsetMin, randomOffsetMax, divisorForRemainder
        );

        dataTensor3dArray[ i ] = tf.tensor( image.dataArray, shape, "int32" );
      }

//!!! (2022/07/26 Remarked) Use create_bySequenceRandom() instead.
//      inputScaleBoundsArray.disposeResources_and_recycleToPool();
//      inputScaleBoundsArray = null;

      return dataTensor3dArray;
    });

    let vocabularyCountPerInputChannel = 256;
    let bEmbedVocabularyId = true;

    // input_height, input_width, input_channelCount,
    // channelMultiplier, vocabularyCountPerInputChannel, bEmbedVocabularyId,
    // bKeepInputTensor
    //
    // The embedding performance testing should:
    //   - ( bKeepInputTensor == true ). Otherwise, the this.dataTensor3d will be destroyed.
    //

    if ( this.testCaseMap )
      this.testCaseMap.clear();
    else
      this.testCaseMap = new Map();

    // Test Case 1: (AddGatherReshape, ( channelMultiplier == 1 ))
    this.testCaseMap.set( "AddGatherReshape_channelMultiplier_1", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 1,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 2: (SplitReshapeGatherConcat, ( channelMultiplier == 1 ))
    this.testCaseMap.set( "SplitReshapeGatherConcat_channelMultiplier_1", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 1,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 3: (AddGatherReshape, ( channelMultiplier == 2 ))
    this.testCaseMap.set( "AddGatherReshape_channelMultiplier_2", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 2,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 4: (SplitReshapeGatherConcat, ( channelMultiplier == 2 ))
    this.testCaseMap.set( "SplitReshapeGatherConcat_channelMultiplier_2", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 2,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 5: (AddGatherReshape, ( channelMultiplier == 4 ))
    this.testCaseMap.set( "AddGatherReshape_channelMultiplier_4", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 4,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 6: (SplitReshapeGatherConcat, ( channelMultiplier == 4 ))
    this.testCaseMap.set( "SplitReshapeGatherConcat_channelMultiplier_4", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 4,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 7: (AddGatherReshape, ( channelMultiplier == 8 ))
    this.testCaseMap.set( "AddGatherReshape_channelMultiplier_8", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 8,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Test Case 8: (SplitReshapeGatherConcat, ( channelMultiplier == 8 ))
    this.testCaseMap.set( "SplitReshapeGatherConcat_channelMultiplier_8", { testParams:
      ( new Embedding_TestParams.Base() ).set_byParamsScattered(
        this.height, this.width, this.depth, 8,
        vocabularyCountPerInputChannel, bEmbedVocabularyId,
        true
      ) } );

    // Create the different Embedding objects for performance testing.
    {
      let i = 0;
      for ( let name_testCase of this.testCaseMap.entries() ) {
        let name = name_testCase[ 0 ];
        let testCase = name_testCase[ 1 ];
        try {
          if ( !testCase.embedding ) {
            let EmbeddingClass;
            {
              if ( ( i % 2 ) == 0 )
                EmbeddingClass = Embedding.AddGatherReshape;
              else
                EmbeddingClass = Embedding.SplitReshapeGatherConcat;
            }

            testCase.embedding = Embedding_Reference.Base.Embedding_create(
              EmbeddingClass, testCase.testParams,
              this.testPerformance_NumberImageArray[ 0 ].boundsArraySet.output0 );
          }
        } catch ( e ) {
          debugger;
          throw e;
        }

        console.log( `Embedding.${name}: tensorWeightCount = { Extracted: ${testCase.embedding.tensorWeightCountExtracted}, `
          + `Total: ${testCase.embedding.tensorWeightCountTotal} }` );

        ++i;
      }
    }
  }

  embedding_PerformanceTest_release() {
    if ( this.testCaseMap ) {
      for ( let name_testCase of this.testCaseMap.entries() ) {
        let name = name_testCase[ 0 ];
        let testCase = name_testCase[ 1 ];
        if ( testCase.embedding ) {
          testCase.embedding.disposeResources_and_recycleToPool();
        }
      }
      this.testCaseMap.clear();
    }

    if ( this.testPerformance_NumberImageArray ) {
      this.testPerformance_NumberImageArray.disposeResources_and_recycleToPool();
      this.testPerformance_NumberImageArray = null;
    }
  }

  /** Test apply by Xxx */
  testEmbedding_ByName( testCaseName ) {
    let testCase = this.testCaseMap.get( testCaseName );
    let embedding = testCase.embedding;
    let outputTensor3d = embedding.apply( this.dataTensor3dArray[ 0 ] );
    tf.dispose( outputTensor3d );
  }

  /** Testing whether the results of different implementation are the same. */
  * testCorrectness() {

    {
      let pool_all_issuedCount_before = Pool.All.issuedCount;

      yield;

      {
        let memoryInfo_testCorrectness_before = tf.memory(); // Test memory leakage of imageSourceBag.

        {
          // Note: imageSourceBag should not be created outside tidy() because tidy() will dispose tensors
          //       dynamically created in them.
          let imageSourceBag = ImageSourceBag.Base.Pool.get_or_create_by( "int32" );

          let testParams = Embedding_TestParams.Base.Pool.get_or_create_by();
          let testParamsGenerator = testParams.ParamsGenerator();
          let testReference = Embedding_Reference.Base.Pool.get_or_create_by();

          let batchIdCalculator = new BatchIdCalculator.Base( 100 * 1000 );

          try {
            for ( testParams of testParamsGenerator ) {
              let bDisplayed = batchIdCalculator.checkAndDisplay( testParams.id );
              if ( bDisplayed )
                yield; // Since just entering a new batch section, take a break so that memory garbage collector could be activated to work.

              testReference.testCorrectness( imageSourceBag, testParams );
            }

          } catch ( e ) {
            let backendName = tf.getBackend();
            let msg = `jsPerf_Embedding.js: testCorrectness(): backendName=${backendName}, `
              + `Embedding, (yieldCount == ${testParams.yieldCount}), testParams.id == ${testParams.id}`;

            console.log( msg );
            alert( `${msg}\n${e}` );

            //debugger;
            throw e;
          }

          batchIdCalculator.checkAndDisplay( testParams.id );

          testReference.disposeResources_and_recycleToPool(); testReference = null;
          testParams.disposeResources_and_recycleToPool(); testParams = null;
          imageSourceBag.disposeResources_and_recycleToPool(); imageSourceBag = null;
        }

        let memoryInfo_testCorrectness_after = tf.memory();

        if ( memoryInfo_testCorrectness_after.numTensors != memoryInfo_testCorrectness_before.numTensors )
          throw Error( `testCorrectness() memory leak. `
            + `result tensor count (${memoryInfo_testCorrectness_after.numTensors}) `
            + `should be (${memoryInfo_testCorrectness_before.numTensors} `
            + `` );
      }

      Pool.Asserter.assert_Pool_issuedCount( "jsPerf_Block.HeightWidthDepth.testCorrectness()", pool_all_issuedCount_before );
      yield;
    }

    try {
      // After correctness testing done, create all Embedding for performance testing.
      this.embedding_PerformanceTest_init();
    } catch ( e ) {
      debugger;
      throw e;
    }
  }

}

function init() {
  //console.log("jsPerf_Embedding.js, init()");

  disposeResources();

  let depth = 4;

  // Using mobile phone's resolution ( 1080 * 2160 ) will crash the computer.
  // Using ( 1 / 10 ) of computer screen ( 1080 * 1920 ).
  globalThis.testSet_108x192x4 = new HeightWidthDepth( 108, 192, depth ); // height, width, depth

  globalThis.testSet_All = [
    globalThis.testSet_108x192x4
  ];
}

function* testCorrectness() {
  for ( let i = 0; i < globalThis.testSet_All.length; ++i ) {
    let testSet = globalThis.testSet_All[ i ];
    yield* testSet.testCorrectness();
  }
}

function disposeResources() {
  if ( globalThis.testSet_All ) {
    for ( let i = 0; i < globalThis.testSet_All.length; ++i ) {
      let testSet = globalThis.testSet_All[ i ];
      if ( testSet )
        testSet.disposeResources();
    }

    globalThis.testSet_All = null;
  }

  globalThis.testSet_108x192x4
    = null;
}
<|endoftext|>


<commit_before>'use strict';

angular.module('classBrowserUHApp.offeredclass', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/offeredclass', {
        templateUrl: 'views/offeredclass/offeredclass.html',
        controller: 'OfferedClassCtrl'
    });
}])
.controller('OfferedClassCtrl', ['$scope', '$http', '$q', '$rootScope', function ($scope, $http, $q, $rootScope) {
    var deleteModel = function() {
        [].slice.call(arguments).forEach(function(arg) {
            delete $scope[arg];
        });
    };

    $rootScope.httpService.getData('resources/format.json').then(function(result) {
        $scope.format = result;
    });

    $rootScope.httpService.getData('resources/terms.json').then(function(result) {
        $scope.terms = result;
    });

    $rootScope.httpService.getData('resources/status.json').then(function(result) {
        $scope.status = result;
    });

    $rootScope.httpService.getData('resources/session.json').then(function(result) {
        $scope.session = result;
    });

    $rootScope.httpService.getData('resources/subjects.json').then(function(result) {
        $scope.departments = result;
    });

    $rootScope.httpService.getData('resources/buildings.json').then(function(result) {
        $scope.buildings = result;
    });

    $rootScope.httpService.getData('resources/locations.json').then(function(result) {
        $scope.locations = result;
    });

    $rootScope.httpService.getData('resources/component.json').then(function(result) {
        $scope.component = result;
    });

    $rootScope.httpService.getData('resources/creditHours.json').then(function(result) {
        $scope.creditHours = result;
    });

    $rootScope.httpService.getData('resources/coreCategories.json').then(function(result) {
        $scope.coreCategories = result;
    });

    $rootScope.httpService.getData('resources/weekendU.json').then(function(result) {
        $scope.weekendU = result;
    });

    $scope.clearForms = function() {
        deleteModel('weekendUModel', 'coreModel');
    };

}]);
<commit_msg>Refactored how available options for dropdown lists are set.<commit_after>'use strict';

angular.module('classBrowserUHApp.offeredclass', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/offeredclass', {
        templateUrl: 'views/offeredclass/offeredclass.html',
        controller: 'OfferedClassCtrl'
    });
}])
.controller('OfferedClassCtrl', ['$scope', '$http', '$q', '$rootScope', '$parse', function ($scope, $http, $q, $rootScope, $parse) {
    var allJSONAndScopeNames = [
        {
            "path": "resources/format.json",
            "scopeName": "format"
        },
        {
            "path": "resources/terms.json",
            "scopeName": "terms"
        },
        {
            "path": "resources/status.json",
            "scopeName": "status"
        },
        {
            "path": "resources/session.json",
            "scopeName": "session"
        },
        {
            "path": "resources/subjects.json",
            "scopeName": "departments"
        },
        {
            "path": "resources/buildings.json",
            "scopeName": "buildings"
        },
        {
            "path": "resources/locations.json",
            "scopeName": "locations"
        },
        {
            "path": "resources/component.json",
            "scopeName": "component"
        },
        {
            "path": "resources/creditHours.json",
            "scopeName": "creditHours"
        },
        {
            "path": "resources/weekendU.json",
            "scopeName": "weekendU"
        },
        {
            "path": "resources/coreCategories.json",
            "scopeName": "coreCategories"
        }
    ];

    var deleteModel = function() {
        [].slice.call(arguments).forEach(function(arg) {
            delete $scope[arg];
        });
    };

    var setScopeVariableFromJSON = function(filePath, scopeVariable) {
        $rootScope.httpService.getData(filePath).then(function(result) {
            $parse(scopeVariable).assign($scope, result);
        });
    };

    allJSONAndScopeNames.forEach(function(e) {
       setScopeVariableFromJSON(e.path, e.scopeName);
    });

    $scope.clearForms = function() {
        deleteModel('weekendUModel', 'coreModel');
    };

}]);
<|endoftext|>


<commit_before>'use strict'

const log = require('util').debuglog('cloudfoundry-actuator-middleware');

const DiscoveryEndpoint = require('./endpoints/discovery')
const HealthEndpoint = require('./endpoints/health')
const InfoEndpoint = require('./endpoints/info')

/**
 *
 */
class Registry {

    constructor(options) {
        this._endpoints = {}
        this.__addEndpoint(new DiscoveryEndpoint(this._endpoints))
        this.__addEndpoint(new HealthEndpoint())
        this.__addEndpoint(new InfoEndpoint())
    }

    /**
     *
     * @param {Endpoint} endpoint
     */
    __addEndpoint(endpoint) {
        this._endpoints[endpoint.getPath()] = endpoint
    }

    /**
     *
     * @param {http.ClientRequest} req
     * @returns {Endpoint} the endpoint, that is registered to handle the incoming request
     */
    getEndpoint(req) {
        let path = req.path
        if (!path.endsWith('/')) {
            path += '/'
        }

        log('getEndpoint %s', path)

        return this._endpoints[path]
    }
}

module.exports = Registry<commit_msg>docs: make addEndpoint private<commit_after>'use strict'

const log = require('util').debuglog('cloudfoundry-actuator-middleware');

const DiscoveryEndpoint = require('./endpoints/discovery')
const HealthEndpoint = require('./endpoints/health')
const InfoEndpoint = require('./endpoints/info')

/**
 *
 */
class Registry {

    constructor(options) {
        this._endpoints = {}
        this.__addEndpoint(new DiscoveryEndpoint(this._endpoints))
        this.__addEndpoint(new HealthEndpoint())
        this.__addEndpoint(new InfoEndpoint())
    }

    /**
     *
     * @private
     * @param {Endpoint} endpoint
     */
    __addEndpoint(endpoint) {
        this._endpoints[endpoint.getPath()] = endpoint
    }

    /**
     *
     * @param {http.ClientRequest} req
     * @returns {Endpoint} the endpoint, that is registered to handle the incoming request
     */
    getEndpoint(req) {
        let path = req.path
        if (!path.endsWith('/')) {
            path += '/'
        }

        log('getEndpoint %s', path)

        return this._endpoints[path]
    }
}

module.exports = Registry<|endoftext|>


<commit_before>var http = require("http");
var guid = require("guid");
var port = 8080;

function createArray(length, valueSelector) {
    var array = [];
    for ( var i = 0; i < length; ++i ) {
        array.push(valueSelector());
    }
    return array;
}

function createPixel(x, y, r, g, b) {
    return [
        x + 1,
        y + 1,
        r * 255,
        g * 255,
        b * 255
    ];
}

var Client = function(id, width, height) {
    var depthBuffer = createArray(width, function() {
        return createArray(height, function() {
            return Number.MAX_SAFE_INTEGER;
        });
    });
    this.id = id;

    this.request = function(dx, dy, dz) {
        var response = [];
        response.push(createPixel(0, 0, 1, 0, 0));
        response.push(createPixel(width - 1, 0, 0, 1, 0));
        response.push(createPixel(width - 1, height - 1, 0, 0, 1));
        response.push(createPixel(0, height - 1, 0, 1, 1, 0));
        for ( var x = width / 2 - 10; x < width / 2 + 10; ++x ) {
            for ( var y = height / 2 - 10; y < height / 2 + 10; ++y ) {
                response.push(createPixel(x, y, 0, 1, 1));
            }
        }
        return response;
    };
};

var clients = {};

function randomToken() {
    var token = guid.create().toString();
    if ( clients.hasOwnProperty(token) ) {
        return randomToken();
    } else {
        return token;
    }
}

function fullRegex(str, regex) {
    var res = str.match(regex);
    return res != null && res.length == 1 && res[0].length == str.length;
}

function serializeCSV(array) {
    var csv = "";
    for ( var i = 0; i < array.length; ++i ) {
        for ( var j = 0; j < array[i].length; ++j ) {
            if ( j > 0 ) {
                csv += ",";
            }
            csv += array[i][j];
        }
        csv += "\n";
    }
    return csv;
}

function toInt(str) {
    return parseInt(str.replace("\"", ""));
}

function toFloat(str) {
    return parseFloat(str.replace("\"", ""));
}

var server = http.createServer(function(req, res) {
    function send(data) {
        res.end(data);
        console.log("> %s", data);
    }
    console.log("Request to %s", req.url);
    req.on("data", function(chunk) {
        var str = chunk.toString();
        console.log("< %s", str);
        var args = str.split(",");
        if ( req.url == "/login" && args.length == 2 ) {
            var token = randomToken();
            clients[token] = new Client(token, toInt(args[0]), toInt(args[1]));
            send(token);
        } else if ( fullRegex(req.url, /\/frame\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/) && args.length == 3 ) {
            var token = req.url.substr(7);
            if ( clients.hasOwnProperty(token) ) {
                send(serializeCSV(clients[token].request(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]))));
            } else {
                send("Invalid token");
            }
        } else {
            send("Invalid protocol");
        }
    });
});

server.listen(port, function() {
    console.log("Server started on http://0.0.0.0:%d/", port);
});
<commit_msg>Added color changing with HSV<commit_after>var http = require("http");
var guid = require("guid");
var onecolor = require("onecolor");
var port = 8080;
var log = true;

function createArray(length, valueSelector) {
    var array = [];
    for ( var i = 0; i < length; ++i ) {
        array.push(valueSelector());
    }
    return array;
}

/*
function createPixel(x, y, r, g, b) {
    return [
        x + 1,
        y + 1,
        r * 255,
        g * 255,
        b * 255
    ];
}
*/

function createPixel(x, y, color) {
    return [
        x + 1,
        y + 1,
        color.red() * 255,
        color.green() * 255,
        color.blue() * 255
    ];
}

var Client = function(id, width, height) {
    var depthBuffer = createArray(width, function() {
        return createArray(height, function() {
            return Number.MAX_SAFE_INTEGER;
        });
    });
    var color = new onecolor.HSV(1, 1, 1, 1);
    this.id = id;

    this.request = function(dx, dy, dz) {
        var response = [];
        color = color.hue(0.05, true);
        /*
        response.push(createPixel(0, 0, 1, 0, 0));
        response.push(createPixel(width - 1, 0, 0, 1, 0));
        response.push(createPixel(width - 1, height - 1, 0, 0, 1));
        response.push(createPixel(0, height - 1, 0, 1, 1, 0));
        */
        for ( var x = width / 2 - 10; x < width / 2 + 10; ++x ) {
            for ( var y = height / 2 - 10; y < height / 2 + 10; ++y ) {
                response.push(createPixel(x, y, color));
            }
        }
        return response;
    };
};

var clients = {};

function randomToken() {
    var token = guid.create().toString();
    if ( clients.hasOwnProperty(token) ) {
        return randomToken();
    } else {
        return token;
    }
}

function fullRegex(str, regex) {
    var res = str.match(regex);
    return res != null && res.length == 1 && res[0].length == str.length;
}

function serializeCSV(array) {
    var csv = "";
    for ( var i = 0; i < array.length; ++i ) {
        for ( var j = 0; j < array[i].length; ++j ) {
            if ( j > 0 ) {
                csv += ",";
            }
            csv += array[i][j];
        }
        csv += "\n";
    }
    return csv;
}

function toInt(str) {
    return parseInt(str.replace("\"", ""));
}

function toFloat(str) {
    return parseFloat(str.replace("\"", ""));
}

var server = http.createServer(function(req, res) {
    function send(data) {
        res.end(data);
        if ( log ) {
            console.log("> %s", data);
        }
    }
    if ( log ) {
        console.log("Request to %s", req.url);
    }
    req.on("data", function(chunk) {
        var str = chunk.toString();
        if ( log ) {
            console.log("< %s", str);
        }
        var args = str.split(",");
        if ( req.url == "/login" && args.length == 2 ) {
            var token = randomToken();
            clients[token] = new Client(token, toInt(args[0]), toInt(args[1]));
            send(token);
        } else if ( fullRegex(req.url, /\/frame\/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/) && args.length == 3 ) {
            var token = req.url.substr(7);
            if ( clients.hasOwnProperty(token) ) {
                send(serializeCSV(clients[token].request(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]))));
            } else {
                send("Invalid token");
            }
        } else {
            send("Invalid protocol");
        }
    });
});

server.listen(port, function() {
    console.log("Server started on http://0.0.0.0:%d/", port);
});
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash'),
    async = require('async'),
    AdminForm = require('./forms/AdminForm'),
    dependencies = require('./dependencies'),
    log = require('nodestrum').logFor('formage');

var LIST_EXCLUDED_FIELDS = ['order', '_id', 'show', '__v'];

/**
 *
 * @constructor
 */
function ModelRegistry(adapter, models, options) {
    this.models = {};
    this.adapter = adapter;
    this.root = options.root || options.route;
    this.title = options.title;
    this.default_section = options.default_section;
    this.version = require('../package.json').version;

    _.forEach(models, this._registerModel.bind(this));
}

ModelRegistry.prototype.getDefaultFieldList = function getDefaultFieldList(model) {
    var list_populate = [];
    var list = this.adapter.getPaths(model).map(function (options) {
        if (!options.type || !options.type.name) return null;
        if (~LIST_EXCLUDED_FIELDS.indexOf(options.db_path)) return null;
        if (options.type.name == 'File') return null;
        if (options.ref) {
            list_populate.push(options.db_path);
        }
        return options.db_path;
    }).compact().valueOf();
    list.length = Math.min(list.length, 3);
    return {list_populate: list_populate, list: list};
};

ModelRegistry.prototype._registerModel = function (model, modelName) {
    this.registerModel(model, modelName);
};
ModelRegistry.prototype.registerModel = function (model, modelName, adhoc_opts) {
    if (modelName[0] === '_') return;

    model = this.adapter.adaptModel(model, modelName);

    var options = _.extend({
        cloneable: true,
        is_single: false,
        form: AdminForm,
        post: _.identity
    }, model.formage, model.schema.formage, adhoc_opts);

    if (!('list' in options)) {
        var list_defaults = this.getDefaultFieldList(model);
        options = _.extend(options, list_defaults);
    }

//    if (model.schema.paths.order) {
//        options.order_by = ['order'];
//        options.sortable = 'order';
//    }
    // legacy option mapping
    if (model.single || (model.formage && model.formage.single)) {
        options.is_single = true;
        console.error('formage: model.single is deprecated. Set schema.formage.is_single instead. At model', modelName);
    }

    var filters = buildModelFilters_fireAndForget(model, this.models, options.filters, this.adapter);
    model.label = model.label || modelName[0].toUpperCase() + modelName.slice(1).replace(/_/g, ' ');
    var modelConfig = this.models[modelName] = {
        model: model,
        filters: filters,
        modelName: modelName,
        options: options,
        search: options.search,
        label: options.label || model.label,
        fields: options.fields,
        is_single: options.is_single,
        actions: [] || options.actions,
        sortable: options.sortable,
        order_by: options.order_by,
        fieldsInTable: options.list
    };
    if (modelConfig.sortable) modelConfig.order_by = [modelConfig.sortable];
    this.adapter.Users.registerModelPermissions(modelName);
    if (!modelConfig.is_single) addDefaultModelActions(modelName, modelConfig, _.pluck(this.models, 'model'));

    log('registered model %s', modelName);
};

ModelRegistry.prototype.getAccessibleModels = function getAccessibleModels(user) {
    var out_models = _.filter(this.models).filter(function (out_model) {
        return user.hasPermissions(out_model.modelName, 'view') && !out_model.options.hideFromMain;
    });
    return out_models;
};

function buildModelFilters_fireAndForget(model, models, filters, adapter) {
    var output = [];
    if (!filters) return output;

    // TODO: support Juggling
    if (model.isJugglingDB) return output;

    var _paths = adapter.getPaths(model);
    process.nextTick(function () {
        filters.forEach(function (filter) {
            var options = _paths.find({db_path: filter});
            if (!options) return;
            model.collection.distinct(filter, function (err, results) {
                if (!results) return;
                results = _(results).flatten().unique().valueOf();
                if (results.length > 30) results.splice(5);
                if (!options.ref) {
                    output.push({
                        key: filter,
                        isString: options.type == String,
                        values: _.map(results, function (result) {return { value: result, text: result };})
                    });
                    return;
                }
                var dbmodel = models[options.ref].model;
                dbmodel.find().where('_id').in(results).exec(function (err, refs) {
                    if (!refs) return;
                    output.push({
                        key: filter,
                        isString: false,
                        values: _.map(refs, function (ref) { return { value: ref.id, text: ref.toString() }; })
                    });
                });
            });
        })
    });
    return output;
}

function addDefaultModelActions(name, modelConfig, models) {
    modelConfig.actions.push({
        id: 'delete',
        label: 'Delete',
        func: function (user, ids, callback) {
            //noinspection JSUnresolvedFunction
            async.map(
                ids,
                _.partial(dependencies.check, models, name),
                function (err, docs_with_deps) {
                    if (err) throw err;
                    docs_with_deps = _.object(docs_with_deps);
                    var with_deps = ids.filter(function (id) {return id in docs_with_deps;});
                    var no_dependencies = _.difference(ids, with_deps);
                    async.each(
                        no_dependencies,
                        function (id, cb) {
                            modelConfig.model.findById(id, function (err, doc) {
                                if (err) throw err;
                                doc.remove(cb)
                            });
                        },
                        function (err) {
                            if (err) throw err;
                            var goodLines = no_dependencies.map(function (id) {return 'document ' + id + ' was deleted.';});
                            goodLines.push('-----------------------------');
                            var errLines = _(docs_with_deps)
                                .map(function (deps, id) {
                                    var lines = dependencies.depsToLines(deps);
                                    if (_.isEmpty(lines)) return null;
                                    lines.unshift('*****');
                                    lines.unshift('document ' + id + ' has dependents:');
                                    lines.push('******');
                                    return lines;
                                })
                                .flatten()
                                .compact()
                                .valueOf();
                            return callback(null, goodLines.concat(errLines))
                        }
                    );
                }
            );
        }
    });
}

module.exports = ModelRegistry;
<commit_msg>fix for tingoose<commit_after>'use strict';
var _ = require('lodash'),
    async = require('async'),
    AdminForm = require('./forms/AdminForm'),
    dependencies = require('./dependencies'),
    log = require('nodestrum').logFor('formage');

var LIST_EXCLUDED_FIELDS = ['order', '_id', 'show', '__v'];

/**
 *
 * @constructor
 */
function ModelRegistry(adapter, models, options) {
    this.models = {};
    this.adapter = adapter;
    this.root = options.root || options.route;
    this.title = options.title;
    this.default_section = options.default_section;
    this.version = require('../package.json').version;

    _.forEach(models, this._registerModel.bind(this));
}

ModelRegistry.prototype.getDefaultFieldList = function getDefaultFieldList(model) {
    var list_populate = [];
    var list = this.adapter.getPaths(model).map(function (options) {
        if (!options.type || !options.type.name) return null;
        if (~LIST_EXCLUDED_FIELDS.indexOf(options.db_path)) return null;
        if (options.type.name == 'File') return null;
        if (options.ref) {
            list_populate.push(options.db_path);
        }
        return options.db_path;
    }).compact().valueOf();
    list.length = Math.min(list.length, 3);
    return {list_populate: list_populate, list: list};
};

ModelRegistry.prototype._registerModel = function (model, modelName) {
    this.registerModel(model, modelName);
};
ModelRegistry.prototype.registerModel = function (model, modelName, adhoc_opts) {
    if (modelName[0] === '_') return;

    model = this.adapter.adaptModel(model, modelName);

    var options = _.extend({
        cloneable: true,
        is_single: false,
        form: AdminForm,
        post: _.identity
    }, model.formage, model.schema.formage, adhoc_opts);

    if (!('list' in options)) {
        var list_defaults = this.getDefaultFieldList(model);
        options = _.extend(options, list_defaults);
    }

//    if (model.schema.paths.order) {
//        options.order_by = ['order'];
//        options.sortable = 'order';
//    }
    // legacy option mapping
    if (model.single || (model.formage && model.formage.single)) {
        options.is_single = true;
        console.error('formage: model.single is deprecated. Set schema.formage.is_single instead. At model', modelName);
    }

    var filters = buildModelFilters_fireAndForget(model, this.models, options.filters, this.adapter);
    model.label = model.label || modelName[0].toUpperCase() + modelName.slice(1).replace(/_/g, ' ');
    var modelConfig = this.models[modelName] = {
        model: model,
        filters: filters,
        modelName: modelName,
        options: options,
        search: options.search,
        label: options.label || model.label,
        fields: options.fields,
        is_single: options.is_single,
        actions: [] || options.actions,
        sortable: options.sortable,
        order_by: options.order_by,
        fieldsInTable: options.list
    };
    if (modelConfig.sortable) modelConfig.order_by = [modelConfig.sortable];
    this.adapter.Users.registerModelPermissions(modelName);
    if (!modelConfig.is_single) addDefaultModelActions(modelName, modelConfig, _.pluck(this.models, 'model'));

    log('registered model %s', modelName);
};

ModelRegistry.prototype.getAccessibleModels = function getAccessibleModels(user) {
    var out_models = _.filter(this.models).filter(function (out_model) {
        return user.hasPermissions(out_model.modelName, 'view') && !out_model.options.hideFromMain;
    });
    return out_models;
};

function buildModelFilters_fireAndForget(model, models, filters, adapter) {
    var output = [];
    if (!filters) return output;

    // TODO: support Juggling
    if (model.isJugglingDB) return output;

    var _paths = adapter.getPaths(model);
    process.nextTick(function () {
        filters.forEach(function (filter) {
            var options = _paths.find({db_path: filter});
            if (!options) return;
            model.find(filter).limit(31).exec(function (err, results) {
                if (!results) return;
                results = _(results).flatten().unique().valueOf();
                if (results.length > 30) results.splice(5);
                if (!options.ref) {
                    output.push({
                        key: filter,
                        isString: options.type == String,
                        values: _.map(results, function (result) {return { value: result, text: result };})
                    });
                    return;
                }
                var dbmodel = models[options.ref].model;
                dbmodel.find().where('_id').in(results).exec(function (err, refs) {
                    if (!refs) return;
                    output.push({
                        key: filter,
                        isString: false,
                        values: _.map(refs, function (ref) { return { value: ref.id, text: ref.toString() }; })
                    });
                });
            });
        })
    });
    return output;
}

function addDefaultModelActions(name, modelConfig, models) {
    modelConfig.actions.push({
        id: 'delete',
        label: 'Delete',
        func: function (user, ids, callback) {
            //noinspection JSUnresolvedFunction
            async.map(
                ids,
                _.partial(dependencies.check, models, name),
                function (err, docs_with_deps) {
                    if (err) throw err;
                    docs_with_deps = _.object(docs_with_deps);
                    var with_deps = ids.filter(function (id) {return id in docs_with_deps;});
                    var no_dependencies = _.difference(ids, with_deps);
                    async.each(
                        no_dependencies,
                        function (id, cb) {
                            modelConfig.model.findById(id, function (err, doc) {
                                if (err) throw err;
                                doc.remove(cb)
                            });
                        },
                        function (err) {
                            if (err) throw err;
                            var goodLines = no_dependencies.map(function (id) {return 'document ' + id + ' was deleted.';});
                            goodLines.push('-----------------------------');
                            var errLines = _(docs_with_deps)
                                .map(function (deps, id) {
                                    var lines = dependencies.depsToLines(deps);
                                    if (_.isEmpty(lines)) return null;
                                    lines.unshift('*****');
                                    lines.unshift('document ' + id + ' has dependents:');
                                    lines.push('******');
                                    return lines;
                                })
                                .flatten()
                                .compact()
                                .valueOf();
                            return callback(null, goodLines.concat(errLines))
                        }
                    );
                }
            );
        }
    });
}

module.exports = ModelRegistry;
<|endoftext|>


<commit_before>var cluster = require('cluster');
var express = require('express'), cookieSessions = require('./cookie-sessions.js');

require('coffee-script')

var routes = require('./routes');
var http = require('http');
var path = require('path');
var browserify = require('browserify-middleware');

var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('exit', function (worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
}
else {

  var app = express();

// all environments
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser('terrafabshapeways'));
  app.use(cookieSessions('shapewaysterrafab'));
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.compress());
  app.use(express.staticCache())
  app.use(express.static(path.join(__dirname, 'public')));

//provide browserified versions of all the files in a directory
  app.use('/js', browserify('./client', {
    grep: /\.(?:js|coffee)$/,
    transform: ['caching-coffeeify', 'brfs'],
    noParse: ['three', 'jquery']
  }));

// development only
  if ('development' == app.get('env')) {
    app.use(express.errorHandler());
  }

  app.get('/', routes.index);

// API routes
  app.get('/dtm', routes.dtm);
  app.get('/map', routes.map);

// Model routes
  app.get('/preview', routes.preview);
  app.get('/download', routes.download);

// Shapeways integration
  app.get('/cart', routes.cart);
  app.get('/cartdata', routes.cartData);
  app.post('/ship', routes.shipToShapeways);
  app.post('/addtocart', routes.addToCart);

// oAuth Bonanza
  app.get('/login', routes.login);
  app.get('/accesstoken', routes.accessToken);
  app.get('/callback', routes.callbackFromShapeways);

  http.createServer(app).listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
  });

}<commit_msg>Bump to 12 workers<commit_after>var cluster = require('cluster');
var express = require('express'), cookieSessions = require('./cookie-sessions.js');

require('coffee-script')

var routes = require('./routes');
var http = require('http');
var path = require('path');
var browserify = require('browserify-middleware');

//var numCPUs = require('os').cpus().length;
var numWorkers = 12;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numWorkers; i++) {
    cluster.fork();
  }
  cluster.on('exit', function (worker, code, signal) {
    console.log('worker ' + worker.process.pid + ' died');
  });
}
else {

  var app = express();

// all environments
  app.set('port', process.env.PORT || 3000);
  app.set('views', __dirname + '/views');
  app.set('view engine', 'jade');
  app.use(express.favicon());
  app.use(express.logger('dev'));
  app.use(express.bodyParser());
  app.use(express.methodOverride());
  app.use(express.cookieParser('terrafabshapeways'));
  app.use(cookieSessions('shapewaysterrafab'));
  app.use(app.router);
  app.use(require('stylus').middleware(__dirname + '/public'));
  app.use(express.compress());
  app.use(express.staticCache())
  app.use(express.static(path.join(__dirname, 'public')));

//provide browserified versions of all the files in a directory
  app.use('/js', browserify('./client', {
    grep: /\.(?:js|coffee)$/,
    transform: ['caching-coffeeify', 'brfs'],
    noParse: ['three', 'jquery']
  }));

// development only
  if ('development' == app.get('env')) {
    app.use(express.errorHandler());
  }

  app.get('/', routes.index);

// API routes
  app.get('/dtm', routes.dtm);
  app.get('/map', routes.map);

// Model routes
  app.get('/preview', routes.preview);
  app.get('/download', routes.download);

// Shapeways integration
  app.get('/cart', routes.cart);
  app.get('/cartdata', routes.cartData);
  app.post('/ship', routes.shipToShapeways);
  app.post('/addtocart', routes.addToCart);

// oAuth Bonanza
  app.get('/login', routes.login);
  app.get('/accesstoken', routes.accessToken);
  app.get('/callback', routes.callbackFromShapeways);

  http.createServer(app).listen(app.get('port'), function(){
    console.log('Express server listening on port ' + app.get('port'));
  });

}<|endoftext|>


<commit_before>var os = require('os'),
    path = require('path'),
    fs = require('fs'),
    builder = require('xmlbuilder'),
    istanbul = require('istanbul');

var HtmlDetailedReporter = function (baseReporterDecorator, config, logger, helper, formatError) {
    'use strict';

    // Logger
    var log = logger.create('htmlDetailed.reporter');

    // Configuraton Settings
    var reporterConfig = config.htmlDetailed || {};
    var outputDir = helper.normalizeWinPath(path.resolve(config.basePath, reporterConfig.dir || '_reports/'));

    var splitResults;
    if (reporterConfig.splitResults == undefined  || reporterConfig.splitResults == null)
        splitResults = true;
    else
        splitResults = reporterConfig.splitResults;

    var useHosted;
    if (reporterConfig.useHostedBootstrap == undefined || reporterConfig.useHostedBootstrap == null)
        useHosted = false;
    else
        useHosted = reporterConfig.useHostedBootstrap;

    // Template Settings
    var templateFile = __dirname + '/../template.html';
    var template;

    // Karma Process Variables
    var pendingFileWritings = 0;
    var fileWritingFinished = function () { };
    var allMessages = [];

    // Private Variables
    var passCnt = {}, skipCnt = {}, failCnt = {};
    var specResults;
    var usingPreprocessor = false;

    baseReporterDecorator(this);

    this.adapters = [function (msg) {
        allMessages.push(msg);
    }];

    this.onRunStart = function () {
        // Reset default values for each run
        setPreprocessorUsed();

        specResults = [];
        passCnt = { _combined: 0 };
        skipCnt = { _combined: 0 };
        failCnt = { _combined: 0 };
    };

    this.onBrowserStart = function (browser) {
        // Reset browser-specific values
        passCnt[browser] = 0;
        skipCnt[browser] = 0;
        failCnt[browser] = 0;
    };

    this.onBrowserComplete = function (browser) {

    };

    this.onRunComplete = function () {
        // Read the template file
        fs.readFile(templateFile, function (err, data) {
            if (err) {
                log.warn('Cannot read template file.\n\t' + err.message);
                template = null;
            } else {
                template = data.toString('ascii', 0, data.length);
            }

            // Path to output file
            var outputFile;

            if (splitResults) {
                // Write results to individual, browser-specific reports
                var browsers = getBrowsers();

                // Iterate through each browser and write a report
                for (var i = 0; i < browsers.length; i++) {
                    outputFile = outputDir + '/' + browsers[i] + '/html-results.html';
                    writeSingleResults(browsers[i], outputFile, template);
                }
            } else {
                // Write all results to a single browser report
                outputFile = outputDir + '/html-results.html';
                writeCombinedResults(outputFile, template);
            }
        });

        allMessages.length = 0;
    };

    this.specSuccess = this.specSkipped = this.specFailure = function (browser, result) {
        // For each completed spec, add to results array
        specResults.push({ browser: browser, result: result });
    };

    // Wait for writing all the reports before exiting
    this.onExit = function (done) {
        if (pendingFileWritings) {
            fileWritingFinished = done;
        } else {
            done();
        }
    };

    // Determine if the preprocessor was used.  If so, set flag to perform preprocessing
    function setPreprocessorUsed() {
        for (var prop in config.preprocessors) {
            if (config.preprocessors[prop].indexOf('htmlDetailed') > -1) {
                usingPreprocessor = true;
                log.debug('htmlDetailed preprocessor used');
                break;
            }
        }
    }

    // Get unique browsers
    function getBrowsers() {
        var browsers = [];

        for (var i = 0; i < specResults.length; i++) {
            if (browsers.indexOf(specResults[i].browser.name) === -1)
                browsers.push(specResults[i].browser.name);
        }

        return browsers;
    }

    // Used for writing individual browser reports
    function writeSingleResults(browser, outputFile, template) {
        pendingFileWritings++;

        helper.mkdirIfNotExists(path.dirname(outputFile), function () {

            if (!!template) {
                var formattedResults = formatResults(browser);

                template = searchReplace(template, browser);
                template = template.replace('{{Test_Results}}', formattedResults.toString({ pretty: true }));

                fs.writeFile(outputFile, template, function (err) {
                    if (err) {
                        log.warn('Cannot write html file.\n\t' + err.message);
                    }

                    if (!--pendingFileWritings) {
                        fileWritingFinished();
                    }
                });
            }
        });
    }

    // Used for combining all browser results to one report
    function writeCombinedResults(outputFile, template) {
        pendingFileWritings++;

        helper.mkdirIfNotExists(path.dirname(outputFile), function () {

            if (!!template) {
                var formattedResults = formatResults();

                template = searchReplace(template);
                template = template.replace('{{Test_Results}}', formattedResults.toString({ pretty: true }));

                fs.writeFile(outputFile, template, function (err) {
                    if (err) {
                        log.warn('Cannot write html file.\n\t' + err.message);
                    }

                    if (!--pendingFileWritings) {
                        fileWritingFinished();
                    }
                });
            }
        });
    }

    // Searches through template replacing all placeholders
    function searchReplace(template, browser) {
        var counts;

        // Set base paths
        if (useHosted) {
            template = template.replace(/\{\{jquery_Path\}\}/g, 'https://code.jquery.com');
            template = template.replace(/\{\{bootstrap_Path\}\}/g, 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7');
        } else {
            var basePaths = getRelativePaths();
            template = template.replace(/\{\{jquery_Path\}\}/g, basePaths.jquery);
            template = template.replace(/\{\{bootstrap_Path\}\}/g, basePaths.bootstrap);
        }

        // If browser is supplied, replace for individual browser.
        // If no browser is supplied, combine results.
        if (splitResults) {
            template = template.replace(/\{\{Browser\}\}/g, '(' + browser + ')');
            counts = getCounts(browser);
        } else {
            template = template.replace(/\{\{Browser\}\}/g, '');
            counts = getCounts();
        }

        // Replace remaining placeholders
        template = template.replace('{{DateTime_Stamp}}', formatTimestamp());
        template = template.replace('{{Total_Test_Count}}', counts.totalCnt);
        template = template.replace('{{Total_Pass_Count}}', counts.passCnt);
        template = template.replace('{{Total_Skip_Count}}', counts.skipCnt);
        template = template.replace('{{Total_Fail_Count}}', counts.failCnt);

        return template;
    }

    // Normalize paths for 3rd-party dependencies
    function getRelativePaths() {
        var paths = {};

        // Get bootstrap's path
        var bootstrap = require.resolve('bootstrap');
        if (!bootstrap) log.error('Bootstrap is not found!');
        else {
            bootstrap = require('path').dirname(bootstrap);
            bootstrap = splitResults ? path.relative(outputDir + '/tempFolder/', bootstrap) : path.relative(outputDir, bootstrap);
            paths.bootstrap = bootstrap.substring(0, bootstrap.indexOf("\\js")).replace(/\\/g, '/');  // <- This gives the path of the '/js' subfolder of bootstrap, so we need to go one level up
        }

        // Get jquery's path
        var jquery = require.resolve('jquery');
        if (!jquery) log.error('jQuery is not found!');
        else {
            jquery = require('path').dirname(jquery);
            paths.jquery = (splitResults ? path.relative(outputDir + '/tempFolder/', jquery) : path.relative(outputDir, jquery)).replace(/\\/g, '/');
        }

        log.debug('Paths: ', paths);
        return paths;
    }

    // Performs calculations (per browser or across all browsers)
    function getCounts(browser) {
        var counts = {
            passCnt: 0,
            skipCnt: 0,
            failCnt: 0,
            totalCnt: 0
        };

        if (splitResults) {
            counts.passCnt = passCnt[browser];
            counts.skipCnt = skipCnt[browser];
            counts.failCnt = failCnt[browser];
        } else {
            counts.passCnt = passCnt['_combined'];
            counts.skipCnt = skipCnt['_combined'];
            counts.failCnt = failCnt['_combined'];
        }

        counts.totalCnt = counts.passCnt + counts.skipCnt + counts.failCnt;

        return counts;
    }

    // Creates the timestamp
    function formatTimestamp() {
        var date = new Date();
        var hours = date.getHours();
        var minutes = date.getMinutes();
        var minutesStr = minutes < 10 ? '0' + minutes : minutes;
        var seconds = date.getSeconds();
        var secondsStr = seconds < 10 ? '0' + seconds : seconds;
        var strTime = hours + ':' + minutesStr + ':' + secondsStr;

        return strTime;
    }

    // Generates the xml (html table) for the report
    function formatResults(browser) {
        var xml = builder.create('table');
        xml.att('class', 'table');
        var header = xml.ele('tr');
        header.ele('th', '');
        header.ele('th', 'Status');
        header.ele('th', 'Test');

        // Add extra column for browser name
        if (!splitResults) {
            header.ele('th', 'Browser');
            browser = '_combined';
        }

        var browserResults;
        if (splitResults) {
            // Filter results by browser
            browserResults = specResults.filter(function (obj) {
                return obj.browser == browser;
            });
        } else {
            browserResults = specResults;
        }

        // Iterate through each result
        for (var i = 0; i < browserResults.length; i++) {
            var result = browserResults[i].result;

            var row = xml.ele('tr');

            if (result.suite && result.suite[0] === 'Jasmine__TopLevel__Suite') {
                result.suite.shift();
            }
            var expandCell = row.ele('td', { 'class': 'expand' });

            var statusCell = row.ele('td');

            if (result.skipped) {
                skipCnt[browser]++;
                row.att('class', 'active');
                statusCell.att('class', 'status');
                statusCell.text('Skipped');

                row.ele('td', result.suite.join(' :: ') + ' :: ' + result.description);
                if (!splitResults) row.ele('td', browserResults[i].browser.name);
            }
            else if (result.success) {
                passCnt[browser]++;
                row.att('class', 'success');
                statusCell.att('class', 'status');
                statusCell.text('Passed');

                row.ele('td', result.suite.join(' :: ') + ' :: ' + result.description);
                if (!splitResults) row.ele('td', browserResults[i].browser.name);
            }
            else {
                failCnt[browser]++;
                row.att('class', 'danger');
                expandCell.att('rowspan', '2');
                statusCell.att('class', 'status');
                statusCell.att('rowspan', '2');
                statusCell.text('Failed');

                row.ele('td', result.suite.join(' :: ') + ' :: ' + result.description);
                if (!splitResults) row.ele('td', browserResults[i].browser.name);

                var errors = '';
                result.log.forEach(function (err) {
                    errors += formatError(err) + '\r\n\r\n';
                });
                var errorRow = xml.ele('tr');
                errorRow.att('class', 'danger');
                errorRow.ele('td', { 'class': 'error', 'colspan': '2' }).ele('pre').text(errors);
            }
        }

        return xml;
    }
};

HtmlDetailedReporter.$inject = ['baseReporterDecorator', 'config', 'logger', 'helper', 'formatError'];

module.exports = HtmlDetailedReporter;
<commit_msg>fix #2: udated urls for hosted libraries<commit_after>var os = require('os'),
    path = require('path'),
    fs = require('fs'),
    builder = require('xmlbuilder'),
    istanbul = require('istanbul');

var HtmlDetailedReporter = function (baseReporterDecorator, config, logger, helper, formatError) {
    'use strict';

    // Logger
    var log = logger.create('htmlDetailed.reporter');

    // Configuraton Settings
    var reporterConfig = config.htmlDetailed || {};
    var outputDir = helper.normalizeWinPath(path.resolve(config.basePath, reporterConfig.dir || '_reports/'));

    var splitResults;
    if (reporterConfig.splitResults == undefined || reporterConfig.splitResults == null)
        splitResults = true;
    else
        splitResults = reporterConfig.splitResults;

    var useHosted;
    if (reporterConfig.useHostedBootstrap == undefined || reporterConfig.useHostedBootstrap == null)
        useHosted = false;
    else
        useHosted = reporterConfig.useHostedBootstrap;

    // Template Settings
    var templateFile = __dirname + '/../template.html';
    var template;

    // Karma Process Variables
    var pendingFileWritings = 0;
    var fileWritingFinished = function () { };
    var allMessages = [];

    // Private Variables
    var passCnt = {}, skipCnt = {}, failCnt = {};
    var specResults;
    var usingPreprocessor = false;

    baseReporterDecorator(this);

    this.adapters = [function (msg) {
        allMessages.push(msg);
    }];

    this.onRunStart = function () {
        // Reset default values for each run
        setPreprocessorUsed();

        specResults = [];
        passCnt = { _combined: 0 };
        skipCnt = { _combined: 0 };
        failCnt = { _combined: 0 };
    };

    this.onBrowserStart = function (browser) {
        // Reset browser-specific values
        passCnt[browser] = 0;
        skipCnt[browser] = 0;
        failCnt[browser] = 0;
    };

    this.onBrowserComplete = function (browser) {

    };

    this.onRunComplete = function () {
        // Read the template file
        fs.readFile(templateFile, function (err, data) {
            if (err) {
                log.warn('Cannot read template file.\n\t' + err.message);
                template = null;
            } else {
                template = data.toString('ascii', 0, data.length);
            }

            // Path to output file
            var outputFile;

            if (splitResults) {
                // Write results to individual, browser-specific reports
                var browsers = getBrowsers();

                // Iterate through each browser and write a report
                for (var i = 0; i < browsers.length; i++) {
                    outputFile = outputDir + '/' + browsers[i] + '/html-results.html';
                    writeSingleResults(browsers[i], outputFile, template);
                }
            } else {
                // Write all results to a single browser report
                outputFile = outputDir + '/html-results.html';
                writeCombinedResults(outputFile, template);
            }
        });

        allMessages.length = 0;
    };

    this.specSuccess = this.specSkipped = this.specFailure = function (browser, result) {
        // For each completed spec, add to results array
        specResults.push({ browser: browser, result: result });
    };

    // Wait for writing all the reports before exiting
    this.onExit = function (done) {
        if (pendingFileWritings) {
            fileWritingFinished = done;
        } else {
            done();
        }
    };

    // Determine if the preprocessor was used.  If so, set flag to perform preprocessing
    function setPreprocessorUsed() {
        for (var prop in config.preprocessors) {
            if (config.preprocessors[prop].indexOf('htmlDetailed') > -1) {
                usingPreprocessor = true;
                log.debug('htmlDetailed preprocessor used');
                break;
            }
        }
    }

    // Get unique browsers
    function getBrowsers() {
        var browsers = [];

        for (var i = 0; i < specResults.length; i++) {
            if (browsers.indexOf(specResults[i].browser.name) === -1)
                browsers.push(specResults[i].browser.name);
        }

        return browsers;
    }

    // Used for writing individual browser reports
    function writeSingleResults(browser, outputFile, template) {
        pendingFileWritings++;

        helper.mkdirIfNotExists(path.dirname(outputFile), function () {

            if (!!template) {
                var formattedResults = formatResults(browser);

                template = searchReplace(template, browser);
                template = template.replace('{{Test_Results}}', formattedResults.toString({ pretty: true }));

                fs.writeFile(outputFile, template, function (err) {
                    if (err) {
                        log.warn('Cannot write html file.\n\t' + err.message);
                    }

                    if (!--pendingFileWritings) {
                        fileWritingFinished();
                    }
                });
            }
        });
    }

    // Used for combining all browser results to one report
    function writeCombinedResults(outputFile, template) {
        pendingFileWritings++;

        helper.mkdirIfNotExists(path.dirname(outputFile), function () {

            if (!!template) {
                var formattedResults = formatResults();

                template = searchReplace(template);
                template = template.replace('{{Test_Results}}', formattedResults.toString({ pretty: true }));

                fs.writeFile(outputFile, template, function (err) {
                    if (err) {
                        log.warn('Cannot write html file.\n\t' + err.message);
                    }

                    if (!--pendingFileWritings) {
                        fileWritingFinished();
                    }
                });
            }
        });
    }

    // Searches through template replacing all placeholders
    function searchReplace(template, browser) {
        var counts;

        // Set base paths
        if (useHosted) {
            template = template.replace(/\{\{jquery_Path\}\}/g, 'https://code.jquery.com');
            template = template.replace(/\{\{bootstrap_Path\}\}/g, 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7');
        } else {
            var basePaths = getRelativePaths();
            template = template.replace(/\{\{jquery_Path\}\}/g, basePaths.jquery);
            template = template.replace(/\{\{bootstrap_Path\}\}/g, basePaths.bootstrap);
        }

        // If browser is supplied, replace for individual browser.
        // If no browser is supplied, combine results.
        if (splitResults) {
            template = template.replace(/\{\{Browser\}\}/g, '(' + browser + ')');
            counts = getCounts(browser);
        } else {
            template = template.replace(/\{\{Browser\}\}/g, '');
            counts = getCounts();
        }

        // Replace remaining placeholders
        template = template.replace('{{DateTime_Stamp}}', formatTimestamp());
        template = template.replace('{{Total_Test_Count}}', counts.totalCnt);
        template = template.replace('{{Total_Pass_Count}}', counts.passCnt);
        template = template.replace('{{Total_Skip_Count}}', counts.skipCnt);
        template = template.replace('{{Total_Fail_Count}}', counts.failCnt);

        return template;
    }

    // Normalize paths for 3rd-party dependencies
    function getRelativePaths() {
        var paths = {};

        // Get bootstrap's path
        var bootstrap = require.resolve('bootstrap');
        if (!bootstrap) log.error('Bootstrap is not found!');
        else {
            bootstrap = require('path').dirname(bootstrap);
            bootstrap = splitResults ? path.relative(outputDir + '/tempFolder/', bootstrap) : path.relative(outputDir, bootstrap);
            paths.bootstrap = bootstrap.substring(0, bootstrap.indexOf("\\js")).replace(/\\/g, '/');  // <- This gives the path of the '/js' subfolder of bootstrap, so we need to go one level up
        }

        // Get jquery's path
        var jquery = require.resolve('jquery');
        if (!jquery) log.error('jQuery is not found!');
        else {
            jquery = require('path').dirname(jquery);
            paths.jquery = (splitResults ? path.relative(outputDir + '/tempFolder/', jquery) : path.relative(outputDir, jquery)).replace(/\\/g, '/');
        }

        log.debug('Paths: ', paths);
        return paths;
    }

    // Performs calculations (per browser or across all browsers)
    function getCounts(browser) {
        var counts = {
            passCnt: 0,
            skipCnt: 0,
            failCnt: 0,
            totalCnt: 0
        };

        if (splitResults) {
            counts.passCnt = passCnt[browser];
            counts.skipCnt = skipCnt[browser];
            counts.failCnt = failCnt[browser];
        } else {
            counts.passCnt = passCnt['_combined'];
            counts.skipCnt = skipCnt['_combined'];
            counts.failCnt = failCnt['_combined'];
        }

        counts.totalCnt = counts.passCnt + counts.skipCnt + counts.failCnt;

        return counts;
    }

    // Creates the timestamp
    function formatTimestamp() {
        var date = new Date();
        var hours = date.getHours();
        var minutes = date.getMinutes();
        var minutesStr = minutes < 10 ? '0' + minutes : minutes;
        var seconds = date.getSeconds();
        var secondsStr = seconds < 10 ? '0' + seconds : seconds;
        var strTime = hours + ':' + minutesStr + ':' + secondsStr;

        return strTime;
    }

    // Generates the xml (html table) for the report
    function formatResults(browser) {
        var xml = builder.create('table');
        xml.att('class', 'table');
        var header = xml.ele('tr');
        header.ele('th', '');
        header.ele('th', 'Status');
        header.ele('th', 'Test');

        // Add extra column for browser name
        if (!splitResults) {
            header.ele('th', 'Browser');
            browser = '_combined';
        }

        var browserResults;
        if (splitResults) {
            // Filter results by browser
            browserResults = specResults.filter(function (obj) {
                return obj.browser == browser;
            });
        } else {
            browserResults = specResults;
        }

        // Iterate through each result
        for (var i = 0; i < browserResults.length; i++) {
            var result = browserResults[i].result;

            var row = xml.ele('tr');

            if (result.suite && result.suite[0] === 'Jasmine__TopLevel__Suite') {
                result.suite.shift();
            }
            var expandCell = row.ele('td', { 'class': 'expand' });

            var statusCell = row.ele('td');

            if (result.skipped) {
                skipCnt[browser]++;
                row.att('class', 'active');
                statusCell.att('class', 'status');
                statusCell.text('Skipped');

                row.ele('td', result.suite.join(' :: ') + ' :: ' + result.description);
                if (!splitResults) row.ele('td', browserResults[i].browser.name);
            }
            else if (result.success) {
                passCnt[browser]++;
                row.att('class', 'success');
                statusCell.att('class', 'status');
                statusCell.text('Passed');

                row.ele('td', result.suite.join(' :: ') + ' :: ' + result.description);
                if (!splitResults) row.ele('td', browserResults[i].browser.name);
            }
            else {
                failCnt[browser]++;
                row.att('class', 'danger');
                expandCell.att('rowspan', '2');
                statusCell.att('class', 'status');
                statusCell.att('rowspan', '2');
                statusCell.text('Failed');

                row.ele('td', result.suite.join(' :: ') + ' :: ' + result.description);
                if (!splitResults) row.ele('td', browserResults[i].browser.name);

                var errors = '';
                result.log.forEach(function (err) {
                    errors += formatError(err) + '\r\n\r\n';
                });
                var errorRow = xml.ele('tr');
                errorRow.att('class', 'danger');
                errorRow.ele('td', { 'class': 'error', 'colspan': '2' }).ele('pre').text(errors);
            }
        }

        return xml;
    }
};

HtmlDetailedReporter.$inject = ['baseReporterDecorator', 'config', 'logger', 'helper', 'formatError'];

module.exports = HtmlDetailedReporter;
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011-2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */
'use strict';

var path = require('path'),
    fs = require('fs'),
    fmt = require('util').format,
    EOL = require('os').EOL,

    mkdirp = require('mkdirp').sync,
    rimraf = require('rimraf').sync,
    log = require('./log');

function prepFile(dir, filename) {
    var opts = {encoding: 'utf8', flags: 'w'},
        pathname = path.join(dir, filename),
        stream;

    try {
        rimraf(dir);
        mkdirp(dir);
        stream = fs.createWriteStream(pathname, opts);
    } catch (err) {
        log.debug('prepFile() exception', err);
        return;
    }

    return stream;
}

// return a function that is responsible for outputing the lint results, to
// a file or stdout, and then invoking the final callback.
function main(env, cb) {
    var dir = env.opts.directory || path.resolve(env.cwd, 'artifacts/jslint'),
        out = env.opts.print ? process.stdout : prepFile(dir, 'jslint.txt');

    if (!out) {
        cb('Failed to initialize report.');
        return;
    }

    // invoked by lintifier.doneYet()
    function reporter(offenses, msg) {
        var files = offenses ? Object.keys(offenses) : [],
            count = 0,
            total = 0,
            plural,
            summary;

        function perline(o) {
            var evidence = o.evidence.trim();
            count++;
            total++;

            out.write(fmt('  #%d %d,%d: %s%s', count, o.line, o.col, o.msg, EOL));
            if (evidence) {
                out.write(fmt('     %s%s', evidence, EOL));
            }
        }

        function perfile(pathname) {
            count = 0;
            out.write(pathname + EOL);
            offenses[pathname].forEach(perline);
            out.write(EOL);
        }

        function done() {
            // final callback is responsible for process.exit(code)
            cb('Done. ' + summary);
        }

        if (offenses) {
            // write to "out" stream
            Object.keys(offenses).forEach(perfile);
            plural = files.length > 1 ? 's' : '';
            summary = fmt('%d errors found in %d file%s', total, files.length, plural);

            if (env.opts.print) {
                done();
            } else {
                out.on('finish', done); // node 0.10.x
                out.on('close', done);  // node 0.8.x
                out.end(summary + EOL);
            }

        } else {
            // no errors
            cb(null, msg);
        }
    }

    return reporter;
}

module.exports = main;
<commit_msg>punt on streams, finish html, comments<commit_after>/*
 * Copyright (c) 2011-2013, Yahoo! Inc.  All rights reserved.
 * Copyrights licensed under the New BSD License.
 * See the accompanying LICENSE file for terms.
 */
'use strict';

// todo? sync, stream,
 for html

var path = require('path'),
    fs = require('fs'),
    fmt = require('util').format,
    EOL = require('os').EOL,

    mkdirp = require('mkdirp').sync,
    rimraf = require('rimraf').sync,
    log = require('./log');

function writeHtmlFile(dir, str) {
    var pathname = path.join(dir, 'jslint.html'),
        err;

    try {
        rimraf(dir);
        mkdirp(dir);
        fs.writeFileSync(pathname, str + EOL);
        log.info('Lint report saved to', path.relative(process.cwd(), pathname));
    } catch (err) {
        log.debug('Unable to save report.', err);
    }

    return err;
}

function getHtml(lines, summary) {
    return [
        '',
        '',
        '<title>JSLint Report</title>',
        '',
        '
JSLint Report
',
        '
' + summary + '
',
        '
'
    ].concat(lines, '
', '', '').join(EOL);
}

function getSummary(errcount, filecount) {
    var fstr = 'Total of %d error%s found in %d file%s.',
        eplural = errcount > 1 ? 's' : '',
        fplural = filecount > 1 ? 's' : '';

    return fmt(fstr, errcount, eplural, filecount, fplural);
}

// return a function that is responsible for outputing the lint results, to
// a file or stdout, and then invoking the final callback.
function main(env, cb) {
    var dir = env.opts.directory || path.resolve(env.cwd, 'artifacts/jslint'),
        lines = [],
        count = 0,
        total = 0;

    function perOffense(o) {
        var evidence = o.evidence.trim();

        count++;
        total++;

        lines.push(fmt('  #%d %d,%d: %s', count, o.line, o.col, o.msg));
        if (evidence) {
            lines.push('     ' + evidence);
        }
    }

    // invoked by lintifier.doneYet()
    function reporter(offenses, msg) {
        var files = offenses ? Object.keys(offenses) : [],
            summary,
            writeErr;

        function perFile(pathname) {
            count = 0;
            lines.push(pathname);
            offenses[pathname].forEach(perOffense);
            lines.push(''); // blank line
        }

        if (offenses) {
            // accumulate report in lines array
            Object.keys(offenses).forEach(perFile);
            summary = getSummary(total, files.length);

            if (env.opts.print) {
                lines.unshift('JSLint Report', '');
                console.error(lines.join(EOL));
                cb(summary);

            } else {
                writeErr = writeHtmlFile(dir, 'jslint.html', getHtml(lines, summary));
            }

            // has errors
            cb(writeErr || summary);

        } else {
            // is lint free
            cb(null, msg);
        }
    }

    return reporter;
}

module.exports = main;
<|endoftext|>


<commit_before>#!/bin/env node

var express = require('express');
var fs      = require('fs');
var request = require('request');
var redis   = require('redis');
var client;

/**
 *  Define the sample application.
 */
var Stilleo = function() {

    //  Scope.
    var self = this;

    /*  ================================================================  */
    /*  Helper functions.                                                 */
    /*  ================================================================  */

    /**
     *  Set up server IP address and port # using env variables/defaults.
     */
    self.setupVariables = function() {
        //  Set the environment variables we need.
        self.ipaddress = process.env.OPENSHIFT_NODEJS_IP;
        self.port      = process.env.OPENSHIFT_NODEJS_PORT || 8080;

        if (typeof self.ipaddress === "undefined") {
            //  Log errors on OpenShift but continue w/ 127.0.0.1 - this
            //  allows us to run/test the app locally.
            console.warn('No OPENSHIFT_NODEJS_IP var, using 127.0.0.1');
            self.ipaddress = "127.0.0.1";

            client = redis.createClient()
        } else {
            client = redis.createClient( process.env.REDIS_PASSWORD, process.env.OPENSHIFT_REDIS_HOST );
            client.auth( process.env.REDIS_PASSWORD );
        }
    };

    /**
     *  terminator === the termination handler
     *  Terminate server on receipt of the specified signal.
     *  @param {string} sig  Signal to terminate on.
     */
    self.terminator = function(sig){
        if (typeof sig === "string") {
           console.log('%s: Received %s - terminating sample app ...',
                       Date(Date.now()), sig);
           process.exit(1);
        }
        console.log('%s: Node server stopped.', Date(Date.now()) );
    };

    /**
     *  Setup termination handlers (for exit and a list of signals).
     */
    self.setupTerminationHandlers = function(){
        //  Process on exit and signals.
        process.on('exit', function() { self.terminator(); });

        // Removed 'SIGPIPE' from the list - bugz 852598.
        ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
         'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'
        ].forEach(function(element, index, array) {
            process.on(element, function() { self.terminator(element); });
        });
    };

    /*  ================================================================  */
    /*  App server functions (main app logic here).                       */
    /*  ================================================================  */

    /**
     *  Initialize the server (express) and create the routes and register
     *  the handlers.
     */
    self.initializeServer = function() {
        self.app = express();

        //  Add handlers for the app (from the routes).
        self.app.get(/^\/id\/(\d+)?$/, function(req, res) {
            var video_id = req.params[0];

            client.get(video_id, function(err, result) {

                if (err || !result) {
                    console.log('Querying vimeo ID: ', video_id);
                    self.queryVimeo( req, res, video_id );
                } else {
                    console.log("Redis works!", result);
                    request(result).pipe(res);
                }
           })
        })

        self.app.get('/', function(req, res) {
            req.write('Test');
        });
    };

    self.queryVimeo = function( req, res, video_id ) {
       request('http://vimeo.com/api/oembed.json?url=http://vimeo.com/' + video_id, function(err, response, body) {
            if ( !err && response.statusCode == 200 ) {

                var json = JSON.parse(body);

                client.setex(video_id, 21600, json.thumbnail_url );
                request( json.thumbnail_url).pipe(res);
            } else {
                console.log(err, response);
            }
        });
    }

    /**
     *  Initializes the sample application.
     */
    self.initialize = function() {
        self.setupVariables();
        self.setupTerminationHandlers();

        // Create the express server and routes.
        self.initializeServer();
    };

    /**
     *  Start the server (starts up the sample application).
     */
    self.start = function() {
        //  Start the app on the specific interface (and port).
        self.app.listen(self.port, self.ipaddress, function() {
            console.log('%s: Node server started on %s:%d ...',
                        Date(Date.now() ), self.ipaddress, self.port);
        });
    };

};   /*  Stilleo Application.  */

/**
 *  main():  Main code.
 */
var zapp = new Stilleo();
zapp.initialize();
zapp.start();<commit_msg>Fixes varas type<commit_after>#!/bin/env node

var express = require('express');
var fs      = require('fs');
var request = require('request');
var redis   = require('redis');
var client;

/**
 *  Define the sample application.
 */
var Stilleo = function() {

    //  Scope.
    var self = this;

    /*  ================================================================  */
    /*  Helper functions.                                                 */
    /*  ================================================================  */

    /**
     *  Set up server IP address and port # using env variables/defaults.
     */
    self.setupVariables = function() {
        //  Set the environment variables we need.
        self.ipaddress = process.env.OPENSHIFT_NODEJS_IP;
        self.port      = process.env.OPENSHIFT_NODEJS_PORT || 8080;

        if (typeof self.ipaddress === "undefined") {
            //  Log errors on OpenShift but continue w/ 127.0.0.1 - this
            //  allows us to run/test the app locally.
            console.warn('No OPENSHIFT_NODEJS_IP var, using 127.0.0.1');
            self.ipaddress = "127.0.0.1";

            client = redis.createClient()
        } else {
            client = redis.createClient( process.env.OPENSHIFT_REDIS_PORT, process.env.OPENSHIFT_REDIS_HOST );
            client.auth( process.env.REDIS_PASSWORD );
        }
    };

    /**
     *  terminator === the termination handler
     *  Terminate server on receipt of the specified signal.
     *  @param {string} sig  Signal to terminate on.
     */
    self.terminator = function(sig){
        if (typeof sig === "string") {
           console.log('%s: Received %s - terminating sample app ...',
                       Date(Date.now()), sig);
           process.exit(1);
        }
        console.log('%s: Node server stopped.', Date(Date.now()) );
    };

    /**
     *  Setup termination handlers (for exit and a list of signals).
     */
    self.setupTerminationHandlers = function(){
        //  Process on exit and signals.
        process.on('exit', function() { self.terminator(); });

        // Removed 'SIGPIPE' from the list - bugz 852598.
        ['SIGHUP', 'SIGINT', 'SIGQUIT', 'SIGILL', 'SIGTRAP', 'SIGABRT',
         'SIGBUS', 'SIGFPE', 'SIGUSR1', 'SIGSEGV', 'SIGUSR2', 'SIGTERM'
        ].forEach(function(element, index, array) {
            process.on(element, function() { self.terminator(element); });
        });
    };

    /*  ================================================================  */
    /*  App server functions (main app logic here).                       */
    /*  ================================================================  */

    /**
     *  Initialize the server (express) and create the routes and register
     *  the handlers.
     */
    self.initializeServer = function() {
        self.app = express();

        //  Add handlers for the app (from the routes).
        self.app.get(/^\/id\/(\d+)?$/, function(req, res) {
            var video_id = req.params[0];

            client.get(video_id, function(err, result) {

                if (err || !result) {
                    console.log('Querying vimeo ID: ', video_id);
                    self.queryVimeo( req, res, video_id );
                } else {
                    console.log("Redis works!", result);
                    request(result).pipe(res);
                }
           })
        })

        self.app.get('/', function(req, res) {
            req.write('Test');
        });
    };

    self.queryVimeo = function( req, res, video_id ) {
       request('http://vimeo.com/api/oembed.json?url=http://vimeo.com/' + video_id, function(err, response, body) {
            if ( !err && response.statusCode == 200 ) {

                var json = JSON.parse(body);

                client.setex(video_id, 21600, json.thumbnail_url );
                request( json.thumbnail_url).pipe(res);
            } else {
                console.log(err, response);
            }
        });
    }

    /**
     *  Initializes the sample application.
     */
    self.initialize = function() {
        self.setupVariables();
        self.setupTerminationHandlers();

        // Create the express server and routes.
        self.initializeServer();
    };

    /**
     *  Start the server (starts up the sample application).
     */
    self.start = function() {
        //  Start the app on the specific interface (and port).
        self.app.listen(self.port, self.ipaddress, function() {
            console.log('%s: Node server started on %s:%d ...',
                        Date(Date.now() ), self.ipaddress, self.port);
        });
    };

};   /*  Stilleo Application.  */

/**
 *  main():  Main code.
 */
var zapp = new Stilleo();
zapp.initialize();
zapp.start();<|endoftext|>