docs: function jptr(obj, prop, newValue) {
      if (typeof obj === 'undefined') return false;
      if (!prop || (prop === '#')) return (typeof newValue !== 'undefined' ? newValue : obj);
  
      if (prop.indexOf('#')>=0) {
          let parts = prop.split('#');
          let uri = parts[0];
          if (uri) return false; // we do internal resolution only
          prop = parts[1];
          prop = decodeURIComponent(prop.slice(1).split('+').join(' '));
      }
      if (prop.startsWith('/')) prop = prop.slice(1);
  
      let components = prop.split('/');
      for (let i=0;i<components.length;i++) {
          components[i] = jpunescape(components[i]);
  
          let setAndLast = (typeof newValue !== 'undefined') && (i == components.length-1);
  
          let index = parseInt(components[i],10);
          if (!Array.isArray(obj) || isNaN(index) || (index.toString() !== components[i])) {
              index = (Array.isArray(obj) && components[i] === '-') ? -2 : -1;
          }
          else {
              components[i] = (i > 0) ? components[i-1] : ''; // backtrack to indexed property name
          }
  
          if ((index != -1) || obj.hasOwnProperty(components[i])) {
              if (index >= 0) {
                  if (setAndLast) {
                      obj[index] = newValue;
                  }
                  obj = obj[index];
              }
              else if (index === -2) {
                  if (setAndLast) {
                      if (Array.isArray(obj)) {
                          obj.push(newValue);
                      }
                      return newValue;
                  }
                  else return undefined;
              }
              else {
                  if (setAndLast) {
                      obj[components[i]] = newValue;
                  }
                  obj = obj[components[i]];
              }
          }
          else {
              if ((typeof newValue !== 'undefined') && (typeof obj === 'object') &&
                  (!Array.isArray(obj))) {
                  obj[components[i]] = (setAndLast ? newValue : ((components[i+1] === '0' || components[i+1] === '-') ? [] : {}));
                  obj = obj[components[i]];
              }
              else return false;
          }
      }
      return obj;
  }