function backslash4Class() //useful library functions in this type/class
{ let _t = this; //space saving shortcut
  _t.version='0.0.6';
  _t.date='2022-12-12';

  _t.init = () => 
  {
    //this does nothing yet
    _t.log('ccdev bs4 init');
  }

  /**
   * fires the callbackk immediately if the DOM is loaded otherwise adds the function to a DOMContentLoaded event
   * @param {function} callback 
   * @return {void}
   */
  _t.ready = (callback) =>
  {
    if (document.readyState != "loading") 
    { _t.log('ccdev bs4 readyState', document.readyState );
      callback();
    } else 
    { _t.log('ccdev bs4 readyState add listener');
      document.addEventListener("DOMContentLoaded", () => { callback() });
    }
  }
  _t.randomID = (length) => {
    var chars = '0123456789abcdefghiklmnopqrstuvwxyz'.split('');

    if (! length) {
        length = Math.floor(Math.random() * chars.length);
    }

    var str = '';
    for (var i = 0; i < length; i++) {
        str += chars[Math.floor(Math.random() * chars.length)];
    }
    return str;
};

  /**
   * plays a beeping bell sound, all paremeters optional
   * @param {number} vol       number 0-1 (default 0.5)
   * @param {number} freq      hertz (default 830.6)
   * @param {number} duration  seconds (default 0.7)
   * @return {void}
   */
  _t.bell = (vol=0.5, freq=830.6, duration=0.7) =>
  { var context = new AudioContext();
    var o = context.createOscillator();
    o.frequency.value = freq;
    var  g = context.createGain();
    o.connect(g);
    g.connect(context.destination);
    g.gain.exponentialRampToValueAtTime(vol, context.currentTime + 0.00001);
    g.gain.exponentialRampToValueAtTime(vol/2, context.currentTime + 0.1);
    g.gain.exponentialRampToValueAtTime(0.00001, context.currentTime + duration);

    o.start(0);
  }

  _t.hasJsonStructure = (str) =>
  {
    if (typeof str !== 'string') return false;
    try {
        const result = JSON.parse(str);
        const type = Object.prototype.toString.call(result);
        return type === '[object Object]' 
            || type === '[object Array]';
    } catch (err) {
        return false;
    }
  }

  _t.log = (...args) => {
    //only do a console if npm run dev mode or VITE_BS4LOG=="1" in env file at build time
    if(import.meta.env.DEV || (import.meta.env.VITE_BS4LOG=="1"))
        console.log(...args);
  }

  /**
   * shortcut/alias for document.querySelector on the document
   */
  _t.$ = document.querySelector.bind(document); //like jQuery

  /**
   * Query the DOM for nodes matching the given selector, using querySelectorAll, scoped to context (or the whole document)
   *
   * @param {String} selector
   * @param {Element} [context = document]
   * @return {Array<Element>}
   */
  _t.$$ = (selector, context) =>
  { return toArray((context || document).querySelectorAll(selector))
  }
}
window.bs4 = new backslash4Class;
var bs4=window.bs4; //@deprecated
window.bs4.init();

//bs4 library functions -- @deprecated use the global windows.bs4 object
window.bs4RandomID = (length) => { //@deprecated use the global windows.bs4 object version
    return window.bs4.randomID(length);
};

console.bs4log = (...args) => {
  bs4.log(args);
}

export default bs4