### Install QTI Components
Source: https://github.com/citolab/qti-components/blob/main/docs/hi-qti.mdx
Use npm to install the QTI Components package. This is the first step before importing the web components.
```sh
npm install @citolab/qti-components
```
--------------------------------
### Install Dependencies
Source: https://github.com/citolab/qti-components/blob/main/AGENTS.md
Use this command to install all project dependencies.
```bash
pnpm install
```
--------------------------------
### Start Interactions Storybook Only
Source: https://github.com/citolab/qti-components/blob/main/AGENTS.md
Launches the Storybook instance specifically for the QTI interaction package.
```bash
pnpm storybook:interactions
```
--------------------------------
### Start Root Storybook and CEM Watch
Source: https://github.com/citolab/qti-components/blob/main/AGENTS.md
Starts the main Storybook instance and the CEM (Component, Element, Module) watch process for the entire repository.
```bash
pnpm storybook
```
--------------------------------
### qti-graphic-gap-match-interaction Drag and Drop Setup
Source: https://github.com/citolab/qti-components/blob/main/packages/interactions/core/src/mixins/drag-drop/drag-drop.md
Illustrates the HTML structure for a qti-graphic-gap-match-interaction, featuring slots for prompts, draggable images, and hotspots.
```html
↳ prompt
↳
↳
```
--------------------------------
### qti-order-interaction Drag and Drop Setup
Source: https://github.com/citolab/qti-components/blob/main/packages/interactions/core/src/mixins/drag-drop/drag-drop.md
Shows the HTML structure for a qti-order-interaction, defining slots for prompts, draggable choices, and a droppable list.
```html
↳ prompt
↳
Rubens <-- drag
Jenson <-- drag
Michael <-- drag
{
<-- drop
correctResponse
}
```
--------------------------------
### qti-associate-interaction Drag and Drop Setup
Source: https://github.com/citolab/qti-components/blob/main/packages/interactions/core/src/mixins/drag-drop/drag-drop.md
Shows the HTML structure for a qti-associate-interaction, with slots for prompts, draggable choices, and distinct droppable areas.
```html
↳ prompt
↳
Antonio
Capulet
Demetrius
```
--------------------------------
### qti-match-interaction Drag and Drop Setup
Source: https://github.com/citolab/qti-components/blob/main/packages/interactions/core/src/mixins/drag-drop/drag-drop.md
Illustrates the HTML structure for a qti-match-interaction using slots for prompts and draggable/droppable choices within simple match sets.
```html
↳ prompt
↳
Capulet <-- drag
Demetrius <-- drag
A Midsummer-Night's <-- drop
Romeo and Juliet <-- drop
```
--------------------------------
### qti-gap-match-interaction Drag and Drop Setup
Source: https://github.com/citolab/qti-components/blob/main/packages/interactions/core/src/mixins/drag-drop/drag-drop.md
Defines the HTML structure for a qti-gap-match-interaction, with slots for prompts, draggable gap texts, and droppable gaps.
```html
↳ prompt
↳
winter <-- drag
spring <-- drag
summer <-- drag
autumn <-- drag
↳
Now is the of our discontent
Made glorious by this sun of York;
And all the clouds that lour'd upon our house
In the deep bosom of the ocean buried.
```
--------------------------------
### Simplified GET and POST Requests
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Provides simplified interfaces for making GET and POST requests. These methods abstract away some of the complexity of the core AJAX function.
```javascript
n.each(['get', 'post'], function (a, b) {
n[b] = function (a, c, d, e) {
return (
n.isFunction(c) && ((e = e || d), (d = c), (c = void 0)),
n.ajax(n.extend({ url: a, type: b, dataT
);
};
})
```
--------------------------------
### Handle Touch Start Event
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Initializes touch event tracking by storing the touch coordinates. This is a precursor to handling touch move and end events.
```javascript
if (void 0 === a.changedTouches) return void this._mousedown(a); var b = a.changedTouches[0]; (this.touchX = b.pageX), (this.touchY = b.pageY);
```
--------------------------------
### Register Web Components
Source: https://github.com/citolab/qti-components/blob/main/readme.md
Import and register the web components in your JavaScript application to enable the rendering of QTI items. This step is necessary after installing via npm.
```javascript
import '@citolab/qti-components';
```
--------------------------------
### Get Default Options for BMI-meter
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Retrieves the default configuration options for the BMI-meter component.
```javascript
(c.prototype.getDefaults = function () { return c.DEFAULTS; })
```
--------------------------------
### QTI Gap Match Interaction Example
Source: https://github.com/citolab/qti-components/blob/main/packages/interactions/core/src/mixins/drag-drop-observables/drag-drop.md
Illustrates a QTI gap match interaction where gap text elements are draggable and gap elements are the drop targets. Does not use clone drags.
```html
↳ prompt
↳
winter <-- drag
spring <-- drag
summer <-- drag
autumn <-- drag
↳
Now is the of our discontent
Made glorious by this sun of York;
And all the clouds that lour'd upon our house
In the deep bosom of the ocean buried.
```
--------------------------------
### jQuery Animation Setup
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Configures jQuery's animation speed and default settings. It allows setting custom durations, easing functions, and completion callbacks for animations.
```javascript
(n.Animation = n.extend(_a, {
tweeners: {
'*': [
function (a, b) {
var c = this.createTween(a, b);
return W(c.elem, a, T.exec(b), c), c;
}
]
},
tweener: function (a, b) {
n.isFunction(a) ? ((b = a), (a = ['*'])) : (a = a.match(G));
for (var c, d = 0, e = a.length; e > d; d++) (c = a[d]), (_a.tweeners[c] = _a.tweeners[c] || []), _a.tweeners[c].unshift(b);
},
prefilters: [Za],
prefilter: function (a, b) {
b ? _a.prefilters.unshift(a) : _a.prefilters.push(a);
}
})),
(n.speed = function (a, b, c) {
var d = a && 'object' == typeof a ? n.extend({}, a) : {
complete: c || (!c && b) || (n.isFunction(a) && a),
duration: a,
easing: (c && b) || (b && !n.isFunction(b) && b)
};
return (
((d.duration = n.fx.off ? 0 : 'number' == typeof d.duration ? d.duration : d.duration in n.fx.speeds ? n.fx.speeds[d.duration] : n.fx.speeds._default),
(null != d.queue && d.queue !== !0) || (d.queue = 'fx'),
(d.old = d.complete),
(d.complete = function () {
n.isFunction(d.old) && d.old.call(this), d.queue && n.dequeue(this, d.queue);
}),
d
);
});
```
--------------------------------
### Queue Management: .queue()
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/index.html
Manage the queue of functions to be executed for a specific element and event queue (default 'fx'). Use .queue() to get the current queue, or to add a function to it. Ensure proper handling of 'inprogress' states for animations.
```javascript
d.queue(this, e, t)
```
--------------------------------
### Handle CSS Properties and Styles
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Provides utilities for getting and setting CSS properties, including handling vendor prefixes and complex calculations like pixel margins and widths. Use this for reliable style manipulation across different browsers.
```javascript
createElement('div'); if (h.style) { (h.style.backgroundClip = 'content-box'), (h.cloneNode(!0).style.backgroundClip = ''), (l.clearCloneStyle = 'content-box' === h.style.backgroundClip), (g.style.cssText = 'border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute'), g.appendChild(h); function i() { (h.style.cssText = '-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%'), (h.innerHTML = ''), Ea.appendChild(g); var d = a.getComputedStyle(h); (b = '1%' !== d.top), (f = '2px' === d.marginLeft), (c = '4px' === d.width), (h.style.marginRight = '50%'), (e = '4px' === d.marginRight), Ea.removeChild(g); } n.extend(l, { pixelPosition: function () { return i(), b; }, boxSizingReliable: function () { return null == c && i(), c; }, pixelMarginRight: function () { return null == c && i(), e; }, reliableMarginLeft: function () { return null == c && i(), f; }, reliableMarginRight: function () { var b, c = h.appendChild(d.createElement('div')); return ( (c.style.cssText = h.style.cssText = '-webkit-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0'), (c.style.marginRight = c.style.width = '0'), (h.style.width = '1px'), Ea.appendChild(g), (b = !parseFloat(a.getComputedStyle(c).marginRight)), Ea.removeChild(g), h.removeChild(c), b ); } }); }
```
--------------------------------
### FacetCommunication Class for QTI Player Interaction
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Handles communication with the QTI player, including getting and setting responses. It finds the CES object in the window or parent window and binds a reset event handler.
```javascript
var FacetCommunication = (function () {
function FacetCommunication(initialResponse, resetElement) {
this.ces = null;
this.initialResponse = null;
if (window['CES']) {
this.ces = window['CES'];
} else if (window.parent['CES']) {
this.ces = window.parent['CES'];
}
if (this.ces) {
this.initialResponse = initialResponse;
if (resetElement != null) resetElement.addEventListener('click', this.resetResponse.bind(this));
} else {
console.log('No player found. No communication possible with QTI-Player');
}
}
FacetCommunication.prototype.getResponse = function () {
var response = null;
if (this.ces) {
if (this.ces.getResponse() != undefined && this.ces.getResponse() != '') {
try {
response = JSON.parse(this.ces.getResponse());
} catch (e) {
console.log('Not a valid response : ' + e);
}
} else {
console.log('Empty response');
}
} else {
console.log('No player found');
}
return response;
};
FacetCommunication.prototype.setResponse = function (model, answer) {
if (answer === void 0) {
answer = null;
}
var responseArray = [];
var modelSerialized = null;
try {
if (model) modelSerialized = JSON.stringify(model);
else modelSerialized = '';
} catch (e) {
console.log('Not a valid model : ' + e);
}
responseArray.push(modelSerialized);
if (answer != null && answer.constructor === Array) {
responseArray = responseArray.concat(answer);
}
if (modelSerialized != null) {
if (this.ces) {
console.log('setAnswer');
this.ces.setResponse(modelSerialized);
} else {
console.log('setResponse : No communication possible with QTI-Player');
console.log('answer from CI was : ' + modelSerialized);
}
}
};
FacetCommunication.prototype.resetResponse = function (e) {
if (e === void 0) {
e = null;
}
this.setResponse(this.initialResponse);
};
return FacetCommunication;
})();
```
--------------------------------
### jQuery Queue and Dequeue Plugin Methods
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Extends jQuery.fn to provide chainable methods for managing element queues. Use `.queue()` to set or get a queue, and `.dequeue()` to advance to the next item.
```javascript
n.fn.extend({ queue: function (a, b) { var c = 2; return ( 'string' != typeof a && ((b = a), (a = 'fx'), c--) ), arguments.length < c ? n.queue(this[0], a) : void 0 === b ? this : this.each(function () { var c = n.queue(this, a, b); n._queueHooks(this, a), 'fx' === a && 'inprogress' !== c[0] && n.dequeue(this, a); }) ); }, dequeue: function (a) { return this.each(function () { n.dequeue(this, a); }); }, clearQueue: function (a) { return this.queue(a || 'fx', []); }, promise: function (a, b) { var c, d = 1, e = n.Deferred(), f = this, g = this.length, h = function () { --d || e.resolveWith(f, [f]); }; 'string' != typeof a && ((b = a), (a = void 0)), (a = a || 'fx'); while (g--) (c = N.get(f[g], a + 'queueHooks')), c && c.empty && (d++, c.empty.add(h)); return h(), e.promise(b); } });
```
--------------------------------
### Function Proxying and Guid Generation
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/index.html
Creates a new function that, when called, has its 'this' keyword set to a provided value. Also manages a unique GUID for functions.
```javascript
guid: 1,
```
```javascript
proxy: function (e, t) { var n, r, o; return ( 'string' == typeof t && ((n = e[t]), (t = e), (e = n)), d.isFunction(e) ? ((r = i.call(arguments, 2)), ((o = function () { return e.apply(t || this, r.concat(i.call(arguments))); }).guid = e.guid = e.guid || d.guid++), o) : void 0 ); }
```
--------------------------------
### Get and Set CSS Properties
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Provides functions to get and set CSS properties of an element, including handling different units and box-sizing models. Use this for direct manipulation of element styles.
```javascript
css: function (a, b, c, d) { var e, f, g, h = n.camelCase(b); return ( (b = n.cssProps[h] || (n.cssProps[h] = Ma(h) || h)), (g = n.cssHooks[b] || n.cssHooks[h]), g && 'get' in g && (e = g.get(a, !0, c)), void 0 === e && (e = Fa(a, b, d)), 'normal' === e && b in Ja && (e = Ja[b]), '' === c || c ? ((f = parseFloat(e)), c === !0 || isFinite(f) ? f || 0 : e) : e ); }
```
--------------------------------
### Get and Set Form Element Values with jQuery
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Handles getting and setting values for various form elements like select, radio, and checkbox. Includes specific hooks for options and select elements.
```javascript
n.fn.extend({
val: function (a) {
var b, c, d, e = this[0]
{
if (arguments.length)
return (
(d = n.isFunction(a)),
this.each(function (c) {
var e
1 === this.nodeType &&
((e = d ? a.call(this, c, n(this).val()) : a),
null == e ? (e = '') : 'number' == typeof e ? (e += '') : n.isArray(e) && (e = n.map(e, function (a) { return null == a ? '' : a + '' })),
(b = n.valHooks[this.type] || n.valHooks[this.nodeName.toLowerCase()]),
(b && 'set' in b && void 0 !== b.set(this, e, 'value')) || (this.value = e))
})
)
if (e)
return (
(b = n.valHooks[e.type] || n.valHooks[e.nodeName.toLowerCase()]),
b && 'get' in b && void 0 !== (c = b.get(e, 'value')) ? c : ((c = e.value), 'string' == typeof c ? c.replace(gb, '') : null == c ? '' : c)
)
}
}
}),
n.extend({
valHooks: {
option: {
get: function (a) {
var b = n.find.attr(a, 'value')
return null != b ? b : n.trim(n.text(a)).replace(hb, ' ')
}
},
select: {
get: function (a) {
for ( var b, c, d = a.options, e = a.selectedIndex, f = 'select-one' === a.type || 0 > e, g = f ? null : [], h = f ? e + 1 : d.length, i = 0 > e ? h : f ? e : 0;
h > i;
i++
)
if (
((c = d[i]),
(c.selected || i === e) &&
(l.optDisabled ? !c.disabled : null === c.getAttribute('disabled')) &&
(!c.parentNode.disabled || !n.nodeName(c.parentNode, 'optgroup')))
) {
if (((b = n(c).val()), f)) return b
g.push(b)
}
return g
},
set: function (a, b) {
var c, d, e = a.options, f = n.makeArray(b), g = e.length
while (g--)
(d = e[g]),
(d.selected = n.inArray(n.valHooks.option.get(d), f) > -1) && (c = !0)
return c || (a.selectedIndex = -1), f
}
}
}
}),
n.each(['radio', 'checkbox'], function () {
(n.valHooks[this] = {
set: function (a, b) {
return n.isArray(b) ? (a.checked = n.inArray(n(a).val(), b) > -1) : void 0
}
}),
l.checkOn || (n.valHooks[this].get = function (a) {
return null === a.getAttribute('value') ? 'on' : a.value
})
});
```
--------------------------------
### Get Keycode for Comma
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/index.html
Returns the keycode value for the comma character (44).
```javascript
getkeycodeComma() { return 44; }
```
--------------------------------
### Import QTI Web Components
Source: https://github.com/citolab/qti-components/blob/main/docs/hi-qti.mdx
Import the necessary QTI web components into your project. This includes core components and specific test navigation components.
```js
import '@citolab/qti-components/qti-components';
import '@citolab/qti-components/qti-test/core';
import '@citolab/qti-components/qti-test/components/test-next';
import '@citolab/qti-components/qti-test/components/test-prev';
```
--------------------------------
### Controller Class Initialization
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/index.html
Initializes the Controller and FacetCommunication, and sets up the ViewModel and data handling.
```javascript
var ctrl, FacetCommunication = com.cito.custominteraction.communication.FacetCommunication;
class ViewModel {
constructor() {
this.data = [];
}
}
window.onload = function() {
ctrl = new Controller();
};
class Controller {
constructor() {
(this.placeTopRowTooltipBottom = !1),
(this.decimalsAllowed = !0),
(this.maxlength = 5),
(this.copyPasteAllowed = !0),
(this.copiedText = ''),
document.getElementById('help').addEventListener('click', this.help.bind(this));
var e = document.getElementById('reset');
e.addEventListener('click', this.reset.bind(this)),
(this.facetCommunication = new FacetCommunication(e)),
(this.viewModel = this.facetCommunication.getResponse()),
this.viewModel ? (this.data = this.viewModel.data) : (this.viewModel = new ViewModel()),
this.setMaxlength(),
this.data ? this.restoreData(this.data) : this.initializeData(),
this.setClassesForTooltipPlacement;
}
}
```
--------------------------------
### Get Element Offset Left
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Retrieves the left offset of an element relative to the viewport.
```javascript
function (a) {
return a.getBoundingClient
```
--------------------------------
### Build All Packages
Source: https://github.com/citolab/qti-components/blob/main/AGENTS.md
Compiles and builds all packages within the monorepo.
```bash
pnpm build
```
--------------------------------
### Get Element Dimensions
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Determines the dimensions of an element, handling different node types and browser compatibility.
```javascript
ow(b) ? b.document.documentElement['client' + a] : 9 === b.nodeType ? ((e = b.documentElement), Math.max( b.body['scroll' + a], e['scroll' + a], b.body['offset' + a], e['offset' + a], e['client' + a] )) : void 0 === d ? n.css(b, c, g) : n.style(b, c, d, g); }, b, f ? d : void 0, f, null ); }; });
```
--------------------------------
### Get Number of Decimal Places
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Calculates the number of digits after the decimal point in a number, considering scientific notation.
```javascript
function (a) {
var b = ('' + a).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
return b ? Math.max(0, (b[1] ? b[1].length : 0) - (b[2] ? +b[2] : 0)) : 0;
}
```
--------------------------------
### Get Delegate Options for BMI-meter
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Constructs an options object for delegated events, excluding any options that match the defaults.
```javascript
(c.prototype.getDelegateOptions = function () { var b = {}, c = this.getDefaults(); return ( this._options && a.each(this._options, function (a, d) { c[a] != d && (b[a] = d); }), b ); })
```
--------------------------------
### Create a Changeset
Source: https://github.com/citolab/qti-components/blob/main/docs/publishing.mdx
Use this command to initiate the creation of a new changeset file, which records changes for versioning and changelog generation.
```bash
pnpm run changeset
```
--------------------------------
### Configure AJAX Settings
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Sets up default AJAX settings and allows for merging custom configurations. Use this to define global defaults for all AJAX requests.
```javascript
ajaxSetup: function (a, b) {
return b ? yb(yb(a, n.ajaxSettings), b) : yb(n.ajaxSettings, a);
}
```
--------------------------------
### FacetCommunication Class
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/index.html
Manages communication with the QTI Player using the CES API. Handles setting and getting responses, and resetting them.
```javascript
var com;
!(function(e) {
!(function(e) {
!(function(e) {
!(function(e) {
var s = (function() {
function e(e, s) {
(this.ces = null),
(this.initialResponse = null),
window.CES
? (this.ces = window.CES)
: window.parent.CES && (this.ces = window.parent.CES),
this.ces
? (e instanceof HTMLElement ? (s = e) : (this.initialResponse = e), null != s && s.addEventListener('click', this.resetResponse.bind(this)))
: console.log('No player found. No communication possible with QTI-Player');
}
return (
(e.prototype.getResponse = function() {
var e = null;
if (this.ces)
if (void 0 !== this.ces.getResponse() && '' !== this.ces.getResponse()) try {
e = JSON.parse(this.ces.getResponse());
} catch (e) {
console.log('Not a valid response : ' + e);
} else console.log('Empty response');
else console.log('No player found');
return e;
}),
(e.prototype.setResponse = function(e) {
var s = null;
try {
s = e ? JSON.stringify(e) : '';
} catch (e) {
console.log('Not a valid model : ' + e);
}
null != s &&
(this.ces
? s === JSON.stringify(this.initialResponse)
? this.ces.setResponse('')
: (console.log('setAnswer'), this.ces.setResponse(s))
: (console.log('setResponse : No communication possible with QTI-Player'), console.log('answer from CI was : ' + s)));
}),
(e.prototype.resetResponse = function(e) {
void 0 === e && (e = null),
this.setResponse(this.initialResponse);
}),
e
);
})();
e.FacetCommunication = s;
})(e.communication || (e.communication = {}));
})(e.custominteraction || (e.custominteraction = {}));
})(e.cito || (e.cito = {}));
})(com || (com = {}));
```
--------------------------------
### Run Test Pipeline
Source: https://github.com/citolab/qti-components/blob/main/AGENTS.md
Executes the standard test suite across all packages.
```bash
pnpm test
```
--------------------------------
### Get Offset Parent
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Extends jQuery to find the closest positioned ancestor of an element. This is crucial for understanding positioning contexts.
```javascript
offsetParent: function () {
return this.map(function () {
var a = this.offsetParent;
while (a && 'static' === n.css(a, 'position')) a = a.offsetParent;
return a || Ea;
});
}
```
--------------------------------
### Import Components via CDN
Source: https://github.com/citolab/qti-components/blob/main/readme.md
Use this script to import the web components directly from a CDN. This is useful for quick integration without a build process.
```html
```
--------------------------------
### Initialize BMI-meter Component
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Initializes the BMI-meter component, setting up event listeners for click, hover, and focus events. It throws an error if the 'selector' option is not provided when initializing on the window.document object.
```javascript
this.init = function () { if (void 0 === this.options.viewport ? this.options.viewport = a(document.viewport || document.body) : 'string' == typeof this.options.viewport && (this.options.viewport = a(this.options.viewport)), (this.inState = { click: !1, hover: !1, focus: !1 }), this.$element[0] instanceof document.constructor && !this.options.selector) throw new Error( '\`selector\` option must be specified when initializing ' + this.type + ' on the window.document object!' ); for (var e = this.options.trigger.split(' '), f = e.length; f--; ) { var g = e[f]; if ('click' == g) this.$element.on('click.' + this.type, this.options.selector, a.proxy(this.toggle, this)); else if ('manual' != g) { var h = 'hover' == g ? 'mouseenter' : 'focusin', i = 'hover' == g ? 'mouseleave' : 'focusout'; this.$element.on(h + '.' + this.type, this.options.selector, a.proxy(this.enter, this)), this.$element.on(i + '.' + this.type, this.options.selector, a.proxy(this.leave, this)); } } this.options.selector ? (this._options = a.extend({}, this.options, { trigger: 'manual', selector: '' })) : this.fixTitle(); }
```
--------------------------------
### Publish Packages Locally
Source: https://github.com/citolab/qti-components/blob/main/docs/publishing.mdx
Use this command to perform a local publish of packages, typically for testing the publishing process before a full release.
```bash
pnpm run changeset:publish
```
--------------------------------
### Check if Highlight Range is Valid
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Validates if the provided start and end values for a highlight range are within the acceptable bounds (0 to 100).
```javascript
a >= 0 && 100 >= a && b >= 0 && 100 >= b ? !0 : !1;
```
--------------------------------
### Bootstrap Affix Plugin Initialization
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Initializes the Bootstrap affix plugin for elements that need to stick to the viewport. Configure with 'offset' for scroll-based positioning.
```javascript
var d = a.fn.affix;
(a.fn.affix = b),
(a.fn.affix.Constructor = c),
(a.fn.affix.noConflict = function () {
return (a.fn.affix = d),
this;
});
a(window).on('load', function () {
a('[data-spy="affix"]').each(function () {
var c = a(this),
d = c.data();
(d.offset = d.offset || {}),
null != d.offsetBottom && (d.offset.bottom = d.offsetBottom),
null != d.offsetTop && (d.offset.top = d.offsetTop),
b.call(c, d);
});
});
```
--------------------------------
### Preview Pending Releases
Source: https://github.com/citolab/qti-components/blob/main/docs/publishing.mdx
This command shows a summary of the changes that will be included in the next release, based on the existing changeset files.
```bash
pnpm run changeset:status
```
--------------------------------
### Fade In/Out Animation
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Provides a convenient method for fading an element to a specific opacity. It ensures the element is visible before starting the fade animation.
```javascript
n.fn.extend({
fadeTo: function (a, b, c, d) {
return this.filter(V).css('opacity', 0).show().end().animate({ opacity: b }, a, c, d);
},
animate: function (a, b, c, d) {
var e = n.isEmptyObject(a), f = n.speed(b, c, d), g = function () {
var b = _a(this, n.extend({}, a), f);
(e || N.get(this, 'finish')) && b.stop(!0);
};
return (g.finish = g), e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g);
},
stop: function (a, b, c) {
var d = function (a) {
var b = a.stop;
delete a.stop;
b(c);
};
return ('string' != typeof a && ((c = b), (b = a), (a = void 0)), b && a !== !1 && this.queue(a || 'fx', []), this.each(function () {
var b = !0, e = null != a && a + 'queueHooks', f = n.timers, g = N.get(this);
if (e) g[e] && g[e].stop && d(g[e]);
else for (e in g) g[e] && g[e].stop && Va.test(e) && d(g[e]);
for (e = f.length; e--; ) f[e].elem !== this || (null != a && f[e].queue !== a) || (f[e].anim.stop(c), (b = !1));
}));
}
});
```
--------------------------------
### Get Active Element
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Safely retrieves the currently active element in the document. Returns the element or null if an error occurs or no element is active.
```javascript
function ia() { try { return d.activeElement; } catch (a) {} }
```
--------------------------------
### Bootstrap Affix Plugin Constructor
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/index.html
Defines the Affix plugin constructor. It initializes the plugin with options and attaches it to the target element. Use this for custom affix implementations.
```javascript
function e(e) {
return this.each(function () {
var o = t(this),
n = o.data('bs.affix'),
s = 'object' == typeof e && e;
n || o.data('bs.affix', (n = new i(this, s))),
'string' == typeof e && n[e]();
});
}
```
--------------------------------
### Bootstrap Tooltip Plugin Initialization
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/index.html
Initializes the Bootstrap tooltip plugin, handling hover and focus triggers. Includes options for placement, template, and delay. Requires 'selector' for window.document initialization.
```javascript
var e = function (t, e) {
(this.type = null),
(this.options = null),
(this.enabled = null),
(this.timeout = null),
(this.hoverState = null),
(this.$element = null),
(this.inState = null),
this.init('tooltip', t, e);
};
(e.VERSION = '3.3.6'),
(e.TRANSITION_DURATION = 150),
(e.DEFAULTS = {
animation: !0,
placement: 'top',
selector: !1,
template: '',
trigger: 'hover focus',
title: '',
delay: 0,
html: !1,
container: !1,
viewport: { selector: 'body', padding: 0 }
}),
(e.prototype.init = function (e, i, o) {
if ( ((this.enabled = !0), (this.type = e), (this.$element = t(i)), (this.options = this.getOptions(o)), (this.$viewport = this.options.viewport && t( t.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : this.options.viewport.selector || this.options.viewport )),
(this.inState = { click: !1, hover: !1, focus: !1 }),
this.$element[0] instanceof document.constructor && !this.options.selector )
) throw new Error( '`selector` option must be specified when initializing ' + this.type + ' on the window.document object!' );
for (var n = this.options.trigger.split(' '), s = n.length; s--; ) {
var a = n[s];
if ('click' == a)
this.$element.on('click.' + this.type, this.options.selector, t.proxy(this.toggle, this));
else if ('manual' != a) {
var r = 'hover' == a ? 'mouseenter' : 'focusin',
l = 'hover' == a ? 'mouseleave' : 'focusout';
this.$element.on(r + '.' + this.type, this.options.selector, t.proxy(this.enter, this)),
this.$element.on(l + '.' + this.type, this.options.selector, t.proxy(this.leave, this));
}
}
this.options.selector ? (this._options = t.extend({}, this.options, { trigger: 'manual', selector: '' })) : this.fixTitle();
}),
(e.prototype.getDefaults = function () {
return e.DEFAULTS;
}),
(e.prototype.getOptions = function (e) {
return ( (e = t.extend({}, this.getDefaults(), this.$element.data(), e)).delay && 'number' == typeof e.delay && (e.delay = { show: e.delay, hide: e.delay }), e );
}),
(e.prototype.getDelegateOptions = function () {
var e = {}, i = this.getDefaults();
return (
this._options && t.each(this._options, function (t, o) {
i[t] != o && (e[t] = o);
}),
e
);
}),
(e.prototype.enter = function (e) {
var i = e instanceof this.constructor ? e : t(e.currentTarget).data('bs.' + this.type);
return (
i ||
((i = new this.constructor(e.currentTarget, this.getDelegateOptions())),
t(e.currentTarget).data('bs.' + this.type, i)),
e instanceof t.Event && (i.inState['focusin'] = !0)
);
});
```
--------------------------------
### Get Element Position
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Extends jQuery to calculate an element's position relative to its offset parent. Useful for understanding layout and internal positioning.
```javascript
position: function () {
if (this[0]) {
var a, b, c = this[0], d = { top: 0, left: 0 };
return (
'fixed' === n.css(c, 'position') ? (b = c.getBoundingClientRect()) : ((a = this.offsetParent()), (b = this.offset()), n.nodeName(a[0], 'html') || (d = a.offset()), (d.top += n.css(a[0], 'borderTopWidth', !0)), (d.left += n.css(a[0], 'borderLeftWidth', !0))),
{ top: b.top - d.top - n.css(c, 'marginTop', !0), left: b.left - d.left - n.css(c, 'marginLeft', !0) }
);
}
}
```
--------------------------------
### Get Element Offset
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Extends jQuery's offset method to retrieve the position of an element relative to the document. Handles cases where the element is not in the document.
```javascript
n.fn.extend({
offset: function (a) {
if (arguments.length) return void 0 === a ? this : this.each(function (b) {
n.offset.setOffset(this, a, b);
});
var b, c, d = this[0], e = { top: 0, left: 0 }, f = d && d.ownerDocument;
if (f) return (
(b = f.documentElement),
n.contains(b, d) ? ((e = d.getBoundingClientRect()), (c = Mb(f)), { top: e.top + c.pageYOffset - b.clientTop, left: e.left + c.pageXOffset - b.clientLeft })
: e
);
}
});
```
--------------------------------
### Popover Constructor Initialization
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Initializes a new Popover instance, inheriting defaults from the tooltip constructor. It requires the 'tooltip.js' plugin to be loaded.
```javascript
if (!a.fn.tooltip) throw new Error('Popover requires tooltip.js');
(c.VERSION = '3.3.7'),
(c.DEFAULTS = a.extend({}, a.fn.tooltip.Constructor.DEFAULTS, {
placement: 'right',
trigger: 'click',
content: '',
template: ''
}));
```
--------------------------------
### Get Window Object
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Helper function to retrieve the window object associated with a DOM element or node. Essential for operations requiring window context.
```javascript
function Mb(a) {
return n.isWindow(a) ? a : 9 === a.nodeType && a.defaultView;
}
```
--------------------------------
### Bootstrap Dropdown Plugin Initialization
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/index.html
Initializes the Bootstrap dropdown plugin, handling click events to toggle dropdown menus and keyboard navigation. Includes backdrop functionality for touch devices.
```javascript
(function (t) {
'use strict';
function e(e) {
var i = e.attr('data-target');
i || (i = (i = e.attr('href')) && /#\[A-Za-z\]/.test(i) && i.replace(/.\*?(?=#\[^\\s\*$\])/, ''));
var o = i && t(i);
return o && o.length ? o : e.parent();
}
function i(i) {
(i && 3 === i.which) ||
(t(o).remove(),
t(n).each(function () {
var o = t(this),
n = e(o),
s = {
relatedTarget: this
};
n.hasClass('open') &&
((i && 'click' == i.type && /input|textarea/i.test(i.target.tagName) && t.contains(n[0], i.target)) ||
(n.trigger((i = t.Event('hide.bs.dropdown', s))), i.isDefaultPrevented() || (o.attr('aria-expanded', 'false'), n.removeClass('open').trigger(t.Event('hidden.bs.dropdown', s))))));
}));
}
var o = '.dropdown-backdrop',
n = '[data-toggle="dropdown"]',
s = function (e) {
t(e).on('click.bs.dropdown', this.toggle);
};
(s.VERSION = '3.3.6'),
(s.prototype.toggle = function (o) {
var n = t(this);
if (!n.is('.disabled, :disabled')) {
var s = e(n),
a = s.hasClass('open');
if ((i(), !a)) {
'ontouchstart' in document.documentElement &&
!s.closest('.navbar-nav').length &&
t(document.createElement('div'))
.addClass('dropdown-backdrop')
.insertAfter(t(this))
.on('click', i);
var r = {
relatedTarget: this
};
if ((s.trigger((o = t.Event('show.bs.dropdown', r))), o.isDefaultPrevented())) return;
n.trigger('focus').attr('aria-expanded', 'true'), s.toggleClass('open').trigger(t.Event('shown.bs.dropdown', r));
}
return !1;
}
}),
(s.prototype.keydown = function (i) {
if (/(38|40|27|32)/.test(i.which) && !/input|textarea/i.test(i.target.tagName)) {
var o = t(this);
if ((i.preventDefault(), i.stopPropagation(), !o.is('.disabled, :disabled'))) {
var s = e(o),
a = s.hasClass('open');
(!a && 27 != i.which) || (a && 27 == i.which)
? 27 == i.which && s.find(n).trigger('focus'), o.trigger('click')
: void 0;
var r = s.find('.dropdown-menu li:not(.disabled):visible a');
if (r.length) {
var l = r.index(i.target);
38 == i.which && l > 0 && l--,
40 == i.which && l < r.length - 1 && l++,
~l || (l = 0),
r.eq(l).trigger('focus');
}
}
}
});
var a = t.fn.dropdown;
(t.fn.dropdown = function (e) {
return this.each(function () {
var i = t(this),
o = i.data('bs.dropdown');
o || i.data('bs.dropdown', (o = new s(this))),
'string' == typeof e && o[e].call(o);
});
}),
(t.fn.dropdown.Constructor = s),
(t.fn.dropdown.noConflict = function () {
return (t.fn.dropdown = a), this;
}),
t(document)
.on('click.bs.dropdown.data-api', n, s.prototype.toggle)
.on('keydown.bs.dropdown.data-api', n, s.prototype.keydown)
.on('keydown.bs.dropdown.data-api',
'.dropdown-menu',
s.prototype.keydown);
})(jQuery);
```
--------------------------------
### Manage Margin and Padding CSS
Source: https://github.com/citolab/qti-components/blob/main/public/assets/qti-custom-interaction/ref/6047-BiKB-bmi_467x370_29/html/BMI.html
Sets up CSS hooks for 'margin', 'padding', and 'borderWidth' to handle shorthand properties and expand them into individual directional properties. Use this for setting consistent spacing around elements.
```javascript
n.each({ margin: '', padding: '', border: 'Width' }, function (a, b) { (n.cssHooks[a + b] = { expand: function (c) { for (var d = 0, e = {}, f = 'string' == typeof c ? c.split(' ') : [c]; 4 > d; d++) e[a + U[d] + b] = f[d] || f[d - 2] || f[0]; return e; } }), Aa.test(a) || (n.cssHooks[a + b].set = Na); })
```