<|start_filename|>demo/load-and-navigation/static/js/lib-integration.js<|end_filename|>
/**
 * Copyright 2020 <NAME>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { BpmnVisualization } from '../../index.es.js';

const bpmnVisualizationIntegration = new BpmnVisualization({ container: 'bpmn-container-custom' });
bpmnVisualizationIntegration.load(bpmnDefaultContent());

function bpmnDefaultContent() {
  return `<bpmn:definitions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" id="Definitions_0x0opj6" targetNamespace="http://example.bpmn.com/schema/bpmn">
  <bpmn:process id="Process_1" isExecutable="false">
    <bpmn:startEvent id="StartEvent_1" name="Start Event Only">
    </bpmn:startEvent>
  </bpmn:process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Process_1">
      <bpmndi:BPMNShape id="BPMNShape_StartEvent_1" bpmnElement="StartEvent_1">
        <dc:Bounds x="156" y="81" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="158" y="124" width="33" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>`;
}


<|start_filename|>examples/diagram-navigation/diagram-navigation/index.js<|end_filename|>
const bpmnContainer = document.getElementById('bpmn-container');
const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: bpmnContainer, navigation: { enabled: true } });
bpmnVisualization.load(getNavigationBpmnDiagram());

let displayScrollBars = false;
document.getElementById('btn-reset').onclick = function () {
  bpmnVisualization.fit({ type: bpmnvisu.FitType.None });

  // reset scrollbars position
  displayScrollBars && bpmnContainer.scrollTo(0, 0);
};

document.getElementById('btn-toggle-scrollbars').onclick = function () {
  displayScrollBars = !displayScrollBars;

  bpmnContainer.style.overflow = displayScrollBars ? 'auto' : 'hidden';

  // ensure that all diagram positions are recomputed (mainly for no scrollbars)
  bpmnVisualization.load(getNavigationBpmnDiagram());
};




<|start_filename|>examples/misc/compare-with-bpmn-js/index.js<|end_filename|>
const bpmnVisualizationContainerId = 'container-bpmn-visualization';
const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: bpmnVisualizationContainerId, navigation: { enabled: true } });

const bpmnJsContainerId = 'container-bpmn-js';
const bpmnJsViewer = new BpmnJS({ container: `#${bpmnJsContainerId}` });

let loadedXml;
let fitView = false;
let isBpmnVisualizationAlreadyLoaded = false;
let isBpmnJsAlreadyLoaded = false;

// Configure custom html elements
document.getElementById('btn-open-file').addEventListener('change', handleFileSelect, false);
const bpmnLibraryRadioButtons = document.getElementsByName('bpmnLibrary');
configureBpmnLibraryRadioButtons();
configureFitViewButton();


function loadWithBpmnVisualization(xml) {
  if (isBpmnVisualizationAlreadyLoaded) {
    logBpmnVisu('Diagram already loaded, skipping new load');
    return;
  }
  logBpmnVisu('Start loading diagram');
  bpmnVisualization.load(xml, { fit: computeBpmnVisualizationFitOptions() });
  logBpmnVisu('Diagram loaded');
  isBpmnVisualizationAlreadyLoaded = true;
}

async function loadWithBpmnJs(xml) {
  if (isBpmnJsAlreadyLoaded) {
    logBpmnJs('Diagram already loaded, skipping new load');
    return;
  }
  logBpmnJs('Starting import XML')
  await bpmnJsViewer.importXML(xml);
  logBpmnJs('Import XML done')
  setZoomLevelBpmnJs();
  isBpmnJsAlreadyLoaded = true;
}

function setZoomLevelBpmnJs() {
  const canvas = bpmnJsViewer.get('canvas');
  if (fitView) {
    // 'auto' to zoom into mid
    canvas.zoom('fit-viewport', 'auto');
  } else {
    // pass null to ensure the position of the diagram is taken from the BPMN xml
    canvas.zoom(1, null);
  }
  logBpmnJs(`Zoom level set, fitView ${fitView}`);
}

function setZoomLevelBpmnVisualization() {
  bpmnVisualization.fit(computeBpmnVisualizationFitOptions());
  logBpmnVisu(`Zoom level set, fitView ${fitView}`);
}

function computeBpmnVisualizationFitOptions() {
  const fitType = fitView ? bpmnvisu.FitType.Center: bpmnvisu.FitType.None;
  return { type: fitType, margin: 10 };
}

function handleFileSelect(evt) {
  evt.stopPropagation();
  evt.preventDefault();

  const file = evt.target.files[0];
  logMain(`New file selected for load: ${file.name}`);
  const reader = new FileReader();
  reader.onload = () => {
    isBpmnVisualizationAlreadyLoaded = false;
    isBpmnJsAlreadyLoaded = false;
    loadBpmn(reader.result);

    document.getElementById('loading-info').classList.remove('hidden');
    document.querySelector('#loading-info > span').innerHTML = `<code>${file.name}</code>`;
  };
  reader.readAsText(file);
}

function loadBpmn(xml) {
  const useBpmnVisualization = isUseBpmnVisualization();
  displayBpmnContainer(useBpmnVisualization);

  // effective load
  try {
    logMain(`Ready to load BPMN with fitView: ${fitView}`);
    if (useBpmnVisualization) {
      loadWithBpmnVisualization(xml);
    } else {
      loadWithBpmnJs(xml);
    }
    loadedXml = xml;
  } catch (err) {
    console.error('[main] Unable to load BPMN diagram', err);
  }
}

function reloadAfterBpmnLibrarySwitch() {
  logMain('BPMN Library switch detected');
  if (!loadedXml) {
    return;
  }
  logMain('Reloading the BPMN diagram');
  loadBpmn(loadedXml);
}


function configureFitViewButton() {
  const fitViewElt = document.getElementById('fitView');

  fitView = fitViewElt.checked;
  logMain(`Initial fitView: ${fitView}`);

  fitViewElt.addEventListener('change', function(event) {
    fitView = event.target.checked;
    changeZoomLevel();
  });
}

function changeZoomLevel() {
  logMain('Zoom level switch detected');
  if (!loadedXml) {
    return;
  }
  logMain(`Changing zoom level with fitView: ${fitView}`);
  if (isUseBpmnVisualization()) {
    setZoomLevelBpmnVisualization();
  } else {
    setZoomLevelBpmnJs();
  }
}

function configureBpmnLibraryRadioButtons() {
  for (let i = 0, length = bpmnLibraryRadioButtons.length; i < length; i++) {
    bpmnLibraryRadioButtons[i].addEventListener('change', reloadAfterBpmnLibrarySwitch);
  }
}

function isUseBpmnVisualization() {
  return getSelectedBpmnLibrary() === 'bpmn-visualization';
}

function getSelectedBpmnLibrary() {
  let bpmnLibrary;
  for (let i = 0, length = bpmnLibraryRadioButtons.length; i < length; i++) {
    if (bpmnLibraryRadioButtons[i].checked) {
      bpmnLibrary = bpmnLibraryRadioButtons[i].value;
      break;
    }
  }
  bpmnLibrary = bpmnLibrary ?? 'bpmn-visualization';
  logMain(`Selected lib: ${bpmnLibrary}`)
  return bpmnLibrary;
}


function displayBpmnContainer(useBpmnVisualization) {
  const bpmnVisualizationContainerElt = document.getElementById(bpmnVisualizationContainerId);
  const bpmnJsContainerElt = document.getElementById(bpmnJsContainerId);

  if (useBpmnVisualization) {
    bpmnVisualizationContainerElt.classList.remove('hidden');
    bpmnJsContainerElt.classList.add('hidden');
  } else {
    bpmnJsContainerElt.classList.remove('hidden');
    bpmnVisualizationContainerElt.classList.add('hidden');
  }
}

function log(header, msg) {
  console.info(`[${header}] ${msg}`);
}

function logBpmnJs(msg) {
  log('bpmn-js', msg)
}

function logBpmnVisu(msg) {
  log('bpmn-visualization', msg)
}

function logMain(msg) {
  log('main', msg)
}


<|start_filename|>examples/custom-behavior/apply-css-classes/index.js<|end_filename|>
let usePathHighLightingStepByStep = false;
configurePathHighlightType();

const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container', navigation: { enabled: true} });
bpmnVisualization.load(getC_1_1_BpmnDiagram(), { fit: { type: bpmnvisu.FitType.Center, margin: 20 } });

const styledElements = [
  // tasks
  'assignApprover', 'approveInvoice', 'reviewInvoice', 'prepareBankTransfer',
  // gateways
  'reviewSuccessful_gw', 'invoice_approved'
];

const pathEdgeElements = ['SequenceFlow_1', 'sequenceFlow_178', 'sequenceFlow_180', 'invoiceApproved'];
const pathLastShape = 'prepareBankTransfer';
const pathShapeElements= ['StartEvent_1', 'assignApprover','approveInvoice', 'invoice_approved', pathLastShape];
const orderedPathElements = [
  {name: 'StartEvent_1', type: 'shape'},
  {name: 'SequenceFlow_1', type: 'edge'},
  {name: 'assignApprover', type: 'shape'},
  {name: 'sequenceFlow_178', type: 'edge'},
  {name: 'approveInvoice', type: 'shape'},
  {name: 'sequenceFlow_180', type: 'edge'},
  {name: 'invoice_approved', type: 'shape'},
  {name: 'invoiceApproved', type: 'edge'},
  {name: pathLastShape, type: 'shape'},
];


applyInitialStyles();

document.getElementById('btn-reset').onclick = function() {
  clearAllStyles();
  applyInitialStyles();

  ['btn-success', 'btn-warning', 'btn-error']
  .forEach(id => document.getElementById(id).disabled = false);
};

document.getElementById('btn-clear').onclick = function() {
  clearAllStyles();
};

document.getElementById('btn-info').onclick = function() {
  toggleCssClass(['assignApprover', 'prepareBankTransfer'], 'bpmn-activity-info');
};
document.getElementById('btn-success').onclick = function() {
  addCssClass(['approveInvoice'], 'bpmn-activity-success');
  this.disabled = true;
};
document.getElementById('btn-warning').onclick = function() {
  removeCssClass(['reviewSuccessful_gw', 'invoice_approved'], 'bpmn-gateway-warning');
  this.disabled = true;
};
document.getElementById('btn-error').onclick = function() {
  addCssClass(['reviewInvoice'], 'bpmn-activity-error');
  this.disabled = true;
};

function configurePathHighlightType() {
  const checkPathByStepElt = document.getElementById('chk-path-step');

  usePathHighLightingStepByStep = checkPathByStepElt.checked;
  console.info(`Initial pathHighLightingStepByStep: ${usePathHighLightingStepByStep}`);

  checkPathByStepElt.addEventListener('change', function(event) {
    usePathHighLightingStepByStep = event.target.checked;
    clearHighlightPath();
  });
}

document.getElementById('btn-path').onclick = function() {
  if (usePathHighLightingStepByStep) {
    pathHighLightingStepByStep();
  } else {
    pathHighLightingByGroup();
  }
};

let pathGroupStep = 'none';
function pathHighLightingByGroup() {
  switch (pathGroupStep) {
    case 'none':
      addHighlightPath(pathEdgeElements);
      pathGroupStep = 'step1';
      break;
    case 'step1':
      addHighlightPath(pathShapeElements, true);
      addCssClass([pathLastShape], 'bpmn-activity-in-progress');
      pathGroupStep = 'step2';
      break;
    case 'step2':
      removeHighlightPath(pathEdgeElements);
      pathGroupStep = 'step3';
      break;
    case 'step3':
      removeHighlightPath(pathShapeElements, true);
      removeCssClass([pathLastShape], 'bpmn-activity-in-progress');
      pathGroupStep = 'step4';
      break;
    case 'step4':
      addHighlightPath(pathEdgeElements);
      addHighlightPath(pathShapeElements, true);
      addCssClass([pathLastShape], 'bpmn-activity-in-progress');
      pathGroupStep = 'step5';
      break;
    default:
      clearHighlightPath();
  }
}

let pathEltCount = 0;
function pathHighLightingStepByStep() {
  if (pathEltCount >= orderedPathElements.length) {
    clearHighlightPath();
    return;
  }

  const pathElement = orderedPathElements[pathEltCount];
  addHighlightPath(pathElement.name, pathElement.type === 'shape');
  pathEltCount++;
  // last element
  if (pathEltCount >= orderedPathElements.length) {
    addCssClass([pathElement.name], 'bpmn-activity-in-progress');
  }
}

function applyInitialStyles() {
  addCssClass(['assignApprover'], 'bpmn-activity-info');
  addCssClass(['reviewSuccessful_gw', 'invoice_approved'], 'bpmn-gateway-warning');
}

function clearAllStyles() {
  removeCssClass(styledElements, 'bpmn-activity-info', 'bpmn-activity-success', 'bpmn-activity-error', 'bpmn-gateway-warning')
  clearHighlightPath();
}


function addHighlightPath(elements, isShape) {
  addCssClass(elements, getPathHighlightClassName(isShape));
}
function getPathHighlightClassName(isShape) {
  return isShape ? 'bpmn-shape-path-highlight' : 'bpmn-edge-path-highlight';
}
function removeHighlightPath(elements, isShape) {
  removeCssClass(elements, getPathHighlightClassName(isShape));
}
function clearHighlightPath() {
  removeCssClass(pathEdgeElements.concat(pathShapeElements), 'bpmn-edge-path-highlight', 'bpmn-shape-path-highlight', 'bpmn-activity-in-progress');
  pathGroupStep = 'none';
  pathEltCount = 0;
}

function addCssClass(elements, ...classNames) {
  bpmnVisualization.bpmnElementsRegistry.addCssClasses(elements, classNames);
}
function removeCssClass(elements, ...classNames) {
  bpmnVisualization.bpmnElementsRegistry.removeCssClasses(elements, classNames);
}
function toggleCssClass(elements, classNames) {
  bpmnVisualization.bpmnElementsRegistry.toggleCssClasses(elements, classNames);
}


<|start_filename|>examples/custom-behavior/select-elements-by-bpmn-kind/index.js<|end_filename|>
const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container' });
const diagrams = new Map([
  ['A.4.1', getA_4_1_BpmnDiagram], // vertical diagram
  ['C.1.0', getC_1_0_BpmnDiagram],
  ['C.1.1', getC_1_1_BpmnDiagram], // no pool
  ['C.2.0', getC_2_0_BpmnDiagram],
]);
let lastLoadedDiagram;
let lastSelectedPool;

const notyf = configureToast();
configureBpmnDiagramsDropdown();
configurePoolSelectionButtons();
loadDiagram('C.2.0');


function loadDiagram(diagramName) {
  console.info('Loading diagram', diagramName);
  const diagram = diagrams.get(diagramName).call();
  bpmnVisualization.load(diagram, { fit: { type: bpmnvisu.FitType.Center, margin: 20 } });
  console.info('Diagram loaded');
  lastLoadedDiagram = diagramName;
  lastSelectedPool = '';

  registerBpmnElements();
}

function configureBpmnDiagramsDropdown() {
  document.getElementById('dropdown-diagram-choice').innerHTML = [...diagrams].map(([diagramName, ]) => {
    return `<li><a href="#" class="btn btn-link">${diagramName}</a></li>`
  }).join('\n');

  document.getElementById('dropdown-diagram-choice').querySelectorAll('li a')
  .forEach(function (anchor)  {
    anchor.onclick = function (e) {
      e.preventDefault();

      hide('dropdown-diagram-choice');
      const diagramName = anchor.parentElement.innerText;
      loadDiagram(diagramName)

      return false;
    };
  });
  // TODO duplicated with configurePoolSelectionDropdown
  document.getElementById('dropdown-toggle-diagram-choice').onclick = function () {
    show('dropdown-diagram-choice');
  }
}


function registerBpmnElements() {
  console.info('Registering Bpmn Elements...');

  const bpmnElements = bpmnVisualization.bpmnElementsRegistry.getElementsByKinds([bpmnvisu.ShapeBpmnElementKind.EVENT_END, bpmnvisu.ShapeBpmnElementKind.POOL]);
  console.info('Found Bpmn Elements:', bpmnElements.length);

  bpmnElements
  .filter(elt => elt.bpmnSemantic.kind !== bpmnvisu.ShapeBpmnElementKind.POOL)
  .forEach(elt => {
        const bpmnSemantic = elt.bpmnSemantic;
        elt.htmlElement.addEventListener('click', function (event) {
          const name = linearizeName(bpmnSemantic);
          const toastMsg = name ? `<b>name</b>: ${name}` : `<b>id</b>: ${bpmnSemantic.id}`
          toast(toastMsg);
        });
      }
  );
  console.info('Non Pools registered');

  const pools = bpmnElements
  .map(elt => elt.bpmnSemantic)
  .filter(bpmnSemantic => bpmnSemantic.kind === bpmnvisu.ShapeBpmnElementKind.POOL);
  configurePoolsSelection(pools);
  console.info('All Bpmn Elements registered');
}

// Some BPMN element names have break line, so remove them
function linearizeName(bpmnSemantic) {
  return bpmnSemantic.name
      // replace all 3 types of line breaks with a space
      ?.replace(/(\r\n|\n|\r)/gm,' ')
      // replace all double white spaces with single spaces
      .replace(/\s+/g," ");
}

// argument: array of pools bpmn semantic
function configurePoolsSelection(pools) {
  hide('btn-group-pools-selection');
  hide('pool-selection-info');
  hide('group-pools-selection-reset');

  console.info('Detected pools:', pools.length);
  if (!pools.length) {
    return;
  }

  // Drop down list
  document.querySelector('#dropdown-select-pool').innerHTML = pools.map(pool => {
    return `<li><a href="#" class="btn btn-link" data-bpmn-id="${pool.id}">${linearizeName(pool)}</a></li>`
  }).join('\n');

  document.querySelectorAll('#dropdown-select-pool li a')
  .forEach(function (anchor)  {
    anchor.onclick = function (e) {
      e.preventDefault();

      changePoolsVisibility(pools, anchor.getAttribute('data-bpmn-id'));

      const lastSelectedPool = anchor.parentElement.innerText;
      document.getElementById('last-selected-pool-name').innerHTML = `<code>${lastSelectedPool}</code>`;
      show('pool-selection-info');
      show('group-pools-selection-reset');

      hide('dropdown-select-pool');
      return false;
    };
  });

  show('btn-group-pools-selection');
}

function changePoolsVisibility(pools, poolIdToHighlight) {
  console.info('Updating model, pool to highlight:', poolIdToHighlight);
  const model = bpmnVisualization.graph.getModel();

  const poolSelectionMethod = getRadioGroupValue('poolSelectionMethod');
  console.info('Selection method:', poolSelectionMethod);
  const hideOthers = poolSelectionMethod === 'hide';
  const modelChangeFunction = hideOthers ?
      // only keep a single visible pool
      (cell => {
        model.setVisible(cell, cell.id === poolIdToHighlight);
        model.setCollapsed(cell, false);
      }) :
      // collapse other pools
      (cell => {
        model.setCollapsed(cell, cell.id !== poolIdToHighlight)
        model.setVisible(cell, true);
      });

  model.beginUpdate();
  try {
    pools.map(pool => model.getCell(pool.id))
    .forEach(modelChangeFunction);
  } finally {
    model.endUpdate();
  }

  console.info('Model updated');
}

function configurePoolSelectionButtons() {
  document.getElementById('dropdown-toggle-select-pool').onclick = function (){
    show('dropdown-select-pool');
  }

  document.getElementById('btn-pools-selection-reset').onclick = function (){
    loadDiagram(lastLoadedDiagram);
  }
}

function show(elementId) {
  document.getElementById(elementId).classList.remove('hidden');
}
function hide(elementId) {
  document.getElementById(elementId).classList.add('hidden');
}

// TODO extract in helper to avoid duplication with diagram-fit-on-load getSelectedFitType
function getRadioGroupValue(elementId) {
  const radios = document.getElementsByName(elementId);
  for (let i = 0, length = radios.length; i < length; i++) {
    if (radios[i].checked) {
      return radios[i].value;
    }
  }
}

function configureToast() {
  return new Notyf({
    position: {
      x: 'right',
      y: 'top',
    },
    types: [
      {
        type: 'success',
        duration: 2500,
      }
    ]
  });
}

function toast(htmlMessage) {
  notyf.success(htmlMessage);
}


<|start_filename|>demo/load-and-navigation/static/js/demo.js<|end_filename|>
/**
 * Copyright 2020 <NAME>.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { documentReady, handleFileSelect, startBpmnVisualization, fit, log, updateLoadOptions, getCurrentLoadOptions } from '../../index.es.js';

let fitOnLoad = true;
let fitOptions = {};

function configureFitOnLoadCheckBox() {
  const fitOnLoadElt = document.getElementById('fitOnLoad');
  fitOnLoadElt.onchange = event => {
    fitOnLoad = event.target.checked;
    log('Fit on load updated!', fitOnLoad);
    updateLoadOptions(fitOnLoad ? fitOptions : {});
  };
  fitOnLoadElt.checked = fitOnLoad;
}

function updateFitConfig(config) {
  log('Updating fit config', config);

  fitOptions.margin = config.margin || fitOptions.margin;
  if (config.type) {
    fitOptions.type = config.type;
  }
  log('Fit config updated!', fitOptions);

  if (fitOnLoad) {
    updateLoadOptions(fitOptions);
  }
}

function configureFitTypeSelect() {
  const fitTypeSelectedElt = document.getElementById('fitType-selected');
  fitTypeSelectedElt.onchange = event => {
    updateFitConfig({ type: event.target.value });
    fit(fitOptions);
  };

  if (fitOptions.type) {
    fitTypeSelectedElt.value = fitOptions.type;
  } else {
    updateFitConfig({ type: fitTypeSelectedElt.value });
  }
}

function configureFitMarginInput() {
  const fitMarginElt = document.getElementById('fit-margin');
  fitMarginElt.onchange = event => {
    updateFitConfig({ margin: event.target.value });
    fit(fitOptions);
  };

  if (fitOptions.margin) {
    fitMarginElt.value = fitOptions.margin;
  } else {
    updateFitConfig({ margin: fitMarginElt.value });
  }
}

function configureControlPanel() {
  const parameters = new URLSearchParams(window.location.search);
  if (parameters.get('hideControls') === 'true') {
    const classList = document.getElementById('controls').classList;
    classList.remove('controls');
    classList.add('hidden');
  }
}

// The following function `preventZoomingPage` serves to block the page content zoom.
// It is to make zooming of the actual diagram area more convenient for the user.
// Without that function, the zooming performed out of the diagram area can mess up the page layout.
function preventZoomingPage() {
  document.addEventListener(
    'wheel',
    e => {
      if (e.ctrlKey) event.preventDefault(); //prevent zoom
    },
    { passive: false, capture: 'bubble' },
  );
}

function setupFixedDiagramContainerSize(containerId) {
  const containerElt = document.getElementById(containerId);
  const height = containerElt.parentNode.parentNode.getBoundingClientRect().height;
  // parent height minus 2 x padding
  containerElt.style = `overflow: hidden; height:${height - 2 * 20}px`;
}

function startDemo() {
  preventZoomingPage();
  const bpmnContainerId = 'bpmn-container';
  setupFixedDiagramContainerSize(bpmnContainerId);

  const parameters = new URLSearchParams(window.location.search);
  const zoomThrottleElt = document.getElementById('zoom-throttle'),
    zoomDebounceElt = document.getElementById('zoom-debounce'),
    zoomControlsElt = document.getElementById('zoom-config-controls');
  if (parameters.get('zoomThrottle')) {
    zoomControlsElt.style = 'visibility: visible';
    zoomThrottleElt.value = parameters.get('zoomThrottle');
  }
  if (parameters.get('zoomDebounce')) {
    zoomControlsElt.style = 'visibility: visible';
    zoomDebounceElt.value = parameters.get('zoomDebounce');
  }
  startBpmnVisualization({
    globalOptions: {
      container: bpmnContainerId,
      navigation: {
        enabled: true,
        zoom: {
          throttleDelay: zoomThrottleElt.value,
          debounceDelay: zoomDebounceElt.value,
        },
      },
    },
  });

  // Configure custom html elements
  document.getElementById('bpmn-file').addEventListener('change', handleFileSelect, false);

  fitOptions = getCurrentLoadOptions().fit;
  configureFitTypeSelect();
  configureFitMarginInput();
  configureFitOnLoadCheckBox();
  configureControlPanel();
}

// Start
documentReady(startDemo);


<|start_filename|>examples/display-bpmn-diagram/load-local-bpmn-diagrams/index.js<|end_filename|>
document.getElementById('btn-open-file').addEventListener('change', handleFileSelect, false);

const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container' });

function handleFileSelect(evt) {
  evt.stopPropagation();
  evt.preventDefault();

  const file = evt.target.files[0];
  const reader = new FileReader();
  reader.onload = () => {
    bpmnVisualization.load(reader.result);
    document.getElementById('loading-info').classList.remove('hidden');
    // TODO we probably don't need it, just select span child
    document.getElementById('loaded-file-name').innerHTML = `<code>${file.name}</code>`;
  };
  reader.readAsText(file);
}


<|start_filename|>examples/misc/compare-with-kie-editors-standalone/index.js<|end_filename|>
const bpmnVisualizationContainerId = 'container-bpmn-visualization';
const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: bpmnVisualizationContainerId, navigation: { enabled: true } });

const kieBpmnEditorContainerId = 'container-kie-editors-standalone';
const kieBpmnEditor = BpmnEditor.open({
  container: document.getElementById(kieBpmnEditorContainerId),
  readOnly: true, // available as of 0.9.0 (https://blog.kie.org/2021/04/design-tools-highlights-on-kogito-and-business-central-april-2021.html)
});
kieBpmnEditor.subscribeToContentChanges((isDirty) => { logKieBpmn(`Content change detected, isDirty?${isDirty}`)})

let loadedXml;
let fitView = true;
let isBpmnVisualizationAlreadyLoaded = false;
let isKieBpmnAlreadyLoaded = false;

// Configure custom html elements
document.getElementById('btn-open-file').addEventListener('change', handleFileSelect, false);
const bpmnLibraryRadioButtons = document.getElementsByName('bpmnLibrary');
configureBpmnLibraryRadioButtons();
configureFitViewButton();


function loadWithBpmnVisualization(xml) {
  if (isBpmnVisualizationAlreadyLoaded) {
    logBpmnVisu('Diagram already loaded, skipping new load');
    return;
  }
  logBpmnVisu('Start loading diagram');
  bpmnVisualization.load(xml, { fit: computeBpmnVisualizationFitOptions() });
  logBpmnVisu('Diagram loaded');
  isBpmnVisualizationAlreadyLoaded = true;
}

async function loadWithKieBpmn(xml) {
  if (isKieBpmnAlreadyLoaded) {
    logKieBpmn('Diagram already loaded, skipping new load');
    return;
  }
  logKieBpmn('Starting setting content')
  // TODO clarify if setContent returns a promise
  // The introduction article and 0.8.1 readme states it returns 'void', but the abstract class TypeScript definition
  // declares a Promise
  // Using promise doesn't change anything, the load is fully asynchronous. We may have to register event listener
  // see https://github.com/kiegroup/kogito-tooling/blob/e151ccdac6ae526e81dc5e0ec302f02c922b00ea/packages/editor/src/api/Editor.ts#L36
  // kieBpmnEditor.setContent(xml)
  //         .then(value => logKieBpmn('Content set'))
  //         .then(value => setZoomLevelKieBpmn())
  //         .catch(reason => console.error('[KIE]', reason));
  kieBpmnEditor.setContent(xml);
  logKieBpmn('Content set');
  setZoomLevelKieBpmn();
  isKieBpmnAlreadyLoaded = true;
}

function setZoomLevelKieBpmn() {
  // TODO see if we have something for kie-editors-standalone
  logKieBpmn('no zoom settings for now');
}

function setZoomLevelBpmnVisualization() {
  bpmnVisualization.fit(computeBpmnVisualizationFitOptions());
  logBpmnVisu(`Zoom level set, fitView ${fitView}`);
}

function computeBpmnVisualizationFitOptions() {
  const fitType = fitView ? bpmnvisu.FitType.Center: bpmnvisu.FitType.None;
  return { type: fitType, margin: 10 };
}

function handleFileSelect(evt) {
  evt.stopPropagation();
  evt.preventDefault();

  const file = evt.target.files[0];
  logMain(`New file selected for load: ${file.name}`);
  const reader = new FileReader();
  reader.onload = () => {
    isBpmnVisualizationAlreadyLoaded = false;
    isKieBpmnAlreadyLoaded = false;
    loadBpmn(reader.result);

    document.getElementById('loading-info').classList.remove('hidden');
    document.querySelector('#loading-info > span').innerHTML = `<code>${file.name}</code>`;
  };
  reader.readAsText(file);
}

function loadBpmn(xml) {
  const useBpmnVisualization = isUseBpmnVisualization();
  displayBpmnContainer(useBpmnVisualization);

  // effective load
  try {
    logMain(`Ready to load BPMN with fitView: ${fitView}`);
    if (useBpmnVisualization) {
      loadWithBpmnVisualization(xml);
    } else {
      loadWithKieBpmn(xml);
    }
    loadedXml = xml;
  } catch (err) {
    console.error('[main] Unable to load BPMN diagram', err);
  }
}

function reloadAfterBpmnLibrarySwitch() {
  logMain('BPMN Library switch detected');
  if (!loadedXml) {
    return;
  }
  logMain('Reloading the BPMN diagram');
  loadBpmn(loadedXml);
}


function configureFitViewButton() {
  document.getElementById('btn-fit-view').addEventListener('click', function(event) {
    changeZoomLevel();
  });
}

function changeZoomLevel() {
  logMain('Zoom level switch detected');
  if (!loadedXml) {
    return;
  }
  logMain(`Changing zoom level with fitView: ${fitView}`);
  if (isUseBpmnVisualization()) {
    setZoomLevelBpmnVisualization();
  } else {
    setZoomLevelKieBpmn();
  }
}

function configureBpmnLibraryRadioButtons() {
  for (let i = 0, length = bpmnLibraryRadioButtons.length; i < length; i++) {
    bpmnLibraryRadioButtons[i].addEventListener('change', reloadAfterBpmnLibrarySwitch);
  }
}

function isUseBpmnVisualization() {
  return getSelectedBpmnLibrary() === 'bpmn-visualization';
}

function getSelectedBpmnLibrary() {
  let bpmnLibrary;
  for (let i = 0, length = bpmnLibraryRadioButtons.length; i < length; i++) {
    if (bpmnLibraryRadioButtons[i].checked) {
      bpmnLibrary = bpmnLibraryRadioButtons[i].value;
      break;
    }
  }
  bpmnLibrary = bpmnLibrary ?? 'bpmn-visualization';
  logMain(`Selected lib: ${bpmnLibrary}`)
  return bpmnLibrary;
}


function displayBpmnContainer(useBpmnVisualization) {
  const bpmnVisualizationContainerElt = document.getElementById(bpmnVisualizationContainerId);
  const kieBpmnContainerElt = document.getElementById(kieBpmnEditorContainerId);

  if (useBpmnVisualization) {
    bpmnVisualizationContainerElt.classList.remove('hidden');
    kieBpmnContainerElt.classList.add('hidden');
  } else {
    kieBpmnContainerElt.classList.remove('hidden');
    bpmnVisualizationContainerElt.classList.add('hidden');
  }
  setButtonState('btn-fit-view', !useBpmnVisualization);
}

function log(header, msg) {
  console.info(`[${header}] ${msg}`);
}

function logKieBpmn(msg) {
  log('kie-editors-standalone', msg)
}

function logBpmnVisu(msg) {
  log('bpmn-visualization', msg)
}

function logMain(msg) {
  log('main', msg)
}


<|start_filename|>examples/display-bpmn-diagram/load-remote-bpmn-diagrams/index.js<|end_filename|>
const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container' });

function log(message, ...optionalParams) {
  console.info('[DEMO] ' + message, ...optionalParams);
}
function loadBpmn(bpmn){
  bpmnVisualization.load(bpmn);
}

function statusFetching(url) {
  const statusElt = document.getElementById('fetch-status');
  statusElt.innerText = 'Fetching ' + url;
  statusElt.className = 'status-fetching';
}

function statusFetched(url, duration) {
  const statusElt = document.getElementById('fetch-status');
  statusElt.innerText = `Fetch OK (${duration} ms): ${url}`;
  statusElt.className = 'toast toast-success';
}

function statusFetchKO(url, error) {
  const statusElt = document.getElementById('fetch-status');
  statusElt.innerText = `Unable to fetch ${url}. ${error}`;
  statusElt.className = 'toast toast-error';
}

function fetchBpmnContent(url) {
  log('Fetching BPMN content from url <%s>', url);
  const startTime = performance.now();
  statusFetching(url);
  return fetch(url)
  .then(response => {
    if (!response.ok) {
      throw Error(String(response.status));
    }
    return response.text();
  })
  .then(responseBody => {
    log('BPMN content fetched');
    const duration = performance.now() - startTime;
    statusFetched(url, duration);
    return responseBody;
  })
  .catch(error => {
    statusFetchKO(url, error);
    throw new Error(`Unable to fetch ${url}. ${error}`);
  });
}

function loadBpmnFromUrl(url) {
  fetchBpmnContent(url).then(bpmn => {
    loadBpmn(bpmn);
    log('Bpmn loaded from url <%s>', url);
  });
}

function loadMiwgFile(fileName) {
  log('Ready to fetch MIWG file %s', fileName);
  const url = `https://raw.githubusercontent.com/bpmn-miwg/bpmn-miwg-test-suite/master/Reference/${fileName}.bpmn`;
  loadBpmnFromUrl(url);
}

const miwgFileNames = [
  'A.1.0',
  'A.2.0', 'A.2.1',
  'A.3.0',
  'A.4.0', 'A.4.1',
  'B.1.0', 'B.2.0',
  'C.1.0', 'C.1.1', 'C.2.0', 'C.3.0', 'C.4.0',
  'C.5.0', 'C.6.0', 'C.7.0',
];

const randomMiwgFileNames = [...miwgFileNames, 'do-not-exist'];
document.getElementById('btn-fetch-miwg').onclick = function() {
  const fileName = randomMiwgFileNames[Math.floor(Math.random() * randomMiwgFileNames.length)];
  loadMiwgFile(fileName);
};

// Drop down list
document.querySelector('#dropdown-fetch-miwg').innerHTML = miwgFileNames.map(fileName => {
  return `<li><a href="#" class="btn btn-link">${fileName}</a></li>`
}).join('\n');

document.querySelectorAll('#dropdown-fetch-miwg li a')
.forEach(function (anchor)  {
  anchor.onclick = function (e) {
    e.preventDefault();
    // get li value
    const miwgFileName = anchor.parentElement.innerText;
    loadMiwgFile(miwgFileName);

    document.getElementById('dropdown-fetch-miwg').classList.add('hidden');

    return false;
  };
});

document.getElementById('dropdown-toggle-fetch-miwg').onclick = function (){
  document.getElementById('dropdown-fetch-miwg').classList.remove('hidden');
}


<|start_filename|>examples/overlays/add-stylized/index.js<|end_filename|>
function removeAllOverlays(){
    // Remove all overlays
    // Shape
    bpmnElementsRegistry.removeAllOverlays('Activity_1potg3p');

    // Edge
    bpmnElementsRegistry.removeAllOverlays('Flow_1wkfbb0');
}


// Initialize the panel of Overlay settings
const fontColorElt = document.getElementById('font-color');
const fontSizeElt = document.getElementById('font-size');
const fillColorElt = document.getElementById('fill-color');
const strokeColorElt = document.getElementById('stroke-color');

const style = {
    font: {
        color: fontColorElt.value,
        size: fontSizeElt.value,
    },
    fill: {
        color: fillColorElt.value,
    },
    stroke: {
        color: strokeColorElt.value,
    }
};

fontColorElt.onchange = (event) => style.font.color = event.target.value;
fontSizeElt.onchange = (event) => style.font.size = event.target.value;
fillColorElt.onchange = (event) => style.fill.color = event.target.value;
strokeColorElt.onchange = (event) => style.stroke.color = event.target.value;

// Initialize BpmnVisualization
const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container', navigation: { enabled: true } });
const bpmnElementsRegistry = bpmnVisualization.bpmnElementsRegistry;

// Load BPMN diagram
bpmnVisualization.load(getGettingStartedBpmnDiagram(), { fit: { type: 'Center' } });

document.getElementById('btn-set-overlay').onclick = () => {
    removeAllOverlays();

    // Add overlays
    // Shape
    bpmnElementsRegistry.addOverlays('Activity_1potg3p', { position: 'bottom-right', label: 'OK 👌', style });

    // Edge
    bpmnElementsRegistry.addOverlays('Flow_1wkfbb0', { position: 'middle', label: '763', style });
};

document.getElementById('btn-reset').onclick = () => {
    removeAllOverlays();
    bpmnVisualization.fit({ type: 'Center' });
};



<|start_filename|>examples/overlays/custom-overlay-default-style/index.js<|end_filename|>
const bpmn = getGettingStartedBpmnDiagram();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// default colors
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container-default' });
bpmnVisualization.load(bpmn);
bpmnVisualization.bpmnElementsRegistry.addOverlays('Activity_1potg3p', { position: 'bottom-center', label: 'OK 👌' });
bpmnVisualization.bpmnElementsRegistry.addOverlays('Flow_1wkfbb0', { position: 'middle', label: '763' });



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// custom default font color
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const originalOverlayDefaultFontColor = bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FONT_COLOR;
const originalOverlayDefaultFontSize = bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FONT_SIZE;

bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FONT_COLOR = 'LimeGreen';
bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FONT_SIZE = 22;
const bpmnVisualizationOverlayCustomDefaultFont = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container-custom-default-font' });
bpmnVisualizationOverlayCustomDefaultFont.load(bpmn);
bpmnVisualizationOverlayCustomDefaultFont.bpmnElementsRegistry.addOverlays('Activity_1potg3p', { position: 'bottom-center', label: 'OK 👌' });
bpmnVisualizationOverlayCustomDefaultFont.bpmnElementsRegistry.addOverlays('Flow_1wkfbb0', { position: 'middle', label: '763' });

// restore StyleConstant defaults
bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FONT_COLOR = originalOverlayDefaultFontColor;
bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FONT_SIZE = originalOverlayDefaultFontSize;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// custom default fill and stroke colors
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const originalOverlayDefaultFillColor = bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FILL_COLOR;

bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FILL_COLOR = 'LightBlue';
const bpmnVisualizationOverlayCustomDefaultFill = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container-custom-default-fill' });
bpmnVisualizationOverlayCustomDefaultFill.load(bpmn);
bpmnVisualizationOverlayCustomDefaultFill.bpmnElementsRegistry.addOverlays('Activity_1potg3p', { position: 'bottom-center', label: 'OK 👌' });
bpmnVisualizationOverlayCustomDefaultFill.bpmnElementsRegistry.addOverlays('Flow_1wkfbb0', { position: 'middle', label: '763' });

// restore StyleConstant defaults
bpmnvisu.StyleDefault.DEFAULT_OVERLAY_FILL_COLOR = originalOverlayDefaultFillColor;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// custom fill and stroke colors depending on BPMN elements
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const originalOverlayDefaultStrokeColor = bpmnvisu.StyleDefault.DEFAULT_OVERLAY_STROKE_COLOR;

bpmnvisu.StyleDefault.DEFAULT_OVERLAY_STROKE_COLOR = 'Red';
const bpmnVisualizationOverlayCustomDefaultStroke = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container-custom-default-stroke' });
bpmnVisualizationOverlayCustomDefaultStroke.load(bpmn);
bpmnVisualizationOverlayCustomDefaultStroke.bpmnElementsRegistry.addOverlays('Activity_1potg3p', { position: 'bottom-center', label: 'OK 👌' });
bpmnVisualizationOverlayCustomDefaultStroke.bpmnElementsRegistry.addOverlays('Flow_1wkfbb0', { position: 'middle', label: '763' });

// restore StyleConstant defaults
bpmnvisu.StyleDefault.DEFAULT_OVERLAY_STROKE_COLOR = originalOverlayDefaultStrokeColor;

<|start_filename|>examples/diagram-navigation/diagram-fit-after-load/index.js<|end_filename|>
let fitType = bpmnvisu.FitType.None;
let fitMargin = 10;
const fitMarginValueElt = document.getElementById('fit-margin-value');
fitMarginValueElt.innerHTML = `<code>${fitMargin}</code>`;

const bpmnVisualization = new bpmnvisu.BpmnVisualization({ container: 'bpmn-container' });
loadDiagram();

function loadDiagram(diagramName) {
  fitType = undefined;
  if (diagramName?.includes('vertical')) {
    bpmnVisualization.load(getVerticalBpmnDiagram());
  } else {
    bpmnVisualization.load(getHorizontalBpmnDiagram());
  }
}

document.getElementById('btn-fit-none').onclick = function() {
  performFit(bpmnvisu.FitType.None);
};
document.getElementById('btn-fit-horizontally').onclick = function() {
  performFit(bpmnvisu.FitType.Horizontal);
};
document.getElementById('btn-fit-vertically').onclick = function() {
  performFit(bpmnvisu.FitType.Vertical);
};
document.getElementById('btn-fit-all').onclick = function() {
  performFit(bpmnvisu.FitType.HorizontalVertical);
};
document.getElementById('btn-fit-center').onclick = function() {
  performFit(bpmnvisu.FitType.Center);
};


function performFit(type) {
  if (type !== undefined) {
    fitType = type;
  }

  // `type` and `margin` are optional. Moreover, `margin` is only considered when FitType is not None.
  bpmnVisualization.fit({type: fitType, margin: fitMargin});
}

// 'Fit Margin' dropdown list
const fitMarginValues = [0, 5, 10, 20, 50];
const dropdownFitMarginElt = document.querySelector('#dropdown-fit-margin');
dropdownFitMarginElt.innerHTML = fitMarginValues.map(fitMargin => {
  return `<li><a href="#" class="btn btn-link">${fitMargin}</a></li>`
}).join('\n');

dropdownFitMarginElt.querySelectorAll('li a')
.forEach(function (anchor)  {
  anchor.onclick = function (e) {
    e.preventDefault();
    // get li value
    fitMargin = anchor.parentElement.innerText;
    fitMarginValueElt.innerHTML = `<code>${fitMargin}</code>`;
    dropdownFitMarginElt.classList.add('hidden');
    performFit();

    return false;
  };
});
document.getElementById('toggle-dropdown-fit-margin').onclick = function (){
  dropdownFitMarginElt.classList.remove('hidden');
}

// 'BPMN Diagram' dropdown list
const dropdownDiagramChoiceElt = document.querySelector('#dropdown-diagram-choice');
dropdownDiagramChoiceElt.querySelectorAll('li a')
.forEach(function (anchor)  {
  anchor.onclick = function (e) {
    e.preventDefault();
    // get li value
    const diagramName = anchor.parentElement.innerText;
    dropdownDiagramChoiceElt.classList.add('hidden');
    loadDiagram(diagramName)

    return false;
  };
});
document.getElementById('toggle-dropdown-diagram-choice').onclick = function (){
  dropdownDiagramChoiceElt.classList.remove('hidden');
}
