diff --git a/libraries/panzoom.js b/libraries/panzoom.js deleted file mode 100644 index 0f8dce56c..000000000 --- a/libraries/panzoom.js +++ /dev/null @@ -1,1753 +0,0 @@ -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.panzoom = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i owner - }; - - eventify(api); - - return api; - - function pause() { - releaseEvents(); - paused = true; - } - - function resume() { - if (paused) { - listenForEvents(); - paused = false; - } - } - - function isPaused() { - return paused; - } - - function showRectangle(rect) { - // TODO: this duplicates autocenter. I think autocenter should go. - var clientRect = owner.getBoundingClientRect(); - var size = transformToScreen(clientRect.width, clientRect.height); - - var rectWidth = rect.right - rect.left; - var rectHeight = rect.bottom - rect.top; - if (!Number.isFinite(rectWidth) || !Number.isFinite(rectHeight)) { - throw new Error('Invalid rectangle'); - } - - var dw = size.x / rectWidth; - var dh = size.y / rectHeight; - var scale = Math.min(dw, dh); - transform.x = -(rect.left + rectWidth / 2) * scale + size.x / 2; - transform.y = -(rect.top + rectHeight / 2) * scale + size.y / 2; - transform.scale = scale; - } - - function transformToScreen(x, y) { - if (panController.getScreenCTM) { - var parentCTM = panController.getScreenCTM(); - var parentScaleX = parentCTM.a; - var parentScaleY = parentCTM.d; - var parentOffsetX = parentCTM.e; - var parentOffsetY = parentCTM.f; - storedCTMResult.x = x * parentScaleX - parentOffsetX; - storedCTMResult.y = y * parentScaleY - parentOffsetY; - } else { - storedCTMResult.x = x; - storedCTMResult.y = y; - } - - return storedCTMResult; - } - - function autocenter() { - var w; // width of the parent - var h; // height of the parent - var left = 0; - var top = 0; - var sceneBoundingBox = getBoundingBox(); - if (sceneBoundingBox) { - // If we have bounding box - use it. - left = sceneBoundingBox.left; - top = sceneBoundingBox.top; - w = sceneBoundingBox.right - sceneBoundingBox.left; - h = sceneBoundingBox.bottom - sceneBoundingBox.top; - } else { - // otherwise just use whatever space we have - var ownerRect = owner.getBoundingClientRect(); - w = ownerRect.width; - h = ownerRect.height; - } - var bbox = panController.getBBox(); - if (bbox.width === 0 || bbox.height === 0) { - // we probably do not have any elements in the SVG - // just bail out; - return; - } - var dh = h / bbox.height; - var dw = w / bbox.width; - var scale = Math.min(dw, dh); - transform.x = -(bbox.left + bbox.width / 2) * scale + w / 2 + left; - transform.y = -(bbox.top + bbox.height / 2) * scale + h / 2 + top; - transform.scale = scale; - } - - function getTransformModel() { - // TODO: should this be read only? - return transform; - } - - function getMinZoom() { - return minZoom; - } - - function setMinZoom(newMinZoom) { - minZoom = newMinZoom; - } - - function getMaxZoom() { - return maxZoom; - } - - function setMaxZoom(newMaxZoom) { - maxZoom = newMaxZoom; - } - - function getTransformOrigin() { - return transformOrigin; - } - - function setTransformOrigin(newTransformOrigin) { - transformOrigin = parseTransformOrigin(newTransformOrigin); - } - - function getZoomSpeed() { - return speed; - } - - function setZoomSpeed(newSpeed) { - if (!Number.isFinite(newSpeed)) { - throw new Error('Zoom speed should be a number'); - } - speed = newSpeed; - } - - function getPoint() { - return { - x: transform.x, - y: transform.y - }; - } - - function moveTo(x, y) { - transform.x = x; - transform.y = y; - - keepTransformInsideBounds(); - - triggerEvent('pan'); - makeDirty(); - } - - function moveBy(dx, dy) { - moveTo(transform.x + dx, transform.y + dy); - } - - function keepTransformInsideBounds() { - var boundingBox = getBoundingBox(); - if (!boundingBox) return; - - var adjusted = false; - var clientRect = getClientRect(); - - var diff = boundingBox.left - clientRect.right; - if (diff > 0) { - transform.x += diff; - adjusted = true; - } - // check the other side: - diff = boundingBox.right - clientRect.left; - if (diff < 0) { - transform.x += diff; - adjusted = true; - } - - // y axis: - diff = boundingBox.top - clientRect.bottom; - if (diff > 0) { - // we adjust transform, so that it matches exactly our bounding box: - // transform.y = boundingBox.top - (boundingBox.height + boundingBox.y) * transform.scale => - // transform.y = boundingBox.top - (clientRect.bottom - transform.y) => - // transform.y = diff + transform.y => - transform.y += diff; - adjusted = true; - } - - diff = boundingBox.bottom - clientRect.top; - if (diff < 0) { - transform.y += diff; - adjusted = true; - } - return adjusted; - } - - /** - * Returns bounding box that should be used to restrict scene movement. - */ - function getBoundingBox() { - if (!bounds) return; // client does not want to restrict movement - - if (typeof bounds === 'boolean') { - // for boolean type we use parent container bounds - var ownerRect = owner.getBoundingClientRect(); - var sceneWidth = ownerRect.width; - var sceneHeight = ownerRect.height; - - return { - left: sceneWidth * boundsPadding, - top: sceneHeight * boundsPadding, - right: sceneWidth * (1 - boundsPadding), - bottom: sceneHeight * (1 - boundsPadding) - }; - } - - return bounds; - } - - function getClientRect() { - var bbox = panController.getBBox(); - var leftTop = client(bbox.left, bbox.top); - - return { - left: leftTop.x, - top: leftTop.y, - right: bbox.width * transform.scale + leftTop.x, - bottom: bbox.height * transform.scale + leftTop.y - }; - } - - function client(x, y) { - return { - x: x * transform.scale + transform.x, - y: y * transform.scale + transform.y - }; - } - - function makeDirty() { - isDirty = true; - frameAnimation = window.requestAnimationFrame(frame); - } - - function zoomByRatio(clientX, clientY, ratio) { - if (isNaN(clientX) || isNaN(clientY) || isNaN(ratio)) { - throw new Error('zoom requires valid numbers'); - } - - var newScale = transform.scale * ratio; - - if (newScale < minZoom) { - if (transform.scale === minZoom) return; - - ratio = minZoom / transform.scale; - } - if (newScale > maxZoom) { - if (transform.scale === maxZoom) return; - - ratio = maxZoom / transform.scale; - } - - var size = transformToScreen(clientX, clientY); - - transform.x = size.x - ratio * (size.x - transform.x); - transform.y = size.y - ratio * (size.y - transform.y); - - // TODO: https://github.com/anvaka/panzoom/issues/112 - if (bounds && boundsPadding === 1 && minZoom === 1) { - transform.scale *= ratio; - keepTransformInsideBounds(); - } else { - var transformAdjusted = keepTransformInsideBounds(); - if (!transformAdjusted) transform.scale *= ratio; - } - - triggerEvent('zoom'); - - makeDirty(); - } - - function zoomAbs(clientX, clientY, zoomLevel) { - var ratio = zoomLevel / transform.scale; - zoomByRatio(clientX, clientY, ratio); - } - - function centerOn(ui) { - var parent = ui.ownerSVGElement; - if (!parent) - throw new Error('ui element is required to be within the scene'); - - // TODO: should i use controller's screen CTM? - var clientRect = ui.getBoundingClientRect(); - var cx = clientRect.left + clientRect.width / 2; - var cy = clientRect.top + clientRect.height / 2; - - var container = parent.getBoundingClientRect(); - var dx = container.width / 2 - cx; - var dy = container.height / 2 - cy; - - internalMoveBy(dx, dy, true); - } - - function internalMoveBy(dx, dy, smooth) { - if (!smooth) { - return moveBy(dx, dy); - } - - if (moveByAnimation) moveByAnimation.cancel(); - - var from = { x: 0, y: 0 }; - var to = { x: dx, y: dy }; - var lastX = 0; - var lastY = 0; - - moveByAnimation = animate(from, to, { - step: function (v) { - moveBy(v.x - lastX, v.y - lastY); - - lastX = v.x; - lastY = v.y; - } - }); - } - - function scroll(x, y) { - cancelZoomAnimation(); - moveTo(x, y); - } - - function dispose() { - releaseEvents(); - } - - function listenForEvents() { - owner.addEventListener('mousedown', onMouseDown, { passive: false }); - owner.addEventListener('dblclick', onDoubleClick, { passive: false }); - owner.addEventListener('touchstart', onTouch, { passive: false }); - owner.addEventListener('keydown', onKeyDown, { passive: false }); - - // Need to listen on the owner container, so that we are not limited - // by the size of the scrollable domElement - wheel.addWheelListener(owner, onMouseWheel, { passive: false }); - - makeDirty(); - } - - function releaseEvents() { - wheel.removeWheelListener(owner, onMouseWheel); - owner.removeEventListener('mousedown', onMouseDown); - owner.removeEventListener('keydown', onKeyDown); - owner.removeEventListener('dblclick', onDoubleClick); - owner.removeEventListener('touchstart', onTouch); - - if (frameAnimation) { - window.cancelAnimationFrame(frameAnimation); - frameAnimation = 0; - } - - smoothScroll.cancel(); - - releaseDocumentMouse(); - releaseTouches(); - textSelection.release(); - - triggerPanEnd(); - } - - function frame() { - if (isDirty) applyTransform(); - } - - function applyTransform() { - isDirty = false; - - // TODO: Should I allow to cancel this? - panController.applyTransform(transform); - - triggerEvent('transform'); - frameAnimation = 0; - } - - function onKeyDown(e) { - var x = 0, - y = 0, - z = 0; - if (e.keyCode === 38) { - y = 1; // up - } else if (e.keyCode === 40) { - y = -1; // down - } else if (e.keyCode === 37) { - x = 1; // left - } else if (e.keyCode === 39) { - x = -1; // right - } else if (e.keyCode === 189 || e.keyCode === 109) { - // DASH or SUBTRACT - z = 1; // `-` - zoom out - } else if (e.keyCode === 187 || e.keyCode === 107) { - // EQUAL SIGN or ADD - z = -1; // `=` - zoom in (equal sign on US layout is under `+`) - } - - if (filterKey(e, x, y, z)) { - // They don't want us to handle the key: https://github.com/anvaka/panzoom/issues/45 - return; - } - - if (x || y) { - e.preventDefault(); - e.stopPropagation(); - - var clientRect = owner.getBoundingClientRect(); - // movement speed should be the same in both X and Y direction: - var offset = Math.min(clientRect.width, clientRect.height); - var moveSpeedRatio = 0.05; - var dx = offset * moveSpeedRatio * x; - var dy = offset * moveSpeedRatio * y; - - // TODO: currently we do not animate this. It could be better to have animation - internalMoveBy(dx, dy); - } - - if (z) { - var scaleMultiplier = getScaleMultiplier(z * 100); - var offset = transformOrigin ? getTransformOriginOffset() : midPoint(); - publicZoomTo(offset.x, offset.y, scaleMultiplier); - } - } - - function midPoint() { - var ownerRect = owner.getBoundingClientRect(); - return { - x: ownerRect.width / 2, - y: ownerRect.height / 2 - }; - } - - function onTouch(e) { - // let the override the touch behavior - beforeTouch(e); - - if (e.touches.length === 1) { - return handleSingleFingerTouch(e, e.touches[0]); - } else if (e.touches.length === 2) { - // handleTouchMove() will care about pinch zoom. - pinchZoomLength = getPinchZoomLength(e.touches[0], e.touches[1]); - multiTouch = true; - startTouchListenerIfNeeded(); - } - } - - function beforeTouch(e) { - // TODO: Need to unify this filtering names. E.g. use `beforeTouch` - if (options.onTouch && !options.onTouch(e)) { - // if they return `false` from onTouch, we don't want to stop - // events propagation. Fixes https://github.com/anvaka/panzoom/issues/12 - return; - } - - e.stopPropagation(); - e.preventDefault(); - } - - function beforeDoubleClick(e) { - // TODO: Need to unify this filtering names. E.g. use `beforeDoubleClick`` - if (options.onDoubleClick && !options.onDoubleClick(e)) { - // if they return `false` from onTouch, we don't want to stop - // events propagation. Fixes https://github.com/anvaka/panzoom/issues/46 - return; - } - - e.preventDefault(); - e.stopPropagation(); - } - - function handleSingleFingerTouch(e) { - var touch = e.touches[0]; - var offset = getOffsetXY(touch); - lastSingleFingerOffset = offset; - var point = transformToScreen(offset.x, offset.y); - mouseX = point.x; - mouseY = point.y; - - smoothScroll.cancel(); - startTouchListenerIfNeeded(); - } - - function startTouchListenerIfNeeded() { - if (touchInProgress) { - // no need to do anything, as we already listen to events; - return; - } - - touchInProgress = true; - document.addEventListener('touchmove', handleTouchMove); - document.addEventListener('touchend', handleTouchEnd); - document.addEventListener('touchcancel', handleTouchEnd); - } - - function handleTouchMove(e) { - if (e.touches.length === 1) { - e.stopPropagation(); - var touch = e.touches[0]; - - var offset = getOffsetXY(touch); - var point = transformToScreen(offset.x, offset.y); - - var dx = point.x - mouseX; - var dy = point.y - mouseY; - - if (dx !== 0 && dy !== 0) { - triggerPanStart(); - } - mouseX = point.x; - mouseY = point.y; - internalMoveBy(dx, dy); - } else if (e.touches.length === 2) { - // it's a zoom, let's find direction - multiTouch = true; - var t1 = e.touches[0]; - var t2 = e.touches[1]; - var currentPinchLength = getPinchZoomLength(t1, t2); - - // since the zoom speed is always based on distance from 1, we need to apply - // pinch speed only on that distance from 1: - var scaleMultiplier = - 1 + (currentPinchLength / pinchZoomLength - 1) * pinchSpeed; - - var firstTouchPoint = getOffsetXY(t1); - var secondTouchPoint = getOffsetXY(t2); - mouseX = (firstTouchPoint.x + secondTouchPoint.x) / 2; - mouseY = (firstTouchPoint.y + secondTouchPoint.y) / 2; - if (transformOrigin) { - var offset = getTransformOriginOffset(); - mouseX = offset.x; - mouseY = offset.y; - } - - publicZoomTo(mouseX, mouseY, scaleMultiplier); - - pinchZoomLength = currentPinchLength; - e.stopPropagation(); - e.preventDefault(); - } - } - - function handleTouchEnd(e) { - if (e.touches.length > 0) { - var offset = getOffsetXY(e.touches[0]); - var point = transformToScreen(offset.x, offset.y); - mouseX = point.x; - mouseY = point.y; - } else { - var now = new Date(); - if (now - lastTouchEndTime < doubleTapSpeedInMS) { - if (transformOrigin) { - var offset = getTransformOriginOffset(); - smoothZoom(offset.x, offset.y, zoomDoubleClickSpeed); - } else { - smoothZoom(lastSingleFingerOffset.x, lastSingleFingerOffset.y, zoomDoubleClickSpeed); - } - } - - lastTouchEndTime = now; - - touchInProgress = false; - triggerPanEnd(); - releaseTouches(); - } - } - - function getPinchZoomLength(finger1, finger2) { - var dx = finger1.clientX - finger2.clientX; - var dy = finger1.clientY - finger2.clientY; - return Math.sqrt(dx * dx + dy * dy); - } - - function onDoubleClick(e) { - beforeDoubleClick(e); - var offset = getOffsetXY(e); - if (transformOrigin) { - // TODO: looks like this is duplicated in the file. - // Need to refactor - offset = getTransformOriginOffset(); - } - smoothZoom(offset.x, offset.y, zoomDoubleClickSpeed); - } - - function onMouseDown(e) { - // if client does not want to handle this event - just ignore the call - if (beforeMouseDown(e)) return; - - if (touchInProgress) { - // modern browsers will fire mousedown for touch events too - // we do not want this: touch is handled separately. - e.stopPropagation(); - return false; - } - // for IE, left click == 1 - // for Firefox, left click == 0 - var isLeftButton = - (e.button === 1 && window.event !== null) || e.button === 0; - if (!isLeftButton) return; - - smoothScroll.cancel(); - - var offset = getOffsetXY(e); - var point = transformToScreen(offset.x, offset.y); - mouseX = point.x; - mouseY = point.y; - - // We need to listen on document itself, since mouse can go outside of the - // window, and we will loose it - document.addEventListener('mousemove', onMouseMove); - document.addEventListener('mouseup', onMouseUp); - textSelection.capture(e.target || e.srcElement); - - return false; - } - - function onMouseMove(e) { - // no need to worry about mouse events when touch is happening - if (touchInProgress) return; - - triggerPanStart(); - - var offset = getOffsetXY(e); - var point = transformToScreen(offset.x, offset.y); - var dx = point.x - mouseX; - var dy = point.y - mouseY; - - mouseX = point.x; - mouseY = point.y; - - internalMoveBy(dx, dy); - } - - function onMouseUp() { - textSelection.release(); - triggerPanEnd(); - releaseDocumentMouse(); - } - - function releaseDocumentMouse() { - document.removeEventListener('mousemove', onMouseMove); - document.removeEventListener('mouseup', onMouseUp); - panstartFired = false; - } - - function releaseTouches() { - document.removeEventListener('touchmove', handleTouchMove); - document.removeEventListener('touchend', handleTouchEnd); - document.removeEventListener('touchcancel', handleTouchEnd); - panstartFired = false; - multiTouch = false; - } - - function onMouseWheel(e) { - // if client does not want to handle this event - just ignore the call - if (beforeWheel(e)) return; - - smoothScroll.cancel(); - - var delta = e.deltaY; - if (e.deltaMode > 0) delta *= 100; - - var scaleMultiplier = getScaleMultiplier(delta); - - if (scaleMultiplier !== 1) { - var offset = transformOrigin - ? getTransformOriginOffset() - : getOffsetXY(e); - publicZoomTo(offset.x, offset.y, scaleMultiplier); - e.preventDefault(); - } - } - - function getOffsetXY(e) { - var offsetX, offsetY; - // I tried using e.offsetX, but that gives wrong results for svg, when user clicks on a path. - var ownerRect = owner.getBoundingClientRect(); - offsetX = e.clientX - ownerRect.left; - offsetY = e.clientY - ownerRect.top; - - return { x: offsetX, y: offsetY }; - } - - function smoothZoom(clientX, clientY, scaleMultiplier) { - var fromValue = transform.scale; - var from = { scale: fromValue }; - var to = { scale: scaleMultiplier * fromValue }; - - smoothScroll.cancel(); - cancelZoomAnimation(); - - zoomToAnimation = animate(from, to, { - step: function (v) { - zoomAbs(clientX, clientY, v.scale); - }, - done: triggerZoomEnd - }); - } - - function smoothZoomAbs(clientX, clientY, toScaleValue) { - var fromValue = transform.scale; - var from = { scale: fromValue }; - var to = { scale: toScaleValue }; - - smoothScroll.cancel(); - cancelZoomAnimation(); - - zoomToAnimation = animate(from, to, { - step: function (v) { - zoomAbs(clientX, clientY, v.scale); - } - }); - } - - function getTransformOriginOffset() { - var ownerRect = owner.getBoundingClientRect(); - return { - x: ownerRect.width * transformOrigin.x, - y: ownerRect.height * transformOrigin.y - }; - } - - function publicZoomTo(clientX, clientY, scaleMultiplier) { - smoothScroll.cancel(); - cancelZoomAnimation(); - return zoomByRatio(clientX, clientY, scaleMultiplier); - } - - function cancelZoomAnimation() { - if (zoomToAnimation) { - zoomToAnimation.cancel(); - zoomToAnimation = null; - } - } - - function getScaleMultiplier(delta) { - var sign = Math.sign(delta); - var deltaAdjustedSpeed = Math.min(0.25, Math.abs(speed * delta / 128)); - return 1 - sign * deltaAdjustedSpeed; - } - - function triggerPanStart() { - if (!panstartFired) { - triggerEvent('panstart'); - panstartFired = true; - smoothScroll.start(); - } - } - - function triggerPanEnd() { - if (panstartFired) { - // we should never run smooth scrolling if it was multiTouch (pinch zoom animation): - if (!multiTouch) smoothScroll.stop(); - triggerEvent('panend'); - } - } - - function triggerZoomEnd() { - triggerEvent('zoomend'); - } - - function triggerEvent(name) { - api.fire(name, api); - } -} - -function parseTransformOrigin(options) { - if (!options) return; - if (typeof options === 'object') { - if (!isNumber(options.x) || !isNumber(options.y)) - failTransformOrigin(options); - return options; - } - - failTransformOrigin(); -} - -function failTransformOrigin(options) { - console.error(options); - throw new Error( - [ - 'Cannot parse transform origin.', - 'Some good examples:', - ' "center center" can be achieved with {x: 0.5, y: 0.5}', - ' "top center" can be achieved with {x: 0.5, y: 0}', - ' "bottom right" can be achieved with {x: 1, y: 1}' - ].join('\n') - ); -} - -function noop() { } - -function validateBounds(bounds) { - var boundsType = typeof bounds; - if (boundsType === 'undefined' || boundsType === 'boolean') return; // this is okay - // otherwise need to be more thorough: - var validBounds = - isNumber(bounds.left) && - isNumber(bounds.top) && - isNumber(bounds.bottom) && - isNumber(bounds.right); - - if (!validBounds) - throw new Error( - 'Bounds object is not valid. It can be: ' + - 'undefined, boolean (true|false) or an object {left, top, right, bottom}' - ); -} - -function isNumber(x) { - return Number.isFinite(x); -} - -// IE 11 does not support isNaN: -function isNaN(value) { - if (Number.isNaN) { - return Number.isNaN(value); - } - - return value !== value; -} - -function rigidScroll() { - return { - start: noop, - stop: noop, - cancel: noop - }; -} - -function autoRun() { - if (typeof document === 'undefined') return; - - var scripts = document.getElementsByTagName('script'); - if (!scripts) return; - var panzoomScript; - - for (var i = 0; i < scripts.length; ++i) { - var x = scripts[i]; - if (x.src && x.src.match(/\bpanzoom(\.min)?\.js/)) { - panzoomScript = x; - break; - } - } - - if (!panzoomScript) return; - - var query = panzoomScript.getAttribute('query'); - if (!query) return; - - var globalName = panzoomScript.getAttribute('name') || 'pz'; - var started = Date.now(); - - tryAttach(); - - function tryAttach() { - var el = document.querySelector(query); - if (!el) { - var now = Date.now(); - var elapsed = now - started; - if (elapsed < 2000) { - // Let's wait a bit - setTimeout(tryAttach, 100); - return; - } - // If we don't attach within 2 seconds to the target element, consider it a failure - console.error('Cannot find the panzoom element', globalName); - return; - } - var options = collectOptions(panzoomScript); - console.log(options); - window[globalName] = createPanZoom(el, options); - } - - function collectOptions(script) { - var attrs = script.attributes; - var options = {}; - for (var i = 0; i < attrs.length; ++i) { - var attr = attrs[i]; - var nameValue = getPanzoomAttributeNameValue(attr); - if (nameValue) { - options[nameValue.name] = nameValue.value; - } - } - - return options; - } - - function getPanzoomAttributeNameValue(attr) { - if (!attr.name) return; - var isPanZoomAttribute = - attr.name[0] === 'p' && attr.name[1] === 'z' && attr.name[2] === '-'; - - if (!isPanZoomAttribute) return; - - var name = attr.name.substr(3); - var value = JSON.parse(attr.value); - return { name: name, value: value }; - } -} - -autoRun(); - -},{"./lib/createTextSelectionInterceptor.js":2,"./lib/domController.js":3,"./lib/kinetic.js":4,"./lib/svgController.js":5,"./lib/transform.js":6,"amator":7,"ngraph.events":9,"wheel":10}],2:[function(require,module,exports){ -/** - * Disallows selecting text. - */ -module.exports = createTextSelectionInterceptor; - -function createTextSelectionInterceptor(useFake) { - if (useFake) { - return { - capture: noop, - release: noop - }; - } - - var dragObject; - var prevSelectStart; - var prevDragStart; - var wasCaptured = false; - - return { - capture: capture, - release: release - }; - - function capture(domObject) { - wasCaptured = true; - prevSelectStart = window.document.onselectstart; - prevDragStart = window.document.ondragstart; - - window.document.onselectstart = disabled; - - dragObject = domObject; - dragObject.ondragstart = disabled; - } - - function release() { - if (!wasCaptured) return; - - wasCaptured = false; - window.document.onselectstart = prevSelectStart; - if (dragObject) dragObject.ondragstart = prevDragStart; - } -} - -function disabled(e) { - e.stopPropagation(); - return false; -} - -function noop() {} - -},{}],3:[function(require,module,exports){ -module.exports = makeDomController - -function makeDomController(domElement, options) { - var elementValid = (domElement instanceof HTMLElement) - if (!elementValid) { - throw new Error('svg element is required for svg.panzoom to work') - } - - var owner = domElement.parentElement - if (!owner) { - throw new Error( - 'Do not apply panzoom to the detached DOM element. ' - ) - } - - domElement.scrollTop = 0; - - if (!options.disableKeyboardInteraction) { - owner.setAttribute('tabindex', 0); - } - - var api = { - getBBox: getBBox, - getOwner: getOwner, - applyTransform: applyTransform, - } - - return api - - function getOwner() { - return owner - } - - function getBBox() { - // TODO: We should probably cache this? - return { - left: 0, - top: 0, - width: domElement.clientWidth, - height: domElement.clientHeight - } - } - - function applyTransform(transform) { - // TODO: Should we cache this? - domElement.style.transformOrigin = '0 0 0'; - domElement.style.transform = 'matrix(' + - transform.scale + ', 0, 0, ' + - transform.scale + ', ' + - transform.x + ', ' + transform.y + ')' - } -} - -},{}],4:[function(require,module,exports){ -(function (global){ -/** - * Allows smooth kinetic scrolling of the surface - */ -module.exports = kinetic; - -function kinetic(getPoint, scroll, settings) { - if (typeof settings !== 'object') { - // setting could come as boolean, we should ignore it, and use an object. - settings = {}; - } - - var minVelocity = typeof settings.minVelocity === 'number' ? settings.minVelocity : 5; - var amplitude = typeof settings.amplitude === 'number' ? settings.amplitude : 0.25; - var cancelAnimationFrame = typeof settings.cancelAnimationFrame === 'function' ? settings.cancelAnimationFrame : getCancelAnimationFrame(); - var requestAnimationFrame = typeof settings.requestAnimationFrame === 'function' ? settings.requestAnimationFrame : getRequestAnimationFrame(); - - var lastPoint; - var timestamp; - var timeConstant = 342; - - var ticker; - var vx, targetX, ax; - var vy, targetY, ay; - - var raf; - - return { - start: start, - stop: stop, - cancel: dispose - }; - - function dispose() { - cancelAnimationFrame(ticker); - cancelAnimationFrame(raf); - } - - function start() { - lastPoint = getPoint(); - - ax = ay = vx = vy = 0; - timestamp = new Date(); - - cancelAnimationFrame(ticker); - cancelAnimationFrame(raf); - - // we start polling the point position to accumulate velocity - // Once we stop(), we will use accumulated velocity to keep scrolling - // an object. - ticker = requestAnimationFrame(track); - } - - function track() { - var now = Date.now(); - var elapsed = now - timestamp; - timestamp = now; - - var currentPoint = getPoint(); - - var dx = currentPoint.x - lastPoint.x; - var dy = currentPoint.y - lastPoint.y; - - lastPoint = currentPoint; - - var dt = 1000 / (1 + elapsed); - - // moving average - vx = 0.8 * dx * dt + 0.2 * vx; - vy = 0.8 * dy * dt + 0.2 * vy; - - ticker = requestAnimationFrame(track); - } - - function stop() { - cancelAnimationFrame(ticker); - cancelAnimationFrame(raf); - - var currentPoint = getPoint(); - - targetX = currentPoint.x; - targetY = currentPoint.y; - timestamp = Date.now(); - - if (vx < -minVelocity || vx > minVelocity) { - ax = amplitude * vx; - targetX += ax; - } - - if (vy < -minVelocity || vy > minVelocity) { - ay = amplitude * vy; - targetY += ay; - } - - raf = requestAnimationFrame(autoScroll); - } - - function autoScroll() { - var elapsed = Date.now() - timestamp; - - var moving = false; - var dx = 0; - var dy = 0; - - if (ax) { - dx = -ax * Math.exp(-elapsed / timeConstant); - - if (dx > 0.5 || dx < -0.5) moving = true; - else dx = ax = 0; - } - - if (ay) { - dy = -ay * Math.exp(-elapsed / timeConstant); - - if (dy > 0.5 || dy < -0.5) moving = true; - else dy = ay = 0; - } - - if (moving) { - scroll(targetX + dx, targetY + dy); - raf = requestAnimationFrame(autoScroll); - } - } -} - -function getCancelAnimationFrame() { - if (typeof global.cancelAnimationFrame === 'function') return global.cancelAnimationFrame; - - return clearTimeout; -} - -function getRequestAnimationFrame() { - if (typeof global.requestAnimationFrame === 'function') return global.requestAnimationFrame; - - return function (handler) { - return setTimeout(handler, 16); - } -} -}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],5:[function(require,module,exports){ -module.exports = makeSvgController - -function makeSvgController(svgElement, options) { - var elementValid = (svgElement instanceof SVGElement) - if (!elementValid) { - throw new Error('svg element is required for svg.panzoom to work') - } - - var owner = svgElement.ownerSVGElement - if (!owner) { - throw new Error( - 'Do not apply panzoom to the root element. ' + - 'Use its child instead (e.g. ). ' + - 'As of March 2016 only FireFox supported transform on the root element') - } - - if (!options.disableKeyboardInteraction) { - owner.setAttribute('tabindex', 0); - } - - var api = { - getBBox: getBBox, - getScreenCTM: getScreenCTM, - getOwner: getOwner, - applyTransform: applyTransform, - initTransform: initTransform - } - - return api - - function getOwner() { - return owner - } - - function getBBox() { - var bbox = svgElement.getBBox() - return { - left: bbox.x, - top: bbox.y, - width: bbox.width, - height: bbox.height, - } - } - - function getScreenCTM() { - var ctm = owner.getCTM(); - if (!ctm) { - // This is likely firefox: https://bugzilla.mozilla.org/show_bug.cgi?id=873106 - // The code below is not entirely correct, but still better than nothing - return owner.getScreenCTM(); - } - return ctm; - } - - function initTransform(transform) { - var screenCTM = svgElement.getCTM() - transform.x = screenCTM.e; - transform.y = screenCTM.f; - transform.scale = screenCTM.a; - owner.removeAttributeNS(null, 'viewBox'); - } - - function applyTransform(transform) { - svgElement.setAttribute('transform', 'matrix(' + - transform.scale + ' 0 0 ' + - transform.scale + ' ' + - transform.x + ' ' + transform.y + ')') - } -} -},{}],6:[function(require,module,exports){ -module.exports = Transform; - -function Transform() { - this.x = 0; - this.y = 0; - this.scale = 1; -} - -},{}],7:[function(require,module,exports){ -var BezierEasing = require('bezier-easing') - -// Predefined set of animations. Similar to CSS easing functions -var animations = { - ease: BezierEasing(0.25, 0.1, 0.25, 1), - easeIn: BezierEasing(0.42, 0, 1, 1), - easeOut: BezierEasing(0, 0, 0.58, 1), - easeInOut: BezierEasing(0.42, 0, 0.58, 1), - linear: BezierEasing(0, 0, 1, 1) -} - - -module.exports = animate; -module.exports.makeAggregateRaf = makeAggregateRaf; -module.exports.sharedScheduler = makeAggregateRaf(); - - -function animate(source, target, options) { - var start = Object.create(null) - var diff = Object.create(null) - options = options || {} - // We let clients specify their own easing function - var easing = (typeof options.easing === 'function') ? options.easing : animations[options.easing] - - // if nothing is specified, default to ease (similar to CSS animations) - if (!easing) { - if (options.easing) { - console.warn('Unknown easing function in amator: ' + options.easing); - } - easing = animations.ease - } - - var step = typeof options.step === 'function' ? options.step : noop - var done = typeof options.done === 'function' ? options.done : noop - - var scheduler = getScheduler(options.scheduler) - - var keys = Object.keys(target) - keys.forEach(function(key) { - start[key] = source[key] - diff[key] = target[key] - source[key] - }) - - var durationInMs = typeof options.duration === 'number' ? options.duration : 400 - var durationInFrames = Math.max(1, durationInMs * 0.06) // 0.06 because 60 frames pers 1,000 ms - var previousAnimationId - var frame = 0 - - previousAnimationId = scheduler.next(loop) - - return { - cancel: cancel - } - - function cancel() { - scheduler.cancel(previousAnimationId) - previousAnimationId = 0 - } - - function loop() { - var t = easing(frame/durationInFrames) - frame += 1 - setValues(t) - if (frame <= durationInFrames) { - previousAnimationId = scheduler.next(loop) - step(source) - } else { - previousAnimationId = 0 - setTimeout(function() { done(source) }, 0) - } - } - - function setValues(t) { - keys.forEach(function(key) { - source[key] = diff[key] * t + start[key] - }) - } -} - -function noop() { } - -function getScheduler(scheduler) { - if (!scheduler) { - var canRaf = typeof window !== 'undefined' && window.requestAnimationFrame - return canRaf ? rafScheduler() : timeoutScheduler() - } - if (typeof scheduler.next !== 'function') throw new Error('Scheduler is supposed to have next(cb) function') - if (typeof scheduler.cancel !== 'function') throw new Error('Scheduler is supposed to have cancel(handle) function') - - return scheduler -} - -function rafScheduler() { - return { - next: window.requestAnimationFrame.bind(window), - cancel: window.cancelAnimationFrame.bind(window) - } -} - -function timeoutScheduler() { - return { - next: function(cb) { - return setTimeout(cb, 1000/60) - }, - cancel: function (id) { - return clearTimeout(id) - } - } -} - -function makeAggregateRaf() { - var frontBuffer = new Set(); - var backBuffer = new Set(); - var frameToken = 0; - - return { - next: next, - cancel: next, - clearAll: clearAll - } - - function clearAll() { - frontBuffer.clear(); - backBuffer.clear(); - cancelAnimationFrame(frameToken); - frameToken = 0; - } - - function next(callback) { - backBuffer.add(callback); - renderNextFrame(); - } - - function renderNextFrame() { - if (!frameToken) frameToken = requestAnimationFrame(renderFrame); - } - - function renderFrame() { - frameToken = 0; - - var t = backBuffer; - backBuffer = frontBuffer; - frontBuffer = t; - - frontBuffer.forEach(function(callback) { - callback(); - }); - frontBuffer.clear(); - } - - function cancel(callback) { - backBuffer.delete(callback); - } -} - -},{"bezier-easing":8}],8:[function(require,module,exports){ -/** - * https://github.com/gre/bezier-easing - * BezierEasing - use bezier curve for transition easing function - * by Gaëtan Renaudeau 2014 - 2015 – MIT License - */ - -// These values are established by empiricism with tests (tradeoff: performance VS precision) -var NEWTON_ITERATIONS = 4; -var NEWTON_MIN_SLOPE = 0.001; -var SUBDIVISION_PRECISION = 0.0000001; -var SUBDIVISION_MAX_ITERATIONS = 10; - -var kSplineTableSize = 11; -var kSampleStepSize = 1.0 / (kSplineTableSize - 1.0); - -var float32ArraySupported = typeof Float32Array === 'function'; - -function A (aA1, aA2) { return 1.0 - 3.0 * aA2 + 3.0 * aA1; } -function B (aA1, aA2) { return 3.0 * aA2 - 6.0 * aA1; } -function C (aA1) { return 3.0 * aA1; } - -// Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2. -function calcBezier (aT, aA1, aA2) { return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT; } - -// Returns dx/dt given t, x1, and x2, or dy/dt given t, y1, and y2. -function getSlope (aT, aA1, aA2) { return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1); } - -function binarySubdivide (aX, aA, aB, mX1, mX2) { - var currentX, currentT, i = 0; - do { - currentT = aA + (aB - aA) / 2.0; - currentX = calcBezier(currentT, mX1, mX2) - aX; - if (currentX > 0.0) { - aB = currentT; - } else { - aA = currentT; - } - } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS); - return currentT; -} - -function newtonRaphsonIterate (aX, aGuessT, mX1, mX2) { - for (var i = 0; i < NEWTON_ITERATIONS; ++i) { - var currentSlope = getSlope(aGuessT, mX1, mX2); - if (currentSlope === 0.0) { - return aGuessT; - } - var currentX = calcBezier(aGuessT, mX1, mX2) - aX; - aGuessT -= currentX / currentSlope; - } - return aGuessT; -} - -function LinearEasing (x) { - return x; -} - -module.exports = function bezier (mX1, mY1, mX2, mY2) { - if (!(0 <= mX1 && mX1 <= 1 && 0 <= mX2 && mX2 <= 1)) { - throw new Error('bezier x values must be in [0, 1] range'); - } - - if (mX1 === mY1 && mX2 === mY2) { - return LinearEasing; - } - - // Precompute samples table - var sampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize); - for (var i = 0; i < kSplineTableSize; ++i) { - sampleValues[i] = calcBezier(i * kSampleStepSize, mX1, mX2); - } - - function getTForX (aX) { - var intervalStart = 0.0; - var currentSample = 1; - var lastSample = kSplineTableSize - 1; - - for (; currentSample !== lastSample && sampleValues[currentSample] <= aX; ++currentSample) { - intervalStart += kSampleStepSize; - } - --currentSample; - - // Interpolate to provide an initial guess for t - var dist = (aX - sampleValues[currentSample]) / (sampleValues[currentSample + 1] - sampleValues[currentSample]); - var guessForT = intervalStart + dist * kSampleStepSize; - - var initialSlope = getSlope(guessForT, mX1, mX2); - if (initialSlope >= NEWTON_MIN_SLOPE) { - return newtonRaphsonIterate(aX, guessForT, mX1, mX2); - } else if (initialSlope === 0.0) { - return guessForT; - } else { - return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize, mX1, mX2); - } - } - - return function BezierEasing (x) { - // Because JavaScript number are imprecise, we should guarantee the extremes are right. - if (x === 0) { - return 0; - } - if (x === 1) { - return 1; - } - return calcBezier(getTForX(x), mY1, mY2); - }; -}; - -},{}],9:[function(require,module,exports){ -module.exports = function(subject) { - validateSubject(subject); - - var eventsStorage = createEventsStorage(subject); - subject.on = eventsStorage.on; - subject.off = eventsStorage.off; - subject.fire = eventsStorage.fire; - return subject; -}; - -function createEventsStorage(subject) { - // Store all event listeners to this hash. Key is event name, value is array - // of callback records. - // - // A callback record consists of callback function and its optional context: - // { 'eventName' => [{callback: function, ctx: object}] } - var registeredEvents = Object.create(null); - - return { - on: function (eventName, callback, ctx) { - if (typeof callback !== 'function') { - throw new Error('callback is expected to be a function'); - } - var handlers = registeredEvents[eventName]; - if (!handlers) { - handlers = registeredEvents[eventName] = []; - } - handlers.push({callback: callback, ctx: ctx}); - - return subject; - }, - - off: function (eventName, callback) { - var wantToRemoveAll = (typeof eventName === 'undefined'); - if (wantToRemoveAll) { - // Killing old events storage should be enough in this case: - registeredEvents = Object.create(null); - return subject; - } - - if (registeredEvents[eventName]) { - var deleteAllCallbacksForEvent = (typeof callback !== 'function'); - if (deleteAllCallbacksForEvent) { - delete registeredEvents[eventName]; - } else { - var callbacks = registeredEvents[eventName]; - for (var i = 0; i < callbacks.length; ++i) { - if (callbacks[i].callback === callback) { - callbacks.splice(i, 1); - } - } - } - } - - return subject; - }, - - fire: function (eventName) { - var callbacks = registeredEvents[eventName]; - if (!callbacks) { - return subject; - } - - var fireArguments; - if (arguments.length > 1) { - fireArguments = Array.prototype.splice.call(arguments, 1); - } - for(var i = 0; i < callbacks.length; ++i) { - var callbackInfo = callbacks[i]; - callbackInfo.callback.apply(callbackInfo.ctx, fireArguments); - } - - return subject; - } - }; -} - -function validateSubject(subject) { - if (!subject) { - throw new Error('Eventify cannot use falsy object as events subject'); - } - var reservedWords = ['on', 'fire', 'off']; - for (var i = 0; i < reservedWords.length; ++i) { - if (subject.hasOwnProperty(reservedWords[i])) { - throw new Error("Subject cannot be eventified, since it already has property '" + reservedWords[i] + "'"); - } - } -} - -},{}],10:[function(require,module,exports){ -/** - * This module used to unify mouse wheel behavior between different browsers in 2014 - * Now it's just a wrapper around addEventListener('wheel'); - * - * Usage: - * var addWheelListener = require('wheel').addWheelListener; - * var removeWheelListener = require('wheel').removeWheelListener; - * addWheelListener(domElement, function (e) { - * // mouse wheel event - * }); - * removeWheelListener(domElement, function); - */ - -module.exports = addWheelListener; - -// But also expose "advanced" api with unsubscribe: -module.exports.addWheelListener = addWheelListener; -module.exports.removeWheelListener = removeWheelListener; - - -function addWheelListener(element, listener, useCapture) { - element.addEventListener('wheel', listener, useCapture); -} - -function removeWheelListener( element, listener, useCapture ) { - element.removeEventListener('wheel', listener, useCapture); -} -},{}]},{},[1])(1) -}); diff --git a/package-lock.json b/package-lock.json index 574677ab4..d999c8b24 100644 --- a/package-lock.json +++ b/package-lock.json @@ -59,6 +59,7 @@ "node-abi": "3.51.0", "normalize-strings": "1.1.1", "open": "8.4.1", + "panzoom": "^9.4.3", "print-this": "^2.0.0", "rand-token": "1.0.1", "react": "18.2.0", @@ -1899,6 +1900,14 @@ "ajv": "^6.9.1" } }, + "node_modules/amator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/amator/-/amator-1.1.0.tgz", + "integrity": "sha512-V5+aH8pe+Z3u/UG3L3pG3BaFQGXAyXHVQDroRwjPHdh08bcUEchAVsU1MCuJSCaU5o60wTK6KaE6te5memzgYw==", + "dependencies": { + "bezier-easing": "^2.0.3" + } + }, "node_modules/ansi-escapes": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", @@ -2619,6 +2628,11 @@ "prebuild-install": "^7.1.0" } }, + "node_modules/bezier-easing": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz", + "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==" + }, "node_modules/bezier-js": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/bezier-js/-/bezier-js-6.1.4.tgz", @@ -10778,6 +10792,11 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "node_modules/ngraph.events": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.2.tgz", + "integrity": "sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ==" + }, "node_modules/node-abi": { "version": "3.51.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", @@ -11474,6 +11493,16 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "node_modules/panzoom": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/panzoom/-/panzoom-9.4.3.tgz", + "integrity": "sha512-xaxCpElcRbQsUtIdwlrZA90P90+BHip4Vda2BC8MEb4tkI05PmR6cKECdqUCZ85ZvBHjpI9htJrZBxV5Gp/q/w==", + "dependencies": { + "amator": "^1.1.0", + "ngraph.events": "^1.2.2", + "wheel": "^1.0.0" + } + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -14815,6 +14844,11 @@ "node": ">=14" } }, + "node_modules/wheel": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wheel/-/wheel-1.0.0.tgz", + "integrity": "sha512-XiCMHibOiqalCQ+BaNSwRoZ9FDTAvOsXxGHXChBugewDj7HC8VBIER71dEOiRH1fSdLbRCQzngKTSiZ06ZQzeA==" + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -16614,6 +16648,14 @@ "dev": true, "requires": {} }, + "amator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/amator/-/amator-1.1.0.tgz", + "integrity": "sha512-V5+aH8pe+Z3u/UG3L3pG3BaFQGXAyXHVQDroRwjPHdh08bcUEchAVsU1MCuJSCaU5o60wTK6KaE6te5memzgYw==", + "requires": { + "bezier-easing": "^2.0.3" + } + }, "ansi-escapes": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-5.0.0.tgz", @@ -17182,6 +17224,11 @@ "prebuild-install": "^7.1.0" } }, + "bezier-easing": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/bezier-easing/-/bezier-easing-2.1.0.tgz", + "integrity": "sha512-gbIqZ/eslnUFC1tjEvtz0sgx+xTK20wDnYMIA27VA04R7w6xxXQPZDbibjA9DTWZRA2CXtwHykkVzlCaAJAZig==" + }, "bezier-js": { "version": "6.1.4", "resolved": "https://registry.npmjs.org/bezier-js/-/bezier-js-6.1.4.tgz", @@ -23183,6 +23230,11 @@ "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", "dev": true }, + "ngraph.events": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/ngraph.events/-/ngraph.events-1.2.2.tgz", + "integrity": "sha512-JsUbEOzANskax+WSYiAPETemLWYXmixuPAlmZmhIbIj6FH/WDgEGCGnRwUQBK0GjOnVm8Ui+e5IJ+5VZ4e32eQ==" + }, "node-abi": { "version": "3.51.0", "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.51.0.tgz", @@ -23711,6 +23763,16 @@ "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==" }, + "panzoom": { + "version": "9.4.3", + "resolved": "https://registry.npmjs.org/panzoom/-/panzoom-9.4.3.tgz", + "integrity": "sha512-xaxCpElcRbQsUtIdwlrZA90P90+BHip4Vda2BC8MEb4tkI05PmR6cKECdqUCZ85ZvBHjpI9htJrZBxV5Gp/q/w==", + "requires": { + "amator": "^1.1.0", + "ngraph.events": "^1.2.2", + "wheel": "^1.0.0" + } + }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -26243,6 +26305,11 @@ "webidl-conversions": "^7.0.0" } }, + "wheel": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wheel/-/wheel-1.0.0.tgz", + "integrity": "sha512-XiCMHibOiqalCQ+BaNSwRoZ9FDTAvOsXxGHXChBugewDj7HC8VBIER71dEOiRH1fSdLbRCQzngKTSiZ06ZQzeA==" + }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index 7d324b315..2459a099a 100644 --- a/package.json +++ b/package.json @@ -85,6 +85,7 @@ "node-abi": "3.51.0", "normalize-strings": "1.1.1", "open": "8.4.1", + "panzoom": "^9.4.3", "print-this": "^2.0.0", "rand-token": "1.0.1", "react": "18.2.0", diff --git a/src/public/app/services/library_loader.js b/src/public/app/services/library_loader.js index 3c7707afc..6860795ca 100644 --- a/src/public/app/services/library_loader.js +++ b/src/public/app/services/library_loader.js @@ -28,7 +28,7 @@ const ESLINT = {js: ["libraries/eslint.js"]}; const RELATION_MAP = { js: [ "libraries/jsplumb.js", - "libraries/panzoom.js" + "node_modules/panzoom/dist/panzoom.min.js" ], css: [ "stylesheets/relation_map.css" diff --git a/src/routes/assets.js b/src/routes/assets.js index 5c193ceb6..8c65e6232 100644 --- a/src/routes/assets.js +++ b/src/routes/assets.js @@ -64,6 +64,8 @@ function register(app) { app.use(`/${assetPath}/node_modules/print-this/`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/print-this/'))); app.use(`/${assetPath}/node_modules/split.js/dist/`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/split.js/dist/'))); + + app.use(`/${assetPath}/node_modules/panzoom/dist/`, persistentCacheStatic(path.join(srcRoot, '..', 'node_modules/panzoom/dist/'))); } module.exports = {