<commit_before>/**
 * Copyright reelyActive 2020-2022
 * We believe in an open Internet of Things
 */


const Raddec = require('raddec');


/**
 * Device Class
 * Represents a radio-identifiable device.
 */
class Device {

  /**
   * Device constructor
   * @param {String} transmitterId The identifier of the transmitter.
   * @param {Number} transmitterIdType The identifier type of the transmitter.
   * @param {Object} parameters The parameters as a JSON object.
   * @constructor
   */
  constructor(transmitterId, transmitterIdType, parameters) {
    parameters = parameters || {};

    this.transmitterId = transmitterId;
    this.transmitterIdType = transmitterIdType;
    this.raddecs = [];
    this.latestRaddecEvent = null;
    this.pendingEvents = [ Raddec.events.APPEARANCE ];
    this.isPossibleDisplacement = false;
    this.timeout = new Date().getTime() + parameters.delayMilliseconds;
    this.disappearanceTimeout = new Date().getTime() +
                                parameters.disappearanceMilliseconds;
  }

  /**
   * Get the unique device signature based on the ID and type.
   */
  get signature() {
    return this.transmitterId + Raddec.identifiers.SIGNATURE_SEPARATOR +
           this.transmitterIdType;
  }

  /**
   * Determine whether or not the device has an identifier or nearest device
   * which matches one or more of the given signatures.
   */
  hasIdOrNearest(signatures) {
    let self = this;

    if(!signatures || !Array.isArray(signatures)) {
      return false;
    }

    if(signatures.includes(self.signature)) {
      return true;
    }

    if(self.statid && self.statid.hasOwnProperty('deviceIds')) {
      for(const signature of self.statid.deviceIds) {
        if(signatures.includes(signature)) {
          return true;
        }
      }
    }

    let nearest = compileNearest(self.latestRaddecEvent, self.dynamb);

    for(const item of nearest) {
      if(signatures.includes(item.device)) {
        return true;
      }
    }

    return false;
  }

  /**
   * Assemble a standard device representation limited to the given properties,
   * if included.
   * @param {Array} properties The optional subset of properties.
   */
  assemble(properties) {
    let self = this;
    let isPropertySubset = properties && Array.isArray(properties);
    let device = {};

    if(isPropertySubset) {
      properties.forEach(function(property) {
        if((property === 'raddec') && self.latestRaddecEvent)  {
          device.raddec = Object.assign({}, self.latestRaddecEvent);
        }
        else if(self.hasOwnProperty(property)) {
          device[property] = Object.assign({}, self[property]);
        }
      });
    }
    else {
      if(self.latestRaddecEvent) {
        device.raddec = Object.assign({}, self.latestRaddecEvent);
      }
      if(self.dynamb) {
        removeStaleDynambProperties(device);
        device.dynamb = Object.assign({}, self.dynamb);
      }
      if(self.statid) {
        device.statid = Object.assign({}, self.statid);
      }
    }

    return device;
  }

  /**
   * Assemble a contextual device representation.
   */
  assembleContext() {
    let self = this;
    let device = {};

    if(self.dynamb) {
      removeStaleDynambProperties(self);
      device.dynamb = Object.assign({}, self.dynamb);
    }
    if(self.statid) {
      device.statid = Object.assign({}, self.statid);
    }
    if(self.latestRaddecEvent) {
      device.nearest = compileNearest(self.latestRaddecEvent, self.dynamb);
    }

    return device;
  }

  /**
   * Handle an inbound raddec.
   * @param {Raddec} raddec The inbound raddec.
   * @param {Object} parameters The parameters as a JSON object.
   */
  handleRaddec(raddec, parameters) {
    let self = this;
    parameters = parameters || {};

    determinePossibleDisplacement(self, raddec, parameters);
    determineNewPacket(self, raddec, parameters);
    updateTimeout(self, parameters);
    insertRaddec(self, raddec, parameters);
  }<commit_msg>Do not add empty dynamb property when assembling device/context<commit_after>/**
 * Copyright reelyActive 2020-2022
 * We believe in an open Internet of Things
 */


const Raddec = require('raddec');


/**
 * Device Class
 * Represents a radio-identifiable device.
 */
class Device {

  /**
   * Device constructor
   * @param {String} transmitterId The identifier of the transmitter.
   * @param {Number} transmitterIdType The identifier type of the transmitter.
   * @param {Object} parameters The parameters as a JSON object.
   * @constructor
   */
  constructor(transmitterId, transmitterIdType, parameters) {
    parameters = parameters || {};

    this.transmitterId = transmitterId;
    this.transmitterIdType = transmitterIdType;
    this.raddecs = [];
    this.latestRaddecEvent = null;
    this.pendingEvents = [ Raddec.events.APPEARANCE ];
    this.isPossibleDisplacement = false;
    this.timeout = new Date().getTime() + parameters.delayMilliseconds;
    this.disappearanceTimeout = new Date().getTime() +
                                parameters.disappearanceMilliseconds;
  }

  /**
   * Get the unique device signature based on the ID and type.
   */
  get signature() {
    return this.transmitterId + Raddec.identifiers.SIGNATURE_SEPARATOR +
           this.transmitterIdType;
  }

  /**
   * Determine whether or not the device has an identifier or nearest device
   * which matches one or more of the given signatures.
   */
  hasIdOrNearest(signatures) {
    let self = this;

    if(!signatures || !Array.isArray(signatures)) {
      return false;
    }

    if(signatures.includes(self.signature)) {
      return true;
    }

    if(self.statid && self.statid.hasOwnProperty('deviceIds')) {
      for(const signature of self.statid.deviceIds) {
        if(signatures.includes(signature)) {
          return true;
        }
      }
    }

    let nearest = compileNearest(self.latestRaddecEvent, self.dynamb);

    for(const item of nearest) {
      if(signatures.includes(item.device)) {
        return true;
      }
    }

    return false;
  }

  /**
   * Assemble a standard device representation limited to the given properties,
   * if included.
   * @param {Array} properties The optional subset of properties.
   */
  assemble(properties) {
    let self = this;
    let isPropertySubset = properties && Array.isArray(properties);
    let device = {};

    if(isPropertySubset) {
      properties.forEach(function(property) {
        if((property === 'raddec') && self.latestRaddecEvent)  {
          device.raddec = Object.assign({}, self.latestRaddecEvent);
        }
        else if(self.hasOwnProperty(property)) {
          device[property] = Object.assign({}, self[property]);
        }
      });
    }
    else {
      if(self.latestRaddecEvent) {
        device.raddec = Object.assign({}, self.latestRaddecEvent);
      }
      if(self.dynamb) {
        removeStaleDynambProperties(device);
        if(Object.keys(self.dynamb).length) {
          device.dynamb = Object.assign({}, self.dynamb);
        }
      }
      if(self.statid) {
        device.statid = Object.assign({}, self.statid);
      }
    }

    return device;
  }

  /**
   * Assemble a contextual device representation.
   */
  assembleContext() {
    let self = this;
    let device = {};

    if(self.dynamb) {
      removeStaleDynambProperties(device);
      if(Object.keys(self.dynamb).length) {
        device.dynamb = Object.assign({}, self.dynamb);
      }
    }
    if(self.statid) {
      device.statid = Object.assign({}, self.statid);
    }
    if(self.latestRaddecEvent) {
      device.nearest = compileNearest(self.latestRaddecEvent, self.dynamb);
    }

    return device;
  }

  /**
   * Handle an inbound raddec.
   * @param {Raddec} raddec The inbound raddec.
   * @param {Object} parameters The parameters as a JSON object.
   */
  handleRaddec(raddec, parameters) {
    let self = this;
    parameters = parameters || {};

    determinePossibleDisplacement(self, raddec, parameters);
    determineNewPacket(self, raddec, parameters);
    updateTimeout(self, parameters);
    insertRaddec(self, raddec, parameters);
  }
{'fraction_non_alphanumeric': 0.11481663795225203, 'fraction_numerical': 0.0019689884321929607, 'mean_word_length': 2.731404958677686, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1592470', 'n_tokens_mistral': 2434, 'n_tokens_neox': 2356, 'n_words': 548}