Difference between revisions of "User:Abel/WbProcessor.js"

From Wikibase Personal data
Jump to navigation Jump to search
m
m
 
(2 intermediate revisions by 2 users not shown)
Line 3: Line 3:
 
console.log('wbprocessor loading');
 
console.log('wbprocessor loading');
  
function WikibaseProcessorContainer( universe, location ) {
+
function WikibaseProcessorContainer(universe, location) {
  
Debug_switch = false;
+
  Debug_switch = false;
  
this.main = interjson( checkdive( universe, location ));
+
  this.main = interjson(checkdive(universe, location));
var the = this.main;
+
  var the = this.main;
 
/* The following is the main exposed function of the current Wb Processing class
 
usage cases
 
  
to check the last value in a location given by a preceding array of internal paths to find, with the possibility of array layers between elements of array of paths:
+
  /* The following is the main exposed function of the current Wb Processing class
wbproc.checkentity( [ wbEStruct['instanceOfRelations'], wbEStruct['IDPropLoc'], wbEStruct['IDName'], 96 ] );
+
  usage cases
  
to return for example content of default value given by array of location paths, or check for existence of  
+
  to check the last value in a location given by a preceding array of internal paths to find, with the possibility of array layers between elements of array of paths:
wbproc.checkentity( { default_value: [ wbEStruct['defaultValRelation'], wbEStruct['IDPropLoc'] ] } )
+
  wbproc.checkentity( [ wbEStruct['instanceOfRelations'], wbEStruct['IDPropLoc'], wbEStruct['IDName'], 96 ] );
  
 +
  to return for example content of default value given by array of location paths, or check for existence of
 +
  wbproc.checkentity( { default_value: [ wbEStruct['defaultValRelation'], wbEStruct['IDPropLoc'] ] } )
  
*/
 
  
this.checkentity = function ( paths ) {
+
  */
if ( ( the !== undefined ) && ( paths !== undefined ) ){
 
return proceed( the, paths );
 
}
 
}
 
  
// Exposed general wrapper for proceed for object other than what the class is originally instanced on, currently unused
+
  this.checkentity = function(paths) {
// Could be used to create a further function to cross check current object with another object 'universe' with another for example
+
    if ((the !== undefined) && (paths !== undefined)) {
 +
      return proceed(the, paths);
 +
    }
 +
  }
  
this.xcontains = function ( unv, angle ) {
+
  // Exposed general wrapper for proceed for object other than what the class is originally instanced on, currently unused
if ( ( unv !== undefined ) && ( angle !== undefined ) ){
+
  // Could be used to create a further function to cross check current object with another object 'universe' with another for example
return proceed( unv, angle );
 
};
 
}
 
  
/* Exposed helper function to get Entity object of alien entity, if ever needed */
+
  this.xcontains = function(unv, angle) {
               
+
    if ((unv !== undefined) && (angle !== undefined)) {
        this.EnqueueWB = async function( idk ) {
+
      return proceed(unv, angle);
var k = await wbqueue(idk);
+
    };
return k;
+
  }
}
 
  
/* Private part of wb Entity getter */
+
  /* Exposed helper function to get Entity object of alien entity, if ever needed */
  
async function wbqueue(id) {
+
  this.EnqueueWB = async function(idk) {
return new Promise(
+
    var k = await wbqueue(idk);
function(resolve, reject) {
+
    return k;
$.getJSON('/w/api.php?action=wbgetentities&format=json&ids=' + id, function(json) {  
+
  }
var h = json.entities;
 
resolve(h);
 
})
 
}).then( function(result) {
 
debuglog(result);
 
return result;
 
});
 
}
 
  
 +
  /* Private part of wb Entity getter */
  
// the list of private helper functions, could not be accessed from outside
+
  async function wbqueue(id) {
// helper function for descend into an object if key exists, otherwise stay at current level of object
+
    return new Promise(
function indexinterpolate(obj,i) { return (obj[i] !== undefined) ? obj[i] : obj};
+
      function(resolve, reject) {
+
        $.getJSON('/w/api.php?action=wbgetentities&format=json&ids=' + id, function(json) {
// helper function for checking a part of an array exists, if it doesn't, go undefined
+
          var h = json.entities;
function indexcheck(obj,i) {  if ( obj !== undefined) { return ( obj[i] !== undefined ) ? obj[i] : undefined } };
+
          resolve(h);
+
        })
// dive selects matrix.a.b.c.d from the array called matrix and 'a.b.c.d' as string
+
      }).then(function(result) {
// if a.b.c.d does not exists, it returns the substructure until the substructure exists, if d does not exist, it returns matrix.a.b.c e.g.
+
      debuglog(result);
function dive(array, read){
+
      return result;
if ( array !== undefined ) {
+
    });
return (read + '').split('.').reduce(indexinterpolate, array);
+
  }
}
 
}
 
// Check returns matrix.a.b.c.d from 'array' ~ 'matrix' and 'read' ~ 'a.b.c.d' only if it exists all the way, otherwise go undefined
 
function check(array, read){
 
if ( array !== undefined ) {
 
return (read + '').split('.').reduce(indexcheck, array);
 
}
 
}
 
  
// Main object / array processing instrument
 
// Array can be a composition of objects and arrays
 
// Read is the instructions, could be an array, or a single path, but for now it should be an object based on our inner convention, example:
 
/*
 
relational_id_list = {
 
controller_id: [ wbEStructure['instanceOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 96 ],
 
personal_data_id: [ wbEStructure['subclassOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 421 ],
 
interface_button_id: [ wbEStructure ['instanceOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 487 ]
 
}
 
*/
 
  
function proceed(array, read) {
+
  // the list of private helper functions, could not be accessed from outside
var ret_obj = {},
+
  // helper function for descend into an object if key exists, otherwise stay at current level of object
temp_obj = array,
+
  function indexinterpolate(obj, i) {
 +
    return (obj[i] !== undefined) ? obj[i] : obj
 +
  };
  
// If we encounter something seriously wrong we will just raise a red flag by setting this false, will check before returning this.
+
  // helper function for checking a part of an array exists, if it doesn't, go undefined
success_o_meter = true,
+
  function indexcheck(obj, i) {
 +
    if (obj !== undefined) {
 +
      return (obj[i] !== undefined) ? obj[i] : undefined
 +
    }
 +
  };
  
// If all goes well, for each path checked, we will have a member in this
+
  // dive selects matrix.a.b.c.d from the array called matrix and 'a.b.c.d' as string
future_instructional_return = [];
+
  // if a.b.c.d does not exists, it returns the substructure until the substructure exists, if d does not exist, it returns matrix.a.b.c e.g.
+
  function dive(array, read) {
//|||||||||||||||||||||||||||||||||||||||||||||||||||||[ I N S T R U C T I O N S  C O N T R O L   ]||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
    if (array !== undefined) {
 +
      return (read + '').split('.').reduce(indexinterpolate, array);
 +
    }
 +
  }
 +
  // Check returns matrix.a.b.c.d from 'array' ~ 'matrix' and 'read' ~ 'a.b.c.d' only if it exists all the way, otherwise go undefined
 +
  function check(array, read) {
 +
    if (array !== undefined) {
 +
      return (read + '').split('.').reduce(indexcheck, array);
 +
    }
 +
   }
  
// Init program, check if instructions are an object (not an array but has multiple keys) :
+
  // Main object / array processing instrument
// This is the main path of the function. Could be improved to have it for simple array of instructions
+
  // Array can be a composition of objects and arrays
if ( ( !Array.isArray(read) ) && ( Object.keys(read).length > 0 ) ) {
+
  // Read is the instructions, could be an array, or a single path, but for now it should be an object based on our inner convention, example:
+
  /*
Object.keys(read).forEach( function(path) {
+
  relational_id_list = {  
debuglog("instructions are an object, in path " + path);
+
  controller_id: [ wbEStructure['instanceOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 96 ],
 +
  personal_data_id: [ wbEStructure['subclassOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 421 ],
 +
  interface_button_id: [ wbEStructure ['instanceOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 487 ]
 +
  }
 +
  */
  
//||||||||||||||||||||||||||[ Check if elements of instruction object are arrays themselves ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
  function proceed(array, read) {
+
    var ret_obj = {},
if ( Array.isArray (read[path]) ) {
+
      temp_obj = array,
  
// for each path, future_instructional_return will be filled with the future_return_partition after proceeding through that path
+
      // If we encounter something seriously wrong we will just raise a red flag by setting this false, will check before returning this.
var future_return_partition = temp_obj;
+
      success_o_meter = true,
  
Object.keys(read[path]).forEach( function( path2 ) {
+
      // If all goes well, for each path checked, we will have a member in this
 +
      future_instructional_return = [];
  
debuglog("instructions are an array of arrays, going through " + read[ path ][ path2 ] );
+
    //|||||||||||||||||||||||||||||||||||||||||||||||||||||[ I N S T R U C T I O N S  C O N T R O L  ]||||||||||||||||||||||||||||||||||||||||||||||||||||||
// for each step, see if it led anywhere other than where we were.
 
if ( data_function( future_return_partition, read[ path ][ path2 ] ) != future_return_partition ){
 
// if it did, proceed;
 
future_return_partition = data_function( future_return_partition, read[ path ][ path2 ] );
 
} else {
 
// if it didn, raise flag
 
success_o_meter = false;
 
}
 
  
//|||||||||||||||||||||||||||||||||||||||||||||||||||[  I N S T R U C T I O N S  C O N T R O L |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
    // Init program, check if instructions are an object (not an array but has multiple keys) :
 +
    // This is the main path of the function. Could be improved to have it for simple array of instructions
 +
    if ((!Array.isArray(read)) && (Object.keys(read).length > 0)) {
  
});
+
      Object.keys(read).forEach(function(path) {
//Now that we went through the path, lets see if everything was ok.
+
        debuglog("instructions are an object, in path " + path);
if ( success_o_meter === true ) {
 
// If yes, put the result of the travel 'future_return_partition' into 'future_instructional_return'
 
 
debuglog("arrived at")
 
debuglog(future_return_partition);
 
future_instructional_return[path] = future_return_partition;
 
} else {
 
  
// Otherwise let's put an undefined in there
+
        //||||||||||||||||||||||||||[ Check if elements of instruction object are arrays themselves ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
debuglog("seeking derailed");
 
success_o_meter = true;
 
future_instructional_return[path] = undefined;
 
}
 
  
}
+
        if (Array.isArray(read[path])) {
  
//|||||||||||||||||| If instruction object element is not an array, lets just try to do that one step ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
          // for each path, future_instructional_return will be filled with the future_return_partition after proceeding through that path
// Unused
+
          var future_return_partition = temp_obj;
else {
 
 
// INCLUDE step block with read[path]
 
if ( data_function( temp_obj, read[ path ] ) !== temp_obj  ){
 
future_instructional_return[path] = data_function( temp_obj, read[ path ] ) ;
 
} else {
 
// future_instructional_return.push( undefined );
 
}
 
  
}
+
          Object.keys(read[path]).forEach(function(path2) {
});
 
  
// Now that we have gone through all paths, make future return object into what we got
+
            debuglog("instructions are an array of arrays, going through " + read[path][path2]);
temp_obj = future_instructional_return;
+
            // for each step, see if it led anywhere other than where we were.
}  
+
            if (data_function(future_return_partition, read[path][path2]) != future_return_partition) {
 +
              // if it did, proceed;
 +
              future_return_partition = data_function(future_return_partition, read[path][path2]);
 +
            } else {
 +
              // if it didn, raise flag
 +
              success_o_meter = false;
 +
            }
  
//||||||||||||[ If we are not in instruction object, let's see if we have an instruction array ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
            //|||||||||||||||||||||||||||||||||||||||||||||||||||[   I N S T R U C T I O N S  C O N T R O L |||||||||||||||||||||||||||||||||||||||||||||||||||||||||
//Unused, this part could be improved
 
else if ( Array.isArray(read) ) {
 
// If so let's follow the array of instructions
 
Object.keys( read ).forEach( function ( ect ) {
 
if ( data_function( temp_obj, read[ ect ] ) !== temp_obj  ){
 
 
temp_obj = data_function( temp_obj, read[ ect ] );
 
  
} else {
+
          });
 +
          //Now that we went through the path, lets see if everything was ok.
 +
          if (success_o_meter === true) {
 +
            // If yes, put the result of the travel 'future_return_partition' into 'future_instructional_return'
  
success_o_meter = false;
+
            debuglog("arrived at")
 +
            debuglog(future_return_partition);
 +
            future_instructional_return[path] = future_return_partition;
 +
          } else {
  
}
+
            // Otherwise let's put an undefined in there
});
+
            debuglog("seeking derailed");
}  
+
            success_o_meter = true;
 +
            future_instructional_return[path] = undefined;
 +
          }
  
//||||||||||||[ If we have a single instruction, let's try following that |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
        }
//Unused, this part could be improved
 
  
else {
+
        //|||||||||||||||||| If instruction object element is not an array, lets just try to do that one step ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
        // Unused
if ( data_function( temp_obj, read ) !== temp_obj  ){
+
        else {
 
temp_obj = data_function( temp_obj, read );
 
  
} else {
+
          // INCLUDE step block with read[path]
 +
          if (data_function(temp_obj, read[path]) !== temp_obj) {
 +
            future_instructional_return[path] = data_function(temp_obj, read[path]);
 +
          } else {
 +
            // future_instructional_return.push( undefined );
 +
          }
  
success_o_meter = false;
+
        }
 +
      });
  
}
+
      // Now that we have gone through all paths, make future return object into what we got
}
+
      temp_obj = future_instructional_return;
+
    }
// If we haven't got a not found signal along the way, let's try returning the object
 
  
if ( success_o_meter === true ) {
+
    //||||||||||||[ If we are not in instruction object, let's see if we have an instruction array ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return temp_obj;
+
    //Unused, this part could be improved
} else {
+
    else if (Array.isArray(read)) {
return undefined;
+
      // If so let's follow the array of instructions
}
+
      Object.keys(read).forEach(function(ect) {
}
+
        if (data_function(temp_obj, read[ect]) !== temp_obj) {
  
//|||||||||||||||||||||||||||||||||||||||||||||||||||||[   S T E P  B L O C K  ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
+
          temp_obj = data_function(temp_obj, read[ect]);
  
// Function that takes 1 step. Proceed (along a path) uses this for each step.
+
        } else {
  
function data_function ( temp_obj, moving ) {
+
          success_o_meter = false;
 
// we will return an array
 
var future_temp_obj = [];
 
  
// Check if we are on an array level,
+
        }
if ( Array.isArray( temp_obj ) ) {
+
      });
debuglog("data is on an array level");
+
    }
Object.keys( temp_obj ).forEach( function ( ect ) {
 
 
// if so, try proceeding in all directions.
 
debuglog("Within partition: " + ect );
 
if ( checkdive( temp_obj[ ect ], moving ) !== undefined ) {
 
future_temp_obj.push( checkdive( temp_obj[ ect ], moving ) );
 
}
 
// Put an element into the return array for each direction we could move into
 
  
});
+
    //||||||||||||[ If we have a single instruction, let's try following that |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 +
    //Unused, this part could be improved
 +
    else {
  
temp_obj = future_temp_obj;
+
      if (data_function(temp_obj, read) !== temp_obj) {
 
} else {
 
  
// if we are not on an array level, proceed with the path
+
        temp_obj = data_function(temp_obj, read);
 
debuglog("data is on an objective level");
 
 
if ( checkdive( temp_obj, moving ) !== temp_obj ) {
 
future_temp_obj = checkdive( temp_obj, moving );
 
}
 
  
if ( future_temp_obj !== undefined ){
+
      } else {
temp_obj = future_temp_obj;
 
} else {
 
debuglog('nothing to see here')
 
}
 
}
 
  
// NOTE this function works now but shows syntactic variance between the else branches
+
        success_o_meter = false;
// Rigorous testing recommended
 
  
return temp_obj;
+
      }
}
+
    }
 
//|||||||||||||||||||||||||||||||||||||||||||||||||||||[  E N D  O F  S T E P  B L O C K    ]|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
  
// This function substitutes a bunch of try catches and also tries to dive into 'array' in different ways
+
    // If we haven't got a not found signal along the way, let's try returning the object
  
function checkdive( array, read ){
+
    if (success_o_meter === true) {
 +
      return temp_obj;
 +
    } else {
 +
      return undefined;
 +
    }
 +
  }
  
// simple case, array is an object containing property 'read'
+
  //|||||||||||||||||||||||||||||||||||||||||||||||||||||[   S T E P  B L O C K  ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 
if ( check(array, read) !== undefined) {
 
return dive(array, read);
 
}
 
 
// array case, 'array' is an actual array, lets return an array of successful trials to dive into each direction
 
 
if ( Array.isArray(array) ) {
 
var potential_return = [];
 
Object.keys(array).forEach( function(item){
 
if ( check(array[item], read) !== undefined ) {
 
potential_return.push( dive( array[item], read) );
 
}
 
});
 
return potential_return;
 
}
 
 
// mystical case, 'what you have been seeking you had it all along... or at least you have it now'
 
// This is for when you already at a value level, and are looking for that value.
 
// Or when on an object level, and looking for that object
 
// or when on an array level, and looking for that array :O
 
 
if ( array === read ) {
 
return read;
 
}
 
 
/* If we did this, it would probably open up a wormhole or a segfault, or that strange error message browsers give when they are maxed out
 
  
if (Object.keys( array ).length > 0 ){
+
  // Function that takes 1 step. Proceed (along a path) uses this for each step.
Object.keys( array ).forEach( function ( piece ) {
 
if ( array[ piece ] === read ) { return read };
 
});
 
}
 
*/
 
}
 
  
// Try parsing json. If not a json, go void.
+
  function data_function(temp_obj, moving) {
this.rxjson( rx ) {
 
return interjson( rx );
 
}
 
  
function interjson( obj ) {
+
    // we will return an array
try {
+
    var future_temp_obj = [];
return JSON.parse( obj )
 
} catch (e) {
 
// if not JSON, do silly things
 
debuglog('not a json ¯\_(ツ)_/¯');
 
};
 
}
 
  
// Heavyweight solution to suppress error messages.  
+
    // Check if we are on an array level,
 +
    if (Array.isArray(temp_obj)) {
 +
      debuglog("data is on an array level");
 +
      Object.keys(temp_obj).forEach(function(ect) {
  
function debuglog( l0g ){
+
        // if so, try proceeding in all directions.
if ( Debug_switch ) {
+
        debuglog("Within partition: " + ect);
debuglog( l0g );
+
        if (checkdive(temp_obj[ect], moving) !== undefined) {
}
+
          future_temp_obj.push(checkdive(temp_obj[ect], moving));
}
+
        }
}
+
        // Put an element into the return array for each direction we could move into
 +
 
 +
      });
 +
 
 +
      temp_obj = future_temp_obj;
 +
 
 +
    } else {
 +
 
 +
      // if we are not on an array level, proceed with the path
 +
 
 +
      debuglog("data is on an objective level");
 +
 
 +
      if (checkdive(temp_obj, moving) !== temp_obj) {
 +
        future_temp_obj = checkdive(temp_obj, moving);
 +
      }
 +
 
 +
      if (future_temp_obj !== undefined) {
 +
        temp_obj = future_temp_obj;
 +
      } else {
 +
        debuglog('nothing to see here')
 +
      }
 +
    }
 +
 
 +
    // NOTE this function works now but shows syntactic variance between the else branches
 +
    // Rigorous testing recommended
 +
 
 +
    return temp_obj;
 +
  }
 +
 
 +
  //|||||||||||||||||||||||||||||||||||||||||||||||||||||[  E N D  O F  S T E P  B L O C K    ]|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 +
 
 +
  // This function substitutes a bunch of try catches and also tries to dive into 'array' in different ways
 +
 
 +
  function checkdive(array, read) {
 +
 
 +
    // simple case, array is an object containing property 'read'
 +
 
 +
    if (check(array, read) !== undefined) {
 +
      return dive(array, read);
 +
    }
 +
 
 +
    // array case, 'array' is an actual array, lets return an array of successful trials to dive into each direction
 +
 
 +
    if (Array.isArray(array)) {
 +
      var potential_return = [];
 +
      Object.keys(array).forEach(function(item) {
 +
        if (check(array[item], read) !== undefined) {
 +
          potential_return.push(dive(array[item], read));
 +
        }
 +
      });
 +
      return potential_return;
 +
    }
 +
 
 +
    // mystical case, 'what you have been seeking you had it all along... or at least you have it now'
 +
    // This is for when you already at a value level, and are looking for that value.
 +
    // Or when on an object level, and looking for that object
 +
    // or when on an array level, and looking for that array :O
 +
 
 +
    if (array === read) {
 +
      return read;
 +
    }
 +
 
 +
    /* If we did this, it would probably open up a wormhole or a segfault, or that strange error message browsers give when they are maxed out
 +
 
 +
    if (Object.keys( array ).length > 0 ){
 +
    Object.keys( array ).forEach( function ( piece ) {
 +
    if ( array[ piece ] === read ) { return read };
 +
    });
 +
    }
 +
    */
 +
  }
 +
 
 +
  // Try parsing json. If not a json, go void.
 +
  this.rxjson = function(rx) {
 +
    return interjson(rx);
 +
  }
 +
 
 +
  function interjson(obj) {
 +
    try {
 +
      return JSON.parse(obj)
 +
    } catch (e) {
 +
      // if not JSON, do silly things
 +
      debuglog('not a json ¯\_(ツ)_/¯');
 +
    };
 +
  }
 +
 
 +
  // Heavyweight solution to suppress error messages.
 +
 
 +
  function debuglog(l0g) {
 +
    if (Debug_switch) {
 +
      console.log(l0g);
 +
    }
 +
  }
 +
}

Latest revision as of 12:07, 4 June 2019

// License: GPL
// Wikibase Processor
console.log('wbprocessor loading');

function WikibaseProcessorContainer(universe, location) {

  Debug_switch = false;

  this.main = interjson(checkdive(universe, location));
  var the = this.main;

  /* The following is the main exposed function of the current Wb Processing class
  	usage cases

  	to check the last value in a location given by a preceding array of internal paths to find, with the possibility of array layers between elements of array of paths: 
  	wbproc.checkentity( [ wbEStruct['instanceOfRelations'], wbEStruct['IDPropLoc'], wbEStruct['IDName'], 96 ] );

  	to return for example content of default value given by array of location paths, or check for existence of 
  	wbproc.checkentity( { default_value: [ wbEStruct['defaultValRelation'], wbEStruct['IDPropLoc'] ] } )


  */

  this.checkentity = function(paths) {
    if ((the !== undefined) && (paths !== undefined)) {
      return proceed(the, paths);
    }
  }

  // Exposed general wrapper for proceed for object other than what the class is originally instanced on, currently unused
  // Could be used to create a further function to cross check current object with another object 'universe' with another for example

  this.xcontains = function(unv, angle) {
    if ((unv !== undefined) && (angle !== undefined)) {
      return proceed(unv, angle);
    };
  }

  /* Exposed helper function to get Entity object of alien entity, if ever needed */

  this.EnqueueWB = async function(idk) {
    var k = await wbqueue(idk);
    return k;
  }

  /* Private part of wb Entity getter */

  async function wbqueue(id) {
    return new Promise(
      function(resolve, reject) {
        $.getJSON('/w/api.php?action=wbgetentities&format=json&ids=' + id, function(json) {
          var h = json.entities;
          resolve(h);
        })
      }).then(function(result) {
      debuglog(result);
      return result;
    });
  }


  // the list of private helper functions, could not be accessed from outside
  // helper function for descend into an object if key exists, otherwise stay at current level of object		
  function indexinterpolate(obj, i) {
    return (obj[i] !== undefined) ? obj[i] : obj
  };

  // helper function for checking a part of an array exists, if it doesn't, go undefined
  function indexcheck(obj, i) {
    if (obj !== undefined) {
      return (obj[i] !== undefined) ? obj[i] : undefined
    }
  };

  // dive selects matrix.a.b.c.d from the array called matrix and 'a.b.c.d' as string
  // if a.b.c.d does not exists, it returns the substructure until the substructure exists, if d does not exist, it returns matrix.a.b.c e.g.
  function dive(array, read) {
    if (array !== undefined) {
      return (read + '').split('.').reduce(indexinterpolate, array);
    }
  }
  // Check returns matrix.a.b.c.d from 'array' ~ 'matrix' and 'read' ~ 'a.b.c.d' only if it exists all the way, otherwise go undefined
  function check(array, read) {
    if (array !== undefined) {
      return (read + '').split('.').reduce(indexcheck, array);
    }
  }

  // Main object / array processing instrument
  // Array can be a composition of objects and arrays 
  // Read is the instructions, could be an array, or a single path, but for now it should be an object based on our inner convention, example:
  /* 
  	relational_id_list = { 
  		controller_id: [ wbEStructure['instanceOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 96 ],
  		personal_data_id: [ wbEStructure['subclassOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 421 ],
  		interface_button_id: [ wbEStructure ['instanceOfRelations'], wbEStructure['IDPropLoc'], wbEStructure['IDName'], 487 ]
  	} 
  */

  function proceed(array, read) {
    var ret_obj = {},
      temp_obj = array,

      // If we encounter something seriously wrong we will just raise a red flag by setting this false, will check before returning this.
      success_o_meter = true,

      // If all goes well, for each path checked, we will have a member in this
      future_instructional_return = [];

    //|||||||||||||||||||||||||||||||||||||||||||||||||||||[ I N S T R U C T I O N S  C O N T R O L   ]||||||||||||||||||||||||||||||||||||||||||||||||||||||

    // Init program, check if instructions are an object (not an array but has multiple keys) :
    // This is the main path of the function. Could be improved to have it for simple array of instructions
    if ((!Array.isArray(read)) && (Object.keys(read).length > 0)) {

      Object.keys(read).forEach(function(path) {
        debuglog("instructions are an object, in path " + path);

        //||||||||||||||||||||||||||[ Check if elements of instruction object are arrays themselves ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

        if (Array.isArray(read[path])) {

          // for each path, future_instructional_return will be filled with the future_return_partition after proceeding through that path
          var future_return_partition = temp_obj;

          Object.keys(read[path]).forEach(function(path2) {

            debuglog("instructions are an array of arrays, going through " + read[path][path2]);
            // for each step, see if it led anywhere other than where we were.
            if (data_function(future_return_partition, read[path][path2]) != future_return_partition) {
              // if it did, proceed;
              future_return_partition = data_function(future_return_partition, read[path][path2]);
            } else {
              // if it didn, raise flag
              success_o_meter = false;
            }

            //|||||||||||||||||||||||||||||||||||||||||||||||||||[   I N S T R U C T I O N S   C O N T R O L |||||||||||||||||||||||||||||||||||||||||||||||||||||||||

          });
          //Now that we went through the path, lets see if everything was ok.
          if (success_o_meter === true) {
            // If yes, put the result of the travel 'future_return_partition' into 'future_instructional_return'

            debuglog("arrived at")
            debuglog(future_return_partition);
            future_instructional_return[path] = future_return_partition;
          } else {

            // Otherwise let's put an undefined in there
            debuglog("seeking derailed");
            success_o_meter = true;
            future_instructional_return[path] = undefined;
          }

        }

        //|||||||||||||||||| If instruction object element is not an array, lets just try to do that one step ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
        // Unused
        else {

          // INCLUDE step block with read[path] 
          if (data_function(temp_obj, read[path]) !== temp_obj) {
            future_instructional_return[path] = data_function(temp_obj, read[path]);
          } else {
            // future_instructional_return.push( undefined );
          }

        }
      });

      // Now that we have gone through all paths, make future return object into what we got
      temp_obj = future_instructional_return;
    }

    //||||||||||||[ If we are not in instruction object, let's see if we have an instruction array ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    //Unused, this part could be improved
    else if (Array.isArray(read)) {
      // If so let's follow the array of instructions
      Object.keys(read).forEach(function(ect) {
        if (data_function(temp_obj, read[ect]) !== temp_obj) {

          temp_obj = data_function(temp_obj, read[ect]);

        } else {

          success_o_meter = false;

        }
      });
    }

    //||||||||||||[ If we have a single instruction, let's try following that |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
    //Unused, this part could be improved
    else {

      if (data_function(temp_obj, read) !== temp_obj) {

        temp_obj = data_function(temp_obj, read);

      } else {

        success_o_meter = false;

      }
    }

    // If we haven't got a not found signal along the way, let's try returning the object

    if (success_o_meter === true) {
      return temp_obj;
    } else {
      return undefined;
    }
  }

  //|||||||||||||||||||||||||||||||||||||||||||||||||||||[   S T E P   B L O C K   ]||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

  // Function that takes 1 step. Proceed (along a path) uses this for each step.

  function data_function(temp_obj, moving) {

    // we will return an array
    var future_temp_obj = [];

    // Check if we are on an array level, 
    if (Array.isArray(temp_obj)) {
      debuglog("data is on an array level");
      Object.keys(temp_obj).forEach(function(ect) {

        // if so, try proceeding in all directions.
        debuglog("Within partition: " + ect);
        if (checkdive(temp_obj[ect], moving) !== undefined) {
          future_temp_obj.push(checkdive(temp_obj[ect], moving));
        }
        // Put an element into the return array for each direction we could move into

      });

      temp_obj = future_temp_obj;

    } else {

      // if we are not on an array level, proceed with the path

      debuglog("data is on an objective level");

      if (checkdive(temp_obj, moving) !== temp_obj) {
        future_temp_obj = checkdive(temp_obj, moving);
      }

      if (future_temp_obj !== undefined) {
        temp_obj = future_temp_obj;
      } else {
        debuglog('nothing to see here')
      }
    }

    // NOTE this function works now but shows syntactic variance between the else branches
    // Rigorous testing recommended

    return temp_obj;
  }

  //|||||||||||||||||||||||||||||||||||||||||||||||||||||[  E N D   O F   S T E P   B L O C K    ]|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

  // This function substitutes a bunch of try catches and also tries to dive into 'array' in different ways

  function checkdive(array, read) {

    // simple case, array is an object containing property 'read'

    if (check(array, read) !== undefined) {
      return dive(array, read);
    }

    // array case, 'array' is an actual array, lets return an array of successful trials to dive into each direction

    if (Array.isArray(array)) {
      var potential_return = [];
      Object.keys(array).forEach(function(item) {
        if (check(array[item], read) !== undefined) {
          potential_return.push(dive(array[item], read));
        }
      });
      return potential_return;
    }

    // mystical case, 'what you have been seeking you had it all along... or at least you have it now'
    // This is for when you already at a value level, and are looking for that value.
    // Or when on an object level, and looking for that object
    // or when on an array level, and looking for that array :O 

    if (array === read) {
      return read;
    }

    /* If we did this, it would probably open up a wormhole or a segfault, or that strange error message browsers give when they are maxed out

    if (Object.keys( array ).length > 0 ){
    	Object.keys( array ).forEach( function ( piece ) {
    		if ( array[ piece ] === read ) { return read };
    	});
    }
    */
  }

  // Try parsing json. If not a json, go void.
  this.rxjson = function(rx) {
    return interjson(rx);
  }

  function interjson(obj) {
    try {
      return JSON.parse(obj)
    } catch (e) {
      // if not JSON, do silly things
      debuglog('not a json ¯\_(ツ)_/¯');
    };
  }

  // Heavyweight solution to suppress error messages. 

  function debuglog(l0g) {
    if (Debug_switch) {
      console.log(l0g);
    }
  }
}