<commit_before>/////////////////////////////////////////////////////////////////////
// Copyright (c) Autodesk, Inc. All rights reserved
// Written by <NAME> 2015 - ADN/Developer Technical Services
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
////////////////////////////////////////////////////////////////////////
var Promise = require('es6-promise').Promise;
var request = require('request');
var admZip = require ('adm-zip');
var mkdirp = require("mkdirp");
var async = require('async');
var path = require('path');
var util = require('util');
var zlib = require ('zlib');
var _ = require('lodash');
var fs = require('fs');

module.exports = function(config) {

  config = _.assign(
    require('./config-view-and-data'),
    config);

  var _self = this;

  var _token = null;

  var _refreshTimeout = 0;

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  function _handleResponse(
    error, res, body,
    resolve,
    reject) {


    if (error || res.statusCode != 200) {

      try {

        if(res) {

          error = error || {error: res.statusMessage};

          error.statusCode = res.statusCode || 204;

          reject(error);
        }
        else {

          reject({
            statusCode: 204,
            message: 'Unspecified Error'
          });
        }
      }
      catch(ex) {

        reject(ex);
      }
    }

    else {

      try {

        resolve(body ? JSON.parse(body) : '')
      }
      catch(ex) {

        reject(ex);
      }
    }
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  function _refreshToken() {

    var promise = new Promise(function(resolve, reject) {

      _self.getToken().then(

        function(response){

          _token = response.access_token;
          clearTimeout(_refreshTimeout)

         /* _refreshTimeout = setTimeout(function() {

         //   _refreshToken(arguments.callee);

          }, (response.expires_in * 0.7) * 1000);*/
			console.log("No error");
			result = {"access_token":_token,"token_type":response.token_type};
			result=JSON.stringify(result);
			console.log(result);
          resolve(result);
        },
        function(error){

          _token = null;
			console.log("Error has occure in line 116");
			console.log(error);
          reject(error);
        });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.getToken = function(scope) {

    var params = {
      client_secret: config.credentials.clientSecret,
      client_id: config.credentials.clientId,
      grant_type: 'client_credentials',
      scope: scope || config.scope.join(' ')
    };
    console.log(config.endPoints.authenticate);
    console.log(JSON.stringify(params));
    var promise = new Promise(function(resolve, reject) {

      request.post(
        config.endPoints.authenticate,
        { form: params },

        function (error, res, body) {
			//console.log(error);
			//console.log(res);
			//console.log(body);
			console.log("Resolving body");
			console.log(body);
         _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.setToken = function(token) {

    _token = token
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.initialize = function() {
    return _refreshToken();
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.getSupportedFormats = function() {

    var promise = new Promise(function(resolve, reject) {

      request.get({
          url: config.endPoints.supported,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json'
          }
        },
        function (error, res, body) {
			//console.log(body);
          _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////
  // Use:
  // Get bucket details
  //
  // API:
  // GET /oss/{apiversion}/buckets/{bucketkey}/details
  //
  // Response:
  //
  // "{
  //      "key":"bucketKey",
  //      "owner":"tAp1fqjjtcgqS4CKpCYDjAyNbKW4IVCC",
  //      "createDate":1404984496468,
  //      "permissions":[{
  //          "serviceId":"tAp1fqjjtcgqS4CKpCYDjAyNbKW4IVCC",
  //          "access":"full"}],
  //      "policyKey":"persistent"
  //  }"
  ///////////////////////////////////////////////////////////////////
  // Use:
  // Create bucket
  //
  // bucketCreationData = {
  //      bucketKey : "bucketKey",
  //      servicesAllowed: {},
  //      policy: "temporary/transient/persistent"
  // }
  //
  // API:
  // POST /oss/{apiversion}/buckets
  //
  // Response:
  //
  // {
  // "bucketKey": "sampletestbucketdanieldu12345",
  // "bucketOwner": "mvMpJWBGyBuGpVycB77FFgP45T4dBycD",
  // "createdDate": 1435633089537,
  // "permissions": [
  // {
  // "authId": "<KEY>",
  // "access": "full"
  // }
  // ],
  // "policyKey": "temporary"
  // }
  ///////////////////////////////////////////////////////////////////
  _self.getBucket = function(
    bucketKey,
    createIfNotExists,
    bucketCreationData) {

    var promise = new Promise(function(resolve, reject) {

      var getBucketUrl = util.format(
        config.endPoints.getBucket,
        bucketKey);
	console.log(getBucketUrl);
	console.log(bucketKey);
	console.log(config.endPoints.createBucket);
	console.log(JSON.stringify(bucketCreationData));
	console.log("begin creation");
	//exit();	//exit on this error
      request.get({
          url: getBucketUrl,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json'
          }
        },
        function (error, res, body) {
	//console.log(body);
          if(res.statusCode == 200 || !createIfNotExists) {

            _handleResponse(error, res, body,
              resolve,
              reject);
          }
          else {

            request.post({
                url: config.endPoints.createBucket,
                headers: {
                  'Authorization': 'Bearer ' + _token,
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify(bucketCreationData)
              },
              function (error, res, body) {

                _handleResponse(error, res, body,
                  resolve,
                  reject);
              });
          }
        });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////////////
  // Use:
  // Upload a file to bucket
  //
  // API:
  // PUT /oss/{apiversion}/buckets/{bucketkey}/objects/{objectkey}
  //
  // Response:
  //
  // "{   "bucket-key" : "adn-10.07.2014-11.28.15",
  //      "file": file,
  //      "objects" : [ {
  //          "location" : "baseUrl/oss/v1/buckets/bucketKey/objects/file.name",
  //          "size" : 1493911,
  //          "key" : "file.name",
  //          "id" : "urn:adsk.objects:os.object:bucketKey/file.name",
  //          "sha-1" : "ba824b22a6df9d0fc30943ffcf8129e2b9de80f6",
  //          "content-type" : "application/stream"  } ]
  //  }"
  ///////////////////////////////////////////////////////////////////////////
  _self.upload = function(filename, bucketKey, objectKey) {

    var promise = new Promise(function(resolve, reject) {

      var uploadUrl = util.format(
        config.endPoints.upload,
        bucketKey, objectKey.replace (/ /g, '+'));

      var readStream = fs.createReadStream(filename);
		console.log(uploadUrl);
      readStream.pipe(
        request.put({
            url: uploadUrl,
            headers: {
              'Authorization': 'Bearer ' + _token,
              'Content-Type': 'application/octet-stream'
            }
          },
          function (error, res, body) {
console.log(body);
            _handleResponse(error, res, body,
              resolve,
              reject);
          }));
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////////////
  // Use:
  // Upload a file to bucket
  //
  // API:
  // PUT /oss/{apiversion}/buckets/{bucketkey}/objects/{objectkey}/resumable
  //
  // Response:
  //
  // "{   "bucket-key" : "adn-10.07.2014-11.28.15",
  //      "file": file,
  //      "objects" : [ {
  //          "location" : "baseUrl/oss/v1/buckets/bucketKey/objects/file.name",
  //          "size" : 1493911,
  //          "key" : "file.name",
  //          "id" : "urn:adsk.objects:os.object:bucketKey/file.name",
  //          "sha-1" : "ba824b22a6df9d0fc30943ffcf8129e2b9de80f6",
  //          "content-type" : "application/stream"  } ]
  //  }"
  ///////////////////////////////////////////////////////////////////////////
  _self.resumableUpload = function(filename, bucketKey, objectKey) {

    var promise = new Promise(function(resolve, reject) {

      fs.stat(filename, function (err, stats) {

        if (err) {

          reject(err);
          return;
        }

        var total = stats.size ;

        var chunkSize = config.fileResumableChunk * 1024 * 1024 ;

        var nbChunks = Math.round (0.5 + total / chunkSize) ;

        var resumableUploadUrl = util.format (
          config.endPoints.resumableUpload,
          bucketKey, objectKey.replace (/ /g, '+')) ;

        var sessionId = 'adn-lmv-' + guid();

        // pipe is better since it avoids loading all in memory
        var fctChunks = function (n, chunkSize) {

          return (function (callback) {

            var start = n * chunkSize ;

            var end = Math.min (total, (n + 1) * chunkSize) - 1 ;

            var contentRange ='bytes '
              + start + '-'
              + end + '/'
              + total ;

            var readStream = fs.createReadStream (filename, {'start': start, 'end': end});

            readStream.pipe (
              request.put({
                  url: resumableUploadUrl,
                  headers: {
                    'Authorization': 'Bearer ' + _token,
                    'Content-Type': 'application/octet-stream',
                    'Content-Range': contentRange,
                    'Session-Id': sessionId
                  }
                },
                function (error, res, body) {

                  if(res.statusCode == 200 || res.statusCode == 202){
                    callback (null, body ? JSON.parse(body) : '');
                  }
                  else {
                    callback(err, null) ;
                  }
                }));
          });
        };

        var fctChunksArray = Array.apply(null, { length: nbChunks }).map(Number.call, Number);

        for ( var i =0 ; i < fctChunksArray.length ; i++)
          fctChunksArray[i] = fctChunks (i, chunkSize);

        async.parallelLimit (
          fctChunksArray,
          10,
          function (err, results) {
            if (err) {

              reject(err);
            }
            else {

              if(results.length == nbChunks)
                resolve(results);

              else
                reject({error: 'incomplete upload'});
            }
          });
      });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////
  // Use:
  // Register an uploaded file
  //
  // API:
  // POST /viewingservice/{apiversion}/register
  //
  // Response:
  //
  // "{"Result":"Success"}"
  ///////////////////////////////////////////////////////////////////
  _self.register = function(urn, force) {

    var promise = new Promise(function(resolve, reject) {

console.log(config.endPoints.register);
//exit();
      request.post({
          url: config.endPoints.register,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json',
            'x-ads-force': force
          },
          body: JSON.stringify({urn: urn})
        },
        function (error, res, body) {
console.log("Register....");
//console.log(body);
          _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });

    return promise;
  }
	///////////////////////////////////////////////////////////////////
  //
  ///////////////////////////////////////////////////////////////////
  
  
   _self.modelView = function(urn) {
	var modelViewUrl = util.format(
        config.endPoints.modelView, urn);
        console.log(modelViewUrl);
    var promise = new Promise(function(resolve, reject) {
		
      request.get({
          url: modelViewUrl,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({urn: urn})
        },
        function (error, res, body) {
          _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });

    return promise;
  }
 	///////////////////////////////////////////////////////////////////
  //
  ///////////////////////////////////////////////////////////////////
  
  
   _self.objectTree = function(urn, guidStr) {
	var objectTreeUrl = util.format(
        config.endPoints.objectTree, urn, guidStr);
        console.log(objectTreeUrl);
        //console.log(guidStr);
    var promise = new Promise(function(resolve, reject) {
		
      request.get({
          url: objectTreeUrl,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({urn: urn})
        },
        function (error, res, body) {
        //	console.log(body);
          _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });
    return promise;
  }

   ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.objfile = function(urn, guidStr, objids) {

    var params = {
      input: {"urn": },
      output: "formats": [
       {
         "type": "obj"
         "advanced": {
           "modelGuid":guidStr,
           "objectIds":objids
        }

     }]
    };
    console.log(config.endPoints.objfile);
    console.log(JSON.stringify(params));
    var promise = new Promise(function(resolve, reject) {
      request.post({
                url: config.endPoints.objfile,
                headers: {<commit_msg>Added objfile<commit_after>/////////////////////////////////////////////////////////////////////
// Copyright (c) Autodesk, Inc. All rights reserved
// Written by <NAME> 2015 - ADN/Developer Technical Services
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE.  AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
////////////////////////////////////////////////////////////////////////
var Promise = require('es6-promise').Promise;
var request = require('request');
var admZip = require ('adm-zip');
var mkdirp = require("mkdirp");
var async = require('async');
var path = require('path');
var util = require('util');
var zlib = require ('zlib');
var _ = require('lodash');
var fs = require('fs');

module.exports = function(config) {

  config = _.assign(
    require('./config-view-and-data'),
    config);

  var _self = this;

  var _token = null;

  var _refreshTimeout = 0;

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  function _handleResponse(
    error, res, body,
    resolve,
    reject) {


    if (error || res.statusCode != 200) {

      try {

        if(res) {

          error = error || {error: res.statusMessage};

          error.statusCode = res.statusCode || 204;

          reject(error);
        }
        else {

          reject({
            statusCode: 204,
            message: 'Unspecified Error'
          });
        }
      }
      catch(ex) {

        reject(ex);
      }
    }

    else {

      try {

        resolve(body ? JSON.parse(body) : '')
      }
      catch(ex) {

        reject(ex);
      }
    }
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  function _refreshToken() {

    var promise = new Promise(function(resolve, reject) {

      _self.getToken().then(

        function(response){

          _token = response.access_token;
          clearTimeout(_refreshTimeout)

         /* _refreshTimeout = setTimeout(function() {

         //   _refreshToken(arguments.callee);

          }, (response.expires_in * 0.7) * 1000);*/
			console.log("No error");
			result = {"access_token":_token,"token_type":response.token_type};
			result=JSON.stringify(result);
			console.log(result);
          resolve(result);
        },
        function(error){

          _token = null;
			console.log("Error has occure in line 116");
			console.log(error);
          reject(error);
        });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.getToken = function(scope) {

    var params = {
      client_secret: config.credentials.clientSecret,
      client_id: config.credentials.clientId,
      grant_type: 'client_credentials',
      scope: scope || config.scope.join(' ')
    };
    console.log(config.endPoints.authenticate);
    console.log(JSON.stringify(params));
    var promise = new Promise(function(resolve, reject) {

      request.post(
        config.endPoints.authenticate,
        { form: params },

        function (error, res, body) {
			//console.log(error);
			//console.log(res);
			//console.log(body);
			console.log("Resolving body");
			console.log(body);
         _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.setToken = function(token) {

    _token = token
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.initialize = function() {
    return _refreshToken();
  }

  ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.getSupportedFormats = function() {

    var promise = new Promise(function(resolve, reject) {

      request.get({
          url: config.endPoints.supported,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json'
          }
        },
        function (error, res, body) {
			//console.log(body);
          _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////
  // Use:
  // Get bucket details
  //
  // API:
  // GET /oss/{apiversion}/buckets/{bucketkey}/details
  //
  // Response:
  //
  // "{
  //      "key":"bucketKey",
  //      "owner":"tAp1fqjjtcgqS4CKpCYDjAyNbKW4IVCC",
  //      "createDate":1404984496468,
  //      "permissions":[{
  //          "serviceId":"tAp1fqjjtcgqS4CKpCYDjAyNbKW4IVCC",
  //          "access":"full"}],
  //      "policyKey":"persistent"
  //  }"
  ///////////////////////////////////////////////////////////////////
  // Use:
  // Create bucket
  //
  // bucketCreationData = {
  //      bucketKey : "bucketKey",
  //      servicesAllowed: {},
  //      policy: "temporary/transient/persistent"
  // }
  //
  // API:
  // POST /oss/{apiversion}/buckets
  //
  // Response:
  //
  // {
  // "bucketKey": "sampletestbucketdanieldu12345",
  // "bucketOwner": "mvMpJWBGyBuG<KEY>",
  // "createdDate": 1435633089537,
  // "permissions": [
  // {
  // "authId": "<KEY>",
  // "access": "full"
  // }
  // ],
  // "policyKey": "temporary"
  // }
  ///////////////////////////////////////////////////////////////////
  _self.getBucket = function(
    bucketKey,
    createIfNotExists,
    bucketCreationData) {

    var promise = new Promise(function(resolve, reject) {

      var getBucketUrl = util.format(
        config.endPoints.getBucket,
        bucketKey);
	console.log(getBucketUrl);
	console.log(bucketKey);
	console.log(config.endPoints.createBucket);
	console.log(JSON.stringify(bucketCreationData));
	console.log("begin creation");
	//exit();	//exit on this error
      request.get({
          url: getBucketUrl,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json'
          }
        },
        function (error, res, body) {
	//console.log(body);
          if(res.statusCode == 200 || !createIfNotExists) {

            _handleResponse(error, res, body,
              resolve,
              reject);
          }
          else {

            request.post({
                url: config.endPoints.createBucket,
                headers: {
                  'Authorization': 'Bearer ' + _token,
                  'Content-Type': 'application/json'
                },
                body: JSON.stringify(bucketCreationData)
              },
              function (error, res, body) {

                _handleResponse(error, res, body,
                  resolve,
                  reject);
              });
          }
        });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////////////
  // Use:
  // Upload a file to bucket
  //
  // API:
  // PUT /oss/{apiversion}/buckets/{bucketkey}/objects/{objectkey}
  //
  // Response:
  //
  // "{   "bucket-key" : "adn-10.07.2014-11.28.15",
  //      "file": file,
  //      "objects" : [ {
  //          "location" : "baseUrl/oss/v1/buckets/bucketKey/objects/file.name",
  //          "size" : 1493911,
  //          "key" : "file.name",
  //          "id" : "urn:adsk.objects:os.object:bucketKey/file.name",
  //          "sha-1" : "ba824b22a6df9d0fc30943ffcf8129e2b9de80f6",
  //          "content-type" : "application/stream"  } ]
  //  }"
  ///////////////////////////////////////////////////////////////////////////
  _self.upload = function(filename, bucketKey, objectKey) {

    var promise = new Promise(function(resolve, reject) {

      var uploadUrl = util.format(
        config.endPoints.upload,
        bucketKey, objectKey.replace (/ /g, '+'));

      var readStream = fs.createReadStream(filename);
		console.log(uploadUrl);
      readStream.pipe(
        request.put({
            url: uploadUrl,
            headers: {
              'Authorization': 'Bearer ' + _token,
              'Content-Type': 'application/octet-stream'
            }
          },
          function (error, res, body) {
console.log(body);
            _handleResponse(error, res, body,
              resolve,
              reject);
          }));
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////////////
  // Use:
  // Upload a file to bucket
  //
  // API:
  // PUT /oss/{apiversion}/buckets/{bucketkey}/objects/{objectkey}/resumable
  //
  // Response:
  //
  // "{   "bucket-key" : "adn-10.07.2014-11.28.15",
  //      "file": file,
  //      "objects" : [ {
  //          "location" : "baseUrl/oss/v1/buckets/bucketKey/objects/file.name",
  //          "size" : 1493911,
  //          "key" : "file.name",
  //          "id" : "urn:adsk.objects:os.object:bucketKey/file.name",
  //          "sha-1" : "ba824b22a6df9d0fc30943ffcf8129e2b9de80f6",
  //          "content-type" : "application/stream"  } ]
  //  }"
  ///////////////////////////////////////////////////////////////////////////
  _self.resumableUpload = function(filename, bucketKey, objectKey) {

    var promise = new Promise(function(resolve, reject) {

      fs.stat(filename, function (err, stats) {

        if (err) {

          reject(err);
          return;
        }

        var total = stats.size ;

        var chunkSize = config.fileResumableChunk * 1024 * 1024 ;

        var nbChunks = Math.round (0.5 + total / chunkSize) ;

        var resumableUploadUrl = util.format (
          config.endPoints.resumableUpload,
          bucketKey, objectKey.replace (/ /g, '+')) ;

        var sessionId = 'adn-lmv-' + guid();

        // pipe is better since it avoids loading all in memory
        var fctChunks = function (n, chunkSize) {

          return (function (callback) {

            var start = n * chunkSize ;

            var end = Math.min (total, (n + 1) * chunkSize) - 1 ;

            var contentRange ='bytes '
              + start + '-'
              + end + '/'
              + total ;

            var readStream = fs.createReadStream (filename, {'start': start, 'end': end});

            readStream.pipe (
              request.put({
                  url: resumableUploadUrl,
                  headers: {
                    'Authorization': 'Bearer ' + _token,
                    'Content-Type': 'application/octet-stream',
                    'Content-Range': contentRange,
                    'Session-Id': sessionId
                  }
                },
                function (error, res, body) {

                  if(res.statusCode == 200 || res.statusCode == 202){
                    callback (null, body ? JSON.parse(body) : '');
                  }
                  else {
                    callback(err, null) ;
                  }
                }));
          });
        };

        var fctChunksArray = Array.apply(null, { length: nbChunks }).map(Number.call, Number);

        for ( var i =0 ; i < fctChunksArray.length ; i++)
          fctChunksArray[i] = fctChunks (i, chunkSize);

        async.parallelLimit (
          fctChunksArray,
          10,
          function (err, results) {
            if (err) {

              reject(err);
            }
            else {

              if(results.length == nbChunks)
                resolve(results);

              else
                reject({error: 'incomplete upload'});
            }
          });
      });
    });

    return promise;
  }

  ///////////////////////////////////////////////////////////////////
  // Use:
  // Register an uploaded file
  //
  // API:
  // POST /viewingservice/{apiversion}/register
  //
  // Response:
  //
  // "{"Result":"Success"}"
  ///////////////////////////////////////////////////////////////////
  _self.register = function(urn, force) {

    var promise = new Promise(function(resolve, reject) {

console.log(config.endPoints.register);
//exit();
      request.post({
          url: config.endPoints.register,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json',
            'x-ads-force': force
          },
          body: JSON.stringify({urn: urn})
        },
        function (error, res, body) {
console.log("Register....");
//console.log(body);
          _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });

    return promise;
  }
	///////////////////////////////////////////////////////////////////
  //
  ///////////////////////////////////////////////////////////////////
  
  
   _self.modelView = function(urn) {
	var modelViewUrl = util.format(
        config.endPoints.modelView, urn);
        console.log(modelViewUrl);
    var promise = new Promise(function(resolve, reject) {
		
      request.get({
          url: modelViewUrl,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({urn: urn})
        },
        function (error, res, body) {
          _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });

    return promise;
  }
 	///////////////////////////////////////////////////////////////////
  //
  ///////////////////////////////////////////////////////////////////
  
  
   _self.objectTree = function(urn, guidStr) {
	var objectTreeUrl = util.format(
        config.endPoints.objectTree, urn, guidStr);
        console.log(objectTreeUrl);
        //console.log(guidStr);
    var promise = new Promise(function(resolve, reject) {
		
      request.get({
          url: objectTreeUrl,
          headers: {
            'Authorization': 'Bearer ' + _token,
            'Content-Type': 'application/json'
          },
          body: JSON.stringify({urn: urn})
        },
        function (error, res, body) {
        //	console.log(body);
          _handleResponse(error, res, body,
            resolve,
            reject);
        });
    });
    return promise;
  }

   ///////////////////////////////////////////////////////////////////
  //
  //
  ///////////////////////////////////////////////////////////////////
  _self.objfile = function(urn, guidStr, objids) {

    var params = {
      input: {"urn": urn},
      output: "formats": [
       {
         "type": "obj"
         "advanced": {
           "modelGuid":guidStr,
           "objectIds":objids
        }

     }]
    };
    console.log(config.endPoints.objfile);
    console.log(JSON.stringify(params));
    var promise = new Promise(function(resolve, reject) {
      request.post({
                url: config.endPoints.objfile,
                headers: {
{'fraction_non_alphanumeric': 0.24961607371384695, 'fraction_numerical': 0.01135781929869465, 'mean_word_length': 1.2183818310858765, 'pattern_counts': {'":': 50, '<': 10, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6931211', 'n_tokens_mistral': 8850, 'n_tokens_neox': 8273, 'n_words': 1630}