{ "version": 3, "sources": ["../../../node_modules/@rails/actioncable/src/adapters.js", "../../../node_modules/@rails/actioncable/src/logger.js", "../../../node_modules/@rails/actioncable/src/connection_monitor.js", "../../../node_modules/@rails/actioncable/src/internal.js", "../../../node_modules/@rails/actioncable/src/connection.js", "../../../node_modules/@rails/actioncable/src/subscription.js", "../../../node_modules/@rails/actioncable/src/subscription_guarantor.js", "../../../node_modules/@rails/actioncable/src/subscriptions.js", "../../../node_modules/@rails/actioncable/src/consumer.js", "../../../node_modules/@rails/actioncable/src/index.js", "../../../node_modules/highcharts/highcharts.js", "../../../node_modules/highlight.js/lib/core.js", "../../../node_modules/highlight.js/lib/languages/1c.js", "../../../node_modules/highlight.js/lib/languages/abnf.js", "../../../node_modules/highlight.js/lib/languages/accesslog.js", "../../../node_modules/highlight.js/lib/languages/actionscript.js", "../../../node_modules/highlight.js/lib/languages/ada.js", "../../../node_modules/highlight.js/lib/languages/angelscript.js", "../../../node_modules/highlight.js/lib/languages/apache.js", "../../../node_modules/highlight.js/lib/languages/applescript.js", "../../../node_modules/highlight.js/lib/languages/arcade.js", "../../../node_modules/highlight.js/lib/languages/arduino.js", "../../../node_modules/highlight.js/lib/languages/armasm.js", "../../../node_modules/highlight.js/lib/languages/xml.js", "../../../node_modules/highlight.js/lib/languages/asciidoc.js", "../../../node_modules/highlight.js/lib/languages/aspectj.js", "../../../node_modules/highlight.js/lib/languages/autohotkey.js", "../../../node_modules/highlight.js/lib/languages/autoit.js", "../../../node_modules/highlight.js/lib/languages/avrasm.js", "../../../node_modules/highlight.js/lib/languages/awk.js", "../../../node_modules/highlight.js/lib/languages/axapta.js", "../../../node_modules/highlight.js/lib/languages/bash.js", "../../../node_modules/highlight.js/lib/languages/basic.js", "../../../node_modules/highlight.js/lib/languages/bnf.js", "../../../node_modules/highlight.js/lib/languages/brainfuck.js", "../../../node_modules/highlight.js/lib/languages/c.js", "../../../node_modules/highlight.js/lib/languages/cal.js", "../../../node_modules/highlight.js/lib/languages/capnproto.js", "../../../node_modules/highlight.js/lib/languages/ceylon.js", "../../../node_modules/highlight.js/lib/languages/clean.js", "../../../node_modules/highlight.js/lib/languages/clojure.js", "../../../node_modules/highlight.js/lib/languages/clojure-repl.js", "../../../node_modules/highlight.js/lib/languages/cmake.js", "../../../node_modules/highlight.js/lib/languages/coffeescript.js", "../../../node_modules/highlight.js/lib/languages/coq.js", "../../../node_modules/highlight.js/lib/languages/cos.js", "../../../node_modules/highlight.js/lib/languages/cpp.js", "../../../node_modules/highlight.js/lib/languages/crmsh.js", "../../../node_modules/highlight.js/lib/languages/crystal.js", "../../../node_modules/highlight.js/lib/languages/csharp.js", "../../../node_modules/highlight.js/lib/languages/csp.js", "../../../node_modules/highlight.js/lib/languages/css.js", "../../../node_modules/highlight.js/lib/languages/d.js", "../../../node_modules/highlight.js/lib/languages/markdown.js", "../../../node_modules/highlight.js/lib/languages/dart.js", "../../../node_modules/highlight.js/lib/languages/delphi.js", "../../../node_modules/highlight.js/lib/languages/diff.js", "../../../node_modules/highlight.js/lib/languages/django.js", "../../../node_modules/highlight.js/lib/languages/dns.js", "../../../node_modules/highlight.js/lib/languages/dockerfile.js", "../../../node_modules/highlight.js/lib/languages/dos.js", "../../../node_modules/highlight.js/lib/languages/dsconfig.js", "../../../node_modules/highlight.js/lib/languages/dts.js", "../../../node_modules/highlight.js/lib/languages/dust.js", "../../../node_modules/highlight.js/lib/languages/ebnf.js", "../../../node_modules/highlight.js/lib/languages/elixir.js", "../../../node_modules/highlight.js/lib/languages/elm.js", "../../../node_modules/highlight.js/lib/languages/ruby.js", "../../../node_modules/highlight.js/lib/languages/erb.js", "../../../node_modules/highlight.js/lib/languages/erlang-repl.js", "../../../node_modules/highlight.js/lib/languages/erlang.js", "../../../node_modules/highlight.js/lib/languages/excel.js", "../../../node_modules/highlight.js/lib/languages/fix.js", "../../../node_modules/highlight.js/lib/languages/flix.js", "../../../node_modules/highlight.js/lib/languages/fortran.js", "../../../node_modules/highlight.js/lib/languages/fsharp.js", "../../../node_modules/highlight.js/lib/languages/gams.js", "../../../node_modules/highlight.js/lib/languages/gauss.js", "../../../node_modules/highlight.js/lib/languages/gcode.js", "../../../node_modules/highlight.js/lib/languages/gherkin.js", "../../../node_modules/highlight.js/lib/languages/glsl.js", "../../../node_modules/highlight.js/lib/languages/gml.js", "../../../node_modules/highlight.js/lib/languages/go.js", "../../../node_modules/highlight.js/lib/languages/golo.js", "../../../node_modules/highlight.js/lib/languages/gradle.js", "../../../node_modules/highlight.js/lib/languages/graphql.js", "../../../node_modules/highlight.js/lib/languages/groovy.js", "../../../node_modules/highlight.js/lib/languages/haml.js", "../../../node_modules/highlight.js/lib/languages/handlebars.js", "../../../node_modules/highlight.js/lib/languages/haskell.js", "../../../node_modules/highlight.js/lib/languages/haxe.js", "../../../node_modules/highlight.js/lib/languages/hsp.js", "../../../node_modules/highlight.js/lib/languages/http.js", "../../../node_modules/highlight.js/lib/languages/hy.js", "../../../node_modules/highlight.js/lib/languages/inform7.js", "../../../node_modules/highlight.js/lib/languages/ini.js", "../../../node_modules/highlight.js/lib/languages/irpf90.js", "../../../node_modules/highlight.js/lib/languages/isbl.js", "../../../node_modules/highlight.js/lib/languages/java.js", "../../../node_modules/highlight.js/lib/languages/javascript.js", "../../../node_modules/highlight.js/lib/languages/jboss-cli.js", "../../../node_modules/highlight.js/lib/languages/json.js", "../../../node_modules/highlight.js/lib/languages/julia.js", "../../../node_modules/highlight.js/lib/languages/julia-repl.js", "../../../node_modules/highlight.js/lib/languages/kotlin.js", "../../../node_modules/highlight.js/lib/languages/lasso.js", "../../../node_modules/highlight.js/lib/languages/latex.js", "../../../node_modules/highlight.js/lib/languages/ldif.js", "../../../node_modules/highlight.js/lib/languages/leaf.js", "../../../node_modules/highlight.js/lib/languages/less.js", "../../../node_modules/highlight.js/lib/languages/lisp.js", "../../../node_modules/highlight.js/lib/languages/livecodeserver.js", "../../../node_modules/highlight.js/lib/languages/livescript.js", "../../../node_modules/highlight.js/lib/languages/llvm.js", "../../../node_modules/highlight.js/lib/languages/lsl.js", "../../../node_modules/highlight.js/lib/languages/lua.js", "../../../node_modules/highlight.js/lib/languages/makefile.js", "../../../node_modules/highlight.js/lib/languages/mathematica.js", "../../../node_modules/highlight.js/lib/languages/matlab.js", "../../../node_modules/highlight.js/lib/languages/maxima.js", "../../../node_modules/highlight.js/lib/languages/mel.js", "../../../node_modules/highlight.js/lib/languages/mercury.js", "../../../node_modules/highlight.js/lib/languages/mipsasm.js", "../../../node_modules/highlight.js/lib/languages/mizar.js", "../../../node_modules/highlight.js/lib/languages/perl.js", "../../../node_modules/highlight.js/lib/languages/mojolicious.js", "../../../node_modules/highlight.js/lib/languages/monkey.js", "../../../node_modules/highlight.js/lib/languages/moonscript.js", "../../../node_modules/highlight.js/lib/languages/n1ql.js", "../../../node_modules/highlight.js/lib/languages/nestedtext.js", "../../../node_modules/highlight.js/lib/languages/nginx.js", "../../../node_modules/highlight.js/lib/languages/nim.js", "../../../node_modules/highlight.js/lib/languages/nix.js", "../../../node_modules/highlight.js/lib/languages/node-repl.js", "../../../node_modules/highlight.js/lib/languages/nsis.js", "../../../node_modules/highlight.js/lib/languages/objectivec.js", "../../../node_modules/highlight.js/lib/languages/ocaml.js", "../../../node_modules/highlight.js/lib/languages/openscad.js", "../../../node_modules/highlight.js/lib/languages/oxygene.js", "../../../node_modules/highlight.js/lib/languages/parser3.js", "../../../node_modules/highlight.js/lib/languages/pf.js", "../../../node_modules/highlight.js/lib/languages/pgsql.js", "../../../node_modules/highlight.js/lib/languages/php.js", "../../../node_modules/highlight.js/lib/languages/php-template.js", "../../../node_modules/highlight.js/lib/languages/plaintext.js", "../../../node_modules/highlight.js/lib/languages/pony.js", "../../../node_modules/highlight.js/lib/languages/powershell.js", "../../../node_modules/highlight.js/lib/languages/processing.js", "../../../node_modules/highlight.js/lib/languages/profile.js", "../../../node_modules/highlight.js/lib/languages/prolog.js", "../../../node_modules/highlight.js/lib/languages/properties.js", "../../../node_modules/highlight.js/lib/languages/protobuf.js", "../../../node_modules/highlight.js/lib/languages/puppet.js", "../../../node_modules/highlight.js/lib/languages/purebasic.js", "../../../node_modules/highlight.js/lib/languages/python.js", "../../../node_modules/highlight.js/lib/languages/python-repl.js", "../../../node_modules/highlight.js/lib/languages/q.js", "../../../node_modules/highlight.js/lib/languages/qml.js", "../../../node_modules/highlight.js/lib/languages/r.js", "../../../node_modules/highlight.js/lib/languages/reasonml.js", "../../../node_modules/highlight.js/lib/languages/rib.js", "../../../node_modules/highlight.js/lib/languages/roboconf.js", "../../../node_modules/highlight.js/lib/languages/routeros.js", "../../../node_modules/highlight.js/lib/languages/rsl.js", "../../../node_modules/highlight.js/lib/languages/ruleslanguage.js", "../../../node_modules/highlight.js/lib/languages/rust.js", "../../../node_modules/highlight.js/lib/languages/sas.js", "../../../node_modules/highlight.js/lib/languages/scala.js", "../../../node_modules/highlight.js/lib/languages/scheme.js", "../../../node_modules/highlight.js/lib/languages/scilab.js", "../../../node_modules/highlight.js/lib/languages/scss.js", "../../../node_modules/highlight.js/lib/languages/shell.js", "../../../node_modules/highlight.js/lib/languages/smali.js", "../../../node_modules/highlight.js/lib/languages/smalltalk.js", "../../../node_modules/highlight.js/lib/languages/sml.js", "../../../node_modules/highlight.js/lib/languages/sqf.js", "../../../node_modules/highlight.js/lib/languages/sql.js", "../../../node_modules/highlight.js/lib/languages/stan.js", "../../../node_modules/highlight.js/lib/languages/stata.js", "../../../node_modules/highlight.js/lib/languages/step21.js", "../../../node_modules/highlight.js/lib/languages/stylus.js", "../../../node_modules/highlight.js/lib/languages/subunit.js", "../../../node_modules/highlight.js/lib/languages/swift.js", "../../../node_modules/highlight.js/lib/languages/taggerscript.js", "../../../node_modules/highlight.js/lib/languages/yaml.js", "../../../node_modules/highlight.js/lib/languages/tap.js", "../../../node_modules/highlight.js/lib/languages/tcl.js", "../../../node_modules/highlight.js/lib/languages/thrift.js", "../../../node_modules/highlight.js/lib/languages/tp.js", "../../../node_modules/highlight.js/lib/languages/twig.js", "../../../node_modules/highlight.js/lib/languages/typescript.js", "../../../node_modules/highlight.js/lib/languages/vala.js", "../../../node_modules/highlight.js/lib/languages/vbnet.js", "../../../node_modules/highlight.js/lib/languages/vbscript.js", "../../../node_modules/highlight.js/lib/languages/vbscript-html.js", "../../../node_modules/highlight.js/lib/languages/verilog.js", "../../../node_modules/highlight.js/lib/languages/vhdl.js", "../../../node_modules/highlight.js/lib/languages/vim.js", "../../../node_modules/highlight.js/lib/languages/wasm.js", "../../../node_modules/highlight.js/lib/languages/wren.js", "../../../node_modules/highlight.js/lib/languages/x86asm.js", "../../../node_modules/highlight.js/lib/languages/xl.js", "../../../node_modules/highlight.js/lib/languages/xquery.js", "../../../node_modules/highlight.js/lib/languages/zephir.js", "../../../node_modules/highlight.js/lib/index.js", "../../../node_modules/lodash/isArray.js", "../../../node_modules/lodash/_freeGlobal.js", "../../../node_modules/lodash/_root.js", "../../../node_modules/lodash/_Symbol.js", "../../../node_modules/lodash/_getRawTag.js", "../../../node_modules/lodash/_objectToString.js", "../../../node_modules/lodash/_baseGetTag.js", "../../../node_modules/lodash/isObjectLike.js", "../../../node_modules/lodash/isSymbol.js", "../../../node_modules/lodash/_isKey.js", "../../../node_modules/lodash/isObject.js", "../../../node_modules/lodash/isFunction.js", "../../../node_modules/lodash/_coreJsData.js", "../../../node_modules/lodash/_isMasked.js", "../../../node_modules/lodash/_toSource.js", "../../../node_modules/lodash/_baseIsNative.js", "../../../node_modules/lodash/_getValue.js", "../../../node_modules/lodash/_getNative.js", "../../../node_modules/lodash/_nativeCreate.js", "../../../node_modules/lodash/_hashClear.js", "../../../node_modules/lodash/_hashDelete.js", "../../../node_modules/lodash/_hashGet.js", "../../../node_modules/lodash/_hashHas.js", "../../../node_modules/lodash/_hashSet.js", "../../../node_modules/lodash/_Hash.js", "../../../node_modules/lodash/_listCacheClear.js", "../../../node_modules/lodash/eq.js", "../../../node_modules/lodash/_assocIndexOf.js", "../../../node_modules/lodash/_listCacheDelete.js", "../../../node_modules/lodash/_listCacheGet.js", "../../../node_modules/lodash/_listCacheHas.js", "../../../node_modules/lodash/_listCacheSet.js", "../../../node_modules/lodash/_ListCache.js", "../../../node_modules/lodash/_Map.js", "../../../node_modules/lodash/_mapCacheClear.js", "../../../node_modules/lodash/_isKeyable.js", "../../../node_modules/lodash/_getMapData.js", "../../../node_modules/lodash/_mapCacheDelete.js", "../../../node_modules/lodash/_mapCacheGet.js", "../../../node_modules/lodash/_mapCacheHas.js", "../../../node_modules/lodash/_mapCacheSet.js", "../../../node_modules/lodash/_MapCache.js", "../../../node_modules/lodash/memoize.js", "../../../node_modules/lodash/_memoizeCapped.js", "../../../node_modules/lodash/_stringToPath.js", "../../../node_modules/lodash/_arrayMap.js", "../../../node_modules/lodash/_baseToString.js", "../../../node_modules/lodash/toString.js", "../../../node_modules/lodash/_castPath.js", "../../../node_modules/lodash/_toKey.js", "../../../node_modules/lodash/_baseGet.js", "../../../node_modules/lodash/get.js", "../../../node_modules/lodash/_baseHas.js", "../../../node_modules/lodash/_baseIsArguments.js", "../../../node_modules/lodash/isArguments.js", "../../../node_modules/lodash/_isIndex.js", "../../../node_modules/lodash/isLength.js", "../../../node_modules/lodash/_hasPath.js", "../../../node_modules/lodash/has.js", "../../../node_modules/lodash/_stackClear.js", "../../../node_modules/lodash/_stackDelete.js", "../../../node_modules/lodash/_stackGet.js", "../../../node_modules/lodash/_stackHas.js", "../../../node_modules/lodash/_stackSet.js", "../../../node_modules/lodash/_Stack.js", "../../../node_modules/lodash/_defineProperty.js", "../../../node_modules/lodash/_baseAssignValue.js", "../../../node_modules/lodash/_assignMergeValue.js", "../../../node_modules/lodash/_createBaseFor.js", "../../../node_modules/lodash/_baseFor.js", "../../../node_modules/lodash/_cloneBuffer.js", "../../../node_modules/lodash/_Uint8Array.js", "../../../node_modules/lodash/_cloneArrayBuffer.js", "../../../node_modules/lodash/_cloneTypedArray.js", "../../../node_modules/lodash/_copyArray.js", "../../../node_modules/lodash/_baseCreate.js", "../../../node_modules/lodash/_overArg.js", "../../../node_modules/lodash/_getPrototype.js", "../../../node_modules/lodash/_isPrototype.js", "../../../node_modules/lodash/_initCloneObject.js", "../../../node_modules/lodash/isArrayLike.js", "../../../node_modules/lodash/isArrayLikeObject.js", "../../../node_modules/lodash/stubFalse.js", "../../../node_modules/lodash/isBuffer.js", "../../../node_modules/lodash/isPlainObject.js", "../../../node_modules/lodash/_baseIsTypedArray.js", "../../../node_modules/lodash/_baseUnary.js", "../../../node_modules/lodash/_nodeUtil.js", "../../../node_modules/lodash/isTypedArray.js", "../../../node_modules/lodash/_safeGet.js", "../../../node_modules/lodash/_assignValue.js", "../../../node_modules/lodash/_copyObject.js", "../../../node_modules/lodash/_baseTimes.js", "../../../node_modules/lodash/_arrayLikeKeys.js", "../../../node_modules/lodash/_nativeKeysIn.js", "../../../node_modules/lodash/_baseKeysIn.js", "../../../node_modules/lodash/keysIn.js", "../../../node_modules/lodash/toPlainObject.js", "../../../node_modules/lodash/_baseMergeDeep.js", "../../../node_modules/lodash/_baseMerge.js", "../../../node_modules/lodash/identity.js", "../../../node_modules/lodash/_apply.js", "../../../node_modules/lodash/_overRest.js", "../../../node_modules/lodash/constant.js", "../../../node_modules/lodash/_baseSetToString.js", "../../../node_modules/lodash/_shortOut.js", "../../../node_modules/lodash/_setToString.js", "../../../node_modules/lodash/_baseRest.js", "../../../node_modules/lodash/_isIterateeCall.js", "../../../node_modules/lodash/_createAssigner.js", "../../../node_modules/lodash/merge.js", "../../../node_modules/lodash/_setCacheAdd.js", "../../../node_modules/lodash/_setCacheHas.js", "../../../node_modules/lodash/_SetCache.js", "../../../node_modules/lodash/_baseFindIndex.js", "../../../node_modules/lodash/_baseIsNaN.js", "../../../node_modules/lodash/_strictIndexOf.js", "../../../node_modules/lodash/_baseIndexOf.js", "../../../node_modules/lodash/_arrayIncludes.js", "../../../node_modules/lodash/_arrayIncludesWith.js", "../../../node_modules/lodash/_cacheHas.js", "../../../node_modules/lodash/_Set.js", "../../../node_modules/lodash/noop.js", "../../../node_modules/lodash/_setToArray.js", "../../../node_modules/lodash/_createSet.js", "../../../node_modules/lodash/_baseUniq.js", "../../../node_modules/lodash/uniq.js", "../../../node_modules/lodash/_baseSlice.js", "../../../node_modules/lodash/_castSlice.js", "../../../node_modules/lodash/_hasUnicode.js", "../../../node_modules/lodash/_asciiToArray.js", "../../../node_modules/lodash/_unicodeToArray.js", "../../../node_modules/lodash/_stringToArray.js", "../../../node_modules/lodash/_createCaseFirst.js", "../../../node_modules/lodash/upperFirst.js", "../../../node_modules/lodash/capitalize.js", "../../../node_modules/lodash/_arrayReduce.js", "../../../node_modules/lodash/_basePropertyOf.js", "../../../node_modules/lodash/_deburrLetter.js", "../../../node_modules/lodash/deburr.js", "../../../node_modules/lodash/_asciiWords.js", "../../../node_modules/lodash/_hasUnicodeWord.js", "../../../node_modules/lodash/_unicodeWords.js", "../../../node_modules/lodash/words.js", "../../../node_modules/lodash/_createCompounder.js", "../../../node_modules/lodash/camelCase.js", "../../../node_modules/lodash/_baseRepeat.js", "../../../node_modules/lodash/_trimmedEndIndex.js", "../../../node_modules/lodash/_baseTrim.js", "../../../node_modules/lodash/toNumber.js", "../../../node_modules/lodash/toFinite.js", "../../../node_modules/lodash/toInteger.js", "../../../node_modules/lodash/repeat.js", "../../../node_modules/lodash/_arrayPush.js", "../../../node_modules/lodash/_isFlattenable.js", "../../../node_modules/lodash/_baseFlatten.js", "../../../node_modules/lodash/_arraySome.js", "../../../node_modules/lodash/_equalArrays.js", "../../../node_modules/lodash/_mapToArray.js", "../../../node_modules/lodash/_equalByTag.js", "../../../node_modules/lodash/_baseGetAllKeys.js", "../../../node_modules/lodash/_arrayFilter.js", "../../../node_modules/lodash/stubArray.js", "../../../node_modules/lodash/_getSymbols.js", "../../../node_modules/lodash/_nativeKeys.js", "../../../node_modules/lodash/_baseKeys.js", "../../../node_modules/lodash/keys.js", "../../../node_modules/lodash/_getAllKeys.js", "../../../node_modules/lodash/_equalObjects.js", "../../../node_modules/lodash/_DataView.js", "../../../node_modules/lodash/_Promise.js", "../../../node_modules/lodash/_WeakMap.js", "../../../node_modules/lodash/_getTag.js", "../../../node_modules/lodash/_baseIsEqualDeep.js", "../../../node_modules/lodash/_baseIsEqual.js", "../../../node_modules/lodash/_baseIsMatch.js", "../../../node_modules/lodash/_isStrictComparable.js", "../../../node_modules/lodash/_getMatchData.js", "../../../node_modules/lodash/_matchesStrictComparable.js", "../../../node_modules/lodash/_baseMatches.js", "../../../node_modules/lodash/_baseHasIn.js", "../../../node_modules/lodash/hasIn.js", "../../../node_modules/lodash/_baseMatchesProperty.js", "../../../node_modules/lodash/_baseProperty.js", "../../../node_modules/lodash/_basePropertyDeep.js", "../../../node_modules/lodash/property.js", "../../../node_modules/lodash/_baseIteratee.js", "../../../node_modules/lodash/_baseForOwn.js", "../../../node_modules/lodash/_createBaseEach.js", "../../../node_modules/lodash/_baseEach.js", "../../../node_modules/lodash/_baseMap.js", "../../../node_modules/lodash/_baseSortBy.js", "../../../node_modules/lodash/_compareAscending.js", "../../../node_modules/lodash/_compareMultiple.js", "../../../node_modules/lodash/_baseOrderBy.js", "../../../node_modules/lodash/sortBy.js", "../../../node_modules/lodash/_baseZipObject.js", "../../../node_modules/lodash/zipObject.js", "../../../node_modules/lodash/_baseRange.js", "../../../node_modules/lodash/_createRange.js", "../../../node_modules/lodash/range.js", "../../../node_modules/dayjs/dayjs.min.js", "../../../node_modules/khroma/dist/utils/channel.js", "../../../node_modules/khroma/dist/utils/lang.js", "../../../node_modules/khroma/dist/utils/unit.js", "../../../node_modules/khroma/dist/utils/index.js", "../../../node_modules/khroma/dist/constants.js", "../../../node_modules/khroma/dist/channels/type.js", "../../../node_modules/khroma/dist/channels/index.js", "../../../node_modules/khroma/dist/channels/reusable.js", "../../../node_modules/khroma/dist/color/hex.js", "../../../node_modules/khroma/dist/color/hsl.js", "../../../node_modules/khroma/dist/color/keyword.js", "../../../node_modules/khroma/dist/color/rgb.js", "../../../node_modules/khroma/dist/color/index.js", "../../../node_modules/khroma/dist/methods/change.js", "../../../node_modules/khroma/dist/methods/rgba.js", "../../../node_modules/khroma/dist/methods/channel.js", "../../../node_modules/khroma/dist/methods/luminance.js", "../../../node_modules/khroma/dist/methods/is_light.js", "../../../node_modules/khroma/dist/methods/is_dark.js", "../../../node_modules/khroma/dist/methods/adjust_channel.js", "../../../node_modules/khroma/dist/methods/lighten.js", "../../../node_modules/khroma/dist/methods/darken.js", "../../../node_modules/khroma/dist/methods/adjust.js", "../../../node_modules/khroma/dist/methods/mix.js", "../../../node_modules/khroma/dist/methods/invert.js", "../../../node_modules/khroma/dist/methods/index.js", "../../../node_modules/khroma/dist/index.js", "../../../node_modules/dompurify/src/utils.js", "../../../node_modules/dompurify/src/tags.js", "../../../node_modules/dompurify/src/attrs.js", "../../../node_modules/dompurify/src/regexp.js", "../../../node_modules/dompurify/src/purify.js", "../../../node_modules/katex/dist/katex.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-IIKMQLIC.mjs", "../../../node_modules/@iconify/utils/lib/icon/defaults.mjs", "../../../node_modules/@iconify/utils/lib/customisations/defaults.mjs", "../../../node_modules/@iconify/utils/lib/icon/name.mjs", "../../../node_modules/@iconify/utils/lib/icon/transformations.mjs", "../../../node_modules/@iconify/utils/lib/icon/merge.mjs", "../../../node_modules/@iconify/utils/lib/icon-set/tree.mjs", "../../../node_modules/@iconify/utils/lib/icon-set/get-icon.mjs", "../../../node_modules/@iconify/utils/lib/svg/size.mjs", "../../../node_modules/@iconify/utils/lib/svg/defs.mjs", "../../../node_modules/@iconify/utils/lib/svg/build.mjs", "../../../node_modules/@iconify/utils/lib/svg/id.mjs", "../../../node_modules/@iconify/utils/lib/svg/html.mjs", "../../../node_modules/@iconify/utils/node_modules/ms/index.js", "../../../node_modules/@iconify/utils/node_modules/debug/src/common.js", "../../../node_modules/@iconify/utils/node_modules/debug/src/browser.js", "../../../node_modules/@iconify/utils/lib/index.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-CUPH5FGA.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-23ATMZXV.mjs", "../../../node_modules/@braintree/sanitize-url/dist/constants.js", "../../../node_modules/@braintree/sanitize-url/dist/index.js", "../../../node_modules/d3-array/src/ascending.js", "../../../node_modules/d3-array/src/descending.js", "../../../node_modules/d3-array/src/bisector.js", "../../../node_modules/d3-array/src/number.js", "../../../node_modules/d3-array/src/bisect.js", "../../../node_modules/internmap/src/index.js", "../../../node_modules/d3-array/src/ticks.js", "../../../node_modules/d3-array/src/max.js", "../../../node_modules/d3-array/src/min.js", "../../../node_modules/d3-array/src/range.js", "../../../node_modules/d3-array/src/index.js", "../../../node_modules/d3-axis/src/identity.js", "../../../node_modules/d3-axis/src/axis.js", "../../../node_modules/d3-axis/src/index.js", "../../../node_modules/d3-dispatch/src/dispatch.js", "../../../node_modules/d3-dispatch/src/index.js", "../../../node_modules/d3-selection/src/namespaces.js", "../../../node_modules/d3-selection/src/namespace.js", "../../../node_modules/d3-selection/src/creator.js", "../../../node_modules/d3-selection/src/selector.js", "../../../node_modules/d3-selection/src/selection/select.js", "../../../node_modules/d3-selection/src/array.js", "../../../node_modules/d3-selection/src/selectorAll.js", "../../../node_modules/d3-selection/src/selection/selectAll.js", "../../../node_modules/d3-selection/src/matcher.js", "../../../node_modules/d3-selection/src/selection/selectChild.js", "../../../node_modules/d3-selection/src/selection/selectChildren.js", "../../../node_modules/d3-selection/src/selection/filter.js", "../../../node_modules/d3-selection/src/selection/sparse.js", "../../../node_modules/d3-selection/src/selection/enter.js", "../../../node_modules/d3-selection/src/constant.js", "../../../node_modules/d3-selection/src/selection/data.js", "../../../node_modules/d3-selection/src/selection/exit.js", "../../../node_modules/d3-selection/src/selection/join.js", "../../../node_modules/d3-selection/src/selection/merge.js", "../../../node_modules/d3-selection/src/selection/order.js", "../../../node_modules/d3-selection/src/selection/sort.js", "../../../node_modules/d3-selection/src/selection/call.js", "../../../node_modules/d3-selection/src/selection/nodes.js", "../../../node_modules/d3-selection/src/selection/node.js", "../../../node_modules/d3-selection/src/selection/size.js", "../../../node_modules/d3-selection/src/selection/empty.js", "../../../node_modules/d3-selection/src/selection/each.js", "../../../node_modules/d3-selection/src/selection/attr.js", "../../../node_modules/d3-selection/src/window.js", "../../../node_modules/d3-selection/src/selection/style.js", "../../../node_modules/d3-selection/src/selection/property.js", "../../../node_modules/d3-selection/src/selection/classed.js", "../../../node_modules/d3-selection/src/selection/text.js", "../../../node_modules/d3-selection/src/selection/html.js", "../../../node_modules/d3-selection/src/selection/raise.js", "../../../node_modules/d3-selection/src/selection/lower.js", "../../../node_modules/d3-selection/src/selection/append.js", "../../../node_modules/d3-selection/src/selection/insert.js", "../../../node_modules/d3-selection/src/selection/remove.js", "../../../node_modules/d3-selection/src/selection/clone.js", "../../../node_modules/d3-selection/src/selection/datum.js", "../../../node_modules/d3-selection/src/selection/on.js", "../../../node_modules/d3-selection/src/selection/dispatch.js", "../../../node_modules/d3-selection/src/selection/iterator.js", "../../../node_modules/d3-selection/src/selection/index.js", "../../../node_modules/d3-selection/src/select.js", "../../../node_modules/d3-selection/src/index.js", "../../../node_modules/d3-drag/src/index.js", "../../../node_modules/d3-color/src/define.js", "../../../node_modules/d3-color/src/color.js", "../../../node_modules/d3-color/src/math.js", "../../../node_modules/d3-color/src/lab.js", "../../../node_modules/d3-color/src/index.js", "../../../node_modules/d3-interpolate/src/basis.js", "../../../node_modules/d3-interpolate/src/basisClosed.js", "../../../node_modules/d3-interpolate/src/constant.js", "../../../node_modules/d3-interpolate/src/color.js", "../../../node_modules/d3-interpolate/src/rgb.js", "../../../node_modules/d3-interpolate/src/numberArray.js", "../../../node_modules/d3-interpolate/src/array.js", "../../../node_modules/d3-interpolate/src/date.js", "../../../node_modules/d3-interpolate/src/number.js", "../../../node_modules/d3-interpolate/src/object.js", "../../../node_modules/d3-interpolate/src/string.js", "../../../node_modules/d3-interpolate/src/value.js", "../../../node_modules/d3-interpolate/src/round.js", "../../../node_modules/d3-interpolate/src/transform/decompose.js", "../../../node_modules/d3-interpolate/src/transform/parse.js", "../../../node_modules/d3-interpolate/src/transform/index.js", "../../../node_modules/d3-interpolate/src/hcl.js", "../../../node_modules/d3-interpolate/src/index.js", "../../../node_modules/d3-timer/src/timer.js", "../../../node_modules/d3-timer/src/timeout.js", "../../../node_modules/d3-timer/src/index.js", "../../../node_modules/d3-transition/src/transition/schedule.js", "../../../node_modules/d3-transition/src/interrupt.js", "../../../node_modules/d3-transition/src/selection/interrupt.js", "../../../node_modules/d3-transition/src/transition/tween.js", "../../../node_modules/d3-transition/src/transition/interpolate.js", "../../../node_modules/d3-transition/src/transition/attr.js", "../../../node_modules/d3-transition/src/transition/attrTween.js", "../../../node_modules/d3-transition/src/transition/delay.js", "../../../node_modules/d3-transition/src/transition/duration.js", "../../../node_modules/d3-transition/src/transition/ease.js", "../../../node_modules/d3-transition/src/transition/easeVarying.js", "../../../node_modules/d3-transition/src/transition/filter.js", "../../../node_modules/d3-transition/src/transition/merge.js", "../../../node_modules/d3-transition/src/transition/on.js", "../../../node_modules/d3-transition/src/transition/remove.js", "../../../node_modules/d3-transition/src/transition/select.js", "../../../node_modules/d3-transition/src/transition/selectAll.js", "../../../node_modules/d3-transition/src/transition/selection.js", "../../../node_modules/d3-transition/src/transition/style.js", "../../../node_modules/d3-transition/src/transition/styleTween.js", "../../../node_modules/d3-transition/src/transition/text.js", "../../../node_modules/d3-transition/src/transition/textTween.js", "../../../node_modules/d3-transition/src/transition/transition.js", "../../../node_modules/d3-transition/src/transition/end.js", "../../../node_modules/d3-transition/src/transition/index.js", "../../../node_modules/d3-ease/src/cubic.js", "../../../node_modules/d3-ease/src/index.js", "../../../node_modules/d3-transition/src/selection/transition.js", "../../../node_modules/d3-transition/src/selection/index.js", "../../../node_modules/d3-transition/src/index.js", "../../../node_modules/d3-brush/src/constant.js", "../../../node_modules/d3-brush/src/event.js", "../../../node_modules/d3-brush/src/noevent.js", "../../../node_modules/d3-brush/src/brush.js", "../../../node_modules/d3-brush/src/index.js", "../../../node_modules/d3-path/src/path.js", "../../../node_modules/d3-path/src/index.js", "../../../node_modules/d3-chord/src/index.js", "../../../node_modules/d3-contour/src/index.js", "../../../node_modules/d3-delaunay/src/index.js", "../../../node_modules/d3-dsv/src/index.js", "../../../node_modules/d3-fetch/src/index.js", "../../../node_modules/d3-quadtree/src/index.js", "../../../node_modules/d3-force/src/index.js", "../../../node_modules/d3-format/src/formatDecimal.js", "../../../node_modules/d3-format/src/exponent.js", "../../../node_modules/d3-format/src/formatGroup.js", "../../../node_modules/d3-format/src/formatNumerals.js", "../../../node_modules/d3-format/src/formatSpecifier.js", "../../../node_modules/d3-format/src/formatTrim.js", "../../../node_modules/d3-format/src/formatPrefixAuto.js", "../../../node_modules/d3-format/src/formatRounded.js", "../../../node_modules/d3-format/src/formatTypes.js", "../../../node_modules/d3-format/src/identity.js", "../../../node_modules/d3-format/src/locale.js", "../../../node_modules/d3-format/src/defaultLocale.js", "../../../node_modules/d3-format/src/precisionFixed.js", "../../../node_modules/d3-format/src/precisionPrefix.js", "../../../node_modules/d3-format/src/precisionRound.js", "../../../node_modules/d3-format/src/index.js", "../../../node_modules/d3-geo/src/index.js", "../../../node_modules/d3-hierarchy/src/index.js", "../../../node_modules/d3-polygon/src/index.js", "../../../node_modules/d3-random/src/index.js", "../../../node_modules/d3-scale/src/init.js", "../../../node_modules/d3-scale/src/ordinal.js", "../../../node_modules/d3-scale/src/band.js", "../../../node_modules/d3-scale/src/constant.js", "../../../node_modules/d3-scale/src/number.js", "../../../node_modules/d3-scale/src/continuous.js", "../../../node_modules/d3-scale/src/tickFormat.js", "../../../node_modules/d3-scale/src/linear.js", "../../../node_modules/d3-scale/src/nice.js", "../../../node_modules/d3-time/src/interval.js", "../../../node_modules/d3-time/src/millisecond.js", "../../../node_modules/d3-time/src/duration.js", "../../../node_modules/d3-time/src/second.js", "../../../node_modules/d3-time/src/minute.js", "../../../node_modules/d3-time/src/hour.js", "../../../node_modules/d3-time/src/day.js", "../../../node_modules/d3-time/src/week.js", "../../../node_modules/d3-time/src/month.js", "../../../node_modules/d3-time/src/year.js", "../../../node_modules/d3-time/src/ticks.js", "../../../node_modules/d3-time/src/index.js", "../../../node_modules/d3-time-format/src/locale.js", "../../../node_modules/d3-time-format/src/defaultLocale.js", "../../../node_modules/d3-time-format/src/index.js", "../../../node_modules/d3-scale/src/time.js", "../../../node_modules/d3-scale/src/index.js", "../../../node_modules/d3-scale-chromatic/src/colors.js", "../../../node_modules/d3-scale-chromatic/src/categorical/Tableau10.js", "../../../node_modules/d3-scale-chromatic/src/index.js", "../../../node_modules/d3-shape/src/constant.js", "../../../node_modules/d3-shape/src/math.js", "../../../node_modules/d3-shape/src/path.js", "../../../node_modules/d3-shape/src/arc.js", "../../../node_modules/d3-shape/src/array.js", "../../../node_modules/d3-shape/src/curve/linear.js", "../../../node_modules/d3-shape/src/point.js", "../../../node_modules/d3-shape/src/line.js", "../../../node_modules/d3-shape/src/descending.js", "../../../node_modules/d3-shape/src/identity.js", "../../../node_modules/d3-shape/src/pie.js", "../../../node_modules/d3-shape/src/curve/bump.js", "../../../node_modules/d3-shape/src/noop.js", "../../../node_modules/d3-shape/src/curve/basis.js", "../../../node_modules/d3-shape/src/curve/basisClosed.js", "../../../node_modules/d3-shape/src/curve/basisOpen.js", "../../../node_modules/d3-shape/src/curve/bundle.js", "../../../node_modules/d3-shape/src/curve/cardinal.js", "../../../node_modules/d3-shape/src/curve/cardinalClosed.js", "../../../node_modules/d3-shape/src/curve/cardinalOpen.js", "../../../node_modules/d3-shape/src/curve/catmullRom.js", "../../../node_modules/d3-shape/src/curve/catmullRomClosed.js", "../../../node_modules/d3-shape/src/curve/catmullRomOpen.js", "../../../node_modules/d3-shape/src/curve/linearClosed.js", "../../../node_modules/d3-shape/src/curve/monotone.js", "../../../node_modules/d3-shape/src/curve/natural.js", "../../../node_modules/d3-shape/src/curve/step.js", "../../../node_modules/d3-shape/src/index.js", "../../../node_modules/d3-zoom/src/constant.js", "../../../node_modules/d3-zoom/src/event.js", "../../../node_modules/d3-zoom/src/transform.js", "../../../node_modules/d3-zoom/src/noevent.js", "../../../node_modules/d3-zoom/src/zoom.js", "../../../node_modules/d3-zoom/src/index.js", "../../../node_modules/d3/src/index.js", "../../../node_modules/lodash-es/_freeGlobal.js", "../../../node_modules/lodash-es/_root.js", "../../../node_modules/lodash-es/_Symbol.js", "../../../node_modules/lodash-es/_getRawTag.js", "../../../node_modules/lodash-es/_objectToString.js", "../../../node_modules/lodash-es/_baseGetTag.js", "../../../node_modules/lodash-es/isObject.js", "../../../node_modules/lodash-es/isFunction.js", "../../../node_modules/lodash-es/_coreJsData.js", "../../../node_modules/lodash-es/_isMasked.js", "../../../node_modules/lodash-es/_toSource.js", "../../../node_modules/lodash-es/_baseIsNative.js", "../../../node_modules/lodash-es/_getValue.js", "../../../node_modules/lodash-es/_getNative.js", "../../../node_modules/lodash-es/_nativeCreate.js", "../../../node_modules/lodash-es/_hashClear.js", "../../../node_modules/lodash-es/_hashDelete.js", "../../../node_modules/lodash-es/_hashGet.js", "../../../node_modules/lodash-es/_hashHas.js", "../../../node_modules/lodash-es/_hashSet.js", "../../../node_modules/lodash-es/_Hash.js", "../../../node_modules/lodash-es/_listCacheClear.js", "../../../node_modules/lodash-es/eq.js", "../../../node_modules/lodash-es/_assocIndexOf.js", "../../../node_modules/lodash-es/_listCacheDelete.js", "../../../node_modules/lodash-es/_listCacheGet.js", "../../../node_modules/lodash-es/_listCacheHas.js", "../../../node_modules/lodash-es/_listCacheSet.js", "../../../node_modules/lodash-es/_ListCache.js", "../../../node_modules/lodash-es/_Map.js", "../../../node_modules/lodash-es/_mapCacheClear.js", "../../../node_modules/lodash-es/_isKeyable.js", "../../../node_modules/lodash-es/_getMapData.js", "../../../node_modules/lodash-es/_mapCacheDelete.js", "../../../node_modules/lodash-es/_mapCacheGet.js", "../../../node_modules/lodash-es/_mapCacheHas.js", "../../../node_modules/lodash-es/_mapCacheSet.js", "../../../node_modules/lodash-es/_MapCache.js", "../../../node_modules/lodash-es/memoize.js", "../../../node_modules/lodash-es/_stackClear.js", "../../../node_modules/lodash-es/_stackDelete.js", "../../../node_modules/lodash-es/_stackGet.js", "../../../node_modules/lodash-es/_stackHas.js", "../../../node_modules/lodash-es/_stackSet.js", "../../../node_modules/lodash-es/_Stack.js", "../../../node_modules/lodash-es/_defineProperty.js", "../../../node_modules/lodash-es/_baseAssignValue.js", "../../../node_modules/lodash-es/_assignMergeValue.js", "../../../node_modules/lodash-es/_createBaseFor.js", "../../../node_modules/lodash-es/_baseFor.js", "../../../node_modules/lodash-es/_cloneBuffer.js", "../../../node_modules/lodash-es/_Uint8Array.js", "../../../node_modules/lodash-es/_cloneArrayBuffer.js", "../../../node_modules/lodash-es/_cloneTypedArray.js", "../../../node_modules/lodash-es/_copyArray.js", "../../../node_modules/lodash-es/_baseCreate.js", "../../../node_modules/lodash-es/_overArg.js", "../../../node_modules/lodash-es/_getPrototype.js", "../../../node_modules/lodash-es/_isPrototype.js", "../../../node_modules/lodash-es/_initCloneObject.js", "../../../node_modules/lodash-es/isObjectLike.js", "../../../node_modules/lodash-es/_baseIsArguments.js", "../../../node_modules/lodash-es/isArguments.js", "../../../node_modules/lodash-es/isArray.js", "../../../node_modules/lodash-es/isLength.js", "../../../node_modules/lodash-es/isArrayLike.js", "../../../node_modules/lodash-es/isArrayLikeObject.js", "../../../node_modules/lodash-es/stubFalse.js", "../../../node_modules/lodash-es/isBuffer.js", "../../../node_modules/lodash-es/isPlainObject.js", "../../../node_modules/lodash-es/_baseIsTypedArray.js", "../../../node_modules/lodash-es/_baseUnary.js", "../../../node_modules/lodash-es/_nodeUtil.js", "../../../node_modules/lodash-es/isTypedArray.js", "../../../node_modules/lodash-es/_safeGet.js", "../../../node_modules/lodash-es/_assignValue.js", "../../../node_modules/lodash-es/_copyObject.js", "../../../node_modules/lodash-es/_baseTimes.js", "../../../node_modules/lodash-es/_isIndex.js", "../../../node_modules/lodash-es/_arrayLikeKeys.js", "../../../node_modules/lodash-es/_nativeKeysIn.js", "../../../node_modules/lodash-es/_baseKeysIn.js", "../../../node_modules/lodash-es/keysIn.js", "../../../node_modules/lodash-es/toPlainObject.js", "../../../node_modules/lodash-es/_baseMergeDeep.js", "../../../node_modules/lodash-es/_baseMerge.js", "../../../node_modules/lodash-es/identity.js", "../../../node_modules/lodash-es/_apply.js", "../../../node_modules/lodash-es/_overRest.js", "../../../node_modules/lodash-es/constant.js", "../../../node_modules/lodash-es/_baseSetToString.js", "../../../node_modules/lodash-es/_shortOut.js", "../../../node_modules/lodash-es/_setToString.js", "../../../node_modules/lodash-es/_baseRest.js", "../../../node_modules/lodash-es/_isIterateeCall.js", "../../../node_modules/lodash-es/_createAssigner.js", "../../../node_modules/lodash-es/merge.js", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-2EDTWDYI.mjs", "../../../node_modules/marked/src/defaults.ts", "../../../node_modules/marked/src/helpers.ts", "../../../node_modules/marked/src/Tokenizer.ts", "../../../node_modules/marked/src/rules.ts", "../../../node_modules/marked/src/Lexer.ts", "../../../node_modules/marked/src/Renderer.ts", "../../../node_modules/marked/src/TextRenderer.ts", "../../../node_modules/marked/src/Parser.ts", "../../../node_modules/marked/src/Hooks.ts", "../../../node_modules/marked/src/Instance.ts", "../../../node_modules/marked/src/marked.ts", "../../../node_modules/ts-dedent/src/index.ts", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-5N55DQE6.mjs", "../../../node_modules/roughjs/bundled/rough.esm.js", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-VR7AIV22.mjs", "../../../node_modules/lodash-es/isSymbol.js", "../../../node_modules/lodash-es/_arrayMap.js", "../../../node_modules/lodash-es/_baseToString.js", "../../../node_modules/lodash-es/_trimmedEndIndex.js", "../../../node_modules/lodash-es/_baseTrim.js", "../../../node_modules/lodash-es/toNumber.js", "../../../node_modules/lodash-es/toFinite.js", "../../../node_modules/lodash-es/toInteger.js", "../../../node_modules/lodash-es/_WeakMap.js", "../../../node_modules/lodash-es/noop.js", "../../../node_modules/lodash-es/_arrayEach.js", "../../../node_modules/lodash-es/_baseFindIndex.js", "../../../node_modules/lodash-es/_baseIsNaN.js", "../../../node_modules/lodash-es/_strictIndexOf.js", "../../../node_modules/lodash-es/_baseIndexOf.js", "../../../node_modules/lodash-es/_arrayIncludes.js", "../../../node_modules/lodash-es/_nativeKeys.js", "../../../node_modules/lodash-es/_baseKeys.js", "../../../node_modules/lodash-es/keys.js", "../../../node_modules/lodash-es/assign.js", "../../../node_modules/lodash-es/_isKey.js", "../../../node_modules/lodash-es/_memoizeCapped.js", "../../../node_modules/lodash-es/_stringToPath.js", "../../../node_modules/lodash-es/toString.js", "../../../node_modules/lodash-es/_castPath.js", "../../../node_modules/lodash-es/_toKey.js", "../../../node_modules/lodash-es/_baseGet.js", "../../../node_modules/lodash-es/get.js", "../../../node_modules/lodash-es/_arrayPush.js", "../../../node_modules/lodash-es/_isFlattenable.js", "../../../node_modules/lodash-es/_baseFlatten.js", "../../../node_modules/lodash-es/flatten.js", "../../../node_modules/lodash-es/_flatRest.js", "../../../node_modules/lodash-es/_baseSlice.js", "../../../node_modules/lodash-es/_hasUnicode.js", "../../../node_modules/lodash-es/_arrayReduce.js", "../../../node_modules/lodash-es/_baseAssign.js", "../../../node_modules/lodash-es/_baseAssignIn.js", "../../../node_modules/lodash-es/_arrayFilter.js", "../../../node_modules/lodash-es/stubArray.js", "../../../node_modules/lodash-es/_getSymbols.js", "../../../node_modules/lodash-es/_copySymbols.js", "../../../node_modules/lodash-es/_getSymbolsIn.js", "../../../node_modules/lodash-es/_copySymbolsIn.js", "../../../node_modules/lodash-es/_baseGetAllKeys.js", "../../../node_modules/lodash-es/_getAllKeys.js", "../../../node_modules/lodash-es/_getAllKeysIn.js", "../../../node_modules/lodash-es/_DataView.js", "../../../node_modules/lodash-es/_Promise.js", "../../../node_modules/lodash-es/_Set.js", "../../../node_modules/lodash-es/_getTag.js", "../../../node_modules/lodash-es/_initCloneArray.js", "../../../node_modules/lodash-es/_cloneDataView.js", "../../../node_modules/lodash-es/_cloneRegExp.js", "../../../node_modules/lodash-es/_cloneSymbol.js", "../../../node_modules/lodash-es/_initCloneByTag.js", "../../../node_modules/lodash-es/_baseIsMap.js", "../../../node_modules/lodash-es/isMap.js", "../../../node_modules/lodash-es/_baseIsSet.js", "../../../node_modules/lodash-es/isSet.js", "../../../node_modules/lodash-es/_baseClone.js", "../../../node_modules/lodash-es/clone.js", "../../../node_modules/lodash-es/cloneDeep.js", "../../../node_modules/lodash-es/compact.js", "../../../node_modules/lodash-es/_setCacheAdd.js", "../../../node_modules/lodash-es/_setCacheHas.js", "../../../node_modules/lodash-es/_SetCache.js", "../../../node_modules/lodash-es/_arraySome.js", "../../../node_modules/lodash-es/_cacheHas.js", "../../../node_modules/lodash-es/_equalArrays.js", "../../../node_modules/lodash-es/_mapToArray.js", "../../../node_modules/lodash-es/_setToArray.js", "../../../node_modules/lodash-es/_equalByTag.js", "../../../node_modules/lodash-es/_equalObjects.js", "../../../node_modules/lodash-es/_baseIsEqualDeep.js", "../../../node_modules/lodash-es/_baseIsEqual.js", "../../../node_modules/lodash-es/_baseIsMatch.js", "../../../node_modules/lodash-es/_isStrictComparable.js", "../../../node_modules/lodash-es/_getMatchData.js", "../../../node_modules/lodash-es/_matchesStrictComparable.js", "../../../node_modules/lodash-es/_baseMatches.js", "../../../node_modules/lodash-es/_baseHasIn.js", "../../../node_modules/lodash-es/_hasPath.js", "../../../node_modules/lodash-es/hasIn.js", "../../../node_modules/lodash-es/_baseMatchesProperty.js", "../../../node_modules/lodash-es/_baseProperty.js", "../../../node_modules/lodash-es/_basePropertyDeep.js", "../../../node_modules/lodash-es/property.js", "../../../node_modules/lodash-es/_baseIteratee.js", "../../../node_modules/lodash-es/_arrayAggregator.js", "../../../node_modules/lodash-es/_baseForOwn.js", "../../../node_modules/lodash-es/_createBaseEach.js", "../../../node_modules/lodash-es/_baseEach.js", "../../../node_modules/lodash-es/_baseAggregator.js", "../../../node_modules/lodash-es/_createAggregator.js", "../../../node_modules/lodash-es/now.js", "../../../node_modules/lodash-es/defaults.js", "../../../node_modules/lodash-es/_arrayIncludesWith.js", "../../../node_modules/lodash-es/_baseDifference.js", "../../../node_modules/lodash-es/difference.js", "../../../node_modules/lodash-es/last.js", "../../../node_modules/lodash-es/drop.js", "../../../node_modules/lodash-es/dropRight.js", "../../../node_modules/lodash-es/_castFunction.js", "../../../node_modules/lodash-es/forEach.js", "../../../node_modules/lodash-es/each.js", "../../../node_modules/lodash-es/_arrayEvery.js", "../../../node_modules/lodash-es/_baseEvery.js", "../../../node_modules/lodash-es/every.js", "../../../node_modules/lodash-es/_baseFilter.js", "../../../node_modules/lodash-es/filter.js", "../../../node_modules/lodash-es/_createFind.js", "../../../node_modules/lodash-es/findIndex.js", "../../../node_modules/lodash-es/find.js", "../../../node_modules/lodash-es/head.js", "../../../node_modules/lodash-es/first.js", "../../../node_modules/lodash-es/_baseMap.js", "../../../node_modules/lodash-es/map.js", "../../../node_modules/lodash-es/flatMap.js", "../../../node_modules/lodash-es/forIn.js", "../../../node_modules/lodash-es/forOwn.js", "../../../node_modules/lodash-es/groupBy.js", "../../../node_modules/lodash-es/_baseGt.js", "../../../node_modules/lodash-es/_baseHas.js", "../../../node_modules/lodash-es/has.js", "../../../node_modules/lodash-es/isString.js", "../../../node_modules/lodash-es/_baseValues.js", "../../../node_modules/lodash-es/values.js", "../../../node_modules/lodash-es/includes.js", "../../../node_modules/lodash-es/indexOf.js", "../../../node_modules/lodash-es/isEmpty.js", "../../../node_modules/lodash-es/_baseIsRegExp.js", "../../../node_modules/lodash-es/isRegExp.js", "../../../node_modules/lodash-es/isUndefined.js", "../../../node_modules/lodash-es/_baseLt.js", "../../../node_modules/lodash-es/mapValues.js", "../../../node_modules/lodash-es/_baseExtremum.js", "../../../node_modules/lodash-es/max.js", "../../../node_modules/lodash-es/min.js", "../../../node_modules/lodash-es/minBy.js", "../../../node_modules/lodash-es/negate.js", "../../../node_modules/lodash-es/_baseSet.js", "../../../node_modules/lodash-es/_basePickBy.js", "../../../node_modules/lodash-es/pickBy.js", "../../../node_modules/lodash-es/_baseSortBy.js", "../../../node_modules/lodash-es/_compareAscending.js", "../../../node_modules/lodash-es/_compareMultiple.js", "../../../node_modules/lodash-es/_baseOrderBy.js", "../../../node_modules/lodash-es/_asciiSize.js", "../../../node_modules/lodash-es/_unicodeSize.js", "../../../node_modules/lodash-es/_stringSize.js", "../../../node_modules/lodash-es/_basePick.js", "../../../node_modules/lodash-es/pick.js", "../../../node_modules/lodash-es/_baseRange.js", "../../../node_modules/lodash-es/_createRange.js", "../../../node_modules/lodash-es/range.js", "../../../node_modules/lodash-es/_baseReduce.js", "../../../node_modules/lodash-es/reduce.js", "../../../node_modules/lodash-es/reject.js", "../../../node_modules/lodash-es/size.js", "../../../node_modules/lodash-es/_baseSome.js", "../../../node_modules/lodash-es/some.js", "../../../node_modules/lodash-es/sortBy.js", "../../../node_modules/lodash-es/_createSet.js", "../../../node_modules/lodash-es/_baseUniq.js", "../../../node_modules/lodash-es/union.js", "../../../node_modules/lodash-es/uniq.js", "../../../node_modules/lodash-es/uniqBy.js", "../../../node_modules/lodash-es/uniqueId.js", "../../../node_modules/lodash-es/_baseZipObject.js", "../../../node_modules/lodash-es/zipObject.js", "../../../node_modules/lodash-es/lodash.js", "../../../node_modules/dagre-d3-es/src/graphlib/graph.js", "../../../node_modules/dagre-d3-es/src/graphlib/index.js", "../../../node_modules/dagre-d3-es/src/dagre/data/list.js", "../../../node_modules/dagre-d3-es/src/dagre/greedy-fas.js", "../../../node_modules/dagre-d3-es/src/dagre/acyclic.js", "../../../node_modules/dagre-d3-es/src/dagre/util.js", "../../../node_modules/dagre-d3-es/src/dagre/add-border-segments.js", "../../../node_modules/dagre-d3-es/src/dagre/coordinate-system.js", "../../../node_modules/dagre-d3-es/src/dagre/normalize.js", "../../../node_modules/dagre-d3-es/src/dagre/rank/util.js", "../../../node_modules/dagre-d3-es/src/dagre/rank/feasible-tree.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/components.js", "../../../node_modules/dagre-d3-es/src/graphlib/data/priority-queue.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/dijkstra.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/dijkstra-all.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/tarjan.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/find-cycles.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/floyd-warshall.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/topsort.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/is-acyclic.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/dfs.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/postorder.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/preorder.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/prim.js", "../../../node_modules/dagre-d3-es/src/graphlib/alg/index.js", "../../../node_modules/dagre-d3-es/src/dagre/rank/network-simplex.js", "../../../node_modules/dagre-d3-es/src/dagre/rank/index.js", "../../../node_modules/dagre-d3-es/src/dagre/nesting-graph.js", "../../../node_modules/dagre-d3-es/src/dagre/order/add-subgraph-constraints.js", "../../../node_modules/dagre-d3-es/src/dagre/order/build-layer-graph.js", "../../../node_modules/dagre-d3-es/src/dagre/order/cross-count.js", "../../../node_modules/dagre-d3-es/src/dagre/order/init-order.js", "../../../node_modules/dagre-d3-es/src/dagre/order/barycenter.js", "../../../node_modules/dagre-d3-es/src/dagre/order/resolve-conflicts.js", "../../../node_modules/dagre-d3-es/src/dagre/order/sort.js", "../../../node_modules/dagre-d3-es/src/dagre/order/sort-subgraph.js", "../../../node_modules/dagre-d3-es/src/dagre/order/index.js", "../../../node_modules/dagre-d3-es/src/dagre/parent-dummy-chains.js", "../../../node_modules/dagre-d3-es/src/dagre/position/bk.js", "../../../node_modules/dagre-d3-es/src/dagre/position/index.js", "../../../node_modules/dagre-d3-es/src/dagre/layout.js", "../../../node_modules/dagre-d3-es/src/dagre/index.js", "../../../node_modules/dagre-d3-es/src/graphlib/json.js", "../../../node_modules/mermaid/dist/chunks/mermaid.core/dagre-P3YPLUS5.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-WSMKYKZ5.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-QZ6ES4KD.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-F2XFN3BY.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-XVOYOM2C.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/c4Diagram-THADGKDP.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-DUMQOTYW.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-YWFND7JV.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/flowDiagram-JSIZSE4D.mjs", "../../../node_modules/uuid/dist/esm-browser/regex.js", "../../../node_modules/uuid/dist/esm-browser/validate.js", "../../../node_modules/uuid/dist/esm-browser/stringify.js", "../../../node_modules/uuid/dist/esm-browser/parse.js", "../../../node_modules/uuid/dist/esm-browser/v35.js", "../../../node_modules/uuid/dist/esm-browser/sha1.js", "../../../node_modules/uuid/dist/esm-browser/v5.js", "../../../node_modules/uuid/dist/esm-browser/index.js", "../../../node_modules/mermaid/dist/chunks/mermaid.core/erDiagram-62CBQV5Y.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-OQCM5LHU.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-2RYQ3QTB.mjs", "../../../node_modules/langium/src/syntax-tree.ts", "../../../node_modules/langium/src/utils/stream.ts", "../../../node_modules/langium/src/utils/cst-utils.ts", "../../../node_modules/langium/src/utils/errors.ts", "../../../node_modules/langium/src/languages/generated/ast.ts", "../../../node_modules/langium/src/utils/ast-utils.ts", "../../../node_modules/@chevrotain/regexp-to-ast/src/utils.ts", "../../../node_modules/@chevrotain/regexp-to-ast/src/character-classes.ts", "../../../node_modules/@chevrotain/regexp-to-ast/src/regexp-parser.ts", "../../../node_modules/@chevrotain/regexp-to-ast/src/base-regexp-visitor.ts", "../../../node_modules/@chevrotain/regexp-to-ast/src/api.ts", "../../../node_modules/langium/src/utils/regexp-utils.ts", "../../../node_modules/langium/src/utils/grammar-utils.ts", "../../../node_modules/langium/src/languages/grammar-config.ts", "../../../node_modules/chevrotain/src/version.ts", "../../../node_modules/@chevrotain/utils/src/print.ts", "../../../node_modules/@chevrotain/utils/src/timer.ts", "../../../node_modules/@chevrotain/utils/src/to-fast-properties.ts", "../../../node_modules/@chevrotain/utils/src/api.ts", "../../../node_modules/@chevrotain/gast/src/model.ts", "../../../node_modules/@chevrotain/gast/src/visitor.ts", "../../../node_modules/@chevrotain/gast/src/helpers.ts", "../../../node_modules/@chevrotain/gast/src/api.ts", "../../../node_modules/chevrotain/src/parse/grammar/rest.ts", "../../../node_modules/chevrotain/src/parse/grammar/first.ts", "../../../node_modules/chevrotain/src/parse/constants.ts", "../../../node_modules/chevrotain/src/parse/grammar/follow.ts", "../../../node_modules/chevrotain/src/scan/reg_exp_parser.ts", "../../../node_modules/chevrotain/src/scan/reg_exp.ts", "../../../node_modules/chevrotain/src/scan/lexer.ts", "../../../node_modules/chevrotain/src/scan/tokens.ts", "../../../node_modules/chevrotain/src/scan/lexer_errors_public.ts", "../../../node_modules/chevrotain/src/scan/lexer_public.ts", "../../../node_modules/chevrotain/src/scan/tokens_public.ts", "../../../node_modules/chevrotain/src/parse/errors_public.ts", "../../../node_modules/chevrotain/src/parse/grammar/resolver.ts", "../../../node_modules/chevrotain/src/parse/grammar/interpreter.ts", "../../../node_modules/chevrotain/src/parse/grammar/lookahead.ts", "../../../node_modules/chevrotain/src/parse/grammar/checks.ts", "../../../node_modules/chevrotain/src/parse/grammar/gast/gast_resolver_public.ts", "../../../node_modules/chevrotain/src/parse/exceptions_public.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/recoverable.ts", "../../../node_modules/chevrotain/src/parse/grammar/keys.ts", "../../../node_modules/chevrotain/src/parse/grammar/llk_lookahead.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/looksahead.ts", "../../../node_modules/chevrotain/src/parse/cst/cst.ts", "../../../node_modules/chevrotain/src/lang/lang_extensions.ts", "../../../node_modules/chevrotain/src/parse/cst/cst_visitor.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/tree_builder.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/lexer_adapter.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/recognizer_api.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/recognizer_engine.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/error_handler.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/context_assist.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/gast_recorder.ts", "../../../node_modules/chevrotain/src/parse/parser/traits/perf_tracer.ts", "../../../node_modules/chevrotain/src/parse/parser/utils/apply_mixins.ts", "../../../node_modules/chevrotain/src/parse/parser/parser.ts", "../../../node_modules/@chevrotain/cst-dts-gen/src/model.ts", "../../../node_modules/@chevrotain/cst-dts-gen/src/generate.ts", "../../../node_modules/@chevrotain/cst-dts-gen/src/api.ts", "../../../node_modules/chevrotain/src/diagrams/render_public.ts", "../../../node_modules/chevrotain/src/api.ts", "../../../node_modules/chevrotain-allstar/src/atn.ts", "../../../node_modules/chevrotain-allstar/src/dfa.ts", "../../../node_modules/chevrotain-allstar/src/all-star-lookahead.ts", "../../../node_modules/chevrotain-allstar/src/index.ts", "../../../node_modules/vscode-languageserver-types/lib/esm/main.js", "../../../node_modules/langium/src/parser/cst-node-builder.ts", "../../../node_modules/langium/src/parser/langium-parser.ts", "../../../node_modules/langium/src/parser/parser-builder-base.ts", "../../../node_modules/langium/src/parser/completion-parser-builder.ts", "../../../node_modules/langium/src/parser/langium-parser-builder.ts", "../../../node_modules/langium/src/parser/token-builder.ts", "../../../node_modules/langium/src/parser/value-converter.ts", "../../../node_modules/vscode-jsonrpc/lib/common/ral.js", "../../../node_modules/vscode-jsonrpc/lib/common/is.js", "../../../node_modules/vscode-jsonrpc/lib/common/events.js", "../../../node_modules/vscode-jsonrpc/lib/common/cancellation.js", "../../../node_modules/langium/src/utils/cancellation.ts", "../../../node_modules/langium/src/utils/promise-utils.ts", "../../../node_modules/vscode-languageserver-textdocument/lib/esm/main.js", "../../../node_modules/vscode-uri/lib/esm/webpack:/LIB/node_modules/path-browserify/index.js", "../../../node_modules/vscode-uri/lib/esm/webpack:/LIB/webpack/bootstrap", "../../../node_modules/vscode-uri/lib/esm/webpack:/LIB/webpack/runtime/define property getters", "../../../node_modules/vscode-uri/lib/esm/webpack:/LIB/webpack/runtime/hasOwnProperty shorthand", "../../../node_modules/vscode-uri/lib/esm/webpack:/LIB/webpack/runtime/make namespace object", "../../../node_modules/vscode-uri/lib/esm/webpack:/LIB/src/platform.ts", "../../../node_modules/vscode-uri/lib/esm/webpack:/LIB/src/uri.ts", "../../../node_modules/vscode-uri/lib/esm/webpack:/LIB/src/utils.ts", "../../../node_modules/langium/src/utils/uri-utils.ts", "../../../node_modules/langium/src/workspace/documents.ts", "../../../node_modules/langium/src/references/linker.ts", "../../../node_modules/langium/src/references/name-provider.ts", "../../../node_modules/langium/src/references/references.ts", "../../../node_modules/langium/src/utils/collections.ts", "../../../node_modules/langium/src/references/scope-computation.ts", "../../../node_modules/langium/src/references/scope.ts", "../../../node_modules/langium/src/utils/caching.ts", "../../../node_modules/langium/src/references/scope-provider.ts", "../../../node_modules/langium/src/serializer/json-serializer.ts", "../../../node_modules/langium/src/service-registry.ts", "../../../node_modules/langium/src/validation/validation-registry.ts", "../../../node_modules/langium/src/validation/document-validator.ts", "../../../node_modules/langium/src/workspace/ast-descriptions.ts", "../../../node_modules/langium/src/workspace/ast-node-locator.ts", "../../../node_modules/langium/src/workspace/configuration.ts", "../../../node_modules/langium/src/utils/disposable.ts", "../../../node_modules/langium/src/workspace/document-builder.ts", "../../../node_modules/langium/src/workspace/index-manager.ts", "../../../node_modules/langium/src/workspace/workspace-manager.ts", "../../../node_modules/langium/src/parser/lexer.ts", "../../../node_modules/langium/src/documentation/jsdoc.ts", "../../../node_modules/langium/src/documentation/documentation-provider.ts", "../../../node_modules/langium/src/documentation/comment-provider.ts", "../../../node_modules/langium/src/utils/event.ts", "../../../node_modules/langium/src/parser/async-parser.ts", "../../../node_modules/langium/src/workspace/workspace-lock.ts", "../../../node_modules/langium/src/serializer/hydrator.ts", "../../../node_modules/langium/src/default-module.ts", "../../../node_modules/langium/src/dependency-injection.ts", "../../../node_modules/langium/src/services.ts", "../../../node_modules/langium/src/documentation/index.ts", "../../../node_modules/langium/src/languages/language-meta-data.ts", "../../../node_modules/langium/src/languages/index.ts", "../../../node_modules/langium/src/parser/parser-config.ts", "../../../node_modules/langium/src/parser/index.ts", "../../../node_modules/langium/src/references/index.ts", "../../../node_modules/langium/src/serializer/index.ts", "../../../node_modules/langium/src/workspace/file-system-provider.ts", "../../../node_modules/langium/src/utils/grammar-loader.ts", "../../../node_modules/langium/src/utils/index.ts", "../../../node_modules/langium/src/validation/index.ts", "../../../node_modules/langium/src/workspace/index.ts", "../../../node_modules/langium/src/index.ts", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/chunk-Y27MQZ3U.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/chunk-NCMFTTUW.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/chunk-4YFB5VUC.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/chunk-EQFLFMNE.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/chunk-BI6EQKOQ.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/chunk-FF7BQXOH.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/info-46DW6VJ7.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/packet-W2GHVCYJ.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/pie-BEWT4RHE.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/architecture-I3QFYML2.mjs", "../../../node_modules/@mermaid-js/parser/dist/chunks/mermaid-parser.core/gitGraph-YCYPL57B.mjs", "../../../node_modules/@mermaid-js/parser/dist/mermaid-parser.core.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/gitGraphDiagram-UL5UFKDR.mjs", "../../../node_modules/dayjs/plugin/isoWeek.js", "../../../node_modules/dayjs/plugin/customParseFormat.js", "../../../node_modules/dayjs/plugin/advancedFormat.js", "../../../node_modules/mermaid/dist/chunks/mermaid.core/ganttDiagram-ASEIQ4P5.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/infoDiagram-7APDZ6AT.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/pieDiagram-OZX6XH5M.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/quadrantDiagram-VG34DGKC.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/xychartDiagram-LESROZAQ.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/requirementDiagram-FPZB6IJI.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/sequenceDiagram-PQT5PN7B.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-BAVOGKFW.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/classDiagram-4BHYIK4I.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-UGV5ZQQN.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/classDiagram-v2-FI7KE7WJ.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/chunk-2JBRQKJ5.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/stateDiagram-TQSDS2D4.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/stateDiagram-v2-J5TZWJW5.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/journeyDiagram-G5LC7W2K.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/timeline-definition-KYQAIZUX.mjs", "../../../node_modules/cytoscape/dist/cytoscape.esm.mjs", "../../../node_modules/layout-base/layout-base.js", "../../../node_modules/cose-base/cose-base.js", "../../../node_modules/cytoscape-cose-bilkent/cytoscape-cose-bilkent.js", "../../../node_modules/mermaid/dist/chunks/mermaid.core/mindmap-definition-FCEC46F3.mjs", "../../../node_modules/d3-sankey/node_modules/d3-array/src/max.js", "../../../node_modules/d3-sankey/node_modules/d3-array/src/min.js", "../../../node_modules/d3-sankey/node_modules/d3-array/src/sum.js", "../../../node_modules/d3-sankey/node_modules/d3-array/src/index.js", "../../../node_modules/d3-sankey/src/align.js", "../../../node_modules/d3-sankey/src/constant.js", "../../../node_modules/d3-sankey/src/sankey.js", "../../../node_modules/d3-sankey/node_modules/d3-path/src/path.js", "../../../node_modules/d3-sankey/node_modules/d3-path/src/index.js", "../../../node_modules/d3-sankey/node_modules/d3-shape/src/constant.js", "../../../node_modules/d3-sankey/node_modules/d3-shape/src/point.js", "../../../node_modules/d3-sankey/node_modules/d3-shape/src/array.js", "../../../node_modules/d3-sankey/node_modules/d3-shape/src/link/index.js", "../../../node_modules/d3-sankey/node_modules/d3-shape/src/index.js", "../../../node_modules/d3-sankey/src/sankeyLinkHorizontal.js", "../../../node_modules/d3-sankey/src/index.js", "../../../node_modules/mermaid/dist/chunks/mermaid.core/sankeyDiagram-KMMQDL5K.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/diagram-QS5GVLUX.mjs", "../../../node_modules/mermaid/dist/chunks/mermaid.core/blockDiagram-EN3ZKWFM.mjs", "../../../node_modules/cytoscape-fcose/node_modules/layout-base/layout-base.js", "../../../node_modules/cytoscape-fcose/node_modules/cose-base/cose-base.js", "../../../node_modules/cytoscape-fcose/cytoscape-fcose.js", "../../../node_modules/mermaid/dist/chunks/mermaid.core/architectureDiagram-V6B76FHG.mjs", "../../../node_modules/lodash.debounce/index.js", "../../../node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/snakeize.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable_stream_source_element.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/fetch_requests.js", "../../../node_modules/@hotwired/turbo-rails/app/javascript/turbo/index.js", "../../../node_modules/@hotwired/stimulus/dist/stimulus.js", "../../javascript/controllers/application.js", "../../javascript/controllers/accordion_controller.js", "../../javascript/controllers/calc_settings_controller.js", "../../javascript/controllers/carousel_controller.js", "../../javascript/controllers/charts/biological_pollutants_controller.js", "../../javascript/controllers/charts/utils/chartSettings.js", "../../javascript/controllers/charts/co2_controller.js", "../../javascript/controllers/charts/mold_controller.js", "../../javascript/controllers/charts/pm_controller.js", "../../javascript/controllers/charts/voc_controller.js", "../../javascript/controllers/clipboard_controller.js", "../../../node_modules/highlight.js/es/index.js", "../../javascript/controllers/code_highlighter_controller.js", "../../javascript/controllers/compare_methods_controller.js", "../../javascript/controllers/content_toggle_controller.js", "../../javascript/controllers/delayed_image_controller.js", "../../../node_modules/@rails/activestorage/app/assets/javascripts/activestorage.esm.js", "../../javascript/controllers/direct_upload_controller.js", "../../javascript/controllers/fade_on_scroll_controller.js", "../../javascript/controllers/flash_controller.js", "../../javascript/controllers/info_point_graphic_controller.js", "../../../node_modules/i18n-js/src/I18n.ts", "../../../node_modules/i18n-js/src/Locales.ts", "../../../node_modules/make-plural/plurals.mjs", "../../../node_modules/i18n-js/src/Pluralization.ts", "../../../node_modules/i18n-js/src/helpers/camelCaseKeys.ts", "../../../node_modules/i18n-js/src/helpers/isSet.ts", "../../../node_modules/i18n-js/src/helpers/createTranslationOptions.ts", "../../../node_modules/bignumber.js/bignumber.mjs", "../../../node_modules/i18n-js/src/helpers/expandRoundMode.ts", "../../../node_modules/i18n-js/src/helpers/formatNumber.ts", "../../../node_modules/i18n-js/src/helpers/roundNumber.ts", "../../../node_modules/i18n-js/src/helpers/getFullScope.ts", "../../../node_modules/i18n-js/src/helpers/inferType.ts", "../../../node_modules/i18n-js/src/helpers/interpolate.ts", "../../../node_modules/i18n-js/src/helpers/lookup.ts", "../../../node_modules/i18n-js/src/helpers/numberToDelimited.ts", "../../../node_modules/i18n-js/src/helpers/numberToHuman.ts", "../../../node_modules/i18n-js/src/helpers/numberToHumanSize.ts", "../../../node_modules/i18n-js/src/helpers/parseDate.ts", "../../../node_modules/i18n-js/src/helpers/pluralize.ts", "../../../node_modules/i18n-js/src/helpers/strftime.ts", "../../../node_modules/i18n-js/src/helpers/timeAgoInWords.ts", "../../../node_modules/i18n-js/src/MissingTranslation.ts", "../../javascript/config/translations.json", "../../javascript/config/i18n.js", "../../javascript/controllers/inputs/address_controller.js", "../../javascript/controllers/inputs/multiple_direct_upload_controller.js", "../../javascript/controllers/inputs/number_controller.js", "../../javascript/controllers/inputs/phone_controller.js", "../../../node_modules/postcode/esm/index.js", "../../javascript/controllers/inputs/postal_code_controller.js", "../../javascript/controllers/lazy_select_controller.js", "../../../node_modules/mermaid/dist/mermaid.core.mjs", "../../../node_modules/stylis/src/Enum.js", "../../../node_modules/stylis/src/Utility.js", "../../../node_modules/stylis/src/Tokenizer.js", "../../../node_modules/stylis/src/Parser.js", "../../../node_modules/stylis/src/Serializer.js", "../../javascript/controllers/mermaid_controller.js", "../../javascript/controllers/modal_controller.js", "../../javascript/controllers/navigation_controller.js", "../../javascript/controllers/passwords_controller.js", "../../javascript/controllers/redirect_controller.js", "../../javascript/controllers/roi_calculator_controller.js", "../../javascript/controllers/search_controller.js", "../../javascript/controllers/shortcut_controller.js", "../../javascript/controllers/slideover_controller.js", "../../javascript/controllers/support_tickets_controller.js", "../../javascript/controllers/tabs_controller.js", "../../javascript/controllers/tags_controller.js", "../../javascript/controllers/timezone_controller.js", "../../javascript/controllers/toggle_controller.js", "../../javascript/controllers/toggle_panel_controller.js", "../../../node_modules/@popperjs/core/lib/enums.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getNodeName.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getWindow.js", "../../../node_modules/@popperjs/core/lib/dom-utils/instanceOf.js", "../../../node_modules/@popperjs/core/lib/modifiers/applyStyles.js", "../../../node_modules/@popperjs/core/lib/utils/getBasePlacement.js", "../../../node_modules/@popperjs/core/lib/utils/math.js", "../../../node_modules/@popperjs/core/lib/utils/userAgent.js", "../../../node_modules/@popperjs/core/lib/dom-utils/isLayoutViewport.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getBoundingClientRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getLayoutRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/contains.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getComputedStyle.js", "../../../node_modules/@popperjs/core/lib/dom-utils/isTableElement.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getDocumentElement.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getParentNode.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getOffsetParent.js", "../../../node_modules/@popperjs/core/lib/utils/getMainAxisFromPlacement.js", "../../../node_modules/@popperjs/core/lib/utils/within.js", "../../../node_modules/@popperjs/core/lib/utils/getFreshSideObject.js", "../../../node_modules/@popperjs/core/lib/utils/mergePaddingObject.js", "../../../node_modules/@popperjs/core/lib/utils/expandToHashMap.js", "../../../node_modules/@popperjs/core/lib/modifiers/arrow.js", "../../../node_modules/@popperjs/core/lib/utils/getVariation.js", "../../../node_modules/@popperjs/core/lib/modifiers/computeStyles.js", "../../../node_modules/@popperjs/core/lib/modifiers/eventListeners.js", "../../../node_modules/@popperjs/core/lib/utils/getOppositePlacement.js", "../../../node_modules/@popperjs/core/lib/utils/getOppositeVariationPlacement.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getWindowScroll.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getWindowScrollBarX.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getViewportRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getDocumentRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/isScrollParent.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getScrollParent.js", "../../../node_modules/@popperjs/core/lib/dom-utils/listScrollParents.js", "../../../node_modules/@popperjs/core/lib/utils/rectToClientRect.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getClippingRect.js", "../../../node_modules/@popperjs/core/lib/utils/computeOffsets.js", "../../../node_modules/@popperjs/core/lib/utils/detectOverflow.js", "../../../node_modules/@popperjs/core/lib/utils/computeAutoPlacement.js", "../../../node_modules/@popperjs/core/lib/modifiers/flip.js", "../../../node_modules/@popperjs/core/lib/modifiers/hide.js", "../../../node_modules/@popperjs/core/lib/modifiers/offset.js", "../../../node_modules/@popperjs/core/lib/modifiers/popperOffsets.js", "../../../node_modules/@popperjs/core/lib/utils/getAltAxis.js", "../../../node_modules/@popperjs/core/lib/modifiers/preventOverflow.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getHTMLElementScroll.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getNodeScroll.js", "../../../node_modules/@popperjs/core/lib/dom-utils/getCompositeRect.js", "../../../node_modules/@popperjs/core/lib/utils/orderModifiers.js", "../../../node_modules/@popperjs/core/lib/utils/debounce.js", "../../../node_modules/@popperjs/core/lib/utils/mergeByName.js", "../../../node_modules/@popperjs/core/lib/createPopper.js", "../../../node_modules/@popperjs/core/lib/popper.js", "../../javascript/controllers/tooltip_controller.js", "../../javascript/controllers/index.js", "../../javascript/application.js", "../../../node_modules/local-time/app/assets/javascripts/local-time.es2017-esm.js", "../../../node_modules/trix/src/trix/config/attachments.js", "../../../node_modules/trix/src/trix/config/block_attributes.js", "../../../node_modules/trix/src/trix/config/browser.js", "../../../node_modules/trix/src/trix/config/dompurify.js", "../../../node_modules/trix/src/trix/config/lang.js", "../../../node_modules/trix/src/trix/config/file_size_formatting.js", "../../../node_modules/trix/src/trix/constants.js", "../../../node_modules/trix/src/trix/core/helpers/extend.js", "../../../node_modules/trix/src/trix/core/helpers/dom.js", "../../../node_modules/trix/src/trix/config/input.js", "../../../node_modules/trix/src/trix/config/key_names.js", "../../../node_modules/trix/src/trix/config/parser.js", "../../../node_modules/trix/src/trix/config/text_attributes.js", "../../../node_modules/trix/src/trix/config/toolbar.js", "../../../node_modules/trix/src/trix/config/undo.js", "../../../node_modules/trix/src/trix/config/css.js", "../../../node_modules/trix/src/trix/core/basic_object.js", "../../../node_modules/trix/src/trix/core/utilities/utf16_string.js", "../../../node_modules/trix/src/trix/core/object.js", "../../../node_modules/trix/src/trix/core/helpers/arrays.js", "../../../node_modules/trix/src/trix/core/helpers/bidi.js", "../../../node_modules/trix/src/trix/core/helpers/config.js", "../../../node_modules/trix/src/trix/core/helpers/custom_elements.js", "../../../node_modules/trix/src/trix/core/helpers/events.js", "../../../node_modules/trix/src/trix/core/helpers/functions.js", "../../../node_modules/trix/src/trix/core/helpers/objects.js", "../../../node_modules/trix/src/trix/core/helpers/ranges.js", "../../../node_modules/trix/src/trix/observers/selection_change_observer.js", "../../../node_modules/trix/src/trix/core/helpers/strings.js", "../../../node_modules/trix/src/trix/core/collections/hash.js", "../../../node_modules/trix/src/trix/core/collections/object_group.js", "../../../node_modules/trix/src/trix/core/collections/object_map.js", "../../../node_modules/trix/src/trix/core/collections/element_store.js", "../../../node_modules/trix/src/trix/core/utilities/operation.js", "../../../node_modules/trix/src/trix/views/object_view.js", "../../../node_modules/trix/node_modules/dompurify/dist/purify.es.mjs", "../../../node_modules/trix/src/trix/models/html_sanitizer.js", "../../../node_modules/trix/src/trix/views/attachment_view.js", "../../../node_modules/trix/src/trix/views/previewable_attachment_view.js", "../../../node_modules/trix/src/trix/views/piece_view.js", "../../../node_modules/trix/src/trix/views/text_view.js", "../../../node_modules/trix/src/trix/views/block_view.js", "../../../node_modules/trix/src/trix/views/document_view.js", "../../../node_modules/trix/src/trix/models/piece.js", "../../../node_modules/trix/src/trix/operations/image_preload_operation.js", "../../../node_modules/trix/src/trix/models/attachment.js", "../../../node_modules/trix/src/trix/models/attachment_piece.js", "../../../node_modules/trix/src/trix/models/string_piece.js", "../../../node_modules/trix/src/trix/models/splittable_list.js", "../../../node_modules/trix/src/trix/models/text.js", "../../../node_modules/trix/src/trix/models/block.js", "../../../node_modules/trix/src/trix/models/document.js", "../../../node_modules/trix/src/trix/models/html_parser.js", "../../../node_modules/trix/src/trix/core/serialization.js", "../../../node_modules/trix/src/trix/models/managed_attachment.js", "../../../node_modules/trix/src/trix/models/attachment_manager.js", "../../../node_modules/trix/src/trix/models/line_break_insertion.js", "../../../node_modules/trix/src/trix/models/composition.js", "../../../node_modules/trix/src/trix/models/undo_manager.js", "../../../node_modules/trix/src/trix/filters/filter.js", "../../../node_modules/trix/src/trix/filters/attachment_gallery_filter.js", "../../../node_modules/trix/src/trix/models/editor.js", "../../../node_modules/trix/src/trix/models/location_mapper.js", "../../../node_modules/trix/src/trix/models/point_mapper.js", "../../../node_modules/trix/src/trix/models/selection_manager.js", "../../../node_modules/trix/src/trix/controllers/attachment_editor_controller.js", "../../../node_modules/trix/src/trix/controllers/composition_controller.js", "../../../node_modules/trix/src/trix/controllers/controller.js", "../../../node_modules/trix/src/trix/observers/mutation_observer.js", "../../../node_modules/trix/src/trix/operations/file_verification_operation.js", "../../../node_modules/trix/src/trix/models/flaky_android_keyboard_detector.js", "../../../node_modules/trix/src/trix/controllers/input_controller.js", "../../../node_modules/trix/src/trix/controllers/level_0_input_controller.js", "../../../node_modules/trix/src/trix/controllers/level_2_input_controller.js", "../../../node_modules/trix/src/trix/controllers/toolbar_controller.js", "../../../node_modules/trix/src/trix/controllers/editor_controller.js", "../../../node_modules/trix/src/trix/elements/trix_toolbar_element.js", "../../../node_modules/trix/src/trix/elements/trix_editor_element.js", "../../../node_modules/trix/src/trix/trix.js", "../../../node_modules/@rails/actiontext/app/assets/javascripts/actiontext.esm.js"], "sourcesContent": ["export default {\n logger: typeof console !== \"undefined\" ? console : undefined,\n WebSocket: typeof WebSocket !== \"undefined\" ? WebSocket : undefined,\n}\n", "import adapters from \"./adapters\"\n\n// The logger is disabled by default. You can enable it with:\n//\n// ActionCable.logger.enabled = true\n//\n// Example:\n//\n// import * as ActionCable from '@rails/actioncable'\n//\n// ActionCable.logger.enabled = true\n// ActionCable.logger.log('Connection Established.')\n//\n\nexport default {\n log(...messages) {\n if (this.enabled) {\n messages.push(Date.now())\n adapters.logger.log(\"[ActionCable]\", ...messages)\n }\n },\n}\n", "import logger from \"./logger\"\n\n// Responsible for ensuring the cable connection is in good health by validating the heartbeat pings sent from the server, and attempting\n// revival reconnections if things go astray. Internal class, not intended for direct user manipulation.\n\nconst now = () => new Date().getTime()\n\nconst secondsSince = time => (now() - time) / 1000\n\nclass ConnectionMonitor {\n constructor(connection) {\n this.visibilityDidChange = this.visibilityDidChange.bind(this)\n this.connection = connection\n this.reconnectAttempts = 0\n }\n\n start() {\n if (!this.isRunning()) {\n this.startedAt = now()\n delete this.stoppedAt\n this.startPolling()\n addEventListener(\"visibilitychange\", this.visibilityDidChange)\n logger.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`)\n }\n }\n\n stop() {\n if (this.isRunning()) {\n this.stoppedAt = now()\n this.stopPolling()\n removeEventListener(\"visibilitychange\", this.visibilityDidChange)\n logger.log(\"ConnectionMonitor stopped\")\n }\n }\n\n isRunning() {\n return this.startedAt && !this.stoppedAt\n }\n\n recordMessage() {\n this.pingedAt = now()\n }\n\n recordConnect() {\n this.reconnectAttempts = 0\n delete this.disconnectedAt\n logger.log(\"ConnectionMonitor recorded connect\")\n }\n\n recordDisconnect() {\n this.disconnectedAt = now()\n logger.log(\"ConnectionMonitor recorded disconnect\")\n }\n\n // Private\n\n startPolling() {\n this.stopPolling()\n this.poll()\n }\n\n stopPolling() {\n clearTimeout(this.pollTimeout)\n }\n\n poll() {\n this.pollTimeout = setTimeout(() => {\n this.reconnectIfStale()\n this.poll()\n }\n , this.getPollInterval())\n }\n\n getPollInterval() {\n const { staleThreshold, reconnectionBackoffRate } = this.constructor\n const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10))\n const jitterMax = this.reconnectAttempts === 0 ? 1.0 : reconnectionBackoffRate\n const jitter = jitterMax * Math.random()\n return staleThreshold * 1000 * backoff * (1 + jitter)\n }\n\n reconnectIfStale() {\n if (this.connectionIsStale()) {\n logger.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`)\n this.reconnectAttempts++\n if (this.disconnectedRecently()) {\n logger.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`)\n } else {\n logger.log(\"ConnectionMonitor reopening\")\n this.connection.reopen()\n }\n }\n }\n\n get refreshedAt() {\n return this.pingedAt ? this.pingedAt : this.startedAt\n }\n\n connectionIsStale() {\n return secondsSince(this.refreshedAt) > this.constructor.staleThreshold\n }\n\n disconnectedRecently() {\n return this.disconnectedAt && (secondsSince(this.disconnectedAt) < this.constructor.staleThreshold)\n }\n\n visibilityDidChange() {\n if (document.visibilityState === \"visible\") {\n setTimeout(() => {\n if (this.connectionIsStale() || !this.connection.isOpen()) {\n logger.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`)\n this.connection.reopen()\n }\n }\n , 200)\n }\n }\n\n}\n\nConnectionMonitor.staleThreshold = 6 // Server::Connections::BEAT_INTERVAL * 2 (missed two pings)\nConnectionMonitor.reconnectionBackoffRate = 0.15\n\nexport default ConnectionMonitor\n", "export default {\n \"message_types\": {\n \"welcome\": \"welcome\",\n \"disconnect\": \"disconnect\",\n \"ping\": \"ping\",\n \"confirmation\": \"confirm_subscription\",\n \"rejection\": \"reject_subscription\"\n },\n \"disconnect_reasons\": {\n \"unauthorized\": \"unauthorized\",\n \"invalid_request\": \"invalid_request\",\n \"server_restart\": \"server_restart\",\n \"remote\": \"remote\"\n },\n \"default_mount_path\": \"/cable\",\n \"protocols\": [\n \"actioncable-v1-json\",\n \"actioncable-unsupported\"\n ]\n}\n", "import adapters from \"./adapters\"\nimport ConnectionMonitor from \"./connection_monitor\"\nimport INTERNAL from \"./internal\"\nimport logger from \"./logger\"\n\n// Encapsulate the cable connection held by the consumer. This is an internal class not intended for direct user manipulation.\n\nconst {message_types, protocols} = INTERNAL\nconst supportedProtocols = protocols.slice(0, protocols.length - 1)\n\nconst indexOf = [].indexOf\n\nclass Connection {\n constructor(consumer) {\n this.open = this.open.bind(this)\n this.consumer = consumer\n this.subscriptions = this.consumer.subscriptions\n this.monitor = new ConnectionMonitor(this)\n this.disconnected = true\n }\n\n send(data) {\n if (this.isOpen()) {\n this.webSocket.send(JSON.stringify(data))\n return true\n } else {\n return false\n }\n }\n\n open() {\n if (this.isActive()) {\n logger.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`)\n return false\n } else {\n const socketProtocols = [...protocols, ...this.consumer.subprotocols || []]\n logger.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`)\n if (this.webSocket) { this.uninstallEventHandlers() }\n this.webSocket = new adapters.WebSocket(this.consumer.url, socketProtocols)\n this.installEventHandlers()\n this.monitor.start()\n return true\n }\n }\n\n close({allowReconnect} = {allowReconnect: true}) {\n if (!allowReconnect) { this.monitor.stop() }\n // Avoid closing websockets in a \"connecting\" state due to Safari 15.1+ bug. See: https://github.com/rails/rails/issues/43835#issuecomment-1002288478\n if (this.isOpen()) {\n return this.webSocket.close()\n }\n }\n\n reopen() {\n logger.log(`Reopening WebSocket, current state is ${this.getState()}`)\n if (this.isActive()) {\n try {\n return this.close()\n } catch (error) {\n logger.log(\"Failed to reopen WebSocket\", error)\n }\n finally {\n logger.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`)\n setTimeout(this.open, this.constructor.reopenDelay)\n }\n } else {\n return this.open()\n }\n }\n\n getProtocol() {\n if (this.webSocket) {\n return this.webSocket.protocol\n }\n }\n\n isOpen() {\n return this.isState(\"open\")\n }\n\n isActive() {\n return this.isState(\"open\", \"connecting\")\n }\n\n triedToReconnect() {\n return this.monitor.reconnectAttempts > 0\n }\n\n // Private\n\n isProtocolSupported() {\n return indexOf.call(supportedProtocols, this.getProtocol()) >= 0\n }\n\n isState(...states) {\n return indexOf.call(states, this.getState()) >= 0\n }\n\n getState() {\n if (this.webSocket) {\n for (let state in adapters.WebSocket) {\n if (adapters.WebSocket[state] === this.webSocket.readyState) {\n return state.toLowerCase()\n }\n }\n }\n return null\n }\n\n installEventHandlers() {\n for (let eventName in this.events) {\n const handler = this.events[eventName].bind(this)\n this.webSocket[`on${eventName}`] = handler\n }\n }\n\n uninstallEventHandlers() {\n for (let eventName in this.events) {\n this.webSocket[`on${eventName}`] = function() {}\n }\n }\n\n}\n\nConnection.reopenDelay = 500\n\nConnection.prototype.events = {\n message(event) {\n if (!this.isProtocolSupported()) { return }\n const {identifier, message, reason, reconnect, type} = JSON.parse(event.data)\n this.monitor.recordMessage()\n switch (type) {\n case message_types.welcome:\n if (this.triedToReconnect()) {\n this.reconnectAttempted = true\n }\n this.monitor.recordConnect()\n return this.subscriptions.reload()\n case message_types.disconnect:\n logger.log(`Disconnecting. Reason: ${reason}`)\n return this.close({allowReconnect: reconnect})\n case message_types.ping:\n return null\n case message_types.confirmation:\n this.subscriptions.confirmSubscription(identifier)\n if (this.reconnectAttempted) {\n this.reconnectAttempted = false\n return this.subscriptions.notify(identifier, \"connected\", {reconnected: true})\n } else {\n return this.subscriptions.notify(identifier, \"connected\", {reconnected: false})\n }\n case message_types.rejection:\n return this.subscriptions.reject(identifier)\n default:\n return this.subscriptions.notify(identifier, \"received\", message)\n }\n },\n\n open() {\n logger.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`)\n this.disconnected = false\n if (!this.isProtocolSupported()) {\n logger.log(\"Protocol is unsupported. Stopping monitor and disconnecting.\")\n return this.close({allowReconnect: false})\n }\n },\n\n close(event) {\n logger.log(\"WebSocket onclose event\")\n if (this.disconnected) { return }\n this.disconnected = true\n this.monitor.recordDisconnect()\n return this.subscriptions.notifyAll(\"disconnected\", {willAttemptReconnect: this.monitor.isRunning()})\n },\n\n error() {\n logger.log(\"WebSocket onerror event\")\n }\n}\n\nexport default Connection\n", "// A new subscription is created through the ActionCable.Subscriptions instance available on the consumer.\n// It provides a number of callbacks and a method for calling remote procedure calls on the corresponding\n// Channel instance on the server side.\n//\n// An example demonstrates the basic functionality:\n//\n// App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\", {\n// connected() {\n// // Called once the subscription has been successfully completed\n// },\n//\n// disconnected({ willAttemptReconnect: boolean }) {\n// // Called when the client has disconnected with the server.\n// // The object will have an `willAttemptReconnect` property which\n// // says whether the client has the intention of attempting\n// // to reconnect.\n// },\n//\n// appear() {\n// this.perform('appear', {appearing_on: this.appearingOn()})\n// },\n//\n// away() {\n// this.perform('away')\n// },\n//\n// appearingOn() {\n// $('main').data('appearing-on')\n// }\n// })\n//\n// The methods #appear and #away forward their intent to the remote AppearanceChannel instance on the server\n// by calling the `perform` method with the first parameter being the action (which maps to AppearanceChannel#appear/away).\n// The second parameter is a hash that'll get JSON encoded and made available on the server in the data parameter.\n//\n// This is how the server component would look:\n//\n// class AppearanceChannel < ApplicationActionCable::Channel\n// def subscribed\n// current_user.appear\n// end\n//\n// def unsubscribed\n// current_user.disappear\n// end\n//\n// def appear(data)\n// current_user.appear on: data['appearing_on']\n// end\n//\n// def away\n// current_user.away\n// end\n// end\n//\n// The \"AppearanceChannel\" name is automatically mapped between the client-side subscription creation and the server-side Ruby class name.\n// The AppearanceChannel#appear/away public methods are exposed automatically to client-side invocation through the perform method.\n\nconst extend = function(object, properties) {\n if (properties != null) {\n for (let key in properties) {\n const value = properties[key]\n object[key] = value\n }\n }\n return object\n}\n\nexport default class Subscription {\n constructor(consumer, params = {}, mixin) {\n this.consumer = consumer\n this.identifier = JSON.stringify(params)\n extend(this, mixin)\n }\n\n // Perform a channel action with the optional data passed as an attribute\n perform(action, data = {}) {\n data.action = action\n return this.send(data)\n }\n\n send(data) {\n return this.consumer.send({command: \"message\", identifier: this.identifier, data: JSON.stringify(data)})\n }\n\n unsubscribe() {\n return this.consumer.subscriptions.remove(this)\n }\n}\n", "import logger from \"./logger\"\n\n// Responsible for ensuring channel subscribe command is confirmed, retrying until confirmation is received.\n// Internal class, not intended for direct user manipulation.\n\nclass SubscriptionGuarantor {\n constructor(subscriptions) {\n this.subscriptions = subscriptions\n this.pendingSubscriptions = []\n }\n\n guarantee(subscription) {\n if(this.pendingSubscriptions.indexOf(subscription) == -1){ \n logger.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`)\n this.pendingSubscriptions.push(subscription) \n }\n else {\n logger.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`)\n }\n this.startGuaranteeing()\n }\n\n forget(subscription) {\n logger.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`)\n this.pendingSubscriptions = (this.pendingSubscriptions.filter((s) => s !== subscription))\n }\n\n startGuaranteeing() {\n this.stopGuaranteeing()\n this.retrySubscribing()\n }\n \n stopGuaranteeing() {\n clearTimeout(this.retryTimeout)\n }\n\n retrySubscribing() {\n this.retryTimeout = setTimeout(() => {\n if (this.subscriptions && typeof(this.subscriptions.subscribe) === \"function\") {\n this.pendingSubscriptions.map((subscription) => {\n logger.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`)\n this.subscriptions.subscribe(subscription)\n })\n }\n }\n , 500)\n }\n}\n\nexport default SubscriptionGuarantor", "import Subscription from \"./subscription\"\nimport SubscriptionGuarantor from \"./subscription_guarantor\"\nimport logger from \"./logger\"\n\n// Collection class for creating (and internally managing) channel subscriptions.\n// The only method intended to be triggered by the user is ActionCable.Subscriptions#create,\n// and it should be called through the consumer like so:\n//\n// App = {}\n// App.cable = ActionCable.createConsumer(\"ws://example.com/accounts/1\")\n// App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\")\n//\n// For more details on how you'd configure an actual channel subscription, see ActionCable.Subscription.\n\nexport default class Subscriptions {\n constructor(consumer) {\n this.consumer = consumer\n this.guarantor = new SubscriptionGuarantor(this)\n this.subscriptions = []\n }\n\n create(channelName, mixin) {\n const channel = channelName\n const params = typeof channel === \"object\" ? channel : {channel}\n const subscription = new Subscription(this.consumer, params, mixin)\n return this.add(subscription)\n }\n\n // Private\n\n add(subscription) {\n this.subscriptions.push(subscription)\n this.consumer.ensureActiveConnection()\n this.notify(subscription, \"initialized\")\n this.subscribe(subscription)\n return subscription\n }\n\n remove(subscription) {\n this.forget(subscription)\n if (!this.findAll(subscription.identifier).length) {\n this.sendCommand(subscription, \"unsubscribe\")\n }\n return subscription\n }\n\n reject(identifier) {\n return this.findAll(identifier).map((subscription) => {\n this.forget(subscription)\n this.notify(subscription, \"rejected\")\n return subscription\n })\n }\n\n forget(subscription) {\n this.guarantor.forget(subscription)\n this.subscriptions = (this.subscriptions.filter((s) => s !== subscription))\n return subscription\n }\n\n findAll(identifier) {\n return this.subscriptions.filter((s) => s.identifier === identifier)\n }\n\n reload() {\n return this.subscriptions.map((subscription) =>\n this.subscribe(subscription))\n }\n\n notifyAll(callbackName, ...args) {\n return this.subscriptions.map((subscription) =>\n this.notify(subscription, callbackName, ...args))\n }\n\n notify(subscription, callbackName, ...args) {\n let subscriptions\n if (typeof subscription === \"string\") {\n subscriptions = this.findAll(subscription)\n } else {\n subscriptions = [subscription]\n }\n\n return subscriptions.map((subscription) =>\n (typeof subscription[callbackName] === \"function\" ? subscription[callbackName](...args) : undefined))\n }\n\n subscribe(subscription) {\n if (this.sendCommand(subscription, \"subscribe\")) {\n this.guarantor.guarantee(subscription)\n }\n }\n\n confirmSubscription(identifier) {\n logger.log(`Subscription confirmed ${identifier}`)\n this.findAll(identifier).map((subscription) =>\n this.guarantor.forget(subscription))\n }\n\n sendCommand(subscription, command) {\n const {identifier} = subscription\n return this.consumer.send({command, identifier})\n }\n}\n", "import Connection from \"./connection\"\nimport Subscriptions from \"./subscriptions\"\n\n// The ActionCable.Consumer establishes the connection to a server-side Ruby Connection object. Once established,\n// the ActionCable.ConnectionMonitor will ensure that its properly maintained through heartbeats and checking for stale updates.\n// The Consumer instance is also the gateway to establishing subscriptions to desired channels through the #createSubscription\n// method.\n//\n// The following example shows how this can be set up:\n//\n// App = {}\n// App.cable = ActionCable.createConsumer(\"ws://example.com/accounts/1\")\n// App.appearance = App.cable.subscriptions.create(\"AppearanceChannel\")\n//\n// For more details on how you'd configure an actual channel subscription, see ActionCable.Subscription.\n//\n// When a consumer is created, it automatically connects with the server.\n//\n// To disconnect from the server, call\n//\n// App.cable.disconnect()\n//\n// and to restart the connection:\n//\n// App.cable.connect()\n//\n// Any channel subscriptions which existed prior to disconnecting will\n// automatically resubscribe.\n\nexport default class Consumer {\n constructor(url) {\n this._url = url\n this.subscriptions = new Subscriptions(this)\n this.connection = new Connection(this)\n this.subprotocols = []\n }\n\n get url() {\n return createWebSocketURL(this._url)\n }\n\n send(data) {\n return this.connection.send(data)\n }\n\n connect() {\n return this.connection.open()\n }\n\n disconnect() {\n return this.connection.close({allowReconnect: false})\n }\n\n ensureActiveConnection() {\n if (!this.connection.isActive()) {\n return this.connection.open()\n }\n }\n\n addSubProtocol(subprotocol) {\n this.subprotocols = [...this.subprotocols, subprotocol]\n }\n}\n\nexport function createWebSocketURL(url) {\n if (typeof url === \"function\") {\n url = url()\n }\n\n if (url && !/^wss?:/i.test(url)) {\n const a = document.createElement(\"a\")\n a.href = url\n // Fix populating Location properties in IE. Otherwise, protocol will be blank.\n a.href = a.href\n a.protocol = a.protocol.replace(\"http\", \"ws\")\n return a.href\n } else {\n return url\n }\n}\n", "import Connection from \"./connection\"\nimport ConnectionMonitor from \"./connection_monitor\"\nimport Consumer, { createWebSocketURL } from \"./consumer\"\nimport INTERNAL from \"./internal\"\nimport Subscription from \"./subscription\"\nimport Subscriptions from \"./subscriptions\"\nimport SubscriptionGuarantor from \"./subscription_guarantor\"\nimport adapters from \"./adapters\"\nimport logger from \"./logger\"\n\nexport {\n Connection,\n ConnectionMonitor,\n Consumer,\n INTERNAL,\n Subscription,\n Subscriptions,\n SubscriptionGuarantor,\n adapters,\n createWebSocketURL,\n logger,\n}\n\nexport function createConsumer(url = getConfig(\"url\") || INTERNAL.default_mount_path) {\n return new Consumer(url)\n}\n\nexport function getConfig(name) {\n const element = document.head.querySelector(`meta[name='action-cable-${name}']`)\n if (element) {\n return element.getAttribute(\"content\")\n }\n}\n", "/**\n * Highcharts JS v11.3.0 (2024-01-10)\n *\n * (c) 2009-2024 Torstein Honsi\n *\n * License: www.highcharts.com/license\n */!function(t,e){\"object\"==typeof module&&module.exports?(e.default=e,module.exports=t&&t.document?e(t):e):\"function\"==typeof define&&define.amd?define(\"highcharts/highcharts\",function(){return e(t)}):(t.Highcharts&&t.Highcharts.error(16,!0),t.Highcharts=e(t))}(\"undefined\"!=typeof window?window:this,function(t){\"use strict\";var e={};function i(e,i,s,o){e.hasOwnProperty(i)||(e[i]=o.apply(null,s),\"function\"==typeof CustomEvent&&t.dispatchEvent(new CustomEvent(\"HighchartsModuleLoaded\",{detail:{path:i,module:e[i]}})))}return i(e,\"Core/Globals.js\",[],function(){var e,i;return(i=e||(e={})).SVG_NS=\"http://www.w3.org/2000/svg\",i.product=\"Highcharts\",i.version=\"11.3.0\",i.win=void 0!==t?t:{},i.doc=i.win.document,i.svg=i.doc&&i.doc.createElementNS&&!!i.doc.createElementNS(i.SVG_NS,\"svg\").createSVGRect,i.userAgent=i.win.navigator&&i.win.navigator.userAgent||\"\",i.isChrome=-1!==i.userAgent.indexOf(\"Chrome\"),i.isFirefox=-1!==i.userAgent.indexOf(\"Firefox\"),i.isMS=/(edge|msie|trident)/i.test(i.userAgent)&&!i.win.opera,i.isSafari=!i.isChrome&&-1!==i.userAgent.indexOf(\"Safari\"),i.isTouchDevice=/(Mobile|Android|Windows Phone)/.test(i.userAgent),i.isWebKit=-1!==i.userAgent.indexOf(\"AppleWebKit\"),i.deg2rad=2*Math.PI/360,i.hasBidiBug=i.isFirefox&&4>parseInt(i.userAgent.split(\"Firefox/\")[1],10),i.hasTouch=!!i.win.TouchEvent,i.marginNames=[\"plotTop\",\"marginRight\",\"marginBottom\",\"plotLeft\"],i.noop=function(){},i.supportsPassiveEvents=function(){let t=!1;if(!i.isMS){let e=Object.defineProperty({},\"passive\",{get:function(){t=!0}});i.win.addEventListener&&i.win.removeEventListener&&(i.win.addEventListener(\"testPassive\",i.noop,e),i.win.removeEventListener(\"testPassive\",i.noop,e))}return t}(),i.charts=[],i.composed=[],i.dateFormats={},i.seriesTypes={},i.symbolSizes={},i.chartCount=0,e}),i(e,\"Core/Utilities.js\",[e[\"Core/Globals.js\"]],function(t){let e;let{charts:i,doc:s,win:o}=t;function r(e,i,s,n){let a=i?\"Highcharts error\":\"Highcharts warning\";32===e&&(e=`${a}: Deprecated member`);let h=p(e),l=h?`${a} #${e}: www.highcharts.com/errors/${e}/`:e.toString();if(void 0!==n){let t=\"\";h&&(l+=\"?\"),k(n,function(e,i){t+=`\n - ${i}: ${e}`,h&&(l+=encodeURI(i)+\"=\"+encodeURI(e))}),l+=t}C(t,\"displayError\",{chart:s,code:e,message:l,params:n},function(){if(i)throw Error(l);o.console&&-1===r.messages.indexOf(l)&&console.warn(l)}),r.messages.push(l)}function n(t,e){return parseInt(t,e||10)}function a(t){return\"string\"==typeof t}function h(t){let e=Object.prototype.toString.call(t);return\"[object Array]\"===e||\"[object Array Iterator]\"===e}function l(t,e){return!!t&&\"object\"==typeof t&&(!e||!h(t))}function d(t){return l(t)&&\"number\"==typeof t.nodeType}function c(t){let e=t&&t.constructor;return!!(l(t,!0)&&!d(t)&&e&&e.name&&\"Object\"!==e.name)}function p(t){return\"number\"==typeof t&&!isNaN(t)&&t<1/0&&t>-1/0}function u(t){return null!=t}function g(t,e,i){let s;let o=a(e)&&!u(i),r=(e,i)=>{u(e)?t.setAttribute(i,e):o?(s=t.getAttribute(i))||\"class\"!==i||(s=t.getAttribute(i+\"Name\")):t.removeAttribute(i)};return a(e)?r(i,e):k(e,r),s}function f(t){return h(t)?t:[t]}function m(t,e){let i;for(i in t||(t={}),e)t[i]=e[i];return t}function x(){let t=arguments,e=t.length;for(let i=0;i1e14?t:parseFloat(t.toPrecision(e||14))}(r||(r={})).messages=[],Math.easeInOutSine=function(t){return -.5*(Math.cos(Math.PI*t)-1)};let S=Array.prototype.find?function(t,e){return t.find(e)}:function(t,e){let i;let s=t.length;for(i=0;it.order-e.order),t.forEach(t=>{!1===t.fn.call(e,o)&&o.preventDefault()})}r&&!o.defaultPrevented&&r.call(e,o)}k({map:\"map\",each:\"forEach\",grep:\"filter\",reduce:\"reduce\",some:\"some\"},function(e,i){t[i]=function(t){return r(32,!1,void 0,{[`Highcharts.${i}`]:`use Array.${e}`}),Array.prototype[e].apply(t,[].slice.call(arguments,1))}});let w=function(){let t=Math.random().toString(36).substring(2,9)+\"-\",i=0;return function(){return\"highcharts-\"+(e?\"\":t)+i++}}();o.jQuery&&(o.jQuery.fn.highcharts=function(){let e=[].slice.call(arguments);if(this[0])return e[0]?(new t[a(e[0])?e.shift():\"Chart\"](this[0],e[0],e[1]),this):i[g(this[0],\"data-highcharts-chart\")]});let T={addEvent:function(e,i,s,o={}){let r=\"function\"==typeof e&&e.prototype||e;Object.hasOwnProperty.call(r,\"hcEvents\")||(r.hcEvents={});let n=r.hcEvents;t.Point&&e instanceof t.Point&&e.series&&e.series.chart&&(e.series.chart.runTrackerClick=!0);let a=e.addEventListener;a&&a.call(e,i,s,!!t.supportsPassiveEvents&&{passive:void 0===o.passive?-1!==i.indexOf(\"touch\"):o.passive,capture:!1}),n[i]||(n[i]=[]);let h={fn:s,order:\"number\"==typeof o.order?o.order:1/0};return n[i].push(h),n[i].sort((t,e)=>t.order-e.order),function(){M(e,i,s)}},arrayMax:function(t){let e=t.length,i=t[0];for(;e--;)t[e]>i&&(i=t[e]);return i},arrayMin:function(t){let e=t.length,i=t[0];for(;e--;)t[e]e?t-1&&o[d]){i=f(i),r[d]=[];for(let e=0;e{if(t.length>1)for(o=t.length-1;o>0;o--)(s=t[o]-t[o-1])<0&&!r?(e?.(),e=void 0):s&&(void 0===i||s=i-1&&(i=Math.floor(s)),Math.max(0,i-(t(e,\"padding-left\",!0)||0)-(t(e,\"padding-right\",!0)||0))}if(\"height\"===i)return Math.max(0,Math.min(e.offsetHeight,e.scrollHeight)-(t(e,\"padding-top\",!0)||0)-(t(e,\"padding-bottom\",!0)||0));let a=o.getComputedStyle(e,void 0);return a&&(r=a.getPropertyValue(i),x(s,\"opacity\"!==i)&&(r=n(r))),r},inArray:function(t,e,i){return r(32,!1,void 0,{\"Highcharts.inArray\":\"use Array.indexOf\"}),e.indexOf(t,i)},insertItem:function(t,e){let i;let s=t.options.index,o=e.length;for(i=t.options.isInternal?o:0;i=t))&&(o||!(a<=(e[r]+(e[r+1]||e[r]))/2)));r++);return v(n*i,-Math.round(Math.log(.001)/Math.LN10))},objectEach:k,offset:function(t){let e=s.documentElement,i=t.parentElement||t.parentNode?t.getBoundingClientRect():{top:0,left:0,width:0,height:0};return{top:i.top+(o.pageYOffset||e.scrollTop)-(e.clientTop||0),left:i.left+(o.pageXOffset||e.scrollLeft)-(e.clientLeft||0),width:i.width,height:i.height}},pad:function(t,e,i){return Array((e||2)+1-String(t).replace(\"-\",\"\").length).join(i||\"0\")+t},pick:x,pInt:n,pushUnique:function(t,e){return 0>t.indexOf(e)&&!!t.push(e)},relativeLength:function(t,e,i){return/%$/.test(t)?e*parseFloat(t)/100+(i||0):parseFloat(t)},removeEvent:M,splat:f,stableSort:function(t,e){let i,s;let o=t.length;for(s=0;s0?setTimeout(t,e,i):(t.call(0,i),-1)},timeUnits:{millisecond:1,second:1e3,minute:6e4,hour:36e5,day:864e5,week:6048e5,month:24192e5,year:314496e5},uniqueKey:w,useSerialIds:function(t){return e=x(t,e)},wrap:function(t,e,i){let s=t[e];t[e]=function(){let t=arguments,e=this;return i.apply(this,[function(){return s.apply(e,arguments.length?arguments:t)}].concat([].slice.call(arguments)))}}};return T}),i(e,\"Core/Chart/ChartDefaults.js\",[],function(){return{alignThresholds:!1,panning:{enabled:!1,type:\"x\"},styledMode:!1,borderRadius:0,colorCount:10,allowMutatingData:!0,ignoreHiddenSeries:!0,spacing:[10,10,15,10],resetZoomButton:{theme:{},position:{}},reflow:!0,type:\"line\",zooming:{singleTouch:!1,resetButton:{theme:{zIndex:6},position:{align:\"right\",x:-10,y:10}}},width:null,height:null,borderColor:\"#334eff\",backgroundColor:\"#ffffff\",plotBorderColor:\"#cccccc\"}}),i(e,\"Core/Color/Palettes.js\",[],function(){return{colors:[\"#2caffe\",\"#544fc5\",\"#00e272\",\"#fe6a35\",\"#6b8abc\",\"#d568fb\",\"#2ee0ca\",\"#fa4b42\",\"#feb56a\",\"#91e8e1\"]}}),i(e,\"Core/Time.js\",[e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e){let{win:i}=t,{defined:s,error:o,extend:r,isNumber:n,isObject:a,merge:h,objectEach:l,pad:d,pick:c,splat:p,timeUnits:u}=e,g=t.isSafari&&i.Intl&&i.Intl.DateTimeFormat.prototype.formatRange,f=t.isSafari&&i.Intl&&!i.Intl.DateTimeFormat.prototype.formatRange;return class{constructor(t){this.options={},this.useUTC=!1,this.variableTimezone=!1,this.Date=i.Date,this.getTimezoneOffset=this.timezoneOffsetFunction(),this.update(t)}get(t,e){if(this.variableTimezone||this.timezoneOffset){let i=e.getTime(),s=i-this.getTimezoneOffset(e);e.setTime(s);let o=e[\"getUTC\"+t]();return e.setTime(i),o}return this.useUTC?e[\"getUTC\"+t]():e[\"get\"+t]()}set(t,e,i){if(this.variableTimezone||this.timezoneOffset){if(\"Milliseconds\"===t||\"Seconds\"===t||\"Minutes\"===t&&this.getTimezoneOffset(e)%36e5==0)return e[\"setUTC\"+t](i);let s=this.getTimezoneOffset(e),o=e.getTime()-s;e.setTime(o),e[\"setUTC\"+t](i);let r=this.getTimezoneOffset(e);return o=e.getTime()+r,e.setTime(o)}return this.useUTC||g&&\"FullYear\"===t?e[\"setUTC\"+t](i):e[\"set\"+t](i)}update(t={}){let e=c(t.useUTC,!0);this.options=t=h(!0,this.options,t),this.Date=t.Date||i.Date||Date,this.useUTC=e,this.timezoneOffset=e&&t.timezoneOffset||void 0,this.getTimezoneOffset=this.timezoneOffsetFunction(),this.variableTimezone=e&&!!(t.getTimezoneOffset||t.timezone)}makeTime(t,e,i,s,o,r){let n,a,h;return this.useUTC?(n=this.Date.UTC.apply(0,arguments),a=this.getTimezoneOffset(n),n+=a,a!==(h=this.getTimezoneOffset(n))?n+=h-a:a-36e5!==this.getTimezoneOffset(n-36e5)||f||(n-=36e5)):n=new this.Date(t,e,c(i,1),c(s,0),c(o,0),c(r,0)).getTime(),n}timezoneOffsetFunction(){let t=this,e=this.options,i=e.getTimezoneOffset;return this.useUTC?e.timezone?t=>{try{let[i,s,o,r,a=0]=Intl.DateTimeFormat(\"en\",{timeZone:e.timezone,timeZoneName:\"shortOffset\"}).format(t).split(/(GMT|:)/).map(Number),h=-(36e5*(o+a/60));if(n(h))return h}catch(t){o(34)}return 0}:this.useUTC&&i?t=>6e4*i(t.valueOf()):()=>6e4*(t.timezoneOffset||0):t=>6e4*new Date(t.toString()).getTimezoneOffset()}dateFormat(e,i,o){if(!s(i)||isNaN(i))return t.defaultOptions.lang&&t.defaultOptions.lang.invalidDate||\"\";e=c(e,\"%Y-%m-%d %H:%M:%S\");let n=this,a=new this.Date(i),h=this.get(\"Hours\",a),p=this.get(\"Day\",a),u=this.get(\"Date\",a),g=this.get(\"Month\",a),f=this.get(\"FullYear\",a),m=t.defaultOptions.lang,x=m&&m.weekdays,y=m&&m.shortWeekdays,b=r({a:y?y[p]:x[p].substr(0,3),A:x[p],d:d(u),e:d(u,2,\" \"),w:p,b:m.shortMonths[g],B:m.months[g],m:d(g+1),o:g+1,y:f.toString().substr(2,2),Y:f,H:d(h),k:h,I:d(h%12||12),l:h%12||12,M:d(this.get(\"Minutes\",a)),p:h<12?\"AM\":\"PM\",P:h<12?\"am\":\"pm\",S:d(this.get(\"Seconds\",a)),L:d(Math.floor(i%1e3),3)},t.dateFormats);return l(b,function(t,s){for(;-1!==e.indexOf(\"%\"+s);)e=e.replace(\"%\"+s,\"function\"==typeof t?t.call(n,i):t)}),o?e.substr(0,1).toUpperCase()+e.substr(1):e}resolveDTLFormat(t){return a(t,!0)?t:{main:(t=p(t))[0],from:t[1],to:t[2]}}getTimeTicks(t,e,i,o){let n,a,h,l;let d=this,p=d.Date,g=[],f={},m=new p(e),x=t.unitRange,y=t.count||1;if(o=c(o,1),s(e)){d.set(\"Milliseconds\",m,x>=u.second?0:y*Math.floor(d.get(\"Milliseconds\",m)/y)),x>=u.second&&d.set(\"Seconds\",m,x>=u.minute?0:y*Math.floor(d.get(\"Seconds\",m)/y)),x>=u.minute&&d.set(\"Minutes\",m,x>=u.hour?0:y*Math.floor(d.get(\"Minutes\",m)/y)),x>=u.hour&&d.set(\"Hours\",m,x>=u.day?0:y*Math.floor(d.get(\"Hours\",m)/y)),x>=u.day&&d.set(\"Date\",m,x>=u.month?1:Math.max(1,y*Math.floor(d.get(\"Date\",m)/y))),x>=u.month&&(d.set(\"Month\",m,x>=u.year?0:y*Math.floor(d.get(\"Month\",m)/y)),a=d.get(\"FullYear\",m)),x>=u.year&&(a-=a%y,d.set(\"FullYear\",m,a)),x===u.week&&(l=d.get(\"Day\",m),d.set(\"Date\",m,d.get(\"Date\",m)-l+o+(l4*u.month||d.getTimezoneOffset(e)!==d.getTimezoneOffset(i));let p=m.getTime();for(n=1;p1?p=d.makeTime(a,t,r,c+n*y):p+=x*y,n++;g.push(p),x<=u.hour&&g.length<1e4&&g.forEach(function(t){t%18e5==0&&\"000000000\"===d.dateFormat(\"%H%M%S%L\",t)&&(f[t]=\"day\")})}return g.info=r(t,{higherRanks:f,totalRange:x*y}),g}getDateFormat(t,e,i,s){let o=this.dateFormat(\"%m-%d %H:%M:%S.%L\",e),r=\"01-01 00:00:00.000\",n={millisecond:15,second:12,minute:9,hour:6,day:3},a=\"millisecond\",h=a;for(a in u){if(t===u.week&&+this.dateFormat(\"%w\",e)===i&&o.substr(6)===r.substr(6)){a=\"week\";break}if(u[a]>t){a=h;break}if(n[a]&&o.substr(n[a])!==r.substr(n[a]))break;\"week\"!==a&&(h=a)}return this.resolveDTLFormat(s[a]).main}}}),i(e,\"Core/Defaults.js\",[e[\"Core/Chart/ChartDefaults.js\"],e[\"Core/Globals.js\"],e[\"Core/Color/Palettes.js\"],e[\"Core/Time.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o){let{isTouchDevice:r,svg:n}=e,{merge:a}=o,h={colors:i.colors,symbols:[\"circle\",\"diamond\",\"square\",\"triangle\",\"triangle-down\"],lang:{loading:\"Loading...\",months:[\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"],shortMonths:[\"Jan\",\"Feb\",\"Mar\",\"Apr\",\"May\",\"Jun\",\"Jul\",\"Aug\",\"Sep\",\"Oct\",\"Nov\",\"Dec\"],weekdays:[\"Sunday\",\"Monday\",\"Tuesday\",\"Wednesday\",\"Thursday\",\"Friday\",\"Saturday\"],decimalPoint:\".\",numericSymbols:[\"k\",\"M\",\"G\",\"T\",\"P\",\"E\"],resetZoom:\"Reset zoom\",resetZoomTitle:\"Reset zoom level 1:1\",thousandsSep:\" \"},global:{},time:{Date:void 0,getTimezoneOffset:void 0,timezone:void 0,timezoneOffset:0,useUTC:!0},chart:t,title:{style:{color:\"#333333\",fontWeight:\"bold\"},text:\"Chart title\",align:\"center\",margin:15,widthAdjust:-44},subtitle:{style:{color:\"#666666\",fontSize:\"0.8em\"},text:\"\",align:\"center\",widthAdjust:-44},caption:{margin:15,style:{color:\"#666666\",fontSize:\"0.8em\"},text:\"\",align:\"left\",verticalAlign:\"bottom\"},plotOptions:{},legend:{enabled:!0,align:\"center\",alignColumns:!0,className:\"highcharts-no-tooltip\",layout:\"horizontal\",itemMarginBottom:2,itemMarginTop:2,labelFormatter:function(){return this.name},borderColor:\"#999999\",borderRadius:0,navigation:{style:{fontSize:\"0.8em\"},activeColor:\"#0022ff\",inactiveColor:\"#cccccc\"},itemStyle:{color:\"#333333\",cursor:\"pointer\",fontSize:\"0.8em\",textDecoration:\"none\",textOverflow:\"ellipsis\"},itemHoverStyle:{color:\"#000000\"},itemHiddenStyle:{color:\"#666666\",textDecoration:\"line-through\"},shadow:!1,itemCheckboxStyle:{position:\"absolute\",width:\"13px\",height:\"13px\"},squareSymbol:!0,symbolPadding:5,verticalAlign:\"bottom\",x:0,y:0,title:{style:{fontSize:\"0.8em\",fontWeight:\"bold\"}}},loading:{labelStyle:{fontWeight:\"bold\",position:\"relative\",top:\"45%\"},style:{position:\"absolute\",backgroundColor:\"#ffffff\",opacity:.5,textAlign:\"center\"}},tooltip:{enabled:!0,animation:n,borderRadius:3,dateTimeLabelFormats:{millisecond:\"%A, %e %b, %H:%M:%S.%L\",second:\"%A, %e %b, %H:%M:%S\",minute:\"%A, %e %b, %H:%M\",hour:\"%A, %e %b, %H:%M\",day:\"%A, %e %b %Y\",week:\"Week from %A, %e %b %Y\",month:\"%B %Y\",year:\"%Y\"},footerFormat:\"\",headerShape:\"callout\",hideDelay:500,padding:8,shape:\"callout\",shared:!1,snap:r?25:10,headerFormat:'{point.key}
',pointFormat:'\u25CF {series.name}: {point.y}
',backgroundColor:\"#ffffff\",borderWidth:void 0,shadow:!0,stickOnContact:!1,style:{color:\"#333333\",cursor:\"default\",fontSize:\"0.8em\"},useHTML:!1},credits:{enabled:!0,href:\"https://www.highcharts.com?credits\",position:{align:\"right\",x:-10,verticalAlign:\"bottom\",y:-5},style:{cursor:\"pointer\",color:\"#999999\",fontSize:\"0.6em\"},text:\"Highcharts.com\"}};h.chart.styledMode=!1;let l=new s(h.time);return{defaultOptions:h,defaultTime:l,getOptions:function(){return h},setOptions:function(t){return a(!0,h,t),(t.time||t.global)&&(e.time?e.time.update(a(h.global,h.time,t.global,t.time)):e.time=l),h}}}),i(e,\"Core/Color/Color.js\",[e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e){let{isNumber:i,merge:s,pInt:o}=e;class r{static parse(t){return t?new r(t):r.None}constructor(e){let i,s,o,n;this.rgba=[NaN,NaN,NaN,NaN],this.input=e;let a=t.Color;if(a&&a!==r)return new a(e);if(\"object\"==typeof e&&void 0!==e.stops)this.stops=e.stops.map(t=>new r(t[1]));else if(\"string\"==typeof e){if(this.input=e=r.names[e.toLowerCase()]||e,\"#\"===e.charAt(0)){let t=e.length,i=parseInt(e.substr(1),16);7===t?s=[(16711680&i)>>16,(65280&i)>>8,255&i,1]:4===t&&(s=[(3840&i)>>4|(3840&i)>>8,(240&i)>>4|240&i,(15&i)<<4|15&i,1])}if(!s)for(o=r.parsers.length;o--&&!s;)(i=(n=r.parsers[o]).regex.exec(e))&&(s=n.parse(i))}s&&(this.rgba=s)}get(t){let e=this.input,o=this.rgba;if(\"object\"==typeof e&&void 0!==this.stops){let i=s(e);return i.stops=[].slice.call(i.stops),this.stops.forEach((e,s)=>{i.stops[s]=[i.stops[s][0],e.get(t)]}),i}return o&&i(o[0])?\"rgb\"!==t&&(t||1!==o[3])?\"a\"===t?`${o[3]}`:\"rgba(\"+o.join(\",\")+\")\":\"rgb(\"+o[0]+\",\"+o[1]+\",\"+o[2]+\")\":e}brighten(t){let e=this.rgba;if(this.stops)this.stops.forEach(function(e){e.brighten(t)});else if(i(t)&&0!==t)for(let i=0;i<3;i++)e[i]+=o(255*t),e[i]<0&&(e[i]=0),e[i]>255&&(e[i]=255);return this}setOpacity(t){return this.rgba[3]=t,this}tweenTo(t,e){let s=this.rgba,o=t.rgba;if(!i(s[0])||!i(o[0]))return t.input||\"none\";let r=1!==o[3]||1!==s[3];return(r?\"rgba(\":\"rgb(\")+Math.round(o[0]+(s[0]-o[0])*(1-e))+\",\"+Math.round(o[1]+(s[1]-o[1])*(1-e))+\",\"+Math.round(o[2]+(s[2]-o[2])*(1-e))+(r?\",\"+(o[3]+(s[3]-o[3])*(1-e)):\"\")+\")\"}}return r.names={white:\"#ffffff\",black:\"#000000\"},r.parsers=[{regex:/rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]?(?:\\.[0-9]+)?)\\s*\\)/,parse:function(t){return[o(t[1]),o(t[2]),o(t[3]),parseFloat(t[4],10)]}},{regex:/rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/,parse:function(t){return[o(t[1]),o(t[2]),o(t[3]),1]}}],r.None=new r(\"\"),r}),i(e,\"Core/Animation/Fx.js\",[e[\"Core/Color/Color.js\"],e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{parse:s}=t,{win:o}=e,{isNumber:r,objectEach:n}=i;class a{constructor(t,e,i){this.pos=NaN,this.options=e,this.elem=t,this.prop=i}dSetter(){let t=this.paths,e=t&&t[0],i=t&&t[1],s=this.now||0,o=[];if(1!==s&&e&&i){if(e.length===i.length&&s<1)for(let t=0;t=h+this.startTime?(this.now=this.end,this.pos=1,this.update(),l[this.prop]=!0,i=!0,n(l,function(t){!0!==t&&(i=!1)}),i&&a&&a.call(r),e=!1):(this.pos=o.easing((s-this.startTime)/h),this.now=this.start+(this.end-this.start)*this.pos,this.update(),e=!0),e}initPath(t,e,i){let s=t.startX,o=t.endX,n=i.slice(),a=t.isArea,h=a?2:1,l,d,c,p,u=e&&e.slice();if(!u)return[n,n];function g(t,e){for(;t.length{let s=d(t.options.animation);a=n(e)&&i(e.defer)?o.defer:Math.max(a,s.duration+s.defer),h=Math.min(o.duration,s.duration)}),t.renderer.forExport&&(a=0);let l={defer:Math.max(0,a-h),duration:Math.min(a,h)};return l},setAnimation:function(t,e){e.renderer.globalAnimation=l(t,e.options.chart.animation,!0)},stop:c}}),i(e,\"Core/Renderer/HTML/AST.js\",[e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e){let{SVG_NS:i,win:s}=t,{attr:o,createElement:r,css:n,error:a,isFunction:h,isString:l,objectEach:d,splat:c}=e,{trustedTypes:p}=s,u=p&&h(p.createPolicy)&&p.createPolicy(\"highcharts\",{createHTML:t=>t}),g=u?u.createHTML(\"\"):\"\",f=function(){try{return!!new DOMParser().parseFromString(g,\"text/html\")}catch(t){return!1}}();class m{static filterUserAttributes(t){return d(t,(e,i)=>{let s=!0;-1===m.allowedAttributes.indexOf(i)&&(s=!1),-1!==[\"background\",\"dynsrc\",\"href\",\"lowsrc\",\"src\"].indexOf(i)&&(s=l(e)&&m.allowedReferences.some(t=>0===e.indexOf(t))),s||(a(33,!1,void 0,{\"Invalid attribute in config\":`${i}`}),delete t[i]),l(e)&&t[i]&&(t[i]=e.replace(/{let i=e.split(\":\").map(t=>t.trim()),s=i.shift();return s&&i.length&&(t[s.replace(/-([a-z])/g,t=>t[1].toUpperCase())]=i.join(\":\")),t},{})}static setElementHTML(t,e){if(t.innerHTML=m.emptyHTML,e){let i=new m(e);i.addToDOM(t)}}constructor(t){this.nodes=\"string\"==typeof t?this.parseMarkup(t):t}addToDOM(e){return function e(s,r){let h;return c(s).forEach(function(s){let l;let c=s.tagName,p=s.textContent?t.doc.createTextNode(s.textContent):void 0,u=m.bypassHTMLFiltering;if(c){if(\"#text\"===c)l=p;else if(-1!==m.allowedTags.indexOf(c)||u){let a=\"svg\"===c?i:r.namespaceURI||i,h=t.doc.createElementNS(a,c),g=s.attributes||{};d(s,function(t,e){\"tagName\"!==e&&\"attributes\"!==e&&\"children\"!==e&&\"style\"!==e&&\"textContent\"!==e&&(g[e]=t)}),o(h,u?g:m.filterUserAttributes(g)),s.style&&n(h,s.style),p&&h.appendChild(p),e(s.children||[],h),l=h}else a(33,!1,void 0,{\"Invalid tagName in config\":c})}l&&r.appendChild(l),h=l}),h}(this.nodes,e)}parseMarkup(t){let e;let i=[];if(t=t.trim().replace(/ style=([\"'])/g,\" data-style=$1\"),f)e=new DOMParser().parseFromString(u?u.createHTML(t):t,\"text/html\");else{let i=r(\"div\");i.innerHTML=t,e={body:i}}let s=(t,e)=>{let i=t.nodeName.toLowerCase(),o={tagName:i};\"#text\"===i&&(o.textContent=t.textContent||\"\");let r=t.attributes;if(r){let t={};[].forEach.call(r,e=>{\"data-style\"===e.name?o.style=m.parseStyle(e.value):t[e.name]=e.value}),o.attributes=t}if(t.childNodes.length){let e=[];[].forEach.call(t.childNodes,t=>{s(t,e)}),e.length&&(o.children=e)}e.push(o)};return[].forEach.call(e.body.childNodes,t=>s(t,i)),i}}return m.allowedAttributes=[\"alt\",\"aria-controls\",\"aria-describedby\",\"aria-expanded\",\"aria-haspopup\",\"aria-hidden\",\"aria-label\",\"aria-labelledby\",\"aria-live\",\"aria-pressed\",\"aria-readonly\",\"aria-roledescription\",\"aria-selected\",\"class\",\"clip-path\",\"color\",\"colspan\",\"cx\",\"cy\",\"d\",\"dx\",\"dy\",\"disabled\",\"fill\",\"filterUnits\",\"flood-color\",\"flood-opacity\",\"height\",\"href\",\"id\",\"in\",\"markerHeight\",\"markerWidth\",\"offset\",\"opacity\",\"orient\",\"padding\",\"paddingLeft\",\"paddingRight\",\"patternUnits\",\"r\",\"refX\",\"refY\",\"role\",\"scope\",\"slope\",\"src\",\"startOffset\",\"stdDeviation\",\"stroke\",\"stroke-linecap\",\"stroke-width\",\"style\",\"tableValues\",\"result\",\"rowspan\",\"summary\",\"target\",\"tabindex\",\"text-align\",\"text-anchor\",\"textAnchor\",\"textLength\",\"title\",\"type\",\"valign\",\"width\",\"x\",\"x1\",\"x2\",\"xlink:href\",\"y\",\"y1\",\"y2\",\"zIndex\"],m.allowedReferences=[\"https://\",\"http://\",\"mailto:\",\"/\",\"../\",\"./\",\"#\"],m.allowedTags=[\"a\",\"abbr\",\"b\",\"br\",\"button\",\"caption\",\"circle\",\"clipPath\",\"code\",\"dd\",\"defs\",\"div\",\"dl\",\"dt\",\"em\",\"feComponentTransfer\",\"feDropShadow\",\"feFuncA\",\"feFuncB\",\"feFuncG\",\"feFuncR\",\"feGaussianBlur\",\"feOffset\",\"feMerge\",\"feMergeNode\",\"filter\",\"h1\",\"h2\",\"h3\",\"h4\",\"h5\",\"h6\",\"hr\",\"i\",\"img\",\"li\",\"linearGradient\",\"marker\",\"ol\",\"p\",\"path\",\"pattern\",\"pre\",\"rect\",\"small\",\"span\",\"stop\",\"strong\",\"style\",\"sub\",\"sup\",\"svg\",\"table\",\"text\",\"textPath\",\"thead\",\"title\",\"tbody\",\"tspan\",\"td\",\"th\",\"tr\",\"u\",\"ul\",\"#text\"],m.emptyHTML=g,m.bypassHTMLFiltering=!1,m}),i(e,\"Core/Templating.js\",[e[\"Core/Defaults.js\"],e[\"Core/Utilities.js\"]],function(t,e){let{defaultOptions:i,defaultTime:s}=t,{extend:o,getNestedProperty:r,isArray:n,isNumber:a,isObject:h,isString:l,pick:d,pInt:c}=e,p={add:(t,e)=>t+e,divide:(t,e)=>0!==e?t/e:\"\",eq:(t,e)=>t==e,each:function(t){let e=arguments[arguments.length-1];return!!n(t)&&t.map((i,s)=>u(e.body,o(h(i)?i:{\"@this\":i},{\"@index\":s,\"@first\":0===s,\"@last\":s===t.length-1}))).join(\"\")},ge:(t,e)=>t>=e,gt:(t,e)=>t>e,if:t=>!!t,le:(t,e)=>t<=e,lt:(t,e)=>tt*e,ne:(t,e)=>t!=e,subtract:(t,e)=>t-e,unless:t=>!t};function u(t=\"\",e,o){let n=/\\{([a-zA-Z0-9\\:\\.\\,;\\-\\/<>%_@\"'= #\\(\\)]+)\\}/g,a=/\\(([a-zA-Z0-9\\:\\.\\,;\\-\\/<>%_@\"'= ]+)\\)/g,h=[],l=/f$/,c=/\\.([0-9])/,f=i.lang,m=o&&o.time||s,x=o&&o.numberFormatter||g,y=(t=\"\")=>{let i;return\"true\"===t||\"false\"!==t&&((i=Number(t)).toString()===t?i:r(t,e))},b,v,S=0,k;for(;null!==(b=n.exec(t));){let i=a.exec(b[1]);i&&(b=i,k=!0),v&&v.isBlock||(v={ctx:e,expression:b[1],find:b[0],isBlock:\"#\"===b[1].charAt(0),start:b.index,startInner:b.index+b[0].length,length:b[0].length});let s=b[1].split(\" \")[0].replace(\"#\",\"\");p[s]&&(v.isBlock&&s===v.fn&&S++,v.fn||(v.fn=s));let o=\"else\"===b[1];if(v.isBlock&&v.fn&&(b[1]===`/${v.fn}`||o)){if(S)!o&&S--;else{let e=v.startInner,i=t.substr(e,b.index-e);void 0===v.body?(v.body=i,v.startInner=b.index+b[0].length):v.elseBody=i,v.find+=i+b[0],o||(h.push(v),v=void 0)}}else v.isBlock||h.push(v);if(i&&!v?.isBlock)break}return h.forEach(i=>{let s,o;let{body:r,elseBody:n,expression:a,fn:h}=i;if(h){let t=[i],l=a.split(\" \");for(o=p[h].length;o--;)t.unshift(y(l[o+1]));s=p[h].apply(e,t),i.isBlock&&\"boolean\"==typeof s&&(s=u(s?r:n,e))}else{let t=a.split(\":\");if(s=y(t.shift()||\"\"),t.length&&\"number\"==typeof s){let e=t.join(\":\");if(l.test(e)){let t=parseInt((e.match(c)||[\"\",\"-1\"])[1],10);null!==s&&(s=x(s,t,f.decimalPoint,e.indexOf(\",\")>-1?f.thousandsSep:\"\"))}else s=m.dateFormat(e,s)}}t=t.replace(i.find,d(s,\"\"))}),k?u(t,e,o):t}function g(t,e,s,o){let r,n;t=+t||0,e=+e;let h=i.lang,l=(t.toString().split(\".\")[1]||\"\").split(\"e\")[0].length,p=t.toString().split(\"e\"),u=e;-1===e?e=Math.min(l,20):a(e)?e&&p[1]&&p[1]<0&&((n=e+ +p[1])>=0?(p[0]=(+p[0]).toExponential(n).split(\"e\")[0],e=n):(p[0]=p[0].split(\".\")[0]||0,t=e<20?(p[0]*Math.pow(10,p[1])).toFixed(e):0,p[1]=0)):e=2;let g=(Math.abs(p[1]?p[0]:t)+Math.pow(10,-Math.max(e,l)-1)).toFixed(e),f=String(c(g)),m=f.length>3?f.length%3:0;return s=d(s,h.decimalPoint),o=d(o,h.thousandsSep),r=(t<0?\"-\":\"\")+(m?f.substr(0,m)+o:\"\"),0>+p[1]&&!u?r=\"0\":r+=f.substr(m).replace(/(\\d{3})(?=\\d)/g,\"$1\"+o),e&&(r+=s+g.slice(-e)),p[1]&&0!=+r&&(r+=\"e\"+p[1]),r}return{dateFormat:function(t,e,i){return s.dateFormat(t,e,i)},format:u,helpers:p,numberFormat:g}}),i(e,\"Core/Renderer/RendererUtilities.js\",[e[\"Core/Utilities.js\"]],function(t){var e;let{clamp:i,pick:s,pushUnique:o,stableSort:r}=t;return(e||(e={})).distribute=function t(e,n,a){let h=e,l=h.reducedLen||n,d=(t,e)=>t.target-e.target,c=[],p=e.length,u=[],g=c.push,f,m,x,y=!0,b,v,S=0,k;for(f=p;f--;)S+=e[f].size;if(S>l){for(r(e,(t,e)=>(e.rank||0)-(t.rank||0)),x=(k=e[0].rank===e[e.length-1].rank)?p/2:-1,m=k?x:p-1;x&&S>l;)b=e[f=Math.floor(m)],o(u,f)&&(S-=b.size),m+=x,k&&m>=e.length&&(x/=2,m=x);u.sort((t,e)=>e-t).forEach(t=>g.apply(c,e.splice(t,1)))}for(r(e,d),e=e.map(t=>({size:t.size,targets:[t.target],align:s(t.align,.5)}));y;){for(f=e.length;f--;)b=e[f],v=(Math.min.apply(0,b.targets)+Math.max.apply(0,b.targets))/2,b.pos=i(v-b.size*b.align,0,n-b.size);for(f=e.length,y=!1;f--;)f>0&&e[f-1].pos+e[f-1].size>e[f].pos&&(e[f-1].size+=e[f].size,e[f-1].targets=e[f-1].targets.concat(e[f].targets),e[f-1].align=.5,e[f-1].pos+e[f-1].size>n&&(e[f-1].pos=n-e[f-1].size),e.splice(f,1),y=!0)}return g.apply(h,c),f=0,e.some(e=>{let i=0;return(e.targets||[]).some(()=>(h[f].pos=e.pos+i,void 0!==a&&Math.abs(h[f].pos-h[f].target)>a)?(h.slice(0,f+1).forEach(t=>delete t.pos),h.reducedLen=(h.reducedLen||n)-.1*n,h.reducedLen>.1*n&&t(h,n,a),!0):(i+=h[f].size,f++,!1))}),r(h,d),h},e}),i(e,\"Core/Renderer/SVG/SVGElement.js\",[e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Color/Color.js\"],e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s){let{animate:o,animObject:r,stop:n}=t,{deg2rad:a,doc:h,noop:l,svg:d,SVG_NS:c,win:p}=i,{addEvent:u,attr:g,createElement:f,css:m,defined:x,erase:y,extend:b,fireEvent:v,isArray:S,isFunction:k,isObject:M,isString:C,merge:w,objectEach:T,pick:A,pInt:P,syncTimeout:L,uniqueKey:O}=s;class D{_defaultGetter(t){let e=A(this[t+\"Value\"],this[t],this.element?this.element.getAttribute(t):null,0);return/^[\\-0-9\\.]+$/.test(e)&&(e=parseFloat(e)),e}_defaultSetter(t,e,i){i.setAttribute(e,t)}add(t){let e;let i=this.renderer,s=this.element;return t&&(this.parentGroup=t),void 0!==this.textStr&&\"text\"===this.element.nodeName&&i.buildText(this),this.added=!0,(!t||t.handleZ||this.zIndex)&&(e=this.zIndexSetter()),e||(t?t.element:i.box).appendChild(s),this.onAdd&&this.onAdd(),this}addClass(t,e){let i=e?\"\":this.attr(\"class\")||\"\";return(t=(t||\"\").split(/ /g).reduce(function(t,e){return -1===i.indexOf(e)&&t.push(e),t},i?[i]:[]).join(\" \"))!==i&&this.attr(\"class\",t),this}afterSetters(){this.doTransform&&(this.updateTransform(),this.doTransform=!1)}align(t,e,i){let s,o,r,n,a;let h={},l=this.renderer,d=l.alignedObjects;t?(this.alignOptions=t,this.alignByTranslate=e,(!i||C(i))&&(this.alignTo=r=i||\"renderer\",y(d,this),d.push(this),i=void 0)):(t=this.alignOptions,e=this.alignByTranslate,r=this.alignTo),i=A(i,l[r],\"scrollablePlotBox\"===r?l.plotBox:void 0,l);let c=t.align,p=t.verticalAlign;return s=(i.x||0)+(t.x||0),o=(i.y||0)+(t.y||0),\"right\"===c?n=1:\"center\"===c&&(n=2),n&&(s+=(i.width-(t.width||0))/n),h[e?\"translateX\":\"x\"]=Math.round(s),\"bottom\"===p?a=1:\"middle\"===p&&(a=2),a&&(o+=(i.height-(t.height||0))/a),h[e?\"translateY\":\"y\"]=Math.round(o),this[this.placed?\"animate\":\"attr\"](h),this.placed=!0,this.alignAttr=h,this}alignSetter(t){let e={left:\"start\",center:\"middle\",right:\"end\"};e[t]&&(this.alignValue=t,this.element.setAttribute(\"text-anchor\",e[t]))}animate(t,e,i){let s=r(A(e,this.renderer.globalAnimation,!0)),n=s.defer;return h.hidden&&(s.duration=0),0!==s.duration?(i&&(s.complete=i),L(()=>{this.element&&o(this,t,s)},n)):(this.attr(t,void 0,i||s.complete),T(t,function(t,e){s.step&&s.step.call(this,t,{prop:e,pos:1,elem:this})},this)),this}applyTextOutline(t){let e=this.element,s=-1!==t.indexOf(\"contrast\");s&&(t=t.replace(/contrast/g,this.renderer.getContrast(e.style.fill)));let o=t.split(\" \"),r=o[o.length-1],n=o[0];if(n&&\"none\"!==n&&i.svg){this.fakeTS=!0,n=n.replace(/(^[\\d\\.]+)(.*?)$/g,function(t,e,i){return 2*Number(e)+i}),this.removeTextOutline();let t=h.createElementNS(c,\"tspan\");g(t,{class:\"highcharts-text-outline\",fill:r,stroke:r,\"stroke-width\":n,\"stroke-linejoin\":\"round\"});let i=e.querySelector(\"textPath\")||e;[].forEach.call(i.childNodes,e=>{let i=e.cloneNode(!0);i.removeAttribute&&[\"fill\",\"stroke\",\"stroke-width\",\"stroke\"].forEach(t=>i.removeAttribute(t)),t.appendChild(i)});let s=0;[].forEach.call(i.querySelectorAll(\"text tspan\"),t=>{s+=Number(t.getAttribute(\"dy\"))});let o=h.createElementNS(c,\"tspan\");o.textContent=\"\u200B\",g(o,{x:Number(e.getAttribute(\"x\")),dy:-s}),t.appendChild(o),i.insertBefore(t,i.firstChild)}}attr(t,e,i,s){let o=this.element,r=D.symbolCustomAttribs,a,h,l=this,d;return\"string\"==typeof t&&void 0!==e&&(a=t,(t={})[a]=e),\"string\"==typeof t?l=(this[t+\"Getter\"]||this._defaultGetter).call(this,t,o):(T(t,function(e,i){d=!1,s||n(this,i),this.symbolName&&-1!==r.indexOf(i)&&(h||(this.symbolAttr(t),h=!0),d=!0),this.rotation&&(\"x\"===i||\"y\"===i)&&(this.doTransform=!0),d||(this[i+\"Setter\"]||this._defaultSetter).call(this,e,i,o)},this),this.afterSetters()),i&&i.call(this),l}clip(t){if(t&&!t.clipPath){let e=O()+\"-\",i=this.renderer.createElement(\"clipPath\").attr({id:e}).add(this.renderer.defs);b(t,{clipPath:i,id:e,count:0}),t.add(i)}return this.attr(\"clip-path\",t?`url(${this.renderer.url}#${t.id})`:\"none\")}crisp(t,e){e=e||t.strokeWidth||0;let i=Math.round(e)%2/2;return t.x=Math.floor(t.x||this.x||0)+i,t.y=Math.floor(t.y||this.y||0)+i,t.width=Math.floor((t.width||this.width||0)-2*i),t.height=Math.floor((t.height||this.height||0)-2*i),x(t.strokeWidth)&&(t.strokeWidth=e),t}complexColor(t,i,s){let o=this.renderer,r,n,a,h,l,d,c,p,u,g,f=[],m;v(this.renderer,\"complexColor\",{args:arguments},function(){if(t.radialGradient?n=\"radialGradient\":t.linearGradient&&(n=\"linearGradient\"),n){if(a=t[n],l=o.gradients,d=t.stops,u=s.radialReference,S(a)&&(t[n]=a={x1:a[0],y1:a[1],x2:a[2],y2:a[3],gradientUnits:\"userSpaceOnUse\"}),\"radialGradient\"===n&&u&&!x(a.gradientUnits)&&(h=a,a=w(a,o.getRadialAttr(u,h),{gradientUnits:\"userSpaceOnUse\"})),T(a,function(t,e){\"id\"!==e&&f.push(e,t)}),T(d,function(t){f.push(t)}),l[f=f.join(\",\")])g=l[f].attr(\"id\");else{a.id=g=O();let t=l[f]=o.createElement(n).attr(a).add(o.defs);t.radAttr=h,t.stops=[],d.forEach(function(i){0===i[1].indexOf(\"rgba\")?(c=(r=e.parse(i[1])).get(\"rgb\"),p=r.get(\"a\")):(c=i[1],p=1);let s=o.createElement(\"stop\").attr({offset:i[0],\"stop-color\":c,\"stop-opacity\":p}).add(t);t.stops.push(s)})}m=\"url(\"+o.url+\"#\"+g+\")\",s.setAttribute(i,m),s.gradient=f,t.toString=function(){return m}}})}css(t){let e=this.styles,i={},s=this.element,o,r=!e;if(e&&T(t,function(t,s){e&&e[s]!==t&&(i[s]=t,r=!0)}),r){e&&(t=b(e,i)),null===t.width||\"auto\"===t.width?delete this.textWidth:\"text\"===s.nodeName.toLowerCase()&&t.width&&(o=this.textWidth=P(t.width)),this.styles=t,o&&!d&&this.renderer.forExport&&delete t.width;let r=w(t);s.namespaceURI===this.SVG_NS&&([\"textOutline\",\"textOverflow\",\"width\"].forEach(t=>r&&delete r[t]),r.color&&(r.fill=r.color)),m(s,r)}return this.added&&(\"text\"===this.element.nodeName&&this.renderer.buildText(this),t.textOutline&&this.applyTextOutline(t.textOutline)),this}dashstyleSetter(t){let e,i=this[\"stroke-width\"];if(\"inherit\"===i&&(i=1),t=t&&t.toLowerCase()){let s=t.replace(\"shortdashdotdot\",\"3,1,1,1,1,1,\").replace(\"shortdashdot\",\"3,1,1,1\").replace(\"shortdot\",\"1,1,\").replace(\"shortdash\",\"3,1,\").replace(\"longdash\",\"8,3,\").replace(/dot/g,\"1,3,\").replace(\"dash\",\"4,3,\").replace(/,$/,\"\").split(\",\");for(e=s.length;e--;)s[e]=\"\"+P(s[e])*A(i,NaN);t=s.join(\",\").replace(/NaN/g,\"none\"),this.element.setAttribute(\"stroke-dasharray\",t)}}destroy(){let t=this,e=t.element||{},i=t.renderer,s=e.ownerSVGElement,o=\"SPAN\"===e.nodeName&&t.parentGroup||void 0,r,a;if(e.onclick=e.onmouseout=e.onmouseover=e.onmousemove=e.point=null,n(t),t.clipPath&&s){let e=t.clipPath;[].forEach.call(s.querySelectorAll(\"[clip-path],[CLIP-PATH]\"),function(t){t.getAttribute(\"clip-path\").indexOf(e.element.id)>-1&&t.removeAttribute(\"clip-path\")}),t.clipPath=e.destroy()}if(t.connector=t.connector?.destroy(),t.stops){for(a=0;ae&&e.join?(i?t+\" \":\"\")+e.join(\" \"):(e||\"\").toString(),\"\")),/(NaN| {2}|^$)/.test(t)&&(t=\"M 0 0\"),this[e]!==t&&(i.setAttribute(e,t),this[e]=t)}fillSetter(t,e,i){\"string\"==typeof t?i.setAttribute(e,t):t&&this.complexColor(t,e,i)}hrefSetter(t,e,i){i.setAttributeNS(\"http://www.w3.org/1999/xlink\",e,t)}getBBox(t,e){let i,s,o,r,n;let{alignValue:h,element:l,renderer:d,styles:c,textStr:p}=this,{cache:u,cacheKeys:g}=d,f=l.namespaceURI===this.SVG_NS,y=A(e,this.rotation,0),v=d.styledMode?l&&D.prototype.getStyle.call(l,\"font-size\"):c&&c.fontSize;if(x(p)&&(-1===(n=p.toString()).indexOf(\"<\")&&(n=n.replace(/[0-9]/g,\"0\")),n+=[\"\",d.rootFontSize,v,y,this.textWidth,h,c&&c.textOverflow,c&&c.fontWeight].join(\",\")),n&&!t&&(i=u[n]),!i){if(f||d.forExport){try{r=this.fakeTS&&function(t){let e=l.querySelector(\".highcharts-text-outline\");e&&m(e,{display:t})},k(r)&&r(\"none\"),i=l.getBBox?b({},l.getBBox()):{width:l.offsetWidth,height:l.offsetHeight,x:0,y:0},k(r)&&r(\"\")}catch(t){}(!i||i.width<0)&&(i={x:0,y:0,width:0,height:0})}else i=this.htmlGetBBox();if(s=i.width,o=i.height,f&&(i.height=o=({\"11px,17\":14,\"13px,20\":16})[`${v||\"\"},${Math.round(o)}`]||o),y){let t=Number(l.getAttribute(\"y\")||0)-i.y,e={right:1,center:.5}[h||0]||0,r=y*a,n=(y-90)*a,d=s*Math.cos(r),c=s*Math.sin(r),p=Math.cos(n),u=Math.sin(n),g=i.x+e*(s-d),f=i.y+t-e*c,m=g+t*p,x=m+d,b=x-o*p,v=b-d,S=f+t*u,k=S+c,M=k-o*u,C=M-c;i.x=Math.min(m,x,b,v),i.y=Math.min(S,k,M,C),i.width=Math.max(m,x,b,v)-i.x,i.height=Math.max(S,k,M,C)-i.y}}if(n&&(\"\"===p||i.height>0)){for(;g.length>250;)delete u[g.shift()];u[n]||g.push(n),u[n]=i}return i}getStyle(t){return p.getComputedStyle(this.element||this,\"\").getPropertyValue(t)}hasClass(t){return -1!==(\"\"+this.attr(\"class\")).split(\" \").indexOf(t)}hide(){return this.attr({visibility:\"hidden\"})}htmlGetBBox(){return{height:0,width:0,x:0,y:0}}constructor(t,e){this.onEvents={},this.opacity=1,this.SVG_NS=c,this.element=\"span\"===e?f(e):h.createElementNS(this.SVG_NS,e),this.renderer=t,v(this,\"afterInit\")}on(t,e){let{onEvents:i}=this;return i[t]&&i[t](),i[t]=u(this.element,t,e),this}opacitySetter(t,e,i){let s=Number(Number(t).toFixed(3));this.opacity=s,i.setAttribute(e,s)}removeClass(t){return this.attr(\"class\",(\"\"+this.attr(\"class\")).replace(C(t)?RegExp(`(^| )${t}( |$)`):t,\" \").replace(/ +/g,\" \").trim())}removeTextOutline(){let t=this.element.querySelector(\"tspan.highcharts-text-outline\");t&&this.safeRemoveChild(t)}safeRemoveChild(t){let e=t.parentNode;e&&e.removeChild(t)}setRadialReference(t){let e=this.element.gradient&&this.renderer.gradients[this.element.gradient];return this.element.radialReference=t,e&&e.radAttr&&e.animate(this.renderer.getRadialAttr(t,e.radAttr)),this}setTextPath(t,e){e=w(!0,{enabled:!0,attributes:{dy:-5,startOffset:\"50%\",textAnchor:\"middle\"}},e);let i=this.renderer.url,s=this.text||this,o=s.textPath,{attributes:r,enabled:n}=e;if(t=t||o&&o.path,o&&o.undo(),t&&n){let e=u(s,\"afterModifyTree\",e=>{if(t&&n){let o=t.attr(\"id\");o||t.attr(\"id\",o=O());let n={x:0,y:0};x(r.dx)&&(n.dx=r.dx,delete r.dx),x(r.dy)&&(n.dy=r.dy,delete r.dy),s.attr(n),this.attr({transform:\"\"}),this.box&&(this.box=this.box.destroy());let a=e.nodes.slice(0);e.nodes.length=0,e.nodes[0]={tagName:\"textPath\",attributes:b(r,{\"text-anchor\":r.textAnchor,href:`${i}#${o}`}),children:a}}});s.textPath={path:t,undo:e}}else s.attr({dx:0,dy:0}),delete s.textPath;return this.added&&(s.textCache=\"\",this.renderer.buildText(s)),this}shadow(t){let{renderer:e}=this,i=w(this.parentGroup?.rotation===90?{offsetX:-1,offsetY:-1}:{},M(t)?t:{}),s=e.shadowDefinition(i);return this.attr({filter:t?`url(${e.url}#${s})`:\"none\"})}show(t=!0){return this.attr({visibility:t?\"inherit\":\"visible\"})}\"stroke-widthSetter\"(t,e,i){this[e]=t,i.setAttribute(e,t)}strokeWidth(){if(!this.renderer.styledMode)return this[\"stroke-width\"]||0;let t=this.getStyle(\"stroke-width\"),e=0,i;return t.indexOf(\"px\")===t.length-2?e=P(t):\"\"!==t&&(g(i=h.createElementNS(c,\"rect\"),{width:t,\"stroke-width\":0}),this.element.parentNode.appendChild(i),e=i.getBBox().width,i.parentNode.removeChild(i)),e}symbolAttr(t){let e=this;D.symbolCustomAttribs.forEach(function(i){e[i]=A(t[i],e[i])}),e.attr({d:e.renderer.symbols[e.symbolName](e.x,e.y,e.width,e.height,e)})}textSetter(t){t!==this.textStr&&(delete this.textPxLength,this.textStr=t,this.added&&this.renderer.buildText(this))}titleSetter(t){let e=this.element,i=e.getElementsByTagName(\"title\")[0]||h.createElementNS(this.SVG_NS,\"title\");e.insertBefore?e.insertBefore(i,e.firstChild):e.appendChild(i),i.textContent=String(A(t,\"\")).replace(/<[^>]*>/g,\"\").replace(/</g,\"<\").replace(/>/g,\">\")}toFront(){let t=this.element;return t.parentNode.appendChild(t),this}translate(t,e){return this.attr({translateX:t,translateY:e})}updateTransform(t=\"transform\"){let{element:e,matrix:i,rotation:s=0,scaleX:o,scaleY:r,translateX:n=0,translateY:a=0}=this,h=[\"translate(\"+n+\",\"+a+\")\"];x(i)&&h.push(\"matrix(\"+i.join(\",\")+\")\"),s&&h.push(\"rotate(\"+s+\" \"+A(this.rotationOriginX,e.getAttribute(\"x\"),0)+\" \"+A(this.rotationOriginY,e.getAttribute(\"y\")||0)+\")\"),(x(o)||x(r))&&h.push(\"scale(\"+A(o,1)+\" \"+A(r,1)+\")\"),h.length&&!(this.text||this).textPath&&e.setAttribute(t,h.join(\" \"))}visibilitySetter(t,e,i){\"inherit\"===t?i.removeAttribute(e):this[e]!==t&&i.setAttribute(e,t),this[e]=t}xGetter(t){return\"circle\"===this.element.nodeName&&(\"x\"===t?t=\"cx\":\"y\"===t&&(t=\"cy\")),this._defaultGetter(t)}zIndexSetter(t,e){let i=this.renderer,s=this.parentGroup,o=s||i,r=o.element||i.box,n=this.element,a=r===i.box,h,l,d,c=!1,p,u=this.added,g;if(x(t)?(n.setAttribute(\"data-z-index\",t),t=+t,this[e]===t&&(u=!1)):x(this[e])&&n.removeAttribute(\"data-z-index\"),this[e]=t,u){for((t=this.zIndex)&&s&&(s.handleZ=!0),g=(h=r.childNodes).length-1;g>=0&&!c;g--)p=!x(d=(l=h[g]).getAttribute(\"data-z-index\")),l!==n&&(t<0&&p&&!a&&!g?(r.insertBefore(n,h[g]),c=!0):(P(d)<=t||p&&(!x(t)||t>=0))&&(r.insertBefore(n,h[g+1]),c=!0));c||(r.insertBefore(n,h[a?3:0]),c=!0)}return c}}return D.symbolCustomAttribs=[\"anchorX\",\"anchorY\",\"clockwise\",\"end\",\"height\",\"innerR\",\"r\",\"start\",\"width\",\"x\",\"y\"],D.prototype.strokeSetter=D.prototype.fillSetter,D.prototype.yGetter=D.prototype.xGetter,D.prototype.matrixSetter=D.prototype.rotationOriginXSetter=D.prototype.rotationOriginYSetter=D.prototype.rotationSetter=D.prototype.scaleXSetter=D.prototype.scaleYSetter=D.prototype.translateXSetter=D.prototype.translateYSetter=D.prototype.verticalAlignSetter=function(t,e){this[e]=t,this.doTransform=!0},D}),i(e,\"Core/Renderer/RendererRegistry.js\",[e[\"Core/Globals.js\"]],function(t){var e,i;let s;return(i=e||(e={})).rendererTypes={},i.getRendererType=function(t=s){return i.rendererTypes[t]||i.rendererTypes[s]},i.registerRendererType=function(e,o,r){i.rendererTypes[e]=o,(!s||r)&&(s=e,t.Renderer=o)},e}),i(e,\"Core/Renderer/SVG/SVGLabel.js\",[e[\"Core/Renderer/SVG/SVGElement.js\"],e[\"Core/Utilities.js\"]],function(t,e){let{defined:i,extend:s,isNumber:o,merge:r,pick:n,removeEvent:a}=e;class h extends t{constructor(t,e,i,s,o,r,n,a,l,d){let c;super(t,\"g\"),this.paddingLeftSetter=this.paddingSetter,this.paddingRightSetter=this.paddingSetter,this.textStr=e,this.x=i,this.y=s,this.anchorX=r,this.anchorY=n,this.baseline=l,this.className=d,this.addClass(\"button\"===d?\"highcharts-no-tooltip\":\"highcharts-label\"),d&&this.addClass(\"highcharts-\"+d),this.text=t.text(void 0,0,0,a).attr({zIndex:1}),\"string\"==typeof o&&((c=/^url\\((.*?)\\)$/.test(o))||this.renderer.symbols[o])&&(this.symbolKey=o),this.bBox=h.emptyBBox,this.padding=3,this.baselineOffset=0,this.needsBox=t.styledMode||c,this.deferredAttr={},this.alignFactor=0}alignSetter(t){let e={left:0,center:.5,right:1}[t];e!==this.alignFactor&&(this.alignFactor=e,this.bBox&&o(this.xSetting)&&this.attr({x:this.xSetting}))}anchorXSetter(t,e){this.anchorX=t,this.boxAttr(e,Math.round(t)-this.getCrispAdjust()-this.xSetting)}anchorYSetter(t,e){this.anchorY=t,this.boxAttr(e,t-this.ySetting)}boxAttr(t,e){this.box?this.box.attr(t,e):this.deferredAttr[t]=e}css(e){if(e){let t={};e=r(e),h.textProps.forEach(i=>{void 0!==e[i]&&(t[i]=e[i],delete e[i])}),this.text.css(t),\"fontSize\"in t||\"fontWeight\"in t?this.updateTextPadding():(\"width\"in t||\"textOverflow\"in t)&&this.updateBoxSize()}return t.prototype.css.call(this,e)}destroy(){a(this.element,\"mouseenter\"),a(this.element,\"mouseleave\"),this.text&&this.text.destroy(),this.box&&(this.box=this.box.destroy()),t.prototype.destroy.call(this)}fillSetter(t,e){t&&(this.needsBox=!0),this.fill=t,this.boxAttr(e,t)}getBBox(){this.textStr&&0===this.bBox.width&&0===this.bBox.height&&this.updateBoxSize();let t=this.padding,e=n(this.paddingLeft,t);return{width:this.width||0,height:this.height||0,x:this.bBox.x-e,y:this.bBox.y-t}}getCrispAdjust(){return this.renderer.styledMode&&this.box?this.box.strokeWidth()%2/2:(this[\"stroke-width\"]?parseInt(this[\"stroke-width\"],10):0)%2/2}heightSetter(t){this.heightSetting=t}onAdd(){this.text.add(this),this.attr({text:n(this.textStr,\"\"),x:this.x||0,y:this.y||0}),this.box&&i(this.anchorX)&&this.attr({anchorX:this.anchorX,anchorY:this.anchorY})}paddingSetter(t,e){o(t)?t!==this[e]&&(this[e]=t,this.updateTextPadding()):this[e]=void 0}rSetter(t,e){this.boxAttr(e,t)}strokeSetter(t,e){this.stroke=t,this.boxAttr(e,t)}\"stroke-widthSetter\"(t,e){t&&(this.needsBox=!0),this[\"stroke-width\"]=t,this.boxAttr(e,t)}\"text-alignSetter\"(t){this.textAlign=t}textSetter(t){void 0!==t&&this.text.attr({text:t}),this.updateTextPadding()}updateBoxSize(){let t;let e=this.text,r={},n=this.padding,a=this.bBox=(!o(this.widthSetting)||!o(this.heightSetting)||this.textAlign)&&i(e.textStr)?e.getBBox():h.emptyBBox;this.width=this.getPaddedWidth(),this.height=(this.heightSetting||a.height||0)+2*n;let l=this.renderer.fontMetrics(e);if(this.baselineOffset=n+Math.min((this.text.firstLineMetrics||l).b,a.height||1/0),this.heightSetting&&(this.baselineOffset+=(this.heightSetting-l.h)/2),this.needsBox&&!e.textPath){if(!this.box){let t=this.box=this.symbolKey?this.renderer.symbol(this.symbolKey):this.renderer.rect();t.addClass((\"button\"===this.className?\"\":\"highcharts-label-box\")+(this.className?\" highcharts-\"+this.className+\"-box\":\"\")),t.add(this)}t=this.getCrispAdjust(),r.x=t,r.y=(this.baseline?-this.baselineOffset:0)+t,r.width=Math.round(this.width),r.height=Math.round(this.height),this.box.attr(s(r,this.deferredAttr)),this.deferredAttr={}}}updateTextPadding(){let t=this.text;if(!t.textPath){this.updateBoxSize();let e=this.baseline?0:this.baselineOffset,s=n(this.paddingLeft,this.padding);i(this.widthSetting)&&this.bBox&&(\"center\"===this.textAlign||\"right\"===this.textAlign)&&(s+=({center:.5,right:1})[this.textAlign]*(this.widthSetting-this.bBox.width)),(s!==t.x||e!==t.y)&&(t.attr(\"x\",s),t.hasBoxWidthChanged&&(this.bBox=t.getBBox(!0)),void 0!==e&&t.attr(\"y\",e)),t.x=s,t.y=e}}widthSetter(t){this.widthSetting=o(t)?t:void 0}getPaddedWidth(){let t=this.padding,e=n(this.paddingLeft,t),i=n(this.paddingRight,t);return(this.widthSetting||this.bBox.width||0)+e+i}xSetter(t){this.x=t,this.alignFactor&&(t-=this.alignFactor*this.getPaddedWidth(),this[\"forceAnimate:x\"]=!0),this.xSetting=Math.round(t),this.attr(\"translateX\",this.xSetting)}ySetter(t){this.ySetting=this.y=Math.round(t),this.attr(\"translateY\",this.ySetting)}}return h.emptyBBox={width:0,height:0,x:0,y:0},h.textProps=[\"color\",\"direction\",\"fontFamily\",\"fontSize\",\"fontStyle\",\"fontWeight\",\"lineHeight\",\"textAlign\",\"textDecoration\",\"textOutline\",\"textOverflow\",\"whiteSpace\",\"width\"],h}),i(e,\"Core/Renderer/SVG/Symbols.js\",[e[\"Core/Utilities.js\"]],function(t){let{defined:e,isNumber:i,pick:s}=t;function o(t,i,o,r,n){let a=[];if(n){let h=n.start||0,l=s(n.r,o),d=s(n.r,r||o),c=.001>Math.abs((n.end||0)-h-2*Math.PI),p=(n.end||0)-.001,u=n.innerR,g=s(n.open,c),f=Math.cos(h),m=Math.sin(h),x=Math.cos(p),y=Math.sin(p),b=s(n.longArc,p-h-Math.PI<.001?0:1),v=[\"A\",l,d,0,b,s(n.clockwise,1),t+l*x,i+d*y];v.params={start:h,end:p,cx:t,cy:i},a.push([\"M\",t+l*f,i+d*m],v),e(u)&&((v=[\"A\",u,u,0,b,e(n.clockwise)?1-n.clockwise:0,t+u*f,i+u*m]).params={start:p,end:h,cx:t,cy:i},a.push(g?[\"M\",t+u*x,i+u*y]:[\"L\",t+u*x,i+u*y],v)),g||a.push([\"Z\"])}return a}function r(t,e,i,s,o){return o&&o.r?n(t,e,i,s,o):[[\"M\",t,e],[\"L\",t+i,e],[\"L\",t+i,e+s],[\"L\",t,e+s],[\"Z\"]]}function n(t,e,i,s,o){let r=o?.r||0;return[[\"M\",t+r,e],[\"L\",t+i-r,e],[\"A\",r,r,0,0,1,t+i,e+r],[\"L\",t+i,e+s-r],[\"A\",r,r,0,0,1,t+i-r,e+s],[\"L\",t+r,e+s],[\"A\",r,r,0,0,1,t,e+s-r],[\"L\",t,e+r],[\"A\",r,r,0,0,1,t+r,e],[\"Z\"]]}return{arc:o,callout:function(t,e,s,o,r){let a=Math.min(r&&r.r||0,s,o),h=a+6,l=r&&r.anchorX,d=r&&r.anchorY||0,c=n(t,e,s,o,{r:a});if(!i(l)||l0&&d0)return c;if(t+l>s-h){if(d>e+h&&de+h&&d0){let i=do&&lh&&c.splice(1,1,[\"L\",l-6,e],[\"L\",l,e-6],[\"L\",l+6,e],[\"L\",s-a,e]);return c},circle:function(t,e,i,s){return o(t+i/2,e+s/2,i/2,s/2,{start:.5*Math.PI,end:2.5*Math.PI,open:!1})},diamond:function(t,e,i,s){return[[\"M\",t+i/2,e],[\"L\",t+i,e+s/2],[\"L\",t+i/2,e+s],[\"L\",t,e+s/2],[\"Z\"]]},rect:r,roundedRect:n,square:r,triangle:function(t,e,i,s){return[[\"M\",t+i/2,e],[\"L\",t+i,e+s],[\"L\",t,e+s],[\"Z\"]]},\"triangle-down\":function(t,e,i,s){return[[\"M\",t,e],[\"L\",t+i,e],[\"L\",t+i/2,e+s],[\"Z\"]]}}}),i(e,\"Core/Renderer/SVG/TextBuilder.js\",[e[\"Core/Renderer/HTML/AST.js\"],e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{doc:s,SVG_NS:o,win:r}=e,{attr:n,extend:a,fireEvent:h,isString:l,objectEach:d,pick:c}=i;return class{constructor(t){let e=t.styles;this.renderer=t.renderer,this.svgElement=t,this.width=t.textWidth,this.textLineHeight=e&&e.lineHeight,this.textOutline=e&&e.textOutline,this.ellipsis=!!(e&&\"ellipsis\"===e.textOverflow),this.noWrap=!!(e&&\"nowrap\"===e.whiteSpace)}buildSVG(){let e=this.svgElement,i=e.element,o=e.renderer,r=c(e.textStr,\"\").toString(),n=-1!==r.indexOf(\"<\"),a=i.childNodes,h=!e.added&&o.box,d=[r,this.ellipsis,this.noWrap,this.textLineHeight,this.textOutline,e.getStyle(\"font-size\"),this.width].join(\",\");if(d!==e.textCache){e.textCache=d,delete e.actualWidth;for(let t=a.length;t--;)i.removeChild(a[t]);if(n||this.ellipsis||this.width||e.textPath||-1!==r.indexOf(\" \")&&(!this.noWrap||//g.test(r))){if(\"\"!==r){h&&h.appendChild(i);let s=new t(r);this.modifyTree(s.nodes),s.addToDOM(i),this.modifyDOM(),this.ellipsis&&-1!==(i.textContent||\"\").indexOf(\"\u2026\")&&e.attr(\"title\",this.unescapeEntities(e.textStr||\"\",[\"<\",\">\"])),h&&h.removeChild(i)}}else i.appendChild(s.createTextNode(this.unescapeEntities(r)));l(this.textOutline)&&e.applyTextOutline&&e.applyTextOutline(this.textOutline)}}modifyDOM(){let t;let e=this.svgElement,i=n(e.element,\"x\");for(e.firstLineMetrics=void 0;t=e.element.firstChild;)if(/^[\\s\\u200B]*$/.test(t.textContent||\" \"))e.element.removeChild(t);else break;[].forEach.call(e.element.querySelectorAll(\"tspan.highcharts-br\"),(t,s)=>{t.nextSibling&&t.previousSibling&&(0===s&&1===t.previousSibling.nodeType&&(e.firstLineMetrics=e.renderer.fontMetrics(t.previousSibling)),n(t,{dy:this.getLineHeight(t.nextSibling),x:i}))});let a=this.width||0;if(!a)return;let h=(t,r)=>{let h=t.textContent||\"\",l=h.replace(/([^\\^])-/g,\"$1- \").split(\" \"),d=!this.noWrap&&(l.length>1||e.element.childNodes.length>1),c=this.getLineHeight(r),p=0,u=e.actualWidth;if(this.ellipsis)h&&this.truncate(t,h,void 0,0,Math.max(0,a-.8*c),(t,e)=>t.substring(0,e)+\"\u2026\");else if(d){let h=[],d=[];for(;r.firstChild&&r.firstChild!==t;)d.push(r.firstChild),r.removeChild(r.firstChild);for(;l.length;)l.length&&!this.noWrap&&p>0&&(h.push(t.textContent||\"\"),t.textContent=l.join(\" \").replace(/- /g,\"-\")),this.truncate(t,void 0,l,0===p&&u||0,a,(t,e)=>l.slice(0,e).join(\" \").replace(/- /g,\"-\")),u=e.actualWidth,p++;d.forEach(e=>{r.insertBefore(e,t)}),h.forEach(e=>{r.insertBefore(s.createTextNode(e),t);let a=s.createElementNS(o,\"tspan\");a.textContent=\"\u200B\",n(a,{dy:c,x:i}),r.insertBefore(a,t)})}},l=t=>{let i=[].slice.call(t.childNodes);i.forEach(i=>{i.nodeType===r.Node.TEXT_NODE?h(i,t):(-1!==i.className.baseVal.indexOf(\"highcharts-br\")&&(e.actualWidth=0),l(i))})};l(e.element)}getLineHeight(t){let e=t.nodeType===r.Node.TEXT_NODE?t.parentElement:t;return this.textLineHeight?parseInt(this.textLineHeight.toString(),10):this.renderer.fontMetrics(e||this.svgElement.element).h}modifyTree(t){let e=(i,s)=>{let{attributes:o={},children:r,style:n={},tagName:h}=i,l=this.renderer.styledMode;if(\"b\"===h||\"strong\"===h?l?o.class=\"highcharts-strong\":n.fontWeight=\"bold\":(\"i\"===h||\"em\"===h)&&(l?o.class=\"highcharts-emphasized\":n.fontStyle=\"italic\"),n&&n.color&&(n.fill=n.color),\"br\"===h){o.class=\"highcharts-br\",i.textContent=\"\u200B\";let e=t[s+1];e&&e.textContent&&(e.textContent=e.textContent.replace(/^ +/gm,\"\"))}else\"a\"===h&&r&&r.some(t=>\"#text\"===t.tagName)&&(i.children=[{children:r,tagName:\"tspan\"}]);\"#text\"!==h&&\"a\"!==h&&(i.tagName=\"tspan\"),a(i,{attributes:o,style:n}),r&&r.filter(t=>\"#text\"!==t.tagName).forEach(e)};t.forEach(e),h(this.svgElement,\"afterModifyTree\",{nodes:t})}truncate(t,e,i,s,o,r){let n,a;let h=this.svgElement,{renderer:l,rotation:d}=h,c=[],p=i?1:0,u=(e||i||\"\").length,g=u,f=function(e,o){let r=o||e,n=t.parentNode;if(n&&void 0===c[r]&&n.getSubStringLength)try{c[r]=s+n.getSubStringLength(0,i?r+1:r)}catch(t){}return c[r]};if(h.rotation=0,s+(a=f(t.textContent.length))>o){for(;p<=u;)g=Math.ceil((p+u)/2),i&&(n=r(i,g)),a=f(g,n&&n.length-1),p===u?p=u+1:a>o?u=g-1:p=g;0===u?t.textContent=\"\":e&&u===e.length-1||(t.textContent=n||r(e||i,g))}i&&i.splice(0,g),h.actualWidth=a,h.rotation=d}unescapeEntities(t,e){return d(this.renderer.escapes,function(i,s){e&&-1!==e.indexOf(i)||(t=t.toString().replace(RegExp(i,\"g\"),s))}),t}}}),i(e,\"Core/Renderer/SVG/SVGRenderer.js\",[e[\"Core/Renderer/HTML/AST.js\"],e[\"Core/Color/Color.js\"],e[\"Core/Globals.js\"],e[\"Core/Renderer/RendererRegistry.js\"],e[\"Core/Renderer/SVG/SVGElement.js\"],e[\"Core/Renderer/SVG/SVGLabel.js\"],e[\"Core/Renderer/SVG/Symbols.js\"],e[\"Core/Renderer/SVG/TextBuilder.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o,r,n,a,h){let l;let{charts:d,deg2rad:c,doc:p,isFirefox:u,isMS:g,isWebKit:f,noop:m,SVG_NS:x,symbolSizes:y,win:b}=i,{addEvent:v,attr:S,createElement:k,css:M,defined:C,destroyObjectProperties:w,extend:T,isArray:A,isNumber:P,isObject:L,isString:O,merge:D,pick:E,pInt:j,uniqueKey:I}=h;class B{constructor(t,e,i,s,o,r,n){let a,h;let l=this.createElement(\"svg\").attr({version:\"1.1\",class:\"highcharts-root\"}),d=l.element;n||l.css(this.getStyle(s||{})),t.appendChild(d),S(t,\"dir\",\"ltr\"),-1===t.innerHTML.indexOf(\"xmlns\")&&S(d,\"xmlns\",this.SVG_NS),this.box=d,this.boxWrapper=l,this.alignedObjects=[],this.url=this.getReferenceURL();let c=this.createElement(\"desc\").add();c.element.appendChild(p.createTextNode(\"Created with Highcharts 11.3.0\")),this.defs=this.createElement(\"defs\").add(),this.allowHTML=r,this.forExport=o,this.styledMode=n,this.gradients={},this.cache={},this.cacheKeys=[],this.imgCount=0,this.rootFontSize=l.getStyle(\"font-size\"),this.setSize(e,i,!1),u&&t.getBoundingClientRect&&((a=function(){M(t,{left:0,top:0}),h=t.getBoundingClientRect(),M(t,{left:Math.ceil(h.left)-h.left+\"px\",top:Math.ceil(h.top)-h.top+\"px\"})})(),this.unSubPixelFix=v(b,\"resize\",a))}definition(e){let i=new t([e]);return i.addToDOM(this.defs.element)}getReferenceURL(){if((u||f)&&p.getElementsByTagName(\"base\").length){if(!C(l)){let e=I(),i=new t([{tagName:\"svg\",attributes:{width:8,height:8},children:[{tagName:\"defs\",children:[{tagName:\"clipPath\",attributes:{id:e},children:[{tagName:\"rect\",attributes:{width:4,height:4}}]}]},{tagName:\"rect\",attributes:{id:\"hitme\",width:8,height:8,\"clip-path\":`url(#${e})`,fill:\"rgba(0,0,0,0.001)\"}}]}]),s=i.addToDOM(p.body);M(s,{position:\"fixed\",top:0,left:0,zIndex:9e5});let o=p.elementFromPoint(6,6);l=\"hitme\"===(o&&o.id),p.body.removeChild(s)}if(l)return b.location.href.split(\"#\")[0].replace(/<[^>]*>/g,\"\").replace(/([\\('\\)])/g,\"\\\\$1\").replace(/ /g,\"%20\")}return\"\"}getStyle(t){return this.style=T({fontFamily:\"Helvetica, Arial, sans-serif\",fontSize:\"1rem\"},t),this.style}setStyle(t){this.boxWrapper.css(this.getStyle(t))}isHidden(){return!this.boxWrapper.getBBox().width}destroy(){let t=this.defs;return this.box=null,this.boxWrapper=this.boxWrapper.destroy(),w(this.gradients||{}),this.gradients=null,this.defs=t.destroy(),this.unSubPixelFix&&this.unSubPixelFix(),this.alignedObjects=null,null}createElement(t){return new this.Element(this,t)}getRadialAttr(t,e){return{cx:t[0]-t[2]/2+(e.cx||0)*t[2],cy:t[1]-t[2]/2+(e.cy||0)*t[2],r:(e.r||0)*t[2]}}shadowDefinition(t){let e=[`highcharts-drop-shadow-${this.chartIndex}`,...Object.keys(t).map(e=>`${e}-${t[e]}`)].join(\"-\").toLowerCase().replace(/[^a-z0-9\\-]/g,\"\"),i=D({color:\"#000000\",offsetX:1,offsetY:1,opacity:.15,width:5},t);return this.defs.element.querySelector(`#${e}`)||this.definition({tagName:\"filter\",attributes:{id:e,filterUnits:i.filterUnits},children:[{tagName:\"feDropShadow\",attributes:{dx:i.offsetX,dy:i.offsetY,\"flood-color\":i.color,\"flood-opacity\":Math.min(5*i.opacity,1),stdDeviation:i.width/2}}]}),e}buildText(t){new a(t).buildSVG()}getContrast(t){let i=e.parse(t).rgba.map(t=>{let e=t/255;return e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4)}),s=.2126*i[0]+.7152*i[1]+.0722*i[2];return 1.05/(s+.05)>(s+.05)/.05?\"#FFFFFF\":\"#000000\"}button(e,i,s,o,r={},n,a,h,l,d){let c,p,u;let f=this.label(e,i,s,l,void 0,void 0,d,void 0,\"button\"),m=this.styledMode,x=r.states||{},y=0;r=D(r),delete r.states;let b=D({color:\"#333333\",cursor:\"pointer\",fontSize:\"0.8em\",fontWeight:\"normal\"},r.style);delete r.style;let S=t.filterUserAttributes(r);return f.attr(D({padding:8,r:2},S)),m||(S=D({fill:\"#f7f7f7\",stroke:\"#cccccc\",\"stroke-width\":1},S),c=(n=D(S,{fill:\"#e6e6e6\"},t.filterUserAttributes(n||x.hover||{}))).style,delete n.style,p=(a=D(S,{fill:\"#e6e9ff\",style:{color:\"#000000\",fontWeight:\"bold\"}},t.filterUserAttributes(a||x.select||{}))).style,delete a.style,u=(h=D(S,{style:{color:\"#cccccc\"}},t.filterUserAttributes(h||x.disabled||{}))).style,delete h.style),v(f.element,g?\"mouseover\":\"mouseenter\",function(){3!==y&&f.setState(1)}),v(f.element,g?\"mouseout\":\"mouseleave\",function(){3!==y&&f.setState(y)}),f.setState=function(t){if(1!==t&&(f.state=y=t),f.removeClass(/highcharts-button-(normal|hover|pressed|disabled)/).addClass(\"highcharts-button-\"+[\"normal\",\"hover\",\"pressed\",\"disabled\"][t||0]),!m){f.attr([S,n,a,h][t||0]);let e=[b,c,p,u][t||0];L(e)&&f.css(e)}},!m&&(f.attr(S).css(T({cursor:\"default\"},b)),d&&f.text.css({pointerEvents:\"none\"})),f.on(\"touchstart\",t=>t.stopPropagation()).on(\"click\",function(t){3!==y&&o.call(f,t)})}crispLine(t,e,i=\"round\"){let s=t[0],o=t[1];return C(s[1])&&s[1]===o[1]&&(s[1]=o[1]=Math[i](s[1])-e%2/2),C(s[2])&&s[2]===o[2]&&(s[2]=o[2]=Math[i](s[2])+e%2/2),t}path(t){let e=this.styledMode?{}:{fill:\"none\"};return A(t)?e.d=t:L(t)&&T(e,t),this.createElement(\"path\").attr(e)}circle(t,e,i){let s=L(t)?t:void 0===t?{}:{x:t,y:e,r:i},o=this.createElement(\"circle\");return o.xSetter=o.ySetter=function(t,e,i){i.setAttribute(\"c\"+e,t)},o.attr(s)}arc(t,e,i,s,o,r){let n;L(t)?(e=(n=t).y,i=n.r,s=n.innerR,o=n.start,r=n.end,t=n.x):n={innerR:s,start:o,end:r};let a=this.symbol(\"arc\",t,e,i,i,n);return a.r=i,a}rect(t,e,i,s,o,r){let n=L(t)?t:void 0===t?{}:{x:t,y:e,r:o,width:Math.max(i||0,0),height:Math.max(s||0,0)},a=this.createElement(\"rect\");return this.styledMode||(void 0!==r&&(n[\"stroke-width\"]=r,T(n,a.crisp(n))),n.fill=\"none\"),a.rSetter=function(t,e,i){a.r=t,S(i,{rx:t,ry:t})},a.rGetter=function(){return a.r||0},a.attr(n)}roundedRect(t){return this.symbol(\"roundedRect\").attr(t)}setSize(t,e,i){this.width=t,this.height=e,this.boxWrapper.animate({width:t,height:e},{step:function(){this.attr({viewBox:\"0 0 \"+this.attr(\"width\")+\" \"+this.attr(\"height\")})},duration:E(i,!0)?void 0:0}),this.alignElements()}g(t){let e=this.createElement(\"g\");return t?e.attr({class:\"highcharts-\"+t}):e}image(t,e,i,s,o,r){let n={preserveAspectRatio:\"none\"};P(e)&&(n.x=e),P(i)&&(n.y=i),P(s)&&(n.width=s),P(o)&&(n.height=o);let a=this.createElement(\"image\").attr(n),h=function(e){a.attr({href:t}),r.call(a,e)};if(r){a.attr({href:\"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\"});let e=new b.Image;v(e,\"load\",h),e.src=t,e.complete&&h({})}else a.attr({href:t});return a}symbol(t,e,i,s,o,r){let n,a,h,l;let c=this,u=/^url\\((.*?)\\)$/,g=u.test(t),f=!g&&(this.symbols[t]?t:\"circle\"),m=f&&this.symbols[f];if(m)\"number\"==typeof e&&(a=m.call(this.symbols,Math.round(e||0),Math.round(i||0),s||0,o||0,r)),n=this.path(a),c.styledMode||n.attr(\"fill\",\"none\"),T(n,{symbolName:f||void 0,x:e,y:i,width:s,height:o}),r&&T(n,r);else if(g){h=t.match(u)[1];let s=n=this.image(h);s.imgwidth=E(r&&r.width,y[h]&&y[h].width),s.imgheight=E(r&&r.height,y[h]&&y[h].height),l=t=>t.attr({width:t.width,height:t.height}),[\"width\",\"height\"].forEach(t=>{s[`${t}Setter`]=function(t,e){this[e]=t;let{alignByTranslate:i,element:s,width:o,height:n,imgwidth:a,imgheight:h}=this,l=\"width\"===e?a:h,d=1;r&&\"within\"===r.backgroundSize&&o&&n&&a&&h?(d=Math.min(o/a,n/h),S(s,{width:Math.round(a*d),height:Math.round(h*d)})):s&&l&&s.setAttribute(e,l),!i&&a&&h&&this.translate(((o||0)-a*d)/2,((n||0)-h*d)/2)}}),C(e)&&s.attr({x:e,y:i}),s.isImg=!0,C(s.imgwidth)&&C(s.imgheight)?l(s):(s.attr({width:0,height:0}),k(\"img\",{onload:function(){let t=d[c.chartIndex];0===this.width&&(M(this,{position:\"absolute\",top:\"-999em\"}),p.body.appendChild(this)),y[h]={width:this.width,height:this.height},s.imgwidth=this.width,s.imgheight=this.height,s.element&&l(s),this.parentNode&&this.parentNode.removeChild(this),c.imgCount--,c.imgCount||!t||t.hasLoaded||t.onload()},src:h}),this.imgCount++)}return n}clipRect(t,e,i,s){return this.rect(t,e,i,s,0)}text(t,e,i,s){let o={};if(s&&(this.allowHTML||!this.forExport))return this.html(t,e,i);o.x=Math.round(e||0),i&&(o.y=Math.round(i)),C(t)&&(o.text=t);let r=this.createElement(\"text\").attr(o);return s&&(!this.forExport||this.allowHTML)||(r.xSetter=function(t,e,i){let s=i.getElementsByTagName(\"tspan\"),o=i.getAttribute(e);for(let i=0,r;it.align())}}return T(B.prototype,{Element:o,SVG_NS:x,escapes:{\"&\":\"&\",\"<\":\"<\",\">\":\">\",\"'\":\"'\",'\"':\""\"},symbols:n,draw:m}),s.registerRendererType(\"svg\",B,!0),B}),i(e,\"Core/Renderer/HTML/HTMLElement.js\",[e[\"Core/Globals.js\"],e[\"Core/Renderer/SVG/SVGElement.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{composed:s}=t,{css:o,defined:r,extend:n,pushUnique:a,pInt:h}=i;class l extends e{static compose(t){if(a(s,this.compose)){let e=l.prototype,i=t.prototype;i.getSpanCorrection=e.getSpanCorrection,i.htmlCss=e.htmlCss,i.htmlGetBBox=e.htmlGetBBox,i.htmlUpdateTransform=e.htmlUpdateTransform,i.setSpanRotation=e.setSpanRotation}return t}getSpanCorrection(t,e,i){this.xCorr=-t*i,this.yCorr=-e}htmlCss(t){let e;let{element:i}=this,s=\"SPAN\"===i.tagName&&t&&\"width\"in t,r=s&&t.width;return s&&(delete t.width,this.textWidth=h(r)||void 0,e=!0),t?.textOverflow===\"ellipsis\"&&(t.whiteSpace=\"nowrap\",t.overflow=\"hidden\"),n(this.styles,t),o(i,t),e&&this.htmlUpdateTransform(),this}htmlGetBBox(){let{element:t}=this;return{x:t.offsetLeft,y:t.offsetTop,width:t.offsetWidth,height:t.offsetHeight}}htmlUpdateTransform(){if(!this.added){this.alignOnAdd=!0;return}let{element:t,renderer:e,rotation:i,styles:s,textAlign:n=\"left\",textWidth:a,translateX:h=0,translateY:l=0,x:d=0,y:c=0}=this,p={left:0,center:.5,right:1}[n],u=s?.whiteSpace;if(o(t,{marginLeft:`${h}px`,marginTop:`${l}px`}),\"SPAN\"===t.tagName){let s=[i,n,t.innerHTML,a,this.textAlign].join(\",\"),h,l=!1;if(a!==this.oldTextWidth){let e=this.textPxLength?this.textPxLength:(o(t,{width:\"\",whiteSpace:u||\"nowrap\"}),t.offsetWidth),s=a||0;(s>this.oldTextWidth||e>s)&&(/[ \\-]/.test(t.textContent||t.innerText)||\"ellipsis\"===t.style.textOverflow)&&(o(t,{width:e>s||i?a+\"px\":\"auto\",display:\"block\",whiteSpace:u||\"normal\"}),this.oldTextWidth=a,l=!0)}this.hasBoxWidthChanged=l,s!==this.cTT&&(h=e.fontMetrics(t).b,r(i)&&(i!==(this.oldRotation||0)||n!==this.oldAlign)&&this.setSpanRotation(i,p,h),this.getSpanCorrection(!r(i)&&this.textPxLength||t.offsetWidth,h,p)),o(t,{left:d+(this.xCorr||0)+\"px\",top:c+(this.yCorr||0)+\"px\"}),this.cTT=s,this.oldRotation=i,this.oldAlign=n}}setSpanRotation(t,e,i){o(this.element,{transform:`rotate(${t}deg)`,transformOrigin:`${100*e}% ${i}px`})}}return l}),i(e,\"Core/Renderer/HTML/HTMLRenderer.js\",[e[\"Core/Renderer/HTML/AST.js\"],e[\"Core/Globals.js\"],e[\"Core/Renderer/SVG/SVGElement.js\"],e[\"Core/Renderer/SVG/SVGRenderer.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o){let{composed:r}=e,{attr:n,createElement:a,extend:h,pick:l,pushUnique:d}=o;class c extends s{static compose(t){if(d(r,this.compose)){let e=c.prototype,i=t.prototype;i.html=e.html}return t}html(e,s,o){let r=this.createElement(\"span\"),d=r.element,c=r.renderer,p=function(t,e){[\"opacity\",\"visibility\"].forEach(function(s){t[s+\"Setter\"]=function(o,r,n){let a=t.div?t.div.style:e;i.prototype[s+\"Setter\"].call(this,o,r,n),a&&(a[r]=o)}}),t.addedSetters=!0};return r.textSetter=function(e){e!==this.textStr&&(delete this.bBox,delete this.oldTextWidth,t.setElementHTML(this.element,l(e,\"\")),this.textStr=e,r.doTransform=!0)},p(r,r.element.style),r.xSetter=r.ySetter=r.alignSetter=r.rotationSetter=function(t,e){\"align\"===e?r.alignValue=r.textAlign=t:r[e]=t,r.doTransform=!0},r.afterSetters=function(){this.doTransform&&(this.htmlUpdateTransform(),this.doTransform=!1)},r.attr({text:e,x:Math.round(s),y:Math.round(o)}).css({position:\"absolute\"}),c.styledMode||r.css({fontFamily:this.style.fontFamily,fontSize:this.style.fontSize}),d.style.whiteSpace=\"nowrap\",r.css=r.htmlCss,r.add=function(t){let e,i;let s=c.box.parentNode,o=[];if(this.parentGroup=t,t){if(!(e=t.div)){for(i=t;i;)o.push(i),i=i.parentGroup;o.reverse().forEach(function(t){var i;let l=n(t.element,\"class\"),d=t.css;function c(e,i){t[i]=e,\"translateX\"===i?g.left=e+\"px\":g.top=e+\"px\",t.doTransform=!0}let u=t.styles||{};e=t.div=t.div||a(\"div\",l?{className:l}:void 0,{position:\"absolute\",left:(t.translateX||0)+\"px\",top:(t.translateY||0)+\"px\",display:t.display,opacity:t.opacity,visibility:t.visibility},e||s);let g=e.style;h(t,{classSetter:(i=e,function(t){this.element.setAttribute(\"class\",t),i.className=t}),css:function(e){return d.call(t,e),[\"cursor\",\"pointerEvents\"].forEach(t=>{e[t]&&(g[t]=e[t])}),t},on:function(){return o[0].div&&r.on.apply({element:o[0].div,onEvents:t.onEvents},arguments),t},translateXSetter:c,translateYSetter:c}),t.addedSetters||p(t),t.css(u)})}}else e=s;return e.appendChild(d),r.added=!0,r.alignOnAdd&&r.htmlUpdateTransform(),r},r}}return c}),i(e,\"Core/Axis/AxisDefaults.js\",[],function(){var t,e;return(e=t||(t={})).xAxis={alignTicks:!0,allowDecimals:void 0,panningEnabled:!0,zIndex:2,zoomEnabled:!0,dateTimeLabelFormats:{millisecond:{main:\"%H:%M:%S.%L\",range:!1},second:{main:\"%H:%M:%S\",range:!1},minute:{main:\"%H:%M\",range:!1},hour:{main:\"%H:%M\",range:!1},day:{main:\"%e %b\"},week:{main:\"%e %b\"},month:{main:\"%b '%y\"},year:{main:\"%Y\"}},endOnTick:!1,gridLineDashStyle:\"Solid\",gridZIndex:1,labels:{autoRotationLimit:80,distance:15,enabled:!0,indentation:10,overflow:\"justify\",padding:5,reserveSpace:void 0,rotation:void 0,staggerLines:0,step:0,useHTML:!1,zIndex:7,style:{color:\"#333333\",cursor:\"default\",fontSize:\"0.8em\"}},maxPadding:.01,minorGridLineDashStyle:\"Solid\",minorTickLength:2,minorTickPosition:\"outside\",minorTicksPerMajor:5,minPadding:.01,offset:void 0,reversed:void 0,reversedStacks:!1,showEmpty:!0,showFirstLabel:!0,showLastLabel:!0,startOfWeek:1,startOnTick:!1,tickLength:10,tickPixelInterval:100,tickmarkPlacement:\"between\",tickPosition:\"outside\",title:{align:\"middle\",useHTML:!1,x:0,y:0,style:{color:\"#666666\",fontSize:\"0.8em\"}},type:\"linear\",uniqueNames:!0,visible:!0,minorGridLineColor:\"#f2f2f2\",minorGridLineWidth:1,minorTickColor:\"#999999\",lineColor:\"#333333\",lineWidth:1,gridLineColor:\"#e6e6e6\",gridLineWidth:void 0,tickColor:\"#333333\"},e.yAxis={reversedStacks:!0,endOnTick:!0,maxPadding:.05,minPadding:.05,tickPixelInterval:72,showLastLabel:!0,labels:{x:void 0},startOnTick:!0,title:{text:\"Values\"},stackLabels:{animation:{},allowOverlap:!1,enabled:!1,crop:!0,overflow:\"justify\",formatter:function(){let{numberFormatter:t}=this.axis.chart;return t(this.total||0,-1)},style:{color:\"#000000\",fontSize:\"0.7em\",fontWeight:\"bold\",textOutline:\"1px contrast\"}},gridLineWidth:1,lineWidth:0},t}),i(e,\"Core/Foundation.js\",[e[\"Core/Utilities.js\"]],function(t){var e;let{addEvent:i,isFunction:s,objectEach:o,removeEvent:r}=t;return(e||(e={})).registerEventOptions=function(t,e){t.eventOptions=t.eventOptions||{},o(e.events,function(e,o){t.eventOptions[o]!==e&&(t.eventOptions[o]&&(r(t,o,t.eventOptions[o]),delete t.eventOptions[o]),s(e)&&(t.eventOptions[o]=e,i(t,o,e,{order:0})))})},e}),i(e,\"Core/Axis/Tick.js\",[e[\"Core/Templating.js\"],e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{deg2rad:s}=e,{clamp:o,correctFloat:r,defined:n,destroyObjectProperties:a,extend:h,fireEvent:l,isNumber:d,merge:c,objectEach:p,pick:u}=i;return class{constructor(t,e,i,s,o){this.isNew=!0,this.isNewLabel=!0,this.axis=t,this.pos=e,this.type=i||\"\",this.parameters=o||{},this.tickmarkOffset=this.parameters.tickmarkOffset,this.options=this.parameters.options,l(this,\"init\"),i||s||this.addLabel()}addLabel(){let e=this,i=e.axis,s=i.options,o=i.chart,a=i.categories,c=i.logarithmic,p=i.names,g=e.pos,f=u(e.options&&e.options.labels,s.labels),m=i.tickPositions,x=g===m[0],y=g===m[m.length-1],b=(!f.step||1===f.step)&&1===i.tickInterval,v=m.info,S=e.label,k,M,C,w=this.parameters.category||(a?u(a[g],p[g],g):g);c&&d(w)&&(w=r(c.lin2log(w))),i.dateTime&&(v?k=(M=o.time.resolveDTLFormat(s.dateTimeLabelFormats[!s.grid&&v.higherRanks[g]||v.unitName])).main:d(w)&&(k=i.dateTime.getXDateFormat(w,s.dateTimeLabelFormats||{}))),e.isFirst=x,e.isLast=y;let T={axis:i,chart:o,dateTimeLabelFormat:k,isFirst:x,isLast:y,pos:g,tick:e,tickPositionInfo:v,value:w};l(this,\"labelFormat\",T);let A=e=>f.formatter?f.formatter.call(e,e):f.format?(e.text=i.defaultLabelFormatter.call(e,e),t.format(f.format,e,o)):i.defaultLabelFormatter.call(e,e),P=A.call(T,T),L=M&&M.list;L?e.shortenLabel=function(){for(C=0;C0&&o+c*p>h&&(y=Math.round((r-o)/Math.cos(d*s))):(o-c*ph&&(m=h-t.x+m*c,x=-1),(m=Math.min(g,m))m||e.autoRotation&&(l.styles||{}).width)&&(y=m)),y&&(this.shortenLabel?this.shortenLabel():(f.width=Math.floor(y)+\"px\",(i.style||{}).textOverflow||(f.textOverflow=\"ellipsis\"),l.css(f)))}moveLabel(t,e){let i=this,s=i.label,o=i.axis,r=!1,n;s&&s.textStr===t?(i.movedLabel=s,r=!0,delete i.label):p(o.ticks,function(e){r||e.isNew||e===i||!e.label||e.label.textStr!==t||(i.movedLabel=e.label,r=!0,e.labelPos=i.movedLabel.xy,delete e.label)}),!r&&(i.labelPos||s)&&(n=i.labelPos||s.xy,i.movedLabel=i.createLabel(t,e,n),i.movedLabel&&i.movedLabel.attr({opacity:0}))}render(t,e,i){let s=this.axis,o=s.horiz,r=this.pos,n=u(this.tickmarkOffset,s.tickmarkOffset),a=this.getPosition(o,r,n,e),h=a.x,d=a.y,c=o&&h===s.pos+s.len||!o&&d===s.pos?-1:1,p=u(i,this.label&&this.label.newOpacity,1);i=u(i,1),this.isActive=!0,this.renderGridLine(e,i,c),this.renderMark(a,i,c),this.renderLabel(a,e,p,t),this.isNew=!1,l(this,\"afterRender\")}renderGridLine(t,e,i){let s=this.axis,o=s.options,r={},n=this.pos,a=this.type,h=u(this.tickmarkOffset,s.tickmarkOffset),l=s.chart.renderer,d=this.gridLine,c,p=o.gridLineWidth,g=o.gridLineColor,f=o.gridLineDashStyle;\"minor\"===this.type&&(p=o.minorGridLineWidth,g=o.minorGridLineColor,f=o.minorGridLineDashStyle),d||(s.chart.styledMode||(r.stroke=g,r[\"stroke-width\"]=p||0,r.dashstyle=f),a||(r.zIndex=1),t&&(e=0),this.gridLine=d=l.path().attr(r).addClass(\"highcharts-\"+(a?a+\"-\":\"\")+\"grid-line\").add(s.gridGroup)),d&&(c=s.getPlotLinePath({value:n+h,lineWidth:d.strokeWidth()*i,force:\"pass\",old:t,acrossPanes:!1}))&&d[t||this.isNew?\"attr\":\"animate\"]({d:c,opacity:e})}renderMark(t,e,i){let s=this.axis,o=s.options,r=s.chart.renderer,n=this.type,a=s.tickSize(n?n+\"Tick\":\"tick\"),h=t.x,l=t.y,d=u(o[\"minor\"!==n?\"tickWidth\":\"minorTickWidth\"],!n&&s.isXAxis?1:0),c=o[\"minor\"!==n?\"tickColor\":\"minorTickColor\"],p=this.mark,g=!p;a&&(s.opposite&&(a[0]=-a[0]),p||(this.mark=p=r.path().addClass(\"highcharts-\"+(n?n+\"-\":\"\")+\"tick\").add(s.axisGroup),s.chart.styledMode||p.attr({stroke:c,\"stroke-width\":d})),p[g?\"attr\":\"animate\"]({d:this.getMarkPath(h,l,a[0],p.strokeWidth()*i,s.horiz,r),opacity:e}))}renderLabel(t,e,i,s){let o=this.axis,r=o.horiz,n=o.options,a=this.label,h=n.labels,l=h.step,c=u(this.tickmarkOffset,o.tickmarkOffset),p=t.x,g=t.y,f=!0;a&&d(p)&&(a.xy=t=this.getLabelPosition(p,g,a,r,h,c,s,l),(!this.isFirst||this.isLast||n.showFirstLabel)&&(!this.isLast||this.isFirst||n.showLastLabel)?!r||h.step||h.rotation||e||0===i||this.handleOverflow(t):f=!1,l&&s%l&&(f=!1),f&&d(t.y)?(t.opacity=i,a[this.isNewLabel?\"attr\":\"animate\"](t).show(!0),this.isNewLabel=!1):(a.hide(),this.isNewLabel=!0))}replaceMovedLabel(){let t=this.label,e=this.axis;t&&!this.isNew&&(t.animate({opacity:0},void 0,t.destroy),delete this.label),e.isDirty=!0,this.label=this.movedLabel,delete this.movedLabel}}}),i(e,\"Core/Axis/Axis.js\",[e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Axis/AxisDefaults.js\"],e[\"Core/Color/Color.js\"],e[\"Core/Defaults.js\"],e[\"Core/Foundation.js\"],e[\"Core/Globals.js\"],e[\"Core/Axis/Tick.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o,r,n,a){let{animObject:h}=t,{xAxis:l,yAxis:d}=e,{defaultOptions:c}=s,{registerEventOptions:p}=o,{deg2rad:u}=r,{arrayMax:g,arrayMin:f,clamp:m,correctFloat:x,defined:y,destroyObjectProperties:b,erase:v,error:S,extend:k,fireEvent:M,getClosestDistance:C,insertItem:w,isArray:T,isNumber:A,isString:P,merge:L,normalizeTickInterval:O,objectEach:D,pick:E,relativeLength:j,removeEvent:I,splat:B,syncTimeout:R}=a,z=(t,e)=>O(e,void 0,void 0,E(t.options.allowDecimals,e<.5||void 0!==t.tickAmount),!!t.tickAmount);k(c,{xAxis:l,yAxis:L(l,d)});class N{constructor(t,e,i){this.init(t,e,i)}init(t,e,i=this.coll){let s=\"xAxis\"===i,o=this.isZAxis||(t.inverted?!s:s);this.chart=t,this.horiz=o,this.isXAxis=s,this.coll=i,M(this,\"init\",{userOptions:e}),this.opposite=E(e.opposite,this.opposite),this.side=E(e.side,this.side,o?this.opposite?0:2:this.opposite?1:3),this.setOptions(e);let r=this.options,n=r.labels,a=r.type;this.userOptions=e,this.minPixelPadding=0,this.reversed=E(r.reversed,this.reversed),this.visible=r.visible,this.zoomEnabled=r.zoomEnabled,this.hasNames=\"category\"===a||!0===r.categories,this.categories=T(r.categories)&&r.categories||(this.hasNames?[]:void 0),this.names||(this.names=[],this.names.keys={}),this.plotLinesAndBandsGroups={},this.positiveValuesOnly=!!this.logarithmic,this.isLinked=y(r.linkedTo),this.ticks={},this.labelEdge=[],this.minorTicks={},this.plotLinesAndBands=[],this.alternateBands={},this.len=0,this.minRange=this.userMinRange=r.minRange||r.maxZoom,this.range=r.range,this.offset=r.offset||0,this.max=void 0,this.min=void 0;let h=E(r.crosshair,B(t.options.tooltip.crosshairs)[s?0:1]);this.crosshair=!0===h?{}:h,-1===t.axes.indexOf(this)&&(s?t.axes.splice(t.xAxis.length,0,this):t.axes.push(this),w(this,t[this.coll])),t.orderItems(this.coll),this.series=this.series||[],t.inverted&&!this.isZAxis&&s&&!y(this.reversed)&&(this.reversed=!0),this.labelRotation=A(n.rotation)?n.rotation:void 0,p(this,r),M(this,\"afterInit\")}setOptions(t){let e=this.horiz?{labels:{autoRotation:[-45]},margin:15}:{title:{rotation:90*this.side}};this.options=L(e,c[this.coll],t),M(this,\"afterSetOptions\",{userOptions:t})}defaultLabelFormatter(t){let e=this.axis,i=this.chart,{numberFormatter:s}=i,o=A(this.value)?this.value:NaN,r=e.chart.time,n=e.categories,a=this.dateTimeLabelFormat,h=c.lang,l=h.numericSymbols,d=h.numericSymbolMagnitude||1e3,p=e.logarithmic?Math.abs(o):e.tickInterval,u=l&&l.length,g,f;if(n)f=`${this.value}`;else if(a)f=r.dateFormat(a,o);else if(u&&l&&p>=1e3)for(;u--&&void 0===f;)p>=(g=Math.pow(d,u+1))&&10*o%g==0&&null!==l[u]&&0!==o&&(f=s(o/g,-1)+l[u]);return void 0===f&&(f=Math.abs(o)>=1e4?s(o,-1):s(o,-1,void 0,\"\")),f}getSeriesExtremes(){let t;let e=this;M(this,\"getSeriesExtremes\",null,function(){e.hasVisibleSeries=!1,e.dataMin=e.dataMax=e.threshold=void 0,e.softThreshold=!e.isXAxis,e.series.forEach(i=>{if(i.reserveSpace()){let s=i.options,o,r=s.threshold,n,a;if(e.hasVisibleSeries=!0,e.positiveValuesOnly&&0>=(r||0)&&(r=void 0),e.isXAxis)(o=i.xData)&&o.length&&(o=e.logarithmic?o.filter(t=>t>0):o,n=(t=i.getXExtremes(o)).min,a=t.max,A(n)||n instanceof Date||(o=o.filter(A),n=(t=i.getXExtremes(o)).min,a=t.max),o.length&&(e.dataMin=Math.min(E(e.dataMin,n),n),e.dataMax=Math.max(E(e.dataMax,a),a)));else{let t=i.applyExtremes();A(t.dataMin)&&(n=t.dataMin,e.dataMin=Math.min(E(e.dataMin,n),n)),A(t.dataMax)&&(a=t.dataMax,e.dataMax=Math.max(E(e.dataMax,a),a)),y(r)&&(e.threshold=r),(!s.softThreshold||e.positiveValuesOnly)&&(e.softThreshold=!1)}}})}),M(this,\"afterGetSeriesExtremes\")}translate(t,e,i,s,o,r){let n=this.linkedParent||this,a=s&&n.old?n.old.min:n.min;if(!A(a))return NaN;let h=n.minPixelPadding,l=(n.isOrdinal||n.brokenAxis?.hasBreaks||n.logarithmic&&o)&&n.lin2val,d=1,c=0,p=s&&n.old?n.old.transA:n.transA,u=0;if(p||(p=n.transA),i&&(d*=-1,c=n.len),n.reversed&&(d*=-1,c-=d*(n.sector||n.len)),e)u=(t=t*d+c-h)/p+a,l&&(u=n.lin2val(u));else{l&&(t=n.val2lin(t));let e=d*(t-a)*p;u=(n.isRadial?e:x(e))+c+d*h+(A(r)?p*r:0)}return u}toPixels(t,e){return this.translate(t,!1,!this.horiz,void 0,!0)+(e?0:this.pos)}toValue(t,e){return this.translate(t-(e?0:this.pos),!0,!this.horiz,void 0,!0)}getPlotLinePath(t){let e=this,i=e.chart,s=e.left,o=e.top,r=t.old,n=t.value,a=t.lineWidth,h=r&&i.oldChartHeight||i.chartHeight,l=r&&i.oldChartWidth||i.chartWidth,d=e.transB,c=t.translatedValue,p=t.force,u,g,f,x,y;function b(t,e,i){return\"pass\"!==p&&(ti)&&(p?t=m(t,e,i):y=!0),t}let v={value:n,lineWidth:a,old:r,force:p,acrossPanes:t.acrossPanes,translatedValue:c};return M(this,\"getPlotLinePath\",v,function(t){u=f=Math.round((c=m(c=E(c,e.translate(n,void 0,void 0,r)),-1e5,1e5))+d),g=x=Math.round(h-c-d),A(c)?e.horiz?(g=o,x=h-e.bottom,u=f=b(u,s,s+e.width)):(u=s,f=l-e.right,g=x=b(g,o,o+e.height)):(y=!0,p=!1),t.path=y&&!p?void 0:i.renderer.crispLine([[\"M\",u,g],[\"L\",f,x]],a||1)}),v.path}getLinearTickPositions(t,e,i){let s,o,r;let n=x(Math.floor(e/t)*t),a=x(Math.ceil(i/t)*t),h=[];if(x(n+t)===n&&(r=20),this.single)return[e];for(s=n;s<=a&&(h.push(s),(s=x(s+t,r))!==o);)o=s;return h}getMinorTickInterval(){let{minorTicks:t,minorTickInterval:e}=this.options;return!0===t?E(e,\"auto\"):!1!==t?e:void 0}getMinorTickPositions(){let t=this.options,e=this.tickPositions,i=this.minorTickInterval,s=this.pointRangePadding||0,o=(this.min||0)-s,r=(this.max||0)+s,n=r-o,a=[],h;if(n&&n/i(t.xIncrement?t.xData?.slice(0,2):t.xData)||[]))||0),this.dataMax-this.dataMin)),A(i)&&A(s)&&A(o)&&i-s=o,r=(o-i+s)/2,a=[s-r,E(t.min,s-r)],n&&(a[2]=e?e.log2lin(this.dataMin):this.dataMin),h=[(s=g(a))+o,E(t.max,s+o)],n&&(h[2]=e?e.log2lin(this.dataMax):this.dataMax),(i=f(h))-st-e),t=C([i]))}return t&&e?Math.min(t,e):t||e}nameToX(t){let e=T(this.options.categories),i=e?this.categories:this.names,s=t.options.x,o;return t.series.requireSorting=!1,y(s)||(s=this.options.uniqueNames&&i?e?i.indexOf(t.name):E(i.keys[t.name],-1):t.series.autoIncrement()),-1===s?!e&&i&&(o=i.length):o=s,void 0!==o?(this.names[o]=t.name,this.names.keys[t.name]=o):t.x&&(o=t.x),o}updateNames(){let t=this,e=this.names,i=e.length;i>0&&(Object.keys(e.keys).forEach(function(t){delete e.keys[t]}),e.length=0,this.minRange=this.userMinRange,(this.series||[]).forEach(e=>{e.xIncrement=null,(!e.points||e.isDirtyData)&&(t.max=Math.max(t.max,e.xData.length-1),e.processData(),e.generatePoints()),e.data.forEach(function(i,s){let o;i?.options&&void 0!==i.name&&void 0!==(o=t.nameToX(i))&&o!==i.x&&(i.x=o,e.xData[s]=o)})}))}setAxisTranslation(){let t=this,e=t.max-t.min,i=t.linkedParent,s=!!t.categories,o=t.isXAxis,r=t.axisPointRange||0,n,a=0,h=0,l,d=t.transA;(o||s||r)&&(n=t.getClosest(),i?(a=i.minPointOffset,h=i.pointRangePadding):t.series.forEach(function(e){let i=s?1:o?E(e.options.pointRange,n,0):t.axisPointRange||0,l=e.options.pointPlacement;if(r=Math.max(r,i),!t.single||s){let t=e.is(\"xrange\")?!o:o;a=Math.max(a,t&&P(l)?0:i/2),h=Math.max(h,t&&\"on\"===l?0:i)}}),l=t.ordinal&&t.ordinal.slope&&n?t.ordinal.slope/n:1,t.minPointOffset=a*=l,t.pointRangePadding=h*=l,t.pointRange=Math.min(r,t.single&&s?1:e),o&&n&&(t.closestPointRange=n)),t.translationSlope=t.transA=d=t.staticScale||t.len/(e+h||1),t.transB=t.horiz?t.left:t.bottom,t.minPixelPadding=d*a,M(this,\"afterSetAxisTranslation\")}minFromRange(){let{max:t,min:e}=this;return A(t)&&A(e)&&t-e||void 0}setTickInterval(t){let{categories:e,chart:i,dataMax:s,dataMin:o,dateTime:r,isXAxis:n,logarithmic:a,options:h,softThreshold:l}=this,d=A(this.threshold)?this.threshold:void 0,c=this.minRange||0,{ceiling:p,floor:u,linkedTo:g,softMax:f,softMin:m}=h,b=A(g)&&i[this.coll]?.[g],v=h.tickPixelInterval,k=h.maxPadding,C=h.minPadding,w=0,T,P=A(h.tickInterval)&&h.tickInterval>=0?h.tickInterval:void 0,L,O,D,j;if(r||e||b||this.getTickAmount(),D=E(this.userMin,h.min),j=E(this.userMax,h.max),b?(this.linkedParent=b,T=b.getExtremes(),this.min=E(T.min,T.dataMin),this.max=E(T.max,T.dataMax),h.type!==b.options.type&&S(11,!0,i)):(l&&y(d)&&A(s)&&A(o)&&(o>=d?(L=d,C=0):s<=d&&(O=d,k=0)),this.min=E(D,L,o),this.max=E(j,O,s)),A(this.max)&&A(this.min)&&(a&&(this.positiveValuesOnly&&!t&&0>=Math.min(this.min,E(o,this.min))&&S(10,!0,i),this.min=x(a.log2lin(this.min),16),this.max=x(a.log2lin(this.max),16)),this.range&&A(o)&&(this.userMin=this.min=D=Math.max(o,this.minFromRange()||0),this.userMax=j=this.max,this.range=void 0)),M(this,\"foundExtremes\"),this.adjustForMinRange(),A(this.min)&&A(this.max)){if(!A(this.userMin)&&A(m)&&mthis.max&&(this.max=j=f),e||this.axisPointRange||this.stacking?.usePercentage||b||!(w=this.max-this.min)||(!y(D)&&C&&(this.min-=w*C),y(j)||!k||(this.max+=w*k)),!A(this.userMin)&&A(u)&&(this.min=Math.max(this.min,u)),!A(this.userMax)&&A(p)&&(this.max=Math.min(this.max,p)),l&&A(o)&&A(s)){let t=d||0;!y(D)&&this.min=t?this.min=h.minRange?Math.min(t,this.max-c):t:!y(j)&&this.max>t&&s<=t&&(this.max=h.minRange?Math.max(t,this.min+c):t)}!i.polar&&this.min>this.max&&(y(h.min)?this.max=this.min:y(h.max)&&(this.min=this.max)),w=this.max-this.min}if(this.min!==this.max&&A(this.min)&&A(this.max)?b&&!P&&v===b.options.tickPixelInterval?this.tickInterval=P=b.tickInterval:this.tickInterval=E(P,this.tickAmount?w/Math.max(this.tickAmount-1,1):void 0,e?1:w*v/Math.max(this.len,v)):this.tickInterval=1,n&&!t){let t=this.min!==this.old?.min||this.max!==this.old?.max;this.series.forEach(function(e){e.forceCrop=e.forceCropping?.(),e.processData(t)}),M(this,\"postProcessData\",{hasExtremesChanged:t})}this.setAxisTranslation(),M(this,\"initialAxisTranslation\"),this.pointRange&&!P&&(this.tickInterval=Math.max(this.pointRange,this.tickInterval));let I=E(h.minTickInterval,r&&!this.series.some(t=>t.noSharedTooltip)?this.closestPointRange:0);!P&&this.tickIntervalMath.max(2*this.len,200))h=[this.min,this.max],S(19,!1,this.chart);else if(this.dateTime)h=this.getTimeTicks(this.dateTime.normalizeTimeTickInterval(this.tickInterval,t.units),this.min,this.max,t.startOfWeek,this.ordinal?.positions,this.closestPointRange,!0);else if(this.logarithmic)h=this.logarithmic.getLogTickPositions(this.tickInterval,this.min,this.max);else{let t=this.tickInterval,e=t;for(;e<=2*t;)if(h=this.getLinearTickPositions(this.tickInterval,this.min,this.max),this.tickAmount&&h.length>this.tickAmount)this.tickInterval=z(this,e*=1.1);else break}h.length>this.len&&(h=[h[0],h[h.length-1]])[0]===h[1]&&(h.length=1),i&&(this.tickPositions=h,(l=i.apply(this,[this.min,this.max]))&&(h=l))}this.tickPositions=h,this.paddedTicks=h.slice(0),this.trimTicks(h,n,a),!this.isLinked&&A(this.min)&&A(this.max)&&(this.single&&h.length<2&&!this.categories&&!this.series.some(t=>t.is(\"heatmap\")&&\"between\"===t.options.pointPlacement)&&(this.min-=.5,this.max+=.5),e||l||this.adjustTickAmount()),M(this,\"afterSetTickPositions\")}trimTicks(t,e,i){let s=t[0],o=t[t.length-1],r=!this.isOrdinal&&this.minPointOffset||0;if(M(this,\"trimTicks\"),!this.isLinked){if(e&&s!==-1/0)this.min=s;else for(;this.min-r>t[0];)t.shift();if(i)this.max=o;else for(;this.max+r{let{horiz:e,options:i}=t;return[e?i.left:i.top,i.width,i.height,i.pane].join(\",\")},o=s(this);this.chart[this.coll].forEach(function(r){let{series:n}=r;n.length&&n.some(t=>t.visible)&&r!==e&&s(r)===o&&(t=!0,i.push(r))})}if(t&&r){i.forEach(t=>{let i=t.getThresholdAlignment(e);A(i)&&n.push(i)});let t=n.length>1?n.reduce((t,e)=>t+=e,0)/n.length:void 0;i.forEach(e=>{e.thresholdAlignment=t})}return t}getThresholdAlignment(t){if((!A(this.dataMin)||this!==t&&this.series.some(t=>t.isDirty||t.isDirtyData))&&this.getSeriesExtremes(),A(this.threshold)){let t=m((this.threshold-(this.dataMin||0))/((this.dataMax||0)-(this.dataMin||0)),0,1);return this.options.reversed&&(t=1-t),t}}getTickAmount(){let t=this.options,e=t.tickPixelInterval,i=t.tickAmount;y(t.tickInterval)||i||!(this.lenr.push(x(r[r.length-1]+p)),f=()=>r.unshift(x(r[0]-p));if(A(a)&&(u=a<.5?Math.ceil(a*(n-1)):Math.floor(a*(n-1)),o.reversed&&(u=n-1-u)),t.hasData()&&A(s)&&A(i)){let a=()=>{t.transA*=(h-1)/(n-1),t.min=o.startOnTick?r[0]:Math.min(s,r[0]),t.max=o.endOnTick?r[r.length-1]:Math.max(i,r[r.length-1])};if(A(u)&&A(t.threshold)){for(;r[u]!==l||r.length!==n||r[0]>s||r[r.length-1]t.threshold?f():g();if(p>8*t.tickInterval)break;p*=2}a()}else if(h0&&c{i=i||t.isDirtyData||t.isDirty,s=s||t.xAxis&&t.xAxis.isDirty||!1}),this.setAxisSize();let o=this.len!==(this.old&&this.old.len);o||i||s||this.isLinked||this.forceRedraw||this.userMin!==(this.old&&this.old.userMin)||this.userMax!==(this.old&&this.old.userMax)||this.alignToOthers()?(e&&\"yAxis\"===t&&e.buildStacks(),this.forceRedraw=!1,this.userMinRange||(this.minRange=void 0),this.getSeriesExtremes(),this.setTickInterval(),e&&\"xAxis\"===t&&e.buildStacks(),this.isDirty||(this.isDirty=o||this.min!==this.old?.min||this.max!==this.old?.max)):e&&e.cleanStacks(),i&&this.panningState&&(this.panningState.isDirty=!0),M(this,\"afterSetScale\")}setExtremes(t,e,i=!0,s,o){let r=this,n=r.chart;r.series.forEach(t=>{delete t.kdTree}),M(r,\"setExtremes\",o=k(o,{min:t,max:e}),()=>{r.userMin=t,r.userMax=e,r.eventArgs=o,i&&n.redraw(s)})}zoom(t,e){let i=this,s=this.dataMin,o=this.dataMax,r=this.options,n=Math.min(s,E(r.min,s)),a=Math.max(o,E(r.max,o)),h={newMin:t,newMax:e};return M(this,\"zoom\",h,function(t){let e=t.newMin,r=t.newMax;(e!==i.min||r!==i.max)&&(!i.allowZoomOutside&&(y(s)&&(ea&&(e=a)),y(o)&&(ra&&(r=a))),i.displayBtn=void 0!==e||void 0!==r,i.setExtremes(e,r,!1,void 0,{trigger:\"zoom\"})),t.zoomed=!0}),h.zoomed}setAxisSize(){let t=this.chart,e=this.options,i=e.offsets||[0,0,0,0],s=this.horiz,o=this.width=Math.round(j(E(e.width,t.plotWidth-i[3]+i[1]),t.plotWidth)),r=this.height=Math.round(j(E(e.height,t.plotHeight-i[0]+i[2]),t.plotHeight)),n=this.top=Math.round(j(E(e.top,t.plotTop+i[0]),t.plotHeight,t.plotTop)),a=this.left=Math.round(j(E(e.left,t.plotLeft+i[3]),t.plotWidth,t.plotLeft));this.bottom=t.chartHeight-r-n,this.right=t.chartWidth-o-a,this.len=Math.max(s?o:r,0),this.pos=s?a:n}getExtremes(){let t=this.logarithmic;return{min:t?x(t.lin2log(this.min)):this.min,max:t?x(t.lin2log(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}}getThreshold(t){let e=this.logarithmic,i=e?e.lin2log(this.min):this.min,s=e?e.lin2log(this.max):this.max;return null===t||t===-1/0?t=i:t===1/0?t=s:i>t?t=i:s15&&e<165?t.align=\"right\":e>195&&e<345&&(t.align=\"left\")}),i.align}tickSize(t){let e=this.options,i=E(e[\"tick\"===t?\"tickWidth\":\"minorTickWidth\"],\"tick\"===t&&this.isXAxis&&!this.categories?1:0),s=e[\"tick\"===t?\"tickLength\":\"minorTickLength\"],o;i&&s&&(\"inside\"===e[t+\"Position\"]&&(s=-s),o=[s,i]);let r={tickSize:o};return M(this,\"afterTickSize\",r),r.tickSize}labelMetrics(){let t=this.chart.renderer,e=this.ticks,i=e[Object.keys(e)[0]]||{};return this.chart.renderer.fontMetrics(i.label||i.movedLabel||t.box)}unsquish(){let t=this.options.labels,e=this.horiz,i=this.tickInterval,s=this.len/(((this.categories?1:0)+this.max-this.min)/i),o=t.rotation,r=this.labelMetrics().h,n=Math.max(this.max-this.min,0),a=function(t){let e=t/(s||1);return(e=e>1?Math.ceil(e):1)*i>n&&t!==1/0&&s!==1/0&&n&&(e=Math.ceil(n/i)),x(e*i)},h=i,l,d=Number.MAX_VALUE,c;if(e){if(!t.staggerLines&&(A(o)?c=[o]:s=-90&&i<=90)&&(e=(t=a(Math.abs(r/Math.sin(u*i))))+Math.abs(i/360))g&&(g=e.label.textPxLength)}),this.maxLabelLength=g,this.autoRotation)g>h&&g>d.h?l.rotation=this.labelRotation:this.labelRotation=0;else if(a&&(p=h,!c))for(u=\"clip\",m=i.length;!n&&m--;)(f=s[i[m]].label)&&(f.styles&&\"ellipsis\"===f.styles.textOverflow?f.css({textOverflow:\"clip\"}):f.textPxLength>a&&f.css({width:a+\"px\"}),f.getBBox().height>this.len/i.length-(d.h-d.f)&&(f.specificTextOverflow=\"ellipsis\"));l.rotation&&(p=g>.5*t.chartHeight?.33*t.chartHeight:g,c||(u=\"ellipsis\")),this.labelAlign=o.align||this.autoLabelAlign(this.labelRotation),this.labelAlign&&(l.align=this.labelAlign),i.forEach(function(t){let e=s[t],i=e&&e.label,o=r.width,n={};i&&(i.attr(l),e.shortenLabel?e.shortenLabel():p&&!o&&\"nowrap\"!==r.whiteSpace&&(po.g(e).attr({zIndex:n}).addClass(`highcharts-${i.toLowerCase()}${r} `+(this.isRadial?`highcharts-radial-axis${r} `:\"\")+(s.className||\"\")).add(t);this.axisGroup||(this.gridGroup=r(\"grid\",\"-grid\",s.gridZIndex),this.axisGroup=r(\"axis\",\"\",s.zIndex),this.labelGroup=r(\"axis-labels\",\"-labels\",s.labels.zIndex))}getOffset(){let t=this,{chart:e,horiz:i,options:s,side:o,ticks:r,tickPositions:n,coll:a}=t,h=e.inverted&&!t.isZAxis?[1,0,3,2][o]:o,l=t.hasData(),d=s.title,c=s.labels,p=A(s.crossing),u=e.axisOffset,g=e.clipOffset,f=[-1,1,1,-1][o],m,x=0,b,v=0,S=0,k,C;if(t.showAxis=m=l||s.showEmpty,t.staggerLines=t.horiz&&c.staggerLines||void 0,t.createGroups(),l||t.isLinked?(n.forEach(function(e){t.generateTick(e)}),t.renderUnsquish(),t.reserveSpaceDefault=0===o||2===o||({1:\"left\",3:\"right\"})[o]===t.labelAlign,E(c.reserveSpace,!p&&null,\"center\"===t.labelAlign||null,t.reserveSpaceDefault)&&n.forEach(function(t){S=Math.max(r[t].getLabelSize(),S)}),t.staggerLines&&(S*=t.staggerLines),t.labelOffset=S*(t.opposite?-1:1)):D(r,function(t,e){t.destroy(),delete r[e]}),d?.text&&!1!==d.enabled&&(t.addTitle(m),m&&!p&&!1!==d.reserveSpace&&(t.titleOffset=x=t.axisTitle.getBBox()[i?\"height\":\"width\"],v=y(b=d.offset)?0:E(d.margin,i?5:10))),t.renderLine(),t.offset=f*E(s.offset,u[o]?u[o]+(s.margin||0):0),t.tickRotCorr=t.tickRotCorr||{x:0,y:0},C=0===o?-t.labelMetrics().h:2===o?t.tickRotCorr.y:0,k=Math.abs(S)+v,S&&(k-=C,k+=f*(i?E(c.y,t.tickRotCorr.y+f*c.distance):E(c.x,f*c.distance))),t.axisTitleMargin=E(b,k),t.getMaxLabelDimensions&&(t.maxLabelDimensions=t.getMaxLabelDimensions(r,n)),\"colorAxis\"!==a){let e=this.tickSize(\"tick\");u[o]=Math.max(u[o],(t.axisTitleMargin||0)+x+f*t.offset,k,n&&n.length&&e?e[0]+f*t.offset:0);let i=!t.axisLine||s.offset?0:2*Math.floor(t.axisLine.strokeWidth()/2);g[h]=Math.max(g[h],i)}M(this,\"afterGetOffset\")}getLinePath(t){let e=this.chart,i=this.opposite,s=this.offset,o=this.horiz,r=this.left+(i?this.width:0)+s,n=e.chartHeight-this.bottom-(i?this.height:0)+s;return i&&(t*=-1),e.renderer.crispLine([[\"M\",o?this.left:r,o?n:this.top],[\"L\",o?e.chartWidth-this.right:r,o?n:e.chartHeight-this.bottom]],t)}renderLine(){this.axisLine||(this.axisLine=this.chart.renderer.path().addClass(\"highcharts-axis-line\").add(this.axisGroup),this.chart.styledMode||this.axisLine.attr({stroke:this.options.lineColor,\"stroke-width\":this.options.lineWidth,zIndex:7}))}getTitlePosition(t){let e=this.horiz,i=this.left,s=this.top,o=this.len,r=this.options.title,n=e?i:s,a=this.opposite,h=this.offset,l=r.x,d=r.y,c=this.chart.renderer.fontMetrics(t),p=t?Math.max(t.getBBox(!1,0).height-c.h-1,0):0,u={low:n+(e?0:o),middle:n+o/2,high:n+(e?o:0)}[r.align],g=(e?s+this.height:i)+(e?1:-1)*(a?-1:1)*(this.axisTitleMargin||0)+[-p,p,c.f,-p][this.side],f={x:e?u+l:g+(a?this.width:0)+h+l,y:e?g+d-(a?this.height:0)+h:u+d};return M(this,\"afterGetTitlePosition\",{titlePosition:f}),f}renderMinorTick(t,e){let i=this.minorTicks;i[t]||(i[t]=new n(this,t,\"minor\")),e&&i[t].isNew&&i[t].render(null,!0),i[t].render(null,!1,1)}renderTick(t,e,i){let s=this.isLinked,o=this.ticks;(!s||t>=this.min&&t<=this.max||this.grid&&this.grid.isColumn)&&(o[t]||(o[t]=new n(this,t)),i&&o[t].isNew&&o[t].render(e,!0,-1),o[t].render(e))}render(){let t,e;let i=this,s=i.chart,o=i.logarithmic,a=s.renderer,l=i.options,d=i.isLinked,c=i.tickPositions,p=i.axisTitle,u=i.ticks,g=i.minorTicks,f=i.alternateBands,m=l.stackLabels,x=l.alternateGridColor,y=l.crossing,b=i.tickmarkOffset,v=i.axisLine,S=i.showAxis,k=h(a.globalAnimation);if(i.labelEdge.length=0,i.overlap=!1,[u,g,f].forEach(function(t){D(t,function(t){t.isActive=!1})}),A(y)){let t=this.isXAxis?s.yAxis[0]:s.xAxis[0],e=[1,-1,-1,1][this.side];if(t){let s=t.toPixels(y,!0);i.horiz&&(s=t.len-s),i.offset=e*s}}if(i.hasData()||d){let a=i.chart.hasRendered&&i.old&&A(i.old.min);i.minorTickInterval&&!i.categories&&i.getMinorTickPositions().forEach(function(t){i.renderMinorTick(t,a)}),c.length&&(c.forEach(function(t,e){i.renderTick(t,e,a)}),b&&(0===i.min||i.single)&&(u[-1]||(u[-1]=new n(i,-1,null,!0)),u[-1].render(-1))),x&&c.forEach(function(n,a){e=void 0!==c[a+1]?c[a+1]+b:i.max-b,a%2==0&&n=.5)t=Math.round(t),l=o.getLinearTickPositions(t,e,i);else if(t>=.08){let o,r,n,a,h,d,c;let p=Math.floor(e);for(o=t>.3?[1,2,4]:t>.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9],r=p;re&&(!s||d<=i)&&void 0!==d&&l.push(d),d>i&&(c=!0),d=h}else{let d=this.lin2log(e),c=this.lin2log(i),p=s?o.getMinorTickInterval():h.tickInterval,u=\"auto\"===p?null:p,g=h.tickPixelInterval/(s?5:1),f=s?a/o.tickPositions.length:a;t=r(t=n(u,this.minorAutoInterval,(c-d)*g/(f||1))),l=o.getLinearTickPositions(t,d,c).map(this.log2lin),s||(this.minorAutoInterval=t/5)}return s||(o.tickInterval=t),l}lin2log(t){return Math.pow(10,t)}log2lin(t){return Math.log(t)/Math.LN10}}t.Additions=h}(i||(i={})),i}),i(e,\"Core/Axis/PlotLineOrBand/PlotLineOrBandAxis.js\",[e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e){var i;let{composed:s}=t,{erase:o,extend:r,isNumber:n,pushUnique:a}=e;return function(t){let e;function i(t){return this.addPlotBandOrLine(t,\"plotBands\")}function h(t,i){let s=this.userOptions,o=new e(this,t);if(this.visible&&(o=o.render()),o){if(this._addedPlotLB||(this._addedPlotLB=!0,(s.plotLines||[]).concat(s.plotBands||[]).forEach(t=>{this.addPlotBandOrLine(t)})),i){let e=s[i]||[];e.push(t),s[i]=e}this.plotLinesAndBands.push(o)}return o}function l(t){return this.addPlotBandOrLine(t,\"plotLines\")}function d(t,e,i){i=i||this.options;let s=this.getPlotLinePath({value:e,force:!0,acrossPanes:i.acrossPanes}),o=[],r=this.horiz,a=!n(this.min)||!n(this.max)||tthis.max&&e>this.max,h=this.getPlotLinePath({value:t,force:!0,acrossPanes:i.acrossPanes}),l,d=1,c;if(h&&s)for(a&&(c=h.toString()===s.toString(),d=0),l=0;l{v?.on(e,function(t){n[e].apply(this,[t])})}),this.eventsAdded=!0),(w||!v.d)&&S?.length?v.attr({d:S}):v&&(S?(v.show(),v.animate({d:S})):v.d&&(v.hide(),b&&(this.label=b=b.destroy()))),y&&(o(y.text)||o(y.formatter))&&S?.length&&t.width>0&&t.height>0&&!S.isFlat?(y=h({align:i&&M&&\"center\",x:i?!M&&4:10,verticalAlign:!i&&M&&\"middle\",y:i?M?16:10:M?6:-4,rotation:i&&!M&&90},y),this.renderLabel(y,S,M,c)):b&&b.hide(),this}renderLabel(t,e,o,r){let n=this.axis,a=n.chart.renderer,l=this.label;l||(this.label=l=a.text(this.getLabelText(t),0,0,t.useHTML).attr({align:t.textAlign||t.align,rotation:t.rotation,class:\"highcharts-plot-\"+(o?\"band\":\"line\")+\"-label\"+(t.className||\"\"),zIndex:r}),n.chart.styledMode||l.css(h({fontSize:\"0.8em\",textOverflow:\"ellipsis\"},t.style)),l.add());let d=e.xBounds||[e[0][1],e[1][1],o?e[2][1]:e[0][1]],c=e.yBounds||[e[0][2],e[1][2],o?e[2][2]:e[0][2]],p=s(d),u=s(c);if(l.align(t,!1,{x:p,y:u,width:i(d)-p,height:i(c)-u}),!l.alignValue||\"left\"===l.alignValue){let e=t.clip?n.width:n.chart.chartWidth;l.css({width:(90===l.rotation?n.height-(l.alignAttr.y-n.top):e-(l.alignAttr.x-n.left))+\"px\"})}l.show(!0)}getLabelText(t){return o(t.formatter)?t.formatter.call(this):t.text}destroy(){n(this.axis.plotLinesAndBands,this),delete this.axis,r(this)}}return c}),i(e,\"Core/Tooltip.js\",[e[\"Core/Templating.js\"],e[\"Core/Globals.js\"],e[\"Core/Renderer/RendererUtilities.js\"],e[\"Core/Renderer/RendererRegistry.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o){var r;let{format:n}=t,{composed:a,doc:h,isSafari:l}=e,{distribute:d}=i,{addEvent:c,clamp:p,css:u,discardElement:g,extend:f,fireEvent:m,isArray:x,isNumber:y,isString:b,merge:v,pick:S,pushUnique:k,splat:M,syncTimeout:C}=o;class w{constructor(t,e){this.allowShared=!0,this.crosshairs=[],this.distance=0,this.isHidden=!0,this.isSticky=!1,this.now={},this.options={},this.outside=!1,this.chart=t,this.init(t,e)}bodyFormatter(t){return t.map(function(t){let e=t.series.tooltipOptions;return(e[(t.point.formatPrefix||\"point\")+\"Formatter\"]||t.point.tooltipFormatter).call(t.point,e[(t.point.formatPrefix||\"point\")+\"Format\"]||\"\")})}cleanSplit(t){this.chart.series.forEach(function(e){let i=e&&e.tt;i&&(!i.isActive||t?e.tt=i.destroy():i.isActive=!1)})}defaultFormatter(t){let e;let i=this.points||M(this);return(e=(e=[t.tooltipFooterHeaderFormatter(i[0])]).concat(t.bodyFormatter(i))).push(t.tooltipFooterHeaderFormatter(i[0],!0)),e}destroy(){this.label&&(this.label=this.label.destroy()),this.split&&(this.cleanSplit(!0),this.tt&&(this.tt=this.tt.destroy())),this.renderer&&(this.renderer=this.renderer.destroy(),g(this.container)),o.clearTimeout(this.hideTimer),o.clearTimeout(this.tooltipTimeout)}getAnchor(t,e){let i;let s=this.chart,o=s.pointer,r=s.inverted,n=s.plotTop,a=s.plotLeft;if((t=M(t))[0].series&&t[0].series.yAxis&&!t[0].series.yAxis.options.reversedStacks&&(t=t.slice().reverse()),this.followPointer&&e)void 0===e.chartX&&(e=o.normalize(e)),i=[e.chartX-a,e.chartY-n];else if(t[0].tooltipPos)i=t[0].tooltipPos;else{let s=0,o=0;t.forEach(function(t){let e=t.pos(!0);e&&(s+=e[0],o+=e[1])}),s/=t.length,o/=t.length,this.shared&&t.length>1&&e&&(r?s=e.chartX:o=e.chartY),i=[s-a,o-n]}return i.map(Math.round)}getClassName(t,e,i){let s=this.options,o=t.series,r=o.options;return[s.className,\"highcharts-label\",i&&\"highcharts-tooltip-header\",e?\"highcharts-tooltip-box\":\"highcharts-tooltip\",!i&&\"highcharts-color-\"+S(t.colorIndex,o.colorIndex),r&&r.className].filter(b).join(\" \")}getLabel(){let t=this,i=this.chart.styledMode,o=this.options,r=this.split&&this.allowShared,n=this.container,a=this.chart.renderer;if(this.label){let t=!this.label.hasClass(\"highcharts-label\");(!r&&t||r&&!t)&&this.destroy()}if(!this.label){if(this.outside){let t=this.chart.options.chart.style,i=s.getRendererType();this.container=n=e.doc.createElement(\"div\"),n.className=\"highcharts-tooltip-container\",u(n,{position:\"absolute\",top:\"1px\",pointerEvents:\"none\",zIndex:Math.max(this.options.style.zIndex||0,(t&&t.zIndex||0)+3)}),this.renderer=a=new i(n,0,0,t,void 0,void 0,a.styledMode)}if(r?this.label=a.g(\"tooltip\"):(this.label=a.label(\"\",0,0,o.shape,void 0,void 0,o.useHTML,void 0,\"tooltip\").attr({padding:o.padding,r:o.borderRadius}),i||this.label.attr({fill:o.backgroundColor,\"stroke-width\":o.borderWidth||0}).css(o.style).css({pointerEvents:o.style.pointerEvents||(this.shouldStickOnContact()?\"auto\":\"none\")})),t.outside){let e=this.label,{xSetter:i,ySetter:s}=e;e.xSetter=function(s){i.call(e,t.distance),n&&(n.style.left=s+\"px\")},e.ySetter=function(i){s.call(e,t.distance),n&&(n.style.top=i+\"px\")}}this.label.attr({zIndex:8}).shadow(o.shadow).add()}return n&&!n.parentElement&&e.doc.body.appendChild(n),this.label}getPlayingField(){let{body:t,documentElement:e}=h,{chart:i,distance:s,outside:o}=this;return{width:o?Math.max(t.scrollWidth,e.scrollWidth,t.offsetWidth,e.offsetWidth,e.clientWidth)-2*s:i.chartWidth,height:o?Math.max(t.scrollHeight,e.scrollHeight,t.offsetHeight,e.offsetHeight,e.clientHeight):i.chartHeight}}getPosition(t,e,i){let{distance:s,chart:o,outside:r}=this,{inverted:n,plotLeft:a,plotTop:h,polar:l}=o,{plotX:d=0,plotY:c=0}=i,p={},u=n&&i.h||0,{height:g,width:f}=this.getPlayingField(),m=o.pointer.getChartPosition(),x=t=>t*m.scaleX,y=t=>t*m.scaleY,b=i=>{let n=\"x\"===i;return[i,n?f:g,n?t:e].concat(r?[n?x(t):y(e),n?m.left-s+x(d+a):m.top-s+y(c+h),0,n?f:g]:[n?t:e,n?d+a:c+h,n?a:h,n?a+o.plotWidth:h+o.plotHeight])},v=b(\"y\"),k=b(\"x\"),M,C=!!i.negative;!l&&o.hoverSeries?.yAxis?.reversed&&(C=!C);let w=!this.followPointer&&S(i.ttBelow,!l&&!n===C),T=function(t,e,i,o,n,a,h){let l=r?\"y\"===t?y(s):x(s):s,d=(i-o)/2,c=oe?m:m+u)}},A=function(t,e,i,o,r){if(re-s)return!1;re-o/2?p[t]=e-o-2:p[t]=r-i/2},P=function(t){[v,k]=[k,v],M=t},L=()=>{!1!==T.apply(0,v)?!1!==A.apply(0,k)||M||(P(!0),L()):M?p.x=p.y=0:(P(!0),L())};return(n&&!l||this.len>1)&&P(),L(),p}hide(t){let e=this;o.clearTimeout(this.hideTimer),t=S(t,this.options.hideDelay),this.isHidden||(this.hideTimer=C(function(){let i=e.getLabel();e.getLabel().animate({opacity:0},{duration:t?150:t,complete:()=>{i.hide(),e.container&&e.container.remove()}}),e.isHidden=!0},t))}init(t,e){this.chart=t,this.options=e,this.crosshairs=[],this.now={x:0,y:0},this.isHidden=!0,this.split=e.split&&!t.inverted&&!t.polar,this.shared=e.shared||this.split,this.outside=S(e.outside,!!(t.scrollablePixelsX||t.scrollablePixelsY))}shouldStickOnContact(t){return!!(!this.followPointer&&this.options.stickOnContact&&(!t||this.chart.pointer.inClass(t.target,\"highcharts-tooltip\")))}move(t,e,i,s){let r=this,n=r.now,a=!1!==r.options.animation&&!r.isHidden&&(Math.abs(t-n.x)>1||Math.abs(e-n.y)>1),h=r.followPointer||r.len>1;f(n,{x:a?(2*n.x+t)/3:t,y:a?(n.y+e)/2:e,anchorX:h?void 0:a?(2*n.anchorX+i)/3:i,anchorY:h?void 0:a?(n.anchorY+s)/2:s}),r.getLabel().attr(n),r.drawTracker(),a&&(o.clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){r&&r.move(t,e,i,s)},32))}refresh(t,e){let i=this.chart,s=this.options,r=i.pointer,a=M(t),h=a[0],l=[],d=s.format,c=s.formatter||this.defaultFormatter,p=this.shared,u=i.styledMode,g={};if(!s.enabled||!h.series)return;o.clearTimeout(this.hideTimer),this.allowShared=!(!x(t)&&t.series&&t.series.noSharedTooltip),this.followPointer=!this.split&&h.series.tooltipOptions.followPointer;let f=this.getAnchor(t,e),y=f[0],v=f[1];p&&this.allowShared?(r.applyInactiveState(a),a.forEach(function(t){t.setState(\"hover\"),l.push(t.getLabelConfig())}),(g=h.getLabelConfig()).points=l):g=h.getLabelConfig(),this.len=l.length;let k=b(d)?n(d,g,i):c.call(g,this),C=h.series;if(this.distance=S(C.tooltipOptions.distance,16),!1===k)this.hide();else{if(this.split&&this.allowShared)this.renderSplit(k,a);else{let t=y,o=v;if(e&&r.isDirectTouch&&(t=e.chartX-i.plotLeft,o=e.chartY-i.plotTop),i.polar||!1===C.options.clip||a.some(e=>r.isDirectTouch||e.series.shouldShowTooltip(t,o))){let t=this.getLabel();(!s.style.width||u)&&t.css({width:(this.outside?this.getPlayingField():i.spacingBox).width+\"px\"}),t.attr({text:k&&k.join?k.join(\"\"):k}),t.addClass(this.getClassName(h),!0),u||t.attr({stroke:s.borderColor||h.color||C.color||\"#666666\"}),this.updatePosition({plotX:y,plotY:v,negative:h.negative,ttBelow:h.ttBelow,h:f[2]||0})}else{this.hide();return}}this.isHidden&&this.label&&this.label.attr({opacity:1}).show(),this.isHidden=!1}m(this,\"refresh\")}renderSplit(t,e){let i=this,{chart:s,chart:{chartWidth:o,chartHeight:r,plotHeight:n,plotLeft:a,plotTop:c,pointer:u,scrollablePixelsY:g=0,scrollablePixelsX:m,scrollingContainer:{scrollLeft:x,scrollTop:y}={scrollLeft:0,scrollTop:0},styledMode:v},distance:k,options:M,options:{positioner:C}}=i,w=i.outside&&\"number\"!=typeof m?h.documentElement.getBoundingClientRect():{left:x,right:x+o,top:y,bottom:y+r},T=i.getLabel(),A=this.renderer||s.renderer,P=!!(s.xAxis[0]&&s.xAxis[0].opposite),{left:L,top:O}=u.getChartPosition(),D=c+y,E=0,j=n-g;function I(t,e,s,o,r=!0){let n,a;return s?(n=P?0:j,a=p(t-o/2,w.left,w.right-o-(i.outside?L:0))):(n=e-D,a=p(a=r?t-o-k:t+k,r?a:w.left,w.right)),{x:a,y:n}}b(t)&&(t=[!1,t]);let B=t.slice(0,e.length+1).reduce(function(t,s,o){if(!1!==s&&\"\"!==s){let r=e[o-1]||{isHeader:!0,plotX:e[0].plotX,plotY:n,series:{}},h=r.isHeader,l=h?i:r.series,d=l.tt=function(t,e,s){let o=t,{isHeader:r,series:n}=e;if(!o){let t={padding:M.padding,r:M.borderRadius};v||(t.fill=M.backgroundColor,t[\"stroke-width\"]=M.borderWidth??1),o=A.label(\"\",0,0,M[r?\"headerShape\":\"shape\"],void 0,void 0,M.useHTML).addClass(i.getClassName(e,!0,r)).attr(t).add(T)}return o.isActive=!0,o.attr({text:s}),v||o.css(M.style).attr({stroke:M.borderColor||e.color||n.color||\"#333333\"}),o}(l.tt,r,s.toString()),u=d.getBBox(),g=u.width+d.strokeWidth();h&&(E=u.height,j+=E,P&&(D-=E));let{anchorX:f,anchorY:m}=function(t){let e,i;let{isHeader:s,plotX:o=0,plotY:r=0,series:h}=t;if(s)e=Math.max(a+o,a),i=c+n/2;else{let{xAxis:t,yAxis:s}=h;e=t.pos+p(o,-k,t.len+k),h.shouldShowTooltip(0,s.pos-c+r,{ignoreX:!0})&&(i=s.pos+r)}return{anchorX:e=p(e,w.left-k,w.right+k),anchorY:i}}(r);if(\"number\"==typeof m){let e=u.height+1,s=C?C.call(i,g,e,r):I(f,m,h,g);t.push({align:C?0:void 0,anchorX:f,anchorY:m,boxWidth:g,point:r,rank:S(s.rank,h?1:0),size:e,target:s.y,tt:d,x:s.x})}else d.isActive=!1}return t},[]);!C&&B.some(t=>{let{outside:e}=i,s=(e?L:0)+t.anchorX;return ss})&&(B=B.map(t=>{let{x:e,y:i}=I(t.anchorX,t.anchorY,t.point.isHeader,t.boxWidth,!1);return f(t,{target:i,x:e})})),i.cleanSplit(),d(B,j);let R={left:L,right:L};B.forEach(function(t){let{x:e,boxWidth:s,isHeader:o}=t;!o&&(i.outside&&L+eR.right&&(R.right=L+e))}),B.forEach(function(t){let{x:e,anchorX:s,anchorY:o,pos:r,point:{isHeader:n}}=t,a={visibility:void 0===r?\"hidden\":\"inherit\",x:e,y:(r||0)+D,anchorX:s,anchorY:o};if(i.outside&&e0&&(n||(a.x=e+t,a.anchorX=s+t),n&&(a.x=(R.right-R.left)/2,a.anchorX=s+t))}t.tt.attr(a)});let{container:z,outside:N,renderer:W}=i;if(N&&z&&W){let{width:t,height:e,x:i,y:s}=T.getBBox();W.setSize(t+i,e+s,!1),z.style.left=R.left+\"px\",z.style.top=O+\"px\"}l&&T.attr({opacity:1===T.opacity?.999:1})}drawTracker(){if(!this.shouldStickOnContact()){this.tracker&&(this.tracker=this.tracker.destroy());return}let t=this.chart,e=this.label,i=this.shared?t.hoverPoints:t.hoverPoint;if(!e||!i)return;let s={x:0,y:0,width:0,height:0},o=this.getAnchor(i),r=e.getBBox();o[0]+=t.plotLeft-(e.translateX||0),o[1]+=t.plotTop-(e.translateY||0),s.x=Math.min(0,o[0]),s.y=Math.min(0,o[1]),s.width=o[0]<0?Math.max(Math.abs(o[0]),r.width-o[0]):Math.max(Math.abs(o[0]),r.width),s.height=o[1]<0?Math.max(Math.abs(o[1]),r.height-Math.abs(o[1])):Math.max(Math.abs(o[1]),r.height),this.tracker?this.tracker.attr(s):(this.tracker=e.renderer.rect(s).addClass(\"highcharts-tracker\").add(e),t.styledMode||this.tracker.attr({fill:\"rgba(0,0,0,0)\"}))}styledModeFormat(t){return t.replace('style=\"font-size: 0.8em\"','class=\"highcharts-header\"').replace(/style=\"color:{(point|series)\\.color}\"/g,'class=\"highcharts-color-{$1.colorIndex} {series.options.className} {point.options.className}\"')}tooltipFooterHeaderFormatter(t,e){let i=t.series,s=i.tooltipOptions,o=i.xAxis,r=o&&o.dateTime,a={isFooter:e,labelConfig:t},h=s.xDateFormat,l=s[e?\"footerFormat\":\"headerFormat\"];return m(this,\"headerFormatter\",a,function(e){r&&!h&&y(t.key)&&(h=r.getXDateFormat(t.key,s.dateTimeLabelFormats)),r&&h&&(t.point&&t.point.tooltipDateKeys||[\"key\"]).forEach(function(t){l=l.replace(\"{point.\"+t+\"}\",\"{point.\"+t+\":\"+h+\"}\")}),i.chart.styledMode&&(l=this.styledModeFormat(l)),e.text=n(l,{point:t,series:i},this.chart)}),a.text}update(t){this.destroy(),this.init(this.chart,v(!0,this.options,t))}updatePosition(t){let{chart:e,container:i,distance:s,options:o,renderer:r}=this,{height:n=0,width:a=0}=this.getLabel(),h=e.pointer,{left:l,top:d,scaleX:c,scaleY:p}=h.getChartPosition(),g=(o.positioner||this.getPosition).call(this,a,n,t),f=(t.plotX||0)+e.plotLeft,m=(t.plotY||0)+e.plotTop,x;r&&i&&(o.positioner&&(g.x+=l-s,g.y+=d-s),x=(o.borderWidth||0)+2*s+2,r.setSize(a+x,n+x,!1),(1!==c||1!==p)&&(u(i,{transform:`scale(${c}, ${p})`}),f*=c,m*=p),f+=l-g.x,m+=d-g.y),this.move(Math.round(g.x),Math.round(g.y||0),f,m)}}return(r=w||(w={})).compose=function t(e){k(a,t)&&c(e,\"afterInit\",function(){let t=this.chart;t.options.tooltip&&(t.tooltip=new r(t,t.options.tooltip))})},w}),i(e,\"Core/Series/Point.js\",[e[\"Core/Renderer/HTML/AST.js\"],e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Defaults.js\"],e[\"Core/Templating.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o){let{animObject:r}=e,{defaultOptions:n}=i,{format:a}=s,{addEvent:h,defined:l,erase:d,extend:c,fireEvent:p,getNestedProperty:u,isArray:g,isFunction:f,isNumber:m,isObject:x,merge:y,objectEach:b,pick:v,syncTimeout:S,removeEvent:k,uniqueKey:M}=o;class C{animateBeforeDestroy(){let t=this,e={x:t.startXPos,opacity:0},i=t.getGraphicalProps();i.singular.forEach(function(i){t[i]=t[i].animate(\"dataLabel\"===i?{x:t[i].startXPos,y:t[i].startYPos,opacity:0}:e)}),i.plural.forEach(function(e){t[e].forEach(function(e){e.element&&e.animate(c({x:t.startXPos},e.startYPos?{x:e.startXPos,y:e.startYPos}:{}))})})}applyOptions(t,e){let i=this.series,s=i.options.pointValKey||i.pointValKey;return c(this,t=C.prototype.optionsToObject.call(this,t)),this.options=this.options?c(this.options,t):t,t.group&&delete this.group,t.dataLabels&&delete this.dataLabels,s&&(this.y=C.prototype.getNestedProperty.call(this,s)),this.selected&&(this.state=\"select\"),\"name\"in this&&void 0===e&&i.xAxis&&i.xAxis.hasNames&&(this.x=i.xAxis.nameToX(this)),void 0===this.x&&i?void 0===e?this.x=i.autoIncrement():this.x=e:m(t.x)&&i.options.relativeXValue&&(this.x=i.autoIncrement(t.x)),this.isNull=this.isValid&&!this.isValid(),this.formatPrefix=this.isNull?\"null\":\"point\",this}destroy(){if(!this.destroyed){let t=this,e=t.series,i=e.chart,s=e.options.dataSorting,o=i.hoverPoints,n=t.series.chart.renderer.globalAnimation,a=r(n),h=()=>{for(let e in(t.graphic||t.graphics||t.dataLabel||t.dataLabels)&&(k(t),t.destroyElements()),t)delete t[e]};t.legendItem&&i.legend.destroyItem(t),o&&(t.setState(),d(o,t),o.length||(i.hoverPoints=null)),t===i.hoverPoint&&t.onMouseOut(),s&&s.enabled?(this.animateBeforeDestroy(),S(h,a.duration)):h(),i.pointCount--}this.destroyed=!0}destroyElements(t){let e=this,i=e.getGraphicalProps(t);i.singular.forEach(function(t){e[t]=e[t].destroy()}),i.plural.forEach(function(t){e[t].forEach(function(t){t&&t.element&&t.destroy()}),delete e[t]})}firePointEvent(t,e,i){let s=this,o=this.series,r=o.options;(r.point.events[t]||s.options&&s.options.events&&s.options.events[t])&&s.importEvents(),\"click\"===t&&r.allowPointSelect&&(i=function(t){!s.destroyed&&s.select&&s.select(null,t.ctrlKey||t.metaKey||t.shiftKey)}),p(s,t,e,i)}getClassName(){return\"highcharts-point\"+(this.selected?\" highcharts-point-select\":\"\")+(this.negative?\" highcharts-negative\":\"\")+(this.isNull?\" highcharts-null-point\":\"\")+(void 0!==this.colorIndex?\" highcharts-color-\"+this.colorIndex:\"\")+(this.options.className?\" \"+this.options.className:\"\")+(this.zone&&this.zone.className?\" \"+this.zone.className.replace(\"highcharts-negative\",\"\"):\"\")}getGraphicalProps(t){let e,i;let s=this,o=[],r={singular:[],plural:[]};for((t=t||{graphic:1,dataLabel:1}).graphic&&o.push(\"graphic\",\"connector\"),t.dataLabel&&o.push(\"dataLabel\",\"dataLabelPath\",\"dataLabelUpper\"),i=o.length;i--;)s[e=o[i]]&&r.singular.push(e);return[\"graphic\",\"dataLabel\"].forEach(function(e){let i=e+\"s\";t[e]&&s[i]&&r.plural.push(i)}),r}getLabelConfig(){return{x:this.category,y:this.y,color:this.color,colorIndex:this.colorIndex,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}}getNestedProperty(t){return t?0===t.indexOf(\"custom.\")?u(t,this.options):this[t]:void 0}getZone(){let t=this.series,e=t.zones,i=t.zoneAxis||\"y\",s,o=0;for(s=e[0];this[i]>=s.value;)s=e[++o];return this.nonZonedColor||(this.nonZonedColor=this.color),s&&s.color&&!this.options.color?this.color=s.color:this.color=this.nonZonedColor,s}hasNewShapeType(){let t=this.graphic&&(this.graphic.symbolName||this.graphic.element.nodeName);return t!==this.shapeType}constructor(t,e,i){this.formatPrefix=\"point\",this.visible=!0,this.series=t,this.applyOptions(e,i),this.id??(this.id=M()),this.resolveColor(),t.chart.pointCount++,p(this,\"afterInit\")}isValid(){return(m(this.x)||this.x instanceof Date)&&m(this.y)}optionsToObject(t){let e=this.series,i=e.options.keys,s=i||e.pointArrayMap||[\"y\"],o=s.length,r={},n,a=0,h=0;if(m(t)||null===t)r[s[0]]=t;else if(g(t))for(!i&&t.length>o&&(\"string\"==(n=typeof t[0])?r.name=t[0]:\"number\"===n&&(r.x=t[0]),a++);h0?C.prototype.setNestedProperty(r,t[a],s[h]):r[s[h]]=t[a]),a++,h++;else\"object\"==typeof t&&(r=t,t.dataLabels&&(e.hasDataLabels=()=>!0),t.marker&&(e._hasPointMarkers=!0));return r}pos(t,e=this.plotY){if(!this.destroyed){let{plotX:i,series:s}=this,{chart:o,xAxis:r,yAxis:n}=s,a=0,h=0;if(m(i)&&m(e))return t&&(a=r?r.pos:o.plotLeft,h=n?n.pos:o.plotTop),o.inverted&&r&&n?[n.len-e+h,r.len-i+a]:[i+a,e+h]}}resolveColor(){let t=this.series,e=t.chart.options.chart,i=t.chart.styledMode,s,o,r=e.colorCount,n;delete this.nonZonedColor,t.options.colorByPoint?(i||(s=(o=t.options.colors||t.chart.options.colors)[t.colorCounter],r=o.length),n=t.colorCounter,t.colorCounter++,t.colorCounter===r&&(t.colorCounter=0)):(i||(s=t.color),n=t.colorIndex),this.colorIndex=v(this.options.colorIndex,n),this.color=v(this.options.color,s)}setNestedProperty(t,e,i){let s=i.split(\".\");return s.reduce(function(t,i,s,o){let r=o.length-1===s;return t[i]=r?e:x(t[i],!0)?t[i]:{},t[i]},t),t}shouldDraw(){return!this.isNull}tooltipFormatter(t){let e=this.series,i=e.tooltipOptions,s=v(i.valueDecimals,\"\"),o=i.valuePrefix||\"\",r=i.valueSuffix||\"\";return e.chart.styledMode&&(t=e.chart.tooltip.styledModeFormat(t)),(e.pointArrayMap||[\"y\"]).forEach(function(e){e=\"{point.\"+e,(o||r)&&(t=t.replace(RegExp(e+\"}\",\"g\"),o+e+\"}\"+r)),t=t.replace(RegExp(e+\"}\",\"g\"),e+\":,.\"+s+\"f}\")}),a(t,{point:this,series:this.series},e.chart)}update(t,e,i,s){let o;let r=this,n=r.series,a=r.graphic,h=n.chart,l=n.options;function d(){r.applyOptions(t);let s=a&&r.hasMockGraphic,d=null===r.y?!s:s;a&&d&&(r.graphic=a.destroy(),delete r.hasMockGraphic),x(t,!0)&&(a&&a.element&&t&&t.marker&&void 0!==t.marker.symbol&&(r.graphic=a.destroy()),t?.dataLabels&&r.dataLabel&&(r.dataLabel=r.dataLabel.destroy())),o=r.index,n.updateParallelArrays(r,o),l.data[o]=x(l.data[o],!0)||x(t,!0)?r.options:v(t,l.data[o]),n.isDirty=n.isDirtyData=!0,!n.fixedBox&&n.hasCartesianSeries&&(h.isDirtyBox=!0),\"point\"===l.legendType&&(h.isDirtyLegend=!0),e&&h.redraw(i)}e=v(e,!0),!1===s?d():r.firePointEvent(\"update\",{options:t},d)}remove(t,e){this.series.removePoint(this.series.data.indexOf(this),t,e)}select(t,e){let i=this,s=i.series,o=s.chart;t=v(t,!i.selected),this.selectedStaging=t,i.firePointEvent(t?\"select\":\"unselect\",{accumulate:e},function(){i.selected=i.options.selected=t,s.options.data[s.data.indexOf(i)]=i.options,i.setState(t&&\"select\"),e||o.getSelectedPoints().forEach(function(t){let e=t.series;t.selected&&t!==i&&(t.selected=t.options.selected=!1,e.options.data[e.data.indexOf(t)]=t.options,t.setState(o.hoverPoints&&e.options.inactiveOtherPoints?\"inactive\":\"\"),t.firePointEvent(\"unselect\"))})}),delete this.selectedStaging}onMouseOver(t){let e=this.series,i=e.chart,s=i.pointer;t=t?s.normalize(t):s.getChartCoordinatesFromPoint(this,i.inverted),s.runPointActions(t,this)}onMouseOut(){let t=this.series.chart;this.firePointEvent(\"mouseOut\"),this.series.options.inactiveOtherPoints||(t.hoverPoints||[]).forEach(function(t){t.setState()}),t.hoverPoints=t.hoverPoint=null}importEvents(){if(!this.hasImportedEvents){let t=this,e=y(t.series.options.point,t.options),i=e.events;t.events=i,b(i,function(e,i){f(e)&&h(t,i,e)}),this.hasImportedEvents=!0}}setState(e,i){let s=this.series,o=this.state,r=s.options.states[e||\"normal\"]||{},a=n.plotOptions[s.type].marker&&s.options.marker,h=a&&!1===a.enabled,l=a&&a.states&&a.states[e||\"normal\"]||{},d=!1===l.enabled,u=this.marker||{},g=s.chart,f=a&&s.markerAttribs,x=s.halo,y,b,S,k=s.stateMarkerGraphic,M;if((e=e||\"\")===this.state&&!i||this.selected&&\"select\"!==e||!1===r.enabled||e&&(d||h&&!1===l.enabled)||e&&u.states&&u.states[e]&&!1===u.states[e].enabled)return;if(this.state=e,f&&(y=s.markerAttribs(this,e)),this.graphic&&!this.hasMockGraphic){if(o&&this.graphic.removeClass(\"highcharts-point-\"+o),e&&this.graphic.addClass(\"highcharts-point-\"+e),!g.styledMode){b=s.pointAttribs(this,e),S=v(g.options.chart.animation,r.animation);let t=b.opacity;s.options.inactiveOtherPoints&&m(t)&&(this.dataLabels||[]).forEach(function(e){e&&!e.hasClass(\"highcharts-data-label-hidden\")&&(e.animate({opacity:t},S),e.connector&&e.connector.animate({opacity:t},S))}),this.graphic.animate(b,S)}y&&this.graphic.animate(y,v(g.options.chart.animation,l.animation,a.animation)),k&&k.hide()}else e&&l&&(M=u.symbol||s.symbol,k&&k.currentSymbol!==M&&(k=k.destroy()),y&&(k?k[i?\"animate\":\"attr\"]({x:y.x,y:y.y}):M&&(s.stateMarkerGraphic=k=g.renderer.symbol(M,y.x,y.y,y.width,y.height).add(s.markerGroup),k.currentSymbol=M)),!g.styledMode&&k&&\"inactive\"!==this.state&&k.attr(s.pointAttribs(this,e))),k&&(k[e&&this.isInside?\"show\":\"hide\"](),k.element.point=this,k.addClass(this.getClassName(),!0));let C=r.halo,w=this.graphic||k,T=w&&w.visibility||\"inherit\";C&&C.size&&w&&\"hidden\"!==T&&!this.isCluster?(x||(s.halo=x=g.renderer.path().add(w.parentGroup)),x.show()[i?\"animate\":\"attr\"]({d:this.haloPath(C.size)}),x.attr({class:\"highcharts-halo highcharts-color-\"+v(this.colorIndex,s.colorIndex)+(this.className?\" \"+this.className:\"\"),visibility:T,zIndex:-1}),x.point=this,g.styledMode||x.attr(c({fill:this.color||s.color,\"fill-opacity\":C.opacity},t.filterUserAttributes(C.attributes||{})))):x&&x.point&&x.point.haloPath&&x.animate({d:x.point.haloPath(0)},null,x.hide),p(this,\"afterSetState\",{state:e})}haloPath(t){let e=this.pos();return e?this.series.chart.renderer.symbols.circle(Math.floor(e[0])-t,e[1]-t,2*t,2*t):[]}}return C}),i(e,\"Core/Pointer.js\",[e[\"Core/Color/Color.js\"],e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){var s;let{parse:o}=t,{charts:r,composed:n,noop:a}=e,{addEvent:h,attr:l,css:d,defined:c,extend:p,find:u,fireEvent:g,isNumber:f,isObject:m,objectEach:x,offset:y,pick:b,pushUnique:v,splat:S}=i;class k{applyInactiveState(t){let e=[],i;(t||[]).forEach(function(t){i=t.series,e.push(i),i.linkedParent&&e.push(i.linkedParent),i.linkedSeries&&(e=e.concat(i.linkedSeries)),i.navigatorSeries&&e.push(i.navigatorSeries)}),this.chart.series.forEach(function(t){-1===e.indexOf(t)?t.setState(\"inactive\",!0):t.options.inactiveOtherPoints&&t.setAllPointsToState(\"inactive\")})}destroy(){let t=this;this.eventsToUnbind.forEach(t=>t()),this.eventsToUnbind=[],!e.chartCount&&(k.unbindDocumentMouseUp&&(k.unbindDocumentMouseUp=k.unbindDocumentMouseUp()),k.unbindDocumentTouchEnd&&(k.unbindDocumentTouchEnd=k.unbindDocumentTouchEnd())),clearInterval(t.tooltipTimeout),x(t,function(e,i){t[i]=void 0})}getSelectionMarkerAttrs(t,e){let i={args:{chartX:t,chartY:e},attrs:{},shapeType:\"rect\"};return g(this,\"getSelectionMarkerAttrs\",i,i=>{let s;let{chart:o,mouseDownX:r=0,mouseDownY:n=0,zoomHor:a,zoomVert:h}=this,l=i.attrs;l.x=o.plotLeft,l.y=o.plotTop,l.width=a?1:o.plotWidth,l.height=h?1:o.plotHeight,a&&(s=t-r,l.width=Math.abs(s),l.x=(s>0?0:s)+r),h&&(s=e-n,l.height=Math.abs(s),l.y=(s>0?0:s)+n)}),i}drag(t){let e=this.chart,i=e.options.chart,s=e.plotLeft,r=e.plotTop,n=e.plotWidth,a=e.plotHeight,h=this.mouseDownX||0,l=this.mouseDownY||0,d=m(i.panning)?i.panning&&i.panning.enabled:i.panning,c=i.panKey&&t[i.panKey+\"Key\"],p=t.chartX,u=t.chartY,g,f=this.selectionMarker;if((!f||!f.touch)&&(ps+n&&(p=s+n),ur+a&&(u=r+a),this.hasDragged=Math.sqrt(Math.pow(h-p,2)+Math.pow(l-u,2)),this.hasDragged>10)){g=e.isInsidePlot(h-s,l-r,{visiblePlotOnly:!0});let{shapeType:n,attrs:a}=this.getSelectionMarkerAttrs(p,u);(e.hasCartesianSeries||e.mapView)&&(this.zoomX||this.zoomY)&&g&&!c&&!f&&(this.selectionMarker=f=e.renderer[n](),f.attr({class:\"highcharts-selection-marker\",zIndex:7}).add(),e.styledMode||f.attr({fill:i.selectionMarkerFill||o(\"#334eff\").setOpacity(.25).get()})),f&&f.attr(a),g&&!f&&d&&e.pan(t,i.panning)}}dragStart(t){let e=this.chart;e.mouseIsDown=t.type,e.cancelClick=!1,e.mouseDownX=this.mouseDownX=t.chartX,e.mouseDownY=this.mouseDownY=t.chartY}getSelectionBox(t){let e={args:{marker:t},result:{}};return g(this,\"getSelectionBox\",e,e=>{e.result={x:t.attr?+t.attr(\"x\"):t.x,y:t.attr?+t.attr(\"y\"):t.y,width:t.attr?t.attr(\"width\"):t.width,height:t.attr?t.attr(\"height\"):t.height}}),e.result}drop(t){let e=this,i=this.chart,s=this.hasPinched;if(this.selectionMarker){let{x:o,y:r,width:n,height:a}=this.getSelectionBox(this.selectionMarker),h={originalEvent:t,xAxis:[],yAxis:[],x:o,y:r,width:n,height:a},l=!!i.mapView;(this.hasDragged||s)&&(i.axes.forEach(function(i){if(i.zoomEnabled&&c(i.min)&&(s||e[({xAxis:\"zoomX\",yAxis:\"zoomY\"})[i.coll]])&&f(o)&&f(r)&&f(n)&&f(a)){let e=i.horiz,s=\"touchend\"===t.type?i.minPixelPadding:0,d=i.toValue((e?o:r)+s),c=i.toValue((e?o+n:r+a)-s);h[i.coll].push({axis:i,min:Math.min(d,c),max:Math.max(d,c)}),l=!0}}),l&&g(i,\"selection\",h,function(t){i.zoom(p(t,s?{animation:!1}:null))})),f(i.index)&&(this.selectionMarker=this.selectionMarker.destroy()),s&&this.scaleGroups()}i&&f(i.index)&&(d(i.container,{cursor:i._cursor}),i.cancelClick=+this.hasDragged>10,i.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[])}findNearestKDPoint(t,e,i){let s;return t.forEach(function(t){let o=t.noSharedTooltip&&e,r=!o&&0>t.options.findNearestPointBy.indexOf(\"y\"),n=t.searchPoint(i,r);m(n,!0)&&n.series&&(!m(s,!0)||function(t,i){let s=t.distX-i.distX,o=t.dist-i.dist,r=(i.series.group&&i.series.group.zIndex)-(t.series.group&&t.series.group.zIndex);return 0!==s&&e?s:0!==o?o:0!==r?r:t.series.index>i.series.index?-1:1}(s,n)>0)&&(s=n)}),s}getChartCoordinatesFromPoint(t,e){let i=t.series,s=i.xAxis,o=i.yAxis,r=t.shapeArgs;if(s&&o){let i=b(t.clientX,t.plotX),n=t.plotY||0;return t.isNode&&r&&f(r.x)&&f(r.y)&&(i=r.x,n=r.y),e?{chartX:o.len+o.pos-n,chartY:s.len+s.pos-i}:{chartX:i+s.pos,chartY:n+o.pos}}if(r&&r.x&&r.y)return{chartX:r.x,chartY:r.y}}getChartPosition(){if(this.chartPosition)return this.chartPosition;let{container:t}=this.chart,e=y(t);this.chartPosition={left:e.left,top:e.top,scaleX:1,scaleY:1};let i=t.offsetWidth,s=t.offsetHeight;return i>2&&s>2&&(this.chartPosition.scaleX=e.width/i,this.chartPosition.scaleY=e.height/s),this.chartPosition}getCoordinates(t){let e={xAxis:[],yAxis:[]};return this.chart.axes.forEach(function(i){e[i.isXAxis?\"xAxis\":\"yAxis\"].push({axis:i,value:i.toValue(t[i.horiz?\"chartX\":\"chartY\"])})}),e}getHoverData(t,e,i,s,o,r){let n=[],a=function(t){return t.visible&&!(!o&&t.directTouch)&&b(t.options.enableMouseTracking,!0)},h=e,l,d={chartX:r?r.chartX:void 0,chartY:r?r.chartY:void 0,shared:o};g(this,\"beforeGetHoverData\",d);let c=h&&!h.stickyTracking;l=c?[h]:i.filter(t=>t.stickyTracking&&(d.filter||a)(t));let p=s&&t||!r?t:this.findNearestKDPoint(l,o,r);return h=p&&p.series,p&&(o&&!h.noSharedTooltip?(l=i.filter(function(t){return d.filter?d.filter(t):a(t)&&!t.noSharedTooltip})).forEach(function(t){let e=u(t.points,function(t){return t.x===p.x&&!t.isNull});m(e)&&(t.boosted&&t.boost&&(e=t.boost.getPoint(e)),n.push(e))}):n.push(p)),g(this,\"afterGetHoverData\",d={hoverPoint:p}),{hoverPoint:d.hoverPoint,hoverSeries:h,hoverPoints:n}}getPointFromEvent(t){let e=t.target,i;for(;e&&!i;)i=e.point,e=e.parentNode;return i}onTrackerMouseOut(t){let e=this.chart,i=t.relatedTarget,s=e.hoverSeries;this.isDirectTouch=!1,!s||!i||s.stickyTracking||this.inClass(i,\"highcharts-tooltip\")||this.inClass(i,\"highcharts-series-\"+s.index)&&this.inClass(i,\"highcharts-tracker\")||s.onMouseOut()}inClass(t,e){let i=t,s;for(;i;){if(s=l(i,\"class\")){if(-1!==s.indexOf(e))return!0;if(-1!==s.indexOf(\"highcharts-container\"))return!1}i=i.parentElement}}constructor(t,e){this.hasDragged=!1,this.lastValidTouch={},this.pinchDown=[],this.eventsToUnbind=[],this.options=e,this.chart=t,this.runChartClick=!!e.chart.events?.click,this.pinchDown=[],this.lastValidTouch={},this.setDOMEvents(),g(this,\"afterInit\")}normalize(t,e){let i=t.touches,s=i?i.length?i.item(0):b(i.changedTouches,t.changedTouches)[0]:t;e||(e=this.getChartPosition());let o=s.pageX-e.left,r=s.pageY-e.top;return p(t,{chartX:Math.round(o/=e.scaleX),chartY:Math.round(r/=e.scaleY)})}onContainerClick(t){let e=this.chart,i=e.hoverPoint,s=this.normalize(t),o=e.plotLeft,r=e.plotTop;!e.cancelClick&&(i&&this.inClass(s.target,\"highcharts-tracker\")?(g(i.series,\"click\",p(s,{point:i})),e.hoverPoint&&i.firePointEvent(\"click\",s)):(p(s,this.getCoordinates(s)),e.isInsidePlot(s.chartX-o,s.chartY-r,{visiblePlotOnly:!0})&&g(e,\"click\",s)))}onContainerMouseDown(t){let i=(1&(t.buttons||t.button))==1;t=this.normalize(t),e.isFirefox&&0!==t.button&&this.onContainerMouseMove(t),(void 0===t.button||i)&&(this.zoomOption(t),i&&t.preventDefault&&t.preventDefault(),this.dragStart(t))}onContainerMouseLeave(t){let e=r[b(k.hoverChartIndex,-1)];t=this.normalize(t),this.onContainerMouseMove(t),e&&t.relatedTarget&&!this.inClass(t.relatedTarget,\"highcharts-tooltip\")&&(e.pointer.reset(),e.pointer.chartPosition=void 0)}onContainerMouseEnter(t){delete this.chartPosition}onContainerMouseMove(t){let e=this.chart,i=e.tooltip,s=this.normalize(t);this.setHoverChartIndex(t),(\"mousedown\"===e.mouseIsDown||this.touchSelect(s))&&this.drag(s),!e.openMenu&&(this.inClass(s.target,\"highcharts-tracker\")||e.isInsidePlot(s.chartX-e.plotLeft,s.chartY-e.plotTop,{visiblePlotOnly:!0}))&&!(i&&i.shouldStickOnContact(s))&&(this.inClass(s.target,\"highcharts-no-tooltip\")?this.reset(!1,0):this.runPointActions(s))}onDocumentTouchEnd(t){let e=r[b(k.hoverChartIndex,-1)];e&&e.pointer.drop(t)}onContainerTouchMove(t){this.touchSelect(t)?this.onContainerMouseMove(t):this.touch(t)}onContainerTouchStart(t){this.touchSelect(t)?this.onContainerMouseDown(t):(this.zoomOption(t),this.touch(t,!0))}onDocumentMouseMove(t){let e=this.chart,i=e.tooltip,s=this.chartPosition,o=this.normalize(t,s);!s||e.isInsidePlot(o.chartX-e.plotLeft,o.chartY-e.plotTop,{visiblePlotOnly:!0})||i&&i.shouldStickOnContact(o)||this.inClass(o.target,\"highcharts-tracker\")||this.reset()}onDocumentMouseUp(t){let e=r[b(k.hoverChartIndex,-1)];e&&e.pointer.drop(t)}pinch(t){let e=this,i=e.chart,s=e.pinchDown,o=t.touches||[],r=o.length,n=e.lastValidTouch,h=e.hasZoom,l={},d=1===r&&(e.inClass(t.target,\"highcharts-tracker\")&&i.runTrackerClick||e.runChartClick),c={},u=e.chart.tooltip,f=1===r&&b(u&&u.options.followTouchMove,!0),m=e.selectionMarker;r>1?e.initiated=!0:f&&(e.initiated=!1),h&&e.initiated&&!d&&!1!==t.cancelable&&t.preventDefault(),[].map.call(o,function(t){return e.normalize(t)}),\"touchstart\"===t.type?([].forEach.call(o,function(t,e){s[e]={chartX:t.chartX,chartY:t.chartY}}),n.x=[s[0].chartX,s[1]&&s[1].chartX],n.y=[s[0].chartY,s[1]&&s[1].chartY],i.axes.forEach(function(t){if(t.zoomEnabled){let e=i.bounds[t.horiz?\"h\":\"v\"],s=t.minPixelPadding,o=t.toPixels(Math.min(b(t.options.min,t.dataMin),t.dataMin)),r=t.toPixels(Math.max(b(t.options.max,t.dataMax),t.dataMax)),n=Math.min(o,r),a=Math.max(o,r);e.min=Math.min(t.pos,n-s),e.max=Math.max(t.pos+t.len,a+s)}}),e.res=!0):f?this.runPointActions(e.normalize(t)):s.length&&(g(i,\"touchpan\",{originalEvent:t},()=>{m||(e.selectionMarker=m=p({destroy:a,touch:!0},i.plotBox)),e.pinchTranslate(s,o,l,m,c,n),e.hasPinched=h,e.scaleGroups(l,c)}),e.res&&(e.res=!1,this.reset(!1,0)))}pinchTranslate(t,e,i,s,o,r){this.zoomHor&&this.pinchTranslateDirection(!0,t,e,i,s,o,r),this.zoomVert&&this.pinchTranslateDirection(!1,t,e,i,s,o,r)}pinchTranslateDirection(t,e,i,s,o,r,n,a){let h=this.chart,l=t?\"x\":\"y\",d=t?\"X\":\"Y\",c=\"chart\"+d,p=t?\"width\":\"height\",u=h[\"plot\"+(t?\"Left\":\"Top\")],g=h.inverted,f=h.bounds[t?\"h\":\"v\"],m=1===e.length,x=e[0][c],y=!m&&e[1][c],b=function(){\"number\"==typeof w&&Math.abs(x-y)>20&&(M=a||Math.abs(C-w)/Math.abs(x-y)),k=(u-C)/M+x,v=h[\"plot\"+(t?\"Width\":\"Height\")]/M},v,S,k,M=a||1,C=i[0][c],w=!m&&i[1][c],T;b(),(S=k)f.max&&(S=f.max-v,T=!0),T?(C-=.8*(C-n[l][0]),\"number\"==typeof w&&(w-=.8*(w-n[l][1])),b()):n[l]=[C,w],g||(r[l]=k-u,r[p]=v);let A=g?t?\"scaleY\":\"scaleX\":\"scale\"+d,P=g?1/M:M;o[p]=v,o[l]=S,s[A]=M*(g&&!t?-1:1),s[\"translate\"+d]=P*u+(C-P*x)}reset(t,e){let i=this.chart,s=i.hoverSeries,o=i.hoverPoint,r=i.hoverPoints,n=i.tooltip,a=n&&n.shared?r:o;t&&a&&S(a).forEach(function(e){e.series.isCartesian&&void 0===e.plotX&&(t=!1)}),t?n&&a&&S(a).length&&(n.refresh(a),n.shared&&r?r.forEach(function(t){t.setState(t.state,!0),t.series.isCartesian&&(t.series.xAxis.crosshair&&t.series.xAxis.drawCrosshair(null,t),t.series.yAxis.crosshair&&t.series.yAxis.drawCrosshair(null,t))}):o&&(o.setState(o.state,!0),i.axes.forEach(function(t){t.crosshair&&o.series[t.coll]===t&&t.drawCrosshair(null,o)}))):(o&&o.onMouseOut(),r&&r.forEach(function(t){t.setState()}),s&&s.onMouseOut(),n&&n.hide(e),this.unDocMouseMove&&(this.unDocMouseMove=this.unDocMouseMove()),i.axes.forEach(function(t){t.hideCrosshair()}),this.hoverX=i.hoverPoints=i.hoverPoint=null)}runPointActions(t,e,i){let s=this.chart,o=s.series,n=s.tooltip&&s.tooltip.options.enabled?s.tooltip:void 0,a=!!n&&n.shared,l=e||s.hoverPoint,d=l&&l.series||s.hoverSeries,c=(!t||\"touchmove\"!==t.type)&&(!!e||d&&d.directTouch&&this.isDirectTouch),p=this.getHoverData(l,d,o,c,a,t);l=p.hoverPoint,d=p.hoverSeries;let g=p.hoverPoints,f=d&&d.tooltipOptions.followPointer&&!d.tooltipOptions.split,m=a&&d&&!d.noSharedTooltip;if(l&&(i||l!==s.hoverPoint||n&&n.isHidden)){if((s.hoverPoints||[]).forEach(function(t){-1===g.indexOf(t)&&t.setState()}),s.hoverSeries!==d&&d.onMouseOver(),this.applyInactiveState(g),(g||[]).forEach(function(t){t.setState(\"hover\")}),s.hoverPoint&&s.hoverPoint.firePointEvent(\"mouseOut\"),!l.series)return;s.hoverPoints=g,s.hoverPoint=l,l.firePointEvent(\"mouseOver\",void 0,()=>{n&&l&&n.refresh(m?g:l,t)})}else if(f&&n&&!n.isHidden){let e=n.getAnchor([{}],t);s.isInsidePlot(e[0],e[1],{visiblePlotOnly:!0})&&n.updatePosition({plotX:e[0],plotY:e[1]})}this.unDocMouseMove||(this.unDocMouseMove=h(s.container.ownerDocument,\"mousemove\",function(t){let e=r[k.hoverChartIndex];e&&e.pointer.onDocumentMouseMove(t)}),this.eventsToUnbind.push(this.unDocMouseMove)),s.axes.forEach(function(e){let i;let o=b((e.crosshair||{}).snap,!0);!o||(i=s.hoverPoint)&&i.series[e.coll]===e||(i=u(g,t=>t.series&&t.series[e.coll]===e)),i||!o?e.drawCrosshair(t,i):e.hideCrosshair()})}scaleGroups(t,e){let i=this.chart;i.series.forEach(function(s){let o=t||s.getPlotBox(\"series\");s.group&&(s.xAxis&&s.xAxis.zoomEnabled||i.mapView)&&(s.group.attr(o),s.markerGroup&&(s.markerGroup.attr(t||s.getPlotBox(\"marker\")),s.markerGroup.clip(e?i.clipRect:null)),s.dataLabelsGroup&&s.dataLabelsGroup.attr(o))}),i.clipRect.attr(e||i.clipBox)}setDOMEvents(){let t=this.chart.container,i=t.ownerDocument;t.onmousedown=this.onContainerMouseDown.bind(this),t.onmousemove=this.onContainerMouseMove.bind(this),t.onclick=this.onContainerClick.bind(this),this.eventsToUnbind.push(h(t,\"mouseenter\",this.onContainerMouseEnter.bind(this))),this.eventsToUnbind.push(h(t,\"mouseleave\",this.onContainerMouseLeave.bind(this))),k.unbindDocumentMouseUp||(k.unbindDocumentMouseUp=h(i,\"mouseup\",this.onDocumentMouseUp.bind(this)));let s=this.chart.renderTo.parentElement;for(;s&&\"BODY\"!==s.tagName;)this.eventsToUnbind.push(h(s,\"scroll\",()=>{delete this.chartPosition})),s=s.parentElement;e.hasTouch&&(this.eventsToUnbind.push(h(t,\"touchstart\",this.onContainerTouchStart.bind(this),{passive:!1})),this.eventsToUnbind.push(h(t,\"touchmove\",this.onContainerTouchMove.bind(this),{passive:!1})),k.unbindDocumentTouchEnd||(k.unbindDocumentTouchEnd=h(i,\"touchend\",this.onDocumentTouchEnd.bind(this),{passive:!1})))}setHoverChartIndex(t){let i=this.chart,s=e.charts[b(k.hoverChartIndex,-1)];s&&s!==i&&s.pointer.onContainerMouseLeave(t||{relatedTarget:i.container}),s&&s.mouseIsDown||(k.hoverChartIndex=i.index)}touch(t,e){let i,s;let o=this.chart;this.setHoverChartIndex(),1===t.touches.length?(t=this.normalize(t),o.isInsidePlot(t.chartX-o.plotLeft,t.chartY-o.plotTop,{visiblePlotOnly:!0})&&!o.openMenu?(e&&this.runPointActions(t),\"touchmove\"===t.type&&(i=!!(s=this.pinchDown)[0]&&Math.sqrt(Math.pow(s[0].chartX-t.chartX,2)+Math.pow(s[0].chartY-t.chartY,2))>=4),b(i,!0)&&this.pinch(t)):e&&this.reset()):2===t.touches.length&&this.pinch(t)}touchSelect(t){return!!(this.chart.zooming.singleTouch&&t.touches&&1===t.touches.length)}zoomOption(t){let e=this.chart,i=(e.options.chart,e.inverted),s=e.zooming.type||\"\",o,r;/touch/.test(t.type)&&(s=b(e.zooming.pinchType,s)),this.zoomX=o=/x/.test(s),this.zoomY=r=/y/.test(s),this.zoomHor=o&&!i||r&&i,this.zoomVert=r&&!i||o&&i,this.hasZoom=o||r}}return(s=k||(k={})).compose=function t(e){v(n,t)&&h(e,\"beforeRender\",function(){this.pointer=new s(this,this.options)})},k}),i(e,\"Core/Legend/Legend.js\",[e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Templating.js\"],e[\"Core/Globals.js\"],e[\"Core/Series/Point.js\"],e[\"Core/Renderer/RendererUtilities.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o,r){var n;let{animObject:a,setAnimation:h}=t,{format:l}=e,{composed:d,marginNames:c}=i,{distribute:p}=o,{addEvent:u,createElement:g,css:f,defined:m,discardElement:x,find:y,fireEvent:b,isNumber:v,merge:S,pick:k,pushUnique:M,relativeLength:C,stableSort:w,syncTimeout:T}=r;class A{constructor(t,e){this.allItems=[],this.initialItemY=0,this.itemHeight=0,this.itemMarginBottom=0,this.itemMarginTop=0,this.itemX=0,this.itemY=0,this.lastItemY=0,this.lastLineHeight=0,this.legendHeight=0,this.legendWidth=0,this.maxItemWidth=0,this.maxLegendWidth=0,this.offsetWidth=0,this.padding=0,this.pages=[],this.symbolHeight=0,this.symbolWidth=0,this.titleHeight=0,this.totalItemWidth=0,this.widthOption=0,this.chart=t,this.setOptions(e),e.enabled&&(this.render(),u(this.chart,\"endResize\",function(){this.legend.positionCheckboxes()})),u(this.chart,\"render\",()=>{this.options.enabled&&this.proximate&&(this.proximatePositions(),this.positionItems())})}setOptions(t){let e=k(t.padding,8);this.options=t,this.chart.styledMode||(this.itemStyle=t.itemStyle,this.itemHiddenStyle=S(this.itemStyle,t.itemHiddenStyle)),this.itemMarginTop=t.itemMarginTop,this.itemMarginBottom=t.itemMarginBottom,this.padding=e,this.initialItemY=e-5,this.symbolWidth=k(t.symbolWidth,16),this.pages=[],this.proximate=\"proximate\"===t.layout&&!this.chart.inverted,this.baseline=void 0}update(t,e){let i=this.chart;this.setOptions(S(!0,this.options,t)),this.destroy(),i.isDirtyLegend=i.isDirtyBox=!0,k(e,!0)&&i.redraw(),b(this,\"afterUpdate\",{redraw:e})}colorizeItem(t,e){let{area:i,group:s,label:o,line:r,symbol:n}=t.legendItem||{};if(s?.[e?\"removeClass\":\"addClass\"](\"highcharts-legend-item-hidden\"),!this.chart.styledMode){let{itemHiddenStyle:s={}}=this,a=s.color,{fillColor:h,fillOpacity:l,lineColor:d,marker:c}=t.options,p=t=>(!e&&(t.fill&&(t.fill=a),t.stroke&&(t.stroke=a)),t);o?.css(S(e?this.itemStyle:s)),r?.attr(p({stroke:d||t.color})),n&&n.attr(p(c&&n.isMarker?t.pointAttribs():{fill:t.color})),i?.attr(p({fill:h||t.color,\"fill-opacity\":h?1:l??.75}))}b(this,\"afterColorizeItem\",{item:t,visible:e})}positionItems(){this.allItems.forEach(this.positionItem,this),this.chart.isResizing||this.positionCheckboxes()}positionItem(t){let{group:e,x:i=0,y:s=0}=t.legendItem||{},o=this.options,r=o.symbolPadding,n=!o.rtl,a=t.checkbox;if(e&&e.element){let o={translateX:n?i:this.legendWidth-i-2*r-4,translateY:s};e[m(e.translateY)?\"animate\":\"attr\"](o,void 0,()=>{b(this,\"afterPositionItem\",{item:t})})}a&&(a.x=i,a.y=s)}destroyItem(t){let e=t.checkbox,i=t.legendItem||{};for(let t of[\"group\",\"label\",\"line\",\"symbol\"])i[t]&&(i[t]=i[t].destroy());e&&x(e),t.legendItem=void 0}destroy(){for(let t of this.getAllItems())this.destroyItem(t);for(let t of[\"clipRect\",\"up\",\"down\",\"pager\",\"nav\",\"box\",\"title\",\"group\"])this[t]&&(this[t]=this[t].destroy());this.display=null}positionCheckboxes(){let t;let e=this.group&&this.group.alignAttr,i=this.clipHeight||this.legendHeight,s=this.titleHeight;e&&(t=e.translateY,this.allItems.forEach(function(o){let r;let n=o.checkbox;n&&(r=t+s+n.y+(this.scrollOffset||0)+3,f(n,{left:e.translateX+o.checkboxOffset+n.x-20+\"px\",top:r+\"px\",display:this.proximate||r>t-6&&r1.5*M?v.height:M))}layoutItem(t){let e=this.options,i=this.padding,s=\"horizontal\"===e.layout,o=t.itemHeight,r=this.itemMarginBottom,n=this.itemMarginTop,a=s?k(e.itemDistance,20):0,h=this.maxLegendWidth,l=e.alignColumns&&this.totalItemWidth>h?this.maxItemWidth:t.itemWidth,d=t.legendItem||{};s&&this.itemX-i+l>h&&(this.itemX=i,this.lastLineHeight&&(this.itemY+=n+this.lastLineHeight+r),this.lastLineHeight=0),this.lastItemY=n+this.itemY+r,this.lastLineHeight=Math.max(o,this.lastLineHeight),d.x=this.itemX,d.y=this.itemY,s?this.itemX+=l:(this.itemY+=n+o+r,this.lastLineHeight=o),this.offsetWidth=this.widthOption||Math.max((s?this.itemX-i-(t.checkbox?0:a):l)+i,this.offsetWidth)}getAllItems(){let t=[];return this.chart.series.forEach(function(e){let i=e&&e.options;e&&k(i.showInLegend,!m(i.linkedTo)&&void 0,!0)&&(t=t.concat((e.legendItem||{}).labels||(\"point\"===i.legendType?e.data:e)))}),b(this,\"afterGetAllItems\",{allItems:t}),t}getAlignment(){let t=this.options;return this.proximate?t.align.charAt(0)+\"tv\":t.floating?\"\":t.align.charAt(0)+t.verticalAlign.charAt(0)+t.layout.charAt(0)}adjustMargins(t,e){let i=this.chart,s=this.options,o=this.getAlignment();o&&[/(lth|ct|rth)/,/(rtv|rm|rbv)/,/(rbh|cb|lbh)/,/(lbv|lm|ltv)/].forEach(function(r,n){r.test(o)&&!m(t[n])&&(i[c[n]]=Math.max(i[c[n]],i.legend[(n+1)%2?\"legendHeight\":\"legendWidth\"]+[1,-1,-1,1][n]*s[n%2?\"x\":\"y\"]+k(s.margin,12)+e[n]+(i.titleOffset[n]||0)))})}proximatePositions(){let t;let e=this.chart,i=[],s=\"left\"===this.options.align;for(let o of(this.allItems.forEach(function(t){let o,r,n=s,a,h;t.yAxis&&(t.xAxis.options.reversed&&(n=!n),t.points&&(o=y(n?t.points:t.points.slice(0).reverse(),function(t){return v(t.plotY)})),r=this.itemMarginTop+t.legendItem.label.getBBox().height+this.itemMarginBottom,h=t.yAxis.top-e.plotTop,a=t.visible?(o?o.plotY:t.yAxis.height)+(h-.3*r):h+t.yAxis.height,i.push({target:a,size:r,item:t}))},this),p(i,e.plotHeight)))t=o.item.legendItem||{},v(o.pos)&&(t.y=e.plotTop-e.spacing[0]+o.pos)}render(){let t=this.chart,e=t.renderer,i=this.options,s=this.padding,o=this.getAllItems(),r,n,a,h=this.group,l,d=this.box;this.itemX=s,this.itemY=this.initialItemY,this.offsetWidth=0,this.lastItemY=0,this.widthOption=C(i.width,t.spacingBox.width-s),l=t.spacingBox.width-2*s-i.x,[\"rm\",\"lm\"].indexOf(this.getAlignment().substring(0,2))>-1&&(l/=2),this.maxLegendWidth=this.widthOption||l,h||(this.group=h=e.g(\"legend\").addClass(i.className||\"\").attr({zIndex:7}).add(),this.contentGroup=e.g().attr({zIndex:1}).add(h),this.scrollGroup=e.g().add(this.contentGroup)),this.renderTitle(),w(o,(t,e)=>(t.options&&t.options.legendIndex||0)-(e.options&&e.options.legendIndex||0)),i.reversed&&o.reverse(),this.allItems=o,this.display=r=!!o.length,this.lastLineHeight=0,this.maxItemWidth=0,this.totalItemWidth=0,this.itemHeight=0,o.forEach(this.renderItem,this),o.forEach(this.layoutItem,this),n=(this.widthOption||this.offsetWidth)+s,a=this.lastItemY+this.lastLineHeight+this.titleHeight,a=this.handleOverflow(a)+s,d||(this.box=d=e.rect().addClass(\"highcharts-legend-box\").attr({r:i.borderRadius}).add(h)),t.styledMode||d.attr({stroke:i.borderColor,\"stroke-width\":i.borderWidth||0,fill:i.backgroundColor||\"none\"}).shadow(i.shadow),n>0&&a>0&&d[d.placed?\"animate\":\"attr\"](d.crisp.call({},{x:0,y:0,width:n,height:a},d.strokeWidth())),h[r?\"show\":\"hide\"](),t.styledMode&&\"none\"===h.getStyle(\"display\")&&(n=a=0),this.legendWidth=n,this.legendHeight=a,r&&this.align(),this.proximate||this.positionItems(),b(this,\"afterRender\")}align(t=this.chart.spacingBox){let e=this.chart,i=this.options,s=t.y;/(lth|ct|rth)/.test(this.getAlignment())&&e.titleOffset[0]>0?s+=e.titleOffset[0]:/(lbh|cb|rbh)/.test(this.getAlignment())&&e.titleOffset[2]>0&&(s-=e.titleOffset[2]),s!==t.y&&(t=S(t,{y:s})),e.hasRendered||(this.group.placed=!1),this.group.align(S(i,{width:this.legendWidth,height:this.legendHeight,verticalAlign:this.proximate?\"top\":i.verticalAlign}),!0,t)}handleOverflow(t){let e=this,i=this.chart,s=i.renderer,o=this.options,r=o.y,n=\"top\"===o.verticalAlign,a=this.padding,h=o.maxHeight,l=o.navigation,d=k(l.animation,!0),c=l.arrowSize||12,p=this.pages,u=this.allItems,g=function(t){\"number\"==typeof t?S.attr({height:t}):S&&(e.clipRect=S.destroy(),e.contentGroup.clip()),e.contentGroup.div&&(e.contentGroup.div.style.clip=t?\"rect(\"+a+\"px,9999px,\"+(a+t)+\"px,0)\":\"auto\")},f=function(t){return e[t]=s.circle(0,0,1.3*c).translate(c/2,c/2).add(v),i.styledMode||e[t].attr(\"fill\",\"rgba(0,0,0,0.0001)\"),e[t]},m,x,y,b=i.spacingBox.height+(n?-r:r)-a,v=this.nav,S=this.clipRect;return\"horizontal\"!==o.layout||\"middle\"===o.verticalAlign||o.floating||(b/=2),h&&(b=Math.min(b,h)),p.length=0,t&&b>0&&t>b&&!1!==l.enabled?(this.clipHeight=m=Math.max(b-20-this.titleHeight-a,0),this.currentPage=k(this.currentPage,1),this.fullHeight=t,u.forEach((t,e)=>{y=t.legendItem||{};let i=y.y||0,s=Math.round(y.label.getBBox().height),o=p.length;(!o||i-p[o-1]>m&&(x||i)!==p[o-1])&&(p.push(x||i),o++),y.pageIx=o-1,x&&((u[e-1].legendItem||{}).pageIx=o-1),e===u.length-1&&i+s-p[o-1]>m&&i>p[o-1]&&(p.push(i),y.pageIx=o),i!==x&&(x=i)}),S||(S=e.clipRect=s.clipRect(0,a-2,9999,0),e.contentGroup.clip(S)),g(m),v||(this.nav=v=s.g().attr({zIndex:1}).add(this.group),this.up=s.symbol(\"triangle\",0,0,c,c).add(v),f(\"upTracker\").on(\"click\",function(){e.scroll(-1,d)}),this.pager=s.text(\"\",15,10).addClass(\"highcharts-legend-navigation\"),!i.styledMode&&l.style&&this.pager.css(l.style),this.pager.add(v),this.down=s.symbol(\"triangle-down\",0,0,c,c).add(v),f(\"downTracker\").on(\"click\",function(){e.scroll(1,d)})),e.scroll(0),t=b):v&&(g(),this.nav=v.destroy(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0),t}scroll(t,e){let i=this.chart,s=this.pages,o=s.length,r=this.clipHeight,n=this.options.navigation,l=this.pager,d=this.padding,c=this.currentPage+t;if(c>o&&(c=o),c>0){void 0!==e&&h(e,i),this.nav.attr({translateX:d,translateY:r+this.padding+7+this.titleHeight,visibility:\"inherit\"}),[this.up,this.upTracker].forEach(function(t){t.attr({class:1===c?\"highcharts-legend-nav-inactive\":\"highcharts-legend-nav-active\"})}),l.attr({text:c+\"/\"+o}),[this.down,this.downTracker].forEach(function(t){t.attr({x:18+this.pager.getBBox().width,class:c===o?\"highcharts-legend-nav-inactive\":\"highcharts-legend-nav-active\"})},this),i.styledMode||(this.up.attr({fill:1===c?n.inactiveColor:n.activeColor}),this.upTracker.css({cursor:1===c?\"default\":\"pointer\"}),this.down.attr({fill:c===o?n.inactiveColor:n.activeColor}),this.downTracker.css({cursor:c===o?\"default\":\"pointer\"})),this.scrollOffset=-s[c-1]+this.initialItemY,this.scrollGroup.animate({translateY:this.scrollOffset}),this.currentPage=c,this.positionCheckboxes();let t=a(k(e,i.renderer.globalAnimation,!0));T(()=>{b(this,\"afterScroll\",{currentPage:c})},t.duration)}}setItemEvents(t,e,i){let o=this,r=t.legendItem||{},n=o.chart.renderer.boxWrapper,a=t instanceof s,h=\"highcharts-legend-\"+(a?\"point\":\"series\")+\"-active\",l=o.chart.styledMode,d=i?[e,r.symbol]:[r.group],c=e=>{o.allItems.forEach(i=>{t!==i&&[i].concat(i.linkedSeries||[]).forEach(t=>{t.setState(e,!a)})})};for(let i of d)i&&i.on(\"mouseover\",function(){t.visible&&c(\"inactive\"),t.setState(\"hover\"),t.visible&&n.addClass(h),l||e.css(o.options.itemHoverStyle)}).on(\"mouseout\",function(){o.chart.styledMode||e.css(S(t.visible?o.itemStyle:o.itemHiddenStyle)),c(\"\"),n.removeClass(h),t.setState()}).on(\"click\",function(e){let i=\"legendItemClick\",s=function(){t.setVisible&&t.setVisible(),c(t.visible?\"inactive\":\"\")};n.removeClass(h),e={browserEvent:e},t.firePointEvent?t.firePointEvent(i,e,s):b(t,i,e,s)})}createCheckboxForItem(t){t.checkbox=g(\"input\",{type:\"checkbox\",className:\"highcharts-legend-checkbox\",checked:t.selected,defaultChecked:t.selected},this.options.itemCheckboxStyle,this.chart.container),u(t.checkbox,\"click\",function(e){let i=e.target;b(t.series||t,\"checkboxClick\",{checked:i.checked,item:t},function(){t.select()})})}}return(n=A||(A={})).compose=function t(e){M(d,t)&&u(e,\"beforeMargins\",function(){this.legend=new n(this,this.options.legend)})},A}),i(e,\"Core/Legend/LegendSymbol.js\",[e[\"Core/Utilities.js\"]],function(t){var e;let{extend:i,merge:s,pick:o}=t;return function(t){function e(t,e,r){let n=this.legendItem=this.legendItem||{},{chart:a,options:h}=this,{baseline:l=0,symbolWidth:d,symbolHeight:c}=t,p=this.symbol||\"circle\",u=c/2,g=a.renderer,f=n.group,m=l-Math.round(c*(r?.4:.3)),x={},y,b=h.marker,v=0;if(a.styledMode||(x[\"stroke-width\"]=Math.min(h.lineWidth||0,24),h.dashStyle?x.dashstyle=h.dashStyle:\"square\"===h.linecap||(x[\"stroke-linecap\"]=\"round\")),n.line=g.path().addClass(\"highcharts-graph\").attr(x).add(f),r&&(n.area=g.path().addClass(\"highcharts-area\").add(f)),x[\"stroke-linecap\"]&&(v=Math.min(n.line.strokeWidth(),d)/2),d){let t=[[\"M\",v,m],[\"L\",d-v,m]];n.line.attr({d:t}),n.area?.attr({d:[...t,[\"L\",d-v,l],[\"L\",v,l]]})}if(b&&!1!==b.enabled&&d){let t=Math.min(o(b.radius,u),u);0===p.indexOf(\"url\")&&(b=s(b,{width:c,height:c}),t=0),n.symbol=y=g.symbol(p,d/2-t,m-t,2*t,2*t,i({context:\"legend\"},b)).addClass(\"highcharts-point\").add(f),y.isMarker=!0}}t.areaMarker=function(t,i){e.call(this,t,i,!0)},t.lineMarker=e,t.rectangle=function(t,e){let i=e.legendItem||{},s=t.options,r=t.symbolHeight,n=s.squareSymbol,a=n?r:t.symbolWidth;i.symbol=this.chart.renderer.rect(n?(t.symbolWidth-r)/2:0,t.baseline-r+1,a,r,o(t.options.symbolRadius,r/2)).addClass(\"highcharts-point\").attr({zIndex:3}).add(i.group)}}(e||(e={})),e}),i(e,\"Core/Series/SeriesDefaults.js\",[],function(){return{lineWidth:2,allowPointSelect:!1,crisp:!0,showCheckbox:!1,animation:{duration:1e3},enableMouseTracking:!0,events:{},marker:{enabledThreshold:2,lineColor:\"#ffffff\",lineWidth:0,radius:4,states:{normal:{animation:!0},hover:{animation:{duration:150},enabled:!0,radiusPlus:2,lineWidthPlus:1},select:{fillColor:\"#cccccc\",lineColor:\"#000000\",lineWidth:2}}},point:{events:{}},dataLabels:{animation:{},align:\"center\",borderWidth:0,defer:!0,formatter:function(){let{numberFormatter:t}=this.series.chart;return\"number\"!=typeof this.y?\"\":t(this.y,-1)},padding:5,style:{fontSize:\"0.7em\",fontWeight:\"bold\",color:\"contrast\",textOutline:\"1px contrast\"},verticalAlign:\"bottom\",x:0,y:0},cropThreshold:300,opacity:1,pointRange:0,softThreshold:!0,states:{normal:{animation:!0},hover:{animation:{duration:150},lineWidthPlus:1,marker:{},halo:{size:10,opacity:.25}},select:{animation:{duration:0}},inactive:{animation:{duration:150},opacity:.2}},stickyTracking:!0,turboThreshold:1e3,findNearestPointBy:\"x\"}}),i(e,\"Core/Series/SeriesRegistry.js\",[e[\"Core/Globals.js\"],e[\"Core/Defaults.js\"],e[\"Core/Series/Point.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s){var o;let{defaultOptions:r}=e,{extendClass:n,merge:a}=s;return function(e){function s(t,s){let o=r.plotOptions||{},n=s.defaultOptions,a=s.prototype;a.type=t,a.pointClass||(a.pointClass=i),n&&(o[t]=n),e.seriesTypes[t]=s}e.seriesTypes=t.seriesTypes,e.registerSeriesType=s,e.seriesType=function(t,o,h,l,d){let c=r.plotOptions||{};return o=o||\"\",c[t]=a(c[o],h),s(t,n(e.seriesTypes[o]||function(){},l)),e.seriesTypes[t].prototype.type=t,d&&(e.seriesTypes[t].prototype.pointClass=n(i,d)),e.seriesTypes[t]}}(o||(o={})),o}),i(e,\"Core/Series/Series.js\",[e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Defaults.js\"],e[\"Core/Foundation.js\"],e[\"Core/Globals.js\"],e[\"Core/Legend/LegendSymbol.js\"],e[\"Core/Series/Point.js\"],e[\"Core/Series/SeriesDefaults.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Renderer/SVG/SVGElement.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o,r,n,a,h,l){let{animObject:d,setAnimation:c}=t,{defaultOptions:p}=e,{registerEventOptions:u}=i,{hasTouch:g,svg:f,win:m}=s,{seriesTypes:x}=a,{arrayMax:y,arrayMin:b,clamp:v,correctFloat:S,defined:k,destroyObjectProperties:M,diffObjects:C,erase:w,error:T,extend:A,find:P,fireEvent:L,getClosestDistance:O,getNestedProperty:D,insertItem:E,isArray:j,isNumber:I,isString:B,merge:R,objectEach:z,pick:N,removeEvent:W,splat:G,syncTimeout:H}=l;class X{constructor(){this.zoneAxis=\"y\"}init(t,e){let i;L(this,\"init\",{options:e});let s=this,o=t.series;this.eventsToUnbind=[],s.chart=t,s.options=s.setOptions(e);let r=s.options,n=!1!==r.visible;s.linkedSeries=[],s.bindAxes(),A(s,{name:r.name,state:\"\",visible:n,selected:!0===r.selected}),u(this,r);let a=r.events;(a&&a.click||r.point&&r.point.events&&r.point.events.click||r.allowPointSelect)&&(t.runTrackerClick=!0),s.getColor(),s.getSymbol(),s.parallelArrays.forEach(function(t){s[t+\"Data\"]||(s[t+\"Data\"]=[])}),s.isCartesian&&(t.hasCartesianSeries=!0),o.length&&(i=o[o.length-1]),s._i=N(i&&i._i,-1)+1,s.opacity=s.options.opacity,t.orderItems(\"series\",E(this,o)),r.dataSorting&&r.dataSorting.enabled?s.setDataSortingOptions():s.points||s.data||s.setData(r.data,!1),L(this,\"afterInit\")}is(t){return x[t]&&this instanceof x[t]}bindAxes(){let t;let e=this,i=e.options,s=e.chart;L(this,\"bindAxes\",null,function(){(e.axisTypes||[]).forEach(function(o){s[o].forEach(function(s){t=s.options,(N(i[o],0)===s.index||void 0!==i[o]&&i[o]===t.id)&&(E(e,s.series),e[o]=s,s.isDirty=!0)}),e[o]||e.optionalAxis===o||T(18,!0,s)})}),L(this,\"afterBindAxes\")}updateParallelArrays(t,e,i){let s=t.series,o=I(e)?function(i){let o=\"y\"===i&&s.toYData?s.toYData(t):t[i];s[i+\"Data\"][e]=o}:function(t){Array.prototype[e].apply(s[t+\"Data\"],i)};s.parallelArrays.forEach(o)}hasData(){return this.visible&&void 0!==this.dataMax&&void 0!==this.dataMin||this.visible&&this.yData&&this.yData.length>0}hasMarkerChanged(t,e){let i=t.marker,s=e.marker||{};return i&&(s.enabled&&!i.enabled||s.symbol!==i.symbol||s.height!==i.height||s.width!==i.width)}autoIncrement(t){let e=this.options,i=e.pointIntervalUnit,s=e.relativeXValue,o=this.chart.time,r=this.xIncrement,n,a;return(r=N(r,e.pointStart,0),this.pointInterval=a=N(this.pointInterval,e.pointInterval,1),s&&I(t)&&(a*=t),i&&(n=new o.Date(r),\"day\"===i?o.set(\"Date\",n,o.get(\"Date\",n)+a):\"month\"===i?o.set(\"Month\",n,o.get(\"Month\",n)+a):\"year\"===i&&o.set(\"FullYear\",n,o.get(\"FullYear\",n)+a),a=n.getTime()-r),s&&I(t))?r+a:(this.xIncrement=r+a,r)}setDataSortingOptions(){let t=this.options;A(this,{requireSorting:!1,sorted:!1,enabledDataSorting:!0,allowDG:!1}),k(t.pointRange)||(t.pointRange=1)}setOptions(t){let e;let i=this.chart,s=i.options,o=s.plotOptions,r=i.userOptions||{},n=R(t),a=i.styledMode,h={plotOptions:o,userOptions:n};L(this,\"setOptions\",h);let l=h.plotOptions[this.type],d=r.plotOptions||{},c=d.series||{},u=p.plotOptions[this.type]||{},g=d[this.type]||{};this.userOptions=h.userOptions;let f=R(l,o.series,g,n);this.tooltipOptions=R(p.tooltip,p.plotOptions.series?.tooltip,u?.tooltip,i.userOptions.tooltip,d.series?.tooltip,g.tooltip,n.tooltip),this.stickyTracking=N(n.stickyTracking,g.stickyTracking,c.stickyTracking,!!this.tooltipOptions.shared&&!this.noSharedTooltip||f.stickyTracking),null===l.marker&&delete f.marker,this.zoneAxis=f.zoneAxis||\"y\";let m=this.zones=(f.zones||[]).slice();return(f.negativeColor||f.negativeFillColor)&&!f.zones&&(e={value:f[this.zoneAxis+\"Threshold\"]||f.threshold||0,className:\"highcharts-negative\"},a||(e.color=f.negativeColor,e.fillColor=f.negativeFillColor),m.push(e)),m.length&&k(m[m.length-1].value)&&m.push(a?{}:{color:this.color,fillColor:this.fillColor}),L(this,\"afterSetOptions\",{options:f}),f}getName(){return N(this.options.name,\"Series \"+(this.index+1))}getCyclic(t,e,i){let s,o;let r=this.chart,n=`${t}Index`,a=`${t}Counter`,h=i?.length||r.options.chart.colorCount;!e&&(k(o=N(\"color\"===t?this.options.colorIndex:void 0,this[n]))?s=o:(r.series.length||(r[a]=0),s=r[a]%h,r[a]+=1),i&&(e=i[s])),void 0!==s&&(this[n]=s),this[t]=e}getColor(){this.chart.styledMode?this.getCyclic(\"color\"):this.options.colorByPoint?this.color=\"#cccccc\":this.getCyclic(\"color\",this.options.color||p.plotOptions[this.type].color,this.chart.options.colors)}getPointsCollection(){return(this.hasGroupedData?this.points:this.data)||[]}getSymbol(){let t=this.options.marker;this.getCyclic(\"symbol\",t.symbol,this.chart.options.symbols)}findPointIndex(t,e){let i,s,o;let n=t.id,a=t.x,h=this.points,l=this.options.dataSorting;if(n){let t=this.chart.get(n);t instanceof r&&(i=t)}else if(this.linkedParent||this.enabledDataSorting||this.options.relativeXValue){let e=e=>!e.touched&&e.index===t.index;if(l&&l.matchByName?e=e=>!e.touched&&e.name===t.name:this.options.relativeXValue&&(e=e=>!e.touched&&e.options.x===t.x),!(i=P(h,e)))return}return i&&void 0!==(o=i&&i.index)&&(s=!0),void 0===o&&I(a)&&(o=this.xData.indexOf(a,e)),-1!==o&&void 0!==o&&this.cropped&&(o=o>=this.cropStart?o-this.cropStart:o),!s&&I(o)&&h[o]&&h[o].touched&&(o=void 0),o}updateData(t,e){let i=this.options,s=i.dataSorting,o=this.points,r=[],n=this.requireSorting,a=t.length===o.length,h,l,d,c,p=!0;if(this.xIncrement=null,t.forEach(function(t,e){let l;let d=k(t)&&this.pointClass.prototype.optionsToObject.call({series:this},t)||{},p=d.x,u=d.id;u||I(p)?(-1===(l=this.findPointIndex(d,c))||void 0===l?r.push(t):o[l]&&t!==i.data[l]?(o[l].update(t,!1,null,!1),o[l].touched=!0,n&&(c=l+1)):o[l]&&(o[l].touched=!0),(!a||e!==l||s&&s.enabled||this.hasDerivedData)&&(h=!0)):r.push(t)},this),h)for(l=o.length;l--;)(d=o[l])&&!d.touched&&d.remove&&d.remove(!1,e);else!a||s&&s.enabled?p=!1:(t.forEach(function(t,e){t===o[e].y||o[e].destroyed||o[e].update(t,!1,null,!1)}),r.length=0);return o.forEach(function(t){t&&(t.touched=!1)}),!!p&&(r.forEach(function(t){this.addPoint(t,!1,null,null,!1)},this),null===this.xIncrement&&this.xData&&this.xData.length&&(this.xIncrement=y(this.xData),this.autoIncrement()),!0)}setData(t,e=!0,i,s){let o=this,r=o.points,n=r&&r.length||0,a=o.options,h=o.chart,l=a.dataSorting,d=o.xAxis,c=a.turboThreshold,p=this.xData,u=this.yData,g=o.pointArrayMap,f=g&&g.length,m=a.keys,x,y,b,v=0,S=1,k=null,M;h.options.chart.allowMutatingData||(a.data&&delete o.options.data,o.userOptions.data&&delete o.userOptions.data,M=R(!0,t)),t=M||t||[];let C=t.length;if(l&&l.enabled&&(t=this.sortData(t)),h.options.chart.allowMutatingData&&!1!==s&&C&&n&&!o.cropped&&!o.hasGroupedData&&o.visible&&!o.boosted&&(b=this.updateData(t,i)),!b){if(o.xIncrement=null,o.colorCounter=0,this.parallelArrays.forEach(function(t){o[t+\"Data\"].length=0}),c&&C>c){if(I(k=o.getFirstValidPoint(t)))for(x=0;x=0?v:0,S=S>=0?S:1),1===k.length&&(S=0),v===S)for(x=0;x{let i=D(o,t),s=D(o,e);return si?1:0});return n.forEach(function(t,e){t.x=e},this),e.linkedSeries&&e.linkedSeries.forEach(function(e){let i=e.options,s=i.data;i.dataSorting&&i.dataSorting.enabled||!s||(s.forEach(function(i,o){s[o]=r(e,i),t[o]&&(s[o].x=t[o].x,s[o].index=o)}),e.setData(s,!1))}),t}getProcessedData(t){let e=this,i=e.xAxis,s=e.options,o=s.cropThreshold,r=t||e.getExtremesFromAll||s.getExtremesFromAll,n=i?.logarithmic,a=e.isCartesian,h,l,d=0,c,p,u,g=e.xData,f=e.yData,m=!1,x=g.length;i&&(p=(c=i.getExtremes()).min,u=c.max,m=!!(i.categories&&!i.names.length)),a&&e.sorted&&!r&&(!o||x>o||e.forceCrop)&&(g[x-1]u?(g=[],f=[]):e.yData&&(g[0]u)&&(g=(h=this.cropData(e.xData,e.yData,p,u)).xData,f=h.yData,d=h.start,l=!0));let y=O([n?g.map(n.log2lin):g],()=>e.requireSorting&&!m&&T(15,!1,e.chart));return{xData:g,yData:f,cropped:l,cropStart:d,closestPointRange:y}}processData(t){let e=this.xAxis;if(this.isCartesian&&!this.isDirty&&!e.isDirty&&!this.yAxis.isDirty&&!t)return!1;let i=this.getProcessedData();this.cropped=i.cropped,this.cropStart=i.cropStart,this.processedXData=i.xData,this.processedYData=i.yData,this.closestPointRange=this.basePointRange=i.closestPointRange,L(this,\"afterProcessData\")}cropData(t,e,i,s){let o=t.length,r,n,a=0,h=o;for(r=0;r=i){a=Math.max(0,r-1);break}for(n=r;ns){h=n+1;break}return{xData:t.slice(a,h),yData:e.slice(a,h),start:a,end:h}}generatePoints(){let t=this.options,e=this.processedData||t.data,i=this.processedXData,s=this.processedYData,o=this.pointClass,r=i.length,n=this.cropStart||0,a=this.hasGroupedData,h=t.keys,l=[],d=t.dataGrouping&&t.dataGrouping.groupAll?n:0,c,p,u,g,f=this.data;if(!f&&!a){let t=[];t.length=e.length,f=this.data=t}for(h&&a&&(this.options.keys=!1),g=0;g0:p.length)||!a),d=e||this.getExtremesFromAll||this.options.getExtremesFromAll||this.cropped||!i||(o[u+n]||c)>=f&&(o[u-n]||c)<=m,l&&d){if(g=p.length)for(;g--;)I(p[g])&&(r[x++]=p[g]);else r[x++]=p}let S={activeYData:r,dataMin:b(r),dataMax:y(r)};return L(this,\"afterGetExtremes\",{dataExtremes:S}),S}applyExtremes(){let t=this.getExtremes();return this.dataMin=t.dataMin,this.dataMax=t.dataMax,t}getFirstValidPoint(t){let e=t.length,i=0,s=null;for(;null===s&&i{t&&!this.chart.container.querySelector(`[clip-path=\"url(#${t.id})\"]`)&&(t.destroy(),delete i[e])}),this.finishedAnimating=!0,L(this,\"afterAnimate\")}drawPoints(t=this.points){let e,i,s,o,r,n,a;let h=this.chart,l=h.styledMode,{colorAxis:d,options:c}=this,p=c.marker,u=this[this.specialGroup||\"markerGroup\"],g=this.xAxis,f=N(p.enabled,!g||!!g.isRadial||null,this.closestPointRangePx>=p.enabledThreshold*p.radius);if(!1!==p.enabled||this._hasPointMarkers)for(e=0;e0||i.hasImage)&&(i.graphic=s=h.renderer.symbol(t,a.x,a.y,a.width,a.height,n?r:p).add(u),this.enabledDataSorting&&h.hasRendered&&(s.attr({x:i.startXPos}),o=\"animate\")),s&&\"animate\"===o&&s[e?\"show\":\"hide\"](e).animate(a),s){let t=this.pointAttribs(i,l||!i.selected?void 0:\"select\");l?d&&s.css({fill:t.fill}):s[o](t)}s&&s.addClass(i.getClassName(),!0)}else s&&(i.graphic=s.destroy())}}markerAttribs(t,e){let i=this.options,s=i.marker,o=t.marker||{},r=o.symbol||s.symbol,n={},a,h,l=N(o.radius,s&&s.radius);e&&(a=s.states[e],l=N((h=o.states&&o.states[e])&&h.radius,a&&a.radius,l&&l+(a&&a.radiusPlus||0))),t.hasImage=r&&0===r.indexOf(\"url\"),t.hasImage&&(l=0);let d=t.pos();return I(l)&&d&&(n.x=d[0]-l,n.y=d[1]-l,i.crisp&&(n.x=Math.floor(n.x))),l&&(n.width=n.height=2*l),n}pointAttribs(t,e){let i=this.options.marker,s=t&&t.options,o=s&&s.marker||{},r=s&&s.color,n=t&&t.color,a=t&&t.zone&&t.zone.color,h,l,d=this.color,c,p,u=N(o.lineWidth,i.lineWidth),g=1;return d=r||a||n||d,c=o.fillColor||i.fillColor||d,p=o.lineColor||i.lineColor||d,e=e||\"normal\",h=i.states[e]||{},u=N((l=o.states&&o.states[e]||{}).lineWidth,h.lineWidth,u+N(l.lineWidthPlus,h.lineWidthPlus,0)),c=l.fillColor||h.fillColor||c,{stroke:p=l.lineColor||h.lineColor||p,\"stroke-width\":u,fill:c,opacity:g=N(l.opacity,h.opacity,g)}}destroy(t){let e,i,s;let o=this,r=o.chart,n=/AppleWebKit\\/533/.test(m.navigator.userAgent),a=o.data||[];for(L(o,\"destroy\",{keepEventsForUpdate:t}),this.removeEvents(t),(o.axisTypes||[]).forEach(function(t){(s=o[t])&&s.series&&(w(s.series,o),s.isDirty=s.forceRedraw=!0)}),o.legendItem&&o.chart.legend.destroyItem(o),e=a.length;e--;)(i=a[e])&&i.destroy&&i.destroy();o.zones.forEach(M),l.clearTimeout(o.animationTimeout),z(o,function(t,e){t instanceof h&&!t.survive&&t[n&&\"group\"===e?\"hide\":\"destroy\"]()}),r.hoverSeries===o&&(r.hoverSeries=void 0),w(r.series,o),r.orderItems(\"series\"),z(o,function(e,i){t&&\"hcEvents\"===i||delete o[i]})}applyZones(){let{area:t,chart:e,graph:i,zones:s,points:o,xAxis:r,yAxis:n,zoneAxis:a}=this,{inverted:h,renderer:l}=e,d=this[`${a}Axis`],{isXAxis:c,len:p=0}=d||{},u=(i?.strokeWidth()||0)/2+1,g=(t,e=0,i=0)=>{h&&(i=p-i);let{translated:s=0,lineClip:o}=t,r=i-s;o?.push([\"L\",e,Math.abs(r){t.forEach((e,i)=>{(\"M\"===e[0]||\"L\"===e[0])&&(t[i]=[e[0],c?p-e[1]:e[1],c?e[2]:p-e[2]])})};if(s.forEach((t,i)=>{t.lineClip=[],t.translated=v(d.toPixels(N(t.value,e),!0)||0,0,p)}),i&&!this.showLine&&i.hide(),t&&t.hide(),\"y\"===a&&o.length{let s=e.lineClip||[],o=Math.round(e.translated||0);r.reversed&&s.reverse();let{clip:a,simpleClip:d}=e,p=0,g=0,x=r.len,y=n.len;c?(p=o,x=m):(g=o,y=m);let b=[[\"M\",p,g],[\"L\",x,g],[\"L\",x,y],[\"L\",p,y],[\"Z\"]],v=[b[0],...s,b[1],b[2],...f,b[3],b[4]];f=s.reverse(),m=o,h&&(u(v),t&&u(b)),a?(a.animate({d:v}),d?.animate({d:b})):(a=e.clip=l.path(v),t&&(d=e.simpleClip=l.path(b))),i&&e.graph?.clip(a),t&&e.area?.clip(d)})}else this.visible&&(i&&i.show(),t&&t.show())}plotGroup(t,e,i,s,o){let r=this[t],n=!r,a={visibility:i,zIndex:s||.1};return k(this.opacity)&&!this.chart.styledMode&&\"inactive\"!==this.state&&(a.opacity=this.opacity),r||(this[t]=r=this.chart.renderer.g().add(o)),r.addClass(\"highcharts-\"+e+\" highcharts-series-\"+this.index+\" highcharts-\"+this.type+\"-series \"+(k(this.colorIndex)?\"highcharts-color-\"+this.colorIndex+\" \":\"\")+(this.options.className||\"\")+(r.hasClass(\"highcharts-tracker\")?\" highcharts-tracker\":\"\"),!0),r.attr(a)[n?\"attr\":\"animate\"](this.getPlotBox(e)),r}getPlotBox(t){let e=this.xAxis,i=this.yAxis,s=this.chart,o=s.inverted&&!s.polar&&e&&!1!==this.invertible&&\"series\"===t;return s.inverted&&(e=i,i=this.xAxis),{translateX:e?e.left:s.plotLeft,translateY:i?i.top:s.plotTop,rotation:o?90:0,rotationOriginX:o?(e.len-i.len)/2:0,rotationOriginY:o?(e.len+i.len)/2:0,scaleX:o?-1:1,scaleY:1}}removeEvents(t){let{eventsToUnbind:e}=this;t||W(this),e.length&&(e.forEach(t=>{t()}),e.length=0)}render(){let t=this,{chart:e,options:i,hasRendered:s}=t,o=d(i.animation),r=t.visible?\"inherit\":\"hidden\",n=i.zIndex,a=e.seriesGroup,h=t.finishedAnimating?0:o.duration;L(this,\"render\"),t.plotGroup(\"group\",\"series\",r,n,a),t.markerGroup=t.plotGroup(\"markerGroup\",\"markers\",r,n,a),!1!==i.clip&&t.setClip(),h&&t.animate?.(!0),t.drawGraph&&(t.drawGraph(),t.applyZones()),t.visible&&t.drawPoints(),t.drawDataLabels?.(),t.redrawPoints?.(),i.enableMouseTracking&&t.drawTracker?.(),h&&t.animate?.(),s||(h&&o.defer&&(h+=o.defer),t.animationTimeout=H(()=>{t.afterAnimate()},h||0)),t.isDirty=!1,t.hasRendered=!0,L(t,\"afterRender\")}redraw(){let t=this.isDirty||this.isDirtyData;this.translate(),this.render(),t&&delete this.kdTree}reserveSpace(){return this.visible||!this.chart.options.chart.ignoreHiddenSeries}searchPoint(t,e){let{xAxis:i,yAxis:s}=this,o=this.chart.inverted;return this.searchKDTree({clientX:o?i.len-t.chartY+i.pos:t.chartX-i.pos,plotY:o?s.len-t.chartX+s.pos:t.chartY-s.pos},e,t)}buildKDTree(t){this.buildingKdTree=!0;let e=this,i=e.options.findNearestPointBy.indexOf(\"y\")>-1?2:1;delete e.kdTree,H(function(){e.kdTree=function t(i,s,o){let r,n;let a=i?.length;if(a)return r=e.kdAxisArray[s%o],i.sort((t,e)=>(t[r]||0)-(e[r]||0)),{point:i[n=Math.floor(a/2)],left:t(i.slice(0,n),s+1,o),right:t(i.slice(n+1),s+1,o)}}(e.getValidPoints(void 0,!e.directTouch),i,i),e.buildingKdTree=!1},e.options.kdNow||t?.type===\"touchstart\"?0:1)}searchKDTree(t,e,i){let s=this,[o,r]=this.kdAxisArray,n=e?\"distX\":\"dist\",a=(s.options.findNearestPointBy||\"\").indexOf(\"y\")>-1?2:1,h=!!s.isBubble;if(this.kdTree||this.buildingKdTree||this.buildKDTree(i),this.kdTree)return function t(e,i,a,l){let d=i.point,c=s.kdAxisArray[a%l],p,u,g=d;!function(t,e){let i=t[o],s=e[o],n=k(i)&&k(s)?i-s:null,a=t[r],l=e[r],d=k(a)&&k(l)?a-l:0,c=h&&e.marker?.radius||0;e.dist=Math.sqrt((n&&n*n||0)+d*d)-c,e.distX=k(n)?Math.abs(n)-c:Number.MAX_VALUE}(e,d);let f=(e[c]||0)-(d[c]||0)+(h&&d.marker?.radius||0),m=f<0?\"left\":\"right\",x=f<0?\"right\":\"left\";return i[m]&&(g=(p=t(e,i[m],a+1,l))[n]=0&&r<=(s?s.len:e.plotHeight)&&o>=0&&o<=(i?i.len:e.plotWidth);return n}drawTracker(){let t=this,e=t.options,i=e.trackByArea,s=[].concat((i?t.areaPath:t.graphPath)||[]),o=t.chart,r=o.pointer,n=o.renderer,a=o.options.tooltip?.snap||0,h=()=>{e.enableMouseTracking&&o.hoverSeries!==t&&t.onMouseOver()},l=\"rgba(192,192,192,\"+(f?1e-4:.002)+\")\",d=t.tracker;d?d.attr({d:s}):t.graph&&(t.tracker=d=n.path(s).attr({visibility:t.visible?\"inherit\":\"hidden\",zIndex:2}).addClass(i?\"highcharts-tracker-area\":\"highcharts-tracker-line\").add(t.group),o.styledMode||d.attr({\"stroke-linecap\":\"round\",\"stroke-linejoin\":\"round\",stroke:l,fill:i?l:\"none\",\"stroke-width\":t.graph.strokeWidth()+(i?0:2*a)}),[t.tracker,t.markerGroup,t.dataLabelsGroup].forEach(t=>{t&&(t.addClass(\"highcharts-tracker\").on(\"mouseover\",h).on(\"mouseout\",t=>{r.onTrackerMouseOut(t)}),e.cursor&&!o.styledMode&&t.css({cursor:e.cursor}),g&&t.on(\"touchstart\",h))})),L(this,\"afterDrawTracker\")}addPoint(t,e,i,s,o){let r,n;let a=this.options,h=this.data,l=this.chart,d=this.xAxis,c=d&&d.hasNames&&d.names,p=a.data,u=this.xData;e=N(e,!0);let g={series:this};this.pointClass.prototype.applyOptions.apply(g,[t]);let f=g.x;if(n=u.length,this.requireSorting&&ff;)n--;this.updateParallelArrays(g,\"splice\",[n,0,0]),this.updateParallelArrays(g,n),c&&g.name&&(c[f]=g.name),p.splice(n,0,t),(r||this.processedData)&&(this.data.splice(n,0,null),this.processData()),\"point\"===a.legendType&&this.generatePoints(),i&&(h[0]&&h[0].remove?h[0].remove(!1):(h.shift(),this.updateParallelArrays(g,\"shift\"),p.shift())),!1!==o&&L(this,\"addPoint\",{point:g}),this.isDirty=!0,this.isDirtyData=!0,e&&l.redraw(s)}removePoint(t,e,i){let s=this,o=s.data,r=o[t],n=s.points,a=s.chart,h=function(){n&&n.length===o.length&&n.splice(t,1),o.splice(t,1),s.options.data.splice(t,1),s.updateParallelArrays(r||{series:s},\"splice\",[t,1]),r&&r.destroy(),s.isDirty=!0,s.isDirtyData=!0,e&&a.redraw()};c(i,a),e=N(e,!0),r?r.firePointEvent(\"remove\",null,h):h()}remove(t,e,i,s){let o=this,r=o.chart;function n(){o.destroy(s),r.isDirtyLegend=r.isDirtyBox=!0,r.linkSeries(s),N(t,!0)&&r.redraw(e)}!1!==i?L(o,\"remove\",null,n):n()}update(t,e){L(this,\"update\",{options:t=C(t,this.userOptions)});let i=this,s=i.chart,o=i.userOptions,r=i.initialType||i.type,n=s.options.plotOptions,a=x[r].prototype,h=i.finishedAnimating&&{animation:!1},l={},d,c,p=[\"colorIndex\",\"eventOptions\",\"navigatorSeries\",\"symbolIndex\",\"baseSeries\"],u=t.type||o.type||s.options.chart.type,g=!(this.hasDerivedData||u&&u!==this.type||void 0!==t.pointStart||void 0!==t.pointInterval||void 0!==t.relativeXValue||t.joinBy||t.mapData||[\"dataGrouping\",\"pointStart\",\"pointInterval\",\"pointIntervalUnit\",\"keys\"].some(t=>i.hasOptionChanged(t)));u=u||r,g&&(p.push(\"data\",\"isDirtyData\",\"isDirtyCanvas\",\"points\",\"processedData\",\"processedXData\",\"processedYData\",\"xIncrement\",\"cropped\",\"_hasPointMarkers\",\"hasDataLabels\",\"nodes\",\"layout\",\"level\",\"mapMap\",\"mapData\",\"minY\",\"maxY\",\"minX\",\"maxX\"),!1!==t.visible&&p.push(\"area\",\"graph\"),i.parallelArrays.forEach(function(t){p.push(t+\"Data\")}),t.data&&(t.dataSorting&&A(i.options.dataSorting,t.dataSorting),this.setData(t.data,!1))),t=R(o,{index:void 0===o.index?i.index:o.index,pointStart:n?.series?.pointStart??o.pointStart??i.xData?.[0]},!g&&{data:i.options.data},t,h),g&&t.data&&(t.data=i.options.data),(p=[\"group\",\"markerGroup\",\"dataLabelsGroup\",\"transformGroup\"].concat(p)).forEach(function(t){p[t]=i[t],delete i[t]});let f=!1;if(x[u]){if(f=u!==i.type,i.remove(!1,!1,!1,!0),f){if(Object.setPrototypeOf)Object.setPrototypeOf(i,x[u].prototype);else{let t=Object.hasOwnProperty.call(i,\"hcEvents\")&&i.hcEvents;for(c in a)i[c]=void 0;A(i,x[u].prototype),t?i.hcEvents=t:delete i.hcEvents}}}else T(17,!0,s,{missingModuleFor:u});if(p.forEach(function(t){i[t]=p[t]}),i.init(s,t),g&&this.points)for(let t of(!1===(d=i.options).visible?(l.graphic=1,l.dataLabel=1):(this.hasMarkerChanged(d,o)&&(l.graphic=1),i.hasDataLabels?.()||(l.dataLabel=1)),this.points))t&&t.series&&(t.resolveColor(),Object.keys(l).length&&t.destroyElements(l),!1===d.showInLegend&&t.legendItem&&s.legend.destroyItem(t));i.initialType=r,s.linkSeries(),s.setSortedData(),f&&i.linkedSeries.length&&(i.isDirtyData=!0),L(this,\"afterUpdate\"),N(e,!0)&&s.redraw(!!g&&void 0)}setName(t){this.name=this.options.name=this.userOptions.name=t,this.chart.isDirtyLegend=!0}hasOptionChanged(t){let e=this.chart,i=this.options[t],s=e.options.plotOptions,o=this.userOptions[t],r=N(s?.[this.type]?.[t],s?.series?.[t]);return o&&!k(r)?i!==o:i!==N(r,i)}onMouseOver(){let t=this.chart,e=t.hoverSeries,i=t.pointer;i.setHoverChartIndex(),e&&e!==this&&e.onMouseOut(),this.options.events.mouseOver&&L(this,\"mouseOver\"),this.setState(\"hover\"),t.hoverSeries=this}onMouseOut(){let t=this.options,e=this.chart,i=e.tooltip,s=e.hoverPoint;e.hoverSeries=null,s&&s.onMouseOut(),this&&t.events.mouseOut&&L(this,\"mouseOut\"),i&&!this.stickyTracking&&(!i.shared||this.noSharedTooltip)&&i.hide(),e.series.forEach(function(t){t.setState(\"\",!0)})}setState(t,e){let i=this,s=i.options,o=i.graph,r=s.inactiveOtherPoints,n=s.states,a=N(n[t||\"normal\"]&&n[t||\"normal\"].animation,i.chart.options.chart.animation),h=s.lineWidth,l=s.opacity;if(t=t||\"\",i.state!==t&&([i.group,i.markerGroup,i.dataLabelsGroup].forEach(function(e){e&&(i.state&&e.removeClass(\"highcharts-series-\"+i.state),t&&e.addClass(\"highcharts-series-\"+t))}),i.state=t,!i.chart.styledMode)){if(n[t]&&!1===n[t].enabled)return;if(t&&(h=n[t].lineWidth||h+(n[t].lineWidthPlus||0),l=N(n[t].opacity,l)),o&&!o.dashstyle&&I(h))for(let t of[o,...this.zones.map(t=>t.graph)])t?.animate({\"stroke-width\":h},a);r||[i.group,i.markerGroup,i.dataLabelsGroup,i.labelBySeries].forEach(function(t){t&&t.animate({opacity:l},a)})}e&&r&&i.points&&i.setAllPointsToState(t||void 0)}setAllPointsToState(t){this.points.forEach(function(e){e.setState&&e.setState(t)})}setVisible(t,e){let i=this,s=i.chart,o=s.options.chart.ignoreHiddenSeries,r=i.visible;i.visible=t=i.options.visible=i.userOptions.visible=void 0===t?!r:t;let n=t?\"show\":\"hide\";[\"group\",\"dataLabelsGroup\",\"markerGroup\",\"tracker\",\"tt\"].forEach(t=>{i[t]?.[n]()}),(s.hoverSeries===i||s.hoverPoint?.series===i)&&i.onMouseOut(),i.legendItem&&s.legend.colorizeItem(i,t),i.isDirty=!0,i.options.stacking&&s.series.forEach(t=>{t.options.stacking&&t.visible&&(t.isDirty=!0)}),i.linkedSeries.forEach(e=>{e.setVisible(t,!1)}),o&&(s.isDirtyBox=!0),L(i,n),!1!==e&&s.redraw()}show(){this.setVisible(!0)}hide(){this.setVisible(!1)}select(t){this.selected=t=this.options.selected=void 0===t?!this.selected:t,this.checkbox&&(this.checkbox.checked=t),L(this,t?\"select\":\"unselect\")}shouldShowTooltip(t,e,i={}){return i.series=this,i.visiblePlotOnly=!0,this.chart.isInsidePlot(t,e,i)}drawLegendSymbol(t,e){o[this.options.legendSymbol||\"rectangle\"]?.call(this,t,e)}}return X.defaultOptions=n,X.types=a.seriesTypes,X.registerType=a.registerSeriesType,A(X.prototype,{axisTypes:[\"xAxis\",\"yAxis\"],coll:\"series\",colorCounter:0,directTouch:!1,isCartesian:!0,kdAxisArray:[\"clientX\",\"plotY\"],parallelArrays:[\"x\",\"y\"],pointClass:r,requireSorting:!0,sorted:!0}),a.series=X,X}),i(e,\"Core/Chart/Chart.js\",[e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Axis/Axis.js\"],e[\"Core/Defaults.js\"],e[\"Core/Templating.js\"],e[\"Core/Foundation.js\"],e[\"Core/Globals.js\"],e[\"Core/Renderer/RendererRegistry.js\"],e[\"Core/Series/Series.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Renderer/SVG/SVGRenderer.js\"],e[\"Core/Time.js\"],e[\"Core/Utilities.js\"],e[\"Core/Renderer/HTML/AST.js\"],e[\"Core/Axis/Tick.js\"]],function(t,e,i,s,o,r,n,a,h,l,d,c,p,u){let{animate:g,animObject:f,setAnimation:m}=t,{defaultOptions:x,defaultTime:y}=i,{numberFormat:b}=s,{registerEventOptions:v}=o,{charts:S,doc:k,marginNames:M,svg:C,win:w}=r,{seriesTypes:T}=h,{addEvent:A,attr:P,createElement:L,clamp:O,css:D,defined:E,diffObjects:j,discardElement:I,erase:B,error:R,extend:z,find:N,fireEvent:W,getStyle:G,isArray:H,isNumber:X,isObject:F,isString:Y,merge:U,objectEach:V,pick:$,pInt:Z,relativeLength:_,removeEvent:q,splat:K,syncTimeout:J,uniqueKey:Q}=c;class tt{static chart(t,e,i){return new tt(t,e,i)}constructor(t,e,i){this.sharedClips={};let s=[...arguments];(Y(t)||t.nodeName)&&(this.renderTo=s.shift()),this.init(s[0],s[1])}setZoomOptions(){let t=this.options.chart,e=t.zooming;this.zooming={...e,type:$(t.zoomType,e.type),key:$(t.zoomKey,e.key),pinchType:$(t.pinchType,e.pinchType),singleTouch:$(t.zoomBySingleTouch,e.singleTouch,!1),resetButton:U(e.resetButton,t.resetZoomButton)}}init(t,e){W(this,\"init\",{args:arguments},function(){let i=U(x,t),s=i.chart;this.userOptions=z({},t),this.margin=[],this.spacing=[],this.bounds={h:{},v:{}},this.labelCollectors=[],this.callback=e,this.isResizing=0,this.options=i,this.axes=[],this.series=[],this.time=t.time&&Object.keys(t.time).length?new d(t.time):r.time,this.numberFormatter=s.numberFormatter||b,this.styledMode=s.styledMode,this.hasCartesianSeries=s.showAxes,this.index=S.length,S.push(this),r.chartCount++,v(this,s),this.xAxis=[],this.yAxis=[],this.pointCount=this.colorCounter=this.symbolCounter=0,this.setZoomOptions(),W(this,\"afterInit\"),this.firstRender()})}initSeries(t){let e=this.options.chart,i=t.type||e.type,s=T[i];s||R(17,!0,this,{missingModuleFor:i});let o=new s;return\"function\"==typeof o.init&&o.init(this,t),o}setSortedData(){this.getSeriesOrderByLinks().forEach(function(t){t.points||t.data||!t.enabledDataSorting||t.setData(t.options.data,!1)})}getSeriesOrderByLinks(){return this.series.concat().sort(function(t,e){return t.linkedSeries.length||e.linkedSeries.length?e.linkedSeries.length-t.linkedSeries.length:0})}orderItems(t,e=0){let i=this[t],s=this.options[t]=K(this.options[t]).slice(),o=this.userOptions[t]=this.userOptions[t]?K(this.userOptions[t]).slice():[];if(this.hasRendered&&(s.splice(e),o.splice(e)),i)for(let t=e,r=i.length;t=Math.max(h+r,t.pos)&&e<=Math.min(h+r+c.width,t.pos+t.len)||(g.isInsidePlot=!1)}if(!i.ignoreY&&g.isInsidePlot){let t=!s&&i.axis&&!i.axis.isXAxis&&i.axis||d&&(s?d.xAxis:d.yAxis)||{pos:n,len:1/0},e=i.paneCoordinates?t.pos+u:n+u;e>=Math.max(l+n,t.pos)&&e<=Math.min(l+n+c.height,t.pos+t.len)||(g.isInsidePlot=!1)}return W(this,\"afterIsInsidePlot\",g),g.isInsidePlot}redraw(t){W(this,\"beforeRedraw\");let e=this.hasCartesianSeries?this.axes:this.colorAxis||[],i=this.series,s=this.pointer,o=this.legend,r=this.userOptions.legend,n=this.renderer,a=n.isHidden(),h=[],l,d,c,p=this.isDirtyBox,u=this.isDirtyLegend,g;for(n.rootFontSize=n.boxWrapper.getStyle(\"font-size\"),this.setResponsive&&this.setResponsive(!1),m(!!this.hasRendered&&t,this),a&&this.temporaryDisplay(),this.layOutTitles(!1),c=i.length;c--;)if(((g=i[c]).options.stacking||g.options.centerInCategory)&&(d=!0,g.isDirty)){l=!0;break}if(l)for(c=i.length;c--;)(g=i[c]).options.stacking&&(g.isDirty=!0);i.forEach(function(t){t.isDirty&&(\"point\"===t.options.legendType?(\"function\"==typeof t.updateTotals&&t.updateTotals(),u=!0):r&&(r.labelFormatter||r.labelFormat)&&(u=!0)),t.isDirtyData&&W(t,\"updatedData\")}),u&&o&&o.options.enabled&&(o.render(),this.isDirtyLegend=!1),d&&this.getStacks(),e.forEach(function(t){t.updateNames(),t.setScale()}),this.getMargins(),e.forEach(function(t){t.isDirty&&(p=!0)}),e.forEach(function(t){let e=t.min+\",\"+t.max;t.extKey!==e&&(t.extKey=e,h.push(function(){W(t,\"afterSetExtremes\",z(t.eventArgs,t.getExtremes())),delete t.eventArgs})),(p||d)&&t.redraw()}),p&&this.drawChartBox(),W(this,\"predraw\"),i.forEach(function(t){(p||t.isDirty)&&t.visible&&t.redraw(),t.isDirtyData=!1}),s&&s.reset(!0),n.draw(),W(this,\"redraw\"),W(this,\"render\"),a&&this.temporaryDisplay(!0),h.forEach(function(t){t.call()})}get(t){let e=this.series;function i(e){return e.id===t||e.options&&e.options.id===t}let s=N(this.axes,i)||N(this.series,i);for(let t=0;!s&&t(e.getPointsCollection().forEach(e=>{$(e.selectedStaging,e.selected)&&t.push(e)}),t),[])}getSelectedSeries(){return this.series.filter(function(t){return t.selected})}setTitle(t,e,i){this.applyDescription(\"title\",t),this.applyDescription(\"subtitle\",e),this.applyDescription(\"caption\",void 0),this.layOutTitles(i)}applyDescription(t,e){let i=this,s=this.options[t]=U(this.options[t],e),o=this[t];o&&e&&(this[t]=o=o.destroy()),s&&!o&&((o=this.renderer.text(s.text,0,0,s.useHTML).attr({align:s.align,class:\"highcharts-\"+t,zIndex:s.zIndex||4}).add()).update=function(e,s){i.applyDescription(t,e),i.layOutTitles(s)},this.styledMode||o.css(z(\"title\"===t?{fontSize:this.options.isStock?\"1em\":\"1.2em\"}:{},s.style)),this[t]=o)}layOutTitles(t=!0){let e=[0,0,0],i=this.renderer,s=this.spacingBox;[\"title\",\"subtitle\",\"caption\"].forEach(function(t){let o=this[t],r=this.options[t],n=r.verticalAlign||\"top\",a=\"title\"===t?\"top\"===n?-3:0:\"top\"===n?e[0]+2:0;if(o){o.css({width:(r.width||s.width+(r.widthAdjust||0))+\"px\"});let t=i.fontMetrics(o).b,h=Math.round(o.getBBox(r.useHTML).height);o.align(z({y:\"bottom\"===n?t:a+t,height:h},r),!1,\"spacingBox\"),r.floating||(\"top\"===n?e[0]=Math.ceil(e[0]+h):\"bottom\"===n&&(e[2]=Math.ceil(e[2]+h)))}},this),e[0]&&\"top\"===(this.options.title.verticalAlign||\"top\")&&(e[0]+=this.options.title.margin),e[2]&&\"bottom\"===this.options.caption.verticalAlign&&(e[2]+=this.options.caption.margin);let o=!this.titleOffset||this.titleOffset.join(\",\")!==e.join(\",\");this.titleOffset=e,W(this,\"afterLayOutTitles\"),!this.isDirtyBox&&o&&(this.isDirtyBox=this.isDirtyLegend=o,this.hasRendered&&t&&this.isDirtyBox&&this.redraw())}getContainerBox(){return{width:G(this.renderTo,\"width\",!0)||0,height:G(this.renderTo,\"height\",!0)||0}}getChartSize(){let t=this.options.chart,e=t.width,i=t.height,s=this.getContainerBox();this.chartWidth=Math.max(0,e||s.width||600),this.chartHeight=Math.max(0,_(i,this.chartWidth)||(s.height>1?s.height:400)),this.containerBox=s}temporaryDisplay(t){let e=this.renderTo,i;if(t)for(;e&&e.style;)e.hcOrigStyle&&(D(e,e.hcOrigStyle),delete e.hcOrigStyle),e.hcOrigDetached&&(k.body.removeChild(e),e.hcOrigDetached=!1),e=e.parentNode;else for(;e&&e.style&&(k.body.contains(e)||e.parentNode||(e.hcOrigDetached=!0,k.body.appendChild(e)),(\"none\"===G(e,\"display\",!1)||e.hcOricDetached)&&(e.hcOrigStyle={display:e.style.display,height:e.style.height,overflow:e.style.overflow},i={display:\"block\",overflow:\"hidden\"},e!==this.renderTo&&(i.height=0),D(e,i),e.offsetWidth||e.style.setProperty(\"display\",\"block\",\"important\")),(e=e.parentNode)!==k.body););}setClassName(t){this.container.className=\"highcharts-container \"+(t||\"\")}getContainer(){let t=this.options,e=t.chart,i=\"data-highcharts-chart\",s=Q(),o,r=this.renderTo;r||(this.renderTo=r=e.renderTo),Y(r)&&(this.renderTo=r=k.getElementById(r)),r||R(13,!0,this);let a=Z(P(r,i));X(a)&&S[a]&&S[a].hasRendered&&S[a].destroy(),P(r,i,this.index),r.innerHTML=p.emptyHTML,e.skipClone||r.offsetWidth||this.temporaryDisplay(),this.getChartSize();let h=this.chartWidth,d=this.chartHeight;D(r,{overflow:\"hidden\"}),this.styledMode||(o=z({position:\"relative\",overflow:\"hidden\",width:h+\"px\",height:d+\"px\",textAlign:\"left\",lineHeight:\"normal\",zIndex:0,\"-webkit-tap-highlight-color\":\"rgba(0,0,0,0)\",userSelect:\"none\",\"touch-action\":\"manipulation\",outline:\"none\"},e.style||{}));let c=L(\"div\",{id:s},o,r);this.container=c,this._cursor=c.style.cursor;let u=e.renderer||!C?n.getRendererType(e.renderer):l;if(this.renderer=new u(c,h,d,void 0,e.forExport,t.exporting&&t.exporting.allowHTML,this.styledMode),this.containerBox=this.getContainerBox(),m(void 0,this),this.setClassName(e.className),this.styledMode)for(let e in t.defs)this.renderer.definition(t.defs[e]);else this.renderer.setStyle(e.style);this.renderer.chartIndex=this.index,W(this,\"afterGetContainer\")}getMargins(t){let{spacing:e,margin:i,titleOffset:s}=this;this.resetMargins(),s[0]&&!E(i[0])&&(this.plotTop=Math.max(this.plotTop,s[0]+e[0])),s[2]&&!E(i[2])&&(this.marginBottom=Math.max(this.marginBottom,s[2]+e[2])),this.legend&&this.legend.display&&this.legend.adjustMargins(i,e),W(this,\"getMargins\"),t||this.getAxisMargins()}getAxisMargins(){let t=this,e=t.axisOffset=[0,0,0,0],i=t.colorAxis,s=t.margin,o=function(t){t.forEach(function(t){t.visible&&t.getOffset()})};t.hasCartesianSeries?o(t.axes):i&&i.length&&o(i),M.forEach(function(i,o){E(s[o])||(t[i]+=e[o])}),t.setChartSize()}getOptions(){return j(this.userOptions,x)}reflow(t){let e=this,i=e.containerBox,s=e.getContainerBox();delete e.pointer.chartPosition,!e.isPrinting&&!e.isResizing&&i&&s.width&&((s.width!==i.width||s.height!==i.height)&&(c.clearTimeout(e.reflowTimeout),e.reflowTimeout=J(function(){e.container&&e.setSize(void 0,void 0,!1)},t?100:0)),e.containerBox=s)}setReflow(){let t=this,e=e=>{t.options?.chart.reflow&&t.hasLoaded&&t.reflow(e)};if(\"function\"==typeof ResizeObserver)new ResizeObserver(e).observe(t.renderTo);else{let t=A(w,\"resize\",e);A(this,\"destroy\",t)}}setSize(t,e,i){let s=this,o=s.renderer;s.isResizing+=1,m(i,s);let r=o.globalAnimation;s.oldChartHeight=s.chartHeight,s.oldChartWidth=s.chartWidth,void 0!==t&&(s.options.chart.width=t),void 0!==e&&(s.options.chart.height=e),s.getChartSize();let{chartWidth:n,chartHeight:a,scrollablePixelsX:h=0,scrollablePixelsY:l=0}=s;(s.isDirtyBox||n!==s.oldChartWidth||a!==s.oldChartHeight)&&(s.styledMode||(r?g:D)(s.container,{width:`${n+h}px`,height:`${a+l}px`},r),s.setChartSize(!0),o.setSize(n,a,r),s.axes.forEach(function(t){t.isDirty=!0,t.setScale()}),s.isDirtyLegend=!0,s.isDirtyBox=!0,s.layOutTitles(),s.getMargins(),s.redraw(r),s.oldChartHeight=void 0,W(s,\"resize\"),setTimeout(()=>{s&&W(s,\"endResize\",void 0,()=>{s.isResizing-=1})},f(r).duration))}setChartSize(t){let e,i,s,o;let r=this.inverted,n=this.renderer,a=this.chartWidth,h=this.chartHeight,l=this.options.chart,d=this.spacing,c=this.clipOffset;this.plotLeft=e=Math.round(this.plotLeft),this.plotTop=i=Math.round(this.plotTop),this.plotWidth=s=Math.max(0,Math.round(a-e-this.marginRight)),this.plotHeight=o=Math.max(0,Math.round(h-i-this.marginBottom)),this.plotSizeX=r?o:s,this.plotSizeY=r?s:o,this.plotBorderWidth=l.plotBorderWidth||0,this.spacingBox=n.spacingBox={x:d[3],y:d[0],width:a-d[3]-d[1],height:h-d[0]-d[2]},this.plotBox=n.plotBox={x:e,y:i,width:s,height:o};let p=2*Math.floor(this.plotBorderWidth/2),u=Math.ceil(Math.max(p,c[3])/2),g=Math.ceil(Math.max(p,c[0])/2);this.clipBox={x:u,y:g,width:Math.floor(this.plotSizeX-Math.max(p,c[1])/2-u),height:Math.max(0,Math.floor(this.plotSizeY-Math.max(p,c[2])/2-g))},t||(this.axes.forEach(function(t){t.setAxisSize(),t.setAxisTranslation()}),n.alignElements()),W(this,\"afterSetChartSize\",{skipAxes:t})}resetMargins(){W(this,\"resetMargins\");let t=this,e=t.options.chart;[\"margin\",\"spacing\"].forEach(function(i){let s=e[i],o=F(s)?s:[s,s,s,s];[\"Top\",\"Right\",\"Bottom\",\"Left\"].forEach(function(s,r){t[i][r]=$(e[i+s],o[r])})}),M.forEach(function(e,i){t[e]=$(t.margin[i],t.spacing[i])}),t.axisOffset=[0,0,0,0],t.clipOffset=[0,0,0,0]}drawChartBox(){let t=this.options.chart,e=this.renderer,i=this.chartWidth,s=this.chartHeight,o=this.styledMode,r=this.plotBGImage,n=t.backgroundColor,a=t.plotBackgroundColor,h=t.plotBackgroundImage,l=this.plotLeft,d=this.plotTop,c=this.plotWidth,p=this.plotHeight,u=this.plotBox,g=this.clipRect,f=this.clipBox,m=this.chartBackground,x=this.plotBackground,y=this.plotBorder,b,v,S,k=\"animate\";m||(this.chartBackground=m=e.rect().addClass(\"highcharts-background\").add(),k=\"attr\"),o?b=v=m.strokeWidth():(v=(b=t.borderWidth||0)+(t.shadow?8:0),S={fill:n||\"none\"},(b||m[\"stroke-width\"])&&(S.stroke=t.borderColor,S[\"stroke-width\"]=b),m.attr(S).shadow(t.shadow)),m[k]({x:v/2,y:v/2,width:i-v-b%2,height:s-v-b%2,r:t.borderRadius}),k=\"animate\",x||(k=\"attr\",this.plotBackground=x=e.rect().addClass(\"highcharts-plot-background\").add()),x[k](u),!o&&(x.attr({fill:a||\"none\"}).shadow(t.plotShadow),h&&(r?(h!==r.attr(\"href\")&&r.attr(\"href\",h),r.animate(u)):this.plotBGImage=e.image(h,l,d,c,p).add())),g?g.animate({width:f.width,height:f.height}):this.clipRect=e.clipRect(f),k=\"animate\",y||(k=\"attr\",this.plotBorder=y=e.rect().addClass(\"highcharts-plot-border\").attr({zIndex:1}).add()),o||y.attr({stroke:t.plotBorderColor,\"stroke-width\":t.plotBorderWidth||0,fill:\"none\"}),y[k](y.crisp({x:l,y:d,width:c,height:p},-y.strokeWidth())),this.isDirtyBox=!1,W(this,\"afterDrawChartBox\")}propFromSeries(){let t,e,i;let s=this,o=s.options.chart,r=s.options.series;[\"inverted\",\"angular\",\"polar\"].forEach(function(n){for(e=T[o.type],i=o[n]||e&&e.prototype[n],t=r&&r.length;!i&&t--;)(e=T[r[t].type])&&e.prototype[n]&&(i=!0);s[n]=i})}linkSeries(t){let e=this,i=e.series;i.forEach(function(t){t.linkedSeries.length=0}),i.forEach(function(t){let{linkedTo:i}=t.options;if(Y(i)){let s;(s=\":previous\"===i?e.series[t.index-1]:e.get(i))&&s.linkedParent!==t&&(s.linkedSeries.push(t),t.linkedParent=s,s.enabledDataSorting&&t.setDataSortingOptions(),t.visible=$(t.options.visible,s.options.visible,t.visible))}}),W(this,\"afterLinkSeries\",{isUpdating:t})}renderSeries(){this.series.forEach(function(t){t.translate(),t.render()})}render(){let t=this.axes,e=this.colorAxis,i=this.renderer,s=this.options.chart.axisLayoutRuns||2,o=t=>{t.forEach(t=>{t.visible&&t.render()})},r=0,n=!0,a,h=0;for(let e of(this.setTitle(),W(this,\"beforeMargins\"),this.getStacks?.(),this.getMargins(!0),this.setChartSize(),t)){let{options:t}=e,{labels:i}=t;if(e.horiz&&e.visible&&i.enabled&&e.series.length&&\"colorAxis\"!==e.coll&&!this.polar){r=t.tickLength,e.createGroups();let s=new u(e,0,\"\",!0),o=s.createLabel(\"x\",i);if(s.destroy(),o&&$(i.reserveSpace,!X(t.crossing))&&(r=o.getBBox().height+i.distance+Math.max(t.offset||0,0)),r){o?.destroy();break}}}for(this.plotHeight=Math.max(this.plotHeight-r,0);(n||a||s>1)&&h(h?1:1.1),a=i/this.plotHeight>(h?1:1.05),h++}this.drawChartBox(),this.hasCartesianSeries?o(t):e&&e.length&&o(e),this.seriesGroup||(this.seriesGroup=i.g(\"series-group\").attr({zIndex:3}).shadow(this.options.chart.seriesGroupShadow).add()),this.renderSeries(),this.addCredits(),this.setResponsive&&this.setResponsive(),this.hasRendered=!0}addCredits(t){let e=this,i=U(!0,this.options.credits,t);i.enabled&&!this.credits&&(this.credits=this.renderer.text(i.text+(this.mapCredits||\"\"),0,0).addClass(\"highcharts-credits\").on(\"click\",function(){i.href&&(w.location.href=i.href)}).attr({align:i.position.align,zIndex:8}),e.styledMode||this.credits.css(i.style),this.credits.add().align(i.position),this.credits.update=function(t){e.credits=e.credits.destroy(),e.addCredits(t)})}destroy(){let t;let e=this,i=e.axes,s=e.series,o=e.container,n=o&&o.parentNode;for(W(e,\"destroy\"),e.renderer.forExport?B(S,e):S[e.index]=void 0,r.chartCount--,e.renderTo.removeAttribute(\"data-highcharts-chart\"),q(e),t=i.length;t--;)i[t]=i[t].destroy();for(this.scroller&&this.scroller.destroy&&this.scroller.destroy(),t=s.length;t--;)s[t]=s[t].destroy();[\"title\",\"subtitle\",\"chartBackground\",\"plotBackground\",\"plotBGImage\",\"plotBorder\",\"seriesGroup\",\"clipRect\",\"credits\",\"pointer\",\"rangeSelector\",\"legend\",\"resetZoomButton\",\"tooltip\",\"renderer\"].forEach(function(t){let i=e[t];i&&i.destroy&&(e[t]=i.destroy())}),o&&(o.innerHTML=p.emptyHTML,q(o),n&&I(o)),V(e,function(t,i){delete e[i]})}firstRender(){let t=this,e=t.options;t.getContainer(),t.resetMargins(),t.setChartSize(),t.propFromSeries(),t.getAxes();let i=H(e.series)?e.series:[];e.series=[],i.forEach(function(e){t.initSeries(e)}),t.linkSeries(),t.setSortedData(),W(t,\"beforeRender\"),t.render(),t.pointer.getChartPosition(),t.renderer.imgCount||t.hasLoaded||t.onload(),t.temporaryDisplay(!0)}onload(){this.callbacks.concat([this.callback]).forEach(function(t){t&&void 0!==this.index&&t.apply(this,[this])},this),W(this,\"load\"),W(this,\"render\"),E(this.index)&&this.setReflow(),this.warnIfA11yModuleNotLoaded(),this.hasLoaded=!0}warnIfA11yModuleNotLoaded(){let{options:t,title:e}=this;!t||this.accessibility||(this.renderer.boxWrapper.attr({role:\"img\",\"aria-label\":(e&&e.element.textContent||\"\").replace(/0&&(y+=v,x=S),(v=y-k)>0&&(y=k,x-=v),e.series.length&&x!==p.min&&y!==p.max&&x>=S&&y<=k&&(e.setExtremes(x,y,!1,!1,{trigger:\"pan\"}),!s.resetZoomButton&&x!==S&&y!==k&&a.match(\"y\")&&(s.showResetZoom(),e.displayBtn=!1),i=!0),r[h]=n)}),V(r,(t,e)=>{s[e]=t}),i&&s.redraw(!1),D(s.container,{cursor:\"move\"})})}}return z(tt.prototype,{callbacks:[],collectionsWithInit:{xAxis:[tt.prototype.addAxis,[!0]],yAxis:[tt.prototype.addAxis,[!1]],series:[tt.prototype.addSeries]},collectionsWithUpdate:[\"xAxis\",\"yAxis\",\"series\"],propsRequireDirtyBox:[\"backgroundColor\",\"borderColor\",\"borderWidth\",\"borderRadius\",\"plotBackgroundColor\",\"plotBackgroundImage\",\"plotBorderColor\",\"plotBorderWidth\",\"plotShadow\",\"shadow\"],propsRequireReflow:[\"margin\",\"marginTop\",\"marginRight\",\"marginBottom\",\"marginLeft\",\"spacing\",\"spacingTop\",\"spacingRight\",\"spacingBottom\",\"spacingLeft\"],propsRequireUpdateSeries:[\"chart.inverted\",\"chart.polar\",\"chart.ignoreHiddenSeries\",\"chart.type\",\"colors\",\"plotOptions\",\"time\",\"tooltip\"]}),tt}),i(e,\"Extensions/ScrollablePlotArea.js\",[e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Globals.js\"],e[\"Core/Renderer/RendererRegistry.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s){let{stop:o}=t,{composed:r}=e,{addEvent:n,createElement:a,css:h,defined:l,extend:d,merge:c,pick:p,pushUnique:u}=s;function g(){let t;let{axisOffset:e,chartWidth:s,chartHeight:r,container:l,plotHeight:d,plotLeft:c,plotTop:u,plotWidth:g,scrollablePixelsX:f=0,scrollablePixelsY:m=0,scrollingContainer:x}=this,y=!this.fixedDiv,b=this.options.chart,v=b.scrollablePlotArea,{scrollPositionX:S,scrollPositionY:k}=v,M=i.getRendererType(),{fixedRenderer:C}=this;C?C.setSize(s,r):(this.fixedDiv=a(\"div\",{className:\"highcharts-fixed\"},{position:\"absolute\",overflow:\"hidden\",pointerEvents:\"none\",zIndex:(b.style?.zIndex||0)+2,top:0},void 0,!0),x?.parentNode.insertBefore(this.fixedDiv,x),h(this.renderTo,{overflow:\"visible\"}),this.fixedRenderer=C=new M(this.fixedDiv,s,r,b.style),this.scrollableMask=C.path().attr({fill:b.backgroundColor||\"#fff\",\"fill-opacity\":p(v.opacity,.85),zIndex:-1}).addClass(\"highcharts-scrollable-mask\").add(),n(this,\"afterShowResetZoom\",this.moveFixedElements),n(this,\"afterApplyDrilldown\",this.moveFixedElements),n(this,\"afterLayOutTitles\",this.moveFixedElements)),(this.scrollableDirty||y)&&(this.scrollableDirty=!1,this.moveFixedElements());let w=s+f,T=r+m;o(this.container),h(l,{width:`${w}px`,height:`${T}px`}),this.renderer.boxWrapper.attr({width:w,height:T,viewBox:[0,0,w,T].join(\" \")}),this.chartBackground?.attr({width:w,height:T}),x&&(h(x,{width:`${this.chartWidth}px`,height:`${this.chartHeight}px`}),y&&(S&&(x.scrollLeft=f*S),k&&(x.scrollTop=m*k)));let A=u-e[0]-1,P=c-e[3]-1,L=u+d+e[2]+1,O=c+g+e[1]+1,D=c+g-f,E=u+d-m;t=f?[[\"M\",0,A],[\"L\",c-1,A],[\"L\",c-1,L],[\"L\",0,L],[\"Z\"],[\"M\",D,A],[\"L\",s,A],[\"L\",s,L],[\"L\",D,L],[\"Z\"]]:m?[[\"M\",P,0],[\"L\",P,u-1],[\"L\",O,u-1],[\"L\",O,0],[\"Z\"],[\"M\",P,E],[\"L\",P,r],[\"L\",O,r],[\"L\",O,E],[\"Z\"]]:[[\"M\",0,0]],\"adjustHeight\"!==this.redrawTrigger&&this.scrollableMask?.attr({d:t})}function f(){let t;let e=this.container,i=this.fixedRenderer,s=[\".highcharts-breadcrumbs-group\",\".highcharts-contextbutton\",\".highcharts-caption\",\".highcharts-credits\",\".highcharts-legend\",\".highcharts-legend-checkbox\",\".highcharts-navigator-series\",\".highcharts-navigator-xaxis\",\".highcharts-navigator-yaxis\",\".highcharts-navigator\",\".highcharts-reset-zoom\",\".highcharts-drillup-button\",\".highcharts-scrollbar\",\".highcharts-subtitle\",\".highcharts-title\"];for(let o of(this.scrollablePixelsX&&!this.inverted?t=\".highcharts-yaxis\":this.scrollablePixelsX&&this.inverted?t=\".highcharts-xaxis\":this.scrollablePixelsY&&!this.inverted?t=\".highcharts-xaxis\":this.scrollablePixelsY&&this.inverted&&(t=\".highcharts-yaxis\"),t&&s.push(`${t}:not(.highcharts-radial-axis)`,`${t}-labels:not(.highcharts-radial-axis-labels)`),s))[].forEach.call(e.querySelectorAll(o),t=>{(t.namespaceURI===i.SVG_NS?i.box:i.box.parentNode).appendChild(t),t.style.pointerEvents=\"auto\"})}function m(){let t;let e={WebkitOverflowScrolling:\"touch\",overflowX:\"hidden\",overflowY:\"hidden\"};this.scrollablePixelsX&&(e.overflowX=\"auto\"),this.scrollablePixelsY&&(e.overflowY=\"auto\"),this.scrollingParent=a(\"div\",{className:\"highcharts-scrolling-parent\"},{position:\"relative\"},this.renderTo),this.scrollingContainer=a(\"div\",{className:\"highcharts-scrolling\"},e,this.scrollingParent),n(this.scrollingContainer,\"scroll\",()=>{this.pointer&&(delete this.pointer.chartPosition,this.hoverPoint&&(t=this.hoverPoint),this.pointer.runPointActions(void 0,t,!0))}),this.innerContainer=a(\"div\",{className:\"highcharts-inner-container\"},null,this.scrollingContainer),this.innerContainer.appendChild(this.container),this.setUpScrolling=null}function x(){this.chart.scrollableDirty=!0}function y(t){let e,i,s;let o=this.options.chart.scrollablePlotArea,r=o&&o.minWidth,n=o&&o.minHeight;if(!this.renderer.forExport&&(r?(this.scrollablePixelsX=e=Math.max(0,r-this.chartWidth),e&&(this.scrollablePlotBox=this.renderer.scrollablePlotBox=c(this.plotBox),this.plotBox.width=this.plotWidth+=e,this.inverted?this.clipBox.height+=e:this.clipBox.width+=e,s={1:{name:\"right\",value:e}})):n&&(this.scrollablePixelsY=i=Math.max(0,n-this.chartHeight),l(i)&&(this.scrollablePlotBox=this.renderer.scrollablePlotBox=c(this.plotBox),this.plotBox.height=this.plotHeight+=i,this.inverted?this.clipBox.width+=i:this.clipBox.height+=i,s={2:{name:\"bottom\",value:i}})),s&&!t.skipAxes))for(let t of this.axes)if(s[t.side]){let e=t.getPlotLinePath;t.getPlotLinePath=function(){let i=s[t.side].name,o=s[t.side].value,r=this[i];this[i]=r-o;let n=e.apply(this,arguments);return this[i]=r,n}}else t.setAxisSize(),t.setAxisTranslation()}function b(){this.scrollablePixelsX||this.scrollablePixelsY?(this.setUpScrolling&&this.setUpScrolling(),this.applyFixed()):this.fixedDiv&&this.applyFixed()}function v(){this.chart.scrollableDirty=!0}return{compose:function t(e,i,s){u(r,t)&&(n(e,\"afterInit\",x),d(i.prototype,{applyFixed:g,moveFixedElements:f,setUpScrolling:m}),n(i,\"afterSetChartSize\",y),n(i,\"render\",b),n(s,\"show\",v))}}}),i(e,\"Core/Axis/Stacking/StackItem.js\",[e[\"Core/Templating.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{format:s}=t,{series:o}=e,{destroyObjectProperties:r,fireEvent:n,isNumber:a,pick:h}=i;return class{constructor(t,e,i,s,o){let r=t.chart.inverted,n=t.reversed;this.axis=t;let a=this.isNegative=!!i!=!!n;this.options=e=e||{},this.x=s,this.total=null,this.cumulative=null,this.points={},this.hasValidPoints=!1,this.stack=o,this.leftCliff=0,this.rightCliff=0,this.alignOptions={align:e.align||(r?a?\"left\":\"right\":\"center\"),verticalAlign:e.verticalAlign||(r?\"middle\":a?\"bottom\":\"top\"),y:e.y,x:e.x},this.textAlign=e.textAlign||(r?a?\"right\":\"left\":\"center\")}destroy(){r(this,this.axis)}render(t){let e=this.axis.chart,i=this.options,o=i.format,r=o?s(o,this,e):i.formatter.call(this);if(this.label)this.label.attr({text:r,visibility:\"hidden\"});else{this.label=e.renderer.label(r,null,void 0,i.shape,void 0,void 0,i.useHTML,!1,\"stack-labels\");let s={r:i.borderRadius||0,text:r,padding:h(i.padding,5),visibility:\"hidden\"};e.styledMode||(s.fill=i.backgroundColor,s.stroke=i.borderColor,s[\"stroke-width\"]=i.borderWidth,this.label.css(i.style||{})),this.label.attr(s),this.label.added||this.label.add(t)}this.label.labelrank=e.plotSizeY,n(this,\"afterRender\")}setOffset(t,e,i,s,r,l){let{alignOptions:d,axis:c,label:p,options:u,textAlign:g}=this,f=c.chart,m=this.getStackBox({xOffset:t,width:e,boxBottom:i,boxTop:s,defaultX:r,xAxis:l}),{verticalAlign:x}=d;if(p&&m){let t=p.getBBox(),e=p.padding,i=\"justify\"===h(u.overflow,\"justify\"),s;d.x=u.x||0,d.y=u.y||0;let{x:r,y:n}=this.adjustStackPosition({labelBox:t,verticalAlign:x,textAlign:g});m.x-=r,m.y-=n,p.align(d,!1,m),(s=f.isInsidePlot(p.alignAttr.x+d.x+r,p.alignAttr.y+d.y+n))||(i=!1),i&&o.prototype.justifyDataLabel.call(c,p,d,p.alignAttr,t,m),p.attr({x:p.alignAttr.x,y:p.alignAttr.y,rotation:u.rotation,rotationOriginX:t.width/2,rotationOriginY:t.height/2}),h(!i&&u.crop,!0)&&(s=a(p.x)&&a(p.y)&&f.isInsidePlot(p.x-e+(p.width||0),p.y)&&f.isInsidePlot(p.x+e,p.y)),p[s?\"show\":\"hide\"]()}n(this,\"afterSetOffset\",{xOffset:t,width:e})}adjustStackPosition({labelBox:t,verticalAlign:e,textAlign:i}){let s={bottom:0,middle:1,top:2,right:1,center:0,left:-1},o=s[e],r=s[i];return{x:t.width/2+t.width/2*r,y:t.height/2*o}}getStackBox(t){let e=this.axis,i=e.chart,{boxTop:s,defaultX:o,xOffset:r,width:n,boxBottom:l}=t,d=e.stacking.usePercentage?100:h(s,this.total,0),c=e.toPixels(d),p=t.xAxis||i.xAxis[0],u=h(o,p.translate(this.x))+r,g=e.toPixels(l||a(e.min)&&e.logarithmic&&e.logarithmic.lin2log(e.min)||0),f=Math.abs(c-g),m=i.inverted,x=this.isNegative;return m?{x:(x?c:c-f)-i.plotLeft,y:p.height-u-n,width:f,height:n}:{x:u+p.transB-i.plotLeft,y:(x?c-f:c)-i.plotTop,width:n,height:f}}}}),i(e,\"Core/Axis/Stacking/StackingAxis.js\",[e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Axis/Axis.js\"],e[\"Core/Globals.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Axis/Stacking/StackItem.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o,r){var n;let{getDeferredAnimation:a}=t,{composed:h}=i,{series:{prototype:l}}=s,{addEvent:d,correctFloat:c,defined:p,destroyObjectProperties:u,fireEvent:g,isArray:f,isNumber:m,objectEach:x,pick:y,pushUnique:b}=r;function v(){let t=this.inverted;this.axes.forEach(t=>{t.stacking&&t.stacking.stacks&&t.hasVisibleSeries&&(t.stacking.oldStacks=t.stacking.stacks)}),this.series.forEach(e=>{let i=e.xAxis&&e.xAxis.options||{};e.options.stacking&&e.reserveSpace()&&(e.stackKey=[e.type,y(e.options.stack,\"\"),t?i.top:i.left,t?i.height:i.width].join(\",\"))})}function S(){let t=this.stacking;if(t){let e=t.stacks;x(e,(t,i)=>{u(t),delete e[i]}),t.stackTotalGroup?.destroy()}}function k(){this.stacking||(this.stacking=new P(this))}function M(t,e,i,s){return!p(t)||t.x!==e||s&&t.stackKey!==s?t={x:e,index:0,key:s,stackKey:s}:t.index++,t.key=[i,e,t.index].join(\",\"),t}function C(){let t;let e=this,i=e.yAxis,s=e.stackKey||\"\",o=i.stacking.stacks,r=e.processedXData,n=e.options.stacking,a=e[n+\"Stacker\"];a&&[s,\"-\"+s].forEach(i=>{let s=r.length,n,h,l;for(;s--;)n=r[s],t=e.getStackIndicator(t,n,e.index,i),h=o[i]?.[n],(l=h?.points[t.key||\"\"])&&a.call(e,l,h,s)})}function w(t,e,i){let s=e.total?100/e.total:0;t[0]=c(t[0]*s),t[1]=c(t[1]*s),this.stackedYData[i]=t[1]}function T(t){(this.is(\"column\")||this.is(\"columnrange\"))&&(this.options.centerInCategory&&!this.options.stacking&&this.chart.series.length>1?l.setStackedPoints.call(this,t,\"group\"):t.stacking.resetStacks())}function A(t,e){let i,s,r,n,a,h,l,d,u;let g=e||this.options.stacking;if(!g||!this.reserveSpace()||(({group:\"xAxis\"})[g]||\"yAxis\")!==t.coll)return;let m=this.processedXData,x=this.processedYData,b=[],v=x.length,S=this.options,k=S.threshold||0,M=S.startFromThreshold?k:0,C=S.stack,w=e?`${this.type},${g}`:this.stackKey||\"\",T=\"-\"+w,A=this.negStacks,P=t.stacking,L=P.stacks,O=P.oldStacks;for(P.stacksTouched+=1,l=0;l0&&!1===this.singleStacks&&(r.points[h][0]=r.points[this.index+\",\"+d+\",0\"][0])):(delete r.points[h],delete r.points[this.index]);let e=r.total||0;\"percent\"===g?(n=s?w:T,e=A&&L[n]?.[d]?(n=L[n][d]).total=Math.max(n.total||0,e)+Math.abs(u)||0:c(e+(Math.abs(u)||0))):\"group\"===g?(f(u)&&(u=u[0]),null!==u&&e++):e=c(e+(u||0)),\"group\"===g?r.cumulative=(e||1)-1:r.cumulative=c(y(r.cumulative,M)+(u||0)),r.total=e,null!==u&&(r.points[h].push(r.cumulative),b[l]=r.cumulative,r.hasValidPoints=!0)}\"percent\"===g&&(P.usePercentage=!0),\"group\"!==g&&(this.stackedYData=b),P.oldStacks={}}class P{constructor(t){this.oldStacks={},this.stacks={},this.stacksTouched=0,this.axis=t}buildStacks(){let t,e;let i=this.axis,s=i.series,o=\"xAxis\"===i.coll,r=i.options.reversedStacks,n=s.length;for(this.resetStacks(),this.usePercentage=!1,e=n;e--;)t=s[r?e:n-e-1],o&&t.setGroupedPoints(i),t.setStackedPoints(i);if(!o)for(e=0;e{x(t,t=>{t.cumulative=t.total})}))}resetStacks(){x(this.stacks,t=>{x(t,(e,i)=>{m(e.touched)&&e.touched{x(t,t=>{t.render(n)})}),n.animate({opacity:1},r)}}return(n||(n={})).compose=function t(e,i,s){if(b(h,t)){let t=i.prototype,o=s.prototype;d(e,\"init\",k),d(e,\"destroy\",S),t.getStacks=v,o.getStackIndicator=M,o.modifyStacks=C,o.percentStacker=w,o.setGroupedPoints=T,o.setStackedPoints=A}},n}),i(e,\"Series/Line/LineSeries.js\",[e[\"Core/Series/Series.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{defined:s,merge:o,isObject:r}=i;class n extends t{drawGraph(){let t=this.options,e=(this.gappedPath||this.getGraphPath).call(this),i=this.chart.styledMode;[this,...this.zones].forEach((s,n)=>{let a,h=s.graph,l=h?\"animate\":\"attr\",d=s.dashStyle||t.dashStyle;h?(h.endX=this.preventGraphAnimation?null:e.xMap,h.animate({d:e})):e.length&&(s.graph=h=this.chart.renderer.path(e).addClass(\"highcharts-graph\"+(n?` highcharts-zone-graph-${n-1} `:\" \")+(n&&s.className||\"\")).attr({zIndex:1}).add(this.group)),h&&!i&&(a={stroke:!n&&t.lineColor||s.color||this.color||\"#cccccc\",\"stroke-width\":t.lineWidth||0,fill:this.fillGraph&&this.color||\"none\"},d?a.dashstyle=d:\"square\"!==t.linecap&&(a[\"stroke-linecap\"]=a[\"stroke-linejoin\"]=\"round\"),h[l](a).shadow(n<2&&t.shadow&&o({filterUnits:\"userSpaceOnUse\"},r(t.shadow)?t.shadow:{}))),h&&(h.startX=e.xMap,h.isArea=e.isArea)})}getGraphPath(t,e,i){let o=this,r=o.options,n=[],a=[],h,l=r.step;t=t||o.points;let d=t.reversed;return d&&t.reverse(),(l=({right:1,center:2})[l]||l&&3)&&d&&(l=4-l),(t=this.getValidPoints(t,!1,!(r.connectNulls&&!e&&!i))).forEach(function(d,c){let p;let u=d.plotX,g=d.plotY,f=t[c-1],m=d.isNull||\"number\"!=typeof g;(d.leftCliff||f&&f.rightCliff)&&!i&&(h=!0),m&&!s(e)&&c>0?h=!r.connectNulls:m&&!e?h=!0:(0===c||h?p=[[\"M\",d.plotX,d.plotY]]:o.getPointSpline?p=[o.getPointSpline(t,d,c)]:l?(p=1===l?[[\"L\",f.plotX,g]]:2===l?[[\"L\",(f.plotX+u)/2,f.plotY],[\"L\",(f.plotX+u)/2,g]]:[[\"L\",u,f.plotY]]).push([\"L\",u,g]):p=[[\"L\",u,g]],a.push(d.x),l&&(a.push(d.x),2===l&&a.push(d.x)),n.push.apply(n,p),h=!1)}),n.xMap=a,o.graphPath=n,n}}return n.defaultOptions=o(t.defaultOptions,{legendSymbol:\"lineMarker\"}),e.registerSeriesType(\"line\",n),n}),i(e,\"Series/Area/AreaSeries.js\",[e[\"Core/Color/Color.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{parse:s}=t,{seriesTypes:{line:o}}=e,{extend:r,merge:n,objectEach:a,pick:h}=i;class l extends o{drawGraph(){this.areaPath=[],super.drawGraph.apply(this);let{areaPath:t,options:e}=this;[this,...this.zones].forEach((i,s)=>{let o={},r=i.fillColor||e.fillColor,n=i.area,a=n?\"animate\":\"attr\";n?(n.endX=this.preventGraphAnimation?null:t.xMap,n.animate({d:t})):(o.zIndex=0,(n=i.area=this.chart.renderer.path(t).addClass(\"highcharts-area\"+(s?` highcharts-zone-area-${s-1} `:\" \")+(s&&i.className||\"\")).add(this.group)).isArea=!0),this.chart.styledMode||(o.fill=r||i.color||this.color,o[\"fill-opacity\"]=r?1:e.fillOpacity??.75,n.css({pointerEvents:this.stickyTracking?\"none\":\"auto\"})),n[a](o),n.startX=t.xMap,n.shiftUnit=e.step?2:1})}getGraphPath(t){let e,i,s;let r=o.prototype.getGraphPath,n=this.options,a=n.stacking,l=this.yAxis,d=[],c=[],p=this.index,u=l.stacking.stacks[this.stackKey],g=n.threshold,f=Math.round(l.getThreshold(n.threshold)),m=h(n.connectNulls,\"percent\"===a),x=function(i,s,o){let r=t[i],n=a&&u[r.x].points[p],h=r[o+\"Null\"]||0,m=r[o+\"Cliff\"]||0,x,y,b=!0;m||h?(x=(h?n[0]:n[1])+m,y=n[0]+m,b=!!h):!a&&t[s]&&t[s].isNull&&(x=y=g),void 0!==x&&(c.push({plotX:e,plotY:null===x?f:l.getThreshold(x),isNull:b,isCliff:!0}),d.push({plotX:e,plotY:null===y?f:l.getThreshold(y),doCurve:!1}))};t=t||this.points,a&&(t=this.getStackPoints(t));for(let o=0,r=t.length;ot.visible);s.forEach(function(t,a){let f=0,m,x;if(l[t]&&!l[t].isNull)i.push(l[t]),[-1,1].forEach(function(i){let o=1===i?\"rightNull\":\"leftNull\",r=n[s[a+i]],h=0;if(r){let i=u;for(;i>=0&&i=0&&ei&&r>l?(r=Math.max(i,l),a=2*l-r):rp&&a>l?(a=Math.max(p,l),r=2*l-a):a=Math.abs(e)&&a>.5;return s=a-(e=Math.round(e)+n),h&&s&&(e-=1,s+=1),{x:t,y:e,width:i,height:s}}adjustForMissingColumns(t,e,i,s){if(!i.isNull&&s.columnCount>1){let o=this.xAxis.series.filter(t=>t.visible).map(t=>t.index),r=0,n=0;b(this.xAxis.stacking?.stacks,t=>{if(\"number\"==typeof i.x){let e=t[i.x.toString()];if(e){let t=e.points[this.index];if(f(t)){let t=Object.keys(e.points).filter(t=>!t.match(\",\")&&e.points[t]&&e.points[t].length>1).map(parseFloat).filter(t=>-1!==o.indexOf(t)).sort((t,e)=>e-t);r=t.indexOf(this.index),n=t.length}}}});let a=(n-1)*s.paddedWidth+e;t=(i.plotX||0)+a/2-e-r*s.paddedWidth}return t}translate(){let t=this,e=t.chart,i=t.options,s=t.dense=t.closestPointRange*t.xAxis.transA<2,r=t.borderWidth=y(i.borderWidth,s?0:1),n=t.xAxis,a=t.yAxis,h=i.threshold,l=y(i.minPointLength,5),d=t.getColumnMetrics(),u=d.width,f=t.pointXOffset=d.offset,x=t.dataMin,b=t.dataMax,v=t.barW=Math.max(u,1+2*r),S=t.translatedThreshold=a.getThreshold(h);e.inverted&&(S-=.5),i.pointPadding&&(v=Math.ceil(v)),o.prototype.translate.apply(t),t.points.forEach(function(s){let o=y(s.yBottom,S),r=999+Math.abs(o),g=s.plotX||0,k=c(s.plotY,-r,a.len+r);s.stackBox;let M,C=Math.min(k,o),w=Math.max(k,o)-C,T=u,A=g+f,P=v;l&&Math.abs(w)l?o-l:S-(M?l:0)),p(s.options.pointWidth)&&(A-=Math.round(((T=P=Math.ceil(s.options.pointWidth))-u)/2)),i.centerInCategory&&!i.stacking&&(A=t.adjustForMissingColumns(A,T,s,d)),s.barX=A,s.pointWidth=T,s.tooltipPos=e.inverted?[c(a.len+a.pos-e.plotLeft-k,a.pos-e.plotLeft,a.len+a.pos-e.plotLeft),n.len+n.pos-e.plotTop-A-P/2,w]:[n.left-e.plotLeft+A+P/2,c(k+a.pos-e.plotTop,a.pos-e.plotTop,a.len+a.pos-e.plotTop),w],s.shapeType=t.pointClass.prototype.shapeType||\"roundedRect\",s.shapeArgs=t.crispCol(A,s.isNull?S:C,P,s.isNull?0:w)}),g(this,\"afterColumnTranslate\")}drawGraph(){this.group[this.dense?\"addClass\":\"removeClass\"](\"highcharts-dense-data\")}pointAttribs(t,e){let i=this.options,s=this.pointAttrToOptions||{},o=s.stroke||\"borderColor\",r=s[\"stroke-width\"]||\"borderWidth\",n,a,l,d=t&&t.color||this.color,c=t&&t[o]||i[o]||d,p=t&&t.options.dashStyle||i.dashStyle,u=t&&t[r]||i[r]||this[r]||0,g=y(t&&t.opacity,i.opacity,1);t&&this.zones.length&&(a=t.getZone(),d=t.options.color||a&&(a.color||t.nonZonedColor)||this.color,a&&(c=a.borderColor||c,p=a.dashStyle||p,u=a.borderWidth||u)),e&&t&&(l=(n=x(i.states[e],t.options.states&&t.options.states[e]||{})).brightness,d=n.color||void 0!==l&&h(d).brighten(n.brightness).get()||d,c=n[o]||c,u=n[r]||u,p=n.dashStyle||p,g=y(n.opacity,g));let f={fill:d,stroke:c,\"stroke-width\":u,opacity:g};return p&&(f.dashstyle=p),f}drawPoints(t=this.points){let e;let i=this,s=this.chart,o=i.options,r=s.renderer,n=o.animationLimit||250;t.forEach(function(t){let a=t.plotY,h=t.graphic,l=!!h,d=h&&s.pointCountt?.enabled)}function i(t,e,i,s,o){let r=this,n=this.chart,a=this.isCartesian&&n.inverted,d=this.enabledDataSorting,c=t.plotX,p=t.plotY,u=i.rotation,g=i.align,m=h(c)&&h(p)&&n.isInsidePlot(c,Math.round(p),{inverted:a,paneCoordinates:!0,series:r}),x=i=>{d&&r.xAxis&&!S&&r.setDataLabelStartPos(t,e,o,m,i)},y,b,v,S=\"justify\"===f(i.overflow,d?\"none\":\"justify\"),k=this.visible&&!1!==t.visible&&h(c)&&(t.series.forceDL||d&&!S||m||f(i.inside,!!this.options.stacking)&&s&&n.isInsidePlot(c,a?s.x+1:s.y+s.height-1,{inverted:a,paneCoordinates:!0,series:r})),M=t.pos();if(k&&M){u&&e.attr({align:g});let t=e.getBBox(!0),a=[0,0];if(y=n.renderer.fontMetrics(e).b,s=l({x:M[0],y:Math.round(M[1]),width:0,height:0},s),l(i,{width:t.width,height:t.height}),u?(S=!1,b=n.renderer.rotCorr(y,u),v={x:s.x+(i.x||0)+s.width/2+b.x,y:s.y+(i.y||0)+({top:0,middle:.5,bottom:1})[i.verticalAlign]*s.height},a=[t.x-Number(e.attr(\"x\")),t.y-Number(e.attr(\"y\"))],x(v),e[o?\"attr\":\"animate\"](v)):(x(s),e.align(i,void 0,s),v=e.alignAttr),S&&s.height>=0)this.justifyDataLabel(e,i,v,t,s,o);else if(f(i.crop,!0)){let{x:e,y:i}=v;e+=a[0],i+=a[1],k=n.isInsidePlot(e,i,{paneCoordinates:!0,series:r})&&n.isInsidePlot(e+t.width,i+t.height,{paneCoordinates:!0,series:r})}i.shape&&!u&&e[o?\"attr\":\"animate\"]({anchorX:M[0],anchorY:M[1]})}o&&d&&(e.placed=!1),k||d&&!S?e.show():(e.hide(),e.placed=!1)}function s(){return this.plotGroup(\"dataLabelsGroup\",\"data-labels\",this.hasRendered?\"inherit\":\"hidden\",this.options.dataLabels.zIndex||6)}function o(t){let e=this.hasRendered||0,i=this.initDataLabelsGroup().attr({opacity:+e});return!e&&i&&(this.visible&&i.show(),this.options.animation?i.animate({opacity:1},t):i.attr({opacity:1})),i}function b(t){let e;t=t||this.points;let i=this,s=i.chart,o=i.options,a=s.renderer,{backgroundColor:l,plotBackgroundColor:c}=s.options.chart,u=a.getContrast(p(c)&&c||p(l)&&l||\"#000000\"),x=k(i),{animation:b,defer:v}=x[0],M=v?r(s,b,i):{defer:0,duration:0};d(this,\"drawDataLabels\"),i.hasDataLabels?.()&&(e=this.initDataLabels(M),t.forEach(t=>{let r=t.dataLabels||[];y(S(x,t.dlOptions||t.options?.dataLabels)).forEach((l,d)=>{let c=l.enabled&&t.visible&&(!t.isNull||t.dataLabelOnNull)&&function(t,e){let i=e.filter;if(i){let e=i.operator,s=t[i.property],o=i.value;return\">\"===e&&s>o||\"<\"===e&&s=\"===e&&s>=o||\"<=\"===e&&s<=o||\"==\"===e&&s==o||\"===\"===e&&s===o||\"!=\"===e&&s!=o||\"!==\"===e&&s!==o}return!0}(t,l),{backgroundColor:x,borderColor:y,distance:b,style:v={}}=l,S,k,M,C,w={},T=r[d],A=!T,P;if(c&&(k=f(l[t.formatPrefix+\"Format\"],l.format),S=t.getLabelConfig(),M=h(k)?n(k,S,s):(l[t.formatPrefix+\"Formatter\"]||l.formatter).call(S,l),C=l.rotation,!s.styledMode&&(v.color=f(l.color,v.color,p(i.color)?i.color:void 0,\"#000000\"),\"contrast\"===v.color?(\"none\"!==x&&(P=x),t.contrastColor=a.getContrast(\"auto\"!==P&&P||t.color||i.color),v.color=P||!h(b)&&l.inside||0>m(b||0)||o.stacking?t.contrastColor:u):delete t.contrastColor,o.cursor&&(v.cursor=o.cursor)),w={r:l.borderRadius||0,rotation:C,padding:l.padding,zIndex:1},s.styledMode||(w.fill=\"auto\"===x?t.color:x,w.stroke=\"auto\"===y?t.color:y,w[\"stroke-width\"]=l.borderWidth),g(w,(t,e)=>{void 0===t&&delete w[e]})),!T||c&&h(M)&&!!T.div==!!l.useHTML&&(T.rotation&&l.rotation||T.rotation===l.rotation)||(T=void 0,A=!0),c&&h(M)&&(T?w.text=M:(T=C?a.text(M,0,0,l.useHTML).addClass(\"highcharts-data-label\"):a.label(M,0,0,l.shape,void 0,void 0,l.useHTML,void 0,\"data-label\"))&&T.addClass(\" highcharts-data-label-color-\"+t.colorIndex+\" \"+(l.className||\"\")+(l.useHTML?\" highcharts-tracker\":\"\")),T)){T.options=l,T.attr(w),s.styledMode||T.css(v).shadow(l.shadow);let o=l[t.formatPrefix+\"TextPath\"]||l.textPath;o&&!l.useHTML&&(T.setTextPath(t.getDataLabelPath?.(T)||t.graphic,o),t.dataLabelPath&&!o.enabled&&(t.dataLabelPath=t.dataLabelPath.destroy())),T.added||T.add(e),i.alignDataLabel(t,T,l,void 0,A),T.isActive=!0,r[d]&&r[d]!==T&&r[d].destroy(),r[d]=T}});let l=r.length;for(;l--;)r[l]&&r[l].isActive?r[l].isActive=!1:(r[l]?.destroy(),r.splice(l,1));t.dataLabel=r[0],t.dataLabels=r})),d(this,\"afterDrawDataLabels\")}function v(t,e,i,s,o,r){let n=this.chart,a=e.align,h=e.verticalAlign,l=t.box?0:t.padding||0,{x:d=0,y:c=0}=e,p,u;return(p=(i.x||0)+l)<0&&(\"right\"===a&&d>=0?(e.align=\"left\",e.inside=!0):d-=p,u=!0),(p=(i.x||0)+s.width-l)>n.plotWidth&&(\"left\"===a&&d<=0?(e.align=\"right\",e.inside=!0):d+=n.plotWidth-p,u=!0),(p=i.y+l)<0&&(\"bottom\"===h&&c>=0?(e.verticalAlign=\"top\",e.inside=!0):c-=p,u=!0),(p=(i.y||0)+s.height-l)>n.plotHeight&&(\"top\"===h&&c<=0?(e.verticalAlign=\"bottom\",e.inside=!0):c+=n.plotHeight-p,u=!0),u&&(e.x=d,e.y=c,t.placed=!r,t.align(e,void 0,o)),u}function S(t,e){let i=[],s;if(c(t)&&!c(e))i=t.map(function(t){return u(t,e)});else if(c(e)&&!c(t))i=e.map(function(e){return u(t,e)});else if(c(t)||c(e)){if(c(t)&&c(e))for(s=Math.max(t.length,e.length);s--;)i[s]=u(t[s],e[s])}else i=u(t,e);return i}function k(t){let e=t.chart.options.plotOptions;return y(S(S(e?.series?.dataLabels,e?.[t.type]?.dataLabels),t.options.dataLabels))}function M(t,e,i,s,o){let r=this.chart,n=r.inverted,a=this.xAxis,h=a.reversed,l=((n?e.height:e.width)||0)/2,d=t.pointWidth,c=d?d/2:0;e.startXPos=n?o.x:h?-l-c:a.width-l+c,e.startYPos=n?h?this.yAxis.height-l+c:-l-c:o.y,s?\"hidden\"===e.visibility&&(e.show(),e.attr({opacity:0}).animate({opacity:1})):e.attr({opacity:1}).animate({opacity:0},void 0,e.hide),r.hasRendered&&(i&&e.attr({x:e.startXPos,y:e.startYPos}),e.placed=!0)}t.compose=function t(r){if(x(a,t)){let t=r.prototype;t.initDataLabelsGroup=s,t.initDataLabels=o,t.alignDataLabel=i,t.drawDataLabels=b,t.justifyDataLabel=v,t.setDataLabelStartPos=M,t.hasDataLabels=e}}}(o||(o={})),o}),i(e,\"Series/Column/ColumnDataLabel.js\",[e[\"Core/Series/DataLabel.js\"],e[\"Core/Globals.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s){var o;let{composed:r}=e,{series:n}=i,{merge:a,pick:h,pushUnique:l}=s;return function(e){function i(t,e,i,s,o){let r=this.chart.inverted,l=t.series,d=(l.xAxis?l.xAxis.len:this.chart.plotSizeX)||0,c=(l.yAxis?l.yAxis.len:this.chart.plotSizeY)||0,p=t.dlBox||t.shapeArgs,u=h(t.below,t.plotY>h(this.translatedThreshold,c)),g=h(i.inside,!!this.options.stacking);if(p){if(s=a(p),!(\"allow\"===i.overflow&&!1===i.crop)){s.y<0&&(s.height+=s.y,s.y=0);let t=s.y+s.height-c;t>0&&t\u25CF {series.name}
',pointFormat:\"x: {point.x}
y: {point.y}
\"}}}),i(e,\"Series/Scatter/ScatterSeries.js\",[e[\"Series/Scatter/ScatterSeriesDefaults.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{column:s,line:o}=e.seriesTypes,{addEvent:r,extend:n,merge:a}=i;class h extends o{applyJitter(){let t=this,e=this.options.jitter,i=this.points.length;e&&this.points.forEach(function(s,o){[\"x\",\"y\"].forEach(function(r,n){let a,h=\"plot\"+r.toUpperCase(),l,d,c;e[r]&&!s.isNull&&(a=t[r+\"Axis\"],c=e[r]*a.transA,a&&!a.isLog&&(l=Math.max(0,s[h]-c),d=Math.min(a.len,s[h]+c),s[h]=l+(d-l)*function(t){let e=1e4*Math.sin(t);return e-Math.floor(e)}(o+n*i),\"x\"===r&&(s.clientX=s.plotX)))})})}drawGraph(){this.options.lineWidth?super.drawGraph():this.graph&&(this.graph=this.graph.destroy())}}return h.defaultOptions=a(o.defaultOptions,t),n(h.prototype,{drawTracker:s.prototype.drawTracker,sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:[\"group\",\"markerGroup\",\"dataLabelsGroup\"]}),r(h,\"afterTranslate\",function(){this.applyJitter()}),e.registerSeriesType(\"scatter\",h),h}),i(e,\"Series/CenteredUtilities.js\",[e[\"Core/Globals.js\"],e[\"Core/Series/Series.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){var s,o;let{deg2rad:r}=t,{fireEvent:n,isNumber:a,pick:h,relativeLength:l}=i;return(o=s||(s={})).getCenter=function(){let t=this.options,i=this.chart,s=2*(t.slicedOffset||0),o=i.plotWidth-2*s,r=i.plotHeight-2*s,d=t.center,c=Math.min(o,r),p=t.thickness,u,g=t.size,f=t.innerSize||0,m,x;\"string\"==typeof g&&(g=parseFloat(g)),\"string\"==typeof f&&(f=parseFloat(f));let y=[h(d[0],\"50%\"),h(d[1],\"50%\"),h(g&&g<0?void 0:t.size,\"100%\"),h(f&&f<0?void 0:t.innerSize||0,\"0%\")];for(!i.angular||this instanceof e||(y[3]=0),m=0;m<4;++m)x=y[m],u=m<2||2===m&&/%$/.test(x),y[m]=l(x,[o,r,c,y[2]][m])+(u?s:0);return y[3]>y[2]&&(y[3]=y[2]),a(p)&&2*p0&&(y[3]=y[2]-2*p),n(this,\"afterGetCenter\",{positions:y}),y},o.getStartAndEndRadians=function(t,e){let i=a(t)?t:0,s=a(e)&&e>i&&e-i<360?e:i+360;return{start:r*(i+-90),end:r*(s+-90)}},s}),i(e,\"Series/Pie/PiePoint.js\",[e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Series/Point.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{setAnimation:s}=t,{addEvent:o,defined:r,extend:n,isNumber:a,isString:h,pick:l,relativeLength:d}=i;class c extends e{getConnectorPath(t){let e=t.dataLabelPosition,i=t.options||{},s=i.connectorShape,o=this.connectorShapes[s]||s;return e&&o.call(this,{...e.computed,alignment:e.alignment},e.connectorPosition,i)||[]}getTranslate(){return this.sliced&&this.slicedTranslation||{translateX:0,translateY:0}}haloPath(t){let e=this.shapeArgs;return this.sliced||!this.visible?[]:this.series.chart.renderer.symbols.arc(e.x,e.y,e.r+t,e.r+t,{innerR:e.r-1,start:e.start,end:e.end,borderRadius:e.borderRadius})}constructor(t,e,i){super(t,e,i),this.half=0,this.name??(this.name=\"Slice\");let s=t=>{this.slice(\"select\"===t.type)};o(this,\"select\",s),o(this,\"unselect\",s)}isValid(){return a(this.y)&&this.y>=0}setVisible(t,e=!0){t!==this.visible&&this.update({visible:t??!this.visible},e,void 0,!1)}slice(t,e,i){let o=this.series,n=o.chart;s(i,n),e=l(e,!0),this.sliced=this.options.sliced=t=r(t)?t:!this.sliced,o.options.data[o.data.indexOf(this)]=this.options,this.graphic&&this.graphic.animate(this.getTranslate())}}return n(c.prototype,{connectorShapes:{fixedOffset:function(t,e,i){let s=e.breakAt,o=e.touchingSliceAt,r=i.softConnector?[\"C\",t.x+(\"left\"===t.alignment?-5:5),t.y,2*s.x-o.x,2*s.y-o.y,s.x,s.y]:[\"L\",s.x,s.y];return[[\"M\",t.x,t.y],r,[\"L\",o.x,o.y]]},straight:function(t,e){let i=e.touchingSliceAt;return[[\"M\",t.x,t.y],[\"L\",i.x,i.y]]},crookedLine:function(t,e,i){let{breakAt:s,touchingSliceAt:o}=e,{series:r}=this,[n,a,h]=r.center,l=h/2,{plotLeft:c,plotWidth:p}=r.chart,u=\"left\"===t.alignment,{x:g,y:f}=t,m=s.x;if(i.crookDistance){let t=d(i.crookDistance,1);m=u?n+l+(p+c-n-l)*(1-t):c+(n-l)*t}else m=n+(a-f)*Math.tan((this.angle||0)-Math.PI/2);let x=[[\"M\",g,f]];return(u?m<=g&&m>=s.x:m>=g&&m<=s.x)&&x.push([\"L\",m,f]),x.push([\"L\",s.x,s.y],[\"L\",o.x,o.y]),x}}}),c}),i(e,\"Series/Pie/PieSeriesDefaults.js\",[],function(){return{borderRadius:3,center:[null,null],clip:!1,colorByPoint:!0,dataLabels:{connectorPadding:5,connectorShape:\"crookedLine\",crookDistance:void 0,distance:30,enabled:!0,formatter:function(){return this.point.isNull?void 0:this.point.name},softConnector:!0,x:0},fillColor:void 0,ignoreHiddenPoint:!0,inactiveOtherPoints:!0,legendType:\"point\",marker:null,size:null,showInLegend:!1,slicedOffset:10,stickyTracking:!1,tooltip:{followPointer:!0},borderColor:\"#ffffff\",borderWidth:1,lineWidth:void 0,states:{hover:{brightness:.1}}}}),i(e,\"Series/Pie/PieSeries.js\",[e[\"Series/CenteredUtilities.js\"],e[\"Series/Column/ColumnSeries.js\"],e[\"Core/Globals.js\"],e[\"Series/Pie/PiePoint.js\"],e[\"Series/Pie/PieSeriesDefaults.js\"],e[\"Core/Series/Series.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Renderer/SVG/Symbols.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o,r,n,a,h){let{getStartAndEndRadians:l}=t,{noop:d}=i,{clamp:c,extend:p,fireEvent:u,merge:g,pick:f,relativeLength:m,splat:x}=h;class y extends r{animate(t){let e=this,i=e.points,s=e.startAngleRad;t||i.forEach(function(t){let i=t.graphic,o=t.shapeArgs;i&&o&&(i.attr({r:f(t.startR,e.center&&e.center[3]/2),start:s,end:s}),i.animate({r:o.r,start:o.start,end:o.end},e.options.animation))})}drawEmpty(){let t,e;let i=this.startAngleRad,s=this.endAngleRad,o=this.options;0===this.total&&this.center?(t=this.center[0],e=this.center[1],this.graph||(this.graph=this.chart.renderer.arc(t,e,this.center[1]/2,0,i,s).addClass(\"highcharts-empty-series\").add(this.group)),this.graph.attr({d:a.arc(t,e,this.center[2]/2,0,{start:i,end:s,innerR:this.center[3]/2})}),this.chart.styledMode||this.graph.attr({\"stroke-width\":o.borderWidth,fill:o.fillColor||\"none\",stroke:o.color||\"#cccccc\"})):this.graph&&(this.graph=this.graph.destroy())}drawPoints(){let t=this.chart.renderer;this.points.forEach(function(e){e.graphic&&e.hasNewShapeType()&&(e.graphic=e.graphic.destroy()),e.graphic||(e.graphic=t[e.shapeType](e.shapeArgs).add(e.series.group),e.delayedRendering=!0)})}generatePoints(){super.generatePoints(),this.updateTotals()}getX(t,e,i,s){let o=this.center,r=this.radii?this.radii[i.index]||0:o[2]/2,n=s.dataLabelPosition,a=n?.distance||0,h=Math.asin(c((t-o[1])/(r+a),-1,1)),l=o[0]+(e?-1:1)*(Math.cos(h)*(r+a))+(a>0?(e?-1:1)*(s.padding||0):0);return l}hasData(){return!!this.processedXData.length}redrawPoints(){let t,e,i,s;let o=this,r=o.chart;this.drawEmpty(),o.group&&!r.styledMode&&o.group.shadow(o.options.shadow),o.points.forEach(function(n){let a={};e=n.graphic,!n.isNull&&e?(s=n.shapeArgs,t=n.getTranslate(),r.styledMode||(i=o.pointAttribs(n,n.selected&&\"select\")),n.delayedRendering?(e.setRadialReference(o.center).attr(s).attr(t),r.styledMode||e.attr(i).attr({\"stroke-linejoin\":\"round\"}),n.delayedRendering=!1):(e.setRadialReference(o.center),r.styledMode||g(!0,a,i),g(!0,a,s,t),e.animate(a)),e.attr({visibility:n.visible?\"inherit\":\"hidden\"}),e.addClass(n.getClassName(),!0)):e&&(n.graphic=e.destroy())})}sortByAngle(t,e){t.sort(function(t,i){return void 0!==t.angle&&(i.angle-t.angle)*e})}translate(t){u(this,\"translate\"),this.generatePoints();let e=this.options,i=e.slicedOffset,s=l(e.startAngle,e.endAngle),o=this.startAngleRad=s.start,r=this.endAngleRad=s.end,n=r-o,a=this.points,h=e.ignoreHiddenPoint,d=a.length,c,p,g,f,m,x,y,b=0;for(t||(this.center=t=this.getCenter()),x=0;x1.5*Math.PI?g-=2*Math.PI:g<-Math.PI/2&&(g+=2*Math.PI),y.slicedTranslation={translateX:Math.round(Math.cos(g)*i),translateY:Math.round(Math.sin(g)*i)},f=Math.cos(g)*t[2]/2,m=Math.sin(g)*t[2]/2,y.tooltipPos=[t[0]+.7*f,t[1]+.7*m],y.half=g<-Math.PI/2||g>Math.PI/2?1:0,y.angle=g}u(this,\"afterTranslate\")}updateTotals(){let t=this.points,e=t.length,i=this.options.ignoreHiddenPoint,s,o,r=0;for(s=0;s0&&(o.visible||!i)?o.y/r*100:0,o.total=r}}return y.defaultOptions=g(r.defaultOptions,o),p(y.prototype,{axisTypes:[],directTouch:!0,drawGraph:void 0,drawTracker:e.prototype.drawTracker,getCenter:t.getCenter,getSymbol:d,isCartesian:!1,noSharedTooltip:!0,pointAttribs:e.prototype.pointAttribs,pointClass:s,requireSorting:!1,searchPoint:d,trackerGroups:[\"group\",\"dataLabelsGroup\"]}),n.registerSeriesType(\"pie\",y),y}),i(e,\"Series/Pie/PieDataLabel.js\",[e[\"Core/Series/DataLabel.js\"],e[\"Core/Globals.js\"],e[\"Core/Renderer/RendererUtilities.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Core/Utilities.js\"]],function(t,e,i,s,o){var r;let{composed:n,noop:a}=e,{distribute:h}=i,{series:l}=s,{arrayMax:d,clamp:c,defined:p,pick:u,pushUnique:g,relativeLength:f}=o;return function(e){let i={radialDistributionY:function(t,e){return(e.dataLabelPosition?.top||0)+t.distributeBox.pos},radialDistributionX:function(t,e,i,s,o){let r=o.dataLabelPosition;return t.getX(i<(r?.top||0)+2||i>(r?.bottom||0)-2?s:i,e.half,e,o)},justify:function(t,e,i,s){return s[0]+(t.half?-1:1)*(i+(e.dataLabelPosition?.distance||0))},alignToPlotEdges:function(t,e,i,s){let o=t.getBBox().width;return e?o+s:i-o-s},alignToConnectors:function(t,e,i,s){let o=0,r;return t.forEach(function(t){(r=t.dataLabel.getBBox().width)>o&&(o=r)}),e?o+s:i-o-s}};function s(t,e){let{center:i,options:s}=this,o=i[2]/2,r=t.angle||0,n=Math.cos(r),a=Math.sin(r),h=i[0]+n*o,l=i[1]+a*o,d=Math.min((s.slicedOffset||0)+(s.borderWidth||0),e/5);return{natural:{x:h+n*e,y:l+a*e},computed:{},alignment:e<0?\"center\":t.half?\"right\":\"left\",connectorPosition:{breakAt:{x:h+n*d,y:l+a*d},touchingSliceAt:{x:h,y:l}},distance:e}}function o(){let t=this,e=t.points,i=t.chart,s=i.plotWidth,o=i.plotHeight,r=i.plotLeft,n=Math.round(i.chartWidth/3),a=t.center,c=a[2]/2,g=a[1],m=[[],[]],x=[0,0,0,0],y=t.dataLabelPositioners,b,v,S,k=0;t.visible&&t.hasDataLabels?.()&&(e.forEach(t=>{(t.dataLabels||[]).forEach(t=>{t.shortened&&(t.attr({width:\"auto\"}).css({width:\"auto\",textOverflow:\"clip\"}),t.shortened=!1)})}),l.prototype.drawDataLabels.apply(t),e.forEach(t=>{(t.dataLabels||[]).forEach((e,i)=>{let s=a[2]/2,o=e.options,r=f(o?.distance||0,s);0===i&&m[t.half].push(t),!p(o?.style?.width)&&e.getBBox().width>n&&(e.css({width:Math.round(.7*n)+\"px\"}),e.shortened=!0),e.dataLabelPosition=this.getDataLabelPosition(t,r),k=Math.max(k,r)})}),m.forEach((e,n)=>{let l=e.length,d=[],f,m,b=0,M;l&&(t.sortByAngle(e,n-.5),k>0&&(f=Math.max(0,g-c-k),m=Math.min(g+c+k,i.plotHeight),e.forEach(t=>{(t.dataLabels||[]).forEach((e,s)=>{let o=e.dataLabelPosition;o&&o.distance>0&&(o.top=Math.max(0,g-c-o.distance),o.bottom=Math.min(g+c+o.distance,i.plotHeight),b=e.getBBox().height||21,t.distributeBox={target:(e.dataLabelPosition?.natural.y||0)-o.top+b/2,size:b,rank:t.y},d.push(t.distributeBox))})}),h(d,M=m+b-f,M/5)),e.forEach(i=>{(i.dataLabels||[]).forEach(h=>{let l=h.options||{},g=i.distributeBox,f=h.dataLabelPosition,m=f?.natural.y||0,b=l.connectorPadding||0,k=0,M=m,C=\"inherit\";if(f){if(d&&p(g)&&f.distance>0&&(void 0===g.pos?C=\"hidden\":(S=g.size,M=y.radialDistributionY(i,h))),l.justify)k=y.justify(i,h,c,a);else switch(l.alignTo){case\"connectors\":k=y.alignToConnectors(e,n,s,r);break;case\"plotEdges\":k=y.alignToPlotEdges(h,n,s,r);break;default:k=y.radialDistributionX(t,i,M,m,h)}if(f.attribs={visibility:C,align:f.alignment},f.posAttribs={x:k+(l.x||0)+(({left:b,right:-b})[f.alignment]||0),y:M+(l.y||0)-h.getBBox().height/2},f.computed.x=k,f.computed.y=M,u(l.crop,!0)){let t;k-(v=h.getBBox().width)s-b&&0===n&&(t=Math.round(k+v-s+b),x[1]=Math.max(t,x[1])),M-S/2<0?x[0]=Math.max(Math.round(-M+S/2),x[0]):M+S/2>o&&(x[2]=Math.max(Math.round(M+S/2-o),x[2])),f.sideOverflow=t}}})}))}),(0===d(x)||this.verifyDataLabelOverflow(x))&&(this.placeDataLabels(),this.points.forEach(e=>{(e.dataLabels||[]).forEach(s=>{let{connectorColor:o,connectorWidth:r=1}=s.options||{},n=s.dataLabelPosition;if(r){let a;b=s.connector,n&&n.distance>0?(a=!b,b||(s.connector=b=i.renderer.path().addClass(\"highcharts-data-label-connector highcharts-color-\"+e.colorIndex+(e.className?\" \"+e.className:\"\")).add(t.dataLabelsGroup)),i.styledMode||b.attr({\"stroke-width\":r,stroke:o||e.color||\"#666666\"}),b[a?\"attr\":\"animate\"]({d:e.getConnectorPath(s)}),b.attr({visibility:n.attribs?.visibility})):b&&(s.connector=b.destroy())}})})))}function r(){this.points.forEach(t=>{(t.dataLabels||[]).forEach(t=>{let e=t.dataLabelPosition;e?(e.sideOverflow&&(t.css({width:Math.max(t.getBBox().width-e.sideOverflow,0)+\"px\",textOverflow:(t.options?.style||{}).textOverflow||\"ellipsis\"}),t.shortened=!0),t.attr(e.attribs),t[t.moved?\"animate\":\"attr\"](e.posAttribs),t.moved=!0):t&&t.attr({y:-9999})}),delete t.distributeBox},this)}function m(t){let e=this.center,i=this.options,s=i.center,o=i.minSize||80,r=o,n=null!==i.size;return!n&&(null!==s[0]?r=Math.max(e[2]-Math.max(t[1],t[3]),o):(r=Math.max(e[2]-t[1]-t[3],o),e[0]+=(t[3]-t[1])/2),null!==s[1]?r=c(r,o,e[2]-Math.max(t[0],t[2])):(r=c(r,o,e[2]-t[0]-t[2]),e[1]+=(t[0]-t[2])/2),r!(e.x>=t.x+t.width||e.x+e.width<=t.x||e.y>=t.y+t.height||e.y+e.height<=t.y),n=t=>{let e=t.box?0:t.padding||0,s,o,n,a=0,h=0,l,d;if(t&&(!t.alignAttr||t.placed))return s=t.alignAttr||{x:t.attr(\"x\"),y:t.attr(\"y\")},o=t.parentGroup,t.width||(n=t.getBBox(),t.width=n.width,t.height=n.height,a=i.fontMetrics(t.element).h),l=t.width-2*e,(d=({left:\"0\",center:\"0.5\",right:\"1\"})[t.alignValue])?h=+d*l:r(t.x)&&Math.round(t.x)!==t.translateX&&(h=t.x-(t.translateX||0)),{x:s.x+(o.translateX||0)+e-(h||0),y:s.y+(o.translateY||0)+e-a,width:t.width-2*e,height:(t.height||0)-2*e}},a,h,l,c,p,u=!1;for(let i=0;i(e.labelrank||0)-(t.labelrank||0));for(let i=0;i{n(t,t=>{t.label&&e.push(t.label)})});for(let i of t.series||[])if(i.visible&&i.hasDataLabels?.()){let s=i=>{for(let s of i)s.visible&&(s.dataLabels||[]).forEach(i=>{let o=i.options||{};i.labelrank=a(o.labelrank,s.labelrank,s.shapeArgs?.height),o.allowOverlap??Number(o.distance)>0?(i.oldOpacity=i.opacity,i.newOpacity=1,d(i,t)):e.push(i)})};s(i.nodes||[]),s(i.points)}this.hideOverlappingLabels(e)}return{compose:function t(e){if(h(i,t)){let t=e.prototype;t.hideOverlappingLabels=l,s(e,\"render\",c)}}}}),i(e,\"Extensions/BorderRadius.js\",[e[\"Core/Defaults.js\"],e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"]],function(t,e,i){let{defaultOptions:s}=t,{composed:o,noop:r}=e,{addEvent:n,extend:a,isObject:h,merge:l,pushUnique:d,relativeLength:c}=i,p={radius:0,scope:\"stack\",where:void 0},u=r,g=r;function f(t,e,i,s,o={}){let r=u(t,e,i,s,o),{innerR:n=0,r:a=i,start:h=0,end:l=0}=o;if(o.open||!o.borderRadius)return r;let d=l-h,p=Math.sin(d/2),g=Math.max(Math.min(c(o.borderRadius||0,a-n),(a-n)/2,a*p/(1+p)),0),f=Math.min(g,2*(d/Math.PI)*n),m=r.length-1;for(;m--;)!function(t,e,i){let s,o,r;let n=t[e],a=t[e+1];if(\"Z\"===a[0]&&(a=t[0]),(\"M\"===n[0]||\"L\"===n[0])&&\"A\"===a[0]?(s=n,o=a,r=!0):\"A\"===n[0]&&(\"M\"===a[0]||\"L\"===a[0])&&(s=a,o=n),s&&o&&o.params){let n=o[1],a=o[5],h=o.params,{start:l,end:d,cx:c,cy:p}=h,u=a?n-i:n+i,g=u?Math.asin(i/u):0,f=a?g:-g,m=Math.cos(g)*u;r?(h.start=l+f,s[1]=c+m*Math.cos(l),s[2]=p+m*Math.sin(l),t.splice(e+1,0,[\"A\",i,i,0,0,1,c+n*Math.cos(h.start),p+n*Math.sin(h.start)])):(h.end=d-f,o[6]=c+n*Math.cos(h.end),o[7]=p+n*Math.sin(h.end),t.splice(e+1,0,[\"A\",i,i,0,0,1,c+m*Math.cos(d),p+m*Math.sin(d)])),o[4]=Math.abs(h.end-h.start)1?f:g);return r}function m(){if(this.options.borderRadius&&!(this.chart.is3d&&this.chart.is3d())){let{options:t,yAxis:e}=this,i=\"percent\"===t.stacking,o=s.plotOptions?.[this.type]?.borderRadius,r=x(t.borderRadius,h(o)?o:{}),n=e.options.reversed;for(let s of this.points){let{shapeArgs:o}=s;if(\"roundedRect\"===s.shapeType&&o){let{width:h=0,height:l=0,y:d=0}=o,p=d,u=l;if(\"stack\"===r.scope&&s.stackTotal){let o=e.translate(i?100:s.stackTotal,!1,!0,!1,!0),r=e.translate(t.threshold||0,!1,!0,!1,!0),n=this.crispCol(0,Math.min(o,r),0,Math.abs(o-r));p=n.y,u=n.height}let g=(s.negative?-1:1)*(n?-1:1)==-1,f=r.where;!f&&this.is(\"waterfall\")&&Math.abs((s.yBottom||0)-(this.translatedThreshold||0))>this.borderWidth&&(f=\"all\"),f||(f=\"end\");let m=Math.min(c(r.radius,h),h/2,\"all\"===f?l/2:1/0)||0;\"end\"===f&&(g&&(p-=m),u+=m),a(o,{brBoxHeight:u,brBoxY:p,r:m})}}}}function x(t,e){return h(t)||(t={radius:t||0}),l(p,e,t)}function y(){let t=x(this.options.borderRadius);for(let e of this.points){let i=e.shapeArgs;i&&(i.borderRadius=c(t.radius,(i.r||0)-(i.innerR||0)))}}function b(t,e,i,s,o={}){let r=g(t,e,i,s,o),{r:n=0,brBoxHeight:a=s,brBoxY:h=e}=o,l=e-h,d=h+a-(e+s),c=l-n>-.1?0:n,p=d-n>-.1?0:n,u=Math.max(c&&l,0),f=Math.max(p&&d,0),m=[t+c,e],x=[t+i-c,e],y=[t+i,e+c],b=[t+i,e+s-p],v=[t+i-p,e+s],S=[t+p,e+s],k=[t,e+s-p],M=[t,e+c],C=(t,e)=>Math.sqrt(Math.pow(t,2)-Math.pow(e,2));if(u){let t=C(c,c-u);m[0]-=t,x[0]+=t,y[1]=M[1]=e+c-u}if(s=h(i.minWidth,0)&&this.chartHeight>=h(i.minHeight,0)};s.call(this)&&e.push(t._id)}function i(t,e){let i=this.options.responsive,s=this.currentResponsive,r=[],h;!e&&i&&i.rules&&i.rules.forEach(t=>{void 0===t._id&&(t._id=d()),this.matchResponsiveRule(t,r)},this);let l=a(...r.map(t=>n((i||{}).rules||[],e=>e._id===t)).map(t=>t&&t.chartOptions));l.isResponsiveOptions=!0,r=r.toString()||void 0;let c=s&&s.ruleIds;r!==c&&(s&&this.update(s.undoOptions,t,!0),r?((h=o(l,this.options,!0,this.collectionsWithUpdate)).isResponsiveOptions=!0,this.currentResponsive={ruleIds:r,mergedOptions:l,undoOptions:h},this.update(l,t,!0)):this.currentResponsive=void 0)}t.compose=function t(o){return l(s,t)&&r(o.prototype,{matchResponsiveRule:e,setResponsive:i}),o}}(i||(i={})),i}),i(e,\"masters/highcharts.src.js\",[e[\"Core/Globals.js\"],e[\"Core/Utilities.js\"],e[\"Core/Defaults.js\"],e[\"Core/Animation/Fx.js\"],e[\"Core/Animation/AnimationUtilities.js\"],e[\"Core/Renderer/HTML/AST.js\"],e[\"Core/Templating.js\"],e[\"Core/Renderer/RendererUtilities.js\"],e[\"Core/Renderer/SVG/SVGElement.js\"],e[\"Core/Renderer/SVG/SVGRenderer.js\"],e[\"Core/Renderer/HTML/HTMLElement.js\"],e[\"Core/Renderer/HTML/HTMLRenderer.js\"],e[\"Core/Axis/Axis.js\"],e[\"Core/Axis/DateTimeAxis.js\"],e[\"Core/Axis/LogarithmicAxis.js\"],e[\"Core/Axis/PlotLineOrBand/PlotLineOrBand.js\"],e[\"Core/Axis/Tick.js\"],e[\"Core/Tooltip.js\"],e[\"Core/Series/Point.js\"],e[\"Core/Pointer.js\"],e[\"Core/Legend/Legend.js\"],e[\"Core/Chart/Chart.js\"],e[\"Extensions/ScrollablePlotArea.js\"],e[\"Core/Axis/Stacking/StackingAxis.js\"],e[\"Core/Axis/Stacking/StackItem.js\"],e[\"Core/Series/Series.js\"],e[\"Core/Series/SeriesRegistry.js\"],e[\"Series/Column/ColumnSeries.js\"],e[\"Series/Column/ColumnDataLabel.js\"],e[\"Series/Pie/PieSeries.js\"],e[\"Series/Pie/PieDataLabel.js\"],e[\"Core/Series/DataLabel.js\"],e[\"Extensions/OverlappingDataLabels.js\"],e[\"Extensions/BorderRadius.js\"],e[\"Core/Responsive.js\"],e[\"Core/Color/Color.js\"],e[\"Core/Time.js\"]],function(t,e,i,s,o,r,n,a,h,l,d,c,p,u,g,f,m,x,y,b,v,S,k,M,C,w,T,A,P,L,O,D,E,j,I,B,R){return t.animate=o.animate,t.animObject=o.animObject,t.getDeferredAnimation=o.getDeferredAnimation,t.setAnimation=o.setAnimation,t.stop=o.stop,t.timers=s.timers,t.AST=r,t.Axis=p,t.Chart=S,t.chart=S.chart,t.Fx=s,t.Legend=v,t.PlotLineOrBand=f,t.Point=y,t.Pointer=b,t.Series=w,t.StackItem=C,t.SVGElement=h,t.SVGRenderer=l,t.Templating=n,t.Tick=m,t.Time=R,t.Tooltip=x,t.Color=B,t.color=B.parse,c.compose(l),d.compose(h),b.compose(S),v.compose(S),t.defaultOptions=i.defaultOptions,t.getOptions=i.getOptions,t.time=i.defaultTime,t.setOptions=i.setOptions,t.dateFormat=n.dateFormat,t.format=n.format,t.numberFormat=n.numberFormat,e.extend(t,e),t.distribute=a.distribute,t.seriesType=T.seriesType,P.compose(A),j.compose(w,L,h,l),D.compose(w),u.compose(p),g.compose(p),E.compose(S),O.compose(L),f.compose(p),I.compose(S),k.compose(p,S,w),M.compose(p,S,w),x.compose(b),t}),e[\"masters/highcharts.src.js\"]._modules=e,e[\"masters/highcharts.src.js\"]});", "/* eslint-disable no-multi-assign */\n\nfunction deepFreeze(obj) {\n if (obj instanceof Map) {\n obj.clear =\n obj.delete =\n obj.set =\n function () {\n throw new Error('map is read-only');\n };\n } else if (obj instanceof Set) {\n obj.add =\n obj.clear =\n obj.delete =\n function () {\n throw new Error('set is read-only');\n };\n }\n\n // Freeze self\n Object.freeze(obj);\n\n Object.getOwnPropertyNames(obj).forEach((name) => {\n const prop = obj[name];\n const type = typeof prop;\n\n // Freeze prop if it is an object or function and also not already frozen\n if ((type === 'object' || type === 'function') && !Object.isFrozen(prop)) {\n deepFreeze(prop);\n }\n });\n\n return obj;\n}\n\n/** @typedef {import('highlight.js').CallbackResponse} CallbackResponse */\n/** @typedef {import('highlight.js').CompiledMode} CompiledMode */\n/** @implements CallbackResponse */\n\nclass Response {\n /**\n * @param {CompiledMode} mode\n */\n constructor(mode) {\n // eslint-disable-next-line no-undefined\n if (mode.data === undefined) mode.data = {};\n\n this.data = mode.data;\n this.isMatchIgnored = false;\n }\n\n ignoreMatch() {\n this.isMatchIgnored = true;\n }\n}\n\n/**\n * @param {string} value\n * @returns {string}\n */\nfunction escapeHTML(value) {\n return value\n .replace(/&/g, '&')\n .replace(//g, '>')\n .replace(/\"/g, '"')\n .replace(/'/g, ''');\n}\n\n/**\n * performs a shallow merge of multiple objects into one\n *\n * @template T\n * @param {T} original\n * @param {Record[]} objects\n * @returns {T} a single new object\n */\nfunction inherit$1(original, ...objects) {\n /** @type Record */\n const result = Object.create(null);\n\n for (const key in original) {\n result[key] = original[key];\n }\n objects.forEach(function(obj) {\n for (const key in obj) {\n result[key] = obj[key];\n }\n });\n return /** @type {T} */ (result);\n}\n\n/**\n * @typedef {object} Renderer\n * @property {(text: string) => void} addText\n * @property {(node: Node) => void} openNode\n * @property {(node: Node) => void} closeNode\n * @property {() => string} value\n */\n\n/** @typedef {{scope?: string, language?: string, sublanguage?: boolean}} Node */\n/** @typedef {{walk: (r: Renderer) => void}} Tree */\n/** */\n\nconst SPAN_CLOSE = '';\n\n/**\n * Determines if a node needs to be wrapped in \n *\n * @param {Node} node */\nconst emitsWrappingTags = (node) => {\n // rarely we can have a sublanguage where language is undefined\n // TODO: track down why\n return !!node.scope;\n};\n\n/**\n *\n * @param {string} name\n * @param {{prefix:string}} options\n */\nconst scopeToCSSClass = (name, { prefix }) => {\n // sub-language\n if (name.startsWith(\"language:\")) {\n return name.replace(\"language:\", \"language-\");\n }\n // tiered scope: comment.line\n if (name.includes(\".\")) {\n const pieces = name.split(\".\");\n return [\n `${prefix}${pieces.shift()}`,\n ...(pieces.map((x, i) => `${x}${\"_\".repeat(i + 1)}`))\n ].join(\" \");\n }\n // simple scope\n return `${prefix}${name}`;\n};\n\n/** @type {Renderer} */\nclass HTMLRenderer {\n /**\n * Creates a new HTMLRenderer\n *\n * @param {Tree} parseTree - the parse tree (must support `walk` API)\n * @param {{classPrefix: string}} options\n */\n constructor(parseTree, options) {\n this.buffer = \"\";\n this.classPrefix = options.classPrefix;\n parseTree.walk(this);\n }\n\n /**\n * Adds texts to the output stream\n *\n * @param {string} text */\n addText(text) {\n this.buffer += escapeHTML(text);\n }\n\n /**\n * Adds a node open to the output stream (if needed)\n *\n * @param {Node} node */\n openNode(node) {\n if (!emitsWrappingTags(node)) return;\n\n const className = scopeToCSSClass(node.scope,\n { prefix: this.classPrefix });\n this.span(className);\n }\n\n /**\n * Adds a node close to the output stream (if needed)\n *\n * @param {Node} node */\n closeNode(node) {\n if (!emitsWrappingTags(node)) return;\n\n this.buffer += SPAN_CLOSE;\n }\n\n /**\n * returns the accumulated buffer\n */\n value() {\n return this.buffer;\n }\n\n // helpers\n\n /**\n * Builds a span element\n *\n * @param {string} className */\n span(className) {\n this.buffer += ``;\n }\n}\n\n/** @typedef {{scope?: string, language?: string, children: Node[]} | string} Node */\n/** @typedef {{scope?: string, language?: string, children: Node[]} } DataNode */\n/** @typedef {import('highlight.js').Emitter} Emitter */\n/** */\n\n/** @returns {DataNode} */\nconst newNode = (opts = {}) => {\n /** @type DataNode */\n const result = { children: [] };\n Object.assign(result, opts);\n return result;\n};\n\nclass TokenTree {\n constructor() {\n /** @type DataNode */\n this.rootNode = newNode();\n this.stack = [this.rootNode];\n }\n\n get top() {\n return this.stack[this.stack.length - 1];\n }\n\n get root() { return this.rootNode; }\n\n /** @param {Node} node */\n add(node) {\n this.top.children.push(node);\n }\n\n /** @param {string} scope */\n openNode(scope) {\n /** @type Node */\n const node = newNode({ scope });\n this.add(node);\n this.stack.push(node);\n }\n\n closeNode() {\n if (this.stack.length > 1) {\n return this.stack.pop();\n }\n // eslint-disable-next-line no-undefined\n return undefined;\n }\n\n closeAllNodes() {\n while (this.closeNode());\n }\n\n toJSON() {\n return JSON.stringify(this.rootNode, null, 4);\n }\n\n /**\n * @typedef { import(\"./html_renderer\").Renderer } Renderer\n * @param {Renderer} builder\n */\n walk(builder) {\n // this does not\n return this.constructor._walk(builder, this.rootNode);\n // this works\n // return TokenTree._walk(builder, this.rootNode);\n }\n\n /**\n * @param {Renderer} builder\n * @param {Node} node\n */\n static _walk(builder, node) {\n if (typeof node === \"string\") {\n builder.addText(node);\n } else if (node.children) {\n builder.openNode(node);\n node.children.forEach((child) => this._walk(builder, child));\n builder.closeNode(node);\n }\n return builder;\n }\n\n /**\n * @param {Node} node\n */\n static _collapse(node) {\n if (typeof node === \"string\") return;\n if (!node.children) return;\n\n if (node.children.every(el => typeof el === \"string\")) {\n // node.text = node.children.join(\"\");\n // delete node.children;\n node.children = [node.children.join(\"\")];\n } else {\n node.children.forEach((child) => {\n TokenTree._collapse(child);\n });\n }\n }\n}\n\n/**\n Currently this is all private API, but this is the minimal API necessary\n that an Emitter must implement to fully support the parser.\n\n Minimal interface:\n\n - addText(text)\n - __addSublanguage(emitter, subLanguageName)\n - startScope(scope)\n - endScope()\n - finalize()\n - toHTML()\n\n*/\n\n/**\n * @implements {Emitter}\n */\nclass TokenTreeEmitter extends TokenTree {\n /**\n * @param {*} options\n */\n constructor(options) {\n super();\n this.options = options;\n }\n\n /**\n * @param {string} text\n */\n addText(text) {\n if (text === \"\") { return; }\n\n this.add(text);\n }\n\n /** @param {string} scope */\n startScope(scope) {\n this.openNode(scope);\n }\n\n endScope() {\n this.closeNode();\n }\n\n /**\n * @param {Emitter & {root: DataNode}} emitter\n * @param {string} name\n */\n __addSublanguage(emitter, name) {\n /** @type DataNode */\n const node = emitter.root;\n if (name) node.scope = `language:${name}`;\n\n this.add(node);\n }\n\n toHTML() {\n const renderer = new HTMLRenderer(this, this.options);\n return renderer.value();\n }\n\n finalize() {\n this.closeAllNodes();\n return true;\n }\n}\n\n/**\n * @param {string} value\n * @returns {RegExp}\n * */\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction source(re) {\n if (!re) return null;\n if (typeof re === \"string\") return re;\n\n return re.source;\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction lookahead(re) {\n return concat('(?=', re, ')');\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction anyNumberOfTimes(re) {\n return concat('(?:', re, ')*');\n}\n\n/**\n * @param {RegExp | string } re\n * @returns {string}\n */\nfunction optional(re) {\n return concat('(?:', re, ')?');\n}\n\n/**\n * @param {...(RegExp | string) } args\n * @returns {string}\n */\nfunction concat(...args) {\n const joined = args.map((x) => source(x)).join(\"\");\n return joined;\n}\n\n/**\n * @param { Array } args\n * @returns {object}\n */\nfunction stripOptionsFromArgs(args) {\n const opts = args[args.length - 1];\n\n if (typeof opts === 'object' && opts.constructor === Object) {\n args.splice(args.length - 1, 1);\n return opts;\n } else {\n return {};\n }\n}\n\n/** @typedef { {capture?: boolean} } RegexEitherOptions */\n\n/**\n * Any of the passed expresssions may match\n *\n * Creates a huge this | this | that | that match\n * @param {(RegExp | string)[] | [...(RegExp | string)[], RegexEitherOptions]} args\n * @returns {string}\n */\nfunction either(...args) {\n /** @type { object & {capture?: boolean} } */\n const opts = stripOptionsFromArgs(args);\n const joined = '('\n + (opts.capture ? \"\" : \"?:\")\n + args.map((x) => source(x)).join(\"|\") + \")\";\n return joined;\n}\n\n/**\n * @param {RegExp | string} re\n * @returns {number}\n */\nfunction countMatchGroups(re) {\n return (new RegExp(re.toString() + '|')).exec('').length - 1;\n}\n\n/**\n * Does lexeme start with a regular expression match at the beginning\n * @param {RegExp} re\n * @param {string} lexeme\n */\nfunction startsWith(re, lexeme) {\n const match = re && re.exec(lexeme);\n return match && match.index === 0;\n}\n\n// BACKREF_RE matches an open parenthesis or backreference. To avoid\n// an incorrect parse, it additionally matches the following:\n// - [...] elements, where the meaning of parentheses and escapes change\n// - other escape sequences, so we do not misparse escape sequences as\n// interesting elements\n// - non-matching or lookahead parentheses, which do not capture. These\n// follow the '(' with a '?'.\nconst BACKREF_RE = /\\[(?:[^\\\\\\]]|\\\\.)*\\]|\\(\\??|\\\\([1-9][0-9]*)|\\\\./;\n\n// **INTERNAL** Not intended for outside usage\n// join logically computes regexps.join(separator), but fixes the\n// backreferences so they continue to match.\n// it also places each individual regular expression into it's own\n// match group, keeping track of the sequencing of those match groups\n// is currently an exercise for the caller. :-)\n/**\n * @param {(string | RegExp)[]} regexps\n * @param {{joinWith: string}} opts\n * @returns {string}\n */\nfunction _rewriteBackreferences(regexps, { joinWith }) {\n let numCaptures = 0;\n\n return regexps.map((regex) => {\n numCaptures += 1;\n const offset = numCaptures;\n let re = source(regex);\n let out = '';\n\n while (re.length > 0) {\n const match = BACKREF_RE.exec(re);\n if (!match) {\n out += re;\n break;\n }\n out += re.substring(0, match.index);\n re = re.substring(match.index + match[0].length);\n if (match[0][0] === '\\\\' && match[1]) {\n // Adjust the backreference.\n out += '\\\\' + String(Number(match[1]) + offset);\n } else {\n out += match[0];\n if (match[0] === '(') {\n numCaptures++;\n }\n }\n }\n return out;\n }).map(re => `(${re})`).join(joinWith);\n}\n\n/** @typedef {import('highlight.js').Mode} Mode */\n/** @typedef {import('highlight.js').ModeCallback} ModeCallback */\n\n// Common regexps\nconst MATCH_NOTHING_RE = /\\b\\B/;\nconst IDENT_RE = '[a-zA-Z]\\\\w*';\nconst UNDERSCORE_IDENT_RE = '[a-zA-Z_]\\\\w*';\nconst NUMBER_RE = '\\\\b\\\\d+(\\\\.\\\\d+)?';\nconst C_NUMBER_RE = '(-?)(\\\\b0[xX][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?|\\\\.\\\\d+)([eE][-+]?\\\\d+)?)'; // 0x..., 0..., decimal, float\nconst BINARY_NUMBER_RE = '\\\\b(0b[01]+)'; // 0b...\nconst RE_STARTERS_RE = '!|!=|!==|%|%=|&|&&|&=|\\\\*|\\\\*=|\\\\+|\\\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\\\?|\\\\[|\\\\{|\\\\(|\\\\^|\\\\^=|\\\\||\\\\|=|\\\\|\\\\||~';\n\n/**\n* @param { Partial & {binary?: string | RegExp} } opts\n*/\nconst SHEBANG = (opts = {}) => {\n const beginShebang = /^#![ ]*\\//;\n if (opts.binary) {\n opts.begin = concat(\n beginShebang,\n /.*\\b/,\n opts.binary,\n /\\b.*/);\n }\n return inherit$1({\n scope: 'meta',\n begin: beginShebang,\n end: /$/,\n relevance: 0,\n /** @type {ModeCallback} */\n \"on:begin\": (m, resp) => {\n if (m.index !== 0) resp.ignoreMatch();\n }\n }, opts);\n};\n\n// Common modes\nconst BACKSLASH_ESCAPE = {\n begin: '\\\\\\\\[\\\\s\\\\S]', relevance: 0\n};\nconst APOS_STRING_MODE = {\n scope: 'string',\n begin: '\\'',\n end: '\\'',\n illegal: '\\\\n',\n contains: [BACKSLASH_ESCAPE]\n};\nconst QUOTE_STRING_MODE = {\n scope: 'string',\n begin: '\"',\n end: '\"',\n illegal: '\\\\n',\n contains: [BACKSLASH_ESCAPE]\n};\nconst PHRASAL_WORDS_MODE = {\n begin: /\\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\\b/\n};\n/**\n * Creates a comment mode\n *\n * @param {string | RegExp} begin\n * @param {string | RegExp} end\n * @param {Mode | {}} [modeOptions]\n * @returns {Partial}\n */\nconst COMMENT = function(begin, end, modeOptions = {}) {\n const mode = inherit$1(\n {\n scope: 'comment',\n begin,\n end,\n contains: []\n },\n modeOptions\n );\n mode.contains.push({\n scope: 'doctag',\n // hack to avoid the space from being included. the space is necessary to\n // match here to prevent the plain text rule below from gobbling up doctags\n begin: '[ ]*(?=(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):)',\n end: /(TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):/,\n excludeBegin: true,\n relevance: 0\n });\n const ENGLISH_WORD = either(\n // list of common 1 and 2 letter words in English\n \"I\",\n \"a\",\n \"is\",\n \"so\",\n \"us\",\n \"to\",\n \"at\",\n \"if\",\n \"in\",\n \"it\",\n \"on\",\n // note: this is not an exhaustive list of contractions, just popular ones\n /[A-Za-z]+['](d|ve|re|ll|t|s|n)/, // contractions - can't we'd they're let's, etc\n /[A-Za-z]+[-][a-z]+/, // `no-way`, etc.\n /[A-Za-z][a-z]{2,}/ // allow capitalized words at beginning of sentences\n );\n // looking like plain text, more likely to be a comment\n mode.contains.push(\n {\n // TODO: how to include \", (, ) without breaking grammars that use these for\n // comment delimiters?\n // begin: /[ ]+([()\"]?([A-Za-z'-]{3,}|is|a|I|so|us|[tT][oO]|at|if|in|it|on)[.]?[()\":]?([.][ ]|[ ]|\\))){3}/\n // ---\n\n // this tries to find sequences of 3 english words in a row (without any\n // \"programming\" type syntax) this gives us a strong signal that we've\n // TRULY found a comment - vs perhaps scanning with the wrong language.\n // It's possible to find something that LOOKS like the start of the\n // comment - but then if there is no readable text - good chance it is a\n // false match and not a comment.\n //\n // for a visual example please see:\n // https://github.com/highlightjs/highlight.js/issues/2827\n\n begin: concat(\n /[ ]+/, // necessary to prevent us gobbling up doctags like /* @author Bob Mcgill */\n '(',\n ENGLISH_WORD,\n /[.]?[:]?([.][ ]|[ ])/,\n '){3}') // look for 3 words in a row\n }\n );\n return mode;\n};\nconst C_LINE_COMMENT_MODE = COMMENT('//', '$');\nconst C_BLOCK_COMMENT_MODE = COMMENT('/\\\\*', '\\\\*/');\nconst HASH_COMMENT_MODE = COMMENT('#', '$');\nconst NUMBER_MODE = {\n scope: 'number',\n begin: NUMBER_RE,\n relevance: 0\n};\nconst C_NUMBER_MODE = {\n scope: 'number',\n begin: C_NUMBER_RE,\n relevance: 0\n};\nconst BINARY_NUMBER_MODE = {\n scope: 'number',\n begin: BINARY_NUMBER_RE,\n relevance: 0\n};\nconst REGEXP_MODE = {\n scope: \"regexp\",\n begin: /\\/(?=[^/\\n]*\\/)/,\n end: /\\/[gimuy]*/,\n contains: [\n BACKSLASH_ESCAPE,\n {\n begin: /\\[/,\n end: /\\]/,\n relevance: 0,\n contains: [BACKSLASH_ESCAPE]\n }\n ]\n};\nconst TITLE_MODE = {\n scope: 'title',\n begin: IDENT_RE,\n relevance: 0\n};\nconst UNDERSCORE_TITLE_MODE = {\n scope: 'title',\n begin: UNDERSCORE_IDENT_RE,\n relevance: 0\n};\nconst METHOD_GUARD = {\n // excludes method names from keyword processing\n begin: '\\\\.\\\\s*' + UNDERSCORE_IDENT_RE,\n relevance: 0\n};\n\n/**\n * Adds end same as begin mechanics to a mode\n *\n * Your mode must include at least a single () match group as that first match\n * group is what is used for comparison\n * @param {Partial} mode\n */\nconst END_SAME_AS_BEGIN = function(mode) {\n return Object.assign(mode,\n {\n /** @type {ModeCallback} */\n 'on:begin': (m, resp) => { resp.data._beginMatch = m[1]; },\n /** @type {ModeCallback} */\n 'on:end': (m, resp) => { if (resp.data._beginMatch !== m[1]) resp.ignoreMatch(); }\n });\n};\n\nvar MODES = /*#__PURE__*/Object.freeze({\n __proto__: null,\n APOS_STRING_MODE: APOS_STRING_MODE,\n BACKSLASH_ESCAPE: BACKSLASH_ESCAPE,\n BINARY_NUMBER_MODE: BINARY_NUMBER_MODE,\n BINARY_NUMBER_RE: BINARY_NUMBER_RE,\n COMMENT: COMMENT,\n C_BLOCK_COMMENT_MODE: C_BLOCK_COMMENT_MODE,\n C_LINE_COMMENT_MODE: C_LINE_COMMENT_MODE,\n C_NUMBER_MODE: C_NUMBER_MODE,\n C_NUMBER_RE: C_NUMBER_RE,\n END_SAME_AS_BEGIN: END_SAME_AS_BEGIN,\n HASH_COMMENT_MODE: HASH_COMMENT_MODE,\n IDENT_RE: IDENT_RE,\n MATCH_NOTHING_RE: MATCH_NOTHING_RE,\n METHOD_GUARD: METHOD_GUARD,\n NUMBER_MODE: NUMBER_MODE,\n NUMBER_RE: NUMBER_RE,\n PHRASAL_WORDS_MODE: PHRASAL_WORDS_MODE,\n QUOTE_STRING_MODE: QUOTE_STRING_MODE,\n REGEXP_MODE: REGEXP_MODE,\n RE_STARTERS_RE: RE_STARTERS_RE,\n SHEBANG: SHEBANG,\n TITLE_MODE: TITLE_MODE,\n UNDERSCORE_IDENT_RE: UNDERSCORE_IDENT_RE,\n UNDERSCORE_TITLE_MODE: UNDERSCORE_TITLE_MODE\n});\n\n/**\n@typedef {import('highlight.js').CallbackResponse} CallbackResponse\n@typedef {import('highlight.js').CompilerExt} CompilerExt\n*/\n\n// Grammar extensions / plugins\n// See: https://github.com/highlightjs/highlight.js/issues/2833\n\n// Grammar extensions allow \"syntactic sugar\" to be added to the grammar modes\n// without requiring any underlying changes to the compiler internals.\n\n// `compileMatch` being the perfect small example of now allowing a grammar\n// author to write `match` when they desire to match a single expression rather\n// than being forced to use `begin`. The extension then just moves `match` into\n// `begin` when it runs. Ie, no features have been added, but we've just made\n// the experience of writing (and reading grammars) a little bit nicer.\n\n// ------\n\n// TODO: We need negative look-behind support to do this properly\n/**\n * Skip a match if it has a preceding dot\n *\n * This is used for `beginKeywords` to prevent matching expressions such as\n * `bob.keyword.do()`. The mode compiler automatically wires this up as a\n * special _internal_ 'on:begin' callback for modes with `beginKeywords`\n * @param {RegExpMatchArray} match\n * @param {CallbackResponse} response\n */\nfunction skipIfHasPrecedingDot(match, response) {\n const before = match.input[match.index - 1];\n if (before === \".\") {\n response.ignoreMatch();\n }\n}\n\n/**\n *\n * @type {CompilerExt}\n */\nfunction scopeClassName(mode, _parent) {\n // eslint-disable-next-line no-undefined\n if (mode.className !== undefined) {\n mode.scope = mode.className;\n delete mode.className;\n }\n}\n\n/**\n * `beginKeywords` syntactic sugar\n * @type {CompilerExt}\n */\nfunction beginKeywords(mode, parent) {\n if (!parent) return;\n if (!mode.beginKeywords) return;\n\n // for languages with keywords that include non-word characters checking for\n // a word boundary is not sufficient, so instead we check for a word boundary\n // or whitespace - this does no harm in any case since our keyword engine\n // doesn't allow spaces in keywords anyways and we still check for the boundary\n // first\n mode.begin = '\\\\b(' + mode.beginKeywords.split(' ').join('|') + ')(?!\\\\.)(?=\\\\b|\\\\s)';\n mode.__beforeBegin = skipIfHasPrecedingDot;\n mode.keywords = mode.keywords || mode.beginKeywords;\n delete mode.beginKeywords;\n\n // prevents double relevance, the keywords themselves provide\n // relevance, the mode doesn't need to double it\n // eslint-disable-next-line no-undefined\n if (mode.relevance === undefined) mode.relevance = 0;\n}\n\n/**\n * Allow `illegal` to contain an array of illegal values\n * @type {CompilerExt}\n */\nfunction compileIllegal(mode, _parent) {\n if (!Array.isArray(mode.illegal)) return;\n\n mode.illegal = either(...mode.illegal);\n}\n\n/**\n * `match` to match a single expression for readability\n * @type {CompilerExt}\n */\nfunction compileMatch(mode, _parent) {\n if (!mode.match) return;\n if (mode.begin || mode.end) throw new Error(\"begin & end are not supported with match\");\n\n mode.begin = mode.match;\n delete mode.match;\n}\n\n/**\n * provides the default 1 relevance to all modes\n * @type {CompilerExt}\n */\nfunction compileRelevance(mode, _parent) {\n // eslint-disable-next-line no-undefined\n if (mode.relevance === undefined) mode.relevance = 1;\n}\n\n// allow beforeMatch to act as a \"qualifier\" for the match\n// the full match begin must be [beforeMatch][begin]\nconst beforeMatchExt = (mode, parent) => {\n if (!mode.beforeMatch) return;\n // starts conflicts with endsParent which we need to make sure the child\n // rule is not matched multiple times\n if (mode.starts) throw new Error(\"beforeMatch cannot be used with starts\");\n\n const originalMode = Object.assign({}, mode);\n Object.keys(mode).forEach((key) => { delete mode[key]; });\n\n mode.keywords = originalMode.keywords;\n mode.begin = concat(originalMode.beforeMatch, lookahead(originalMode.begin));\n mode.starts = {\n relevance: 0,\n contains: [\n Object.assign(originalMode, { endsParent: true })\n ]\n };\n mode.relevance = 0;\n\n delete originalMode.beforeMatch;\n};\n\n// keywords that should have no default relevance value\nconst COMMON_KEYWORDS = [\n 'of',\n 'and',\n 'for',\n 'in',\n 'not',\n 'or',\n 'if',\n 'then',\n 'parent', // common variable name\n 'list', // common variable name\n 'value' // common variable name\n];\n\nconst DEFAULT_KEYWORD_SCOPE = \"keyword\";\n\n/**\n * Given raw keywords from a language definition, compile them.\n *\n * @param {string | Record | Array} rawKeywords\n * @param {boolean} caseInsensitive\n */\nfunction compileKeywords(rawKeywords, caseInsensitive, scopeName = DEFAULT_KEYWORD_SCOPE) {\n /** @type {import(\"highlight.js/private\").KeywordDict} */\n const compiledKeywords = Object.create(null);\n\n // input can be a string of keywords, an array of keywords, or a object with\n // named keys representing scopeName (which can then point to a string or array)\n if (typeof rawKeywords === 'string') {\n compileList(scopeName, rawKeywords.split(\" \"));\n } else if (Array.isArray(rawKeywords)) {\n compileList(scopeName, rawKeywords);\n } else {\n Object.keys(rawKeywords).forEach(function(scopeName) {\n // collapse all our objects back into the parent object\n Object.assign(\n compiledKeywords,\n compileKeywords(rawKeywords[scopeName], caseInsensitive, scopeName)\n );\n });\n }\n return compiledKeywords;\n\n // ---\n\n /**\n * Compiles an individual list of keywords\n *\n * Ex: \"for if when while|5\"\n *\n * @param {string} scopeName\n * @param {Array} keywordList\n */\n function compileList(scopeName, keywordList) {\n if (caseInsensitive) {\n keywordList = keywordList.map(x => x.toLowerCase());\n }\n keywordList.forEach(function(keyword) {\n const pair = keyword.split('|');\n compiledKeywords[pair[0]] = [scopeName, scoreForKeyword(pair[0], pair[1])];\n });\n }\n}\n\n/**\n * Returns the proper score for a given keyword\n *\n * Also takes into account comment keywords, which will be scored 0 UNLESS\n * another score has been manually assigned.\n * @param {string} keyword\n * @param {string} [providedScore]\n */\nfunction scoreForKeyword(keyword, providedScore) {\n // manual scores always win over common keywords\n // so you can force a score of 1 if you really insist\n if (providedScore) {\n return Number(providedScore);\n }\n\n return commonKeyword(keyword) ? 0 : 1;\n}\n\n/**\n * Determines if a given keyword is common or not\n *\n * @param {string} keyword */\nfunction commonKeyword(keyword) {\n return COMMON_KEYWORDS.includes(keyword.toLowerCase());\n}\n\n/*\n\nFor the reasoning behind this please see:\nhttps://github.com/highlightjs/highlight.js/issues/2880#issuecomment-747275419\n\n*/\n\n/**\n * @type {Record}\n */\nconst seenDeprecations = {};\n\n/**\n * @param {string} message\n */\nconst error = (message) => {\n console.error(message);\n};\n\n/**\n * @param {string} message\n * @param {any} args\n */\nconst warn = (message, ...args) => {\n console.log(`WARN: ${message}`, ...args);\n};\n\n/**\n * @param {string} version\n * @param {string} message\n */\nconst deprecated = (version, message) => {\n if (seenDeprecations[`${version}/${message}`]) return;\n\n console.log(`Deprecated as of ${version}. ${message}`);\n seenDeprecations[`${version}/${message}`] = true;\n};\n\n/* eslint-disable no-throw-literal */\n\n/**\n@typedef {import('highlight.js').CompiledMode} CompiledMode\n*/\n\nconst MultiClassError = new Error();\n\n/**\n * Renumbers labeled scope names to account for additional inner match\n * groups that otherwise would break everything.\n *\n * Lets say we 3 match scopes:\n *\n * { 1 => ..., 2 => ..., 3 => ... }\n *\n * So what we need is a clean match like this:\n *\n * (a)(b)(c) => [ \"a\", \"b\", \"c\" ]\n *\n * But this falls apart with inner match groups:\n *\n * (a)(((b)))(c) => [\"a\", \"b\", \"b\", \"b\", \"c\" ]\n *\n * Our scopes are now \"out of alignment\" and we're repeating `b` 3 times.\n * What needs to happen is the numbers are remapped:\n *\n * { 1 => ..., 2 => ..., 5 => ... }\n *\n * We also need to know that the ONLY groups that should be output\n * are 1, 2, and 5. This function handles this behavior.\n *\n * @param {CompiledMode} mode\n * @param {Array} regexes\n * @param {{key: \"beginScope\"|\"endScope\"}} opts\n */\nfunction remapScopeNames(mode, regexes, { key }) {\n let offset = 0;\n const scopeNames = mode[key];\n /** @type Record */\n const emit = {};\n /** @type Record */\n const positions = {};\n\n for (let i = 1; i <= regexes.length; i++) {\n positions[i + offset] = scopeNames[i];\n emit[i + offset] = true;\n offset += countMatchGroups(regexes[i - 1]);\n }\n // we use _emit to keep track of which match groups are \"top-level\" to avoid double\n // output from inside match groups\n mode[key] = positions;\n mode[key]._emit = emit;\n mode[key]._multi = true;\n}\n\n/**\n * @param {CompiledMode} mode\n */\nfunction beginMultiClass(mode) {\n if (!Array.isArray(mode.begin)) return;\n\n if (mode.skip || mode.excludeBegin || mode.returnBegin) {\n error(\"skip, excludeBegin, returnBegin not compatible with beginScope: {}\");\n throw MultiClassError;\n }\n\n if (typeof mode.beginScope !== \"object\" || mode.beginScope === null) {\n error(\"beginScope must be object\");\n throw MultiClassError;\n }\n\n remapScopeNames(mode, mode.begin, { key: \"beginScope\" });\n mode.begin = _rewriteBackreferences(mode.begin, { joinWith: \"\" });\n}\n\n/**\n * @param {CompiledMode} mode\n */\nfunction endMultiClass(mode) {\n if (!Array.isArray(mode.end)) return;\n\n if (mode.skip || mode.excludeEnd || mode.returnEnd) {\n error(\"skip, excludeEnd, returnEnd not compatible with endScope: {}\");\n throw MultiClassError;\n }\n\n if (typeof mode.endScope !== \"object\" || mode.endScope === null) {\n error(\"endScope must be object\");\n throw MultiClassError;\n }\n\n remapScopeNames(mode, mode.end, { key: \"endScope\" });\n mode.end = _rewriteBackreferences(mode.end, { joinWith: \"\" });\n}\n\n/**\n * this exists only to allow `scope: {}` to be used beside `match:`\n * Otherwise `beginScope` would necessary and that would look weird\n\n {\n match: [ /def/, /\\w+/ ]\n scope: { 1: \"keyword\" , 2: \"title\" }\n }\n\n * @param {CompiledMode} mode\n */\nfunction scopeSugar(mode) {\n if (mode.scope && typeof mode.scope === \"object\" && mode.scope !== null) {\n mode.beginScope = mode.scope;\n delete mode.scope;\n }\n}\n\n/**\n * @param {CompiledMode} mode\n */\nfunction MultiClass(mode) {\n scopeSugar(mode);\n\n if (typeof mode.beginScope === \"string\") {\n mode.beginScope = { _wrap: mode.beginScope };\n }\n if (typeof mode.endScope === \"string\") {\n mode.endScope = { _wrap: mode.endScope };\n }\n\n beginMultiClass(mode);\n endMultiClass(mode);\n}\n\n/**\n@typedef {import('highlight.js').Mode} Mode\n@typedef {import('highlight.js').CompiledMode} CompiledMode\n@typedef {import('highlight.js').Language} Language\n@typedef {import('highlight.js').HLJSPlugin} HLJSPlugin\n@typedef {import('highlight.js').CompiledLanguage} CompiledLanguage\n*/\n\n// compilation\n\n/**\n * Compiles a language definition result\n *\n * Given the raw result of a language definition (Language), compiles this so\n * that it is ready for highlighting code.\n * @param {Language} language\n * @returns {CompiledLanguage}\n */\nfunction compileLanguage(language) {\n /**\n * Builds a regex with the case sensitivity of the current language\n *\n * @param {RegExp | string} value\n * @param {boolean} [global]\n */\n function langRe(value, global) {\n return new RegExp(\n source(value),\n 'm'\n + (language.case_insensitive ? 'i' : '')\n + (language.unicodeRegex ? 'u' : '')\n + (global ? 'g' : '')\n );\n }\n\n /**\n Stores multiple regular expressions and allows you to quickly search for\n them all in a string simultaneously - returning the first match. It does\n this by creating a huge (a|b|c) regex - each individual item wrapped with ()\n and joined by `|` - using match groups to track position. When a match is\n found checking which position in the array has content allows us to figure\n out which of the original regexes / match groups triggered the match.\n\n The match object itself (the result of `Regex.exec`) is returned but also\n enhanced by merging in any meta-data that was registered with the regex.\n This is how we keep track of which mode matched, and what type of rule\n (`illegal`, `begin`, end, etc).\n */\n class MultiRegex {\n constructor() {\n this.matchIndexes = {};\n // @ts-ignore\n this.regexes = [];\n this.matchAt = 1;\n this.position = 0;\n }\n\n // @ts-ignore\n addRule(re, opts) {\n opts.position = this.position++;\n // @ts-ignore\n this.matchIndexes[this.matchAt] = opts;\n this.regexes.push([opts, re]);\n this.matchAt += countMatchGroups(re) + 1;\n }\n\n compile() {\n if (this.regexes.length === 0) {\n // avoids the need to check length every time exec is called\n // @ts-ignore\n this.exec = () => null;\n }\n const terminators = this.regexes.map(el => el[1]);\n this.matcherRe = langRe(_rewriteBackreferences(terminators, { joinWith: '|' }), true);\n this.lastIndex = 0;\n }\n\n /** @param {string} s */\n exec(s) {\n this.matcherRe.lastIndex = this.lastIndex;\n const match = this.matcherRe.exec(s);\n if (!match) { return null; }\n\n // eslint-disable-next-line no-undefined\n const i = match.findIndex((el, i) => i > 0 && el !== undefined);\n // @ts-ignore\n const matchData = this.matchIndexes[i];\n // trim off any earlier non-relevant match groups (ie, the other regex\n // match groups that make up the multi-matcher)\n match.splice(0, i);\n\n return Object.assign(match, matchData);\n }\n }\n\n /*\n Created to solve the key deficiently with MultiRegex - there is no way to\n test for multiple matches at a single location. Why would we need to do\n that? In the future a more dynamic engine will allow certain matches to be\n ignored. An example: if we matched say the 3rd regex in a large group but\n decided to ignore it - we'd need to started testing again at the 4th\n regex... but MultiRegex itself gives us no real way to do that.\n\n So what this class creates MultiRegexs on the fly for whatever search\n position they are needed.\n\n NOTE: These additional MultiRegex objects are created dynamically. For most\n grammars most of the time we will never actually need anything more than the\n first MultiRegex - so this shouldn't have too much overhead.\n\n Say this is our search group, and we match regex3, but wish to ignore it.\n\n regex1 | regex2 | regex3 | regex4 | regex5 ' ie, startAt = 0\n\n What we need is a new MultiRegex that only includes the remaining\n possibilities:\n\n regex4 | regex5 ' ie, startAt = 3\n\n This class wraps all that complexity up in a simple API... `startAt` decides\n where in the array of expressions to start doing the matching. It\n auto-increments, so if a match is found at position 2, then startAt will be\n set to 3. If the end is reached startAt will return to 0.\n\n MOST of the time the parser will be setting startAt manually to 0.\n */\n class ResumableMultiRegex {\n constructor() {\n // @ts-ignore\n this.rules = [];\n // @ts-ignore\n this.multiRegexes = [];\n this.count = 0;\n\n this.lastIndex = 0;\n this.regexIndex = 0;\n }\n\n // @ts-ignore\n getMatcher(index) {\n if (this.multiRegexes[index]) return this.multiRegexes[index];\n\n const matcher = new MultiRegex();\n this.rules.slice(index).forEach(([re, opts]) => matcher.addRule(re, opts));\n matcher.compile();\n this.multiRegexes[index] = matcher;\n return matcher;\n }\n\n resumingScanAtSamePosition() {\n return this.regexIndex !== 0;\n }\n\n considerAll() {\n this.regexIndex = 0;\n }\n\n // @ts-ignore\n addRule(re, opts) {\n this.rules.push([re, opts]);\n if (opts.type === \"begin\") this.count++;\n }\n\n /** @param {string} s */\n exec(s) {\n const m = this.getMatcher(this.regexIndex);\n m.lastIndex = this.lastIndex;\n let result = m.exec(s);\n\n // The following is because we have no easy way to say \"resume scanning at the\n // existing position but also skip the current rule ONLY\". What happens is\n // all prior rules are also skipped which can result in matching the wrong\n // thing. Example of matching \"booger\":\n\n // our matcher is [string, \"booger\", number]\n //\n // ....booger....\n\n // if \"booger\" is ignored then we'd really need a regex to scan from the\n // SAME position for only: [string, number] but ignoring \"booger\" (if it\n // was the first match), a simple resume would scan ahead who knows how\n // far looking only for \"number\", ignoring potential string matches (or\n // future \"booger\" matches that might be valid.)\n\n // So what we do: We execute two matchers, one resuming at the same\n // position, but the second full matcher starting at the position after:\n\n // /--- resume first regex match here (for [number])\n // |/---- full match here for [string, \"booger\", number]\n // vv\n // ....booger....\n\n // Which ever results in a match first is then used. So this 3-4 step\n // process essentially allows us to say \"match at this position, excluding\n // a prior rule that was ignored\".\n //\n // 1. Match \"booger\" first, ignore. Also proves that [string] does non match.\n // 2. Resume matching for [number]\n // 3. Match at index + 1 for [string, \"booger\", number]\n // 4. If #2 and #3 result in matches, which came first?\n if (this.resumingScanAtSamePosition()) {\n if (result && result.index === this.lastIndex) ; else { // use the second matcher result\n const m2 = this.getMatcher(0);\n m2.lastIndex = this.lastIndex + 1;\n result = m2.exec(s);\n }\n }\n\n if (result) {\n this.regexIndex += result.position + 1;\n if (this.regexIndex === this.count) {\n // wrap-around to considering all matches again\n this.considerAll();\n }\n }\n\n return result;\n }\n }\n\n /**\n * Given a mode, builds a huge ResumableMultiRegex that can be used to walk\n * the content and find matches.\n *\n * @param {CompiledMode} mode\n * @returns {ResumableMultiRegex}\n */\n function buildModeRegex(mode) {\n const mm = new ResumableMultiRegex();\n\n mode.contains.forEach(term => mm.addRule(term.begin, { rule: term, type: \"begin\" }));\n\n if (mode.terminatorEnd) {\n mm.addRule(mode.terminatorEnd, { type: \"end\" });\n }\n if (mode.illegal) {\n mm.addRule(mode.illegal, { type: \"illegal\" });\n }\n\n return mm;\n }\n\n /** skip vs abort vs ignore\n *\n * @skip - The mode is still entered and exited normally (and contains rules apply),\n * but all content is held and added to the parent buffer rather than being\n * output when the mode ends. Mostly used with `sublanguage` to build up\n * a single large buffer than can be parsed by sublanguage.\n *\n * - The mode begin ands ends normally.\n * - Content matched is added to the parent mode buffer.\n * - The parser cursor is moved forward normally.\n *\n * @abort - A hack placeholder until we have ignore. Aborts the mode (as if it\n * never matched) but DOES NOT continue to match subsequent `contains`\n * modes. Abort is bad/suboptimal because it can result in modes\n * farther down not getting applied because an earlier rule eats the\n * content but then aborts.\n *\n * - The mode does not begin.\n * - Content matched by `begin` is added to the mode buffer.\n * - The parser cursor is moved forward accordingly.\n *\n * @ignore - Ignores the mode (as if it never matched) and continues to match any\n * subsequent `contains` modes. Ignore isn't technically possible with\n * the current parser implementation.\n *\n * - The mode does not begin.\n * - Content matched by `begin` is ignored.\n * - The parser cursor is not moved forward.\n */\n\n /**\n * Compiles an individual mode\n *\n * This can raise an error if the mode contains certain detectable known logic\n * issues.\n * @param {Mode} mode\n * @param {CompiledMode | null} [parent]\n * @returns {CompiledMode | never}\n */\n function compileMode(mode, parent) {\n const cmode = /** @type CompiledMode */ (mode);\n if (mode.isCompiled) return cmode;\n\n [\n scopeClassName,\n // do this early so compiler extensions generally don't have to worry about\n // the distinction between match/begin\n compileMatch,\n MultiClass,\n beforeMatchExt\n ].forEach(ext => ext(mode, parent));\n\n language.compilerExtensions.forEach(ext => ext(mode, parent));\n\n // __beforeBegin is considered private API, internal use only\n mode.__beforeBegin = null;\n\n [\n beginKeywords,\n // do this later so compiler extensions that come earlier have access to the\n // raw array if they wanted to perhaps manipulate it, etc.\n compileIllegal,\n // default to 1 relevance if not specified\n compileRelevance\n ].forEach(ext => ext(mode, parent));\n\n mode.isCompiled = true;\n\n let keywordPattern = null;\n if (typeof mode.keywords === \"object\" && mode.keywords.$pattern) {\n // we need a copy because keywords might be compiled multiple times\n // so we can't go deleting $pattern from the original on the first\n // pass\n mode.keywords = Object.assign({}, mode.keywords);\n keywordPattern = mode.keywords.$pattern;\n delete mode.keywords.$pattern;\n }\n keywordPattern = keywordPattern || /\\w+/;\n\n if (mode.keywords) {\n mode.keywords = compileKeywords(mode.keywords, language.case_insensitive);\n }\n\n cmode.keywordPatternRe = langRe(keywordPattern, true);\n\n if (parent) {\n if (!mode.begin) mode.begin = /\\B|\\b/;\n cmode.beginRe = langRe(cmode.begin);\n if (!mode.end && !mode.endsWithParent) mode.end = /\\B|\\b/;\n if (mode.end) cmode.endRe = langRe(cmode.end);\n cmode.terminatorEnd = source(cmode.end) || '';\n if (mode.endsWithParent && parent.terminatorEnd) {\n cmode.terminatorEnd += (mode.end ? '|' : '') + parent.terminatorEnd;\n }\n }\n if (mode.illegal) cmode.illegalRe = langRe(/** @type {RegExp | string} */ (mode.illegal));\n if (!mode.contains) mode.contains = [];\n\n mode.contains = [].concat(...mode.contains.map(function(c) {\n return expandOrCloneMode(c === 'self' ? mode : c);\n }));\n mode.contains.forEach(function(c) { compileMode(/** @type Mode */ (c), cmode); });\n\n if (mode.starts) {\n compileMode(mode.starts, parent);\n }\n\n cmode.matcher = buildModeRegex(cmode);\n return cmode;\n }\n\n if (!language.compilerExtensions) language.compilerExtensions = [];\n\n // self is not valid at the top-level\n if (language.contains && language.contains.includes('self')) {\n throw new Error(\"ERR: contains `self` is not supported at the top-level of a language. See documentation.\");\n }\n\n // we need a null object, which inherit will guarantee\n language.classNameAliases = inherit$1(language.classNameAliases || {});\n\n return compileMode(/** @type Mode */ (language));\n}\n\n/**\n * Determines if a mode has a dependency on it's parent or not\n *\n * If a mode does have a parent dependency then often we need to clone it if\n * it's used in multiple places so that each copy points to the correct parent,\n * where-as modes without a parent can often safely be re-used at the bottom of\n * a mode chain.\n *\n * @param {Mode | null} mode\n * @returns {boolean} - is there a dependency on the parent?\n * */\nfunction dependencyOnParent(mode) {\n if (!mode) return false;\n\n return mode.endsWithParent || dependencyOnParent(mode.starts);\n}\n\n/**\n * Expands a mode or clones it if necessary\n *\n * This is necessary for modes with parental dependenceis (see notes on\n * `dependencyOnParent`) and for nodes that have `variants` - which must then be\n * exploded into their own individual modes at compile time.\n *\n * @param {Mode} mode\n * @returns {Mode | Mode[]}\n * */\nfunction expandOrCloneMode(mode) {\n if (mode.variants && !mode.cachedVariants) {\n mode.cachedVariants = mode.variants.map(function(variant) {\n return inherit$1(mode, { variants: null }, variant);\n });\n }\n\n // EXPAND\n // if we have variants then essentially \"replace\" the mode with the variants\n // this happens in compileMode, where this function is called from\n if (mode.cachedVariants) {\n return mode.cachedVariants;\n }\n\n // CLONE\n // if we have dependencies on parents then we need a unique\n // instance of ourselves, so we can be reused with many\n // different parents without issue\n if (dependencyOnParent(mode)) {\n return inherit$1(mode, { starts: mode.starts ? inherit$1(mode.starts) : null });\n }\n\n if (Object.isFrozen(mode)) {\n return inherit$1(mode);\n }\n\n // no special dependency issues, just return ourselves\n return mode;\n}\n\nvar version = \"11.10.0\";\n\nclass HTMLInjectionError extends Error {\n constructor(reason, html) {\n super(reason);\n this.name = \"HTMLInjectionError\";\n this.html = html;\n }\n}\n\n/*\nSyntax highlighting with language autodetection.\nhttps://highlightjs.org/\n*/\n\n\n\n/**\n@typedef {import('highlight.js').Mode} Mode\n@typedef {import('highlight.js').CompiledMode} CompiledMode\n@typedef {import('highlight.js').CompiledScope} CompiledScope\n@typedef {import('highlight.js').Language} Language\n@typedef {import('highlight.js').HLJSApi} HLJSApi\n@typedef {import('highlight.js').HLJSPlugin} HLJSPlugin\n@typedef {import('highlight.js').PluginEvent} PluginEvent\n@typedef {import('highlight.js').HLJSOptions} HLJSOptions\n@typedef {import('highlight.js').LanguageFn} LanguageFn\n@typedef {import('highlight.js').HighlightedHTMLElement} HighlightedHTMLElement\n@typedef {import('highlight.js').BeforeHighlightContext} BeforeHighlightContext\n@typedef {import('highlight.js/private').MatchType} MatchType\n@typedef {import('highlight.js/private').KeywordData} KeywordData\n@typedef {import('highlight.js/private').EnhancedMatch} EnhancedMatch\n@typedef {import('highlight.js/private').AnnotatedError} AnnotatedError\n@typedef {import('highlight.js').AutoHighlightResult} AutoHighlightResult\n@typedef {import('highlight.js').HighlightOptions} HighlightOptions\n@typedef {import('highlight.js').HighlightResult} HighlightResult\n*/\n\n\nconst escape = escapeHTML;\nconst inherit = inherit$1;\nconst NO_MATCH = Symbol(\"nomatch\");\nconst MAX_KEYWORD_HITS = 7;\n\n/**\n * @param {any} hljs - object that is extended (legacy)\n * @returns {HLJSApi}\n */\nconst HLJS = function(hljs) {\n // Global internal variables used within the highlight.js library.\n /** @type {Record} */\n const languages = Object.create(null);\n /** @type {Record} */\n const aliases = Object.create(null);\n /** @type {HLJSPlugin[]} */\n const plugins = [];\n\n // safe/production mode - swallows more errors, tries to keep running\n // even if a single syntax or parse hits a fatal error\n let SAFE_MODE = true;\n const LANGUAGE_NOT_FOUND = \"Could not find the language '{}', did you forget to load/include a language module?\";\n /** @type {Language} */\n const PLAINTEXT_LANGUAGE = { disableAutodetect: true, name: 'Plain text', contains: [] };\n\n // Global options used when within external APIs. This is modified when\n // calling the `hljs.configure` function.\n /** @type HLJSOptions */\n let options = {\n ignoreUnescapedHTML: false,\n throwUnescapedHTML: false,\n noHighlightRe: /^(no-?highlight)$/i,\n languageDetectRe: /\\blang(?:uage)?-([\\w-]+)\\b/i,\n classPrefix: 'hljs-',\n cssSelector: 'pre code',\n languages: null,\n // beta configuration options, subject to change, welcome to discuss\n // https://github.com/highlightjs/highlight.js/issues/1086\n __emitter: TokenTreeEmitter\n };\n\n /* Utility functions */\n\n /**\n * Tests a language name to see if highlighting should be skipped\n * @param {string} languageName\n */\n function shouldNotHighlight(languageName) {\n return options.noHighlightRe.test(languageName);\n }\n\n /**\n * @param {HighlightedHTMLElement} block - the HTML element to determine language for\n */\n function blockLanguage(block) {\n let classes = block.className + ' ';\n\n classes += block.parentNode ? block.parentNode.className : '';\n\n // language-* takes precedence over non-prefixed class names.\n const match = options.languageDetectRe.exec(classes);\n if (match) {\n const language = getLanguage(match[1]);\n if (!language) {\n warn(LANGUAGE_NOT_FOUND.replace(\"{}\", match[1]));\n warn(\"Falling back to no-highlight mode for this block.\", block);\n }\n return language ? match[1] : 'no-highlight';\n }\n\n return classes\n .split(/\\s+/)\n .find((_class) => shouldNotHighlight(_class) || getLanguage(_class));\n }\n\n /**\n * Core highlighting function.\n *\n * OLD API\n * highlight(lang, code, ignoreIllegals, continuation)\n *\n * NEW API\n * highlight(code, {lang, ignoreIllegals})\n *\n * @param {string} codeOrLanguageName - the language to use for highlighting\n * @param {string | HighlightOptions} optionsOrCode - the code to highlight\n * @param {boolean} [ignoreIllegals] - whether to ignore illegal matches, default is to bail\n *\n * @returns {HighlightResult} Result - an object that represents the result\n * @property {string} language - the language name\n * @property {number} relevance - the relevance score\n * @property {string} value - the highlighted HTML code\n * @property {string} code - the original raw code\n * @property {CompiledMode} top - top of the current mode stack\n * @property {boolean} illegal - indicates whether any illegal matches were found\n */\n function highlight(codeOrLanguageName, optionsOrCode, ignoreIllegals) {\n let code = \"\";\n let languageName = \"\";\n if (typeof optionsOrCode === \"object\") {\n code = codeOrLanguageName;\n ignoreIllegals = optionsOrCode.ignoreIllegals;\n languageName = optionsOrCode.language;\n } else {\n // old API\n deprecated(\"10.7.0\", \"highlight(lang, code, ...args) has been deprecated.\");\n deprecated(\"10.7.0\", \"Please use highlight(code, options) instead.\\nhttps://github.com/highlightjs/highlight.js/issues/2277\");\n languageName = codeOrLanguageName;\n code = optionsOrCode;\n }\n\n // https://github.com/highlightjs/highlight.js/issues/3149\n // eslint-disable-next-line no-undefined\n if (ignoreIllegals === undefined) { ignoreIllegals = true; }\n\n /** @type {BeforeHighlightContext} */\n const context = {\n code,\n language: languageName\n };\n // the plugin can change the desired language or the code to be highlighted\n // just be changing the object it was passed\n fire(\"before:highlight\", context);\n\n // a before plugin can usurp the result completely by providing it's own\n // in which case we don't even need to call highlight\n const result = context.result\n ? context.result\n : _highlight(context.language, context.code, ignoreIllegals);\n\n result.code = context.code;\n // the plugin can change anything in result to suite it\n fire(\"after:highlight\", result);\n\n return result;\n }\n\n /**\n * private highlight that's used internally and does not fire callbacks\n *\n * @param {string} languageName - the language to use for highlighting\n * @param {string} codeToHighlight - the code to highlight\n * @param {boolean?} [ignoreIllegals] - whether to ignore illegal matches, default is to bail\n * @param {CompiledMode?} [continuation] - current continuation mode, if any\n * @returns {HighlightResult} - result of the highlight operation\n */\n function _highlight(languageName, codeToHighlight, ignoreIllegals, continuation) {\n const keywordHits = Object.create(null);\n\n /**\n * Return keyword data if a match is a keyword\n * @param {CompiledMode} mode - current mode\n * @param {string} matchText - the textual match\n * @returns {KeywordData | false}\n */\n function keywordData(mode, matchText) {\n return mode.keywords[matchText];\n }\n\n function processKeywords() {\n if (!top.keywords) {\n emitter.addText(modeBuffer);\n return;\n }\n\n let lastIndex = 0;\n top.keywordPatternRe.lastIndex = 0;\n let match = top.keywordPatternRe.exec(modeBuffer);\n let buf = \"\";\n\n while (match) {\n buf += modeBuffer.substring(lastIndex, match.index);\n const word = language.case_insensitive ? match[0].toLowerCase() : match[0];\n const data = keywordData(top, word);\n if (data) {\n const [kind, keywordRelevance] = data;\n emitter.addText(buf);\n buf = \"\";\n\n keywordHits[word] = (keywordHits[word] || 0) + 1;\n if (keywordHits[word] <= MAX_KEYWORD_HITS) relevance += keywordRelevance;\n if (kind.startsWith(\"_\")) {\n // _ implied for relevance only, do not highlight\n // by applying a class name\n buf += match[0];\n } else {\n const cssClass = language.classNameAliases[kind] || kind;\n emitKeyword(match[0], cssClass);\n }\n } else {\n buf += match[0];\n }\n lastIndex = top.keywordPatternRe.lastIndex;\n match = top.keywordPatternRe.exec(modeBuffer);\n }\n buf += modeBuffer.substring(lastIndex);\n emitter.addText(buf);\n }\n\n function processSubLanguage() {\n if (modeBuffer === \"\") return;\n /** @type HighlightResult */\n let result = null;\n\n if (typeof top.subLanguage === 'string') {\n if (!languages[top.subLanguage]) {\n emitter.addText(modeBuffer);\n return;\n }\n result = _highlight(top.subLanguage, modeBuffer, true, continuations[top.subLanguage]);\n continuations[top.subLanguage] = /** @type {CompiledMode} */ (result._top);\n } else {\n result = highlightAuto(modeBuffer, top.subLanguage.length ? top.subLanguage : null);\n }\n\n // Counting embedded language score towards the host language may be disabled\n // with zeroing the containing mode relevance. Use case in point is Markdown that\n // allows XML everywhere and makes every XML snippet to have a much larger Markdown\n // score.\n if (top.relevance > 0) {\n relevance += result.relevance;\n }\n emitter.__addSublanguage(result._emitter, result.language);\n }\n\n function processBuffer() {\n if (top.subLanguage != null) {\n processSubLanguage();\n } else {\n processKeywords();\n }\n modeBuffer = '';\n }\n\n /**\n * @param {string} text\n * @param {string} scope\n */\n function emitKeyword(keyword, scope) {\n if (keyword === \"\") return;\n\n emitter.startScope(scope);\n emitter.addText(keyword);\n emitter.endScope();\n }\n\n /**\n * @param {CompiledScope} scope\n * @param {RegExpMatchArray} match\n */\n function emitMultiClass(scope, match) {\n let i = 1;\n const max = match.length - 1;\n while (i <= max) {\n if (!scope._emit[i]) { i++; continue; }\n const klass = language.classNameAliases[scope[i]] || scope[i];\n const text = match[i];\n if (klass) {\n emitKeyword(text, klass);\n } else {\n modeBuffer = text;\n processKeywords();\n modeBuffer = \"\";\n }\n i++;\n }\n }\n\n /**\n * @param {CompiledMode} mode - new mode to start\n * @param {RegExpMatchArray} match\n */\n function startNewMode(mode, match) {\n if (mode.scope && typeof mode.scope === \"string\") {\n emitter.openNode(language.classNameAliases[mode.scope] || mode.scope);\n }\n if (mode.beginScope) {\n // beginScope just wraps the begin match itself in a scope\n if (mode.beginScope._wrap) {\n emitKeyword(modeBuffer, language.classNameAliases[mode.beginScope._wrap] || mode.beginScope._wrap);\n modeBuffer = \"\";\n } else if (mode.beginScope._multi) {\n // at this point modeBuffer should just be the match\n emitMultiClass(mode.beginScope, match);\n modeBuffer = \"\";\n }\n }\n\n top = Object.create(mode, { parent: { value: top } });\n return top;\n }\n\n /**\n * @param {CompiledMode } mode - the mode to potentially end\n * @param {RegExpMatchArray} match - the latest match\n * @param {string} matchPlusRemainder - match plus remainder of content\n * @returns {CompiledMode | void} - the next mode, or if void continue on in current mode\n */\n function endOfMode(mode, match, matchPlusRemainder) {\n let matched = startsWith(mode.endRe, matchPlusRemainder);\n\n if (matched) {\n if (mode[\"on:end\"]) {\n const resp = new Response(mode);\n mode[\"on:end\"](match, resp);\n if (resp.isMatchIgnored) matched = false;\n }\n\n if (matched) {\n while (mode.endsParent && mode.parent) {\n mode = mode.parent;\n }\n return mode;\n }\n }\n // even if on:end fires an `ignore` it's still possible\n // that we might trigger the end node because of a parent mode\n if (mode.endsWithParent) {\n return endOfMode(mode.parent, match, matchPlusRemainder);\n }\n }\n\n /**\n * Handle matching but then ignoring a sequence of text\n *\n * @param {string} lexeme - string containing full match text\n */\n function doIgnore(lexeme) {\n if (top.matcher.regexIndex === 0) {\n // no more regexes to potentially match here, so we move the cursor forward one\n // space\n modeBuffer += lexeme[0];\n return 1;\n } else {\n // no need to move the cursor, we still have additional regexes to try and\n // match at this very spot\n resumeScanAtSamePosition = true;\n return 0;\n }\n }\n\n /**\n * Handle the start of a new potential mode match\n *\n * @param {EnhancedMatch} match - the current match\n * @returns {number} how far to advance the parse cursor\n */\n function doBeginMatch(match) {\n const lexeme = match[0];\n const newMode = match.rule;\n\n const resp = new Response(newMode);\n // first internal before callbacks, then the public ones\n const beforeCallbacks = [newMode.__beforeBegin, newMode[\"on:begin\"]];\n for (const cb of beforeCallbacks) {\n if (!cb) continue;\n cb(match, resp);\n if (resp.isMatchIgnored) return doIgnore(lexeme);\n }\n\n if (newMode.skip) {\n modeBuffer += lexeme;\n } else {\n if (newMode.excludeBegin) {\n modeBuffer += lexeme;\n }\n processBuffer();\n if (!newMode.returnBegin && !newMode.excludeBegin) {\n modeBuffer = lexeme;\n }\n }\n startNewMode(newMode, match);\n return newMode.returnBegin ? 0 : lexeme.length;\n }\n\n /**\n * Handle the potential end of mode\n *\n * @param {RegExpMatchArray} match - the current match\n */\n function doEndMatch(match) {\n const lexeme = match[0];\n const matchPlusRemainder = codeToHighlight.substring(match.index);\n\n const endMode = endOfMode(top, match, matchPlusRemainder);\n if (!endMode) { return NO_MATCH; }\n\n const origin = top;\n if (top.endScope && top.endScope._wrap) {\n processBuffer();\n emitKeyword(lexeme, top.endScope._wrap);\n } else if (top.endScope && top.endScope._multi) {\n processBuffer();\n emitMultiClass(top.endScope, match);\n } else if (origin.skip) {\n modeBuffer += lexeme;\n } else {\n if (!(origin.returnEnd || origin.excludeEnd)) {\n modeBuffer += lexeme;\n }\n processBuffer();\n if (origin.excludeEnd) {\n modeBuffer = lexeme;\n }\n }\n do {\n if (top.scope) {\n emitter.closeNode();\n }\n if (!top.skip && !top.subLanguage) {\n relevance += top.relevance;\n }\n top = top.parent;\n } while (top !== endMode.parent);\n if (endMode.starts) {\n startNewMode(endMode.starts, match);\n }\n return origin.returnEnd ? 0 : lexeme.length;\n }\n\n function processContinuations() {\n const list = [];\n for (let current = top; current !== language; current = current.parent) {\n if (current.scope) {\n list.unshift(current.scope);\n }\n }\n list.forEach(item => emitter.openNode(item));\n }\n\n /** @type {{type?: MatchType, index?: number, rule?: Mode}}} */\n let lastMatch = {};\n\n /**\n * Process an individual match\n *\n * @param {string} textBeforeMatch - text preceding the match (since the last match)\n * @param {EnhancedMatch} [match] - the match itself\n */\n function processLexeme(textBeforeMatch, match) {\n const lexeme = match && match[0];\n\n // add non-matched text to the current mode buffer\n modeBuffer += textBeforeMatch;\n\n if (lexeme == null) {\n processBuffer();\n return 0;\n }\n\n // we've found a 0 width match and we're stuck, so we need to advance\n // this happens when we have badly behaved rules that have optional matchers to the degree that\n // sometimes they can end up matching nothing at all\n // Ref: https://github.com/highlightjs/highlight.js/issues/2140\n if (lastMatch.type === \"begin\" && match.type === \"end\" && lastMatch.index === match.index && lexeme === \"\") {\n // spit the \"skipped\" character that our regex choked on back into the output sequence\n modeBuffer += codeToHighlight.slice(match.index, match.index + 1);\n if (!SAFE_MODE) {\n /** @type {AnnotatedError} */\n const err = new Error(`0 width match regex (${languageName})`);\n err.languageName = languageName;\n err.badRule = lastMatch.rule;\n throw err;\n }\n return 1;\n }\n lastMatch = match;\n\n if (match.type === \"begin\") {\n return doBeginMatch(match);\n } else if (match.type === \"illegal\" && !ignoreIllegals) {\n // illegal match, we do not continue processing\n /** @type {AnnotatedError} */\n const err = new Error('Illegal lexeme \"' + lexeme + '\" for mode \"' + (top.scope || '') + '\"');\n err.mode = top;\n throw err;\n } else if (match.type === \"end\") {\n const processed = doEndMatch(match);\n if (processed !== NO_MATCH) {\n return processed;\n }\n }\n\n // edge case for when illegal matches $ (end of line) which is technically\n // a 0 width match but not a begin/end match so it's not caught by the\n // first handler (when ignoreIllegals is true)\n if (match.type === \"illegal\" && lexeme === \"\") {\n // advance so we aren't stuck in an infinite loop\n return 1;\n }\n\n // infinite loops are BAD, this is a last ditch catch all. if we have a\n // decent number of iterations yet our index (cursor position in our\n // parsing) still 3x behind our index then something is very wrong\n // so we bail\n if (iterations > 100000 && iterations > match.index * 3) {\n const err = new Error('potential infinite loop, way more iterations than matches');\n throw err;\n }\n\n /*\n Why might be find ourselves here? An potential end match that was\n triggered but could not be completed. IE, `doEndMatch` returned NO_MATCH.\n (this could be because a callback requests the match be ignored, etc)\n\n This causes no real harm other than stopping a few times too many.\n */\n\n modeBuffer += lexeme;\n return lexeme.length;\n }\n\n const language = getLanguage(languageName);\n if (!language) {\n error(LANGUAGE_NOT_FOUND.replace(\"{}\", languageName));\n throw new Error('Unknown language: \"' + languageName + '\"');\n }\n\n const md = compileLanguage(language);\n let result = '';\n /** @type {CompiledMode} */\n let top = continuation || md;\n /** @type Record */\n const continuations = {}; // keep continuations for sub-languages\n const emitter = new options.__emitter(options);\n processContinuations();\n let modeBuffer = '';\n let relevance = 0;\n let index = 0;\n let iterations = 0;\n let resumeScanAtSamePosition = false;\n\n try {\n if (!language.__emitTokens) {\n top.matcher.considerAll();\n\n for (;;) {\n iterations++;\n if (resumeScanAtSamePosition) {\n // only regexes not matched previously will now be\n // considered for a potential match\n resumeScanAtSamePosition = false;\n } else {\n top.matcher.considerAll();\n }\n top.matcher.lastIndex = index;\n\n const match = top.matcher.exec(codeToHighlight);\n // console.log(\"match\", match[0], match.rule && match.rule.begin)\n\n if (!match) break;\n\n const beforeMatch = codeToHighlight.substring(index, match.index);\n const processedCount = processLexeme(beforeMatch, match);\n index = match.index + processedCount;\n }\n processLexeme(codeToHighlight.substring(index));\n } else {\n language.__emitTokens(codeToHighlight, emitter);\n }\n\n emitter.finalize();\n result = emitter.toHTML();\n\n return {\n language: languageName,\n value: result,\n relevance,\n illegal: false,\n _emitter: emitter,\n _top: top\n };\n } catch (err) {\n if (err.message && err.message.includes('Illegal')) {\n return {\n language: languageName,\n value: escape(codeToHighlight),\n illegal: true,\n relevance: 0,\n _illegalBy: {\n message: err.message,\n index,\n context: codeToHighlight.slice(index - 100, index + 100),\n mode: err.mode,\n resultSoFar: result\n },\n _emitter: emitter\n };\n } else if (SAFE_MODE) {\n return {\n language: languageName,\n value: escape(codeToHighlight),\n illegal: false,\n relevance: 0,\n errorRaised: err,\n _emitter: emitter,\n _top: top\n };\n } else {\n throw err;\n }\n }\n }\n\n /**\n * returns a valid highlight result, without actually doing any actual work,\n * auto highlight starts with this and it's possible for small snippets that\n * auto-detection may not find a better match\n * @param {string} code\n * @returns {HighlightResult}\n */\n function justTextHighlightResult(code) {\n const result = {\n value: escape(code),\n illegal: false,\n relevance: 0,\n _top: PLAINTEXT_LANGUAGE,\n _emitter: new options.__emitter(options)\n };\n result._emitter.addText(code);\n return result;\n }\n\n /**\n Highlighting with language detection. Accepts a string with the code to\n highlight. Returns an object with the following properties:\n\n - language (detected language)\n - relevance (int)\n - value (an HTML string with highlighting markup)\n - secondBest (object with the same structure for second-best heuristically\n detected language, may be absent)\n\n @param {string} code\n @param {Array} [languageSubset]\n @returns {AutoHighlightResult}\n */\n function highlightAuto(code, languageSubset) {\n languageSubset = languageSubset || options.languages || Object.keys(languages);\n const plaintext = justTextHighlightResult(code);\n\n const results = languageSubset.filter(getLanguage).filter(autoDetection).map(name =>\n _highlight(name, code, false)\n );\n results.unshift(plaintext); // plaintext is always an option\n\n const sorted = results.sort((a, b) => {\n // sort base on relevance\n if (a.relevance !== b.relevance) return b.relevance - a.relevance;\n\n // always award the tie to the base language\n // ie if C++ and Arduino are tied, it's more likely to be C++\n if (a.language && b.language) {\n if (getLanguage(a.language).supersetOf === b.language) {\n return 1;\n } else if (getLanguage(b.language).supersetOf === a.language) {\n return -1;\n }\n }\n\n // otherwise say they are equal, which has the effect of sorting on\n // relevance while preserving the original ordering - which is how ties\n // have historically been settled, ie the language that comes first always\n // wins in the case of a tie\n return 0;\n });\n\n const [best, secondBest] = sorted;\n\n /** @type {AutoHighlightResult} */\n const result = best;\n result.secondBest = secondBest;\n\n return result;\n }\n\n /**\n * Builds new class name for block given the language name\n *\n * @param {HTMLElement} element\n * @param {string} [currentLang]\n * @param {string} [resultLang]\n */\n function updateClassName(element, currentLang, resultLang) {\n const language = (currentLang && aliases[currentLang]) || resultLang;\n\n element.classList.add(\"hljs\");\n element.classList.add(`language-${language}`);\n }\n\n /**\n * Applies highlighting to a DOM node containing code.\n *\n * @param {HighlightedHTMLElement} element - the HTML element to highlight\n */\n function highlightElement(element) {\n /** @type HTMLElement */\n let node = null;\n const language = blockLanguage(element);\n\n if (shouldNotHighlight(language)) return;\n\n fire(\"before:highlightElement\",\n { el: element, language });\n\n if (element.dataset.highlighted) {\n console.log(\"Element previously highlighted. To highlight again, first unset `dataset.highlighted`.\", element);\n return;\n }\n\n // we should be all text, no child nodes (unescaped HTML) - this is possibly\n // an HTML injection attack - it's likely too late if this is already in\n // production (the code has likely already done its damage by the time\n // we're seeing it)... but we yell loudly about this so that hopefully it's\n // more likely to be caught in development before making it to production\n if (element.children.length > 0) {\n if (!options.ignoreUnescapedHTML) {\n console.warn(\"One of your code blocks includes unescaped HTML. This is a potentially serious security risk.\");\n console.warn(\"https://github.com/highlightjs/highlight.js/wiki/security\");\n console.warn(\"The element with unescaped HTML:\");\n console.warn(element);\n }\n if (options.throwUnescapedHTML) {\n const err = new HTMLInjectionError(\n \"One of your code blocks includes unescaped HTML.\",\n element.innerHTML\n );\n throw err;\n }\n }\n\n node = element;\n const text = node.textContent;\n const result = language ? highlight(text, { language, ignoreIllegals: true }) : highlightAuto(text);\n\n element.innerHTML = result.value;\n element.dataset.highlighted = \"yes\";\n updateClassName(element, language, result.language);\n element.result = {\n language: result.language,\n // TODO: remove with version 11.0\n re: result.relevance,\n relevance: result.relevance\n };\n if (result.secondBest) {\n element.secondBest = {\n language: result.secondBest.language,\n relevance: result.secondBest.relevance\n };\n }\n\n fire(\"after:highlightElement\", { el: element, result, text });\n }\n\n /**\n * Updates highlight.js global options with the passed options\n *\n * @param {Partial} userOptions\n */\n function configure(userOptions) {\n options = inherit(options, userOptions);\n }\n\n // TODO: remove v12, deprecated\n const initHighlighting = () => {\n highlightAll();\n deprecated(\"10.6.0\", \"initHighlighting() deprecated. Use highlightAll() now.\");\n };\n\n // TODO: remove v12, deprecated\n function initHighlightingOnLoad() {\n highlightAll();\n deprecated(\"10.6.0\", \"initHighlightingOnLoad() deprecated. Use highlightAll() now.\");\n }\n\n let wantsHighlight = false;\n\n /**\n * auto-highlights all pre>code elements on the page\n */\n function highlightAll() {\n // if we are called too early in the loading process\n if (document.readyState === \"loading\") {\n wantsHighlight = true;\n return;\n }\n\n const blocks = document.querySelectorAll(options.cssSelector);\n blocks.forEach(highlightElement);\n }\n\n function boot() {\n // if a highlight was requested before DOM was loaded, do now\n if (wantsHighlight) highlightAll();\n }\n\n // make sure we are in the browser environment\n if (typeof window !== 'undefined' && window.addEventListener) {\n window.addEventListener('DOMContentLoaded', boot, false);\n }\n\n /**\n * Register a language grammar module\n *\n * @param {string} languageName\n * @param {LanguageFn} languageDefinition\n */\n function registerLanguage(languageName, languageDefinition) {\n let lang = null;\n try {\n lang = languageDefinition(hljs);\n } catch (error$1) {\n error(\"Language definition for '{}' could not be registered.\".replace(\"{}\", languageName));\n // hard or soft error\n if (!SAFE_MODE) { throw error$1; } else { error(error$1); }\n // languages that have serious errors are replaced with essentially a\n // \"plaintext\" stand-in so that the code blocks will still get normal\n // css classes applied to them - and one bad language won't break the\n // entire highlighter\n lang = PLAINTEXT_LANGUAGE;\n }\n // give it a temporary name if it doesn't have one in the meta-data\n if (!lang.name) lang.name = languageName;\n languages[languageName] = lang;\n lang.rawDefinition = languageDefinition.bind(null, hljs);\n\n if (lang.aliases) {\n registerAliases(lang.aliases, { languageName });\n }\n }\n\n /**\n * Remove a language grammar module\n *\n * @param {string} languageName\n */\n function unregisterLanguage(languageName) {\n delete languages[languageName];\n for (const alias of Object.keys(aliases)) {\n if (aliases[alias] === languageName) {\n delete aliases[alias];\n }\n }\n }\n\n /**\n * @returns {string[]} List of language internal names\n */\n function listLanguages() {\n return Object.keys(languages);\n }\n\n /**\n * @param {string} name - name of the language to retrieve\n * @returns {Language | undefined}\n */\n function getLanguage(name) {\n name = (name || '').toLowerCase();\n return languages[name] || languages[aliases[name]];\n }\n\n /**\n *\n * @param {string|string[]} aliasList - single alias or list of aliases\n * @param {{languageName: string}} opts\n */\n function registerAliases(aliasList, { languageName }) {\n if (typeof aliasList === 'string') {\n aliasList = [aliasList];\n }\n aliasList.forEach(alias => { aliases[alias.toLowerCase()] = languageName; });\n }\n\n /**\n * Determines if a given language has auto-detection enabled\n * @param {string} name - name of the language\n */\n function autoDetection(name) {\n const lang = getLanguage(name);\n return lang && !lang.disableAutodetect;\n }\n\n /**\n * Upgrades the old highlightBlock plugins to the new\n * highlightElement API\n * @param {HLJSPlugin} plugin\n */\n function upgradePluginAPI(plugin) {\n // TODO: remove with v12\n if (plugin[\"before:highlightBlock\"] && !plugin[\"before:highlightElement\"]) {\n plugin[\"before:highlightElement\"] = (data) => {\n plugin[\"before:highlightBlock\"](\n Object.assign({ block: data.el }, data)\n );\n };\n }\n if (plugin[\"after:highlightBlock\"] && !plugin[\"after:highlightElement\"]) {\n plugin[\"after:highlightElement\"] = (data) => {\n plugin[\"after:highlightBlock\"](\n Object.assign({ block: data.el }, data)\n );\n };\n }\n }\n\n /**\n * @param {HLJSPlugin} plugin\n */\n function addPlugin(plugin) {\n upgradePluginAPI(plugin);\n plugins.push(plugin);\n }\n\n /**\n * @param {HLJSPlugin} plugin\n */\n function removePlugin(plugin) {\n const index = plugins.indexOf(plugin);\n if (index !== -1) {\n plugins.splice(index, 1);\n }\n }\n\n /**\n *\n * @param {PluginEvent} event\n * @param {any} args\n */\n function fire(event, args) {\n const cb = event;\n plugins.forEach(function(plugin) {\n if (plugin[cb]) {\n plugin[cb](args);\n }\n });\n }\n\n /**\n * DEPRECATED\n * @param {HighlightedHTMLElement} el\n */\n function deprecateHighlightBlock(el) {\n deprecated(\"10.7.0\", \"highlightBlock will be removed entirely in v12.0\");\n deprecated(\"10.7.0\", \"Please use highlightElement now.\");\n\n return highlightElement(el);\n }\n\n /* Interface definition */\n Object.assign(hljs, {\n highlight,\n highlightAuto,\n highlightAll,\n highlightElement,\n // TODO: Remove with v12 API\n highlightBlock: deprecateHighlightBlock,\n configure,\n initHighlighting,\n initHighlightingOnLoad,\n registerLanguage,\n unregisterLanguage,\n listLanguages,\n getLanguage,\n registerAliases,\n autoDetection,\n inherit,\n addPlugin,\n removePlugin\n });\n\n hljs.debugMode = function() { SAFE_MODE = false; };\n hljs.safeMode = function() { SAFE_MODE = true; };\n hljs.versionString = version;\n\n hljs.regex = {\n concat: concat,\n lookahead: lookahead,\n either: either,\n optional: optional,\n anyNumberOfTimes: anyNumberOfTimes\n };\n\n for (const key in MODES) {\n // @ts-ignore\n if (typeof MODES[key] === \"object\") {\n // @ts-ignore\n deepFreeze(MODES[key]);\n }\n }\n\n // merge all the modes/regexes into our main object\n Object.assign(hljs, MODES);\n\n return hljs;\n};\n\n// Other names for the variable may break build script\nconst highlight = HLJS({});\n\n// returns a new instance of the highlighter to be used for extensions\n// check https://github.com/wooorm/lowlight/issues/47\nhighlight.newInstance = () => HLJS({});\n\nmodule.exports = highlight;\nhighlight.HighlightJS = highlight;\nhighlight.default = highlight;\n", "/*\nLanguage: 1C:Enterprise\nAuthor: Stanislav Belov \nDescription: built-in language 1C:Enterprise (v7, v8)\nCategory: enterprise\n*/\n\nfunction _1c(hljs) {\n // \u043E\u0431\u0449\u0438\u0439 \u043F\u0430\u0442\u0442\u0435\u0440\u043D \u0434\u043B\u044F \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u044F \u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u043E\u0432\n const UNDERSCORE_IDENT_RE = '[A-Za-z\u0410-\u042F\u0430-\u044F\u0451\u0401_][A-Za-z\u0410-\u042F\u0430-\u044F\u0451\u0401_0-9]+';\n\n // v7 \u0443\u043D\u0438\u043A\u0430\u043B\u044C\u043D\u044B\u0435 \u043A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430, \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0432 v8 ==> keyword\n const v7_keywords =\n '\u0434\u0430\u043B\u0435\u0435 ';\n\n // v8 \u043A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430 ==> keyword\n const v8_keywords =\n '\u0432\u043E\u0437\u0432\u0440\u0430\u0442 \u0432\u044B\u0437\u0432\u0430\u0442\u044C\u0438\u0441\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C \u0434\u043B\u044F \u0435\u0441\u043B\u0438 \u0438 \u0438\u0437 \u0438\u043B\u0438 \u0438\u043D\u0430\u0447\u0435 \u0438\u043D\u0430\u0447\u0435\u0435\u0441\u043B\u0438 \u0438\u0441\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435 \u043A\u0430\u0436\u0434\u043E\u0433\u043E \u043A\u043E\u043D\u0435\u0446\u0435\u0441\u043B\u0438 '\n + '\u043A\u043E\u043D\u0435\u0446\u043F\u043E\u043F\u044B\u0442\u043A\u0438 \u043A\u043E\u043D\u0435\u0446\u0446\u0438\u043A\u043B\u0430 \u043D\u0435 \u043D\u043E\u0432\u044B\u0439 \u043F\u0435\u0440\u0435\u0439\u0442\u0438 \u043F\u0435\u0440\u0435\u043C \u043F\u043E \u043F\u043E\u043A\u0430 \u043F\u043E\u043F\u044B\u0442\u043A\u0430 \u043F\u0440\u0435\u0440\u0432\u0430\u0442\u044C \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C \u0442\u043E\u0433\u0434\u0430 \u0446\u0438\u043A\u043B \u044D\u043A\u0441\u043F\u043E\u0440\u0442 ';\n\n // keyword : \u043A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430\n const KEYWORD = v7_keywords + v8_keywords;\n\n // v7 \u0443\u043D\u0438\u043A\u0430\u043B\u044C\u043D\u044B\u0435 \u0434\u0438\u0440\u0435\u043A\u0442\u0438\u0432\u044B, \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0432 v8 ==> meta-keyword\n const v7_meta_keywords =\n '\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C\u0438\u0437\u0444\u0430\u0439\u043B\u0430 ';\n\n // v8 \u043A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430 \u0432 \u0438\u043D\u0441\u0442\u0440\u0443\u043A\u0446\u0438\u044F\u0445 \u043F\u0440\u0435\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u0440\u0430, \u0434\u0438\u0440\u0435\u043A\u0442\u0438\u0432\u0430\u0445 \u043A\u043E\u043C\u043F\u0438\u043B\u044F\u0446\u0438\u0438, \u0430\u043D\u043D\u043E\u0442\u0430\u0446\u0438\u044F\u0445 ==> meta-keyword\n const v8_meta_keywords =\n '\u0432\u0435\u0431\u043A\u043B\u0438\u0435\u043D\u0442 \u0432\u043C\u0435\u0441\u0442\u043E \u0432\u043D\u0435\u0448\u043D\u0435\u0435\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u043A\u043B\u0438\u0435\u043D\u0442 \u043A\u043E\u043D\u0435\u0446\u043E\u0431\u043B\u0430\u0441\u0442\u0438 \u043C\u043E\u0431\u0438\u043B\u044C\u043D\u043E\u0435\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043A\u043B\u0438\u0435\u043D\u0442 \u043C\u043E\u0431\u0438\u043B\u044C\u043D\u043E\u0435\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0441\u0435\u0440\u0432\u0435\u0440 '\n + '\u043D\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0435 \u043D\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0435\u043D\u0430\u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043D\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0435\u043D\u0430\u0441\u0435\u0440\u0432\u0435\u0440\u0435\u0431\u0435\u0437\u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u043D\u0430\u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043D\u0430\u0441\u0435\u0440\u0432\u0435\u0440\u0435\u0431\u0435\u0437\u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 \u043E\u0431\u043B\u0430\u0441\u0442\u044C \u043F\u0435\u0440\u0435\u0434 '\n + '\u043F\u043E\u0441\u043B\u0435 \u0441\u0435\u0440\u0432\u0435\u0440 \u0442\u043E\u043B\u0441\u0442\u044B\u0439\u043A\u043B\u0438\u0435\u043D\u0442\u043E\u0431\u044B\u0447\u043D\u043E\u0435\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0442\u043E\u043B\u0441\u0442\u044B\u0439\u043A\u043B\u0438\u0435\u043D\u0442\u0443\u043F\u0440\u0430\u0432\u043B\u044F\u0435\u043C\u043E\u0435\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0442\u043E\u043D\u043A\u0438\u0439\u043A\u043B\u0438\u0435\u043D\u0442 ';\n\n // meta-keyword : \u043A\u043B\u044E\u0447\u0435\u0432\u044B\u0435 \u0441\u043B\u043E\u0432\u0430 \u0432 \u0438\u043D\u0441\u0442\u0440\u0443\u043A\u0446\u0438\u044F\u0445 \u043F\u0440\u0435\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u0440\u0430, \u0434\u0438\u0440\u0435\u043A\u0442\u0438\u0432\u0430\u0445 \u043A\u043E\u043C\u043F\u0438\u043B\u044F\u0446\u0438\u0438, \u0430\u043D\u043D\u043E\u0442\u0430\u0446\u0438\u044F\u0445\n const METAKEYWORD = v7_meta_keywords + v8_meta_keywords;\n\n // v7 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043A\u043E\u043D\u0441\u0442\u0430\u043D\u0442\u044B ==> built_in\n const v7_system_constants =\n '\u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C\u0441\u0442\u0440\u0430\u043D\u0438\u0446 \u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C\u0441\u0442\u0440\u043E\u043A \u0441\u0438\u043C\u0432\u043E\u043B\u0442\u0430\u0431\u0443\u043B\u044F\u0446\u0438\u0438 ';\n\n // v7 \u0443\u043D\u0438\u043A\u0430\u043B\u044C\u043D\u044B\u0435 \u043C\u0435\u0442\u043E\u0434\u044B \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430, \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0449\u0438\u0435 \u0432 v8 ==> built_in\n const v7_global_context_methods =\n 'ansitooem oemtoansi \u0432\u0432\u0435\u0441\u0442\u0438\u0432\u0438\u0434\u0441\u0443\u0431\u043A\u043E\u043D\u0442\u043E \u0432\u0432\u0435\u0441\u0442\u0438\u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u0435 \u0432\u0432\u0435\u0441\u0442\u0438\u043F\u0435\u0440\u0438\u043E\u0434 \u0432\u0432\u0435\u0441\u0442\u0438\u043F\u043B\u0430\u043D\u0441\u0447\u0435\u0442\u043E\u0432 \u0432\u044B\u0431\u0440\u0430\u043D\u043D\u044B\u0439\u043F\u043B\u0430\u043D\u0441\u0447\u0435\u0442\u043E\u0432 '\n + '\u0434\u0430\u0442\u0430\u0433\u043E\u0434 \u0434\u0430\u0442\u0430\u043C\u0435\u0441\u044F\u0446 \u0434\u0430\u0442\u0430\u0447\u0438\u0441\u043B\u043E \u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\u0441\u0438\u0441\u0442\u0435\u043C\u044B \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0432\u0441\u0442\u0440\u043E\u043A\u0443 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0438\u0437\u0441\u0442\u0440\u043E\u043A\u0438 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0438\u0431 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F '\n + '\u043A\u043E\u0434\u0441\u0438\u043C\u0432 \u043A\u043E\u043D\u0433\u043E\u0434\u0430 \u043A\u043E\u043D\u0435\u0446\u043F\u0435\u0440\u0438\u043E\u0434\u0430\u0431\u0438 \u043A\u043E\u043D\u0435\u0446\u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u043D\u043D\u043E\u0433\u043E\u043F\u0435\u0440\u0438\u043E\u0434\u0430\u0431\u0438 \u043A\u043E\u043D\u0435\u0446\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0433\u043E\u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430 \u043A\u043E\u043D\u043A\u0432\u0430\u0440\u0442\u0430\u043B\u0430 \u043A\u043E\u043D\u043C\u0435\u0441\u044F\u0446\u0430 '\n + '\u043A\u043E\u043D\u043D\u0435\u0434\u0435\u043B\u0438 \u043B\u043E\u0433 \u043B\u043E\u043310 \u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0435\u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\u0441\u0443\u0431\u043A\u043E\u043D\u0442\u043E \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043D\u0430\u0437\u0432\u0430\u043D\u0438\u0435\u043D\u0430\u0431\u043E\u0440\u0430\u043F\u0440\u0430\u0432 \u043D\u0430\u0437\u043D\u0430\u0447\u0438\u0442\u044C\u0432\u0438\u0434 '\n + '\u043D\u0430\u0437\u043D\u0430\u0447\u0438\u0442\u044C\u0441\u0447\u0435\u0442 \u043D\u0430\u0439\u0442\u0438\u0441\u0441\u044B\u043B\u043A\u0438 \u043D\u0430\u0447\u0430\u043B\u043E\u043F\u0435\u0440\u0438\u043E\u0434\u0430\u0431\u0438 \u043D\u0430\u0447\u0430\u043B\u043E\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0433\u043E\u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430 \u043D\u0430\u0447\u0433\u043E\u0434\u0430 \u043D\u0430\u0447\u043A\u0432\u0430\u0440\u0442\u0430\u043B\u0430 \u043D\u0430\u0447\u043C\u0435\u0441\u044F\u0446\u0430 '\n + '\u043D\u0430\u0447\u043D\u0435\u0434\u0435\u043B\u0438 \u043D\u043E\u043C\u0435\u0440\u0434\u043D\u044F\u0433\u043E\u0434\u0430 \u043D\u043E\u043C\u0435\u0440\u0434\u043D\u044F\u043D\u0435\u0434\u0435\u043B\u0438 \u043D\u043E\u043C\u0435\u0440\u043D\u0435\u0434\u0435\u043B\u0438\u0433\u043E\u0434\u0430 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430\u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0439\u0436\u0443\u0440\u043D\u0430\u043B\u0440\u0430\u0441\u0447\u0435\u0442\u043E\u0432 '\n + '\u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0439\u043F\u043B\u0430\u043D\u0441\u0447\u0435\u0442\u043E\u0432 \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0439\u044F\u0437\u044B\u043A \u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C\u043E\u043A\u043D\u043E\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0439 \u043F\u0435\u0440\u0438\u043E\u0434\u0441\u0442\u0440 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0432\u0440\u0435\u043C\u044F\u0442\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0434\u0430\u0442\u0443\u0442\u0430 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0442\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u043E\u0442\u0431\u043E\u0440\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043F\u043E\u0437\u0438\u0446\u0438\u044E\u0442\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043F\u0443\u0441\u0442\u043E\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0442\u0430 '\n + '\u043F\u0440\u0435\u0444\u0438\u043A\u0441\u0430\u0432\u0442\u043E\u043D\u0443\u043C\u0435\u0440\u0430\u0446\u0438\u0438 \u043F\u0440\u043E\u043F\u0438\u0441\u044C \u043F\u0443\u0441\u0442\u043E\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0440\u0430\u0437\u043C \u0440\u0430\u0437\u043E\u0431\u0440\u0430\u0442\u044C\u043F\u043E\u0437\u0438\u0446\u0438\u044E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044C\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044B\u043D\u0430 '\n + '\u0440\u0430\u0441\u0441\u0447\u0438\u0442\u0430\u0442\u044C\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044B\u043F\u043E \u0441\u0438\u043C\u0432 \u0441\u043E\u0437\u0434\u0430\u0442\u044C\u043E\u0431\u044A\u0435\u043A\u0442 \u0441\u0442\u0430\u0442\u0443\u0441\u0432\u043E\u0437\u0432\u0440\u0430\u0442\u0430 \u0441\u0442\u0440\u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u043E\u0441\u0442\u0440\u043E\u043A \u0441\u0444\u043E\u0440\u043C\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u043F\u043E\u0437\u0438\u0446\u0438\u044E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 '\n + '\u0441\u0447\u0435\u0442\u043F\u043E\u043A\u043E\u0434\u0443 \u0442\u0435\u043A\u0443\u0449\u0435\u0435\u0432\u0440\u0435\u043C\u044F \u0442\u0438\u043F\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u0442\u0438\u043F\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u0441\u0442\u0440 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0442\u0430\u043D\u0430 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0442\u0430\u043F\u043E \u0444\u0438\u043A\u0441\u0448\u0430\u0431\u043B\u043E\u043D \u0448\u0430\u0431\u043B\u043E\u043D ';\n\n // v8 \u043C\u0435\u0442\u043E\u0434\u044B \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 ==> built_in\n const v8_global_context_methods =\n 'acos asin atan base64\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 base64\u0441\u0442\u0440\u043E\u043A\u0430 cos exp log log10 pow sin sqrt tan xml\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 xml\u0441\u0442\u0440\u043E\u043A\u0430 '\n + 'xml\u0442\u0438\u043F xml\u0442\u0438\u043F\u0437\u043D\u0447 \u0430\u043A\u0442\u0438\u0432\u043D\u043E\u0435\u043E\u043A\u043D\u043E \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C \u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C\u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u044F\u0434\u0430\u043D\u043D\u044B\u0445 \u0431\u0443\u043B\u0435\u0432\u043E \u0432\u0432\u0435\u0441\u0442\u0438\u0434\u0430\u0442\u0443 \u0432\u0432\u0435\u0441\u0442\u0438\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 '\n + '\u0432\u0432\u0435\u0441\u0442\u0438\u0441\u0442\u0440\u043E\u043A\u0443 \u0432\u0432\u0435\u0441\u0442\u0438\u0447\u0438\u0441\u043B\u043E \u0432\u043E\u0437\u043C\u043E\u0436\u043D\u043E\u0441\u0442\u044C\u0447\u0442\u0435\u043D\u0438\u044Fxml \u0432\u043E\u043F\u0440\u043E\u0441 \u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0432\u0440\u0435\u0433 \u0432\u044B\u0433\u0440\u0443\u0437\u0438\u0442\u044C\u0436\u0443\u0440\u043D\u0430\u043B\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 '\n + '\u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0443\u043E\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u044F \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u044C\u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0443\u043F\u0440\u0430\u0432\u0434\u043E\u0441\u0442\u0443\u043F\u0430 \u0432\u044B\u0447\u0438\u0441\u043B\u0438\u0442\u044C \u0433\u043E\u0434 \u0434\u0430\u043D\u043D\u044B\u0435\u0444\u043E\u0440\u043C\u044B\u0432\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0434\u0430\u0442\u0430 \u0434\u0435\u043D\u044C \u0434\u0435\u043D\u044C\u0433\u043E\u0434\u0430 '\n + '\u0434\u0435\u043D\u044C\u043D\u0435\u0434\u0435\u043B\u0438 \u0434\u043E\u0431\u0430\u0432\u0438\u0442\u044C\u043C\u0435\u0441\u044F\u0446 \u0437\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0434\u0430\u043D\u043D\u044B\u0435\u0434\u043B\u044F\u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0437\u0430\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0440\u0430\u0431\u043E\u0442\u0443\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044C\u0440\u0430\u0431\u043E\u0442\u0443\u0441\u0438\u0441\u0442\u0435\u043C\u044B '\n + '\u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C\u0432\u043D\u0435\u0448\u043D\u044E\u044E\u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0443 \u0437\u0430\u043A\u0440\u044B\u0442\u044C\u0441\u043F\u0440\u0430\u0432\u043A\u0443 \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044Cjson \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044Cxml \u0437\u0430\u043F\u0438\u0441\u0430\u0442\u044C\u0434\u0430\u0442\u0443json \u0437\u0430\u043F\u0438\u0441\u044C\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 '\n + '\u0437\u0430\u043F\u043E\u043B\u043D\u0438\u0442\u044C\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u0441\u0432\u043E\u0439\u0441\u0442\u0432 \u0437\u0430\u043F\u0440\u043E\u0441\u0438\u0442\u044C\u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u0438\u0435\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0437\u0430\u043F\u0443\u0441\u0442\u0438\u0442\u044C\u0441\u0438\u0441\u0442\u0435\u043C\u0443 \u0437\u0430\u0444\u0438\u043A\u0441\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u044E '\n + '\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0432\u0434\u0430\u043D\u043D\u044B\u0435\u0444\u043E\u0440\u043C\u044B \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0432\u0441\u0442\u0440\u043E\u043A\u0443\u0432\u043D\u0443\u0442\u0440 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0432\u0444\u0430\u0439\u043B \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u043E \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0438\u0437\u0441\u0442\u0440\u043E\u043A\u0438\u0432\u043D\u0443\u0442\u0440 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0438\u0437\u0444\u0430\u0439\u043B\u0430 '\n + '\u0438\u0437xml\u0442\u0438\u043F\u0430 \u0438\u043C\u043F\u043E\u0440\u0442\u043C\u043E\u0434\u0435\u043B\u0438xdto \u0438\u043C\u044F\u043A\u043E\u043C\u043F\u044C\u044E\u0442\u0435\u0440\u0430 \u0438\u043C\u044F\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0438\u043D\u0438\u0446\u0438\u0430\u043B\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u043F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0435\u0434\u0430\u043D\u043D\u044B\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\u043E\u0431\u043E\u0448\u0438\u0431\u043A\u0435 '\n + '\u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0438\u043C\u043E\u0431\u0438\u043B\u044C\u043D\u043E\u0433\u043E\u0443\u0441\u0442\u0440\u043E\u0439\u0441\u0442\u0432\u0430 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445\u0444\u0430\u0439\u043B\u043E\u0432 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u043A\u0430\u0442\u0430\u043B\u043E\u0433\u043F\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u043A\u043E\u0434\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0441\u0442\u0440\u043E\u043A\u0443 '\n + '\u043A\u043E\u0434\u043B\u043E\u043A\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u043A\u043E\u0434\u0441\u0438\u043C\u0432\u043E\u043B\u0430 \u043A\u043E\u043C\u0430\u043D\u0434\u0430\u0441\u0438\u0441\u0442\u0435\u043C\u044B \u043A\u043E\u043D\u0435\u0446\u0433\u043E\u0434\u0430 \u043A\u043E\u043D\u0435\u0446\u0434\u043D\u044F \u043A\u043E\u043D\u0435\u0446\u043A\u0432\u0430\u0440\u0442\u0430\u043B\u0430 \u043A\u043E\u043D\u0435\u0446\u043C\u0435\u0441\u044F\u0446\u0430 \u043A\u043E\u043D\u0435\u0446\u043C\u0438\u043D\u0443\u0442\u044B '\n + '\u043A\u043E\u043D\u0435\u0446\u043D\u0435\u0434\u0435\u043B\u0438 \u043A\u043E\u043D\u0435\u0446\u0447\u0430\u0441\u0430 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F\u0431\u0430\u0437\u044B\u0434\u0430\u043D\u043D\u044B\u0445\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0430\u0434\u0438\u043D\u0430\u043C\u0438\u0447\u0435\u0441\u043A\u0438 \u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044F\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0430 \u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0434\u0430\u043D\u043D\u044B\u0435\u0444\u043E\u0440\u043C\u044B '\n + '\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0444\u0430\u0439\u043B \u043A\u0440\u0430\u0442\u043A\u043E\u0435\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043E\u0448\u0438\u0431\u043A\u0438 \u043B\u0435\u0432 \u043C\u0430\u043A\u0441 \u043C\u0435\u0441\u0442\u043D\u043E\u0435\u0432\u0440\u0435\u043C\u044F \u043C\u0435\u0441\u044F\u0446 \u043C\u0438\u043D \u043C\u0438\u043D\u0443\u0442\u0430 \u043C\u043E\u043D\u043E\u043F\u043E\u043B\u044C\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C \u043D\u0430\u0439\u0442\u0438 '\n + '\u043D\u0430\u0439\u0442\u0438\u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435\u0441\u0438\u043C\u0432\u043E\u043B\u044Bxml \u043D\u0430\u0439\u0442\u0438\u043E\u043A\u043D\u043E\u043F\u043E\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0441\u0441\u044B\u043B\u043A\u0435 \u043D\u0430\u0439\u0442\u0438\u043F\u043E\u043C\u0435\u0447\u0435\u043D\u043D\u044B\u0435\u043D\u0430\u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435 \u043D\u0430\u0439\u0442\u0438\u043F\u043E\u0441\u0441\u044B\u043B\u043A\u0430\u043C \u043D\u0430\u0439\u0442\u0438\u0444\u0430\u0439\u043B\u044B '\n + '\u043D\u0430\u0447\u0430\u043B\u043E\u0433\u043E\u0434\u0430 \u043D\u0430\u0447\u0430\u043B\u043E\u0434\u043D\u044F \u043D\u0430\u0447\u0430\u043B\u043E\u043A\u0432\u0430\u0440\u0442\u0430\u043B\u0430 \u043D\u0430\u0447\u0430\u043B\u043E\u043C\u0435\u0441\u044F\u0446\u0430 \u043D\u0430\u0447\u0430\u043B\u043E\u043C\u0438\u043D\u0443\u0442\u044B \u043D\u0430\u0447\u0430\u043B\u043E\u043D\u0435\u0434\u0435\u043B\u0438 \u043D\u0430\u0447\u0430\u043B\u043E\u0447\u0430\u0441\u0430 \u043D\u0430\u0447\u0430\u0442\u044C\u0437\u0430\u043F\u0440\u043E\u0441\u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043D\u0438\u044F\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F '\n + '\u043D\u0430\u0447\u0430\u0442\u044C\u0437\u0430\u043F\u0443\u0441\u043A\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043D\u0430\u0447\u0430\u0442\u044C\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u0444\u0430\u0439\u043B\u0430 \u043D\u0430\u0447\u0430\u0442\u044C\u043F\u0435\u0440\u0435\u043C\u0435\u0449\u0435\u043D\u0438\u0435\u0444\u0430\u0439\u043B\u0430 \u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435\u0432\u043D\u0435\u0448\u043D\u0435\u0439\u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u044B '\n + '\u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F\u0440\u0430\u0431\u043E\u0442\u044B\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0435\u0439 \u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F\u0440\u0430\u0431\u043E\u0442\u044B\u0441\u0444\u0430\u0439\u043B\u0430\u043C\u0438 \u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u0438\u0441\u043A\u0444\u0430\u0439\u043B\u043E\u0432 '\n + '\u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u0435\u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445\u0444\u0430\u0439\u043B\u043E\u0432 \u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u0435\u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u0435\u0440\u0430\u0431\u043E\u0447\u0435\u0433\u043E\u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F '\n + '\u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u0435\u0444\u0430\u0439\u043B\u043E\u0432 \u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u043C\u0435\u0449\u0435\u043D\u0438\u0435\u0444\u0430\u0439\u043B\u0430 \u043D\u0430\u0447\u0430\u0442\u044C\u043F\u043E\u043C\u0435\u0449\u0435\u043D\u0438\u0435\u0444\u0430\u0439\u043B\u043E\u0432 \u043D\u0430\u0447\u0430\u0442\u044C\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435\u0434\u0432\u043E\u0438\u0447\u043D\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445\u0438\u0437\u0444\u0430\u0439\u043B\u0430 \u043D\u0430\u0447\u0430\u0442\u044C\u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435\u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0430 '\n + '\u043D\u0430\u0447\u0430\u0442\u044C\u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u044E \u043D\u0430\u0447\u0430\u0442\u044C\u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435\u0444\u0430\u0439\u043B\u043E\u0432 \u043D\u0430\u0447\u0430\u0442\u044C\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0443\u0432\u043D\u0435\u0448\u043D\u0435\u0439\u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u044B \u043D\u0430\u0447\u0430\u0442\u044C\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0443\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F\u0440\u0430\u0431\u043E\u0442\u044B\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0435\u0439 '\n + '\u043D\u0430\u0447\u0430\u0442\u044C\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0443\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F\u0440\u0430\u0431\u043E\u0442\u044B\u0441\u0444\u0430\u0439\u043B\u0430\u043C\u0438 \u043D\u0435\u0434\u0435\u043B\u044F\u0433\u043E\u0434\u0430 \u043D\u0435\u043E\u0431\u0445\u043E\u0434\u0438\u043C\u043E\u0441\u0442\u044C\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F \u043D\u043E\u043C\u0435\u0440\u0441\u0435\u0430\u043D\u0441\u0430\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B '\n + '\u043D\u043E\u043C\u0435\u0440\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u043D\u0440\u0435\u0433 \u043D\u0441\u0442\u0440 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C\u043D\u0443\u043C\u0435\u0440\u0430\u0446\u0438\u044E\u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 \u043E\u0431\u043D\u043E\u0432\u0438\u0442\u044C\u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C\u044B\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F '\n + '\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430\u043F\u0440\u0435\u0440\u044B\u0432\u0430\u043D\u0438\u044F\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u043E\u0431\u044A\u0435\u0434\u0438\u043D\u0438\u0442\u044C\u0444\u0430\u0439\u043B\u044B \u043E\u043A\u0440 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u043E\u0448\u0438\u0431\u043A\u0438 \u043E\u043F\u043E\u0432\u0435\u0441\u0442\u0438\u0442\u044C \u043E\u043F\u043E\u0432\u0435\u0441\u0442\u0438\u0442\u044C\u043E\u0431\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0438 '\n + '\u043E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u0437\u0430\u043F\u0440\u043E\u0441\u0430\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u043A\u043B\u0438\u0435\u043D\u0442\u0430\u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F \u043E\u0442\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u043E\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u044F '\n + '\u043E\u0442\u043A\u0440\u044B\u0442\u044C\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043E\u0442\u043A\u0440\u044B\u0442\u044C\u0438\u043D\u0434\u0435\u043A\u0441\u0441\u043F\u0440\u0430\u0432\u043A\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u044C\u0441\u043E\u0434\u0435\u0440\u0436\u0430\u043D\u0438\u0435\u0441\u043F\u0440\u0430\u0432\u043A\u0438 \u043E\u0442\u043A\u0440\u044B\u0442\u044C\u0441\u043F\u0440\u0430\u0432\u043A\u0443 \u043E\u0442\u043A\u0440\u044B\u0442\u044C\u0444\u043E\u0440\u043C\u0443 \u043E\u0442\u043A\u0440\u044B\u0442\u044C\u0444\u043E\u0440\u043C\u0443\u043C\u043E\u0434\u0430\u043B\u044C\u043D\u043E '\n + '\u043E\u0442\u043C\u0435\u043D\u0438\u0442\u044C\u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u044E \u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C\u0436\u0443\u0440\u043D\u0430\u043B\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u043E\u0447\u0438\u0441\u0442\u0438\u0442\u044C\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B\u0434\u043E\u0441\u0442\u0443\u043F\u0430 '\n + '\u043F\u0435\u0440\u0435\u0439\u0442\u0438\u043F\u043E\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0441\u0441\u044B\u043B\u043A\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u0441\u0442\u0438\u0442\u044C\u0444\u0430\u0439\u043B \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0432\u043D\u0435\u0448\u043D\u044E\u044E\u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0443 '\n + '\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u0437\u0430\u043F\u0440\u043E\u0441\u0430\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u043A\u043B\u0438\u0435\u043D\u0442\u0430\u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u0447\u0438\u043A\u043E\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u044F '\n + '\u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435\u0440\u0430\u0431\u043E\u0442\u044B\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0435\u0439 \u043F\u043E\u0434\u043A\u043B\u044E\u0447\u0438\u0442\u044C\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435\u0440\u0430\u0431\u043E\u0442\u044B\u0441\u0444\u0430\u0439\u043B\u0430\u043C\u0438 \u043F\u043E\u0434\u0440\u043E\u0431\u043D\u043E\u0435\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043E\u0448\u0438\u0431\u043A\u0438 '\n + '\u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u0432\u0432\u043E\u0434\u0434\u0430\u0442\u044B \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u0432\u0432\u043E\u0434\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u0432\u0432\u043E\u0434\u0441\u0442\u0440\u043E\u043A\u0438 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u0432\u0432\u043E\u0434\u0447\u0438\u0441\u043B\u0430 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u0432\u043E\u043F\u0440\u043E\u0441 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 '\n + '\u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044E\u043E\u0431\u043E\u0448\u0438\u0431\u043A\u0435 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u043D\u0430\u043A\u0430\u0440\u0442\u0435 \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u043E\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u0435\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u043F\u043E\u043A\u0430\u0437\u0430\u0442\u044C\u043F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0436\u0434\u0435\u043D\u0438\u0435 \u043F\u043E\u043B\u043D\u043E\u0435\u0438\u043C\u044F\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044Ccom\u043E\u0431\u044A\u0435\u043A\u0442 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044Cxml\u0442\u0438\u043F \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0430\u0434\u0440\u0435\u0441\u043F\u043E\u043C\u0435\u0441\u0442\u043E\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u044E \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0443\u0441\u0435\u0430\u043D\u0441\u043E\u0432 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0432\u0440\u0435\u043C\u044F\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F\u0441\u043F\u044F\u0449\u0435\u0433\u043E\u0441\u0435\u0430\u043D\u0441\u0430 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0432\u0440\u0435\u043C\u044F\u0437\u0430\u0441\u044B\u043F\u0430\u043D\u0438\u044F\u043F\u0430\u0441\u0441\u0438\u0432\u043D\u043E\u0433\u043E\u0441\u0435\u0430\u043D\u0441\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0432\u0440\u0435\u043C\u044F\u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0434\u0430\u043D\u043D\u044B\u0435\u0432\u044B\u0431\u043E\u0440\u0430 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u043A\u043B\u0438\u0435\u043D\u0442\u0430\u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435\u043A\u043E\u0434\u044B\u043B\u043E\u043A\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435\u0447\u0430\u0441\u043E\u0432\u044B\u0435\u043F\u043E\u044F\u0441\u0430 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\u0441\u0438\u0441\u0442\u0435\u043C\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u043E\u0442\u0431\u043E\u0440\u0430\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0438\u0437\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u0433\u043E\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0438\u043C\u044F\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u0433\u043E\u0444\u0430\u0439\u043B\u0430 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0438\u043C\u044F\u043A\u043B\u0438\u0435\u043D\u0442\u0430\u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044E\u044D\u043A\u0440\u0430\u043D\u043E\u0432\u043A\u043B\u0438\u0435\u043D\u0442\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0441\u043E\u0431\u044B\u0442\u0438\u044F\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043A\u0440\u0430\u0442\u043A\u0438\u0439\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043C\u0430\u043A\u0435\u0442\u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u044F '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043C\u0430\u0441\u043A\u0443\u0432\u0441\u0435\u0444\u0430\u0439\u043B\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043C\u0430\u0441\u043A\u0443\u0432\u0441\u0435\u0444\u0430\u0439\u043B\u044B\u043A\u043B\u0438\u0435\u043D\u0442\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043C\u0430\u0441\u043A\u0443\u0432\u0441\u0435\u0444\u0430\u0439\u043B\u044B\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043C\u0435\u0441\u0442\u043E\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043F\u043E\u0430\u0434\u0440\u0435\u0441\u0443 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0443\u044E\u0434\u043B\u0438\u043D\u0443\u043F\u0430\u0440\u043E\u043B\u0435\u0439\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043E\u043D\u043D\u0443\u044E\u0441\u0441\u044B\u043B\u043A\u0443 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043E\u043D\u043D\u0443\u044E\u0441\u0441\u044B\u043B\u043A\u0443\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438\u0431\u0430\u0437\u044B\u0434\u0430\u043D\u043D\u044B\u0445 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043E\u0431\u0449\u0438\u0439\u043C\u0430\u043A\u0435\u0442 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043E\u0431\u0449\u0443\u044E\u0444\u043E\u0440\u043C\u0443 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043E\u043A\u043D\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043E\u043F\u0435\u0440\u0430\u0442\u0438\u0432\u043D\u0443\u044E\u043E\u0442\u043C\u0435\u0442\u043A\u0443\u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043E\u0442\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435\u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0433\u043E\u0440\u0435\u0436\u0438\u043C\u0430 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B\u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0445\u043E\u043F\u0446\u0438\u0439\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043F\u043E\u043B\u043D\u043E\u0435\u0438\u043C\u044F\u043F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043D\u043E\u0433\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043D\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u043E\u043D\u043D\u044B\u0445\u0441\u0441\u044B\u043B\u043E\u043A \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0443\u0441\u043B\u043E\u0436\u043D\u043E\u0441\u0442\u0438\u043F\u0430\u0440\u043E\u043B\u0435\u0439\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C\u043F\u0443\u0442\u0438 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C\u043F\u0443\u0442\u0438\u043A\u043B\u0438\u0435\u043D\u0442\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u0435\u043B\u044C\u043F\u0443\u0442\u0438\u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0441\u0435\u0430\u043D\u0441\u044B\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0441\u043A\u043E\u0440\u043E\u0441\u0442\u044C\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044E '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435\u043E\u0431\u044A\u0435\u043A\u0442\u0430\u0438\u0444\u043E\u0440\u043C\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0441\u043E\u0441\u0442\u0430\u0432\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0433\u043E\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430odata \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0443\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F\u0431\u0430\u0437\u044B\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0442\u0435\u043A\u0443\u0449\u0438\u0439\u0441\u0435\u0430\u043D\u0441\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0444\u0430\u0439\u043B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0444\u0430\u0439\u043B\u044B \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0444\u043E\u0440\u043C\u0443 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u0443\u044E\u043E\u043F\u0446\u0438\u044E '\n + '\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u0443\u044E\u043E\u043F\u0446\u0438\u044E\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0447\u0430\u0441\u043E\u0432\u043E\u0439\u043F\u043E\u044F\u0441\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438\u043E\u0441 \u043F\u043E\u043C\u0435\u0441\u0442\u0438\u0442\u044C\u0432\u043E\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u0435\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435 '\n + '\u043F\u043E\u043C\u0435\u0441\u0442\u0438\u0442\u044C\u0444\u0430\u0439\u043B \u043F\u043E\u043C\u0435\u0441\u0442\u0438\u0442\u044C\u0444\u0430\u0439\u043B\u044B \u043F\u0440\u0430\u0432 \u043F\u0440\u0430\u0432\u043E\u0434\u043E\u0441\u0442\u0443\u043F\u0430 \u043F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043D\u043E\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043A\u043E\u0434\u0430\u043B\u043E\u043A\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 \u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0435\u0440\u0438\u043E\u0434\u0430 '\n + '\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0440\u0430\u0432\u0430 \u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0441\u043E\u0431\u044B\u0442\u0438\u044F\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0447\u0430\u0441\u043E\u0432\u043E\u0433\u043E\u043F\u043E\u044F\u0441\u0430 \u043F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0436\u0434\u0435\u043D\u0438\u0435 '\n + '\u043F\u0440\u0435\u043A\u0440\u0430\u0442\u0438\u0442\u044C\u0440\u0430\u0431\u043E\u0442\u0443\u0441\u0438\u0441\u0442\u0435\u043C\u044B \u043F\u0440\u0438\u0432\u0438\u043B\u0435\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C \u043F\u0440\u043E\u0434\u043E\u043B\u0436\u0438\u0442\u044C\u0432\u044B\u0437\u043E\u0432 \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044Cjson \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044Cxml \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C\u0434\u0430\u0442\u0443json \u043F\u0443\u0441\u0442\u0430\u044F\u0441\u0442\u0440\u043E\u043A\u0430 '\n + '\u0440\u0430\u0431\u043E\u0447\u0438\u0439\u043A\u0430\u0442\u0430\u043B\u043E\u0433\u0434\u0430\u043D\u043D\u044B\u0445\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0440\u0430\u0437\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0434\u0430\u043D\u043D\u044B\u0435\u0434\u043B\u044F\u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u044C\u0444\u0430\u0439\u043B \u0440\u0430\u0437\u043E\u0440\u0432\u0430\u0442\u044C\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435\u0441\u0432\u043D\u0435\u0448\u043D\u0438\u043C\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u043E\u043C\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0440\u0430\u0441\u043A\u043E\u0434\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0441\u0442\u0440\u043E\u043A\u0443 \u0440\u043E\u043B\u044C\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u0430 \u0441\u0435\u043A\u0443\u043D\u0434\u0430 \u0441\u0438\u0433\u043D\u0430\u043B \u0441\u0438\u043C\u0432\u043E\u043B \u0441\u043A\u043E\u043F\u0438\u0440\u043E\u0432\u0430\u0442\u044C\u0436\u0443\u0440\u043D\u0430\u043B\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u043C\u0435\u0449\u0435\u043D\u0438\u0435\u043B\u0435\u0442\u043D\u0435\u0433\u043E\u0432\u0440\u0435\u043C\u0435\u043D\u0438 '\n + '\u0441\u043C\u0435\u0449\u0435\u043D\u0438\u0435\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0433\u043E\u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u0441\u043E\u0435\u0434\u0438\u043D\u0438\u0442\u044C\u0431\u0443\u0444\u0435\u0440\u044B\u0434\u0432\u043E\u0438\u0447\u043D\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u043E\u0437\u0434\u0430\u0442\u044C\u043A\u0430\u0442\u0430\u043B\u043E\u0433 \u0441\u043E\u0437\u0434\u0430\u0442\u044C\u0444\u0430\u0431\u0440\u0438\u043A\u0443xdto \u0441\u043E\u043A\u0440\u043B \u0441\u043E\u043A\u0440\u043B\u043F \u0441\u043E\u043A\u0440\u043F \u0441\u043E\u043E\u0431\u0449\u0438\u0442\u044C '\n + '\u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435 \u0441\u043E\u0445\u0440\u0430\u043D\u0438\u0442\u044C\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0441\u0440\u0435\u0434 \u0441\u0442\u0440\u0434\u043B\u0438\u043D\u0430 \u0441\u0442\u0440\u0437\u0430\u043A\u0430\u043D\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044F\u043D\u0430 \u0441\u0442\u0440\u0437\u0430\u043C\u0435\u043D\u0438\u0442\u044C \u0441\u0442\u0440\u043D\u0430\u0439\u0442\u0438 \u0441\u0442\u0440\u043D\u0430\u0447\u0438\u043D\u0430\u0435\u0442\u0441\u044F\u0441 '\n + '\u0441\u0442\u0440\u043E\u043A\u0430 \u0441\u0442\u0440\u043E\u043A\u0430\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u0441\u0442\u0440\u043F\u043E\u043B\u0443\u0447\u0438\u0442\u044C\u0441\u0442\u0440\u043E\u043A\u0443 \u0441\u0442\u0440\u0440\u0430\u0437\u0434\u0435\u043B\u0438\u0442\u044C \u0441\u0442\u0440\u0441\u043E\u0435\u0434\u0438\u043D\u0438\u0442\u044C \u0441\u0442\u0440\u0441\u0440\u0430\u0432\u043D\u0438\u0442\u044C \u0441\u0442\u0440\u0447\u0438\u0441\u043B\u043E\u0432\u0445\u043E\u0436\u0434\u0435\u043D\u0438\u0439 '\n + '\u0441\u0442\u0440\u0447\u0438\u0441\u043B\u043E\u0441\u0442\u0440\u043E\u043A \u0441\u0442\u0440\u0448\u0430\u0431\u043B\u043E\u043D \u0442\u0435\u043A\u0443\u0449\u0430\u044F\u0434\u0430\u0442\u0430 \u0442\u0435\u043A\u0443\u0449\u0430\u044F\u0434\u0430\u0442\u0430\u0441\u0435\u0430\u043D\u0441\u0430 \u0442\u0435\u043A\u0443\u0449\u0430\u044F\u0443\u043D\u0438\u0432\u0435\u0440\u0441\u0430\u043B\u044C\u043D\u0430\u044F\u0434\u0430\u0442\u0430 \u0442\u0435\u043A\u0443\u0449\u0430\u044F\u0443\u043D\u0438\u0432\u0435\u0440\u0441\u0430\u043B\u044C\u043D\u0430\u044F\u0434\u0430\u0442\u0430\u0432\u043C\u0438\u043B\u043B\u0438\u0441\u0435\u043A\u0443\u043D\u0434\u0430\u0445 '\n + '\u0442\u0435\u043A\u0443\u0449\u0438\u0439\u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0442\u0435\u043A\u0443\u0449\u0438\u0439\u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0433\u043E\u0448\u0440\u0438\u0444\u0442\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0442\u0435\u043A\u0443\u0449\u0438\u0439\u043A\u043E\u0434\u043B\u043E\u043A\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438 '\n + '\u0442\u0435\u043A\u0443\u0449\u0438\u0439\u0440\u0435\u0436\u0438\u043C\u0437\u0430\u043F\u0443\u0441\u043A\u0430 \u0442\u0435\u043A\u0443\u0449\u0438\u0439\u044F\u0437\u044B\u043A \u0442\u0435\u043A\u0443\u0449\u0438\u0439\u044F\u0437\u044B\u043A\u0441\u0438\u0441\u0442\u0435\u043C\u044B \u0442\u0438\u043F \u0442\u0438\u043F\u0437\u043D\u0447 \u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u044F\u0430\u043A\u0442\u0438\u0432\u043D\u0430 \u0442\u0440\u0435\u0433 \u0443\u0434\u0430\u043B\u0438\u0442\u044C\u0434\u0430\u043D\u043D\u044B\u0435\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B '\n + '\u0443\u0434\u0430\u043B\u0438\u0442\u044C\u0438\u0437\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u0433\u043E\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430 \u0443\u0434\u0430\u043B\u0438\u0442\u044C\u043E\u0431\u044A\u0435\u043A\u0442\u044B \u0443\u0434\u0430\u043B\u0438\u0442\u044C\u0444\u0430\u0439\u043B\u044B \u0443\u043D\u0438\u0432\u0435\u0440\u0441\u0430\u043B\u044C\u043D\u043E\u0435\u0432\u0440\u0435\u043C\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C\u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u044F\u0434\u0430\u043D\u043D\u044B\u0445 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0443\u0441\u0435\u0430\u043D\u0441\u043E\u0432 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0432\u043D\u0435\u0448\u043D\u044E\u044E\u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u0443 '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0432\u0440\u0435\u043C\u044F\u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u0438\u044F\u0441\u043F\u044F\u0449\u0435\u0433\u043E\u0441\u0435\u0430\u043D\u0441\u0430 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0432\u0440\u0435\u043C\u044F\u0437\u0430\u0441\u044B\u043F\u0430\u043D\u0438\u044F\u043F\u0430\u0441\u0441\u0438\u0432\u043D\u043E\u0433\u043E\u0441\u0435\u0430\u043D\u0441\u0430 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0432\u0440\u0435\u043C\u044F\u043E\u0436\u0438\u0434\u0430\u043D\u0438\u044F\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\u0441\u0438\u0441\u0442\u0435\u043C\u044B \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0441\u043E\u0431\u044B\u0442\u0438\u044F\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043A\u0440\u0430\u0442\u043A\u0438\u0439\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043E\u043A\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0443\u044E\u0434\u043B\u0438\u043D\u0443\u043F\u0430\u0440\u043E\u043B\u0435\u0439\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043C\u043E\u043D\u043E\u043F\u043E\u043B\u044C\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\u043A\u043B\u0438\u0435\u043D\u0442\u0430\u043B\u0438\u0446\u0435\u043D\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043E\u0442\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435\u0431\u0435\u0437\u043E\u043F\u0430\u0441\u043D\u043E\u0433\u043E\u0440\u0435\u0436\u0438\u043C\u0430 '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B\u0444\u0443\u043D\u043A\u0446\u0438\u043E\u043D\u0430\u043B\u044C\u043D\u044B\u0445\u043E\u043F\u0446\u0438\u0439\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043F\u0440\u0438\u0432\u0438\u043B\u0435\u0433\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0443\u0441\u043B\u043E\u0436\u043D\u043E\u0441\u0442\u0438\u043F\u0430\u0440\u043E\u043B\u0435\u0439\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0435\u0439 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435\u0440\u0430\u0431\u043E\u0442\u044B\u0441\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0435\u0439 '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0435\u0440\u0430\u0431\u043E\u0442\u044B\u0441\u0444\u0430\u0439\u043B\u0430\u043C\u0438 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435\u0441\u0432\u043D\u0435\u0448\u043D\u0438\u043C\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u043E\u043C\u0434\u0430\u043D\u043D\u044B\u0445 \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435\u043E\u0431\u044A\u0435\u043A\u0442\u0430\u0438\u0444\u043E\u0440\u043C\u044B '\n + '\u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0441\u043E\u0441\u0442\u0430\u0432\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0433\u043E\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430odata \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0447\u0430\u0441\u043E\u0432\u043E\u0439\u043F\u043E\u044F\u0441\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u0443\u0441\u0442\u0430\u043D\u043E\u0432\u0438\u0442\u044C\u0447\u0430\u0441\u043E\u0432\u043E\u0439\u043F\u043E\u044F\u0441\u0441\u0435\u0430\u043D\u0441\u0430 '\n + '\u0444\u043E\u0440\u043C\u0430\u0442 \u0446\u0435\u043B \u0447\u0430\u0441 \u0447\u0430\u0441\u043E\u0432\u043E\u0439\u043F\u043E\u044F\u0441 \u0447\u0430\u0441\u043E\u0432\u043E\u0439\u043F\u043E\u044F\u0441\u0441\u0435\u0430\u043D\u0441\u0430 \u0447\u0438\u0441\u043B\u043E \u0447\u0438\u0441\u043B\u043E\u043F\u0440\u043E\u043F\u0438\u0441\u044C\u044E \u044D\u0442\u043E\u0430\u0434\u0440\u0435\u0441\u0432\u0440\u0435\u043C\u0435\u043D\u043D\u043E\u0433\u043E\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430 ';\n\n // v8 \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 \u0433\u043B\u043E\u0431\u0430\u043B\u044C\u043D\u043E\u0433\u043E \u043A\u043E\u043D\u0442\u0435\u043A\u0441\u0442\u0430 ==> built_in\n const v8_global_context_property =\n 'ws\u0441\u0441\u044B\u043B\u043A\u0438 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430\u043A\u0430\u0440\u0442\u0438\u043D\u043E\u043A \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430\u043C\u0430\u043A\u0435\u0442\u043E\u0432\u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u044F\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430\u0441\u0442\u0438\u043B\u0435\u0439 \u0431\u0438\u0437\u043D\u0435\u0441\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u044B '\n + '\u0432\u043D\u0435\u0448\u043D\u0438\u0435\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0432\u043D\u0435\u0448\u043D\u0438\u0435\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438 \u0432\u043D\u0435\u0448\u043D\u0438\u0435\u043E\u0442\u0447\u0435\u0442\u044B \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435\u043F\u043E\u043A\u0443\u043F\u043A\u0438 \u0433\u043B\u0430\u0432\u043D\u044B\u0439\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0433\u043B\u0430\u0432\u043D\u044B\u0439\u0441\u0442\u0438\u043B\u044C '\n + '\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u044B \u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u043C\u044B\u0435\u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F \u0436\u0443\u0440\u043D\u0430\u043B\u044B\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u0437\u0430\u0434\u0430\u0447\u0438 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\u043E\u0431\u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0438 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0440\u0430\u0431\u043E\u0447\u0435\u0439\u0434\u0430\u0442\u044B '\n + '\u0438\u0441\u0442\u043E\u0440\u0438\u044F\u0440\u0430\u0431\u043E\u0442\u044B\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u043A\u043E\u043D\u0441\u0442\u0430\u043D\u0442\u044B \u043A\u0440\u0438\u0442\u0435\u0440\u0438\u0438\u043E\u0442\u0431\u043E\u0440\u0430 \u043C\u0435\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0435 \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0440\u0435\u043A\u043B\u0430\u043C\u044B \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0430\u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u043C\u044B\u0445\u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0439 '\n + '\u043E\u0442\u0447\u0435\u0442\u044B \u043F\u0430\u043D\u0435\u043B\u044C\u0437\u0430\u0434\u0430\u0447\u043E\u0441 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0437\u0430\u043F\u0443\u0441\u043A\u0430 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B\u0441\u0435\u0430\u043D\u0441\u0430 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F \u043F\u043B\u0430\u043D\u044B\u0432\u0438\u0434\u043E\u0432\u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043F\u043B\u0430\u043D\u044B\u0432\u0438\u0434\u043E\u0432\u0445\u0430\u0440\u0430\u043A\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043A '\n + '\u043F\u043B\u0430\u043D\u044B\u043E\u0431\u043C\u0435\u043D\u0430 \u043F\u043B\u0430\u043D\u044B\u0441\u0447\u0435\u0442\u043E\u0432 \u043F\u043E\u043B\u043D\u043E\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0439\u043F\u043E\u0438\u0441\u043A \u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u0438\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u043E\u043D\u043D\u043E\u0439\u0431\u0430\u0437\u044B \u043F\u043E\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0438 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430\u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0445\u043F\u043E\u043A\u0443\u043F\u043E\u043A '\n + '\u0440\u0430\u0431\u043E\u0447\u0430\u044F\u0434\u0430\u0442\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044B\u0431\u0443\u0445\u0433\u0430\u043B\u0442\u0435\u0440\u0438\u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044B\u043D\u0430\u043A\u043E\u043F\u043B\u0435\u043D\u0438\u044F \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044B\u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u044B\u0441\u0432\u0435\u0434\u0435\u043D\u0438\u0439 '\n + '\u0440\u0435\u0433\u043B\u0430\u043C\u0435\u043D\u0442\u043D\u044B\u0435\u0437\u0430\u0434\u0430\u043D\u0438\u044F \u0441\u0435\u0440\u0438\u0430\u043B\u0438\u0437\u0430\u0442\u043E\u0440xdto \u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u0433\u0435\u043E\u043F\u043E\u0437\u0438\u0446\u0438\u043E\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043C\u0443\u043B\u044C\u0442\u0438\u043C\u0435\u0434\u0438\u0430 '\n + '\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0440\u0435\u043A\u043B\u0430\u043C\u044B \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043F\u043E\u0447\u0442\u044B \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u0442\u0435\u043B\u0435\u0444\u043E\u043D\u0438\u0438 \u0444\u0430\u0431\u0440\u0438\u043A\u0430xdto \u0444\u0430\u0439\u043B\u043E\u0432\u044B\u0435\u043F\u043E\u0442\u043E\u043A\u0438 \u0444\u043E\u043D\u043E\u0432\u044B\u0435\u0437\u0430\u0434\u0430\u043D\u0438\u044F \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A '\n + '\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435\u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043E\u0432\u043E\u0442\u0447\u0435\u0442\u043E\u0432 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u0434\u0430\u043D\u043D\u044B\u0445\u0444\u043E\u0440\u043C \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435\u043E\u0431\u0449\u0438\u0445\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u0434\u0438\u043D\u0430\u043C\u0438\u0447\u0435\u0441\u043A\u0438\u0445\u0441\u043F\u0438\u0441\u043A\u043E\u0432 '\n + '\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u0441\u043A\u0438\u0445\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u043E\u0442\u0447\u0435\u0442\u043E\u0432 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435\u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0445\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A ';\n\n // built_in : \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u0438\u043B\u0438 \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u0447\u043D\u044B\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B (\u043A\u043E\u043D\u0441\u0442\u0430\u043D\u0442\u044B, \u043A\u043B\u0430\u0441\u0441\u044B, \u0444\u0443\u043D\u043A\u0446\u0438\u0438)\n const BUILTIN =\n v7_system_constants\n + v7_global_context_methods + v8_global_context_methods\n + v8_global_context_property;\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043D\u0430\u0431\u043E\u0440\u044B \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 ==> class\n const v8_system_sets_of_values =\n 'web\u0446\u0432\u0435\u0442\u0430 windows\u0446\u0432\u0435\u0442\u0430 windows\u0448\u0440\u0438\u0444\u0442\u044B \u0431\u0438\u0431\u043B\u0438\u043E\u0442\u0435\u043A\u0430\u043A\u0430\u0440\u0442\u0438\u043D\u043E\u043A \u0440\u0430\u043C\u043A\u0438\u0441\u0442\u0438\u043B\u044F \u0441\u0438\u043C\u0432\u043E\u043B\u044B \u0446\u0432\u0435\u0442\u0430\u0441\u0442\u0438\u043B\u044F \u0448\u0440\u0438\u0444\u0442\u044B\u0441\u0442\u0438\u043B\u044F ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043D\u044B\u0435 ==> class\n const v8_system_enums_interface =\n '\u0430\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u043E\u0435\u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435\u0434\u0430\u043D\u043D\u044B\u0445\u0444\u043E\u0440\u043C\u044B\u0432\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445 \u0430\u0432\u0442\u043E\u043D\u0443\u043C\u0435\u0440\u0430\u0446\u0438\u044F\u0432\u0444\u043E\u0440\u043C\u0435 \u0430\u0432\u0442\u043E\u0440\u0430\u0437\u0434\u0432\u0438\u0436\u0435\u043D\u0438\u0435\u0441\u0435\u0440\u0438\u0439 '\n + '\u0430\u043D\u0438\u043C\u0430\u0446\u0438\u044F\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u044F\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\u0438\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u043E\u0432 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u0432\u044B\u0441\u043E\u0442\u043E\u0439\u0442\u0430\u0431\u043B\u0438\u0446\u044B '\n + '\u0432\u0435\u0440\u0442\u0438\u043A\u0430\u043B\u044C\u043D\u0430\u044F\u043F\u0440\u043E\u043A\u0440\u0443\u0442\u043A\u0430\u0444\u043E\u0440\u043C\u044B \u0432\u0435\u0440\u0442\u0438\u043A\u0430\u043B\u044C\u043D\u043E\u0435\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0432\u0435\u0440\u0442\u0438\u043A\u0430\u043B\u044C\u043D\u043E\u0435\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430 \u0432\u0438\u0434\u0433\u0440\u0443\u043F\u043F\u044B\u0444\u043E\u0440\u043C\u044B '\n + '\u0432\u0438\u0434\u0434\u0435\u043A\u043E\u0440\u0430\u0446\u0438\u0438\u0444\u043E\u0440\u043C\u044B \u0432\u0438\u0434\u0434\u043E\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0444\u043E\u0440\u043C\u044B \u0432\u0438\u0434\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F\u0434\u0430\u043D\u043D\u044B\u0445 \u0432\u0438\u0434\u043A\u043D\u043E\u043F\u043A\u0438\u0444\u043E\u0440\u043C\u044B \u0432\u0438\u0434\u043F\u0435\u0440\u0435\u043A\u043B\u044E\u0447\u0430\u0442\u0435\u043B\u044F '\n + '\u0432\u0438\u0434\u043F\u043E\u0434\u043F\u0438\u0441\u0435\u0439\u043A\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u0435 \u0432\u0438\u0434\u043F\u043E\u043B\u044F\u0444\u043E\u0440\u043C\u044B \u0432\u0438\u0434\u0444\u043B\u0430\u0436\u043A\u0430 \u0432\u043B\u0438\u044F\u043D\u0438\u0435\u0440\u0430\u0437\u043C\u0435\u0440\u0430\u043D\u0430\u043F\u0443\u0437\u044B\u0440\u0435\u043A\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0433\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0435\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435 '\n + '\u0433\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0435\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430 \u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u043A\u0430\u043A\u043E\u043B\u043E\u043D\u043E\u043A \u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u043A\u0430\u043F\u043E\u0434\u0447\u0438\u043D\u0435\u043D\u043D\u044B\u0445\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\u0444\u043E\u0440\u043C\u044B '\n + '\u0433\u0440\u0443\u043F\u043F\u044B\u0438\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043F\u0435\u0440\u0435\u0442\u0430\u0441\u043A\u0438\u0432\u0430\u043D\u0438\u044F \u0434\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u044B\u0439\u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F \u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044F\u043F\u0435\u0440\u0435\u0442\u0430\u0441\u043A\u0438\u0432\u0430\u043D\u0438\u044F '\n + '\u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u043C\u0435\u0436\u0434\u0443\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u043C\u0438\u0444\u043E\u0440\u043C\u044B \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0432\u044B\u0432\u043E\u0434\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043F\u043E\u043B\u043E\u0441\u044B\u043F\u0440\u043E\u043A\u0440\u0443\u0442\u043A\u0438 '\n + '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C\u043E\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0442\u043E\u0447\u043A\u0438\u0431\u0438\u0440\u0436\u0435\u0432\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0438\u0441\u0442\u043E\u0440\u0438\u044F\u0432\u044B\u0431\u043E\u0440\u0430\u043F\u0440\u0438\u0432\u0432\u043E\u0434\u0435 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439\u043E\u0441\u0438\u0442\u043E\u0447\u0435\u043A\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u0440\u0430\u0437\u043C\u0435\u0440\u0430\u043F\u0443\u0437\u044B\u0440\u044C\u043A\u0430\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F\u0433\u0440\u0443\u043F\u043F\u044B\u043A\u043E\u043C\u0430\u043D\u0434 \u043C\u0430\u043A\u0441\u0438\u043C\u0443\u043C\u0441\u0435\u0440\u0438\u0439 \u043D\u0430\u0447\u0430\u043B\u044C\u043D\u043E\u0435\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0434\u0435\u0440\u0435\u0432\u0430 '\n + '\u043D\u0430\u0447\u0430\u043B\u044C\u043D\u043E\u0435\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0441\u043F\u0438\u0441\u043A\u0430 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\u0442\u0435\u043A\u0441\u0442\u0430\u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F \u043E\u0440\u0438\u0435\u043D\u0442\u0430\u0446\u0438\u044F\u0434\u0435\u043D\u0434\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u043E\u0440\u0438\u0435\u043D\u0442\u0430\u0446\u0438\u044F\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u043E\u0440\u0438\u0435\u043D\u0442\u0430\u0446\u0438\u044F\u043C\u0435\u0442\u043E\u043A\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u043E\u0440\u0438\u0435\u043D\u0442\u0430\u0446\u0438\u044F\u043C\u0435\u0442\u043E\u043A\u0441\u0432\u043E\u0434\u043D\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u043E\u0440\u0438\u0435\u043D\u0442\u0430\u0446\u0438\u044F\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0444\u043E\u0440\u043C\u044B \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0432\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u0435 '\n + '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0432\u043B\u0435\u0433\u0435\u043D\u0434\u0435\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0433\u0440\u0443\u043F\u043F\u044B\u043A\u043D\u043E\u043F\u043E\u043A \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u0448\u043A\u0430\u043B\u044B\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439\u0441\u0432\u043E\u0434\u043D\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u0438\u0437\u043C\u0435\u0440\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B\u0433\u0430\u043D\u0442\u0430 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043A\u043D\u043E\u043F\u043A\u0438 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043A\u043D\u043E\u043F\u043A\u0438\u0432\u044B\u0431\u043E\u0440\u0430 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043E\u0431\u0441\u0443\u0436\u0434\u0435\u043D\u0438\u0439\u0444\u043E\u0440\u043C\u044B '\n + '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043E\u0431\u044B\u0447\u043D\u043E\u0439\u0433\u0440\u0443\u043F\u043F\u044B \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043E\u0442\u0440\u0438\u0446\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0445\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439\u043F\u0443\u0437\u044B\u0440\u044C\u043A\u043E\u0432\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043F\u0430\u043D\u0435\u043B\u0438\u043F\u043E\u0438\u0441\u043A\u0430 '\n + '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043F\u0440\u0435\u0434\u0443\u043F\u0440\u0435\u0436\u0434\u0435\u043D\u0438\u044F\u043F\u0440\u0438\u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0438 \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0440\u0430\u0437\u043C\u0435\u0442\u043A\u0438\u043F\u043E\u043B\u043E\u0441\u044B\u0440\u0435\u0433\u0443\u043B\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F '\n + '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0444\u043E\u0440\u043C\u044B \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0442\u0430\u0431\u043B\u0438\u0446\u044B \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0442\u0435\u043A\u0441\u0442\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B\u0433\u0430\u043D\u0442\u0430 '\n + '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043E\u0431\u044B\u0447\u043D\u043E\u0439\u0433\u0440\u0443\u043F\u043F\u044B \u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0444\u0438\u0433\u0443\u0440\u044B\u043A\u043D\u043E\u043F\u043A\u0438 \u043F\u0430\u043B\u0438\u0442\u0440\u0430\u0446\u0432\u0435\u0442\u043E\u0432\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u043F\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0435\u043E\u0431\u044B\u0447\u043D\u043E\u0439\u0433\u0440\u0443\u043F\u043F\u044B '\n + '\u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0430\u043C\u0430\u0441\u0448\u0442\u0430\u0431\u0430\u0434\u0435\u043D\u0434\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0430\u043C\u0430\u0441\u0448\u0442\u0430\u0431\u0430\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B\u0433\u0430\u043D\u0442\u0430 \u043F\u043E\u0434\u0434\u0435\u0440\u0436\u043A\u0430\u043C\u0430\u0441\u0448\u0442\u0430\u0431\u0430\u0441\u0432\u043E\u0434\u043D\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u043F\u043E\u0438\u0441\u043A\u0432\u0442\u0430\u0431\u043B\u0438\u0446\u0435\u043F\u0440\u0438\u0432\u0432\u043E\u0434\u0435 \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0444\u043E\u0440\u043C\u044B \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438\u043A\u043D\u043E\u043F\u043A\u0438\u0444\u043E\u0440\u043C\u044B '\n + '\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043A\u043E\u043C\u0430\u043D\u0434\u043D\u043E\u0439\u043F\u0430\u043D\u0435\u043B\u0438\u0444\u043E\u0440\u043C\u044B \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043A\u043E\u043C\u0430\u043D\u0434\u043D\u043E\u0439\u043F\u0430\u043D\u0435\u043B\u0438\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0444\u043E\u0440\u043C\u044B '\n + '\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043E\u043F\u043E\u0440\u043D\u043E\u0439\u0442\u043E\u0447\u043A\u0438\u043E\u0442\u0440\u0438\u0441\u043E\u0432\u043A\u0438 \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043F\u043E\u0434\u043F\u0438\u0441\u0435\u0439\u043A\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u0435 \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043F\u043E\u0434\u043F\u0438\u0441\u0435\u0439\u0448\u043A\u0430\u043B\u044B\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439\u0438\u0437\u043C\u0435\u0440\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F\u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0430 \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0441\u0442\u0440\u043E\u043A\u0438\u043F\u043E\u0438\u0441\u043A\u0430 \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0442\u0435\u043A\u0441\u0442\u0430\u0441\u043E\u0435\u0434\u0438\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439\u043B\u0438\u043D\u0438\u0438 \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043F\u043E\u0438\u0441\u043A\u043E\u043C '\n + '\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0448\u043A\u0430\u043B\u044B\u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u043F\u043E\u0440\u044F\u0434\u043E\u043A\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0442\u043E\u0447\u0435\u043A\u0433\u043E\u0440\u0438\u0437\u043E\u043D\u0442\u0430\u043B\u044C\u043D\u043E\u0439\u0433\u0438\u0441\u0442\u043E\u0433\u0440\u0430\u043C\u043C\u044B \u043F\u043E\u0440\u044F\u0434\u043E\u043A\u0441\u0435\u0440\u0438\u0439\u0432\u043B\u0435\u0433\u0435\u043D\u0434\u0435\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u0440\u0430\u0437\u043C\u0435\u0440\u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u0448\u043A\u0430\u043B\u044B\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0440\u0430\u0441\u0442\u044F\u0433\u0438\u0432\u0430\u043D\u0438\u0435\u043F\u043E\u0432\u0435\u0440\u0442\u0438\u043A\u0430\u043B\u0438\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B\u0433\u0430\u043D\u0442\u0430 '\n + '\u0440\u0435\u0436\u0438\u043C\u0430\u0432\u0442\u043E\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u044F \u0440\u0435\u0436\u0438\u043C\u0432\u0432\u043E\u0434\u0430\u0441\u0442\u0440\u043E\u043A\u0442\u0430\u0431\u043B\u0438\u0446\u044B \u0440\u0435\u0436\u0438\u043C\u0432\u044B\u0431\u043E\u0440\u0430\u043D\u0435\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u043D\u043E\u0433\u043E \u0440\u0435\u0436\u0438\u043C\u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u044F\u0434\u0430\u0442\u044B '\n + '\u0440\u0435\u0436\u0438\u043C\u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u044F\u0441\u0442\u0440\u043E\u043A\u0438\u0442\u0430\u0431\u043B\u0438\u0446\u044B \u0440\u0435\u0436\u0438\u043C\u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u044F\u0442\u0430\u0431\u043B\u0438\u0446\u044B \u0440\u0435\u0436\u0438\u043C\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F\u0440\u0430\u0437\u043C\u0435\u0440\u0430 \u0440\u0435\u0436\u0438\u043C\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u044F\u0441\u0432\u044F\u0437\u0430\u043D\u043D\u043E\u0433\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F '\n + '\u0440\u0435\u0436\u0438\u043C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0434\u0438\u0430\u043B\u043E\u0433\u0430\u043F\u0435\u0447\u0430\u0442\u0438 \u0440\u0435\u0436\u0438\u043C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043A\u043E\u043C\u0430\u043D\u0434\u044B \u0440\u0435\u0436\u0438\u043C\u043C\u0430\u0441\u0448\u0442\u0430\u0431\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\u043F\u0440\u043E\u0441\u043C\u043E\u0442\u0440\u0430 '\n + '\u0440\u0435\u0436\u0438\u043C\u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0433\u043E\u043E\u043A\u043D\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043A\u0440\u044B\u0442\u0438\u044F\u043E\u043A\u043D\u0430\u0444\u043E\u0440\u043C\u044B \u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u044F '\n + '\u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439\u0441\u0435\u0440\u0438\u0438 \u0440\u0435\u0436\u0438\u043C\u043E\u0442\u0440\u0438\u0441\u043E\u0432\u043A\u0438\u0441\u0435\u0442\u043A\u0438\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B '\n + '\u0440\u0435\u0436\u0438\u043C\u043F\u043E\u043B\u0443\u043F\u0440\u043E\u0437\u0440\u0430\u0447\u043D\u043E\u0441\u0442\u0438\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0440\u0435\u0436\u0438\u043C\u043F\u0440\u043E\u0431\u0435\u043B\u043E\u0432\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0440\u0435\u0436\u0438\u043C\u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F\u043D\u0430\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u0435 \u0440\u0435\u0436\u0438\u043C\u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\u043A\u043E\u043B\u043E\u043D\u043A\u0438 '\n + '\u0440\u0435\u0436\u0438\u043C\u0441\u0433\u043B\u0430\u0436\u0438\u0432\u0430\u043D\u0438\u044F\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0440\u0435\u0436\u0438\u043C\u0441\u0433\u043B\u0430\u0436\u0438\u0432\u0430\u043D\u0438\u044F\u0438\u043D\u0434\u0438\u043A\u0430\u0442\u043E\u0440\u0430 \u0440\u0435\u0436\u0438\u043C\u0441\u043F\u0438\u0441\u043A\u0430\u0437\u0430\u0434\u0430\u0447 \u0441\u043A\u0432\u043E\u0437\u043D\u043E\u0435\u0432\u044B\u0440\u0430\u0432\u043D\u0438\u0432\u0430\u043D\u0438\u0435 '\n + '\u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u0435\u0434\u0430\u043D\u043D\u044B\u0445\u0444\u043E\u0440\u043C\u044B\u0432\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0430\u0445 \u0441\u043F\u043E\u0441\u043E\u0431\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F\u0442\u0435\u043A\u0441\u0442\u0430\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u0448\u043A\u0430\u043B\u044B\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u0441\u043F\u043E\u0441\u043E\u0431\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u044F\u043E\u0433\u0440\u0430\u043D\u0438\u0447\u0438\u0432\u0430\u044E\u0449\u0435\u0433\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u0430\u044F\u0433\u0440\u0443\u043F\u043F\u0430\u043A\u043E\u043C\u0430\u043D\u0434 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0435\u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u0435 '\n + '\u0441\u0442\u0430\u0442\u0443\u0441\u043E\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u044F\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044F \u0441\u0442\u0438\u043B\u044C\u0441\u0442\u0440\u0435\u043B\u043A\u0438 \u0442\u0438\u043F\u0430\u043F\u043F\u0440\u043E\u043A\u0441\u0438\u043C\u0430\u0446\u0438\u0438\u043B\u0438\u043D\u0438\u0438\u0442\u0440\u0435\u043D\u0434\u0430\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0442\u0438\u043F\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u0442\u0438\u043F\u0435\u0434\u0438\u043D\u0438\u0446\u044B\u0448\u043A\u0430\u043B\u044B\u0432\u0440\u0435\u043C\u0435\u043D\u0438 \u0442\u0438\u043F\u0438\u043C\u043F\u043E\u0440\u0442\u0430\u0441\u0435\u0440\u0438\u0439\u0441\u043B\u043E\u044F\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0442\u0438\u043F\u043B\u0438\u043D\u0438\u0438\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0442\u0438\u043F\u043B\u0438\u043D\u0438\u0438\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u0442\u0438\u043F\u043C\u0430\u0440\u043A\u0435\u0440\u0430\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0442\u0438\u043F\u043C\u0430\u0440\u043A\u0435\u0440\u0430\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0442\u0438\u043F\u043E\u0431\u043B\u0430\u0441\u0442\u0438\u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u044F '\n + '\u0442\u0438\u043F\u043E\u0440\u0433\u0430\u043D\u0438\u0437\u0430\u0446\u0438\u0438\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0442\u0438\u043F\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0441\u0435\u0440\u0438\u0438\u0441\u043B\u043E\u044F\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B '\n + '\u0442\u0438\u043F\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0442\u043E\u0447\u0435\u0447\u043D\u043E\u0433\u043E\u043E\u0431\u044A\u0435\u043A\u0442\u0430\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0442\u0438\u043F\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0448\u043A\u0430\u043B\u044B\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u043B\u0435\u0433\u0435\u043D\u0434\u044B\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B '\n + '\u0442\u0438\u043F\u043F\u043E\u0438\u0441\u043A\u0430\u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0442\u0438\u043F\u043F\u0440\u043E\u0435\u043A\u0446\u0438\u0438\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0442\u0438\u043F\u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F\u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u0439 '\n + '\u0442\u0438\u043F\u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u043E\u0432\u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u0439 \u0442\u0438\u043F\u0440\u0430\u043C\u043A\u0438\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F \u0442\u0438\u043F\u0441\u0432\u043E\u0434\u043D\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u0442\u0438\u043F\u0441\u0432\u044F\u0437\u0438\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B\u0433\u0430\u043D\u0442\u0430 \u0442\u0438\u043F\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439\u043F\u043E\u0441\u0435\u0440\u0438\u044F\u043C\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0442\u0438\u043F\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\u0442\u043E\u0447\u0435\u043A\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u0442\u0438\u043F\u0441\u043E\u0435\u0434\u0438\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0439\u043B\u0438\u043D\u0438\u0438 \u0442\u0438\u043F\u0441\u0442\u043E\u0440\u043E\u043D\u044B\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0442\u0438\u043F\u0444\u043E\u0440\u043C\u044B\u043E\u0442\u0447\u0435\u0442\u0430 \u0442\u0438\u043F\u0448\u043A\u0430\u043B\u044B\u0440\u0430\u0434\u0430\u0440\u043D\u043E\u0439\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B '\n + '\u0444\u0430\u043A\u0442\u043E\u0440\u043B\u0438\u043D\u0438\u0438\u0442\u0440\u0435\u043D\u0434\u0430\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B \u0444\u0438\u0433\u0443\u0440\u0430\u043A\u043D\u043E\u043F\u043A\u0438 \u0444\u0438\u0433\u0443\u0440\u044B\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u043E\u0439\u0441\u0445\u0435\u043C\u044B \u0444\u0438\u043A\u0441\u0430\u0446\u0438\u044F\u0432\u0442\u0430\u0431\u043B\u0438\u0446\u0435 \u0444\u043E\u0440\u043C\u0430\u0442\u0434\u043D\u044F\u0448\u043A\u0430\u043B\u044B\u0432\u0440\u0435\u043C\u0435\u043D\u0438 '\n + '\u0444\u043E\u0440\u043C\u0430\u0442\u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u0448\u0438\u0440\u0438\u043D\u0430\u043F\u043E\u0434\u0447\u0438\u043D\u0435\u043D\u043D\u044B\u0445\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\u0444\u043E\u0440\u043C\u044B ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 \u043F\u0440\u0438\u043A\u043B\u0430\u0434\u043D\u044B\u0445 \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 ==> class\n const v8_system_enums_objects_properties =\n '\u0432\u0438\u0434\u0434\u0432\u0438\u0436\u0435\u043D\u0438\u044F\u0431\u0443\u0445\u0433\u0430\u043B\u0442\u0435\u0440\u0438\u0438 \u0432\u0438\u0434\u0434\u0432\u0438\u0436\u0435\u043D\u0438\u044F\u043D\u0430\u043A\u043E\u043F\u043B\u0435\u043D\u0438\u044F \u0432\u0438\u0434\u043F\u0435\u0440\u0438\u043E\u0434\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0432\u0438\u0434\u0441\u0447\u0435\u0442\u0430 \u0432\u0438\u0434\u0442\u043E\u0447\u043A\u0438\u043C\u0430\u0440\u0448\u0440\u0443\u0442\u0430\u0431\u0438\u0437\u043D\u0435\u0441\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 '\n + '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u043D\u0430\u043A\u043E\u043F\u043B\u0435\u043D\u0438\u044F \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0433\u0440\u0443\u043F\u043F\u0438\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0440\u0435\u0436\u0438\u043C\u0430\u043F\u0440\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u044F '\n + '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0441\u0440\u0435\u0437\u0430 \u043F\u0435\u0440\u0438\u043E\u0434\u0438\u0447\u043D\u043E\u0441\u0442\u044C\u0430\u0433\u0440\u0435\u0433\u0430\u0442\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u043D\u0430\u043A\u043E\u043F\u043B\u0435\u043D\u0438\u044F \u0440\u0435\u0436\u0438\u043C\u0430\u0432\u0442\u043E\u0432\u0440\u0435\u043C\u044F \u0440\u0435\u0436\u0438\u043C\u0437\u0430\u043F\u0438\u0441\u0438\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0440\u0435\u0436\u0438\u043C\u043F\u0440\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u044F\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u043F\u043B\u0430\u043D\u044B \u043E\u0431\u043C\u0435\u043D\u0430 ==> class\n const v8_system_enums_exchange_plans =\n '\u0430\u0432\u0442\u043E\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044F\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0439 \u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439\u043D\u043E\u043C\u0435\u0440\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043E\u0442\u043F\u0440\u0430\u0432\u043A\u0430\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u0435\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0445 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0442\u0430\u0431\u043B\u0438\u0447\u043D\u044B\u0439 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 ==> class\n const v8_system_enums_tabular_document =\n '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0438\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u043E\u0440\u0438\u0435\u043D\u0442\u0430\u0446\u0438\u044F\u0441\u0442\u0440\u0430\u043D\u0438\u0446\u044B \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0438\u0442\u043E\u0433\u043E\u0432\u043A\u043E\u043B\u043E\u043D\u043E\u043A\u0441\u0432\u043E\u0434\u043D\u043E\u0439\u0442\u0430\u0431\u043B\u0438\u0446\u044B '\n + '\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0438\u0442\u043E\u0433\u043E\u0432\u0441\u0442\u0440\u043E\u043A\u0441\u0432\u043E\u0434\u043D\u043E\u0439\u0442\u0430\u0431\u043B\u0438\u0446\u044B \u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0442\u0435\u043A\u0441\u0442\u0430\u043E\u0442\u043D\u043E\u0441\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u043A\u0438\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 '\n + '\u0441\u043F\u043E\u0441\u043E\u0431\u0447\u0442\u0435\u043D\u0438\u044F\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u0434\u0432\u0443\u0441\u0442\u043E\u0440\u043E\u043D\u043D\u0435\u0439\u043F\u0435\u0447\u0430\u0442\u0438 \u0442\u0438\u043F\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F\u043E\u0431\u043B\u0430\u0441\u0442\u0438\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 '\n + '\u0442\u0438\u043F\u043A\u0443\u0440\u0441\u043E\u0440\u043E\u0432\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u043B\u0438\u043D\u0438\u0438\u0440\u0438\u0441\u0443\u043D\u043A\u0430\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u043B\u0438\u043D\u0438\u0438\u044F\u0447\u0435\u0439\u043A\u0438\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 '\n + '\u0442\u0438\u043F\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043F\u0435\u0440\u0435\u0445\u043E\u0434\u0430\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u0432\u044B\u0434\u0435\u043B\u0435\u043D\u0438\u044F\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u043B\u0438\u043D\u0438\u0439\u0441\u0432\u043E\u0434\u043D\u043E\u0439\u0442\u0430\u0431\u043B\u0438\u0446\u044B '\n + '\u0442\u0438\u043F\u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F\u0442\u0435\u043A\u0441\u0442\u0430\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u0440\u0438\u0441\u0443\u043D\u043A\u0430\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u0441\u043C\u0435\u0449\u0435\u043D\u0438\u044F\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 '\n + '\u0442\u0438\u043F\u0443\u0437\u043E\u0440\u0430\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u0444\u0430\u0439\u043B\u0430\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u043E\u0447\u043D\u043E\u0441\u0442\u044C\u043F\u0435\u0447\u0430\u0442\u0438 \u0447\u0435\u0440\u0435\u0434\u043E\u0432\u0430\u043D\u0438\u0435\u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u044F\u0441\u0442\u0440\u0430\u043D\u0438\u0446 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u043F\u043B\u0430\u043D\u0438\u0440\u043E\u0432\u0449\u0438\u043A ==> class\n const v8_system_enums_sheduler =\n '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u0432\u0440\u0435\u043C\u0435\u043D\u0438\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\u043F\u043B\u0430\u043D\u0438\u0440\u043E\u0432\u0449\u0438\u043A\u0430 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 ==> class\n const v8_system_enums_formatted_document =\n '\u0442\u0438\u043F\u0444\u0430\u0439\u043B\u0430\u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E\u0433\u043E\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0437\u0430\u043F\u0440\u043E\u0441 ==> class\n const v8_system_enums_query =\n '\u043E\u0431\u0445\u043E\u0434\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u0442\u0438\u043F\u0437\u0430\u043F\u0438\u0441\u0438\u0437\u0430\u043F\u0440\u043E\u0441\u0430 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044C \u043E\u0442\u0447\u0435\u0442\u0430 ==> class\n const v8_system_enums_report_builder =\n '\u0432\u0438\u0434\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F\u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0438\u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044F\u043E\u0442\u0447\u0435\u0442\u0430 \u0442\u0438\u043F\u0434\u043E\u0431\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0439 \u0442\u0438\u043F\u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u044F\u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044F\u043E\u0442\u0447\u0435\u0442\u0430 \u0442\u0438\u043F\u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F\u0438\u0442\u043E\u0433\u043E\u0432 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0440\u0430\u0431\u043E\u0442\u0430 \u0441 \u0444\u0430\u0439\u043B\u0430\u043C\u0438 ==> class\n const v8_system_enums_files =\n '\u0434\u043E\u0441\u0442\u0443\u043F\u043A\u0444\u0430\u0439\u043B\u0443 \u0440\u0435\u0436\u0438\u043C\u0434\u0438\u0430\u043B\u043E\u0433\u0430\u0432\u044B\u0431\u043E\u0440\u0430\u0444\u0430\u0439\u043B\u0430 \u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043A\u0440\u044B\u0442\u0438\u044F\u0444\u0430\u0439\u043B\u0430 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044C \u0437\u0430\u043F\u0440\u043E\u0441\u0430 ==> class\n const v8_system_enums_query_builder =\n '\u0442\u0438\u043F\u0438\u0437\u043C\u0435\u0440\u0435\u043D\u0438\u044F\u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044F\u0437\u0430\u043F\u0440\u043E\u0441\u0430 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0430\u043D\u0430\u043B\u0438\u0437 \u0434\u0430\u043D\u043D\u044B\u0445 ==> class\n const v8_system_enums_data_analysis =\n '\u0432\u0438\u0434\u0434\u0430\u043D\u043D\u044B\u0445\u0430\u043D\u0430\u043B\u0438\u0437\u0430 \u043C\u0435\u0442\u043E\u0434\u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u0438 \u0442\u0438\u043F\u0435\u0434\u0438\u043D\u0438\u0446\u044B\u0438\u043D\u0442\u0435\u0440\u0432\u0430\u043B\u0430\u0432\u0440\u0435\u043C\u0435\u043D\u0438\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F\u0442\u0430\u0431\u043B\u0438\u0446\u044B\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0442\u0438\u043F\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0447\u0438\u0441\u043B\u043E\u0432\u044B\u0445\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u043F\u043E\u0438\u0441\u043A\u0430\u0430\u0441\u0441\u043E\u0446\u0438\u0430\u0446\u0438\u0439 \u0442\u0438\u043F\u043A\u043E\u043B\u043E\u043D\u043A\u0438\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u0434\u0435\u0440\u0435\u0432\u043E\u0440\u0435\u0448\u0435\u043D\u0438\u0439 '\n + '\u0442\u0438\u043F\u043A\u043E\u043B\u043E\u043D\u043A\u0438\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u043A\u043B\u0430\u0441\u0442\u0435\u0440\u0438\u0437\u0430\u0446\u0438\u044F \u0442\u0438\u043F\u043A\u043E\u043B\u043E\u043D\u043A\u0438\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u043E\u0431\u0449\u0430\u044F\u0441\u0442\u0430\u0442\u0438\u0441\u0442\u0438\u043A\u0430 \u0442\u0438\u043F\u043A\u043E\u043B\u043E\u043D\u043A\u0438\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u043F\u043E\u0438\u0441\u043A\u0430\u0441\u0441\u043E\u0446\u0438\u0430\u0446\u0438\u0439 '\n + '\u0442\u0438\u043F\u043A\u043E\u043B\u043E\u043D\u043A\u0438\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u043F\u043E\u0438\u0441\u043A\u043F\u043E\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0435\u0439 \u0442\u0438\u043F\u043A\u043E\u043B\u043E\u043D\u043A\u0438\u043C\u043E\u0434\u0435\u043B\u0438\u043F\u0440\u043E\u0433\u043D\u043E\u0437\u0430 \u0442\u0438\u043F\u043C\u0435\u0440\u044B\u0440\u0430\u0441\u0441\u0442\u043E\u044F\u043D\u0438\u044F\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0442\u0438\u043F\u043E\u0442\u0441\u0435\u0447\u0435\u043D\u0438\u044F\u043F\u0440\u0430\u0432\u0438\u043B\u0430\u0441\u0441\u043E\u0446\u0438\u0430\u0446\u0438\u0438 \u0442\u0438\u043F\u043F\u043E\u043B\u044F\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u0438\u0437\u0430\u0446\u0438\u0438\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0443\u043F\u043E\u0440\u044F\u0434\u043E\u0447\u0438\u0432\u0430\u043D\u0438\u044F\u043F\u0440\u0430\u0432\u0438\u043B\u0430\u0441\u0441\u043E\u0446\u0438\u0430\u0446\u0438\u0438\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0442\u0438\u043F\u0443\u043F\u043E\u0440\u044F\u0434\u043E\u0447\u0438\u0432\u0430\u043D\u0438\u044F\u0448\u0430\u0431\u043B\u043E\u043D\u043E\u0432\u043F\u043E\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0435\u0439\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0443\u043F\u0440\u043E\u0449\u0435\u043D\u0438\u044F\u0434\u0435\u0440\u0435\u0432\u0430\u0440\u0435\u0448\u0435\u043D\u0438\u0439 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - xml, json, xs, dom, xdto, web-\u0441\u0435\u0440\u0432\u0438\u0441\u044B ==> class\n const v8_system_enums_xml_json_xs_dom_xdto_ws =\n 'ws\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430 \u0432\u0430\u0440\u0438\u0430\u043D\u0442xpathxs \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0437\u0430\u043F\u0438\u0441\u0438\u0434\u0430\u0442\u044Bjson \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043F\u0440\u043E\u0441\u0442\u043E\u0433\u043E\u0442\u0438\u043F\u0430xs \u0432\u0438\u0434\u0433\u0440\u0443\u043F\u043F\u044B\u043C\u043E\u0434\u0435\u043B\u0438xs \u0432\u0438\u0434\u0444\u0430\u0441\u0435\u0442\u0430xdto '\n + '\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044Fdom \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u043D\u043E\u0441\u0442\u044C\u043F\u0440\u043E\u0441\u0442\u043E\u0433\u043E\u0442\u0438\u043F\u0430xs \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u043D\u043E\u0441\u0442\u044C\u0441\u043E\u0441\u0442\u0430\u0432\u043D\u043E\u0433\u043E\u0442\u0438\u043F\u0430xs \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043D\u043D\u043E\u0441\u0442\u044C\u0441\u0445\u0435\u043C\u044Bxs \u0437\u0430\u043F\u0440\u0435\u0449\u0435\u043D\u043D\u044B\u0435\u043F\u043E\u0434\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438xs '\n + '\u0438\u0441\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F\u0433\u0440\u0443\u043F\u043F\u043F\u043E\u0434\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438xs \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430xs \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F\u043E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D\u0438\u044F\u0438\u0434\u0435\u043D\u0442\u0438\u0447\u043D\u043E\u0441\u0442\u0438xs \u043A\u0430\u0442\u0435\u0433\u043E\u0440\u0438\u044F\u043E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D\u0438\u044F\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0441\u0442\u0432\u0438\u043C\u0435\u043Dxs '\n + '\u043C\u0435\u0442\u043E\u0434\u043D\u0430\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u043D\u0438\u044Fxs \u043C\u043E\u0434\u0435\u043B\u044C\u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043Exs \u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0442\u0438\u043F\u0430xml \u043D\u0435\u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0435\u043F\u043E\u0434\u0441\u0442\u0430\u043D\u043E\u0432\u043A\u0438xs \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430\u043F\u0440\u043E\u0431\u0435\u043B\u044C\u043D\u044B\u0445\u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432xs \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430\u0441\u043E\u0434\u0435\u0440\u0436\u0438\u043C\u043E\u0433\u043Exs '\n + '\u043E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D\u0438\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044Fxs \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B\u043E\u0442\u0431\u043E\u0440\u0430\u0443\u0437\u043B\u043E\u0432dom \u043F\u0435\u0440\u0435\u043D\u043E\u0441\u0441\u0442\u0440\u043E\u043Ajson \u043F\u043E\u0437\u0438\u0446\u0438\u044F\u0432\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0435dom \u043F\u0440\u043E\u0431\u0435\u043B\u044C\u043D\u044B\u0435\u0441\u0438\u043C\u0432\u043E\u043B\u044Bxml \u0442\u0438\u043F\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430xml \u0442\u0438\u043F\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044Fjson '\n + '\u0442\u0438\u043F\u043A\u0430\u043D\u043E\u043D\u0438\u0447\u0435\u0441\u043A\u043E\u0433\u043Exml \u0442\u0438\u043F\u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u044Bxs \u0442\u0438\u043F\u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438xml \u0442\u0438\u043F\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430domxpath \u0442\u0438\u043F\u0443\u0437\u043B\u0430dom \u0442\u0438\u043F\u0443\u0437\u043B\u0430xml \u0444\u043E\u0440\u043C\u0430xml \u0444\u043E\u0440\u043C\u0430\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u044Fxs '\n + '\u0444\u043E\u0440\u043C\u0430\u0442\u0434\u0430\u0442\u044Bjson \u044D\u043A\u0440\u0430\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432json ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0441\u0438\u0441\u0442\u0435\u043C\u0430 \u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438 \u0434\u0430\u043D\u043D\u044B\u0445 ==> class\n const v8_system_enums_data_composition_system =\n '\u0432\u0438\u0434\u0441\u0440\u0430\u0432\u043D\u0435\u043D\u0438\u044F\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438\u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0432\u043B\u043E\u0436\u0435\u043D\u043D\u044B\u0445\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0438\u0442\u043E\u0433\u043E\u0432\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043F\u043E\u043B\u0435\u0439\u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043F\u043E\u043B\u044F\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u043E\u0432\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0440\u0435\u0441\u0443\u0440\u0441\u043E\u0432\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0431\u0443\u0445\u0433\u0430\u043B\u0442\u0435\u0440\u0441\u043A\u043E\u0433\u043E\u043E\u0441\u0442\u0430\u0442\u043A\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0432\u044B\u0432\u043E\u0434\u0430\u0442\u0435\u043A\u0441\u0442\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0442\u0438\u043F\u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0433\u0440\u0443\u043F\u043F\u044B\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u043E\u0432\u043E\u0442\u0431\u043E\u0440\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0434\u043E\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F\u043F\u0435\u0440\u0438\u043E\u0434\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0442\u0438\u043F\u0437\u0430\u0433\u043E\u043B\u043E\u0432\u043A\u0430\u043F\u043E\u043B\u0435\u0439\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u043C\u0430\u043A\u0435\u0442\u0430\u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u043C\u0430\u043A\u0435\u0442\u0430\u043E\u0431\u043B\u0430\u0441\u0442\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u043E\u0441\u0442\u0430\u0442\u043A\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0442\u0438\u043F\u043F\u0435\u0440\u0438\u043E\u0434\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0440\u0430\u0437\u043C\u0435\u0449\u0435\u043D\u0438\u044F\u0442\u0435\u043A\u0441\u0442\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u0441\u0432\u044F\u0437\u0438\u043D\u0430\u0431\u043E\u0440\u043E\u0432\u0434\u0430\u043D\u043D\u044B\u0445\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u043B\u0435\u0433\u0435\u043D\u0434\u044B\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u044B\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u043F\u0440\u0438\u043C\u0435\u043D\u0435\u043D\u0438\u044F\u043E\u0442\u0431\u043E\u0440\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u043F\u043E\u0441\u043E\u0431\u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0440\u0435\u0436\u0438\u043C\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0430\u0432\u0442\u043E\u043F\u043E\u0437\u0438\u0446\u0438\u044F\u0440\u0435\u0441\u0443\u0440\u0441\u043E\u0432\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0433\u0440\u0443\u043F\u043F\u0438\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0440\u0435\u0441\u0443\u0440\u0441\u043E\u0432\u0432\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u0435\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0444\u0438\u043A\u0441\u0430\u0446\u0438\u044F\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0443\u0441\u043B\u043E\u0432\u043D\u043E\u0433\u043E\u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u044F\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u043F\u043E\u0447\u0442\u0430 ==> class\n const v8_system_enums_email =\n '\u0432\u0430\u0436\u043D\u043E\u0441\u0442\u044C\u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u043E\u0447\u0442\u043E\u0432\u043E\u0433\u043E\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430\u0442\u0435\u043A\u0441\u0442\u0430\u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u043E\u0447\u0442\u043E\u0432\u043E\u0433\u043E\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0441\u043F\u043E\u0441\u043E\u0431\u043A\u043E\u0434\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u043E\u0447\u0442\u043E\u0432\u043E\u0433\u043E\u0432\u043B\u043E\u0436\u0435\u043D\u0438\u044F '\n + '\u0441\u043F\u043E\u0441\u043E\u0431\u043A\u043E\u0434\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\u043D\u0435ascii\u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432\u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u043E\u0447\u0442\u043E\u0432\u043E\u0433\u043E\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0442\u0438\u043F\u0442\u0435\u043A\u0441\u0442\u0430\u043F\u043E\u0447\u0442\u043E\u0432\u043E\u0433\u043E\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u043F\u0440\u043E\u0442\u043E\u043A\u043E\u043B\u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u043E\u0447\u0442\u044B '\n + '\u0441\u0442\u0430\u0442\u0443\u0441\u0440\u0430\u0437\u0431\u043E\u0440\u0430\u043F\u043E\u0447\u0442\u043E\u0432\u043E\u0433\u043E\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0436\u0443\u0440\u043D\u0430\u043B \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 ==> class\n const v8_system_enums_logbook =\n '\u0440\u0435\u0436\u0438\u043C\u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0438\u0437\u0430\u043F\u0438\u0441\u0438\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0438\u0437\u0430\u043F\u0438\u0441\u0438\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0443\u0440\u043E\u0432\u0435\u043D\u044C\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u044F ==> class\n const v8_system_enums_cryptography =\n '\u0440\u0430\u0441\u043F\u043E\u043B\u043E\u0436\u0435\u043D\u0438\u0435\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0432\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0438 \u0440\u0435\u0436\u0438\u043C\u0432\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u044F\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0432\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0438 \u0440\u0435\u0436\u0438\u043C\u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0438\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u0430\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0438 '\n + '\u0442\u0438\u043F\u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0430\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0432\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0438 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - ZIP ==> class\n const v8_system_enums_zip =\n '\u043A\u043E\u0434\u0438\u0440\u043E\u0432\u043A\u0430\u0438\u043C\u0435\u043D\u0444\u0430\u0439\u043B\u043E\u0432\u0432zip\u0444\u0430\u0439\u043B\u0435 \u043C\u0435\u0442\u043E\u0434\u0441\u0436\u0430\u0442\u0438\u044Fzip \u043C\u0435\u0442\u043E\u0434\u0448\u0438\u0444\u0440\u043E\u0432\u0430\u043D\u0438\u044Fzip \u0440\u0435\u0436\u0438\u043C\u0432\u043E\u0441\u0441\u0442\u0430\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F\u043F\u0443\u0442\u0435\u0439\u0444\u0430\u0439\u043B\u043E\u0432zip \u0440\u0435\u0436\u0438\u043C\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438\u043F\u043E\u0434\u043A\u0430\u0442\u0430\u043B\u043E\u0433\u043E\u0432zip '\n + '\u0440\u0435\u0436\u0438\u043C\u0441\u043E\u0445\u0440\u0430\u043D\u0435\u043D\u0438\u044F\u043F\u0443\u0442\u0435\u0439zip \u0443\u0440\u043E\u0432\u0435\u043D\u044C\u0441\u0436\u0430\u0442\u0438\u044Fzip ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F -\n // \u0411\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430 \u0434\u0430\u043D\u043D\u044B\u0445, \u0424\u043E\u043D\u043E\u0432\u044B\u0435 \u0437\u0430\u0434\u0430\u043D\u0438\u044F, \u0410\u0432\u0442\u043E\u043C\u0430\u0442\u0438\u0437\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E\u0435 \u0442\u0435\u0441\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435,\n // \u0414\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u043C\u044B\u0435 \u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u044F, \u0412\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u043F\u043E\u043A\u0443\u043F\u043A\u0438, \u0418\u043D\u0442\u0435\u0440\u043D\u0435\u0442, \u0420\u0430\u0431\u043E\u0442\u0430 \u0441 \u0434\u0432\u043E\u0438\u0447\u043D\u044B\u043C\u0438 \u0434\u0430\u043D\u043D\u044B\u043C\u0438 ==> class\n const v8_system_enums_other =\n '\u0437\u0432\u0443\u043A\u043E\u0432\u043E\u0435\u043E\u043F\u043E\u0432\u0435\u0449\u0435\u043D\u0438\u0435 \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0435\u0440\u0435\u0445\u043E\u0434\u0430\u043A\u0441\u0442\u0440\u043E\u043A\u0435 \u043F\u043E\u0437\u0438\u0446\u0438\u044F\u0432\u043F\u043E\u0442\u043E\u043A\u0435 \u043F\u043E\u0440\u044F\u0434\u043E\u043A\u0431\u0430\u0439\u0442\u043E\u0432 \u0440\u0435\u0436\u0438\u043C\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0440\u0435\u0436\u0438\u043C\u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u043E\u0439\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0441\u0435\u0440\u0432\u0438\u0441\u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0445\u043F\u043E\u043A\u0443\u043F\u043E\u043A \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\u0444\u043E\u043D\u043E\u0432\u043E\u0433\u043E\u0437\u0430\u0434\u0430\u043D\u0438\u044F \u0442\u0438\u043F\u043F\u043E\u0434\u043F\u0438\u0441\u0447\u0438\u043A\u0430\u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u043C\u044B\u0445\u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0439 \u0443\u0440\u043E\u0432\u0435\u043D\u044C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0437\u0430\u0449\u0438\u0449\u0435\u043D\u043D\u043E\u0433\u043E\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044Fftp ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0441\u0445\u0435\u043C\u0430 \u0437\u0430\u043F\u0440\u043E\u0441\u0430 ==> class\n const v8_system_enums_request_schema =\n '\u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u043E\u0440\u044F\u0434\u043A\u0430\u0441\u0445\u0435\u043C\u044B\u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u0442\u0438\u043F\u0434\u043E\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F\u043F\u0435\u0440\u0438\u043E\u0434\u0430\u043C\u0438\u0441\u0445\u0435\u043C\u044B\u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u0442\u0438\u043F\u043A\u043E\u043D\u0442\u0440\u043E\u043B\u044C\u043D\u043E\u0439\u0442\u043E\u0447\u043A\u0438\u0441\u0445\u0435\u043C\u044B\u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u0442\u0438\u043F\u043E\u0431\u044A\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\u0441\u0445\u0435\u043C\u044B\u0437\u0430\u043F\u0440\u043E\u0441\u0430 '\n + '\u0442\u0438\u043F\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u043E\u0439\u0442\u0430\u0431\u043B\u0438\u0446\u044B\u0441\u0445\u0435\u043C\u044B\u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u0442\u0438\u043F\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F\u0441\u0445\u0435\u043C\u044B\u0437\u0430\u043F\u0440\u043E\u0441\u0430 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0441\u0432\u043E\u0439\u0441\u0442\u0432\u0430 \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 \u043C\u0435\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0445 ==> class\n const v8_system_enums_properties_of_metadata_objects =\n 'http\u043C\u0435\u0442\u043E\u0434 \u0430\u0432\u0442\u043E\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043E\u0431\u0449\u0435\u0433\u043E\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u0430 \u0430\u0432\u0442\u043E\u043F\u0440\u0435\u0444\u0438\u043A\u0441\u043D\u043E\u043C\u0435\u0440\u0430\u0437\u0430\u0434\u0430\u0447\u0438 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u043E\u0433\u043E\u044F\u0437\u044B\u043A\u0430 \u0432\u0438\u0434\u0438\u0435\u0440\u0430\u0440\u0445\u0438\u0438 \u0432\u0438\u0434\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u043D\u0430\u043A\u043E\u043F\u043B\u0435\u043D\u0438\u044F '\n + '\u0432\u0438\u0434\u0442\u0430\u0431\u043B\u0438\u0446\u044B\u0432\u043D\u0435\u0448\u043D\u0435\u0433\u043E\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0437\u0430\u043F\u0438\u0441\u044C\u0434\u0432\u0438\u0436\u0435\u043D\u0438\u0439\u043F\u0440\u0438\u043F\u0440\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0438 \u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0435\u043F\u043E\u0441\u043B\u0435\u0434\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u0435\u0439 \u0438\u043D\u0434\u0435\u043A\u0441\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435 '\n + '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0431\u0430\u0437\u044B\u043F\u043B\u0430\u043D\u0430\u0432\u0438\u0434\u043E\u0432\u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0431\u044B\u0441\u0442\u0440\u043E\u0433\u043E\u0432\u044B\u0431\u043E\u0440\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043E\u0431\u0449\u0435\u0433\u043E\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043F\u043E\u0434\u0447\u0438\u043D\u0435\u043D\u0438\u044F '\n + '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043F\u043E\u043B\u043D\u043E\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E\u043F\u043E\u0438\u0441\u043A\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0440\u0430\u0437\u0434\u0435\u043B\u044F\u0435\u043C\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445\u043E\u0431\u0449\u0435\u0433\u043E\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u0430 \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u0430 '\n + '\u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u043D\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0435\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043E\u043F\u0435\u0440\u0430\u0442\u0438\u0432\u043D\u043E\u0435\u043F\u0440\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0435 \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0435\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0432\u0438\u0434\u0430\u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0435\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0432\u0438\u0434\u0430\u0445\u0430\u0440\u0430\u043A\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043A\u0438 \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0435\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0437\u0430\u0434\u0430\u0447\u0438 '\n + '\u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0435\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u043B\u0430\u043D\u0430\u043E\u0431\u043C\u0435\u043D\u0430 \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0435\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0430 \u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0435\u043F\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0441\u0447\u0435\u0442\u0430 \u043F\u0435\u0440\u0435\u043C\u0435\u0449\u0435\u043D\u0438\u0435\u0433\u0440\u0430\u043D\u0438\u0446\u044B\u043F\u0440\u0438\u043F\u0440\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0438 '\n + '\u043F\u0435\u0440\u0438\u043E\u0434\u0438\u0447\u043D\u043E\u0441\u0442\u044C\u043D\u043E\u043C\u0435\u0440\u0430\u0431\u0438\u0437\u043D\u0435\u0441\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 \u043F\u0435\u0440\u0438\u043E\u0434\u0438\u0447\u043D\u043E\u0441\u0442\u044C\u043D\u043E\u043C\u0435\u0440\u0430\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u043F\u0435\u0440\u0438\u043E\u0434\u0438\u0447\u043D\u043E\u0441\u0442\u044C\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u043F\u0435\u0440\u0438\u043E\u0434\u0438\u0447\u043D\u043E\u0441\u0442\u044C\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0441\u0432\u0435\u0434\u0435\u043D\u0438\u0439 '\n + '\u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0432\u043E\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043C\u044B\u0445\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u043F\u043E\u043B\u043D\u043E\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0439\u043F\u043E\u0438\u0441\u043A\u043F\u0440\u0438\u0432\u0432\u043E\u0434\u0435\u043F\u043E\u0441\u0442\u0440\u043E\u043A\u0435 \u043F\u0440\u0438\u043D\u0430\u0434\u043B\u0435\u0436\u043D\u043E\u0441\u0442\u044C\u043E\u0431\u044A\u0435\u043A\u0442\u0430 \u043F\u0440\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u0435 '\n + '\u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u0430\u0443\u0442\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0446\u0438\u0438\u043E\u0431\u0449\u0435\u0433\u043E\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u0430 \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u0434\u0430\u043D\u043D\u044B\u0445\u043E\u0431\u0449\u0435\u0433\u043E\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u0430 \u0440\u0430\u0437\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0439\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438\u043E\u0431\u0449\u0435\u0433\u043E\u0440\u0435\u043A\u0432\u0438\u0437\u0438\u0442\u0430 '\n + '\u0440\u0435\u0436\u0438\u043C\u0430\u0432\u0442\u043E\u043D\u0443\u043C\u0435\u0440\u0430\u0446\u0438\u0438\u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 \u0440\u0435\u0436\u0438\u043C\u0437\u0430\u043F\u0438\u0441\u0438\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430 \u0440\u0435\u0436\u0438\u043C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u043C\u043E\u0434\u0430\u043B\u044C\u043D\u043E\u0441\u0442\u0438 '\n + '\u0440\u0435\u0436\u0438\u043C\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0441\u0438\u043D\u0445\u0440\u043E\u043D\u043D\u044B\u0445\u0432\u044B\u0437\u043E\u0432\u043E\u0432\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0439\u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u044B\u0438\u0432\u043D\u0435\u0448\u043D\u0438\u0445\u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442 \u0440\u0435\u0436\u0438\u043C\u043F\u043E\u0432\u0442\u043E\u0440\u043D\u043E\u0433\u043E\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0441\u0435\u0430\u043D\u0441\u043E\u0432 '\n + '\u0440\u0435\u0436\u0438\u043C\u043F\u043E\u043B\u0443\u0447\u0435\u043D\u0438\u044F\u0434\u0430\u043D\u043D\u044B\u0445\u0432\u044B\u0431\u043E\u0440\u0430\u043F\u0440\u0438\u0432\u0432\u043E\u0434\u0435\u043F\u043E\u0441\u0442\u0440\u043E\u043A\u0435 \u0440\u0435\u0436\u0438\u043C\u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0441\u0442\u0438 \u0440\u0435\u0436\u0438\u043C\u0441\u043E\u0432\u043C\u0435\u0441\u0442\u0438\u043C\u043E\u0441\u0442\u0438\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 '\n + '\u0440\u0435\u0436\u0438\u043C\u0443\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u044F\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u043E\u0439\u0434\u0430\u043D\u043D\u044B\u0445\u043F\u043E\u0443\u043C\u043E\u043B\u0447\u0430\u043D\u0438\u044E \u0441\u0435\u0440\u0438\u0438\u043A\u043E\u0434\u043E\u0432\u043F\u043B\u0430\u043D\u0430\u0432\u0438\u0434\u043E\u0432\u0445\u0430\u0440\u0430\u043A\u0442\u0435\u0440\u0438\u0441\u0442\u0438\u043A \u0441\u0435\u0440\u0438\u0438\u043A\u043E\u0434\u043E\u0432\u043F\u043B\u0430\u043D\u0430\u0441\u0447\u0435\u0442\u043E\u0432 '\n + '\u0441\u0435\u0440\u0438\u0438\u043A\u043E\u0434\u043E\u0432\u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0430 \u0441\u043E\u0437\u0434\u0430\u043D\u0438\u0435\u043F\u0440\u0438\u0432\u0432\u043E\u0434\u0435 \u0441\u043F\u043E\u0441\u043E\u0431\u0432\u044B\u0431\u043E\u0440\u0430 \u0441\u043F\u043E\u0441\u043E\u0431\u043F\u043E\u0438\u0441\u043A\u0430\u0441\u0442\u0440\u043E\u043A\u0438\u043F\u0440\u0438\u0432\u0432\u043E\u0434\u0435\u043F\u043E\u0441\u0442\u0440\u043E\u043A\u0435 \u0441\u043F\u043E\u0441\u043E\u0431\u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F '\n + '\u0442\u0438\u043F\u0434\u0430\u043D\u043D\u044B\u0445\u0442\u0430\u0431\u043B\u0438\u0446\u044B\u0432\u043D\u0435\u0448\u043D\u0435\u0433\u043E\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0438\u043F\u043A\u043E\u0434\u0430\u043F\u043B\u0430\u043D\u0430\u0432\u0438\u0434\u043E\u0432\u0440\u0430\u0441\u0447\u0435\u0442\u0430 \u0442\u0438\u043F\u043A\u043E\u0434\u0430\u0441\u043F\u0440\u0430\u0432\u043E\u0447\u043D\u0438\u043A\u0430 \u0442\u0438\u043F\u043C\u0430\u043A\u0435\u0442\u0430 \u0442\u0438\u043F\u043D\u043E\u043C\u0435\u0440\u0430\u0431\u0438\u0437\u043D\u0435\u0441\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u0430 '\n + '\u0442\u0438\u043F\u043D\u043E\u043C\u0435\u0440\u0430\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430 \u0442\u0438\u043F\u043D\u043E\u043C\u0435\u0440\u0430\u0437\u0430\u0434\u0430\u0447\u0438 \u0442\u0438\u043F\u0444\u043E\u0440\u043C\u044B \u0443\u0434\u0430\u043B\u0435\u043D\u0438\u0435\u0434\u0432\u0438\u0436\u0435\u043D\u0438\u0439 ';\n\n // v8 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F - \u0440\u0430\u0437\u043D\u044B\u0435 ==> class\n const v8_system_enums_differents =\n '\u0432\u0430\u0436\u043D\u043E\u0441\u0442\u044C\u043F\u0440\u043E\u0431\u043B\u0435\u043C\u044B\u043F\u0440\u0438\u043C\u0435\u043D\u0435\u043D\u0438\u044F\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u044F\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0438\u043D\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043C\u0430\u0441\u0448\u0442\u0430\u0431\u0430\u0444\u043E\u0440\u043C\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F '\n + '\u0432\u0430\u0440\u0438\u0430\u043D\u0442\u043E\u0441\u043D\u043E\u0432\u043D\u043E\u0433\u043E\u0448\u0440\u0438\u0444\u0442\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0433\u043E\u043F\u0435\u0440\u0438\u043E\u0434\u0430 \u0432\u0430\u0440\u0438\u0430\u043D\u0442\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0439\u0434\u0430\u0442\u044B\u043D\u0430\u0447\u0430\u043B\u0430 \u0432\u0438\u0434\u0433\u0440\u0430\u043D\u0438\u0446\u044B \u0432\u0438\u0434\u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0438 '\n + '\u0432\u0438\u0434\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u044F\u043F\u043E\u043B\u043D\u043E\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E\u043F\u043E\u0438\u0441\u043A\u0430 \u0432\u0438\u0434\u0440\u0430\u043C\u043A\u0438 \u0432\u0438\u0434\u0441\u0440\u0430\u0432\u043D\u0435\u043D\u0438\u044F \u0432\u0438\u0434\u0446\u0432\u0435\u0442\u0430 \u0432\u0438\u0434\u0447\u0438\u0441\u043B\u043E\u0432\u043E\u0433\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u0432\u0438\u0434\u0448\u0440\u0438\u0444\u0442\u0430 \u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u0430\u044F\u0434\u043B\u0438\u043D\u0430 \u0434\u043E\u043F\u0443\u0441\u0442\u0438\u043C\u044B\u0439\u0437\u043D\u0430\u043A '\n + '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435byteordermark \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043C\u0435\u0442\u0430\u0434\u0430\u043D\u043D\u044B\u0445\u043F\u043E\u043B\u043D\u043E\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E\u043F\u043E\u0438\u0441\u043A\u0430 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u0438\u0439\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438 \u043A\u043B\u0430\u0432\u0438\u0448\u0430 \u043A\u043E\u0434\u0432\u043E\u0437\u0432\u0440\u0430\u0442\u0430\u0434\u0438\u0430\u043B\u043E\u0433\u0430 '\n + '\u043A\u043E\u0434\u0438\u0440\u043E\u0432\u043A\u0430xbase \u043A\u043E\u0434\u0438\u0440\u043E\u0432\u043A\u0430\u0442\u0435\u043A\u0441\u0442\u0430 \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u043E\u0438\u0441\u043A\u0430 \u043D\u0430\u043F\u0440\u0430\u0432\u043B\u0435\u043D\u0438\u0435\u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0440\u0435\u0434\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043D\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445 \u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u0435\u043F\u0440\u0438\u0438\u0437\u043C\u0435\u043D\u0435\u043D\u0438\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043F\u0430\u043D\u0435\u043B\u0438\u0440\u0430\u0437\u0434\u0435\u043B\u043E\u0432 \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430\u0437\u0430\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u044F \u0440\u0435\u0436\u0438\u043C\u0434\u0438\u0430\u043B\u043E\u0433\u0430\u0432\u043E\u043F\u0440\u043E\u0441 \u0440\u0435\u0436\u0438\u043C\u0437\u0430\u043F\u0443\u0441\u043A\u0430\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F \u0440\u0435\u0436\u0438\u043C\u043E\u043A\u0440\u0443\u0433\u043B\u0435\u043D\u0438\u044F \u0440\u0435\u0436\u0438\u043C\u043E\u0442\u043A\u0440\u044B\u0442\u0438\u044F\u0444\u043E\u0440\u043C\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044F '\n + '\u0440\u0435\u0436\u0438\u043C\u043F\u043E\u043B\u043D\u043E\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u043E\u0433\u043E\u043F\u043E\u0438\u0441\u043A\u0430 \u0441\u043A\u043E\u0440\u043E\u0441\u0442\u044C\u043A\u043B\u0438\u0435\u043D\u0442\u0441\u043A\u043E\u0433\u043E\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u044F \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\u0432\u043D\u0435\u0448\u043D\u0435\u0433\u043E\u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u043E\u0441\u0442\u043E\u044F\u043D\u0438\u0435\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438\u0431\u0430\u0437\u044B\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0441\u043F\u043E\u0441\u043E\u0431\u0432\u044B\u0431\u043E\u0440\u0430\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u0430windows \u0441\u043F\u043E\u0441\u043E\u0431\u043A\u043E\u0434\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\u0441\u0442\u0440\u043E\u043A\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u044F \u0442\u0438\u043F\u0432\u043D\u0435\u0448\u043D\u0435\u0439\u043A\u043E\u043C\u043F\u043E\u043D\u0435\u043D\u0442\u044B \u0442\u0438\u043F\u043F\u043B\u0430\u0442\u0444\u043E\u0440\u043C\u044B \u0442\u0438\u043F\u043F\u043E\u0432\u0435\u0434\u0435\u043D\u0438\u044F\u043A\u043B\u0430\u0432\u0438\u0448\u0438enter '\n + '\u0442\u0438\u043F\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u0438\u043E\u0432\u044B\u043F\u043E\u043B\u043D\u0435\u043D\u0438\u0438\u043E\u0431\u043D\u043E\u0432\u043B\u0435\u043D\u0438\u044F\u043A\u043E\u043D\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438\u0431\u0430\u0437\u044B\u0434\u0430\u043D\u043D\u044B\u0445 \u0443\u0440\u043E\u0432\u0435\u043D\u044C\u0438\u0437\u043E\u043B\u044F\u0446\u0438\u0438\u0442\u0440\u0430\u043D\u0437\u0430\u043A\u0446\u0438\u0439 \u0445\u0435\u0448\u0444\u0443\u043D\u043A\u0446\u0438\u044F \u0447\u0430\u0441\u0442\u0438\u0434\u0430\u0442\u044B';\n\n // class: \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u043D\u0430\u0431\u043E\u0440\u044B \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439, \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044F (\u0441\u043E\u0434\u0435\u0440\u0436\u0430\u0442 \u0434\u043E\u0447\u0435\u0440\u043D\u0438\u0435 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F, \u043E\u0431\u0440\u0430\u0449\u0435\u043D\u0438\u044F \u043A \u043A\u043E\u0442\u043E\u0440\u044B\u043C \u0447\u0435\u0440\u0435\u0437 \u0440\u0430\u0437\u044B\u043C\u0435\u043D\u043E\u0432\u0430\u043D\u0438\u0435)\n const CLASS =\n v8_system_sets_of_values\n + v8_system_enums_interface\n + v8_system_enums_objects_properties\n + v8_system_enums_exchange_plans\n + v8_system_enums_tabular_document\n + v8_system_enums_sheduler\n + v8_system_enums_formatted_document\n + v8_system_enums_query\n + v8_system_enums_report_builder\n + v8_system_enums_files\n + v8_system_enums_query_builder\n + v8_system_enums_data_analysis\n + v8_system_enums_xml_json_xs_dom_xdto_ws\n + v8_system_enums_data_composition_system\n + v8_system_enums_email\n + v8_system_enums_logbook\n + v8_system_enums_cryptography\n + v8_system_enums_zip\n + v8_system_enums_other\n + v8_system_enums_request_schema\n + v8_system_enums_properties_of_metadata_objects\n + v8_system_enums_differents;\n\n // v8 \u043E\u0431\u0449\u0438\u0435 \u043E\u0431\u044A\u0435\u043A\u0442\u044B (\u0443 \u043E\u0431\u044A\u0435\u043A\u0442\u043E\u0432 \u0435\u0441\u0442\u044C \u043A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u043E\u0440, \u044D\u043A\u0437\u0435\u043C\u043F\u043B\u044F\u0440\u044B \u0441\u043E\u0437\u0434\u0430\u044E\u0442\u0441\u044F \u043C\u0435\u0442\u043E\u0434\u043E\u043C \u041D\u041E\u0412\u042B\u0419) ==> type\n const v8_shared_object =\n 'com\u043E\u0431\u044A\u0435\u043A\u0442 ftp\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 http\u0437\u0430\u043F\u0440\u043E\u0441 http\u0441\u0435\u0440\u0432\u0438\u0441\u043E\u0442\u0432\u0435\u0442 http\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 ws\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u044F ws\u043F\u0440\u043E\u043A\u0441\u0438 xbase \u0430\u043D\u0430\u043B\u0438\u0437\u0434\u0430\u043D\u043D\u044B\u0445 \u0430\u043D\u043D\u043E\u0442\u0430\u0446\u0438\u044Fxs '\n + '\u0431\u043B\u043E\u043A\u0438\u0440\u043E\u0432\u043A\u0430\u0434\u0430\u043D\u043D\u044B\u0445 \u0431\u0443\u0444\u0435\u0440\u0434\u0432\u043E\u0438\u0447\u043D\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445 \u0432\u043A\u043B\u044E\u0447\u0435\u043D\u0438\u0435xs \u0432\u044B\u0440\u0430\u0436\u0435\u043D\u0438\u0435\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0433\u0435\u043D\u0435\u0440\u0430\u0442\u043E\u0440\u0441\u043B\u0443\u0447\u0430\u0439\u043D\u044B\u0445\u0447\u0438\u0441\u0435\u043B \u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u0430\u044F\u0441\u0445\u0435\u043C\u0430 '\n + '\u0433\u0435\u043E\u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u0438\u0435\u043A\u043E\u043E\u0440\u0434\u0438\u043D\u0430\u0442\u044B \u0433\u0440\u0430\u0444\u0438\u0447\u0435\u0441\u043A\u0430\u044F\u0441\u0445\u0435\u043C\u0430 \u0433\u0440\u0443\u043F\u043F\u0430\u043C\u043E\u0434\u0435\u043B\u0438xs \u0434\u0430\u043D\u043D\u044B\u0435\u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0434\u0432\u043E\u0438\u0447\u043D\u044B\u0435\u0434\u0430\u043D\u043D\u044B\u0435 \u0434\u0435\u043D\u0434\u0440\u043E\u0433\u0440\u0430\u043C\u043C\u0430 '\n + '\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u0430 \u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u0430\u0433\u0430\u043D\u0442\u0430 \u0434\u0438\u0430\u043B\u043E\u0433\u0432\u044B\u0431\u043E\u0440\u0430\u0444\u0430\u0439\u043B\u0430 \u0434\u0438\u0430\u043B\u043E\u0433\u0432\u044B\u0431\u043E\u0440\u0430\u0446\u0432\u0435\u0442\u0430 \u0434\u0438\u0430\u043B\u043E\u0433\u0432\u044B\u0431\u043E\u0440\u0430\u0448\u0440\u0438\u0444\u0442\u0430 \u0434\u0438\u0430\u043B\u043E\u0433\u0440\u0430\u0441\u043F\u0438\u0441\u0430\u043D\u0438\u044F\u0440\u0435\u0433\u043B\u0430\u043C\u0435\u043D\u0442\u043D\u043E\u0433\u043E\u0437\u0430\u0434\u0430\u043D\u0438\u044F '\n + '\u0434\u0438\u0430\u043B\u043E\u0433\u0440\u0435\u0434\u0430\u043A\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u044F\u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u043E\u0433\u043E\u043F\u0435\u0440\u0438\u043E\u0434\u0430 \u0434\u0438\u0430\u043F\u0430\u0437\u043E\u043D \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442dom \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442html \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044Fxs \u0434\u043E\u0441\u0442\u0430\u0432\u043B\u044F\u0435\u043C\u043E\u0435\u0443\u0432\u0435\u0434\u043E\u043C\u043B\u0435\u043D\u0438\u0435 '\n + '\u0437\u0430\u043F\u0438\u0441\u044Cdom \u0437\u0430\u043F\u0438\u0441\u044Cfastinfoset \u0437\u0430\u043F\u0438\u0441\u044Chtml \u0437\u0430\u043F\u0438\u0441\u044Cjson \u0437\u0430\u043F\u0438\u0441\u044Cxml \u0437\u0430\u043F\u0438\u0441\u044Czip\u0444\u0430\u0439\u043B\u0430 \u0437\u0430\u043F\u0438\u0441\u044C\u0434\u0430\u043D\u043D\u044B\u0445 \u0437\u0430\u043F\u0438\u0441\u044C\u0442\u0435\u043A\u0441\u0442\u0430 \u0437\u0430\u043F\u0438\u0441\u044C\u0443\u0437\u043B\u043E\u0432dom '\n + '\u0437\u0430\u043F\u0440\u043E\u0441 \u0437\u0430\u0449\u0438\u0449\u0435\u043D\u043D\u043E\u0435\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435openssl \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F\u043F\u043E\u043B\u0435\u0439\u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0438\u0437\u0432\u043B\u0435\u0447\u0435\u043D\u0438\u0435\u0442\u0435\u043A\u0441\u0442\u0430 \u0438\u043C\u043F\u043E\u0440\u0442xs \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u043E\u0447\u0442\u0430 '\n + '\u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u043E\u0447\u0442\u043E\u0432\u043E\u0435\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u043E\u0447\u0442\u043E\u0432\u044B\u0439\u043F\u0440\u043E\u0444\u0438\u043B\u044C \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u043F\u0440\u043E\u043A\u0441\u0438 \u0438\u043D\u0442\u0435\u0440\u043D\u0435\u0442\u0441\u043E\u0435\u0434\u0438\u043D\u0435\u043D\u0438\u0435 \u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F\u0434\u043B\u044F\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u044Fxs '\n + '\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430xs \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u0441\u043E\u0431\u044B\u0442\u0438\u044F\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A\u0434\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0445\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u0438\u0442\u0435\u0440\u0430\u0442\u043E\u0440\u0443\u0437\u043B\u043E\u0432dom \u043A\u0430\u0440\u0442\u0438\u043D\u043A\u0430 \u043A\u0432\u0430\u043B\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u044B\u0434\u0430\u0442\u044B \u043A\u0432\u0430\u043B\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u044B\u0434\u0432\u043E\u0438\u0447\u043D\u044B\u0445\u0434\u0430\u043D\u043D\u044B\u0445 \u043A\u0432\u0430\u043B\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u044B\u0441\u0442\u0440\u043E\u043A\u0438 \u043A\u0432\u0430\u043B\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440\u044B\u0447\u0438\u0441\u043B\u0430 '\n + '\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u0449\u0438\u043A\u043C\u0430\u043A\u0435\u0442\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u0449\u0438\u043A\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u043E\u0440\u043C\u0430\u043A\u0435\u0442\u0430\u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u044F\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u043E\u0440\u043D\u0430\u0441\u0442\u0440\u043E\u0435\u043A\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043A\u043E\u043D\u0441\u0442\u0440\u0443\u043A\u0442\u043E\u0440\u0444\u043E\u0440\u043C\u0430\u0442\u043D\u043E\u0439\u0441\u0442\u0440\u043E\u043A\u0438 \u043B\u0438\u043D\u0438\u044F \u043C\u0430\u043A\u0435\u0442\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043C\u0430\u043A\u0435\u0442\u043E\u0431\u043B\u0430\u0441\u0442\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043C\u0430\u043A\u0435\u0442\u043E\u0444\u043E\u0440\u043C\u043B\u0435\u043D\u0438\u044F\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043C\u0430\u0441\u043A\u0430xs \u043C\u0435\u043D\u0435\u0434\u0436\u0435\u0440\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0438 \u043D\u0430\u0431\u043E\u0440\u0441\u0445\u0435\u043Cxml \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043D\u0430\u0441\u0442\u0440\u043E\u0439\u043A\u0438\u0441\u0435\u0440\u0438\u0430\u043B\u0438\u0437\u0430\u0446\u0438\u0438json '\n + '\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430\u043A\u0430\u0440\u0442\u0438\u043D\u043E\u043A \u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0430\u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043E\u0431\u0445\u043E\u0434\u0434\u0435\u0440\u0435\u0432\u0430dom \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D\u0438\u0435\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430xs \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D\u0438\u0435\u043D\u043E\u0442\u0430\u0446\u0438\u0438xs '\n + '\u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D\u0438\u0435\u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0430xs \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0441\u043E\u0431\u044B\u0442\u0438\u044F\u0434\u043E\u0441\u0442\u0443\u043F\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 '\n + '\u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u0438\u0441\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u043D\u0438\u044F\u0441\u043E\u0431\u044B\u0442\u0438\u044F\u043E\u0442\u043A\u0430\u0437\u0432\u0434\u043E\u0441\u0442\u0443\u043F\u0435\u0436\u0443\u0440\u043D\u0430\u043B\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u043E\u0431\u0440\u0430\u0431\u043E\u0442\u043A\u0438\u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043E\u0432\u043A\u0438\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u043F\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043C\u043E\u0433\u043E\u0444\u0430\u0439\u043B\u0430 \u043E\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u0442\u0438\u043F\u043E\u0432 \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u0433\u0440\u0443\u043F\u043F\u044B\u0430\u0442\u0440\u0438\u0431\u0443\u0442\u043E\u0432xs \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u0433\u0440\u0443\u043F\u043F\u044B\u043C\u043E\u0434\u0435\u043B\u0438xs '\n + '\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u043E\u0433\u0440\u0430\u043D\u0438\u0447\u0435\u043D\u0438\u044F\u0438\u0434\u0435\u043D\u0442\u0438\u0447\u043D\u043E\u0441\u0442\u0438xs \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u043F\u0440\u043E\u0441\u0442\u043E\u0433\u043E\u0442\u0438\u043F\u0430xs \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u0441\u043E\u0441\u0442\u0430\u0432\u043D\u043E\u0433\u043E\u0442\u0438\u043F\u0430xs \u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435\u0442\u0438\u043F\u0430\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430dom '\n + '\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u044Fxpathxs \u043E\u0442\u0431\u043E\u0440\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043F\u0430\u043A\u0435\u0442\u043E\u0442\u043E\u0431\u0440\u0430\u0436\u0430\u0435\u043C\u044B\u0445\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u043E\u0432 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0432\u044B\u0431\u043E\u0440\u0430 \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B\u0437\u0430\u043F\u0438\u0441\u0438json \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B\u0437\u0430\u043F\u0438\u0441\u0438xml \u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B\u0447\u0442\u0435\u043D\u0438\u044Fxml \u043F\u0435\u0440\u0435\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u0438\u0435xs \u043F\u043B\u0430\u043D\u0438\u0440\u043E\u0432\u0449\u0438\u043A \u043F\u043E\u043B\u0435\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043F\u043E\u043B\u0435\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044Cdom \u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044C\u0437\u0430\u043F\u0440\u043E\u0441\u0430 \u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044C\u043E\u0442\u0447\u0435\u0442\u0430 \u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044C\u043E\u0442\u0447\u0435\u0442\u0430\u0430\u043D\u0430\u043B\u0438\u0437\u0430\u0434\u0430\u043D\u043D\u044B\u0445 '\n + '\u043F\u043E\u0441\u0442\u0440\u043E\u0438\u0442\u0435\u043B\u044C\u0441\u0445\u0435\u043Cxml \u043F\u043E\u0442\u043E\u043A \u043F\u043E\u0442\u043E\u043A\u0432\u043F\u0430\u043C\u044F\u0442\u0438 \u043F\u043E\u0447\u0442\u0430 \u043F\u043E\u0447\u0442\u043E\u0432\u043E\u0435\u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435 \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u0435xsl \u043F\u0440\u0435\u043E\u0431\u0440\u0430\u0437\u043E\u0432\u0430\u043D\u0438\u0435\u043A\u043A\u0430\u043D\u043E\u043D\u0438\u0447\u0435\u0441\u043A\u043E\u043C\u0443xml '\n + '\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u0440\u0432\u044B\u0432\u043E\u0434\u0430\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445\u0432\u043A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u044E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u0440\u0432\u044B\u0432\u043E\u0434\u0430\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445\u0432\u0442\u0430\u0431\u043B\u0438\u0447\u043D\u044B\u0439\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 '\n + '\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u0440\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0440\u0430\u0437\u044B\u043C\u0435\u043D\u043E\u0432\u0430\u0442\u0435\u043B\u044C\u043F\u0440\u043E\u0441\u0442\u0440\u0430\u043D\u0441\u0442\u0432\u0438\u043C\u0435\u043Ddom \u0440\u0430\u043C\u043A\u0430 \u0440\u0430\u0441\u043F\u0438\u0441\u0430\u043D\u0438\u0435\u0440\u0435\u0433\u043B\u0430\u043C\u0435\u043D\u0442\u043D\u043E\u0433\u043E\u0437\u0430\u0434\u0430\u043D\u0438\u044F \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u043D\u043E\u0435\u0438\u043C\u044Fxml '\n + '\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0447\u0442\u0435\u043D\u0438\u044F\u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u0432\u043E\u0434\u043D\u0430\u044F\u0434\u0438\u0430\u0433\u0440\u0430\u043C\u043C\u0430 \u0441\u0432\u044F\u0437\u044C\u043F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u0430\u0432\u044B\u0431\u043E\u0440\u0430 \u0441\u0432\u044F\u0437\u044C\u043F\u043E\u0442\u0438\u043F\u0443 \u0441\u0432\u044F\u0437\u044C\u043F\u043E\u0442\u0438\u043F\u0443\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u0435\u0440\u0438\u0430\u043B\u0438\u0437\u0430\u0442\u043E\u0440xdto '\n + '\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043A\u043B\u0438\u0435\u043D\u0442\u0430windows \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043A\u043B\u0438\u0435\u043D\u0442\u0430\u0444\u0430\u0439\u043B \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043A\u0440\u0438\u043F\u0442\u043E\u0433\u0440\u0430\u0444\u0438\u0438 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u044B\u0443\u0434\u043E\u0441\u0442\u043E\u0432\u0435\u0440\u044F\u044E\u0449\u0438\u0445\u0446\u0435\u043D\u0442\u0440\u043E\u0432windows '\n + '\u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u044B\u0443\u0434\u043E\u0441\u0442\u043E\u0432\u0435\u0440\u044F\u044E\u0449\u0438\u0445\u0446\u0435\u043D\u0442\u0440\u043E\u0432\u0444\u0430\u0439\u043B \u0441\u0436\u0430\u0442\u0438\u0435\u0434\u0430\u043D\u043D\u044B\u0445 \u0441\u0438\u0441\u0442\u0435\u043C\u043D\u0430\u044F\u0438\u043D\u0444\u043E\u0440\u043C\u0430\u0446\u0438\u044F \u0441\u043E\u043E\u0431\u0449\u0435\u043D\u0438\u0435\u043F\u043E\u043B\u044C\u0437\u043E\u0432\u0430\u0442\u0435\u043B\u044E \u0441\u043E\u0447\u0435\u0442\u0430\u043D\u0438\u0435\u043A\u043B\u0430\u0432\u0438\u0448 '\n + '\u0441\u0440\u0430\u0432\u043D\u0435\u043D\u0438\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u0430\u044F\u0434\u0430\u0442\u0430\u043D\u0430\u0447\u0430\u043B\u0430 \u0441\u0442\u0430\u043D\u0434\u0430\u0440\u0442\u043D\u044B\u0439\u043F\u0435\u0440\u0438\u043E\u0434 \u0441\u0445\u0435\u043C\u0430xml \u0441\u0445\u0435\u043C\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 \u0442\u0430\u0431\u043B\u0438\u0447\u043D\u044B\u0439\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 '\n + '\u0442\u0435\u043A\u0441\u0442\u043E\u0432\u044B\u0439\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 \u0442\u0435\u0441\u0442\u0438\u0440\u0443\u0435\u043C\u043E\u0435\u043F\u0440\u0438\u043B\u043E\u0436\u0435\u043D\u0438\u0435 \u0442\u0438\u043F\u0434\u0430\u043D\u043D\u044B\u0445xml \u0443\u043D\u0438\u043A\u0430\u043B\u044C\u043D\u044B\u0439\u0438\u0434\u0435\u043D\u0442\u0438\u0444\u0438\u043A\u0430\u0442\u043E\u0440 \u0444\u0430\u0431\u0440\u0438\u043A\u0430xdto \u0444\u0430\u0439\u043B \u0444\u0430\u0439\u043B\u043E\u0432\u044B\u0439\u043F\u043E\u0442\u043E\u043A '\n + '\u0444\u0430\u0441\u0435\u0442\u0434\u043B\u0438\u043D\u044Bxs \u0444\u0430\u0441\u0435\u0442\u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430\u0440\u0430\u0437\u0440\u044F\u0434\u043E\u0432\u0434\u0440\u043E\u0431\u043D\u043E\u0439\u0447\u0430\u0441\u0442\u0438xs \u0444\u0430\u0441\u0435\u0442\u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0433\u043E\u0432\u043A\u043B\u044E\u0447\u0430\u044E\u0449\u0435\u0433\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044Fxs '\n + '\u0444\u0430\u0441\u0435\u0442\u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0433\u043E\u0438\u0441\u043A\u043B\u044E\u0447\u0430\u044E\u0449\u0435\u0433\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044Fxs \u0444\u0430\u0441\u0435\u0442\u043C\u0430\u043A\u0441\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0439\u0434\u043B\u0438\u043D\u044Bxs \u0444\u0430\u0441\u0435\u0442\u043C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0433\u043E\u0432\u043A\u043B\u044E\u0447\u0430\u044E\u0449\u0435\u0433\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044Fxs '\n + '\u0444\u0430\u0441\u0435\u0442\u043C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0433\u043E\u0438\u0441\u043A\u043B\u044E\u0447\u0430\u044E\u0449\u0435\u0433\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044Fxs \u0444\u0430\u0441\u0435\u0442\u043C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u043E\u0439\u0434\u043B\u0438\u043D\u044Bxs \u0444\u0430\u0441\u0435\u0442\u043E\u0431\u0440\u0430\u0437\u0446\u0430xs \u0444\u0430\u0441\u0435\u0442\u043E\u0431\u0449\u0435\u0433\u043E\u043A\u043E\u043B\u0438\u0447\u0435\u0441\u0442\u0432\u0430\u0440\u0430\u0437\u0440\u044F\u0434\u043E\u0432xs '\n + '\u0444\u0430\u0441\u0435\u0442\u043F\u0435\u0440\u0435\u0447\u0438\u0441\u043B\u0435\u043D\u0438\u044Fxs \u0444\u0430\u0441\u0435\u0442\u043F\u0440\u043E\u0431\u0435\u043B\u044C\u043D\u044B\u0445\u0441\u0438\u043C\u0432\u043E\u043B\u043E\u0432xs \u0444\u0438\u043B\u044C\u0442\u0440\u0443\u0437\u043B\u043E\u0432dom \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u0430\u044F\u0441\u0442\u0440\u043E\u043A\u0430 \u0444\u043E\u0440\u043C\u0430\u0442\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439\u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442 '\n + '\u0444\u0440\u0430\u0433\u043C\u0435\u043D\u0442xs \u0445\u0435\u0448\u0438\u0440\u043E\u0432\u0430\u043D\u0438\u0435\u0434\u0430\u043D\u043D\u044B\u0445 \u0445\u0440\u0430\u043D\u0438\u043B\u0438\u0449\u0435\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u044F \u0446\u0432\u0435\u0442 \u0447\u0442\u0435\u043D\u0438\u0435fastinfoset \u0447\u0442\u0435\u043D\u0438\u0435html \u0447\u0442\u0435\u043D\u0438\u0435json \u0447\u0442\u0435\u043D\u0438\u0435xml \u0447\u0442\u0435\u043D\u0438\u0435zip\u0444\u0430\u0439\u043B\u0430 '\n + '\u0447\u0442\u0435\u043D\u0438\u0435\u0434\u0430\u043D\u043D\u044B\u0445 \u0447\u0442\u0435\u043D\u0438\u0435\u0442\u0435\u043A\u0441\u0442\u0430 \u0447\u0442\u0435\u043D\u0438\u0435\u0443\u0437\u043B\u043E\u0432dom \u0448\u0440\u0438\u0444\u0442 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u0440\u0435\u0437\u0443\u043B\u044C\u0442\u0430\u0442\u0430\u043A\u043E\u043C\u043F\u043E\u043D\u043E\u0432\u043A\u0438\u0434\u0430\u043D\u043D\u044B\u0445 ';\n\n // v8 \u0443\u043D\u0438\u0432\u0435\u0440\u0441\u0430\u043B\u044C\u043D\u044B\u0435 \u043A\u043E\u043B\u043B\u0435\u043A\u0446\u0438\u0438 \u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 ==> type\n const v8_universal_collection =\n 'comsafearray \u0434\u0435\u0440\u0435\u0432\u043E\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u043C\u0430\u0441\u0441\u0438\u0432 \u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0441\u043F\u0438\u0441\u043E\u043A\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 \u0442\u0430\u0431\u043B\u0438\u0446\u0430\u0437\u043D\u0430\u0447\u0435\u043D\u0438\u0439 \u0444\u0438\u043A\u0441\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u0430\u044F\u0441\u0442\u0440\u0443\u043A\u0442\u0443\u0440\u0430 '\n + '\u0444\u0438\u043A\u0441\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u043E\u0435\u0441\u043E\u043E\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0444\u0438\u043A\u0441\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u044B\u0439\u043C\u0430\u0441\u0441\u0438\u0432 ';\n\n // type : \u0432\u0441\u0442\u0440\u043E\u0435\u043D\u043D\u044B\u0435 \u0442\u0438\u043F\u044B\n const TYPE =\n v8_shared_object\n + v8_universal_collection;\n\n // literal : \u043F\u0440\u0438\u043C\u0438\u0442\u0438\u0432\u043D\u044B\u0435 \u0442\u0438\u043F\u044B\n const LITERAL = 'null \u0438\u0441\u0442\u0438\u043D\u0430 \u043B\u043E\u0436\u044C \u043D\u0435\u043E\u043F\u0440\u0435\u0434\u0435\u043B\u0435\u043D\u043E';\n\n // number : \u0447\u0438\u0441\u043B\u0430\n const NUMBERS = hljs.inherit(hljs.NUMBER_MODE);\n\n // string : \u0441\u0442\u0440\u043E\u043A\u0438\n const STRINGS = {\n className: 'string',\n begin: '\"|\\\\|',\n end: '\"|$',\n contains: [ { begin: '\"\"' } ]\n };\n\n // number : \u0434\u0430\u0442\u044B\n const DATE = {\n begin: \"'\",\n end: \"'\",\n excludeBegin: true,\n excludeEnd: true,\n contains: [\n {\n className: 'number',\n begin: '\\\\d{4}([\\\\.\\\\\\\\/:-]?\\\\d{2}){0,5}'\n }\n ]\n };\n\n const PUNCTUATION = {\n match: /[;()+\\-:=,]/,\n className: \"punctuation\",\n relevance: 0\n };\n\n // comment : \u043A\u043E\u043C\u043C\u0435\u043D\u0442\u0430\u0440\u0438\u0438\n const COMMENTS = hljs.inherit(hljs.C_LINE_COMMENT_MODE);\n\n // meta : \u0438\u043D\u0441\u0442\u0440\u0443\u043A\u0446\u0438\u0438 \u043F\u0440\u0435\u043F\u0440\u043E\u0446\u0435\u0441\u0441\u043E\u0440\u0430, \u0434\u0438\u0440\u0435\u043A\u0442\u0438\u0432\u044B \u043A\u043E\u043C\u043F\u0438\u043B\u044F\u0446\u0438\u0438\n const META = {\n className: 'meta',\n\n begin: '#|&',\n end: '$',\n keywords: {\n $pattern: UNDERSCORE_IDENT_RE,\n keyword: KEYWORD + METAKEYWORD\n },\n contains: [ COMMENTS ]\n };\n\n // symbol : \u043C\u0435\u0442\u043A\u0430 goto\n const SYMBOL = {\n className: 'symbol',\n begin: '~',\n end: ';|:',\n excludeEnd: true\n };\n\n // function : \u043E\u0431\u044A\u044F\u0432\u043B\u0435\u043D\u0438\u0435 \u043F\u0440\u043E\u0446\u0435\u0434\u0443\u0440 \u0438 \u0444\u0443\u043D\u043A\u0446\u0438\u0439\n const FUNCTION = {\n className: 'function',\n variants: [\n {\n begin: '\u043F\u0440\u043E\u0446\u0435\u0434\u0443\u0440\u0430|\u0444\u0443\u043D\u043A\u0446\u0438\u044F',\n end: '\\\\)',\n keywords: '\u043F\u0440\u043E\u0446\u0435\u0434\u0443\u0440\u0430 \u0444\u0443\u043D\u043A\u0446\u0438\u044F'\n },\n {\n begin: '\u043A\u043E\u043D\u0435\u0446\u043F\u0440\u043E\u0446\u0435\u0434\u0443\u0440\u044B|\u043A\u043E\u043D\u0435\u0446\u0444\u0443\u043D\u043A\u0446\u0438\u0438',\n keywords: '\u043A\u043E\u043D\u0435\u0446\u043F\u0440\u043E\u0446\u0435\u0434\u0443\u0440\u044B \u043A\u043E\u043D\u0435\u0446\u0444\u0443\u043D\u043A\u0446\u0438\u0438'\n }\n ],\n contains: [\n {\n begin: '\\\\(',\n end: '\\\\)',\n endsParent: true,\n contains: [\n {\n className: 'params',\n begin: UNDERSCORE_IDENT_RE,\n end: ',',\n excludeEnd: true,\n endsWithParent: true,\n keywords: {\n $pattern: UNDERSCORE_IDENT_RE,\n keyword: '\u0437\u043D\u0430\u0447',\n literal: LITERAL\n },\n contains: [\n NUMBERS,\n STRINGS,\n DATE\n ]\n },\n COMMENTS\n ]\n },\n hljs.inherit(hljs.TITLE_MODE, { begin: UNDERSCORE_IDENT_RE })\n ]\n };\n\n return {\n name: '1C:Enterprise',\n case_insensitive: true,\n keywords: {\n $pattern: UNDERSCORE_IDENT_RE,\n keyword: KEYWORD,\n built_in: BUILTIN,\n class: CLASS,\n type: TYPE,\n literal: LITERAL\n },\n contains: [\n META,\n FUNCTION,\n COMMENTS,\n SYMBOL,\n NUMBERS,\n STRINGS,\n DATE,\n PUNCTUATION\n ]\n };\n}\n\nmodule.exports = _1c;\n", "/*\nLanguage: Augmented Backus-Naur Form\nAuthor: Alex McKibben \nWebsite: https://tools.ietf.org/html/rfc5234\nCategory: syntax\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction abnf(hljs) {\n const regex = hljs.regex;\n const IDENT = /^[a-zA-Z][a-zA-Z0-9-]*/;\n\n const KEYWORDS = [\n \"ALPHA\",\n \"BIT\",\n \"CHAR\",\n \"CR\",\n \"CRLF\",\n \"CTL\",\n \"DIGIT\",\n \"DQUOTE\",\n \"HEXDIG\",\n \"HTAB\",\n \"LF\",\n \"LWSP\",\n \"OCTET\",\n \"SP\",\n \"VCHAR\",\n \"WSP\"\n ];\n\n const COMMENT = hljs.COMMENT(/;/, /$/);\n\n const TERMINAL_BINARY = {\n scope: \"symbol\",\n match: /%b[0-1]+(-[0-1]+|(\\.[0-1]+)+)?/\n };\n\n const TERMINAL_DECIMAL = {\n scope: \"symbol\",\n match: /%d[0-9]+(-[0-9]+|(\\.[0-9]+)+)?/\n };\n\n const TERMINAL_HEXADECIMAL = {\n scope: \"symbol\",\n match: /%x[0-9A-F]+(-[0-9A-F]+|(\\.[0-9A-F]+)+)?/\n };\n\n const CASE_SENSITIVITY = {\n scope: \"symbol\",\n match: /%[si](?=\".*\")/\n };\n\n const RULE_DECLARATION = {\n scope: \"attribute\",\n match: regex.concat(IDENT, /(?=\\s*=)/)\n };\n\n const ASSIGNMENT = {\n scope: \"operator\",\n match: /=\\/?/\n };\n\n return {\n name: 'Augmented Backus-Naur Form',\n illegal: /[!@#$^&',?+~`|:]/,\n keywords: KEYWORDS,\n contains: [\n ASSIGNMENT,\n RULE_DECLARATION,\n COMMENT,\n TERMINAL_BINARY,\n TERMINAL_DECIMAL,\n TERMINAL_HEXADECIMAL,\n CASE_SENSITIVITY,\n hljs.QUOTE_STRING_MODE,\n hljs.NUMBER_MODE\n ]\n };\n}\n\nmodule.exports = abnf;\n", "/*\n Language: Apache Access Log\n Author: Oleg Efimov \n Description: Apache/Nginx Access Logs\n Website: https://httpd.apache.org/docs/2.4/logs.html#accesslog\n Category: web, logs\n Audit: 2020\n */\n\n/** @type LanguageFn */\nfunction accesslog(hljs) {\n const regex = hljs.regex;\n // https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods\n const HTTP_VERBS = [\n \"GET\",\n \"POST\",\n \"HEAD\",\n \"PUT\",\n \"DELETE\",\n \"CONNECT\",\n \"OPTIONS\",\n \"PATCH\",\n \"TRACE\"\n ];\n return {\n name: 'Apache Access Log',\n contains: [\n // IP\n {\n className: 'number',\n begin: /^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b/,\n relevance: 5\n },\n // Other numbers\n {\n className: 'number',\n begin: /\\b\\d+\\b/,\n relevance: 0\n },\n // Requests\n {\n className: 'string',\n begin: regex.concat(/\"/, regex.either(...HTTP_VERBS)),\n end: /\"/,\n keywords: HTTP_VERBS,\n illegal: /\\n/,\n relevance: 5,\n contains: [\n {\n begin: /HTTP\\/[12]\\.\\d'/,\n relevance: 5\n }\n ]\n },\n // Dates\n {\n className: 'string',\n // dates must have a certain length, this prevents matching\n // simple array accesses a[123] and [] and other common patterns\n // found in other languages\n begin: /\\[\\d[^\\]\\n]{8,}\\]/,\n illegal: /\\n/,\n relevance: 1\n },\n {\n className: 'string',\n begin: /\\[/,\n end: /\\]/,\n illegal: /\\n/,\n relevance: 0\n },\n // User agent / relevance boost\n {\n className: 'string',\n begin: /\"Mozilla\\/\\d\\.\\d \\(/,\n end: /\"/,\n illegal: /\\n/,\n relevance: 3\n },\n // Strings\n {\n className: 'string',\n begin: /\"/,\n end: /\"/,\n illegal: /\\n/,\n relevance: 0\n }\n ]\n };\n}\n\nmodule.exports = accesslog;\n", "/*\nLanguage: ActionScript\nAuthor: Alexander Myadzel \nCategory: scripting\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction actionscript(hljs) {\n const regex = hljs.regex;\n const IDENT_RE = /[a-zA-Z_$][a-zA-Z0-9_$]*/;\n const PKG_NAME_RE = regex.concat(\n IDENT_RE,\n regex.concat(\"(\\\\.\", IDENT_RE, \")*\")\n );\n const IDENT_FUNC_RETURN_TYPE_RE = /([*]|[a-zA-Z_$][a-zA-Z0-9_$]*)/;\n\n const AS3_REST_ARG_MODE = {\n className: 'rest_arg',\n begin: /[.]{3}/,\n end: IDENT_RE,\n relevance: 10\n };\n\n const KEYWORDS = [\n \"as\",\n \"break\",\n \"case\",\n \"catch\",\n \"class\",\n \"const\",\n \"continue\",\n \"default\",\n \"delete\",\n \"do\",\n \"dynamic\",\n \"each\",\n \"else\",\n \"extends\",\n \"final\",\n \"finally\",\n \"for\",\n \"function\",\n \"get\",\n \"if\",\n \"implements\",\n \"import\",\n \"in\",\n \"include\",\n \"instanceof\",\n \"interface\",\n \"internal\",\n \"is\",\n \"namespace\",\n \"native\",\n \"new\",\n \"override\",\n \"package\",\n \"private\",\n \"protected\",\n \"public\",\n \"return\",\n \"set\",\n \"static\",\n \"super\",\n \"switch\",\n \"this\",\n \"throw\",\n \"try\",\n \"typeof\",\n \"use\",\n \"var\",\n \"void\",\n \"while\",\n \"with\"\n ];\n const LITERALS = [\n \"true\",\n \"false\",\n \"null\",\n \"undefined\"\n ];\n\n return {\n name: 'ActionScript',\n aliases: [ 'as' ],\n keywords: {\n keyword: KEYWORDS,\n literal: LITERALS\n },\n contains: [\n hljs.APOS_STRING_MODE,\n hljs.QUOTE_STRING_MODE,\n hljs.C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE,\n hljs.C_NUMBER_MODE,\n {\n match: [\n /\\bpackage/,\n /\\s+/,\n PKG_NAME_RE\n ],\n className: {\n 1: \"keyword\",\n 3: \"title.class\"\n }\n },\n {\n match: [\n /\\b(?:class|interface|extends|implements)/,\n /\\s+/,\n IDENT_RE\n ],\n className: {\n 1: \"keyword\",\n 3: \"title.class\"\n }\n },\n {\n className: 'meta',\n beginKeywords: 'import include',\n end: /;/,\n keywords: { keyword: 'import include' }\n },\n {\n beginKeywords: 'function',\n end: /[{;]/,\n excludeEnd: true,\n illegal: /\\S/,\n contains: [\n hljs.inherit(hljs.TITLE_MODE, { className: \"title.function\" }),\n {\n className: 'params',\n begin: /\\(/,\n end: /\\)/,\n contains: [\n hljs.APOS_STRING_MODE,\n hljs.QUOTE_STRING_MODE,\n hljs.C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE,\n AS3_REST_ARG_MODE\n ]\n },\n { begin: regex.concat(/:\\s*/, IDENT_FUNC_RETURN_TYPE_RE) }\n ]\n },\n hljs.METHOD_GUARD\n ],\n illegal: /#/\n };\n}\n\nmodule.exports = actionscript;\n", "/*\nLanguage: Ada\nAuthor: Lars Schulna \nDescription: Ada is a general-purpose programming language that has great support for saftey critical and real-time applications.\n It has been developed by the DoD and thus has been used in military and safety-critical applications (like civil aviation).\n The first version appeared in the 80s, but it's still actively developed today with\n the newest standard being Ada2012.\n*/\n\n// We try to support full Ada2012\n//\n// We highlight all appearances of types, keywords, literals (string, char, number, bool)\n// and titles (user defined function/procedure/package)\n// CSS classes are set accordingly\n//\n// Languages causing problems for language detection:\n// xml (broken by Foo : Bar type), elm (broken by Foo : Bar type), vbscript-html (broken by body keyword)\n// sql (ada default.txt has a lot of sql keywords)\n\n/** @type LanguageFn */\nfunction ada(hljs) {\n // Regular expression for Ada numeric literals.\n // stolen form the VHDL highlighter\n\n // Decimal literal:\n const INTEGER_RE = '\\\\d(_|\\\\d)*';\n const EXPONENT_RE = '[eE][-+]?' + INTEGER_RE;\n const DECIMAL_LITERAL_RE = INTEGER_RE + '(\\\\.' + INTEGER_RE + ')?' + '(' + EXPONENT_RE + ')?';\n\n // Based literal:\n const BASED_INTEGER_RE = '\\\\w+';\n const BASED_LITERAL_RE = INTEGER_RE + '#' + BASED_INTEGER_RE + '(\\\\.' + BASED_INTEGER_RE + ')?' + '#' + '(' + EXPONENT_RE + ')?';\n\n const NUMBER_RE = '\\\\b(' + BASED_LITERAL_RE + '|' + DECIMAL_LITERAL_RE + ')';\n\n // Identifier regex\n const ID_REGEX = '[A-Za-z](_?[A-Za-z0-9.])*';\n\n // bad chars, only allowed in literals\n const BAD_CHARS = `[]\\\\{\\\\}%#'\"`;\n\n // Ada doesn't have block comments, only line comments\n const COMMENTS = hljs.COMMENT('--', '$');\n\n // variable declarations of the form\n // Foo : Bar := Baz;\n // where only Bar will be highlighted\n const VAR_DECLS = {\n // TODO: These spaces are not required by the Ada syntax\n // however, I have yet to see handwritten Ada code where\n // someone does not put spaces around :\n begin: '\\\\s+:\\\\s+',\n end: '\\\\s*(:=|;|\\\\)|=>|$)',\n // endsWithParent: true,\n // returnBegin: true,\n illegal: BAD_CHARS,\n contains: [\n {\n // workaround to avoid highlighting\n // named loops and declare blocks\n beginKeywords: 'loop for declare others',\n endsParent: true\n },\n {\n // properly highlight all modifiers\n className: 'keyword',\n beginKeywords: 'not null constant access function procedure in out aliased exception'\n },\n {\n className: 'type',\n begin: ID_REGEX,\n endsParent: true,\n relevance: 0\n }\n ]\n };\n\n const KEYWORDS = [\n \"abort\",\n \"else\",\n \"new\",\n \"return\",\n \"abs\",\n \"elsif\",\n \"not\",\n \"reverse\",\n \"abstract\",\n \"end\",\n \"accept\",\n \"entry\",\n \"select\",\n \"access\",\n \"exception\",\n \"of\",\n \"separate\",\n \"aliased\",\n \"exit\",\n \"or\",\n \"some\",\n \"all\",\n \"others\",\n \"subtype\",\n \"and\",\n \"for\",\n \"out\",\n \"synchronized\",\n \"array\",\n \"function\",\n \"overriding\",\n \"at\",\n \"tagged\",\n \"generic\",\n \"package\",\n \"task\",\n \"begin\",\n \"goto\",\n \"pragma\",\n \"terminate\",\n \"body\",\n \"private\",\n \"then\",\n \"if\",\n \"procedure\",\n \"type\",\n \"case\",\n \"in\",\n \"protected\",\n \"constant\",\n \"interface\",\n \"is\",\n \"raise\",\n \"use\",\n \"declare\",\n \"range\",\n \"delay\",\n \"limited\",\n \"record\",\n \"when\",\n \"delta\",\n \"loop\",\n \"rem\",\n \"while\",\n \"digits\",\n \"renames\",\n \"with\",\n \"do\",\n \"mod\",\n \"requeue\",\n \"xor\"\n ];\n\n return {\n name: 'Ada',\n case_insensitive: true,\n keywords: {\n keyword: KEYWORDS,\n literal: [\n \"True\",\n \"False\"\n ]\n },\n contains: [\n COMMENTS,\n // strings \"foobar\"\n {\n className: 'string',\n begin: /\"/,\n end: /\"/,\n contains: [\n {\n begin: /\"\"/,\n relevance: 0\n }\n ]\n },\n // characters ''\n {\n // character literals always contain one char\n className: 'string',\n begin: /'.'/\n },\n {\n // number literals\n className: 'number',\n begin: NUMBER_RE,\n relevance: 0\n },\n {\n // Attributes\n className: 'symbol',\n begin: \"'\" + ID_REGEX\n },\n {\n // package definition, maybe inside generic\n className: 'title',\n begin: '(\\\\bwith\\\\s+)?(\\\\bprivate\\\\s+)?\\\\bpackage\\\\s+(\\\\bbody\\\\s+)?',\n end: '(is|$)',\n keywords: 'package body',\n excludeBegin: true,\n excludeEnd: true,\n illegal: BAD_CHARS\n },\n {\n // function/procedure declaration/definition\n // maybe inside generic\n begin: '(\\\\b(with|overriding)\\\\s+)?\\\\b(function|procedure)\\\\s+',\n end: '(\\\\bis|\\\\bwith|\\\\brenames|\\\\)\\\\s*;)',\n keywords: 'overriding function procedure with is renames return',\n // we need to re-match the 'function' keyword, so that\n // the title mode below matches only exactly once\n returnBegin: true,\n contains:\n [\n COMMENTS,\n {\n // name of the function/procedure\n className: 'title',\n begin: '(\\\\bwith\\\\s+)?\\\\b(function|procedure)\\\\s+',\n end: '(\\\\(|\\\\s+|$)',\n excludeBegin: true,\n excludeEnd: true,\n illegal: BAD_CHARS\n },\n // 'self'\n // // parameter types\n VAR_DECLS,\n {\n // return type\n className: 'type',\n begin: '\\\\breturn\\\\s+',\n end: '(\\\\s+|;|$)',\n keywords: 'return',\n excludeBegin: true,\n excludeEnd: true,\n // we are done with functions\n endsParent: true,\n illegal: BAD_CHARS\n\n }\n ]\n },\n {\n // new type declarations\n // maybe inside generic\n className: 'type',\n begin: '\\\\b(sub)?type\\\\s+',\n end: '\\\\s+',\n keywords: 'type',\n excludeBegin: true,\n illegal: BAD_CHARS\n },\n\n // see comment above the definition\n VAR_DECLS\n\n // no markup\n // relevance boosters for small snippets\n // {begin: '\\\\s*=>\\\\s*'},\n // {begin: '\\\\s*:=\\\\s*'},\n // {begin: '\\\\s+:=\\\\s+'},\n ]\n };\n}\n\nmodule.exports = ada;\n", "/*\nLanguage: AngelScript\nAuthor: Melissa Geels \nCategory: scripting\nWebsite: https://www.angelcode.com/angelscript/\n*/\n\n/** @type LanguageFn */\nfunction angelscript(hljs) {\n const builtInTypeMode = {\n className: 'built_in',\n begin: '\\\\b(void|bool|int8|int16|int32|int64|int|uint8|uint16|uint32|uint64|uint|string|ref|array|double|float|auto|dictionary)'\n };\n\n const objectHandleMode = {\n className: 'symbol',\n begin: '[a-zA-Z0-9_]+@'\n };\n\n const genericMode = {\n className: 'keyword',\n begin: '<',\n end: '>',\n contains: [\n builtInTypeMode,\n objectHandleMode\n ]\n };\n\n builtInTypeMode.contains = [ genericMode ];\n objectHandleMode.contains = [ genericMode ];\n\n const KEYWORDS = [\n \"for\",\n \"in|0\",\n \"break\",\n \"continue\",\n \"while\",\n \"do|0\",\n \"return\",\n \"if\",\n \"else\",\n \"case\",\n \"switch\",\n \"namespace\",\n \"is\",\n \"cast\",\n \"or\",\n \"and\",\n \"xor\",\n \"not\",\n \"get|0\",\n \"in\",\n \"inout|10\",\n \"out\",\n \"override\",\n \"set|0\",\n \"private\",\n \"public\",\n \"const\",\n \"default|0\",\n \"final\",\n \"shared\",\n \"external\",\n \"mixin|10\",\n \"enum\",\n \"typedef\",\n \"funcdef\",\n \"this\",\n \"super\",\n \"import\",\n \"from\",\n \"interface\",\n \"abstract|0\",\n \"try\",\n \"catch\",\n \"protected\",\n \"explicit\",\n \"property\"\n ];\n\n return {\n name: 'AngelScript',\n aliases: [ 'asc' ],\n\n keywords: KEYWORDS,\n\n // avoid close detection with C# and JS\n illegal: '(^using\\\\s+[A-Za-z0-9_\\\\.]+;$|\\\\bfunction\\\\s*[^\\\\(])',\n\n contains: [\n { // 'strings'\n className: 'string',\n begin: '\\'',\n end: '\\'',\n illegal: '\\\\n',\n contains: [ hljs.BACKSLASH_ESCAPE ],\n relevance: 0\n },\n\n // \"\"\"heredoc strings\"\"\"\n {\n className: 'string',\n begin: '\"\"\"',\n end: '\"\"\"'\n },\n\n { // \"strings\"\n className: 'string',\n begin: '\"',\n end: '\"',\n illegal: '\\\\n',\n contains: [ hljs.BACKSLASH_ESCAPE ],\n relevance: 0\n },\n\n hljs.C_LINE_COMMENT_MODE, // single-line comments\n hljs.C_BLOCK_COMMENT_MODE, // comment blocks\n\n { // metadata\n className: 'string',\n begin: '^\\\\s*\\\\[',\n end: '\\\\]'\n },\n\n { // interface or namespace declaration\n beginKeywords: 'interface namespace',\n end: /\\{/,\n illegal: '[;.\\\\-]',\n contains: [\n { // interface or namespace name\n className: 'symbol',\n begin: '[a-zA-Z0-9_]+'\n }\n ]\n },\n\n { // class declaration\n beginKeywords: 'class',\n end: /\\{/,\n illegal: '[;.\\\\-]',\n contains: [\n { // class name\n className: 'symbol',\n begin: '[a-zA-Z0-9_]+',\n contains: [\n {\n begin: '[:,]\\\\s*',\n contains: [\n {\n className: 'symbol',\n begin: '[a-zA-Z0-9_]+'\n }\n ]\n }\n ]\n }\n ]\n },\n\n builtInTypeMode, // built-in types\n objectHandleMode, // object handles\n\n { // literals\n className: 'literal',\n begin: '\\\\b(null|true|false)'\n },\n\n { // numbers\n className: 'number',\n relevance: 0,\n begin: '(-?)(\\\\b0[xXbBoOdD][a-fA-F0-9]+|(\\\\b\\\\d+(\\\\.\\\\d*)?f?|\\\\.\\\\d+f?)([eE][-+]?\\\\d+f?)?)'\n }\n ]\n };\n}\n\nmodule.exports = angelscript;\n", "/*\nLanguage: Apache config\nAuthor: Ruslan Keba \nContributors: Ivan Sagalaev \nWebsite: https://httpd.apache.org\nDescription: language definition for Apache configuration files (httpd.conf & .htaccess)\nCategory: config, web\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction apache(hljs) {\n const NUMBER_REF = {\n className: 'number',\n begin: /[$%]\\d+/\n };\n const NUMBER = {\n className: 'number',\n begin: /\\b\\d+/\n };\n const IP_ADDRESS = {\n className: \"number\",\n begin: /\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?/\n };\n const PORT_NUMBER = {\n className: \"number\",\n begin: /:\\d{1,5}/\n };\n return {\n name: 'Apache config',\n aliases: [ 'apacheconf' ],\n case_insensitive: true,\n contains: [\n hljs.HASH_COMMENT_MODE,\n {\n className: 'section',\n begin: /<\\/?/,\n end: />/,\n contains: [\n IP_ADDRESS,\n PORT_NUMBER,\n // low relevance prevents us from claming XML/HTML where this rule would\n // match strings inside of XML tags\n hljs.inherit(hljs.QUOTE_STRING_MODE, { relevance: 0 })\n ]\n },\n {\n className: 'attribute',\n begin: /\\w+/,\n relevance: 0,\n // keywords aren\u2019t needed for highlighting per se, they only boost relevance\n // for a very generally defined mode (starts with a word, ends with line-end\n keywords: { _: [\n \"order\",\n \"deny\",\n \"allow\",\n \"setenv\",\n \"rewriterule\",\n \"rewriteengine\",\n \"rewritecond\",\n \"documentroot\",\n \"sethandler\",\n \"errordocument\",\n \"loadmodule\",\n \"options\",\n \"header\",\n \"listen\",\n \"serverroot\",\n \"servername\"\n ] },\n starts: {\n end: /$/,\n relevance: 0,\n keywords: { literal: 'on off all deny allow' },\n contains: [\n {\n className: 'meta',\n begin: /\\s\\[/,\n end: /\\]$/\n },\n {\n className: 'variable',\n begin: /[\\$%]\\{/,\n end: /\\}/,\n contains: [\n 'self',\n NUMBER_REF\n ]\n },\n IP_ADDRESS,\n NUMBER,\n hljs.QUOTE_STRING_MODE\n ]\n }\n }\n ],\n illegal: /\\S/\n };\n}\n\nmodule.exports = apache;\n", "/*\nLanguage: AppleScript\nAuthors: Nathan Grigg , Dr. Drang \nCategory: scripting\nWebsite: https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction applescript(hljs) {\n const regex = hljs.regex;\n const STRING = hljs.inherit(\n hljs.QUOTE_STRING_MODE, { illegal: null });\n const PARAMS = {\n className: 'params',\n begin: /\\(/,\n end: /\\)/,\n contains: [\n 'self',\n hljs.C_NUMBER_MODE,\n STRING\n ]\n };\n const COMMENT_MODE_1 = hljs.COMMENT(/--/, /$/);\n const COMMENT_MODE_2 = hljs.COMMENT(\n /\\(\\*/,\n /\\*\\)/,\n { contains: [\n 'self', // allow nesting\n COMMENT_MODE_1\n ] }\n );\n const COMMENTS = [\n COMMENT_MODE_1,\n COMMENT_MODE_2,\n hljs.HASH_COMMENT_MODE\n ];\n\n const KEYWORD_PATTERNS = [\n /apart from/,\n /aside from/,\n /instead of/,\n /out of/,\n /greater than/,\n /isn't|(doesn't|does not) (equal|come before|come after|contain)/,\n /(greater|less) than( or equal)?/,\n /(starts?|ends|begins?) with/,\n /contained by/,\n /comes (before|after)/,\n /a (ref|reference)/,\n /POSIX (file|path)/,\n /(date|time) string/,\n /quoted form/\n ];\n\n const BUILT_IN_PATTERNS = [\n /clipboard info/,\n /the clipboard/,\n /info for/,\n /list (disks|folder)/,\n /mount volume/,\n /path to/,\n /(close|open for) access/,\n /(get|set) eof/,\n /current date/,\n /do shell script/,\n /get volume settings/,\n /random number/,\n /set volume/,\n /system attribute/,\n /system info/,\n /time to GMT/,\n /(load|run|store) script/,\n /scripting components/,\n /ASCII (character|number)/,\n /localized string/,\n /choose (application|color|file|file name|folder|from list|remote application|URL)/,\n /display (alert|dialog)/\n ];\n\n return {\n name: 'AppleScript',\n aliases: [ 'osascript' ],\n keywords: {\n keyword:\n 'about above after against and around as at back before beginning '\n + 'behind below beneath beside between but by considering '\n + 'contain contains continue copy div does eighth else end equal '\n + 'equals error every exit fifth first for fourth from front '\n + 'get given global if ignoring in into is it its last local me '\n + 'middle mod my ninth not of on onto or over prop property put ref '\n + 'reference repeat returning script second set seventh since '\n + 'sixth some tell tenth that the|0 then third through thru '\n + 'timeout times to transaction try until where while whose with '\n + 'without',\n literal:\n 'AppleScript false linefeed return pi quote result space tab true',\n built_in:\n 'alias application boolean class constant date file integer list '\n + 'number real record string text '\n + 'activate beep count delay launch log offset read round '\n + 'run say summarize write '\n + 'character characters contents day frontmost id item length '\n + 'month name|0 paragraph paragraphs rest reverse running time version '\n + 'weekday word words year'\n },\n contains: [\n STRING,\n hljs.C_NUMBER_MODE,\n {\n className: 'built_in',\n begin: regex.concat(\n /\\b/,\n regex.either(...BUILT_IN_PATTERNS),\n /\\b/\n )\n },\n {\n className: 'built_in',\n begin: /^\\s*return\\b/\n },\n {\n className: 'literal',\n begin:\n /\\b(text item delimiters|current application|missing value)\\b/\n },\n {\n className: 'keyword',\n begin: regex.concat(\n /\\b/,\n regex.either(...KEYWORD_PATTERNS),\n /\\b/\n )\n },\n {\n beginKeywords: 'on',\n illegal: /[${=;\\n]/,\n contains: [\n hljs.UNDERSCORE_TITLE_MODE,\n PARAMS\n ]\n },\n ...COMMENTS\n ],\n illegal: /\\/\\/|->|=>|\\[\\[/\n };\n}\n\nmodule.exports = applescript;\n", "/*\n Language: ArcGIS Arcade\n Category: scripting\n Author: John Foster \n Website: https://developers.arcgis.com/arcade/\n Description: ArcGIS Arcade is an expression language used in many Esri ArcGIS products such as Pro, Online, Server, Runtime, JavaScript, and Python\n*/\n\n/** @type LanguageFn */\nfunction arcade(hljs) {\n const regex = hljs.regex;\n const IDENT_RE = '[A-Za-z_][0-9A-Za-z_]*';\n const KEYWORDS = {\n keyword: [\n \"break\",\n \"case\",\n \"catch\",\n \"continue\",\n \"debugger\",\n \"do\",\n \"else\",\n \"export\",\n \"for\",\n \"function\",\n \"if\",\n \"import\",\n \"in\",\n \"new\",\n \"return\",\n \"switch\",\n \"try\",\n \"var\",\n \"void\",\n \"while\"\n ],\n literal: [\n \"BackSlash\",\n \"DoubleQuote\",\n \"ForwardSlash\",\n \"Infinity\",\n \"NaN\",\n \"NewLine\",\n \"PI\",\n \"SingleQuote\",\n \"Tab\",\n \"TextFormatting\",\n \"false\",\n \"null\",\n \"true\",\n \"undefined\"\n ],\n built_in: [\n \"Abs\",\n \"Acos\",\n \"All\",\n \"Angle\",\n \"Any\",\n \"Area\",\n \"AreaGeodetic\",\n \"Array\",\n \"Asin\",\n \"Atan\",\n \"Atan2\",\n \"Attachments\",\n \"Average\",\n \"Back\",\n \"Bearing\",\n \"Boolean\",\n \"Buffer\",\n \"BufferGeodetic\",\n \"Ceil\",\n \"Centroid\",\n \"ChangeTimeZone\",\n \"Clip\",\n \"Concatenate\",\n \"Console\",\n \"Constrain\",\n \"Contains\",\n \"ConvertDirection\",\n \"ConvexHull\",\n \"Cos\",\n \"Count\",\n \"Crosses\",\n \"Cut\",\n \"Date|0\",\n \"DateAdd\",\n \"DateDiff\",\n \"DateOnly\",\n \"Day\",\n \"Decode\",\n \"DefaultValue\",\n \"Densify\",\n \"DensifyGeodetic\",\n \"Dictionary\",\n \"Difference\",\n \"Disjoint\",\n \"Distance\",\n \"DistanceGeodetic\",\n \"Distinct\",\n \"Domain\",\n \"DomainCode\",\n \"DomainName\",\n \"EnvelopeIntersects\",\n \"Equals\",\n \"Erase\",\n \"Exp\",\n \"Expects\",\n \"Extent\",\n \"Feature\",\n \"FeatureSet\",\n \"FeatureSetByAssociation\",\n \"FeatureSetById\",\n \"FeatureSetByName\",\n \"FeatureSetByPortalItem\",\n \"FeatureSetByRelationshipClass\",\n \"FeatureSetByRelationshipName\",\n \"Filter\",\n \"Find\",\n \"First|0\",\n \"Floor\",\n \"FromCharCode\",\n \"FromCodePoint\",\n \"FromJSON\",\n \"Front\",\n \"GdbVersion\",\n \"Generalize\",\n \"Geometry\",\n \"GetEnvironment\",\n \"GetFeatureSet\",\n \"GetFeatureSetInfo\",\n \"GetUser\",\n \"GroupBy\",\n \"Guid\",\n \"HasKey\",\n \"HasValue\",\n \"Hash\",\n \"Hour\",\n \"IIf\",\n \"ISOMonth\",\n \"ISOWeek\",\n \"ISOWeekday\",\n \"ISOYear\",\n \"Includes\",\n \"IndexOf\",\n \"Insert\",\n \"Intersection\",\n \"Intersects\",\n \"IsEmpty\",\n \"IsNan\",\n \"IsSelfIntersecting\",\n \"IsSimple\",\n \"Left|0\",\n \"Length\",\n \"Length3D\",\n \"LengthGeodetic\",\n \"Log\",\n \"Lower\",\n \"Map\",\n \"Max\",\n \"Mean\",\n \"Mid\",\n \"Millisecond\",\n \"Min\",\n \"Minute\",\n \"Month\",\n \"MultiPartToSinglePart\",\n \"Multipoint\",\n \"NearestCoordinate\",\n \"NearestVertex\",\n \"NextSequenceValue\",\n \"None\",\n \"Now\",\n \"Number\",\n \"Offset\",\n \"OrderBy\",\n \"Overlaps\",\n \"Point\",\n \"Polygon\",\n \"Polyline\",\n \"Pop\",\n \"Portal\",\n \"Pow\",\n \"Proper\",\n \"Push\",\n \"Random\",\n \"Reduce\",\n \"Relate\",\n \"Replace\",\n \"Resize\",\n \"Reverse\",\n \"Right|0\",\n \"RingIsClockwise\",\n \"Rotate\",\n \"Round\",\n \"Schema\",\n \"Second\",\n \"SetGeometry\",\n \"Simplify\",\n \"Sin\",\n \"Slice\",\n \"Sort\",\n \"Splice\",\n \"Split\",\n \"Sqrt\",\n \"StandardizeGuid\",\n \"Stdev\",\n \"SubtypeCode\",\n \"SubtypeName\",\n \"Subtypes\",\n \"Sum\",\n \"SymmetricDifference\",\n \"Tan\",\n \"Text\",\n \"Time\",\n \"TimeZone\",\n \"TimeZoneOffset\",\n \"Timestamp\",\n \"ToCharCode\",\n \"ToCodePoint\",\n \"ToHex\",\n \"ToLocal\",\n \"ToUTC\",\n \"Today\",\n \"Top|0\",\n \"Touches\",\n \"TrackAccelerationAt\",\n \"TrackAccelerationWindow\",\n \"TrackCurrentAcceleration\",\n \"TrackCurrentDistance\",\n \"TrackCurrentSpeed\",\n \"TrackCurrentTime\",\n \"TrackDistanceAt\",\n \"TrackDistanceWindow\",\n \"TrackDuration\",\n \"TrackFieldWindow\",\n \"TrackGeometryWindow\",\n \"TrackIndex\",\n \"TrackSpeedAt\",\n \"TrackSpeedWindow\",\n \"TrackStartTime\",\n \"TrackWindow\",\n \"Trim\",\n \"TypeOf\",\n \"Union\",\n \"Upper\",\n \"UrlEncode\",\n \"Variance\",\n \"Week\",\n \"Weekday\",\n \"When|0\",\n \"Within\",\n \"Year|0\",\n ]\n };\n const PROFILE_VARS = [\n \"aggregatedFeatures\",\n \"analytic\",\n \"config\",\n \"datapoint\",\n \"datastore\",\n \"editcontext\",\n \"feature\",\n \"featureSet\",\n \"feedfeature\",\n \"fencefeature\",\n \"fencenotificationtype\",\n \"join\",\n \"layer\",\n \"locationupdate\",\n \"map\",\n \"measure\",\n \"measure\",\n \"originalFeature\",\n \"record\",\n \"reference\",\n \"rowindex\",\n \"sourcedatastore\",\n \"sourcefeature\",\n \"sourcelayer\",\n \"target\",\n \"targetdatastore\",\n \"targetfeature\",\n \"targetlayer\",\n \"value\",\n \"view\"\n ];\n const SYMBOL = {\n className: 'symbol',\n begin: '\\\\$' + regex.either(...PROFILE_VARS)\n };\n const NUMBER = {\n className: 'number',\n variants: [\n { begin: '\\\\b(0[bB][01]+)' },\n { begin: '\\\\b(0[oO][0-7]+)' },\n { begin: hljs.C_NUMBER_RE }\n ],\n relevance: 0\n };\n const SUBST = {\n className: 'subst',\n begin: '\\\\$\\\\{',\n end: '\\\\}',\n keywords: KEYWORDS,\n contains: [] // defined later\n };\n const TEMPLATE_STRING = {\n className: 'string',\n begin: '`',\n end: '`',\n contains: [\n hljs.BACKSLASH_ESCAPE,\n SUBST\n ]\n };\n SUBST.contains = [\n hljs.APOS_STRING_MODE,\n hljs.QUOTE_STRING_MODE,\n TEMPLATE_STRING,\n NUMBER,\n hljs.REGEXP_MODE\n ];\n const PARAMS_CONTAINS = SUBST.contains.concat([\n hljs.C_BLOCK_COMMENT_MODE,\n hljs.C_LINE_COMMENT_MODE\n ]);\n\n return {\n name: 'ArcGIS Arcade',\n case_insensitive: true,\n keywords: KEYWORDS,\n contains: [\n hljs.APOS_STRING_MODE,\n hljs.QUOTE_STRING_MODE,\n TEMPLATE_STRING,\n hljs.C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE,\n SYMBOL,\n NUMBER,\n { // object attr container\n begin: /[{,]\\s*/,\n relevance: 0,\n contains: [\n {\n begin: IDENT_RE + '\\\\s*:',\n returnBegin: true,\n relevance: 0,\n contains: [\n {\n className: 'attr',\n begin: IDENT_RE,\n relevance: 0\n }\n ]\n }\n ]\n },\n { // \"value\" container\n begin: '(' + hljs.RE_STARTERS_RE + '|\\\\b(return)\\\\b)\\\\s*',\n keywords: 'return',\n contains: [\n hljs.C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE,\n hljs.REGEXP_MODE,\n {\n className: 'function',\n begin: '(\\\\(.*?\\\\)|' + IDENT_RE + ')\\\\s*=>',\n returnBegin: true,\n end: '\\\\s*=>',\n contains: [\n {\n className: 'params',\n variants: [\n { begin: IDENT_RE },\n { begin: /\\(\\s*\\)/ },\n {\n begin: /\\(/,\n end: /\\)/,\n excludeBegin: true,\n excludeEnd: true,\n keywords: KEYWORDS,\n contains: PARAMS_CONTAINS\n }\n ]\n }\n ]\n }\n ],\n relevance: 0\n },\n {\n beginKeywords: 'function',\n end: /\\{/,\n excludeEnd: true,\n contains: [\n hljs.inherit(hljs.TITLE_MODE, {\n className: \"title.function\",\n begin: IDENT_RE\n }),\n {\n className: 'params',\n begin: /\\(/,\n end: /\\)/,\n excludeBegin: true,\n excludeEnd: true,\n contains: PARAMS_CONTAINS\n }\n ],\n illegal: /\\[|%/\n },\n { begin: /\\$[(.]/ }\n ],\n illegal: /#(?!!)/\n };\n}\n\nmodule.exports = arcade;\n", "/*\nLanguage: C++\nCategory: common, system\nWebsite: https://isocpp.org\n*/\n\n/** @type LanguageFn */\nfunction cPlusPlus(hljs) {\n const regex = hljs.regex;\n // added for historic reasons because `hljs.C_LINE_COMMENT_MODE` does\n // not include such support nor can we be sure all the grammars depending\n // on it would desire this behavior\n const C_LINE_COMMENT_MODE = hljs.COMMENT('//', '$', { contains: [ { begin: /\\\\\\n/ } ] });\n const DECLTYPE_AUTO_RE = 'decltype\\\\(auto\\\\)';\n const NAMESPACE_RE = '[a-zA-Z_]\\\\w*::';\n const TEMPLATE_ARGUMENT_RE = '<[^<>]+>';\n const FUNCTION_TYPE_RE = '(?!struct)('\n + DECLTYPE_AUTO_RE + '|'\n + regex.optional(NAMESPACE_RE)\n + '[a-zA-Z_]\\\\w*' + regex.optional(TEMPLATE_ARGUMENT_RE)\n + ')';\n\n const CPP_PRIMITIVE_TYPES = {\n className: 'type',\n begin: '\\\\b[a-z\\\\d_]*_t\\\\b'\n };\n\n // https://en.cppreference.com/w/cpp/language/escape\n // \\\\ \\x \\xFF \\u2837 \\u00323747 \\374\n const CHARACTER_ESCAPES = '\\\\\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\\\S)';\n const STRINGS = {\n className: 'string',\n variants: [\n {\n begin: '(u8?|U|L)?\"',\n end: '\"',\n illegal: '\\\\n',\n contains: [ hljs.BACKSLASH_ESCAPE ]\n },\n {\n begin: '(u8?|U|L)?\\'(' + CHARACTER_ESCAPES + '|.)',\n end: '\\'',\n illegal: '.'\n },\n hljs.END_SAME_AS_BEGIN({\n begin: /(?:u8?|U|L)?R\"([^()\\\\ ]{0,16})\\(/,\n end: /\\)([^()\\\\ ]{0,16})\"/\n })\n ]\n };\n\n const NUMBERS = {\n className: 'number',\n variants: [\n // Floating-point literal.\n { begin:\n \"[+-]?(?:\" // Leading sign.\n // Decimal.\n + \"(?:\"\n +\"[0-9](?:'?[0-9])*\\\\.(?:[0-9](?:'?[0-9])*)?\"\n + \"|\\\\.[0-9](?:'?[0-9])*\"\n + \")(?:[Ee][+-]?[0-9](?:'?[0-9])*)?\"\n + \"|[0-9](?:'?[0-9])*[Ee][+-]?[0-9](?:'?[0-9])*\"\n // Hexadecimal.\n + \"|0[Xx](?:\"\n +\"[0-9A-Fa-f](?:'?[0-9A-Fa-f])*(?:\\\\.(?:[0-9A-Fa-f](?:'?[0-9A-Fa-f])*)?)?\"\n + \"|\\\\.[0-9A-Fa-f](?:'?[0-9A-Fa-f])*\"\n + \")[Pp][+-]?[0-9](?:'?[0-9])*\"\n + \")(?:\" // Literal suffixes.\n + \"[Ff](?:16|32|64|128)?\"\n + \"|(BF|bf)16\"\n + \"|[Ll]\"\n + \"|\" // Literal suffix is optional.\n + \")\"\n },\n // Integer literal.\n { begin:\n \"[+-]?\\\\b(?:\" // Leading sign.\n + \"0[Bb][01](?:'?[01])*\" // Binary.\n + \"|0[Xx][0-9A-Fa-f](?:'?[0-9A-Fa-f])*\" // Hexadecimal.\n + \"|0(?:'?[0-7])*\" // Octal or just a lone zero.\n + \"|[1-9](?:'?[0-9])*\" // Decimal.\n + \")(?:\" // Literal suffixes.\n + \"[Uu](?:LL?|ll?)\"\n + \"|[Uu][Zz]?\"\n + \"|(?:LL?|ll?)[Uu]?\"\n + \"|[Zz][Uu]\"\n + \"|\" // Literal suffix is optional.\n + \")\"\n // Note: there are user-defined literal suffixes too, but perhaps having the custom suffix not part of the\n // literal highlight actually makes it stand out more.\n }\n ],\n relevance: 0\n };\n\n const PREPROCESSOR = {\n className: 'meta',\n begin: /#\\s*[a-z]+\\b/,\n end: /$/,\n keywords: { keyword:\n 'if else elif endif define undef warning error line '\n + 'pragma _Pragma ifdef ifndef include' },\n contains: [\n {\n begin: /\\\\\\n/,\n relevance: 0\n },\n hljs.inherit(STRINGS, { className: 'string' }),\n {\n className: 'string',\n begin: /<.*?>/\n },\n C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE\n ]\n };\n\n const TITLE_MODE = {\n className: 'title',\n begin: regex.optional(NAMESPACE_RE) + hljs.IDENT_RE,\n relevance: 0\n };\n\n const FUNCTION_TITLE = regex.optional(NAMESPACE_RE) + hljs.IDENT_RE + '\\\\s*\\\\(';\n\n // https://en.cppreference.com/w/cpp/keyword\n const RESERVED_KEYWORDS = [\n 'alignas',\n 'alignof',\n 'and',\n 'and_eq',\n 'asm',\n 'atomic_cancel',\n 'atomic_commit',\n 'atomic_noexcept',\n 'auto',\n 'bitand',\n 'bitor',\n 'break',\n 'case',\n 'catch',\n 'class',\n 'co_await',\n 'co_return',\n 'co_yield',\n 'compl',\n 'concept',\n 'const_cast|10',\n 'consteval',\n 'constexpr',\n 'constinit',\n 'continue',\n 'decltype',\n 'default',\n 'delete',\n 'do',\n 'dynamic_cast|10',\n 'else',\n 'enum',\n 'explicit',\n 'export',\n 'extern',\n 'false',\n 'final',\n 'for',\n 'friend',\n 'goto',\n 'if',\n 'import',\n 'inline',\n 'module',\n 'mutable',\n 'namespace',\n 'new',\n 'noexcept',\n 'not',\n 'not_eq',\n 'nullptr',\n 'operator',\n 'or',\n 'or_eq',\n 'override',\n 'private',\n 'protected',\n 'public',\n 'reflexpr',\n 'register',\n 'reinterpret_cast|10',\n 'requires',\n 'return',\n 'sizeof',\n 'static_assert',\n 'static_cast|10',\n 'struct',\n 'switch',\n 'synchronized',\n 'template',\n 'this',\n 'thread_local',\n 'throw',\n 'transaction_safe',\n 'transaction_safe_dynamic',\n 'true',\n 'try',\n 'typedef',\n 'typeid',\n 'typename',\n 'union',\n 'using',\n 'virtual',\n 'volatile',\n 'while',\n 'xor',\n 'xor_eq'\n ];\n\n // https://en.cppreference.com/w/cpp/keyword\n const RESERVED_TYPES = [\n 'bool',\n 'char',\n 'char16_t',\n 'char32_t',\n 'char8_t',\n 'double',\n 'float',\n 'int',\n 'long',\n 'short',\n 'void',\n 'wchar_t',\n 'unsigned',\n 'signed',\n 'const',\n 'static'\n ];\n\n const TYPE_HINTS = [\n 'any',\n 'auto_ptr',\n 'barrier',\n 'binary_semaphore',\n 'bitset',\n 'complex',\n 'condition_variable',\n 'condition_variable_any',\n 'counting_semaphore',\n 'deque',\n 'false_type',\n 'future',\n 'imaginary',\n 'initializer_list',\n 'istringstream',\n 'jthread',\n 'latch',\n 'lock_guard',\n 'multimap',\n 'multiset',\n 'mutex',\n 'optional',\n 'ostringstream',\n 'packaged_task',\n 'pair',\n 'promise',\n 'priority_queue',\n 'queue',\n 'recursive_mutex',\n 'recursive_timed_mutex',\n 'scoped_lock',\n 'set',\n 'shared_future',\n 'shared_lock',\n 'shared_mutex',\n 'shared_timed_mutex',\n 'shared_ptr',\n 'stack',\n 'string_view',\n 'stringstream',\n 'timed_mutex',\n 'thread',\n 'true_type',\n 'tuple',\n 'unique_lock',\n 'unique_ptr',\n 'unordered_map',\n 'unordered_multimap',\n 'unordered_multiset',\n 'unordered_set',\n 'variant',\n 'vector',\n 'weak_ptr',\n 'wstring',\n 'wstring_view'\n ];\n\n const FUNCTION_HINTS = [\n 'abort',\n 'abs',\n 'acos',\n 'apply',\n 'as_const',\n 'asin',\n 'atan',\n 'atan2',\n 'calloc',\n 'ceil',\n 'cerr',\n 'cin',\n 'clog',\n 'cos',\n 'cosh',\n 'cout',\n 'declval',\n 'endl',\n 'exchange',\n 'exit',\n 'exp',\n 'fabs',\n 'floor',\n 'fmod',\n 'forward',\n 'fprintf',\n 'fputs',\n 'free',\n 'frexp',\n 'fscanf',\n 'future',\n 'invoke',\n 'isalnum',\n 'isalpha',\n 'iscntrl',\n 'isdigit',\n 'isgraph',\n 'islower',\n 'isprint',\n 'ispunct',\n 'isspace',\n 'isupper',\n 'isxdigit',\n 'labs',\n 'launder',\n 'ldexp',\n 'log',\n 'log10',\n 'make_pair',\n 'make_shared',\n 'make_shared_for_overwrite',\n 'make_tuple',\n 'make_unique',\n 'malloc',\n 'memchr',\n 'memcmp',\n 'memcpy',\n 'memset',\n 'modf',\n 'move',\n 'pow',\n 'printf',\n 'putchar',\n 'puts',\n 'realloc',\n 'scanf',\n 'sin',\n 'sinh',\n 'snprintf',\n 'sprintf',\n 'sqrt',\n 'sscanf',\n 'std',\n 'stderr',\n 'stdin',\n 'stdout',\n 'strcat',\n 'strchr',\n 'strcmp',\n 'strcpy',\n 'strcspn',\n 'strlen',\n 'strncat',\n 'strncmp',\n 'strncpy',\n 'strpbrk',\n 'strrchr',\n 'strspn',\n 'strstr',\n 'swap',\n 'tan',\n 'tanh',\n 'terminate',\n 'to_underlying',\n 'tolower',\n 'toupper',\n 'vfprintf',\n 'visit',\n 'vprintf',\n 'vsprintf'\n ];\n\n const LITERALS = [\n 'NULL',\n 'false',\n 'nullopt',\n 'nullptr',\n 'true'\n ];\n\n // https://en.cppreference.com/w/cpp/keyword\n const BUILT_IN = [ '_Pragma' ];\n\n const CPP_KEYWORDS = {\n type: RESERVED_TYPES,\n keyword: RESERVED_KEYWORDS,\n literal: LITERALS,\n built_in: BUILT_IN,\n _type_hints: TYPE_HINTS\n };\n\n const FUNCTION_DISPATCH = {\n className: 'function.dispatch',\n relevance: 0,\n keywords: {\n // Only for relevance, not highlighting.\n _hint: FUNCTION_HINTS },\n begin: regex.concat(\n /\\b/,\n /(?!decltype)/,\n /(?!if)/,\n /(?!for)/,\n /(?!switch)/,\n /(?!while)/,\n hljs.IDENT_RE,\n regex.lookahead(/(<[^<>]+>|)\\s*\\(/))\n };\n\n const EXPRESSION_CONTAINS = [\n FUNCTION_DISPATCH,\n PREPROCESSOR,\n CPP_PRIMITIVE_TYPES,\n C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE,\n NUMBERS,\n STRINGS\n ];\n\n const EXPRESSION_CONTEXT = {\n // This mode covers expression context where we can't expect a function\n // definition and shouldn't highlight anything that looks like one:\n // `return some()`, `else if()`, `(x*sum(1, 2))`\n variants: [\n {\n begin: /=/,\n end: /;/\n },\n {\n begin: /\\(/,\n end: /\\)/\n },\n {\n beginKeywords: 'new throw return else',\n end: /;/\n }\n ],\n keywords: CPP_KEYWORDS,\n contains: EXPRESSION_CONTAINS.concat([\n {\n begin: /\\(/,\n end: /\\)/,\n keywords: CPP_KEYWORDS,\n contains: EXPRESSION_CONTAINS.concat([ 'self' ]),\n relevance: 0\n }\n ]),\n relevance: 0\n };\n\n const FUNCTION_DECLARATION = {\n className: 'function',\n begin: '(' + FUNCTION_TYPE_RE + '[\\\\*&\\\\s]+)+' + FUNCTION_TITLE,\n returnBegin: true,\n end: /[{;=]/,\n excludeEnd: true,\n keywords: CPP_KEYWORDS,\n illegal: /[^\\w\\s\\*&:<>.]/,\n contains: [\n { // to prevent it from being confused as the function title\n begin: DECLTYPE_AUTO_RE,\n keywords: CPP_KEYWORDS,\n relevance: 0\n },\n {\n begin: FUNCTION_TITLE,\n returnBegin: true,\n contains: [ TITLE_MODE ],\n relevance: 0\n },\n // needed because we do not have look-behind on the below rule\n // to prevent it from grabbing the final : in a :: pair\n {\n begin: /::/,\n relevance: 0\n },\n // initializers\n {\n begin: /:/,\n endsWithParent: true,\n contains: [\n STRINGS,\n NUMBERS\n ]\n },\n // allow for multiple declarations, e.g.:\n // extern void f(int), g(char);\n {\n relevance: 0,\n match: /,/\n },\n {\n className: 'params',\n begin: /\\(/,\n end: /\\)/,\n keywords: CPP_KEYWORDS,\n relevance: 0,\n contains: [\n C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE,\n STRINGS,\n NUMBERS,\n CPP_PRIMITIVE_TYPES,\n // Count matching parentheses.\n {\n begin: /\\(/,\n end: /\\)/,\n keywords: CPP_KEYWORDS,\n relevance: 0,\n contains: [\n 'self',\n C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE,\n STRINGS,\n NUMBERS,\n CPP_PRIMITIVE_TYPES\n ]\n }\n ]\n },\n CPP_PRIMITIVE_TYPES,\n C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE,\n PREPROCESSOR\n ]\n };\n\n return {\n name: 'C++',\n aliases: [\n 'cc',\n 'c++',\n 'h++',\n 'hpp',\n 'hh',\n 'hxx',\n 'cxx'\n ],\n keywords: CPP_KEYWORDS,\n illegal: ' rooms (9);`\n begin: '\\\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array|tuple|optional|variant|function)\\\\s*<(?!<)',\n end: '>',\n keywords: CPP_KEYWORDS,\n contains: [\n 'self',\n CPP_PRIMITIVE_TYPES\n ]\n },\n {\n begin: hljs.IDENT_RE + '::',\n keywords: CPP_KEYWORDS\n },\n {\n match: [\n // extra complexity to deal with `enum class` and `enum struct`\n /\\b(?:enum(?:\\s+(?:class|struct))?|class|struct|union)/,\n /\\s+/,\n /\\w+/\n ],\n className: {\n 1: 'keyword',\n 3: 'title.class'\n }\n }\n ])\n };\n}\n\n/*\nLanguage: Arduino\nAuthor: Stefania Mellai \nDescription: The Arduino\u00AE Language is a superset of C++. This rules are designed to highlight the Arduino\u00AE source code. For info about language see http://www.arduino.cc.\nWebsite: https://www.arduino.cc\nCategory: system\n*/\n\n\n/** @type LanguageFn */\nfunction arduino(hljs) {\n const ARDUINO_KW = {\n type: [\n \"boolean\",\n \"byte\",\n \"word\",\n \"String\"\n ],\n built_in: [\n \"KeyboardController\",\n \"MouseController\",\n \"SoftwareSerial\",\n \"EthernetServer\",\n \"EthernetClient\",\n \"LiquidCrystal\",\n \"RobotControl\",\n \"GSMVoiceCall\",\n \"EthernetUDP\",\n \"EsploraTFT\",\n \"HttpClient\",\n \"RobotMotor\",\n \"WiFiClient\",\n \"GSMScanner\",\n \"FileSystem\",\n \"Scheduler\",\n \"GSMServer\",\n \"YunClient\",\n \"YunServer\",\n \"IPAddress\",\n \"GSMClient\",\n \"GSMModem\",\n \"Keyboard\",\n \"Ethernet\",\n \"Console\",\n \"GSMBand\",\n \"Esplora\",\n \"Stepper\",\n \"Process\",\n \"WiFiUDP\",\n \"GSM_SMS\",\n \"Mailbox\",\n \"USBHost\",\n \"Firmata\",\n \"PImage\",\n \"Client\",\n \"Server\",\n \"GSMPIN\",\n \"FileIO\",\n \"Bridge\",\n \"Serial\",\n \"EEPROM\",\n \"Stream\",\n \"Mouse\",\n \"Audio\",\n \"Servo\",\n \"File\",\n \"Task\",\n \"GPRS\",\n \"WiFi\",\n \"Wire\",\n \"TFT\",\n \"GSM\",\n \"SPI\",\n \"SD\"\n ],\n _hints: [\n \"setup\",\n \"loop\",\n \"runShellCommandAsynchronously\",\n \"analogWriteResolution\",\n \"retrieveCallingNumber\",\n \"printFirmwareVersion\",\n \"analogReadResolution\",\n \"sendDigitalPortPair\",\n \"noListenOnLocalhost\",\n \"readJoystickButton\",\n \"setFirmwareVersion\",\n \"readJoystickSwitch\",\n \"scrollDisplayRight\",\n \"getVoiceCallStatus\",\n \"scrollDisplayLeft\",\n \"writeMicroseconds\",\n \"delayMicroseconds\",\n \"beginTransmission\",\n \"getSignalStrength\",\n \"runAsynchronously\",\n \"getAsynchronously\",\n \"listenOnLocalhost\",\n \"getCurrentCarrier\",\n \"readAccelerometer\",\n \"messageAvailable\",\n \"sendDigitalPorts\",\n \"lineFollowConfig\",\n \"countryNameWrite\",\n \"runShellCommand\",\n \"readStringUntil\",\n \"rewindDirectory\",\n \"readTemperature\",\n \"setClockDivider\",\n \"readLightSensor\",\n \"endTransmission\",\n \"analogReference\",\n \"detachInterrupt\",\n \"countryNameRead\",\n \"attachInterrupt\",\n \"encryptionType\",\n \"readBytesUntil\",\n \"robotNameWrite\",\n \"readMicrophone\",\n \"robotNameRead\",\n \"cityNameWrite\",\n \"userNameWrite\",\n \"readJoystickY\",\n \"readJoystickX\",\n \"mouseReleased\",\n \"openNextFile\",\n \"scanNetworks\",\n \"noInterrupts\",\n \"digitalWrite\",\n \"beginSpeaker\",\n \"mousePressed\",\n \"isActionDone\",\n \"mouseDragged\",\n \"displayLogos\",\n \"noAutoscroll\",\n \"addParameter\",\n \"remoteNumber\",\n \"getModifiers\",\n \"keyboardRead\",\n \"userNameRead\",\n \"waitContinue\",\n \"processInput\",\n \"parseCommand\",\n \"printVersion\",\n \"readNetworks\",\n \"writeMessage\",\n \"blinkVersion\",\n \"cityNameRead\",\n \"readMessage\",\n \"setDataMode\",\n \"parsePacket\",\n \"isListening\",\n \"setBitOrder\",\n \"beginPacket\",\n \"isDirectory\",\n \"motorsWrite\",\n \"drawCompass\",\n \"digitalRead\",\n \"clearScreen\",\n \"serialEvent\",\n \"rightToLeft\",\n \"setTextSize\",\n \"leftToRight\",\n \"requestFrom\",\n \"keyReleased\",\n \"compassRead\",\n \"analogWrite\",\n \"interrupts\",\n \"WiFiServer\",\n \"disconnect\",\n \"playMelody\",\n \"parseFloat\",\n \"autoscroll\",\n \"getPINUsed\",\n \"setPINUsed\",\n \"setTimeout\",\n \"sendAnalog\",\n \"readSlider\",\n \"analogRead\",\n \"beginWrite\",\n \"createChar\",\n \"motorsStop\",\n \"keyPressed\",\n \"tempoWrite\",\n \"readButton\",\n \"subnetMask\",\n \"debugPrint\",\n \"macAddress\",\n \"writeGreen\",\n \"randomSeed\",\n \"attachGPRS\",\n \"readString\",\n \"sendString\",\n \"remotePort\",\n \"releaseAll\",\n \"mouseMoved\",\n \"background\",\n \"getXChange\",\n \"getYChange\",\n \"answerCall\",\n \"getResult\",\n \"voiceCall\",\n \"endPacket\",\n \"constrain\",\n \"getSocket\",\n \"writeJSON\",\n \"getButton\",\n \"available\",\n \"connected\",\n \"findUntil\",\n \"readBytes\",\n \"exitValue\",\n \"readGreen\",\n \"writeBlue\",\n \"startLoop\",\n \"IPAddress\",\n \"isPressed\",\n \"sendSysex\",\n \"pauseMode\",\n \"gatewayIP\",\n \"setCursor\",\n \"getOemKey\",\n \"tuneWrite\",\n \"noDisplay\",\n \"loadImage\",\n \"switchPIN\",\n \"onRequest\",\n \"onReceive\",\n \"changePIN\",\n \"playFile\",\n \"noBuffer\",\n \"parseInt\",\n \"overflow\",\n \"checkPIN\",\n \"knobRead\",\n \"beginTFT\",\n \"bitClear\",\n \"updateIR\",\n \"bitWrite\",\n \"position\",\n \"writeRGB\",\n \"highByte\",\n \"writeRed\",\n \"setSpeed\",\n \"readBlue\",\n \"noStroke\",\n \"remoteIP\",\n \"transfer\",\n \"shutdown\",\n \"hangCall\",\n \"beginSMS\",\n \"endWrite\",\n \"attached\",\n \"maintain\",\n \"noCursor\",\n \"checkReg\",\n \"checkPUK\",\n \"shiftOut\",\n \"isValid\",\n \"shiftIn\",\n \"pulseIn\",\n \"connect\",\n \"println\",\n \"localIP\",\n \"pinMode\",\n \"getIMEI\",\n \"display\",\n \"noBlink\",\n \"process\",\n \"getBand\",\n \"running\",\n \"beginSD\",\n \"drawBMP\",\n \"lowByte\",\n \"setBand\",\n \"release\",\n \"bitRead\",\n \"prepare\",\n \"pointTo\",\n \"readRed\",\n \"setMode\",\n \"noFill\",\n \"remove\",\n \"listen\",\n \"stroke\",\n \"detach\",\n \"attach\",\n \"noTone\",\n \"exists\",\n \"buffer\",\n \"height\",\n \"bitSet\",\n \"circle\",\n \"config\",\n \"cursor\",\n \"random\",\n \"IRread\",\n \"setDNS\",\n \"endSMS\",\n \"getKey\",\n \"micros\",\n \"millis\",\n \"begin\",\n \"print\",\n \"write\",\n \"ready\",\n \"flush\",\n \"width\",\n \"isPIN\",\n \"blink\",\n \"clear\",\n \"press\",\n \"mkdir\",\n \"rmdir\",\n \"close\",\n \"point\",\n \"yield\",\n \"image\",\n \"BSSID\",\n \"click\",\n \"delay\",\n \"read\",\n \"text\",\n \"move\",\n \"peek\",\n \"beep\",\n \"rect\",\n \"line\",\n \"open\",\n \"seek\",\n \"fill\",\n \"size\",\n \"turn\",\n \"stop\",\n \"home\",\n \"find\",\n \"step\",\n \"tone\",\n \"sqrt\",\n \"RSSI\",\n \"SSID\",\n \"end\",\n \"bit\",\n \"tan\",\n \"cos\",\n \"sin\",\n \"pow\",\n \"map\",\n \"abs\",\n \"max\",\n \"min\",\n \"get\",\n \"run\",\n \"put\"\n ],\n literal: [\n \"DIGITAL_MESSAGE\",\n \"FIRMATA_STRING\",\n \"ANALOG_MESSAGE\",\n \"REPORT_DIGITAL\",\n \"REPORT_ANALOG\",\n \"INPUT_PULLUP\",\n \"SET_PIN_MODE\",\n \"INTERNAL2V56\",\n \"SYSTEM_RESET\",\n \"LED_BUILTIN\",\n \"INTERNAL1V1\",\n \"SYSEX_START\",\n \"INTERNAL\",\n \"EXTERNAL\",\n \"DEFAULT\",\n \"OUTPUT\",\n \"INPUT\",\n \"HIGH\",\n \"LOW\"\n ]\n };\n\n const ARDUINO = cPlusPlus(hljs);\n\n const kws = /** @type {Record} */ (ARDUINO.keywords);\n\n kws.type = [\n ...kws.type,\n ...ARDUINO_KW.type\n ];\n kws.literal = [\n ...kws.literal,\n ...ARDUINO_KW.literal\n ];\n kws.built_in = [\n ...kws.built_in,\n ...ARDUINO_KW.built_in\n ];\n kws._hints = ARDUINO_KW._hints;\n\n ARDUINO.name = 'Arduino';\n ARDUINO.aliases = [ 'ino' ];\n ARDUINO.supersetOf = \"cpp\";\n\n return ARDUINO;\n}\n\nmodule.exports = arduino;\n", "/*\nLanguage: ARM Assembly\nAuthor: Dan Panzarella \nDescription: ARM Assembly including Thumb and Thumb2 instructions\nCategory: assembler\n*/\n\n/** @type LanguageFn */\nfunction armasm(hljs) {\n // local labels: %?[FB]?[AT]?\\d{1,2}\\w+\n\n const COMMENT = { variants: [\n hljs.COMMENT('^[ \\\\t]*(?=#)', '$', {\n relevance: 0,\n excludeBegin: true\n }),\n hljs.COMMENT('[;@]', '$', { relevance: 0 }),\n hljs.C_LINE_COMMENT_MODE,\n hljs.C_BLOCK_COMMENT_MODE\n ] };\n\n return {\n name: 'ARM Assembly',\n case_insensitive: true,\n aliases: [ 'arm' ],\n keywords: {\n $pattern: '\\\\.?' + hljs.IDENT_RE,\n meta:\n // GNU preprocs\n '.2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg '\n // ARM directives\n + 'ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ',\n built_in:\n 'r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 ' // standard registers\n + 'w0 w1 w2 w3 w4 w5 w6 w7 w8 w9 w10 w11 w12 w13 w14 w15 ' // 32 bit ARMv8 registers\n + 'w16 w17 w18 w19 w20 w21 w22 w23 w24 w25 w26 w27 w28 w29 w30 '\n + 'x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 x11 x12 x13 x14 x15 ' // 64 bit ARMv8 registers\n + 'x16 x17 x18 x19 x20 x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 '\n + 'pc lr sp ip sl sb fp ' // typical regs plus backward compatibility\n + 'a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 ' // more regs and fp\n + 'p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 ' // coprocessor regs\n + 'c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 ' // more coproc\n + 'q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 ' // advanced SIMD NEON regs\n\n // program status registers\n + 'cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf '\n + 'spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf '\n\n // NEON and VFP registers\n + 's0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 '\n + 's16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 '\n + 'd0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 '\n + 'd16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 '\n\n + '{PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @'\n },\n contains: [\n {\n className: 'keyword',\n begin: '\\\\b(' // mnemonics\n + 'adc|'\n + '(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|'\n + 'and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|'\n + 'bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|'\n + 'setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|'\n + 'ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|'\n + 'mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|'\n + 'mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|'\n + 'mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|'\n + 'rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|'\n + 'stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|'\n + '[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|'\n + 'wfe|wfi|yield'\n + ')'\n + '(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?' // condition codes\n + '[sptrx]?' // legal postfixes\n + '(?=\\\\s)' // followed by space\n },\n COMMENT,\n hljs.QUOTE_STRING_MODE,\n {\n className: 'string',\n begin: '\\'',\n end: '[^\\\\\\\\]\\'',\n relevance: 0\n },\n {\n className: 'title',\n begin: '\\\\|',\n end: '\\\\|',\n illegal: '\\\\n',\n relevance: 0\n },\n {\n className: 'number',\n variants: [\n { // hex\n begin: '[#$=]?0x[0-9a-f]+' },\n { // bin\n begin: '[#$=]?0b[01]+' },\n { // literal\n begin: '[#$=]\\\\d+' },\n { // bare number\n begin: '\\\\b\\\\d+' }\n ],\n relevance: 0\n },\n {\n className: 'symbol',\n variants: [\n { // GNU ARM syntax\n begin: '^[ \\\\t]*[a-z_\\\\.\\\\$][a-z0-9_\\\\.\\\\$]+:' },\n { // ARM syntax\n begin: '^[a-z_\\\\.\\\\$][a-z0-9_\\\\.\\\\$]+' },\n { // label reference\n begin: '[=#]\\\\w+' }\n ],\n relevance: 0\n }\n ]\n };\n}\n\nmodule.exports = armasm;\n", "/*\nLanguage: HTML, XML\nWebsite: https://www.w3.org/XML/\nCategory: common, web\nAudit: 2020\n*/\n\n/** @type LanguageFn */\nfunction xml(hljs) {\n const regex = hljs.regex;\n // XML names can have the following additional letters: https://www.w3.org/TR/xml/#NT-NameChar\n // OTHER_NAME_CHARS = /[:\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]/;\n // Element names start with NAME_START_CHAR followed by optional other Unicode letters, ASCII digits, hyphens, underscores, and periods\n // const TAG_NAME_RE = regex.concat(/[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]/, regex.optional(/[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*:/), /[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*/);;\n // const XML_IDENT_RE = /[A-Z_a-z:\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]+/;\n // const TAG_NAME_RE = regex.concat(/[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD]/, regex.optional(/[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*:/), /[A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040]*/);\n // however, to cater for performance and more Unicode support rely simply on the Unicode letter class\n const TAG_NAME_RE = regex.concat(/[\\p{L}_]/u, regex.optional(/[\\p{L}0-9_.-]*:/u), /[\\p{L}0-9_.-]*/u);\n const XML_IDENT_RE = /[\\p{L}0-9._:-]+/u;\n const XML_ENTITIES = {\n className: 'symbol',\n begin: /&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/\n };\n const XML_META_KEYWORDS = {\n begin: /\\s/,\n contains: [\n {\n className: 'keyword',\n begin: /#?[a-z_][a-z1-9_-]+/,\n illegal: /\\n/\n }\n ]\n };\n const XML_META_PAR_KEYWORDS = hljs.inherit(XML_META_KEYWORDS, {\n begin: /\\(/,\n end: /\\)/\n });\n const APOS_META_STRING_MODE = hljs.inherit(hljs.APOS_STRING_MODE, { className: 'string' });\n const QUOTE_META_STRING_MODE = hljs.inherit(hljs.QUOTE_STRING_MODE, { className: 'string' });\n const TAG_INTERNALS = {\n endsWithParent: true,\n illegal: /`]+/ }\n ]\n }\n ]\n }\n ]\n };\n return {\n name: 'HTML, XML',\n aliases: [\n 'html',\n 'xhtml',\n 'rss',\n 'atom',\n 'xjb',\n 'xsd',\n 'xsl',\n 'plist',\n 'wsf',\n 'svg'\n ],\n case_insensitive: true,\n unicodeRegex: true,\n contains: [\n {\n className: 'meta',\n begin: //,\n relevance: 10,\n contains: [\n XML_META_KEYWORDS,\n QUOTE_META_STRING_MODE,\n APOS_META_STRING_MODE,\n XML_META_PAR_KEYWORDS,\n {\n begin: /\\[/,\n end: /\\]/,\n contains: [\n {\n className: 'meta',\n begin: //,\n contains: [\n XML_META_KEYWORDS,\n XML_META_PAR_KEYWORDS,\n QUOTE_META_STRING_MODE,\n APOS_META_STRING_MODE\n ]\n }\n ]\n }\n ]\n },\n hljs.COMMENT(\n //,\n { relevance: 10 }\n ),\n {\n begin: //,\n relevance: 10\n },\n XML_ENTITIES,\n // xml processing instructions\n {\n className: 'meta',\n end: /\\?>/,\n variants: [\n {\n begin: /<\\?xml/,\n relevance: 10,\n contains: [\n QUOTE_META_STRING_MODE\n ]\n },\n {\n begin: /<\\?[a-z][a-z0-9]+/,\n }\n ]\n\n },\n {\n className: 'tag',\n /*\n The lookahead pattern (?=...) ensures that 'begin' only matches\n ')/,\n end: />/,\n keywords: { name: 'style' },\n contains: [ TAG_INTERNALS ],\n starts: {\n end: /<\\/style>/,\n returnEnd: true,\n subLanguage: [\n 'css',\n 'xml'\n ]\n }\n },\n {\n className: 'tag',\n // See the comment in the \n\n`;\n const cssHtml = `\n\n`;\n\n const scripts = `\n\n\n\n\n`;\n const diagramsDiv = `\n
\n`;\n const serializedGrammar = `\n\n`;\n\n const initLogic = `\n\n`;\n return (\n header + cssHtml + scripts + diagramsDiv + serializedGrammar + initLogic\n );\n}\n", "/* istanbul ignore file - tricky to import some things from this module during testing */\n\n// semantic version\nexport { VERSION } from \"./version.js\";\n\nexport {\n CstParser,\n EmbeddedActionsParser,\n ParserDefinitionErrorType,\n EMPTY_ALT,\n} from \"./parse/parser/parser.js\";\n\nexport { Lexer, LexerDefinitionErrorType } from \"./scan/lexer_public.js\";\n\n// Tokens utilities\nexport {\n createToken,\n createTokenInstance,\n EOF,\n tokenLabel,\n tokenMatcher,\n tokenName,\n} from \"./scan/tokens_public.js\";\n\n// Lookahead\n\nexport { getLookaheadPaths } from \"./parse/grammar/lookahead.js\";\n\nexport { LLkLookaheadStrategy } from \"./parse/grammar/llk_lookahead.js\";\n\n// Other Utilities\n\nexport { defaultParserErrorProvider } from \"./parse/errors_public.js\";\n\nexport {\n EarlyExitException,\n isRecognitionException,\n MismatchedTokenException,\n NotAllInputParsedException,\n NoViableAltException,\n} from \"./parse/exceptions_public.js\";\n\nexport { defaultLexerErrorProvider } from \"./scan/lexer_errors_public.js\";\n\n// grammar reflection API\nexport {\n Alternation,\n Alternative,\n NonTerminal,\n Option,\n Repetition,\n RepetitionMandatory,\n RepetitionMandatoryWithSeparator,\n RepetitionWithSeparator,\n Rule,\n Terminal,\n} from \"@chevrotain/gast\";\n\n// GAST Utilities\n\nexport {\n serializeGrammar,\n serializeProduction,\n GAstVisitor,\n} from \"@chevrotain/gast\";\n\nexport { generateCstDts } from \"@chevrotain/cst-dts-gen\";\n\n/* istanbul ignore next */\nexport function clearCache() {\n console.warn(\n \"The clearCache function was 'soft' removed from the Chevrotain API.\" +\n \"\\n\\t It performs no action other than printing this message.\" +\n \"\\n\\t Please avoid using it as it will be completely removed in the future\",\n );\n}\n\nexport { createSyntaxDiagramsCode } from \"./diagrams/render_public.js\";\n\nexport class Parser {\n constructor() {\n throw new Error(\n \"The Parser class has been deprecated, use CstParser or EmbeddedActionsParser instead.\\t\\n\" +\n \"See: https://chevrotain.io/docs/changes/BREAKING_CHANGES.html#_7-0-0\",\n );\n }\n}\n", "/******************************************************************************\r\n * Copyright 2022 TypeFox GmbH\r\n * This program and the accompanying materials are made available under the\r\n * terms of the MIT License, which is available in the project root.\r\n ******************************************************************************/\r\n\r\nimport map from \"lodash-es/map.js\"\r\nimport filter from \"lodash-es/filter.js\"\r\nimport {\r\n IProduction,\r\n IProductionWithOccurrence,\r\n TokenType,\r\n Alternation,\r\n NonTerminal,\r\n Rule,\r\n Option,\r\n RepetitionMandatory,\r\n Repetition,\r\n Terminal,\r\n Alternative,\r\n RepetitionWithSeparator,\r\n RepetitionMandatoryWithSeparator,\r\n LookaheadProductionType\r\n} from \"chevrotain\"\r\n\r\nexport function buildATNKey(rule: Rule, type: LookaheadProductionType, occurrence: number): string {\r\n return `${rule.name}_${type}_${occurrence}`;\r\n}\r\n\r\nexport interface ATN {\r\n decisionMap: Record\r\n states: ATNState[]\r\n decisionStates: DecisionState[]\r\n ruleToStartState: Map\r\n ruleToStopState: Map\r\n}\r\n\r\nexport const ATN_INVALID_TYPE = 0\r\nexport const ATN_BASIC = 1\r\nexport const ATN_RULE_START = 2\r\nexport const ATN_PLUS_BLOCK_START = 4\r\nexport const ATN_STAR_BLOCK_START = 5\r\n// Currently unused as the ATN is not used for lexing\r\nexport const ATN_TOKEN_START = 6\r\nexport const ATN_RULE_STOP = 7\r\nexport const ATN_BLOCK_END = 8\r\nexport const ATN_STAR_LOOP_BACK = 9\r\nexport const ATN_STAR_LOOP_ENTRY = 10\r\nexport const ATN_PLUS_LOOP_BACK = 11\r\nexport const ATN_LOOP_END = 12\r\n\r\nexport type ATNState =\r\n | BasicState\r\n | BasicBlockStartState\r\n | PlusBlockStartState\r\n | PlusLoopbackState\r\n | StarBlockStartState\r\n | StarLoopbackState\r\n | StarLoopEntryState\r\n | BlockEndState\r\n | RuleStartState\r\n | RuleStopState\r\n | LoopEndState\r\n\r\nexport interface ATNBaseState {\r\n atn: ATN\r\n production: IProductionWithOccurrence\r\n stateNumber: number\r\n rule: Rule\r\n epsilonOnlyTransitions: boolean\r\n transitions: Transition[]\r\n nextTokenWithinRule: number[]\r\n}\r\n\r\nexport interface BasicState extends ATNBaseState {\r\n type: typeof ATN_BASIC\r\n}\r\n\r\nexport interface BlockStartState extends DecisionState {\r\n end: BlockEndState\r\n}\r\n\r\nexport interface BasicBlockStartState extends BlockStartState {\r\n type: typeof ATN_BASIC\r\n}\r\n\r\nexport interface PlusBlockStartState extends BlockStartState {\r\n loopback: PlusLoopbackState\r\n type: typeof ATN_PLUS_BLOCK_START\r\n}\r\n\r\nexport interface PlusLoopbackState extends DecisionState {\r\n type: typeof ATN_PLUS_LOOP_BACK\r\n}\r\n\r\nexport interface StarBlockStartState extends BlockStartState {\r\n type: typeof ATN_STAR_BLOCK_START\r\n}\r\n\r\nexport interface StarLoopbackState extends ATNBaseState {\r\n type: typeof ATN_STAR_LOOP_BACK\r\n}\r\n\r\nexport interface StarLoopEntryState extends DecisionState {\r\n loopback: StarLoopbackState\r\n type: typeof ATN_STAR_LOOP_ENTRY\r\n}\r\n\r\nexport interface BlockEndState extends ATNBaseState {\r\n start: BlockStartState\r\n type: typeof ATN_BLOCK_END\r\n}\r\n\r\nexport interface DecisionState extends ATNBaseState {\r\n decision: number\r\n}\r\n\r\nexport interface LoopEndState extends ATNBaseState {\r\n loopback: ATNState\r\n type: typeof ATN_LOOP_END\r\n}\r\n\r\nexport interface RuleStartState extends ATNBaseState {\r\n stop: RuleStopState\r\n type: typeof ATN_RULE_START\r\n}\r\n\r\nexport interface RuleStopState extends ATNBaseState {\r\n type: typeof ATN_RULE_STOP\r\n}\r\n\r\nexport interface Transition {\r\n target: ATNState\r\n isEpsilon(): boolean\r\n}\r\n\r\nexport abstract class AbstractTransition implements Transition {\r\n target: ATNState\r\n\r\n constructor(target: ATNState) {\r\n this.target = target\r\n }\r\n\r\n isEpsilon() {\r\n return false\r\n }\r\n}\r\n\r\nexport class AtomTransition extends AbstractTransition {\r\n tokenType: TokenType\r\n\r\n constructor(target: ATNState, tokenType: TokenType) {\r\n super(target)\r\n this.tokenType = tokenType\r\n }\r\n}\r\n\r\nexport class EpsilonTransition extends AbstractTransition {\r\n constructor(target: ATNState) {\r\n super(target)\r\n }\r\n\r\n isEpsilon() {\r\n return true\r\n }\r\n}\r\n\r\nexport class RuleTransition extends AbstractTransition {\r\n rule: Rule\r\n followState: ATNState\r\n\r\n constructor(ruleStart: RuleStartState, rule: Rule, followState: ATNState) {\r\n super(ruleStart)\r\n this.rule = rule\r\n this.followState = followState\r\n }\r\n\r\n isEpsilon() {\r\n return true\r\n }\r\n}\r\n\r\ninterface ATNHandle {\r\n left: ATNState\r\n right: ATNState\r\n}\r\n\r\nexport function createATN(rules: Rule[]): ATN {\r\n const atn: ATN = {\r\n decisionMap: {},\r\n decisionStates: [],\r\n ruleToStartState: new Map(),\r\n ruleToStopState: new Map(),\r\n states: []\r\n }\r\n createRuleStartAndStopATNStates(atn, rules)\r\n const ruleLength = rules.length\r\n for (let i = 0; i < ruleLength; i++) {\r\n const rule = rules[i]\r\n const ruleBlock = block(atn, rule, rule)\r\n if (ruleBlock === undefined) {\r\n continue\r\n }\r\n buildRuleHandle(atn, rule, ruleBlock)\r\n }\r\n return atn\r\n}\r\n\r\nfunction createRuleStartAndStopATNStates(atn: ATN, rules: Rule[]): void {\r\n const ruleLength = rules.length\r\n for (let i = 0; i < ruleLength; i++) {\r\n const rule = rules[i]\r\n const start = newState(atn, rule, undefined, {\r\n type: ATN_RULE_START\r\n })\r\n const stop = newState(atn, rule, undefined, {\r\n type: ATN_RULE_STOP\r\n })\r\n start.stop = stop\r\n atn.ruleToStartState.set(rule, start)\r\n atn.ruleToStopState.set(rule, stop)\r\n }\r\n}\r\n\r\nfunction atom(\r\n atn: ATN,\r\n rule: Rule,\r\n production: IProduction\r\n): ATNHandle | undefined {\r\n if (production instanceof Terminal) {\r\n return tokenRef(atn, rule, production.terminalType, production)\r\n } else if (production instanceof NonTerminal) {\r\n return ruleRef(atn, rule, production)\r\n } else if (production instanceof Alternation) {\r\n return alternation(atn, rule, production)\r\n } else if (production instanceof Option) {\r\n return option(atn, rule, production)\r\n } else if (production instanceof Repetition) {\r\n return repetition(atn, rule, production)\r\n } else if (production instanceof RepetitionWithSeparator) {\r\n return repetitionSep(atn, rule, production)\r\n } else if (production instanceof RepetitionMandatory) {\r\n return repetitionMandatory(atn, rule, production)\r\n } else if (production instanceof RepetitionMandatoryWithSeparator) {\r\n return repetitionMandatorySep(atn, rule, production)\r\n } else {\r\n return block(atn, rule, production as Alternative)\r\n }\r\n}\r\n\r\nfunction repetition(atn: ATN, rule: Rule, repetition: Repetition): ATNHandle {\r\n const starState = newState(atn, rule, repetition, {\r\n type: ATN_STAR_BLOCK_START\r\n })\r\n defineDecisionState(atn, starState)\r\n const handle = makeAlts(\r\n atn,\r\n rule,\r\n starState,\r\n repetition,\r\n block(atn, rule, repetition)\r\n )\r\n return star(atn, rule, repetition, handle)\r\n}\r\n\r\nfunction repetitionSep(\r\n atn: ATN,\r\n rule: Rule,\r\n repetition: RepetitionWithSeparator\r\n): ATNHandle {\r\n const starState = newState(atn, rule, repetition, {\r\n type: ATN_STAR_BLOCK_START\r\n })\r\n defineDecisionState(atn, starState)\r\n const handle = makeAlts(\r\n atn,\r\n rule,\r\n starState,\r\n repetition,\r\n block(atn, rule, repetition)\r\n )\r\n const sep = tokenRef(atn, rule, repetition.separator, repetition)\r\n return star(atn, rule, repetition, handle, sep)\r\n}\r\n\r\nfunction repetitionMandatory(\r\n atn: ATN,\r\n rule: Rule,\r\n repetition: RepetitionMandatory\r\n): ATNHandle {\r\n const plusState = newState(atn, rule, repetition, {\r\n type: ATN_PLUS_BLOCK_START\r\n })\r\n defineDecisionState(atn, plusState)\r\n const handle = makeAlts(\r\n atn,\r\n rule,\r\n plusState,\r\n repetition,\r\n block(atn, rule, repetition)\r\n )\r\n return plus(atn, rule, repetition, handle)\r\n}\r\n\r\nfunction repetitionMandatorySep(\r\n atn: ATN,\r\n rule: Rule,\r\n repetition: RepetitionMandatoryWithSeparator\r\n): ATNHandle {\r\n const plusState = newState(atn, rule, repetition, {\r\n type: ATN_PLUS_BLOCK_START\r\n })\r\n defineDecisionState(atn, plusState)\r\n const handle = makeAlts(\r\n atn,\r\n rule,\r\n plusState,\r\n repetition,\r\n block(atn, rule, repetition)\r\n )\r\n const sep = tokenRef(atn, rule, repetition.separator, repetition)\r\n return plus(atn, rule, repetition, handle, sep)\r\n}\r\n\r\nfunction alternation(\r\n atn: ATN,\r\n rule: Rule,\r\n alternation: Alternation\r\n): ATNHandle {\r\n const start = newState(atn, rule, alternation, {\r\n type: ATN_BASIC\r\n })\r\n defineDecisionState(atn, start)\r\n const alts = map(alternation.definition, (e) => atom(atn, rule, e))\r\n const handle = makeAlts(atn, rule, start, alternation, ...alts)\r\n return handle\r\n}\r\n\r\nfunction option(atn: ATN, rule: Rule, option: Option): ATNHandle {\r\n const start = newState(atn, rule, option, {\r\n type: ATN_BASIC\r\n })\r\n defineDecisionState(atn, start)\r\n const handle = makeAlts(atn, rule, start, option, block(atn, rule, option))\r\n return optional(atn, rule, option, handle)\r\n}\r\n\r\nfunction block(\r\n atn: ATN,\r\n rule: Rule,\r\n block: { definition: IProduction[] }\r\n): ATNHandle | undefined {\r\n const handles = filter(\r\n map(block.definition, (e) => atom(atn, rule, e)),\r\n (e) => e !== undefined\r\n ) as ATNHandle[]\r\n if (handles.length === 1) {\r\n return handles[0]\r\n } else if (handles.length === 0) {\r\n return undefined\r\n } else {\r\n return makeBlock(atn, handles)\r\n }\r\n}\r\n\r\nfunction plus(\r\n atn: ATN,\r\n rule: Rule,\r\n plus: IProductionWithOccurrence,\r\n handle: ATNHandle,\r\n sep?: ATNHandle\r\n): ATNHandle {\r\n const blkStart = handle.left as PlusBlockStartState\r\n const blkEnd = handle.right\r\n\r\n const loop = newState(atn, rule, plus, {\r\n type: ATN_PLUS_LOOP_BACK\r\n })\r\n defineDecisionState(atn, loop)\r\n const end = newState(atn, rule, plus, {\r\n type: ATN_LOOP_END\r\n })\r\n blkStart.loopback = loop\r\n end.loopback = loop\r\n atn.decisionMap[buildATNKey(rule, sep ? 'RepetitionMandatoryWithSeparator' : 'RepetitionMandatory', plus.idx)] = loop;\r\n epsilon(blkEnd, loop) // block can see loop back\r\n\r\n // Depending on whether we have a separator we put the exit transition at index 1 or 0\r\n // This influences the chosen option in the lookahead DFA\r\n if (sep === undefined) {\r\n epsilon(loop, blkStart) // loop back to start\r\n epsilon(loop, end) // exit\r\n } else {\r\n epsilon(loop, end) // exit\r\n // loop back to start with separator\r\n epsilon(loop, sep.left)\r\n epsilon(sep.right, blkStart)\r\n }\r\n\r\n return {\r\n left: blkStart,\r\n right: end\r\n }\r\n}\r\n\r\nfunction star(\r\n atn: ATN,\r\n rule: Rule,\r\n star: IProductionWithOccurrence,\r\n handle: ATNHandle,\r\n sep?: ATNHandle\r\n): ATNHandle {\r\n const start = handle.left\r\n const end = handle.right\r\n\r\n const entry = newState(atn, rule, star, {\r\n type: ATN_STAR_LOOP_ENTRY\r\n })\r\n defineDecisionState(atn, entry)\r\n const loopEnd = newState(atn, rule, star, {\r\n type: ATN_LOOP_END\r\n })\r\n const loop = newState(atn, rule, star, {\r\n type: ATN_STAR_LOOP_BACK\r\n })\r\n entry.loopback = loop\r\n loopEnd.loopback = loop\r\n\r\n epsilon(entry, start) // loop enter edge (alt 2)\r\n epsilon(entry, loopEnd) // bypass loop edge (alt 1)\r\n epsilon(end, loop) // block end hits loop back\r\n\r\n if (sep !== undefined) {\r\n epsilon(loop, loopEnd) // end loop\r\n // loop back to start of handle using separator\r\n epsilon(loop, sep.left)\r\n epsilon(sep.right, start)\r\n } else {\r\n epsilon(loop, entry) // loop back to entry/exit decision\r\n }\r\n\r\n atn.decisionMap[buildATNKey(rule, sep ? 'RepetitionWithSeparator' : 'Repetition', star.idx)] = entry;\r\n return {\r\n left: entry,\r\n right: loopEnd\r\n }\r\n}\r\n\r\nfunction optional(atn: ATN, rule: Rule, optional: Option, handle: ATNHandle): ATNHandle {\r\n const start = handle.left as DecisionState\r\n const end = handle.right\r\n\r\n epsilon(start, end)\r\n\r\n atn.decisionMap[buildATNKey(rule, 'Option', optional.idx)] = start;\r\n return handle\r\n}\r\n\r\nfunction defineDecisionState(atn: ATN, state: DecisionState): number {\r\n atn.decisionStates.push(state)\r\n state.decision = atn.decisionStates.length - 1\r\n return state.decision\r\n}\r\n\r\nfunction makeAlts(\r\n atn: ATN,\r\n rule: Rule,\r\n start: BlockStartState,\r\n production: IProductionWithOccurrence,\r\n ...alts: (ATNHandle | undefined)[]\r\n): ATNHandle {\r\n const end = newState(atn, rule, production, {\r\n type: ATN_BLOCK_END,\r\n start\r\n })\r\n start.end = end\r\n for (const alt of alts) {\r\n if (alt !== undefined) {\r\n // hook alts up to decision block\r\n epsilon(start, alt.left)\r\n epsilon(alt.right, end)\r\n } else {\r\n epsilon(start, end)\r\n }\r\n }\r\n\r\n const handle: ATNHandle = {\r\n left: start as ATNState,\r\n right: end\r\n }\r\n atn.decisionMap[buildATNKey(rule, getProdType(production), production.idx)] = start\r\n return handle\r\n}\r\n\r\nfunction getProdType(production: IProduction): LookaheadProductionType {\r\n if (production instanceof Alternation) {\r\n return 'Alternation';\r\n } else if (production instanceof Option) {\r\n return 'Option';\r\n } else if (production instanceof Repetition) {\r\n return 'Repetition';\r\n } else if (production instanceof RepetitionWithSeparator) {\r\n return 'RepetitionWithSeparator';\r\n } else if (production instanceof RepetitionMandatory) {\r\n return 'RepetitionMandatory';\r\n } else if (production instanceof RepetitionMandatoryWithSeparator) {\r\n return 'RepetitionMandatoryWithSeparator';\r\n } else {\r\n throw new Error('Invalid production type encountered');\r\n }\r\n}\r\n\r\nfunction makeBlock(atn: ATN, alts: ATNHandle[]): ATNHandle {\r\n const altsLength = alts.length\r\n for (let i = 0; i < altsLength - 1; i++) {\r\n const handle = alts[i]\r\n let transition: Transition | undefined\r\n if (handle.left.transitions.length === 1) {\r\n transition = handle.left.transitions[0]\r\n }\r\n const isRuleTransition = transition instanceof RuleTransition\r\n const ruleTransition = transition as RuleTransition\r\n const next = alts[i + 1].left\r\n if (\r\n handle.left.type === ATN_BASIC &&\r\n handle.right.type === ATN_BASIC &&\r\n transition !== undefined &&\r\n ((isRuleTransition && ruleTransition.followState === handle.right) ||\r\n transition.target === handle.right)\r\n ) {\r\n // we can avoid epsilon edge to next element\r\n if (isRuleTransition) {\r\n ruleTransition.followState = next\r\n } else {\r\n transition.target = next\r\n }\r\n removeState(atn, handle.right) // we skipped over this state\r\n } else {\r\n // need epsilon if previous block's right end node is complex\r\n epsilon(handle.right, next)\r\n }\r\n }\r\n\r\n const first = alts[0]\r\n const last = alts[altsLength - 1]\r\n return {\r\n left: first.left,\r\n right: last.right\r\n }\r\n}\r\n\r\nfunction tokenRef(\r\n atn: ATN,\r\n rule: Rule,\r\n tokenType: TokenType,\r\n production: IProductionWithOccurrence\r\n): ATNHandle {\r\n const left = newState(atn, rule, production, {\r\n type: ATN_BASIC\r\n })\r\n const right = newState(atn, rule, production, {\r\n type: ATN_BASIC\r\n })\r\n addTransition(left, new AtomTransition(right, tokenType))\r\n return {\r\n left,\r\n right\r\n }\r\n}\r\n\r\nfunction ruleRef(\r\n atn: ATN,\r\n currentRule: Rule,\r\n nonTerminal: NonTerminal\r\n): ATNHandle {\r\n const rule = nonTerminal.referencedRule\r\n const start = atn.ruleToStartState.get(rule)!\r\n const left = newState(atn, currentRule, nonTerminal, {\r\n type: ATN_BASIC\r\n })\r\n const right = newState(atn, currentRule, nonTerminal, {\r\n type: ATN_BASIC\r\n })\r\n\r\n const call = new RuleTransition(start, rule, right)\r\n addTransition(left, call)\r\n\r\n return {\r\n left,\r\n right\r\n }\r\n}\r\n\r\nfunction buildRuleHandle(atn: ATN, rule: Rule, block: ATNHandle): ATNHandle {\r\n const start = atn.ruleToStartState.get(rule)!\r\n epsilon(start, block.left)\r\n const stop = atn.ruleToStopState.get(rule)!\r\n epsilon(block.right, stop)\r\n const handle: ATNHandle = {\r\n left: start,\r\n right: stop\r\n }\r\n return handle\r\n}\r\n\r\nfunction epsilon(a: ATNBaseState, b: ATNBaseState): void {\r\n const transition = new EpsilonTransition(b as ATNState)\r\n addTransition(a, transition)\r\n}\r\n\r\nfunction newState(\r\n atn: ATN,\r\n rule: Rule,\r\n production: IProductionWithOccurrence | undefined,\r\n partial: Partial\r\n): T {\r\n const t: T = {\r\n atn,\r\n production,\r\n epsilonOnlyTransitions: false,\r\n rule,\r\n transitions: [],\r\n nextTokenWithinRule: [],\r\n stateNumber: atn.states.length,\r\n ...partial\r\n } as unknown as T\r\n atn.states.push(t)\r\n return t\r\n}\r\n\r\nfunction addTransition(state: ATNBaseState, transition: Transition) {\r\n // A single ATN state can only contain epsilon transitions or non-epsilon transitions\r\n // Because they are never mixed, only setting the property for the first transition is fine\r\n if (state.transitions.length === 0) {\r\n state.epsilonOnlyTransitions = transition.isEpsilon()\r\n }\r\n state.transitions.push(transition)\r\n}\r\n\r\nfunction removeState(atn: ATN, state: ATNState): void {\r\n atn.states.splice(atn.states.indexOf(state), 1)\r\n}\r\n", "/******************************************************************************\r\n * Copyright 2022 TypeFox GmbH\r\n * This program and the accompanying materials are made available under the\r\n * terms of the MIT License, which is available in the project root.\r\n ******************************************************************************/\r\n\r\nimport map from \"lodash-es/map.js\"\r\nimport { ATNState, DecisionState } from \"./atn.js\"\r\n\r\nexport interface DFA {\r\n start?: DFAState\r\n states: Record\r\n decision: number\r\n atnStartState: DecisionState\r\n}\r\n\r\nexport interface DFAState {\r\n configs: ATNConfigSet\r\n edges: Record\r\n isAcceptState: boolean\r\n prediction: number\r\n}\r\n\r\nexport const DFA_ERROR = {} as DFAState\r\n\r\nexport interface ATNConfig {\r\n state: ATNState\r\n alt: number\r\n stack: ATNState[]\r\n}\r\n\r\nexport class ATNConfigSet {\r\n private map: Record = {}\r\n private configs: ATNConfig[] = []\r\n\r\n uniqueAlt: number | undefined\r\n\r\n get size(): number {\r\n return this.configs.length\r\n }\r\n\r\n finalize(): void {\r\n // Empties the map to free up memory\r\n this.map = {}\r\n }\r\n\r\n add(config: ATNConfig): void {\r\n const key = getATNConfigKey(config)\r\n // Only add configs which don't exist in our map already\r\n // While this does not influence the actual algorithm, adding them anyway would massively increase memory consumption\r\n if (!(key in this.map)) {\r\n this.map[key] = this.configs.length\r\n this.configs.push(config)\r\n }\r\n }\r\n\r\n get elements(): readonly ATNConfig[] {\r\n return this.configs\r\n }\r\n\r\n get alts(): number[] {\r\n return map(this.configs, (e) => e.alt)\r\n }\r\n\r\n get key(): string {\r\n let value = \"\"\r\n for (const k in this.map) {\r\n value += k + \":\"\r\n }\r\n return value\r\n }\r\n}\r\n\r\nexport function getATNConfigKey(config: ATNConfig, alt = true) {\r\n return `${alt ? `a${config.alt}` : \"\"}s${\r\n config.state.stateNumber\r\n }:${config.stack.map((e) => e.stateNumber.toString()).join(\"_\")}`\r\n}\r\n", "/******************************************************************************\r\n * Copyright 2022 TypeFox GmbH\r\n * This program and the accompanying materials are made available under the\r\n * terms of the MIT License, which is available in the project root.\r\n ******************************************************************************/\r\n\r\nimport {\r\n IToken,\r\n TokenType,\r\n tokenMatcher,\r\n tokenLabel,\r\n Rule,\r\n IProductionWithOccurrence,\r\n NonTerminal,\r\n Alternation,\r\n Option,\r\n RepetitionMandatory,\r\n RepetitionMandatoryWithSeparator,\r\n RepetitionWithSeparator,\r\n Repetition,\r\n Terminal,\r\n BaseParser,\r\n LLkLookaheadStrategy,\r\n ILookaheadValidationError,\r\n IOrAlt,\r\n getLookaheadPaths,\r\n OptionalProductionType\r\n} from \"chevrotain\";\r\nimport {\r\n ATN,\r\n ATNState,\r\n ATN_RULE_STOP,\r\n AtomTransition,\r\n buildATNKey,\r\n createATN,\r\n DecisionState,\r\n EpsilonTransition,\r\n RuleTransition,\r\n Transition\r\n} from \"./atn.js\";\r\nimport {\r\n ATNConfig,\r\n ATNConfigSet,\r\n DFA,\r\n DFAState,\r\n DFA_ERROR,\r\n getATNConfigKey\r\n} from \"./dfa.js\";\r\nimport min from \"lodash-es/min.js\";\r\nimport flatMap from \"lodash-es/flatMap.js\";\r\nimport uniqBy from \"lodash-es/uniqBy.js\";\r\nimport map from \"lodash-es/map.js\";\r\nimport flatten from \"lodash-es/flatten.js\";\r\nimport forEach from \"lodash-es/forEach.js\";\r\nimport isEmpty from \"lodash-es/isEmpty.js\";\r\nimport reduce from \"lodash-es/reduce.js\";\r\n\r\ntype DFACache = (predicateSet: PredicateSet) => DFA\r\n\r\nexport type AmbiguityReport = (message: string) => void;\r\n\r\nfunction createDFACache(startState: DecisionState, decision: number): DFACache {\r\n const map: Record = {}\r\n return (predicateSet) => {\r\n const key = predicateSet.toString()\r\n let existing = map[key]\r\n if (existing !== undefined) {\r\n return existing\r\n } else {\r\n existing = {\r\n atnStartState: startState,\r\n decision,\r\n states: {}\r\n }\r\n map[key] = existing\r\n return existing\r\n }\r\n }\r\n}\r\n\r\nclass PredicateSet {\r\n private predicates: boolean[] = []\r\n\r\n is(index: number): boolean {\r\n return index >= this.predicates.length || this.predicates[index]\r\n }\r\n\r\n set(index: number, value: boolean) {\r\n this.predicates[index] = value\r\n }\r\n\r\n toString(): string {\r\n let value = \"\"\r\n const size = this.predicates.length\r\n for (let i = 0; i < size; i++) {\r\n value += this.predicates[i] === true ? \"1\" : \"0\"\r\n }\r\n return value\r\n }\r\n}\r\n\r\ninterface AdaptivePredictError {\r\n tokenPath: IToken[]\r\n possibleTokenTypes: TokenType[]\r\n actualToken: IToken\r\n}\r\n\r\nconst EMPTY_PREDICATES = new PredicateSet()\r\n\r\nexport interface LLStarLookaheadOptions {\r\n logging?: AmbiguityReport\r\n}\r\n\r\nexport class LLStarLookaheadStrategy extends LLkLookaheadStrategy {\r\n\r\n private atn: ATN;\r\n private dfas: DFACache[];\r\n private logging: AmbiguityReport;\r\n\r\n constructor(options?: LLStarLookaheadOptions) {\r\n super();\r\n this.logging = options?.logging ?? ((message) => console.log(message));\r\n }\r\n\r\n override initialize(options: { rules: Rule[] }): void {\r\n this.atn = createATN(options.rules);\r\n this.dfas = initATNSimulator(this.atn);\r\n }\r\n\r\n override validateAmbiguousAlternationAlternatives(): ILookaheadValidationError[] {\r\n return [];\r\n }\r\n\r\n override validateEmptyOrAlternatives(): ILookaheadValidationError[] {\r\n return [];\r\n }\r\n\r\n override buildLookaheadForAlternation(options: {\r\n prodOccurrence: number;\r\n rule: Rule;\r\n maxLookahead: number;\r\n hasPredicates: boolean;\r\n dynamicTokensEnabled: boolean\r\n }): (this: BaseParser, orAlts?: IOrAlt[] | undefined) => number | undefined {\r\n const { prodOccurrence, rule, hasPredicates, dynamicTokensEnabled } = options;\r\n const dfas = this.dfas;\r\n const logging = this.logging;\r\n const key = buildATNKey(rule, 'Alternation', prodOccurrence);\r\n const decisionState = this.atn.decisionMap[key];\r\n const decisionIndex = decisionState.decision;\r\n const partialAlts: (TokenType | undefined)[][] = map(\r\n getLookaheadPaths({\r\n maxLookahead: 1,\r\n occurrence: prodOccurrence,\r\n prodType: \"Alternation\",\r\n rule: rule\r\n }),\r\n (currAlt) => map(currAlt, (path) => path[0])\r\n )\r\n\r\n if (isLL1Sequence(partialAlts, false) && !dynamicTokensEnabled) {\r\n const choiceToAlt = reduce(\r\n partialAlts,\r\n (result, currAlt, idx) => {\r\n forEach(currAlt, (currTokType) => {\r\n if (currTokType) {\r\n result[currTokType.tokenTypeIdx!] = idx\r\n forEach(currTokType.categoryMatches!, (currExtendingType) => {\r\n result[currExtendingType] = idx\r\n })\r\n }\r\n })\r\n return result\r\n },\r\n {} as Record\r\n )\r\n\r\n if (hasPredicates) {\r\n return function (this: BaseParser, orAlts) {\r\n const nextToken = this.LA(1)\r\n const prediction: number | undefined = choiceToAlt[nextToken.tokenTypeIdx]\r\n if (orAlts !== undefined && prediction !== undefined) {\r\n const gate = orAlts[prediction]?.GATE\r\n if (gate !== undefined && gate.call(this) === false) {\r\n return undefined;\r\n }\r\n }\r\n return prediction\r\n }\r\n } else {\r\n return function (this: BaseParser): number | undefined {\r\n const nextToken = this.LA(1)\r\n return choiceToAlt[nextToken.tokenTypeIdx];\r\n }\r\n }\r\n } else if (hasPredicates) {\r\n return function (this: BaseParser, orAlts) {\r\n const predicates = new PredicateSet()\r\n const length = orAlts === undefined ? 0 : orAlts.length\r\n for (let i = 0; i < length; i++) {\r\n const gate = orAlts?.[i].GATE\r\n predicates.set(i, gate === undefined || gate.call(this))\r\n }\r\n const result = adaptivePredict.call(this, dfas, decisionIndex, predicates, logging);\r\n return typeof result === 'number' ? result : undefined;\r\n }\r\n } else {\r\n return function (this: BaseParser) {\r\n const result = adaptivePredict.call(this, dfas, decisionIndex, EMPTY_PREDICATES, logging);\r\n return typeof result === 'number' ? result : undefined;\r\n }\r\n }\r\n }\r\n\r\n override buildLookaheadForOptional(options: {\r\n prodOccurrence: number;\r\n prodType: OptionalProductionType;\r\n rule: Rule;\r\n maxLookahead: number;\r\n dynamicTokensEnabled: boolean\r\n }): (this: BaseParser) => boolean {\r\n const { prodOccurrence, rule, prodType, dynamicTokensEnabled } = options;\r\n const dfas = this.dfas;\r\n const logging = this.logging;\r\n const key = buildATNKey(rule, prodType, prodOccurrence);\r\n const decisionState = this.atn.decisionMap[key];\r\n const decisionIndex = decisionState.decision;\r\n const alts = map(\r\n getLookaheadPaths({\r\n maxLookahead: 1,\r\n occurrence: prodOccurrence,\r\n prodType,\r\n rule\r\n }),\r\n (e) => {\r\n return map(e, (g) => g[0])\r\n }\r\n )\r\n \r\n if (isLL1Sequence(alts) && alts[0][0] && !dynamicTokensEnabled) {\r\n const alt = alts[0]\r\n const singleTokensTypes = flatten(alt)\r\n \r\n if (\r\n singleTokensTypes.length === 1 &&\r\n isEmpty(singleTokensTypes[0].categoryMatches)\r\n ) {\r\n const expectedTokenType = singleTokensTypes[0]\r\n const expectedTokenUniqueKey = expectedTokenType.tokenTypeIdx\r\n \r\n return function (this: BaseParser): boolean {\r\n return this.LA(1).tokenTypeIdx === expectedTokenUniqueKey\r\n }\r\n } else {\r\n const choiceToAlt = reduce(\r\n singleTokensTypes,\r\n (result, currTokType) => {\r\n if (currTokType !== undefined) {\r\n result[currTokType.tokenTypeIdx!] = true\r\n forEach(currTokType.categoryMatches, (currExtendingType) => {\r\n result[currExtendingType] = true\r\n })\r\n }\r\n return result\r\n },\r\n {} as Record\r\n )\r\n \r\n return function (this: BaseParser): boolean {\r\n const nextToken = this.LA(1)\r\n return choiceToAlt[nextToken.tokenTypeIdx] === true\r\n }\r\n }\r\n }\r\n return function (this: BaseParser) {\r\n const result = adaptivePredict.call(this, dfas, decisionIndex, EMPTY_PREDICATES, logging)\r\n return typeof result === \"object\" ? false : result === 0;\r\n }\r\n }\r\n\r\n}\r\n\r\nfunction isLL1Sequence(sequences: (TokenType | undefined)[][], allowEmpty = true): boolean {\r\n const fullSet = new Set()\r\n\r\n for (const alt of sequences) {\r\n const altSet = new Set()\r\n for (const tokType of alt) {\r\n if (tokType === undefined) {\r\n if (allowEmpty) {\r\n // Epsilon production encountered\r\n break\r\n } else {\r\n return false;\r\n }\r\n }\r\n const indices = [tokType.tokenTypeIdx!].concat(tokType.categoryMatches!)\r\n for (const index of indices) {\r\n if (fullSet.has(index)) {\r\n if (!altSet.has(index)) {\r\n return false\r\n }\r\n } else {\r\n fullSet.add(index)\r\n altSet.add(index)\r\n }\r\n }\r\n }\r\n }\r\n return true\r\n}\r\n\r\nfunction initATNSimulator(atn: ATN): DFACache[] {\r\n const decisionLength = atn.decisionStates.length\r\n const decisionToDFA: DFACache[] = Array(decisionLength)\r\n for (let i = 0; i < decisionLength; i++) {\r\n decisionToDFA[i] = createDFACache(atn.decisionStates[i], i)\r\n }\r\n return decisionToDFA;\r\n}\r\n\r\nfunction adaptivePredict(\r\n this: BaseParser,\r\n dfaCaches: DFACache[],\r\n decision: number,\r\n predicateSet: PredicateSet,\r\n logging: AmbiguityReport\r\n): number | AdaptivePredictError {\r\n const dfa = dfaCaches[decision](predicateSet)\r\n let start = dfa.start\r\n if (start === undefined) {\r\n const closure = computeStartState(dfa.atnStartState as ATNState)\r\n start = addDFAState(dfa, newDFAState(closure))\r\n dfa.start = start\r\n }\r\n\r\n const alt = performLookahead.apply(this, [dfa, start, predicateSet, logging])\r\n return alt\r\n}\r\n\r\nfunction performLookahead(\r\n this: BaseParser,\r\n dfa: DFA,\r\n s0: DFAState,\r\n predicateSet: PredicateSet,\r\n logging: AmbiguityReport\r\n): number | AdaptivePredictError {\r\n let previousD = s0\r\n\r\n let i = 1\r\n const path: IToken[] = []\r\n let t = this.LA(i++)\r\n\r\n while (true) {\r\n let d = getExistingTargetState(previousD, t)\r\n if (d === undefined) {\r\n d = computeLookaheadTarget.apply(this, [dfa, previousD, t, i, predicateSet, logging])\r\n }\r\n\r\n if (d === DFA_ERROR) {\r\n return buildAdaptivePredictError(path, previousD, t)\r\n }\r\n\r\n if (d.isAcceptState === true) {\r\n return d.prediction\r\n }\r\n\r\n previousD = d\r\n path.push(t)\r\n t = this.LA(i++)\r\n }\r\n}\r\n\r\nfunction computeLookaheadTarget(\r\n this: BaseParser,\r\n dfa: DFA,\r\n previousD: DFAState,\r\n token: IToken,\r\n lookahead: number,\r\n predicateSet: PredicateSet,\r\n logging: AmbiguityReport\r\n): DFAState {\r\n const reach = computeReachSet(previousD.configs, token, predicateSet)\r\n if (reach.size === 0) {\r\n addDFAEdge(dfa, previousD, token, DFA_ERROR)\r\n return DFA_ERROR\r\n }\r\n\r\n let newState = newDFAState(reach)\r\n const predictedAlt = getUniqueAlt(reach, predicateSet)\r\n\r\n if (predictedAlt !== undefined) {\r\n newState.isAcceptState = true\r\n newState.prediction = predictedAlt\r\n newState.configs.uniqueAlt = predictedAlt\r\n } else if (hasConflictTerminatingPrediction(reach)) {\r\n const prediction = min(reach.alts)!\r\n newState.isAcceptState = true\r\n newState.prediction = prediction\r\n newState.configs.uniqueAlt = prediction\r\n reportLookaheadAmbiguity.apply(this, [dfa, lookahead, reach.alts, logging])\r\n }\r\n\r\n newState = addDFAEdge(dfa, previousD, token, newState)\r\n return newState\r\n}\r\n\r\nfunction reportLookaheadAmbiguity(\r\n this: BaseParser,\r\n dfa: DFA,\r\n lookahead: number,\r\n ambiguityIndices: number[],\r\n logging: AmbiguityReport\r\n) {\r\n const prefixPath: TokenType[] = []\r\n for (let i = 1; i <= lookahead; i++) {\r\n prefixPath.push(this.LA(i).tokenType)\r\n }\r\n const atnState = dfa.atnStartState\r\n const topLevelRule = atnState.rule\r\n const production = atnState.production\r\n const message = buildAmbiguityError({\r\n topLevelRule,\r\n ambiguityIndices,\r\n production,\r\n prefixPath\r\n })\r\n logging(message)\r\n}\r\n\r\nfunction buildAmbiguityError(options: {\r\n topLevelRule: Rule\r\n prefixPath: TokenType[]\r\n ambiguityIndices: number[]\r\n production: IProductionWithOccurrence\r\n}): string {\r\n const pathMsg = map(options.prefixPath, (currtok) =>\r\n tokenLabel(currtok)\r\n ).join(\", \")\r\n const occurrence =\r\n options.production.idx === 0 ? \"\" : options.production.idx\r\n let currMessage =\r\n `Ambiguous Alternatives Detected: <${options.ambiguityIndices.join(\r\n \", \"\r\n )}> in <${getProductionDslName(options.production)}${occurrence}>` +\r\n ` inside <${options.topLevelRule.name}> Rule,\\n` +\r\n `<${pathMsg}> may appears as a prefix path in all these alternatives.\\n`\r\n\r\n currMessage =\r\n currMessage +\r\n `See: https://chevrotain.io/docs/guide/resolving_grammar_errors.html#AMBIGUOUS_ALTERNATIVES\\n` +\r\n `For Further details.`\r\n return currMessage\r\n}\r\n\r\nfunction getProductionDslName(prod: IProductionWithOccurrence): string {\r\n if (prod instanceof NonTerminal) {\r\n return \"SUBRULE\"\r\n } else if (prod instanceof Option) {\r\n return \"OPTION\"\r\n } else if (prod instanceof Alternation) {\r\n return \"OR\"\r\n } else if (prod instanceof RepetitionMandatory) {\r\n return \"AT_LEAST_ONE\"\r\n } else if (prod instanceof RepetitionMandatoryWithSeparator) {\r\n return \"AT_LEAST_ONE_SEP\"\r\n } else if (prod instanceof RepetitionWithSeparator) {\r\n return \"MANY_SEP\"\r\n } else if (prod instanceof Repetition) {\r\n return \"MANY\"\r\n } else if (prod instanceof Terminal) {\r\n return \"CONSUME\"\r\n } else {\r\n throw Error(\"non exhaustive match\")\r\n }\r\n}\r\n\r\nfunction buildAdaptivePredictError(\r\n path: IToken[],\r\n previous: DFAState,\r\n current: IToken\r\n): AdaptivePredictError {\r\n const nextTransitions = flatMap(\r\n previous.configs.elements,\r\n (e) => e.state.transitions\r\n )\r\n const nextTokenTypes = uniqBy(\r\n nextTransitions\r\n .filter((e): e is AtomTransition => e instanceof AtomTransition)\r\n .map((e) => e.tokenType),\r\n (e) => e.tokenTypeIdx\r\n )\r\n return {\r\n actualToken: current,\r\n possibleTokenTypes: nextTokenTypes,\r\n tokenPath: path\r\n }\r\n}\r\n\r\nfunction getExistingTargetState(\r\n state: DFAState,\r\n token: IToken\r\n): DFAState | undefined {\r\n return state.edges[token.tokenTypeIdx]\r\n}\r\n\r\nfunction computeReachSet(\r\n configs: ATNConfigSet,\r\n token: IToken,\r\n predicateSet: PredicateSet\r\n): ATNConfigSet {\r\n const intermediate = new ATNConfigSet()\r\n const skippedStopStates: ATNConfig[] = []\r\n\r\n for (const c of configs.elements) {\r\n if (predicateSet.is(c.alt) === false) {\r\n continue\r\n }\r\n if (c.state.type === ATN_RULE_STOP) {\r\n skippedStopStates.push(c)\r\n continue\r\n }\r\n const transitionLength = c.state.transitions.length\r\n for (let i = 0; i < transitionLength; i++) {\r\n const transition = c.state.transitions[i]\r\n const target = getReachableTarget(transition, token)\r\n if (target !== undefined) {\r\n intermediate.add({\r\n state: target,\r\n alt: c.alt,\r\n stack: c.stack\r\n })\r\n }\r\n }\r\n }\r\n\r\n let reach: ATNConfigSet | undefined\r\n\r\n if (skippedStopStates.length === 0 && intermediate.size === 1) {\r\n reach = intermediate\r\n }\r\n\r\n if (reach === undefined) {\r\n reach = new ATNConfigSet()\r\n for (const c of intermediate.elements) {\r\n closure(c, reach)\r\n }\r\n }\r\n\r\n if (skippedStopStates.length > 0 && !hasConfigInRuleStopState(reach)) {\r\n for (const c of skippedStopStates) {\r\n reach.add(c)\r\n }\r\n }\r\n\r\n return reach\r\n}\r\n\r\nfunction getReachableTarget(\r\n transition: Transition,\r\n token: IToken\r\n): ATNState | undefined {\r\n if (\r\n transition instanceof AtomTransition &&\r\n tokenMatcher(token, transition.tokenType)\r\n ) {\r\n return transition.target\r\n }\r\n return undefined\r\n}\r\n\r\nfunction getUniqueAlt(\r\n configs: ATNConfigSet,\r\n predicateSet: PredicateSet\r\n): number | undefined {\r\n let alt: number | undefined\r\n for (const c of configs.elements) {\r\n if (predicateSet.is(c.alt) === true) {\r\n if (alt === undefined) {\r\n alt = c.alt\r\n } else if (alt !== c.alt) {\r\n return undefined\r\n }\r\n }\r\n }\r\n return alt\r\n}\r\n\r\nfunction newDFAState(closure: ATNConfigSet): DFAState {\r\n return {\r\n configs: closure,\r\n edges: {},\r\n isAcceptState: false,\r\n prediction: -1\r\n }\r\n}\r\n\r\nfunction addDFAEdge(\r\n dfa: DFA,\r\n from: DFAState,\r\n token: IToken,\r\n to: DFAState\r\n): DFAState {\r\n to = addDFAState(dfa, to)\r\n from.edges[token.tokenTypeIdx] = to\r\n return to\r\n}\r\n\r\nfunction addDFAState(dfa: DFA, state: DFAState): DFAState {\r\n if (state === DFA_ERROR) {\r\n return state\r\n }\r\n // Repetitions have the same config set\r\n // Therefore, storing the key of the config in a map allows us to create a loop in our DFA\r\n const mapKey = state.configs.key\r\n const existing = dfa.states[mapKey]\r\n if (existing !== undefined) {\r\n return existing\r\n }\r\n state.configs.finalize()\r\n dfa.states[mapKey] = state\r\n return state\r\n}\r\n\r\nfunction computeStartState(atnState: ATNState): ATNConfigSet {\r\n const configs = new ATNConfigSet()\r\n\r\n const numberOfTransitions = atnState.transitions.length\r\n for (let i = 0; i < numberOfTransitions; i++) {\r\n const target = atnState.transitions[i].target\r\n const config: ATNConfig = {\r\n state: target,\r\n alt: i,\r\n stack: []\r\n }\r\n closure(config, configs)\r\n }\r\n\r\n return configs\r\n}\r\n\r\nfunction closure(config: ATNConfig, configs: ATNConfigSet): void {\r\n const p = config.state\r\n\r\n if (p.type === ATN_RULE_STOP) {\r\n if (config.stack.length > 0) {\r\n const atnStack = [...config.stack]\r\n const followState = atnStack.pop()!\r\n const followConfig: ATNConfig = {\r\n state: followState,\r\n alt: config.alt,\r\n stack: atnStack\r\n }\r\n closure(followConfig, configs)\r\n } else {\r\n // Dipping into outer context, simply add the config\r\n // This will stop computation once every config is at the rule stop state\r\n configs.add(config)\r\n }\r\n return\r\n }\r\n\r\n if (!p.epsilonOnlyTransitions) {\r\n configs.add(config)\r\n }\r\n\r\n const transitionLength = p.transitions.length\r\n for (let i = 0; i < transitionLength; i++) {\r\n const transition = p.transitions[i]\r\n const c = getEpsilonTarget(config, transition)\r\n\r\n if (c !== undefined) {\r\n closure(c, configs)\r\n }\r\n }\r\n}\r\n\r\nfunction getEpsilonTarget(\r\n config: ATNConfig,\r\n transition: Transition\r\n): ATNConfig | undefined {\r\n if (transition instanceof EpsilonTransition) {\r\n return {\r\n state: transition.target,\r\n alt: config.alt,\r\n stack: config.stack\r\n }\r\n } else if (transition instanceof RuleTransition) {\r\n const stack = [...config.stack, transition.followState]\r\n return {\r\n state: transition.target,\r\n alt: config.alt,\r\n stack\r\n }\r\n }\r\n return undefined\r\n}\r\n\r\nfunction hasConfigInRuleStopState(configs: ATNConfigSet): boolean {\r\n for (const c of configs.elements) {\r\n if (c.state.type === ATN_RULE_STOP) {\r\n return true\r\n }\r\n }\r\n return false\r\n}\r\n\r\nfunction allConfigsInRuleStopStates(configs: ATNConfigSet): boolean {\r\n for (const c of configs.elements) {\r\n if (c.state.type !== ATN_RULE_STOP) {\r\n return false\r\n }\r\n }\r\n return true\r\n}\r\n\r\nfunction hasConflictTerminatingPrediction(configs: ATNConfigSet): boolean {\r\n if (allConfigsInRuleStopStates(configs)) {\r\n return true\r\n }\r\n const altSets = getConflictingAltSets(configs.elements)\r\n const heuristic =\r\n hasConflictingAltSet(altSets) && !hasStateAssociatedWithOneAlt(altSets)\r\n return heuristic\r\n}\r\n\r\nfunction getConflictingAltSets(\r\n configs: readonly ATNConfig[]\r\n): Map> {\r\n const configToAlts = new Map>()\r\n for (const c of configs) {\r\n const key = getATNConfigKey(c, false)\r\n let alts = configToAlts.get(key)\r\n if (alts === undefined) {\r\n alts = {}\r\n configToAlts.set(key, alts)\r\n }\r\n alts[c.alt] = true\r\n }\r\n return configToAlts\r\n}\r\n\r\nfunction hasConflictingAltSet(\r\n altSets: Map>\r\n): boolean {\r\n for (const value of Array.from(altSets.values())) {\r\n if (Object.keys(value).length > 1) {\r\n return true\r\n }\r\n }\r\n return false\r\n}\r\n\r\nfunction hasStateAssociatedWithOneAlt(\r\n altSets: Map>\r\n): boolean {\r\n for (const value of Array.from(altSets.values())) {\r\n if (Object.keys(value).length === 1) {\r\n return true\r\n }\r\n }\r\n return false\r\n}\r\n", "/******************************************************************************\r\n * Copyright 2022 TypeFox GmbH\r\n * This program and the accompanying materials are made available under the\r\n * terms of the MIT License, which is available in the project root.\r\n ******************************************************************************/\r\n\r\nexport {\r\n AmbiguityReport,\r\n LLStarLookaheadOptions,\r\n LLStarLookaheadStrategy\r\n} from './all-star-lookahead.js';\r\n", "/* --------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n * ------------------------------------------------------------------------------------------ */\n'use strict';\nexport var DocumentUri;\n(function (DocumentUri) {\n function is(value) {\n return typeof value === 'string';\n }\n DocumentUri.is = is;\n})(DocumentUri || (DocumentUri = {}));\nexport var URI;\n(function (URI) {\n function is(value) {\n return typeof value === 'string';\n }\n URI.is = is;\n})(URI || (URI = {}));\nexport var integer;\n(function (integer) {\n integer.MIN_VALUE = -2147483648;\n integer.MAX_VALUE = 2147483647;\n function is(value) {\n return typeof value === 'number' && integer.MIN_VALUE <= value && value <= integer.MAX_VALUE;\n }\n integer.is = is;\n})(integer || (integer = {}));\nexport var uinteger;\n(function (uinteger) {\n uinteger.MIN_VALUE = 0;\n uinteger.MAX_VALUE = 2147483647;\n function is(value) {\n return typeof value === 'number' && uinteger.MIN_VALUE <= value && value <= uinteger.MAX_VALUE;\n }\n uinteger.is = is;\n})(uinteger || (uinteger = {}));\n/**\n * The Position namespace provides helper functions to work with\n * {@link Position} literals.\n */\nexport var Position;\n(function (Position) {\n /**\n * Creates a new Position literal from the given line and character.\n * @param line The position's line.\n * @param character The position's character.\n */\n function create(line, character) {\n if (line === Number.MAX_VALUE) {\n line = uinteger.MAX_VALUE;\n }\n if (character === Number.MAX_VALUE) {\n character = uinteger.MAX_VALUE;\n }\n return { line, character };\n }\n Position.create = create;\n /**\n * Checks whether the given literal conforms to the {@link Position} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.objectLiteral(candidate) && Is.uinteger(candidate.line) && Is.uinteger(candidate.character);\n }\n Position.is = is;\n})(Position || (Position = {}));\n/**\n * The Range namespace provides helper functions to work with\n * {@link Range} literals.\n */\nexport var Range;\n(function (Range) {\n function create(one, two, three, four) {\n if (Is.uinteger(one) && Is.uinteger(two) && Is.uinteger(three) && Is.uinteger(four)) {\n return { start: Position.create(one, two), end: Position.create(three, four) };\n }\n else if (Position.is(one) && Position.is(two)) {\n return { start: one, end: two };\n }\n else {\n throw new Error(`Range#create called with invalid arguments[${one}, ${two}, ${three}, ${four}]`);\n }\n }\n Range.create = create;\n /**\n * Checks whether the given literal conforms to the {@link Range} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.objectLiteral(candidate) && Position.is(candidate.start) && Position.is(candidate.end);\n }\n Range.is = is;\n})(Range || (Range = {}));\n/**\n * The Location namespace provides helper functions to work with\n * {@link Location} literals.\n */\nexport var Location;\n(function (Location) {\n /**\n * Creates a Location literal.\n * @param uri The location's uri.\n * @param range The location's range.\n */\n function create(uri, range) {\n return { uri, range };\n }\n Location.create = create;\n /**\n * Checks whether the given literal conforms to the {@link Location} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.objectLiteral(candidate) && Range.is(candidate.range) && (Is.string(candidate.uri) || Is.undefined(candidate.uri));\n }\n Location.is = is;\n})(Location || (Location = {}));\n/**\n * The LocationLink namespace provides helper functions to work with\n * {@link LocationLink} literals.\n */\nexport var LocationLink;\n(function (LocationLink) {\n /**\n * Creates a LocationLink literal.\n * @param targetUri The definition's uri.\n * @param targetRange The full range of the definition.\n * @param targetSelectionRange The span of the symbol definition at the target.\n * @param originSelectionRange The span of the symbol being defined in the originating source file.\n */\n function create(targetUri, targetRange, targetSelectionRange, originSelectionRange) {\n return { targetUri, targetRange, targetSelectionRange, originSelectionRange };\n }\n LocationLink.create = create;\n /**\n * Checks whether the given literal conforms to the {@link LocationLink} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.objectLiteral(candidate) && Range.is(candidate.targetRange) && Is.string(candidate.targetUri)\n && Range.is(candidate.targetSelectionRange)\n && (Range.is(candidate.originSelectionRange) || Is.undefined(candidate.originSelectionRange));\n }\n LocationLink.is = is;\n})(LocationLink || (LocationLink = {}));\n/**\n * The Color namespace provides helper functions to work with\n * {@link Color} literals.\n */\nexport var Color;\n(function (Color) {\n /**\n * Creates a new Color literal.\n */\n function create(red, green, blue, alpha) {\n return {\n red,\n green,\n blue,\n alpha,\n };\n }\n Color.create = create;\n /**\n * Checks whether the given literal conforms to the {@link Color} interface.\n */\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && Is.numberRange(candidate.red, 0, 1)\n && Is.numberRange(candidate.green, 0, 1)\n && Is.numberRange(candidate.blue, 0, 1)\n && Is.numberRange(candidate.alpha, 0, 1);\n }\n Color.is = is;\n})(Color || (Color = {}));\n/**\n * The ColorInformation namespace provides helper functions to work with\n * {@link ColorInformation} literals.\n */\nexport var ColorInformation;\n(function (ColorInformation) {\n /**\n * Creates a new ColorInformation literal.\n */\n function create(range, color) {\n return {\n range,\n color,\n };\n }\n ColorInformation.create = create;\n /**\n * Checks whether the given literal conforms to the {@link ColorInformation} interface.\n */\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && Range.is(candidate.range) && Color.is(candidate.color);\n }\n ColorInformation.is = is;\n})(ColorInformation || (ColorInformation = {}));\n/**\n * The Color namespace provides helper functions to work with\n * {@link ColorPresentation} literals.\n */\nexport var ColorPresentation;\n(function (ColorPresentation) {\n /**\n * Creates a new ColorInformation literal.\n */\n function create(label, textEdit, additionalTextEdits) {\n return {\n label,\n textEdit,\n additionalTextEdits,\n };\n }\n ColorPresentation.create = create;\n /**\n * Checks whether the given literal conforms to the {@link ColorInformation} interface.\n */\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && Is.string(candidate.label)\n && (Is.undefined(candidate.textEdit) || TextEdit.is(candidate))\n && (Is.undefined(candidate.additionalTextEdits) || Is.typedArray(candidate.additionalTextEdits, TextEdit.is));\n }\n ColorPresentation.is = is;\n})(ColorPresentation || (ColorPresentation = {}));\n/**\n * A set of predefined range kinds.\n */\nexport var FoldingRangeKind;\n(function (FoldingRangeKind) {\n /**\n * Folding range for a comment\n */\n FoldingRangeKind.Comment = 'comment';\n /**\n * Folding range for an import or include\n */\n FoldingRangeKind.Imports = 'imports';\n /**\n * Folding range for a region (e.g. `#region`)\n */\n FoldingRangeKind.Region = 'region';\n})(FoldingRangeKind || (FoldingRangeKind = {}));\n/**\n * The folding range namespace provides helper functions to work with\n * {@link FoldingRange} literals.\n */\nexport var FoldingRange;\n(function (FoldingRange) {\n /**\n * Creates a new FoldingRange literal.\n */\n function create(startLine, endLine, startCharacter, endCharacter, kind, collapsedText) {\n const result = {\n startLine,\n endLine\n };\n if (Is.defined(startCharacter)) {\n result.startCharacter = startCharacter;\n }\n if (Is.defined(endCharacter)) {\n result.endCharacter = endCharacter;\n }\n if (Is.defined(kind)) {\n result.kind = kind;\n }\n if (Is.defined(collapsedText)) {\n result.collapsedText = collapsedText;\n }\n return result;\n }\n FoldingRange.create = create;\n /**\n * Checks whether the given literal conforms to the {@link FoldingRange} interface.\n */\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && Is.uinteger(candidate.startLine) && Is.uinteger(candidate.startLine)\n && (Is.undefined(candidate.startCharacter) || Is.uinteger(candidate.startCharacter))\n && (Is.undefined(candidate.endCharacter) || Is.uinteger(candidate.endCharacter))\n && (Is.undefined(candidate.kind) || Is.string(candidate.kind));\n }\n FoldingRange.is = is;\n})(FoldingRange || (FoldingRange = {}));\n/**\n * The DiagnosticRelatedInformation namespace provides helper functions to work with\n * {@link DiagnosticRelatedInformation} literals.\n */\nexport var DiagnosticRelatedInformation;\n(function (DiagnosticRelatedInformation) {\n /**\n * Creates a new DiagnosticRelatedInformation literal.\n */\n function create(location, message) {\n return {\n location,\n message\n };\n }\n DiagnosticRelatedInformation.create = create;\n /**\n * Checks whether the given literal conforms to the {@link DiagnosticRelatedInformation} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Location.is(candidate.location) && Is.string(candidate.message);\n }\n DiagnosticRelatedInformation.is = is;\n})(DiagnosticRelatedInformation || (DiagnosticRelatedInformation = {}));\n/**\n * The diagnostic's severity.\n */\nexport var DiagnosticSeverity;\n(function (DiagnosticSeverity) {\n /**\n * Reports an error.\n */\n DiagnosticSeverity.Error = 1;\n /**\n * Reports a warning.\n */\n DiagnosticSeverity.Warning = 2;\n /**\n * Reports an information.\n */\n DiagnosticSeverity.Information = 3;\n /**\n * Reports a hint.\n */\n DiagnosticSeverity.Hint = 4;\n})(DiagnosticSeverity || (DiagnosticSeverity = {}));\n/**\n * The diagnostic tags.\n *\n * @since 3.15.0\n */\nexport var DiagnosticTag;\n(function (DiagnosticTag) {\n /**\n * Unused or unnecessary code.\n *\n * Clients are allowed to render diagnostics with this tag faded out instead of having\n * an error squiggle.\n */\n DiagnosticTag.Unnecessary = 1;\n /**\n * Deprecated or obsolete code.\n *\n * Clients are allowed to rendered diagnostics with this tag strike through.\n */\n DiagnosticTag.Deprecated = 2;\n})(DiagnosticTag || (DiagnosticTag = {}));\n/**\n * The CodeDescription namespace provides functions to deal with descriptions for diagnostic codes.\n *\n * @since 3.16.0\n */\nexport var CodeDescription;\n(function (CodeDescription) {\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && Is.string(candidate.href);\n }\n CodeDescription.is = is;\n})(CodeDescription || (CodeDescription = {}));\n/**\n * The Diagnostic namespace provides helper functions to work with\n * {@link Diagnostic} literals.\n */\nexport var Diagnostic;\n(function (Diagnostic) {\n /**\n * Creates a new Diagnostic literal.\n */\n function create(range, message, severity, code, source, relatedInformation) {\n let result = { range, message };\n if (Is.defined(severity)) {\n result.severity = severity;\n }\n if (Is.defined(code)) {\n result.code = code;\n }\n if (Is.defined(source)) {\n result.source = source;\n }\n if (Is.defined(relatedInformation)) {\n result.relatedInformation = relatedInformation;\n }\n return result;\n }\n Diagnostic.create = create;\n /**\n * Checks whether the given literal conforms to the {@link Diagnostic} interface.\n */\n function is(value) {\n var _a;\n let candidate = value;\n return Is.defined(candidate)\n && Range.is(candidate.range)\n && Is.string(candidate.message)\n && (Is.number(candidate.severity) || Is.undefined(candidate.severity))\n && (Is.integer(candidate.code) || Is.string(candidate.code) || Is.undefined(candidate.code))\n && (Is.undefined(candidate.codeDescription) || (Is.string((_a = candidate.codeDescription) === null || _a === void 0 ? void 0 : _a.href)))\n && (Is.string(candidate.source) || Is.undefined(candidate.source))\n && (Is.undefined(candidate.relatedInformation) || Is.typedArray(candidate.relatedInformation, DiagnosticRelatedInformation.is));\n }\n Diagnostic.is = is;\n})(Diagnostic || (Diagnostic = {}));\n/**\n * The Command namespace provides helper functions to work with\n * {@link Command} literals.\n */\nexport var Command;\n(function (Command) {\n /**\n * Creates a new Command literal.\n */\n function create(title, command, ...args) {\n let result = { title, command };\n if (Is.defined(args) && args.length > 0) {\n result.arguments = args;\n }\n return result;\n }\n Command.create = create;\n /**\n * Checks whether the given literal conforms to the {@link Command} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Is.string(candidate.title) && Is.string(candidate.command);\n }\n Command.is = is;\n})(Command || (Command = {}));\n/**\n * The TextEdit namespace provides helper function to create replace,\n * insert and delete edits more easily.\n */\nexport var TextEdit;\n(function (TextEdit) {\n /**\n * Creates a replace text edit.\n * @param range The range of text to be replaced.\n * @param newText The new text.\n */\n function replace(range, newText) {\n return { range, newText };\n }\n TextEdit.replace = replace;\n /**\n * Creates an insert text edit.\n * @param position The position to insert the text at.\n * @param newText The text to be inserted.\n */\n function insert(position, newText) {\n return { range: { start: position, end: position }, newText };\n }\n TextEdit.insert = insert;\n /**\n * Creates a delete text edit.\n * @param range The range of text to be deleted.\n */\n function del(range) {\n return { range, newText: '' };\n }\n TextEdit.del = del;\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate)\n && Is.string(candidate.newText)\n && Range.is(candidate.range);\n }\n TextEdit.is = is;\n})(TextEdit || (TextEdit = {}));\nexport var ChangeAnnotation;\n(function (ChangeAnnotation) {\n function create(label, needsConfirmation, description) {\n const result = { label };\n if (needsConfirmation !== undefined) {\n result.needsConfirmation = needsConfirmation;\n }\n if (description !== undefined) {\n result.description = description;\n }\n return result;\n }\n ChangeAnnotation.create = create;\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && Is.string(candidate.label) &&\n (Is.boolean(candidate.needsConfirmation) || candidate.needsConfirmation === undefined) &&\n (Is.string(candidate.description) || candidate.description === undefined);\n }\n ChangeAnnotation.is = is;\n})(ChangeAnnotation || (ChangeAnnotation = {}));\nexport var ChangeAnnotationIdentifier;\n(function (ChangeAnnotationIdentifier) {\n function is(value) {\n const candidate = value;\n return Is.string(candidate);\n }\n ChangeAnnotationIdentifier.is = is;\n})(ChangeAnnotationIdentifier || (ChangeAnnotationIdentifier = {}));\nexport var AnnotatedTextEdit;\n(function (AnnotatedTextEdit) {\n /**\n * Creates an annotated replace text edit.\n *\n * @param range The range of text to be replaced.\n * @param newText The new text.\n * @param annotation The annotation.\n */\n function replace(range, newText, annotation) {\n return { range, newText, annotationId: annotation };\n }\n AnnotatedTextEdit.replace = replace;\n /**\n * Creates an annotated insert text edit.\n *\n * @param position The position to insert the text at.\n * @param newText The text to be inserted.\n * @param annotation The annotation.\n */\n function insert(position, newText, annotation) {\n return { range: { start: position, end: position }, newText, annotationId: annotation };\n }\n AnnotatedTextEdit.insert = insert;\n /**\n * Creates an annotated delete text edit.\n *\n * @param range The range of text to be deleted.\n * @param annotation The annotation.\n */\n function del(range, annotation) {\n return { range, newText: '', annotationId: annotation };\n }\n AnnotatedTextEdit.del = del;\n function is(value) {\n const candidate = value;\n return TextEdit.is(candidate) && (ChangeAnnotation.is(candidate.annotationId) || ChangeAnnotationIdentifier.is(candidate.annotationId));\n }\n AnnotatedTextEdit.is = is;\n})(AnnotatedTextEdit || (AnnotatedTextEdit = {}));\n/**\n * The TextDocumentEdit namespace provides helper function to create\n * an edit that manipulates a text document.\n */\nexport var TextDocumentEdit;\n(function (TextDocumentEdit) {\n /**\n * Creates a new `TextDocumentEdit`\n */\n function create(textDocument, edits) {\n return { textDocument, edits };\n }\n TextDocumentEdit.create = create;\n function is(value) {\n let candidate = value;\n return Is.defined(candidate)\n && OptionalVersionedTextDocumentIdentifier.is(candidate.textDocument)\n && Array.isArray(candidate.edits);\n }\n TextDocumentEdit.is = is;\n})(TextDocumentEdit || (TextDocumentEdit = {}));\nexport var CreateFile;\n(function (CreateFile) {\n function create(uri, options, annotation) {\n let result = {\n kind: 'create',\n uri\n };\n if (options !== undefined && (options.overwrite !== undefined || options.ignoreIfExists !== undefined)) {\n result.options = options;\n }\n if (annotation !== undefined) {\n result.annotationId = annotation;\n }\n return result;\n }\n CreateFile.create = create;\n function is(value) {\n let candidate = value;\n return candidate && candidate.kind === 'create' && Is.string(candidate.uri) && (candidate.options === undefined ||\n ((candidate.options.overwrite === undefined || Is.boolean(candidate.options.overwrite)) && (candidate.options.ignoreIfExists === undefined || Is.boolean(candidate.options.ignoreIfExists)))) && (candidate.annotationId === undefined || ChangeAnnotationIdentifier.is(candidate.annotationId));\n }\n CreateFile.is = is;\n})(CreateFile || (CreateFile = {}));\nexport var RenameFile;\n(function (RenameFile) {\n function create(oldUri, newUri, options, annotation) {\n let result = {\n kind: 'rename',\n oldUri,\n newUri\n };\n if (options !== undefined && (options.overwrite !== undefined || options.ignoreIfExists !== undefined)) {\n result.options = options;\n }\n if (annotation !== undefined) {\n result.annotationId = annotation;\n }\n return result;\n }\n RenameFile.create = create;\n function is(value) {\n let candidate = value;\n return candidate && candidate.kind === 'rename' && Is.string(candidate.oldUri) && Is.string(candidate.newUri) && (candidate.options === undefined ||\n ((candidate.options.overwrite === undefined || Is.boolean(candidate.options.overwrite)) && (candidate.options.ignoreIfExists === undefined || Is.boolean(candidate.options.ignoreIfExists)))) && (candidate.annotationId === undefined || ChangeAnnotationIdentifier.is(candidate.annotationId));\n }\n RenameFile.is = is;\n})(RenameFile || (RenameFile = {}));\nexport var DeleteFile;\n(function (DeleteFile) {\n function create(uri, options, annotation) {\n let result = {\n kind: 'delete',\n uri\n };\n if (options !== undefined && (options.recursive !== undefined || options.ignoreIfNotExists !== undefined)) {\n result.options = options;\n }\n if (annotation !== undefined) {\n result.annotationId = annotation;\n }\n return result;\n }\n DeleteFile.create = create;\n function is(value) {\n let candidate = value;\n return candidate && candidate.kind === 'delete' && Is.string(candidate.uri) && (candidate.options === undefined ||\n ((candidate.options.recursive === undefined || Is.boolean(candidate.options.recursive)) && (candidate.options.ignoreIfNotExists === undefined || Is.boolean(candidate.options.ignoreIfNotExists)))) && (candidate.annotationId === undefined || ChangeAnnotationIdentifier.is(candidate.annotationId));\n }\n DeleteFile.is = is;\n})(DeleteFile || (DeleteFile = {}));\nexport var WorkspaceEdit;\n(function (WorkspaceEdit) {\n function is(value) {\n let candidate = value;\n return candidate &&\n (candidate.changes !== undefined || candidate.documentChanges !== undefined) &&\n (candidate.documentChanges === undefined || candidate.documentChanges.every((change) => {\n if (Is.string(change.kind)) {\n return CreateFile.is(change) || RenameFile.is(change) || DeleteFile.is(change);\n }\n else {\n return TextDocumentEdit.is(change);\n }\n }));\n }\n WorkspaceEdit.is = is;\n})(WorkspaceEdit || (WorkspaceEdit = {}));\nclass TextEditChangeImpl {\n constructor(edits, changeAnnotations) {\n this.edits = edits;\n this.changeAnnotations = changeAnnotations;\n }\n insert(position, newText, annotation) {\n let edit;\n let id;\n if (annotation === undefined) {\n edit = TextEdit.insert(position, newText);\n }\n else if (ChangeAnnotationIdentifier.is(annotation)) {\n id = annotation;\n edit = AnnotatedTextEdit.insert(position, newText, annotation);\n }\n else {\n this.assertChangeAnnotations(this.changeAnnotations);\n id = this.changeAnnotations.manage(annotation);\n edit = AnnotatedTextEdit.insert(position, newText, id);\n }\n this.edits.push(edit);\n if (id !== undefined) {\n return id;\n }\n }\n replace(range, newText, annotation) {\n let edit;\n let id;\n if (annotation === undefined) {\n edit = TextEdit.replace(range, newText);\n }\n else if (ChangeAnnotationIdentifier.is(annotation)) {\n id = annotation;\n edit = AnnotatedTextEdit.replace(range, newText, annotation);\n }\n else {\n this.assertChangeAnnotations(this.changeAnnotations);\n id = this.changeAnnotations.manage(annotation);\n edit = AnnotatedTextEdit.replace(range, newText, id);\n }\n this.edits.push(edit);\n if (id !== undefined) {\n return id;\n }\n }\n delete(range, annotation) {\n let edit;\n let id;\n if (annotation === undefined) {\n edit = TextEdit.del(range);\n }\n else if (ChangeAnnotationIdentifier.is(annotation)) {\n id = annotation;\n edit = AnnotatedTextEdit.del(range, annotation);\n }\n else {\n this.assertChangeAnnotations(this.changeAnnotations);\n id = this.changeAnnotations.manage(annotation);\n edit = AnnotatedTextEdit.del(range, id);\n }\n this.edits.push(edit);\n if (id !== undefined) {\n return id;\n }\n }\n add(edit) {\n this.edits.push(edit);\n }\n all() {\n return this.edits;\n }\n clear() {\n this.edits.splice(0, this.edits.length);\n }\n assertChangeAnnotations(value) {\n if (value === undefined) {\n throw new Error(`Text edit change is not configured to manage change annotations.`);\n }\n }\n}\n/**\n * A helper class\n */\nclass ChangeAnnotations {\n constructor(annotations) {\n this._annotations = annotations === undefined ? Object.create(null) : annotations;\n this._counter = 0;\n this._size = 0;\n }\n all() {\n return this._annotations;\n }\n get size() {\n return this._size;\n }\n manage(idOrAnnotation, annotation) {\n let id;\n if (ChangeAnnotationIdentifier.is(idOrAnnotation)) {\n id = idOrAnnotation;\n }\n else {\n id = this.nextId();\n annotation = idOrAnnotation;\n }\n if (this._annotations[id] !== undefined) {\n throw new Error(`Id ${id} is already in use.`);\n }\n if (annotation === undefined) {\n throw new Error(`No annotation provided for id ${id}`);\n }\n this._annotations[id] = annotation;\n this._size++;\n return id;\n }\n nextId() {\n this._counter++;\n return this._counter.toString();\n }\n}\n/**\n * A workspace change helps constructing changes to a workspace.\n */\nexport class WorkspaceChange {\n constructor(workspaceEdit) {\n this._textEditChanges = Object.create(null);\n if (workspaceEdit !== undefined) {\n this._workspaceEdit = workspaceEdit;\n if (workspaceEdit.documentChanges) {\n this._changeAnnotations = new ChangeAnnotations(workspaceEdit.changeAnnotations);\n workspaceEdit.changeAnnotations = this._changeAnnotations.all();\n workspaceEdit.documentChanges.forEach((change) => {\n if (TextDocumentEdit.is(change)) {\n const textEditChange = new TextEditChangeImpl(change.edits, this._changeAnnotations);\n this._textEditChanges[change.textDocument.uri] = textEditChange;\n }\n });\n }\n else if (workspaceEdit.changes) {\n Object.keys(workspaceEdit.changes).forEach((key) => {\n const textEditChange = new TextEditChangeImpl(workspaceEdit.changes[key]);\n this._textEditChanges[key] = textEditChange;\n });\n }\n }\n else {\n this._workspaceEdit = {};\n }\n }\n /**\n * Returns the underlying {@link WorkspaceEdit} literal\n * use to be returned from a workspace edit operation like rename.\n */\n get edit() {\n this.initDocumentChanges();\n if (this._changeAnnotations !== undefined) {\n if (this._changeAnnotations.size === 0) {\n this._workspaceEdit.changeAnnotations = undefined;\n }\n else {\n this._workspaceEdit.changeAnnotations = this._changeAnnotations.all();\n }\n }\n return this._workspaceEdit;\n }\n getTextEditChange(key) {\n if (OptionalVersionedTextDocumentIdentifier.is(key)) {\n this.initDocumentChanges();\n if (this._workspaceEdit.documentChanges === undefined) {\n throw new Error('Workspace edit is not configured for document changes.');\n }\n const textDocument = { uri: key.uri, version: key.version };\n let result = this._textEditChanges[textDocument.uri];\n if (!result) {\n const edits = [];\n const textDocumentEdit = {\n textDocument,\n edits\n };\n this._workspaceEdit.documentChanges.push(textDocumentEdit);\n result = new TextEditChangeImpl(edits, this._changeAnnotations);\n this._textEditChanges[textDocument.uri] = result;\n }\n return result;\n }\n else {\n this.initChanges();\n if (this._workspaceEdit.changes === undefined) {\n throw new Error('Workspace edit is not configured for normal text edit changes.');\n }\n let result = this._textEditChanges[key];\n if (!result) {\n let edits = [];\n this._workspaceEdit.changes[key] = edits;\n result = new TextEditChangeImpl(edits);\n this._textEditChanges[key] = result;\n }\n return result;\n }\n }\n initDocumentChanges() {\n if (this._workspaceEdit.documentChanges === undefined && this._workspaceEdit.changes === undefined) {\n this._changeAnnotations = new ChangeAnnotations();\n this._workspaceEdit.documentChanges = [];\n this._workspaceEdit.changeAnnotations = this._changeAnnotations.all();\n }\n }\n initChanges() {\n if (this._workspaceEdit.documentChanges === undefined && this._workspaceEdit.changes === undefined) {\n this._workspaceEdit.changes = Object.create(null);\n }\n }\n createFile(uri, optionsOrAnnotation, options) {\n this.initDocumentChanges();\n if (this._workspaceEdit.documentChanges === undefined) {\n throw new Error('Workspace edit is not configured for document changes.');\n }\n let annotation;\n if (ChangeAnnotation.is(optionsOrAnnotation) || ChangeAnnotationIdentifier.is(optionsOrAnnotation)) {\n annotation = optionsOrAnnotation;\n }\n else {\n options = optionsOrAnnotation;\n }\n let operation;\n let id;\n if (annotation === undefined) {\n operation = CreateFile.create(uri, options);\n }\n else {\n id = ChangeAnnotationIdentifier.is(annotation) ? annotation : this._changeAnnotations.manage(annotation);\n operation = CreateFile.create(uri, options, id);\n }\n this._workspaceEdit.documentChanges.push(operation);\n if (id !== undefined) {\n return id;\n }\n }\n renameFile(oldUri, newUri, optionsOrAnnotation, options) {\n this.initDocumentChanges();\n if (this._workspaceEdit.documentChanges === undefined) {\n throw new Error('Workspace edit is not configured for document changes.');\n }\n let annotation;\n if (ChangeAnnotation.is(optionsOrAnnotation) || ChangeAnnotationIdentifier.is(optionsOrAnnotation)) {\n annotation = optionsOrAnnotation;\n }\n else {\n options = optionsOrAnnotation;\n }\n let operation;\n let id;\n if (annotation === undefined) {\n operation = RenameFile.create(oldUri, newUri, options);\n }\n else {\n id = ChangeAnnotationIdentifier.is(annotation) ? annotation : this._changeAnnotations.manage(annotation);\n operation = RenameFile.create(oldUri, newUri, options, id);\n }\n this._workspaceEdit.documentChanges.push(operation);\n if (id !== undefined) {\n return id;\n }\n }\n deleteFile(uri, optionsOrAnnotation, options) {\n this.initDocumentChanges();\n if (this._workspaceEdit.documentChanges === undefined) {\n throw new Error('Workspace edit is not configured for document changes.');\n }\n let annotation;\n if (ChangeAnnotation.is(optionsOrAnnotation) || ChangeAnnotationIdentifier.is(optionsOrAnnotation)) {\n annotation = optionsOrAnnotation;\n }\n else {\n options = optionsOrAnnotation;\n }\n let operation;\n let id;\n if (annotation === undefined) {\n operation = DeleteFile.create(uri, options);\n }\n else {\n id = ChangeAnnotationIdentifier.is(annotation) ? annotation : this._changeAnnotations.manage(annotation);\n operation = DeleteFile.create(uri, options, id);\n }\n this._workspaceEdit.documentChanges.push(operation);\n if (id !== undefined) {\n return id;\n }\n }\n}\n/**\n * The TextDocumentIdentifier namespace provides helper functions to work with\n * {@link TextDocumentIdentifier} literals.\n */\nexport var TextDocumentIdentifier;\n(function (TextDocumentIdentifier) {\n /**\n * Creates a new TextDocumentIdentifier literal.\n * @param uri The document's uri.\n */\n function create(uri) {\n return { uri };\n }\n TextDocumentIdentifier.create = create;\n /**\n * Checks whether the given literal conforms to the {@link TextDocumentIdentifier} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Is.string(candidate.uri);\n }\n TextDocumentIdentifier.is = is;\n})(TextDocumentIdentifier || (TextDocumentIdentifier = {}));\n/**\n * The VersionedTextDocumentIdentifier namespace provides helper functions to work with\n * {@link VersionedTextDocumentIdentifier} literals.\n */\nexport var VersionedTextDocumentIdentifier;\n(function (VersionedTextDocumentIdentifier) {\n /**\n * Creates a new VersionedTextDocumentIdentifier literal.\n * @param uri The document's uri.\n * @param version The document's version.\n */\n function create(uri, version) {\n return { uri, version };\n }\n VersionedTextDocumentIdentifier.create = create;\n /**\n * Checks whether the given literal conforms to the {@link VersionedTextDocumentIdentifier} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Is.string(candidate.uri) && Is.integer(candidate.version);\n }\n VersionedTextDocumentIdentifier.is = is;\n})(VersionedTextDocumentIdentifier || (VersionedTextDocumentIdentifier = {}));\n/**\n * The OptionalVersionedTextDocumentIdentifier namespace provides helper functions to work with\n * {@link OptionalVersionedTextDocumentIdentifier} literals.\n */\nexport var OptionalVersionedTextDocumentIdentifier;\n(function (OptionalVersionedTextDocumentIdentifier) {\n /**\n * Creates a new OptionalVersionedTextDocumentIdentifier literal.\n * @param uri The document's uri.\n * @param version The document's version.\n */\n function create(uri, version) {\n return { uri, version };\n }\n OptionalVersionedTextDocumentIdentifier.create = create;\n /**\n * Checks whether the given literal conforms to the {@link OptionalVersionedTextDocumentIdentifier} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Is.string(candidate.uri) && (candidate.version === null || Is.integer(candidate.version));\n }\n OptionalVersionedTextDocumentIdentifier.is = is;\n})(OptionalVersionedTextDocumentIdentifier || (OptionalVersionedTextDocumentIdentifier = {}));\n/**\n * The TextDocumentItem namespace provides helper functions to work with\n * {@link TextDocumentItem} literals.\n */\nexport var TextDocumentItem;\n(function (TextDocumentItem) {\n /**\n * Creates a new TextDocumentItem literal.\n * @param uri The document's uri.\n * @param languageId The document's language identifier.\n * @param version The document's version number.\n * @param text The document's text.\n */\n function create(uri, languageId, version, text) {\n return { uri, languageId, version, text };\n }\n TextDocumentItem.create = create;\n /**\n * Checks whether the given literal conforms to the {@link TextDocumentItem} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Is.string(candidate.uri) && Is.string(candidate.languageId) && Is.integer(candidate.version) && Is.string(candidate.text);\n }\n TextDocumentItem.is = is;\n})(TextDocumentItem || (TextDocumentItem = {}));\n/**\n * Describes the content type that a client supports in various\n * result literals like `Hover`, `ParameterInfo` or `CompletionItem`.\n *\n * Please note that `MarkupKinds` must not start with a `$`. This kinds\n * are reserved for internal usage.\n */\nexport var MarkupKind;\n(function (MarkupKind) {\n /**\n * Plain text is supported as a content format\n */\n MarkupKind.PlainText = 'plaintext';\n /**\n * Markdown is supported as a content format\n */\n MarkupKind.Markdown = 'markdown';\n /**\n * Checks whether the given value is a value of the {@link MarkupKind} type.\n */\n function is(value) {\n const candidate = value;\n return candidate === MarkupKind.PlainText || candidate === MarkupKind.Markdown;\n }\n MarkupKind.is = is;\n})(MarkupKind || (MarkupKind = {}));\nexport var MarkupContent;\n(function (MarkupContent) {\n /**\n * Checks whether the given value conforms to the {@link MarkupContent} interface.\n */\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(value) && MarkupKind.is(candidate.kind) && Is.string(candidate.value);\n }\n MarkupContent.is = is;\n})(MarkupContent || (MarkupContent = {}));\n/**\n * The kind of a completion entry.\n */\nexport var CompletionItemKind;\n(function (CompletionItemKind) {\n CompletionItemKind.Text = 1;\n CompletionItemKind.Method = 2;\n CompletionItemKind.Function = 3;\n CompletionItemKind.Constructor = 4;\n CompletionItemKind.Field = 5;\n CompletionItemKind.Variable = 6;\n CompletionItemKind.Class = 7;\n CompletionItemKind.Interface = 8;\n CompletionItemKind.Module = 9;\n CompletionItemKind.Property = 10;\n CompletionItemKind.Unit = 11;\n CompletionItemKind.Value = 12;\n CompletionItemKind.Enum = 13;\n CompletionItemKind.Keyword = 14;\n CompletionItemKind.Snippet = 15;\n CompletionItemKind.Color = 16;\n CompletionItemKind.File = 17;\n CompletionItemKind.Reference = 18;\n CompletionItemKind.Folder = 19;\n CompletionItemKind.EnumMember = 20;\n CompletionItemKind.Constant = 21;\n CompletionItemKind.Struct = 22;\n CompletionItemKind.Event = 23;\n CompletionItemKind.Operator = 24;\n CompletionItemKind.TypeParameter = 25;\n})(CompletionItemKind || (CompletionItemKind = {}));\n/**\n * Defines whether the insert text in a completion item should be interpreted as\n * plain text or a snippet.\n */\nexport var InsertTextFormat;\n(function (InsertTextFormat) {\n /**\n * The primary text to be inserted is treated as a plain string.\n */\n InsertTextFormat.PlainText = 1;\n /**\n * The primary text to be inserted is treated as a snippet.\n *\n * A snippet can define tab stops and placeholders with `$1`, `$2`\n * and `${3:foo}`. `$0` defines the final tab stop, it defaults to\n * the end of the snippet. Placeholders with equal identifiers are linked,\n * that is typing in one will update others too.\n *\n * See also: https://microsoft.github.io/language-server-protocol/specifications/specification-current/#snippet_syntax\n */\n InsertTextFormat.Snippet = 2;\n})(InsertTextFormat || (InsertTextFormat = {}));\n/**\n * Completion item tags are extra annotations that tweak the rendering of a completion\n * item.\n *\n * @since 3.15.0\n */\nexport var CompletionItemTag;\n(function (CompletionItemTag) {\n /**\n * Render a completion as obsolete, usually using a strike-out.\n */\n CompletionItemTag.Deprecated = 1;\n})(CompletionItemTag || (CompletionItemTag = {}));\n/**\n * The InsertReplaceEdit namespace provides functions to deal with insert / replace edits.\n *\n * @since 3.16.0\n */\nexport var InsertReplaceEdit;\n(function (InsertReplaceEdit) {\n /**\n * Creates a new insert / replace edit\n */\n function create(newText, insert, replace) {\n return { newText, insert, replace };\n }\n InsertReplaceEdit.create = create;\n /**\n * Checks whether the given literal conforms to the {@link InsertReplaceEdit} interface.\n */\n function is(value) {\n const candidate = value;\n return candidate && Is.string(candidate.newText) && Range.is(candidate.insert) && Range.is(candidate.replace);\n }\n InsertReplaceEdit.is = is;\n})(InsertReplaceEdit || (InsertReplaceEdit = {}));\n/**\n * How whitespace and indentation is handled during completion\n * item insertion.\n *\n * @since 3.16.0\n */\nexport var InsertTextMode;\n(function (InsertTextMode) {\n /**\n * The insertion or replace strings is taken as it is. If the\n * value is multi line the lines below the cursor will be\n * inserted using the indentation defined in the string value.\n * The client will not apply any kind of adjustments to the\n * string.\n */\n InsertTextMode.asIs = 1;\n /**\n * The editor adjusts leading whitespace of new lines so that\n * they match the indentation up to the cursor of the line for\n * which the item is accepted.\n *\n * Consider a line like this: <2tabs><3tabs>foo. Accepting a\n * multi line completion item is indented using 2 tabs and all\n * following lines inserted will be indented using 2 tabs as well.\n */\n InsertTextMode.adjustIndentation = 2;\n})(InsertTextMode || (InsertTextMode = {}));\nexport var CompletionItemLabelDetails;\n(function (CompletionItemLabelDetails) {\n function is(value) {\n const candidate = value;\n return candidate && (Is.string(candidate.detail) || candidate.detail === undefined) &&\n (Is.string(candidate.description) || candidate.description === undefined);\n }\n CompletionItemLabelDetails.is = is;\n})(CompletionItemLabelDetails || (CompletionItemLabelDetails = {}));\n/**\n * The CompletionItem namespace provides functions to deal with\n * completion items.\n */\nexport var CompletionItem;\n(function (CompletionItem) {\n /**\n * Create a completion item and seed it with a label.\n * @param label The completion item's label\n */\n function create(label) {\n return { label };\n }\n CompletionItem.create = create;\n})(CompletionItem || (CompletionItem = {}));\n/**\n * The CompletionList namespace provides functions to deal with\n * completion lists.\n */\nexport var CompletionList;\n(function (CompletionList) {\n /**\n * Creates a new completion list.\n *\n * @param items The completion items.\n * @param isIncomplete The list is not complete.\n */\n function create(items, isIncomplete) {\n return { items: items ? items : [], isIncomplete: !!isIncomplete };\n }\n CompletionList.create = create;\n})(CompletionList || (CompletionList = {}));\nexport var MarkedString;\n(function (MarkedString) {\n /**\n * Creates a marked string from plain text.\n *\n * @param plainText The plain text.\n */\n function fromPlainText(plainText) {\n return plainText.replace(/[\\\\`*_{}[\\]()#+\\-.!]/g, '\\\\$&'); // escape markdown syntax tokens: http://daringfireball.net/projects/markdown/syntax#backslash\n }\n MarkedString.fromPlainText = fromPlainText;\n /**\n * Checks whether the given value conforms to the {@link MarkedString} type.\n */\n function is(value) {\n const candidate = value;\n return Is.string(candidate) || (Is.objectLiteral(candidate) && Is.string(candidate.language) && Is.string(candidate.value));\n }\n MarkedString.is = is;\n})(MarkedString || (MarkedString = {}));\nexport var Hover;\n(function (Hover) {\n /**\n * Checks whether the given value conforms to the {@link Hover} interface.\n */\n function is(value) {\n let candidate = value;\n return !!candidate && Is.objectLiteral(candidate) && (MarkupContent.is(candidate.contents) ||\n MarkedString.is(candidate.contents) ||\n Is.typedArray(candidate.contents, MarkedString.is)) && (value.range === undefined || Range.is(value.range));\n }\n Hover.is = is;\n})(Hover || (Hover = {}));\n/**\n * The ParameterInformation namespace provides helper functions to work with\n * {@link ParameterInformation} literals.\n */\nexport var ParameterInformation;\n(function (ParameterInformation) {\n /**\n * Creates a new parameter information literal.\n *\n * @param label A label string.\n * @param documentation A doc string.\n */\n function create(label, documentation) {\n return documentation ? { label, documentation } : { label };\n }\n ParameterInformation.create = create;\n})(ParameterInformation || (ParameterInformation = {}));\n/**\n * The SignatureInformation namespace provides helper functions to work with\n * {@link SignatureInformation} literals.\n */\nexport var SignatureInformation;\n(function (SignatureInformation) {\n function create(label, documentation, ...parameters) {\n let result = { label };\n if (Is.defined(documentation)) {\n result.documentation = documentation;\n }\n if (Is.defined(parameters)) {\n result.parameters = parameters;\n }\n else {\n result.parameters = [];\n }\n return result;\n }\n SignatureInformation.create = create;\n})(SignatureInformation || (SignatureInformation = {}));\n/**\n * A document highlight kind.\n */\nexport var DocumentHighlightKind;\n(function (DocumentHighlightKind) {\n /**\n * A textual occurrence.\n */\n DocumentHighlightKind.Text = 1;\n /**\n * Read-access of a symbol, like reading a variable.\n */\n DocumentHighlightKind.Read = 2;\n /**\n * Write-access of a symbol, like writing to a variable.\n */\n DocumentHighlightKind.Write = 3;\n})(DocumentHighlightKind || (DocumentHighlightKind = {}));\n/**\n * DocumentHighlight namespace to provide helper functions to work with\n * {@link DocumentHighlight} literals.\n */\nexport var DocumentHighlight;\n(function (DocumentHighlight) {\n /**\n * Create a DocumentHighlight object.\n * @param range The range the highlight applies to.\n * @param kind The highlight kind\n */\n function create(range, kind) {\n let result = { range };\n if (Is.number(kind)) {\n result.kind = kind;\n }\n return result;\n }\n DocumentHighlight.create = create;\n})(DocumentHighlight || (DocumentHighlight = {}));\n/**\n * A symbol kind.\n */\nexport var SymbolKind;\n(function (SymbolKind) {\n SymbolKind.File = 1;\n SymbolKind.Module = 2;\n SymbolKind.Namespace = 3;\n SymbolKind.Package = 4;\n SymbolKind.Class = 5;\n SymbolKind.Method = 6;\n SymbolKind.Property = 7;\n SymbolKind.Field = 8;\n SymbolKind.Constructor = 9;\n SymbolKind.Enum = 10;\n SymbolKind.Interface = 11;\n SymbolKind.Function = 12;\n SymbolKind.Variable = 13;\n SymbolKind.Constant = 14;\n SymbolKind.String = 15;\n SymbolKind.Number = 16;\n SymbolKind.Boolean = 17;\n SymbolKind.Array = 18;\n SymbolKind.Object = 19;\n SymbolKind.Key = 20;\n SymbolKind.Null = 21;\n SymbolKind.EnumMember = 22;\n SymbolKind.Struct = 23;\n SymbolKind.Event = 24;\n SymbolKind.Operator = 25;\n SymbolKind.TypeParameter = 26;\n})(SymbolKind || (SymbolKind = {}));\n/**\n * Symbol tags are extra annotations that tweak the rendering of a symbol.\n *\n * @since 3.16\n */\nexport var SymbolTag;\n(function (SymbolTag) {\n /**\n * Render a symbol as obsolete, usually using a strike-out.\n */\n SymbolTag.Deprecated = 1;\n})(SymbolTag || (SymbolTag = {}));\nexport var SymbolInformation;\n(function (SymbolInformation) {\n /**\n * Creates a new symbol information literal.\n *\n * @param name The name of the symbol.\n * @param kind The kind of the symbol.\n * @param range The range of the location of the symbol.\n * @param uri The resource of the location of symbol.\n * @param containerName The name of the symbol containing the symbol.\n */\n function create(name, kind, range, uri, containerName) {\n let result = {\n name,\n kind,\n location: { uri, range }\n };\n if (containerName) {\n result.containerName = containerName;\n }\n return result;\n }\n SymbolInformation.create = create;\n})(SymbolInformation || (SymbolInformation = {}));\nexport var WorkspaceSymbol;\n(function (WorkspaceSymbol) {\n /**\n * Create a new workspace symbol.\n *\n * @param name The name of the symbol.\n * @param kind The kind of the symbol.\n * @param uri The resource of the location of the symbol.\n * @param range An options range of the location.\n * @returns A WorkspaceSymbol.\n */\n function create(name, kind, uri, range) {\n return range !== undefined\n ? { name, kind, location: { uri, range } }\n : { name, kind, location: { uri } };\n }\n WorkspaceSymbol.create = create;\n})(WorkspaceSymbol || (WorkspaceSymbol = {}));\nexport var DocumentSymbol;\n(function (DocumentSymbol) {\n /**\n * Creates a new symbol information literal.\n *\n * @param name The name of the symbol.\n * @param detail The detail of the symbol.\n * @param kind The kind of the symbol.\n * @param range The range of the symbol.\n * @param selectionRange The selectionRange of the symbol.\n * @param children Children of the symbol.\n */\n function create(name, detail, kind, range, selectionRange, children) {\n let result = {\n name,\n detail,\n kind,\n range,\n selectionRange\n };\n if (children !== undefined) {\n result.children = children;\n }\n return result;\n }\n DocumentSymbol.create = create;\n /**\n * Checks whether the given literal conforms to the {@link DocumentSymbol} interface.\n */\n function is(value) {\n let candidate = value;\n return candidate &&\n Is.string(candidate.name) && Is.number(candidate.kind) &&\n Range.is(candidate.range) && Range.is(candidate.selectionRange) &&\n (candidate.detail === undefined || Is.string(candidate.detail)) &&\n (candidate.deprecated === undefined || Is.boolean(candidate.deprecated)) &&\n (candidate.children === undefined || Array.isArray(candidate.children)) &&\n (candidate.tags === undefined || Array.isArray(candidate.tags));\n }\n DocumentSymbol.is = is;\n})(DocumentSymbol || (DocumentSymbol = {}));\n/**\n * A set of predefined code action kinds\n */\nexport var CodeActionKind;\n(function (CodeActionKind) {\n /**\n * Empty kind.\n */\n CodeActionKind.Empty = '';\n /**\n * Base kind for quickfix actions: 'quickfix'\n */\n CodeActionKind.QuickFix = 'quickfix';\n /**\n * Base kind for refactoring actions: 'refactor'\n */\n CodeActionKind.Refactor = 'refactor';\n /**\n * Base kind for refactoring extraction actions: 'refactor.extract'\n *\n * Example extract actions:\n *\n * - Extract method\n * - Extract function\n * - Extract variable\n * - Extract interface from class\n * - ...\n */\n CodeActionKind.RefactorExtract = 'refactor.extract';\n /**\n * Base kind for refactoring inline actions: 'refactor.inline'\n *\n * Example inline actions:\n *\n * - Inline function\n * - Inline variable\n * - Inline constant\n * - ...\n */\n CodeActionKind.RefactorInline = 'refactor.inline';\n /**\n * Base kind for refactoring rewrite actions: 'refactor.rewrite'\n *\n * Example rewrite actions:\n *\n * - Convert JavaScript function to class\n * - Add or remove parameter\n * - Encapsulate field\n * - Make method static\n * - Move method to base class\n * - ...\n */\n CodeActionKind.RefactorRewrite = 'refactor.rewrite';\n /**\n * Base kind for source actions: `source`\n *\n * Source code actions apply to the entire file.\n */\n CodeActionKind.Source = 'source';\n /**\n * Base kind for an organize imports source action: `source.organizeImports`\n */\n CodeActionKind.SourceOrganizeImports = 'source.organizeImports';\n /**\n * Base kind for auto-fix source actions: `source.fixAll`.\n *\n * Fix all actions automatically fix errors that have a clear fix that do not require user input.\n * They should not suppress errors or perform unsafe fixes such as generating new types or classes.\n *\n * @since 3.15.0\n */\n CodeActionKind.SourceFixAll = 'source.fixAll';\n})(CodeActionKind || (CodeActionKind = {}));\n/**\n * The reason why code actions were requested.\n *\n * @since 3.17.0\n */\nexport var CodeActionTriggerKind;\n(function (CodeActionTriggerKind) {\n /**\n * Code actions were explicitly requested by the user or by an extension.\n */\n CodeActionTriggerKind.Invoked = 1;\n /**\n * Code actions were requested automatically.\n *\n * This typically happens when current selection in a file changes, but can\n * also be triggered when file content changes.\n */\n CodeActionTriggerKind.Automatic = 2;\n})(CodeActionTriggerKind || (CodeActionTriggerKind = {}));\n/**\n * The CodeActionContext namespace provides helper functions to work with\n * {@link CodeActionContext} literals.\n */\nexport var CodeActionContext;\n(function (CodeActionContext) {\n /**\n * Creates a new CodeActionContext literal.\n */\n function create(diagnostics, only, triggerKind) {\n let result = { diagnostics };\n if (only !== undefined && only !== null) {\n result.only = only;\n }\n if (triggerKind !== undefined && triggerKind !== null) {\n result.triggerKind = triggerKind;\n }\n return result;\n }\n CodeActionContext.create = create;\n /**\n * Checks whether the given literal conforms to the {@link CodeActionContext} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Is.typedArray(candidate.diagnostics, Diagnostic.is)\n && (candidate.only === undefined || Is.typedArray(candidate.only, Is.string))\n && (candidate.triggerKind === undefined || candidate.triggerKind === CodeActionTriggerKind.Invoked || candidate.triggerKind === CodeActionTriggerKind.Automatic);\n }\n CodeActionContext.is = is;\n})(CodeActionContext || (CodeActionContext = {}));\nexport var CodeAction;\n(function (CodeAction) {\n function create(title, kindOrCommandOrEdit, kind) {\n let result = { title };\n let checkKind = true;\n if (typeof kindOrCommandOrEdit === 'string') {\n checkKind = false;\n result.kind = kindOrCommandOrEdit;\n }\n else if (Command.is(kindOrCommandOrEdit)) {\n result.command = kindOrCommandOrEdit;\n }\n else {\n result.edit = kindOrCommandOrEdit;\n }\n if (checkKind && kind !== undefined) {\n result.kind = kind;\n }\n return result;\n }\n CodeAction.create = create;\n function is(value) {\n let candidate = value;\n return candidate && Is.string(candidate.title) &&\n (candidate.diagnostics === undefined || Is.typedArray(candidate.diagnostics, Diagnostic.is)) &&\n (candidate.kind === undefined || Is.string(candidate.kind)) &&\n (candidate.edit !== undefined || candidate.command !== undefined) &&\n (candidate.command === undefined || Command.is(candidate.command)) &&\n (candidate.isPreferred === undefined || Is.boolean(candidate.isPreferred)) &&\n (candidate.edit === undefined || WorkspaceEdit.is(candidate.edit));\n }\n CodeAction.is = is;\n})(CodeAction || (CodeAction = {}));\n/**\n * The CodeLens namespace provides helper functions to work with\n * {@link CodeLens} literals.\n */\nexport var CodeLens;\n(function (CodeLens) {\n /**\n * Creates a new CodeLens literal.\n */\n function create(range, data) {\n let result = { range };\n if (Is.defined(data)) {\n result.data = data;\n }\n return result;\n }\n CodeLens.create = create;\n /**\n * Checks whether the given literal conforms to the {@link CodeLens} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.command) || Command.is(candidate.command));\n }\n CodeLens.is = is;\n})(CodeLens || (CodeLens = {}));\n/**\n * The FormattingOptions namespace provides helper functions to work with\n * {@link FormattingOptions} literals.\n */\nexport var FormattingOptions;\n(function (FormattingOptions) {\n /**\n * Creates a new FormattingOptions literal.\n */\n function create(tabSize, insertSpaces) {\n return { tabSize, insertSpaces };\n }\n FormattingOptions.create = create;\n /**\n * Checks whether the given literal conforms to the {@link FormattingOptions} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Is.uinteger(candidate.tabSize) && Is.boolean(candidate.insertSpaces);\n }\n FormattingOptions.is = is;\n})(FormattingOptions || (FormattingOptions = {}));\n/**\n * The DocumentLink namespace provides helper functions to work with\n * {@link DocumentLink} literals.\n */\nexport var DocumentLink;\n(function (DocumentLink) {\n /**\n * Creates a new DocumentLink literal.\n */\n function create(range, target, data) {\n return { range, target, data };\n }\n DocumentLink.create = create;\n /**\n * Checks whether the given literal conforms to the {@link DocumentLink} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Range.is(candidate.range) && (Is.undefined(candidate.target) || Is.string(candidate.target));\n }\n DocumentLink.is = is;\n})(DocumentLink || (DocumentLink = {}));\n/**\n * The SelectionRange namespace provides helper function to work with\n * SelectionRange literals.\n */\nexport var SelectionRange;\n(function (SelectionRange) {\n /**\n * Creates a new SelectionRange\n * @param range the range.\n * @param parent an optional parent.\n */\n function create(range, parent) {\n return { range, parent };\n }\n SelectionRange.create = create;\n function is(value) {\n let candidate = value;\n return Is.objectLiteral(candidate) && Range.is(candidate.range) && (candidate.parent === undefined || SelectionRange.is(candidate.parent));\n }\n SelectionRange.is = is;\n})(SelectionRange || (SelectionRange = {}));\n/**\n * A set of predefined token types. This set is not fixed\n * an clients can specify additional token types via the\n * corresponding client capabilities.\n *\n * @since 3.16.0\n */\nexport var SemanticTokenTypes;\n(function (SemanticTokenTypes) {\n SemanticTokenTypes[\"namespace\"] = \"namespace\";\n /**\n * Represents a generic type. Acts as a fallback for types which can't be mapped to\n * a specific type like class or enum.\n */\n SemanticTokenTypes[\"type\"] = \"type\";\n SemanticTokenTypes[\"class\"] = \"class\";\n SemanticTokenTypes[\"enum\"] = \"enum\";\n SemanticTokenTypes[\"interface\"] = \"interface\";\n SemanticTokenTypes[\"struct\"] = \"struct\";\n SemanticTokenTypes[\"typeParameter\"] = \"typeParameter\";\n SemanticTokenTypes[\"parameter\"] = \"parameter\";\n SemanticTokenTypes[\"variable\"] = \"variable\";\n SemanticTokenTypes[\"property\"] = \"property\";\n SemanticTokenTypes[\"enumMember\"] = \"enumMember\";\n SemanticTokenTypes[\"event\"] = \"event\";\n SemanticTokenTypes[\"function\"] = \"function\";\n SemanticTokenTypes[\"method\"] = \"method\";\n SemanticTokenTypes[\"macro\"] = \"macro\";\n SemanticTokenTypes[\"keyword\"] = \"keyword\";\n SemanticTokenTypes[\"modifier\"] = \"modifier\";\n SemanticTokenTypes[\"comment\"] = \"comment\";\n SemanticTokenTypes[\"string\"] = \"string\";\n SemanticTokenTypes[\"number\"] = \"number\";\n SemanticTokenTypes[\"regexp\"] = \"regexp\";\n SemanticTokenTypes[\"operator\"] = \"operator\";\n /**\n * @since 3.17.0\n */\n SemanticTokenTypes[\"decorator\"] = \"decorator\";\n})(SemanticTokenTypes || (SemanticTokenTypes = {}));\n/**\n * A set of predefined token modifiers. This set is not fixed\n * an clients can specify additional token types via the\n * corresponding client capabilities.\n *\n * @since 3.16.0\n */\nexport var SemanticTokenModifiers;\n(function (SemanticTokenModifiers) {\n SemanticTokenModifiers[\"declaration\"] = \"declaration\";\n SemanticTokenModifiers[\"definition\"] = \"definition\";\n SemanticTokenModifiers[\"readonly\"] = \"readonly\";\n SemanticTokenModifiers[\"static\"] = \"static\";\n SemanticTokenModifiers[\"deprecated\"] = \"deprecated\";\n SemanticTokenModifiers[\"abstract\"] = \"abstract\";\n SemanticTokenModifiers[\"async\"] = \"async\";\n SemanticTokenModifiers[\"modification\"] = \"modification\";\n SemanticTokenModifiers[\"documentation\"] = \"documentation\";\n SemanticTokenModifiers[\"defaultLibrary\"] = \"defaultLibrary\";\n})(SemanticTokenModifiers || (SemanticTokenModifiers = {}));\n/**\n * @since 3.16.0\n */\nexport var SemanticTokens;\n(function (SemanticTokens) {\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && (candidate.resultId === undefined || typeof candidate.resultId === 'string') &&\n Array.isArray(candidate.data) && (candidate.data.length === 0 || typeof candidate.data[0] === 'number');\n }\n SemanticTokens.is = is;\n})(SemanticTokens || (SemanticTokens = {}));\n/**\n * The InlineValueText namespace provides functions to deal with InlineValueTexts.\n *\n * @since 3.17.0\n */\nexport var InlineValueText;\n(function (InlineValueText) {\n /**\n * Creates a new InlineValueText literal.\n */\n function create(range, text) {\n return { range, text };\n }\n InlineValueText.create = create;\n function is(value) {\n const candidate = value;\n return candidate !== undefined && candidate !== null && Range.is(candidate.range) && Is.string(candidate.text);\n }\n InlineValueText.is = is;\n})(InlineValueText || (InlineValueText = {}));\n/**\n * The InlineValueVariableLookup namespace provides functions to deal with InlineValueVariableLookups.\n *\n * @since 3.17.0\n */\nexport var InlineValueVariableLookup;\n(function (InlineValueVariableLookup) {\n /**\n * Creates a new InlineValueText literal.\n */\n function create(range, variableName, caseSensitiveLookup) {\n return { range, variableName, caseSensitiveLookup };\n }\n InlineValueVariableLookup.create = create;\n function is(value) {\n const candidate = value;\n return candidate !== undefined && candidate !== null && Range.is(candidate.range) && Is.boolean(candidate.caseSensitiveLookup)\n && (Is.string(candidate.variableName) || candidate.variableName === undefined);\n }\n InlineValueVariableLookup.is = is;\n})(InlineValueVariableLookup || (InlineValueVariableLookup = {}));\n/**\n * The InlineValueEvaluatableExpression namespace provides functions to deal with InlineValueEvaluatableExpression.\n *\n * @since 3.17.0\n */\nexport var InlineValueEvaluatableExpression;\n(function (InlineValueEvaluatableExpression) {\n /**\n * Creates a new InlineValueEvaluatableExpression literal.\n */\n function create(range, expression) {\n return { range, expression };\n }\n InlineValueEvaluatableExpression.create = create;\n function is(value) {\n const candidate = value;\n return candidate !== undefined && candidate !== null && Range.is(candidate.range)\n && (Is.string(candidate.expression) || candidate.expression === undefined);\n }\n InlineValueEvaluatableExpression.is = is;\n})(InlineValueEvaluatableExpression || (InlineValueEvaluatableExpression = {}));\n/**\n * The InlineValueContext namespace provides helper functions to work with\n * {@link InlineValueContext} literals.\n *\n * @since 3.17.0\n */\nexport var InlineValueContext;\n(function (InlineValueContext) {\n /**\n * Creates a new InlineValueContext literal.\n */\n function create(frameId, stoppedLocation) {\n return { frameId, stoppedLocation };\n }\n InlineValueContext.create = create;\n /**\n * Checks whether the given literal conforms to the {@link InlineValueContext} interface.\n */\n function is(value) {\n const candidate = value;\n return Is.defined(candidate) && Range.is(value.stoppedLocation);\n }\n InlineValueContext.is = is;\n})(InlineValueContext || (InlineValueContext = {}));\n/**\n * Inlay hint kinds.\n *\n * @since 3.17.0\n */\nexport var InlayHintKind;\n(function (InlayHintKind) {\n /**\n * An inlay hint that for a type annotation.\n */\n InlayHintKind.Type = 1;\n /**\n * An inlay hint that is for a parameter.\n */\n InlayHintKind.Parameter = 2;\n function is(value) {\n return value === 1 || value === 2;\n }\n InlayHintKind.is = is;\n})(InlayHintKind || (InlayHintKind = {}));\nexport var InlayHintLabelPart;\n(function (InlayHintLabelPart) {\n function create(value) {\n return { value };\n }\n InlayHintLabelPart.create = create;\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate)\n && (candidate.tooltip === undefined || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip))\n && (candidate.location === undefined || Location.is(candidate.location))\n && (candidate.command === undefined || Command.is(candidate.command));\n }\n InlayHintLabelPart.is = is;\n})(InlayHintLabelPart || (InlayHintLabelPart = {}));\nexport var InlayHint;\n(function (InlayHint) {\n function create(position, label, kind) {\n const result = { position, label };\n if (kind !== undefined) {\n result.kind = kind;\n }\n return result;\n }\n InlayHint.create = create;\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && Position.is(candidate.position)\n && (Is.string(candidate.label) || Is.typedArray(candidate.label, InlayHintLabelPart.is))\n && (candidate.kind === undefined || InlayHintKind.is(candidate.kind))\n && (candidate.textEdits === undefined) || Is.typedArray(candidate.textEdits, TextEdit.is)\n && (candidate.tooltip === undefined || Is.string(candidate.tooltip) || MarkupContent.is(candidate.tooltip))\n && (candidate.paddingLeft === undefined || Is.boolean(candidate.paddingLeft))\n && (candidate.paddingRight === undefined || Is.boolean(candidate.paddingRight));\n }\n InlayHint.is = is;\n})(InlayHint || (InlayHint = {}));\nexport var StringValue;\n(function (StringValue) {\n function createSnippet(value) {\n return { kind: 'snippet', value };\n }\n StringValue.createSnippet = createSnippet;\n})(StringValue || (StringValue = {}));\nexport var InlineCompletionItem;\n(function (InlineCompletionItem) {\n function create(insertText, filterText, range, command) {\n return { insertText, filterText, range, command };\n }\n InlineCompletionItem.create = create;\n})(InlineCompletionItem || (InlineCompletionItem = {}));\nexport var InlineCompletionList;\n(function (InlineCompletionList) {\n function create(items) {\n return { items };\n }\n InlineCompletionList.create = create;\n})(InlineCompletionList || (InlineCompletionList = {}));\n/**\n * Describes how an {@link InlineCompletionItemProvider inline completion provider} was triggered.\n *\n * @since 3.18.0\n * @proposed\n */\nexport var InlineCompletionTriggerKind;\n(function (InlineCompletionTriggerKind) {\n /**\n * Completion was triggered explicitly by a user gesture.\n */\n InlineCompletionTriggerKind.Invoked = 0;\n /**\n * Completion was triggered automatically while editing.\n */\n InlineCompletionTriggerKind.Automatic = 1;\n})(InlineCompletionTriggerKind || (InlineCompletionTriggerKind = {}));\nexport var SelectedCompletionInfo;\n(function (SelectedCompletionInfo) {\n function create(range, text) {\n return { range, text };\n }\n SelectedCompletionInfo.create = create;\n})(SelectedCompletionInfo || (SelectedCompletionInfo = {}));\nexport var InlineCompletionContext;\n(function (InlineCompletionContext) {\n function create(triggerKind, selectedCompletionInfo) {\n return { triggerKind, selectedCompletionInfo };\n }\n InlineCompletionContext.create = create;\n})(InlineCompletionContext || (InlineCompletionContext = {}));\nexport var WorkspaceFolder;\n(function (WorkspaceFolder) {\n function is(value) {\n const candidate = value;\n return Is.objectLiteral(candidate) && URI.is(candidate.uri) && Is.string(candidate.name);\n }\n WorkspaceFolder.is = is;\n})(WorkspaceFolder || (WorkspaceFolder = {}));\nexport const EOL = ['\\n', '\\r\\n', '\\r'];\n/**\n * @deprecated Use the text document from the new vscode-languageserver-textdocument package.\n */\nexport var TextDocument;\n(function (TextDocument) {\n /**\n * Creates a new ITextDocument literal from the given uri and content.\n * @param uri The document's uri.\n * @param languageId The document's language Id.\n * @param version The document's version.\n * @param content The document's content.\n */\n function create(uri, languageId, version, content) {\n return new FullTextDocument(uri, languageId, version, content);\n }\n TextDocument.create = create;\n /**\n * Checks whether the given literal conforms to the {@link ITextDocument} interface.\n */\n function is(value) {\n let candidate = value;\n return Is.defined(candidate) && Is.string(candidate.uri) && (Is.undefined(candidate.languageId) || Is.string(candidate.languageId)) && Is.uinteger(candidate.lineCount)\n && Is.func(candidate.getText) && Is.func(candidate.positionAt) && Is.func(candidate.offsetAt) ? true : false;\n }\n TextDocument.is = is;\n function applyEdits(document, edits) {\n let text = document.getText();\n let sortedEdits = mergeSort(edits, (a, b) => {\n let diff = a.range.start.line - b.range.start.line;\n if (diff === 0) {\n return a.range.start.character - b.range.start.character;\n }\n return diff;\n });\n let lastModifiedOffset = text.length;\n for (let i = sortedEdits.length - 1; i >= 0; i--) {\n let e = sortedEdits[i];\n let startOffset = document.offsetAt(e.range.start);\n let endOffset = document.offsetAt(e.range.end);\n if (endOffset <= lastModifiedOffset) {\n text = text.substring(0, startOffset) + e.newText + text.substring(endOffset, text.length);\n }\n else {\n throw new Error('Overlapping edit');\n }\n lastModifiedOffset = startOffset;\n }\n return text;\n }\n TextDocument.applyEdits = applyEdits;\n function mergeSort(data, compare) {\n if (data.length <= 1) {\n // sorted\n return data;\n }\n const p = (data.length / 2) | 0;\n const left = data.slice(0, p);\n const right = data.slice(p);\n mergeSort(left, compare);\n mergeSort(right, compare);\n let leftIdx = 0;\n let rightIdx = 0;\n let i = 0;\n while (leftIdx < left.length && rightIdx < right.length) {\n let ret = compare(left[leftIdx], right[rightIdx]);\n if (ret <= 0) {\n // smaller_equal -> take left to preserve order\n data[i++] = left[leftIdx++];\n }\n else {\n // greater -> take right\n data[i++] = right[rightIdx++];\n }\n }\n while (leftIdx < left.length) {\n data[i++] = left[leftIdx++];\n }\n while (rightIdx < right.length) {\n data[i++] = right[rightIdx++];\n }\n return data;\n }\n})(TextDocument || (TextDocument = {}));\n/**\n * @deprecated Use the text document from the new vscode-languageserver-textdocument package.\n */\nclass FullTextDocument {\n constructor(uri, languageId, version, content) {\n this._uri = uri;\n this._languageId = languageId;\n this._version = version;\n this._content = content;\n this._lineOffsets = undefined;\n }\n get uri() {\n return this._uri;\n }\n get languageId() {\n return this._languageId;\n }\n get version() {\n return this._version;\n }\n getText(range) {\n if (range) {\n let start = this.offsetAt(range.start);\n let end = this.offsetAt(range.end);\n return this._content.substring(start, end);\n }\n return this._content;\n }\n update(event, version) {\n this._content = event.text;\n this._version = version;\n this._lineOffsets = undefined;\n }\n getLineOffsets() {\n if (this._lineOffsets === undefined) {\n let lineOffsets = [];\n let text = this._content;\n let isLineStart = true;\n for (let i = 0; i < text.length; i++) {\n if (isLineStart) {\n lineOffsets.push(i);\n isLineStart = false;\n }\n let ch = text.charAt(i);\n isLineStart = (ch === '\\r' || ch === '\\n');\n if (ch === '\\r' && i + 1 < text.length && text.charAt(i + 1) === '\\n') {\n i++;\n }\n }\n if (isLineStart && text.length > 0) {\n lineOffsets.push(text.length);\n }\n this._lineOffsets = lineOffsets;\n }\n return this._lineOffsets;\n }\n positionAt(offset) {\n offset = Math.max(Math.min(offset, this._content.length), 0);\n let lineOffsets = this.getLineOffsets();\n let low = 0, high = lineOffsets.length;\n if (high === 0) {\n return Position.create(0, offset);\n }\n while (low < high) {\n let mid = Math.floor((low + high) / 2);\n if (lineOffsets[mid] > offset) {\n high = mid;\n }\n else {\n low = mid + 1;\n }\n }\n // low is the least x for which the line offset is larger than the current offset\n // or array.length if no line offset is larger than the current offset\n let line = low - 1;\n return Position.create(line, offset - lineOffsets[line]);\n }\n offsetAt(position) {\n let lineOffsets = this.getLineOffsets();\n if (position.line >= lineOffsets.length) {\n return this._content.length;\n }\n else if (position.line < 0) {\n return 0;\n }\n let lineOffset = lineOffsets[position.line];\n let nextLineOffset = (position.line + 1 < lineOffsets.length) ? lineOffsets[position.line + 1] : this._content.length;\n return Math.max(Math.min(lineOffset + position.character, nextLineOffset), lineOffset);\n }\n get lineCount() {\n return this.getLineOffsets().length;\n }\n}\nvar Is;\n(function (Is) {\n const toString = Object.prototype.toString;\n function defined(value) {\n return typeof value !== 'undefined';\n }\n Is.defined = defined;\n function undefined(value) {\n return typeof value === 'undefined';\n }\n Is.undefined = undefined;\n function boolean(value) {\n return value === true || value === false;\n }\n Is.boolean = boolean;\n function string(value) {\n return toString.call(value) === '[object String]';\n }\n Is.string = string;\n function number(value) {\n return toString.call(value) === '[object Number]';\n }\n Is.number = number;\n function numberRange(value, min, max) {\n return toString.call(value) === '[object Number]' && min <= value && value <= max;\n }\n Is.numberRange = numberRange;\n function integer(value) {\n return toString.call(value) === '[object Number]' && -2147483648 <= value && value <= 2147483647;\n }\n Is.integer = integer;\n function uinteger(value) {\n return toString.call(value) === '[object Number]' && 0 <= value && value <= 2147483647;\n }\n Is.uinteger = uinteger;\n function func(value) {\n return toString.call(value) === '[object Function]';\n }\n Is.func = func;\n function objectLiteral(value) {\n // Strictly speaking class instances pass this check as well. Since the LSP\n // doesn't use classes we ignore this for now. If we do we need to add something\n // like this: `Object.getPrototypeOf(Object.getPrototypeOf(x)) === null`\n return value !== null && typeof value === 'object';\n }\n Is.objectLiteral = objectLiteral;\n function typedArray(value, check) {\n return Array.isArray(value) && value.every(check);\n }\n Is.typedArray = typedArray;\n})(Is || (Is = {}));\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { IToken, TokenType } from 'chevrotain';\nimport type { Range } from 'vscode-languageserver-types';\nimport type { AbstractElement } from '../languages/generated/ast.js';\nimport type { AstNode, CompositeCstNode, CstNode, LeafCstNode, RootCstNode } from '../syntax-tree.js';\nimport { Position } from 'vscode-languageserver-types';\nimport { isCompositeCstNode } from '../syntax-tree.js';\nimport { tokenToRange } from '../utils/cst-utils.js';\n\nexport class CstNodeBuilder {\n\n private rootNode!: RootCstNodeImpl;\n private nodeStack: CompositeCstNodeImpl[] = [];\n\n private get current(): CompositeCstNodeImpl {\n return this.nodeStack[this.nodeStack.length - 1];\n }\n\n buildRootNode(input: string): RootCstNode {\n this.rootNode = new RootCstNodeImpl(input);\n this.rootNode.root = this.rootNode;\n this.nodeStack = [this.rootNode];\n return this.rootNode;\n }\n\n buildCompositeNode(feature: AbstractElement): CompositeCstNode {\n const compositeNode = new CompositeCstNodeImpl();\n compositeNode.grammarSource = feature;\n compositeNode.root = this.rootNode;\n this.current.content.push(compositeNode);\n this.nodeStack.push(compositeNode);\n return compositeNode;\n }\n\n buildLeafNode(token: IToken, feature: AbstractElement): LeafCstNode {\n const leafNode = new LeafCstNodeImpl(token.startOffset, token.image.length, tokenToRange(token), token.tokenType, false);\n leafNode.grammarSource = feature;\n leafNode.root = this.rootNode;\n this.current.content.push(leafNode);\n return leafNode;\n }\n\n removeNode(node: CstNode): void {\n const parent = node.container;\n if (parent) {\n const index = parent.content.indexOf(node);\n if (index >= 0) {\n parent.content.splice(index, 1);\n }\n }\n }\n\n construct(item: { $type: string | symbol | undefined, $cstNode: CstNode }): void {\n const current: CstNode = this.current;\n // The specified item could be a datatype ($type is symbol) or a fragment ($type is undefined)\n // Only if the $type is a string, we actually assign the element\n if (typeof item.$type === 'string') {\n this.current.astNode = item;\n }\n item.$cstNode = current;\n const node = this.nodeStack.pop();\n // Empty composite nodes are not valid\n // Simply remove the node from the tree\n if (node?.content.length === 0) {\n this.removeNode(node);\n }\n }\n\n addHiddenTokens(hiddenTokens: IToken[]): void {\n for (const token of hiddenTokens) {\n const hiddenNode = new LeafCstNodeImpl(token.startOffset, token.image.length, tokenToRange(token), token.tokenType, true);\n hiddenNode.root = this.rootNode;\n this.addHiddenToken(this.rootNode, hiddenNode);\n }\n }\n\n private addHiddenToken(node: CompositeCstNode, token: LeafCstNode): void {\n const { offset: tokenStart, end: tokenEnd } = token;\n\n for (let i = 0; i < node.content.length; i++) {\n const child = node.content[i];\n const { offset: childStart, end: childEnd } = child;\n if (isCompositeCstNode(child) && tokenStart > childStart && tokenEnd < childEnd) {\n this.addHiddenToken(child, token);\n return;\n } else if (tokenEnd <= childStart) {\n node.content.splice(i, 0, token);\n return;\n }\n }\n\n // We know that we haven't found a suited position for the token\n // So we simply add it to the end of the current node\n node.content.push(token);\n }\n}\n\nexport abstract class AbstractCstNode implements CstNode {\n abstract get offset(): number;\n abstract get length(): number;\n abstract get end(): number;\n abstract get range(): Range;\n\n container?: CompositeCstNode;\n grammarSource: AbstractElement;\n root: RootCstNode;\n private _astNode?: AstNode;\n\n /** @deprecated use `container` instead. */\n get parent(): CompositeCstNode | undefined {\n return this.container;\n }\n\n /** @deprecated use `grammarSource` instead. */\n get feature(): AbstractElement {\n return this.grammarSource;\n }\n\n get hidden(): boolean {\n return false;\n }\n\n get astNode(): AstNode {\n const node = typeof this._astNode?.$type === 'string' ? this._astNode : this.container?.astNode;\n if (!node) {\n throw new Error('This node has no associated AST element');\n }\n return node;\n }\n\n set astNode(value: AstNode) {\n this._astNode = value;\n }\n\n /** @deprecated use `astNode` instead. */\n get element(): AstNode {\n return this.astNode;\n }\n\n get text(): string {\n return this.root.fullText.substring(this.offset, this.end);\n }\n}\n\nexport class LeafCstNodeImpl extends AbstractCstNode implements LeafCstNode {\n get offset(): number {\n return this._offset;\n }\n\n get length(): number {\n return this._length;\n }\n\n get end(): number {\n return this._offset + this._length;\n }\n\n override get hidden(): boolean {\n return this._hidden;\n }\n\n get tokenType(): TokenType {\n return this._tokenType;\n }\n\n get range(): Range {\n return this._range;\n }\n\n private _hidden: boolean;\n private _offset: number;\n private _length: number;\n private _range: Range;\n private _tokenType: TokenType;\n\n constructor(offset: number, length: number, range: Range, tokenType: TokenType, hidden = false) {\n super();\n this._hidden = hidden;\n this._offset = offset;\n this._tokenType = tokenType;\n this._length = length;\n this._range = range;\n }\n}\n\nexport class CompositeCstNodeImpl extends AbstractCstNode implements CompositeCstNode {\n readonly content: CstNode[] = new CstNodeContainer(this);\n private _rangeCache?: Range;\n\n /** @deprecated use `content` instead. */\n get children(): CstNode[] {\n return this.content;\n }\n\n get offset(): number {\n return this.firstNonHiddenNode?.offset ?? 0;\n }\n\n get length(): number {\n return this.end - this.offset;\n }\n\n get end(): number {\n return this.lastNonHiddenNode?.end ?? 0;\n }\n\n get range(): Range {\n const firstNode = this.firstNonHiddenNode;\n const lastNode = this.lastNonHiddenNode;\n if (firstNode && lastNode) {\n if (this._rangeCache === undefined) {\n const { range: firstRange } = firstNode;\n const { range: lastRange } = lastNode;\n this._rangeCache = { start: firstRange.start, end: lastRange.end.line < firstRange.start.line ? firstRange.start : lastRange.end };\n }\n return this._rangeCache;\n } else {\n return { start: Position.create(0, 0), end: Position.create(0, 0) };\n }\n }\n\n private get firstNonHiddenNode(): CstNode | undefined {\n for (const child of this.content) {\n if (!child.hidden) {\n return child;\n }\n }\n return this.content[0];\n }\n\n private get lastNonHiddenNode(): CstNode | undefined {\n for (let i = this.content.length - 1; i >= 0; i--) {\n const child = this.content[i];\n if (!child.hidden) {\n return child;\n }\n }\n return this.content[this.content.length - 1];\n }\n}\n\nclass CstNodeContainer extends Array {\n readonly parent: CompositeCstNode;\n\n constructor(parent: CompositeCstNode) {\n super();\n this.parent = parent;\n Object.setPrototypeOf(this, CstNodeContainer.prototype);\n }\n\n override push(...items: CstNode[]): number {\n this.addParents(items);\n return super.push(...items);\n }\n\n override unshift(...items: CstNode[]): number {\n this.addParents(items);\n return super.unshift(...items);\n }\n\n override splice(start: number, count: number, ...items: CstNode[]): CstNode[] {\n this.addParents(items);\n return super.splice(start, count, ...items);\n }\n\n private addParents(items: CstNode[]): void {\n for (const item of items) {\n (item).container = this.parent;\n }\n }\n}\n\nexport class RootCstNodeImpl extends CompositeCstNodeImpl implements RootCstNode {\n private _text = '';\n\n override get text(): string {\n return this._text.substring(this.offset, this.end);\n }\n\n get fullText(): string {\n return this._text;\n }\n\n constructor(input?: string) {\n super();\n this._text = input ?? '';\n }\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport type { DSLMethodOpts, ILexingError, IOrAlt, IParserErrorMessageProvider, IRecognitionException, IToken, TokenType, TokenVocabulary } from 'chevrotain';\nimport type { AbstractElement, Action, Assignment, ParserRule } from '../languages/generated/ast.js';\nimport type { Linker } from '../references/linker.js';\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, AstReflection, CompositeCstNode, CstNode } from '../syntax-tree.js';\nimport type { Lexer } from './lexer.js';\nimport type { IParserConfig } from './parser-config.js';\nimport type { ValueConverter } from './value-converter.js';\nimport { defaultParserErrorProvider, EmbeddedActionsParser, LLkLookaheadStrategy } from 'chevrotain';\nimport { LLStarLookaheadStrategy } from 'chevrotain-allstar';\nimport { isAssignment, isCrossReference, isKeyword } from '../languages/generated/ast.js';\nimport { getTypeName, isDataTypeRule } from '../utils/grammar-utils.js';\nimport { assignMandatoryProperties, getContainerOfType, linkContentToContainer } from '../utils/ast-utils.js';\nimport { CstNodeBuilder } from './cst-node-builder.js';\n\nexport type ParseResult = {\n value: T,\n parserErrors: IRecognitionException[],\n lexerErrors: ILexingError[]\n}\n\nexport const DatatypeSymbol = Symbol('Datatype');\n\ninterface DataTypeNode {\n $cstNode: CompositeCstNode\n /** Instead of a string, this node is uniquely identified by the `Datatype` symbol */\n $type: symbol\n /** Used as a storage for all parsed terminals, keywords and sub-datatype rules */\n value: string\n}\n\nfunction isDataTypeNode(node: { $type: string | symbol | undefined }): node is DataTypeNode {\n return node.$type === DatatypeSymbol;\n}\n\ntype RuleResult = (args: Args) => any;\n\ntype Args = Record;\n\ntype RuleImpl = (args: Args) => any;\n\ninterface AssignmentElement {\n assignment?: Assignment\n isCrossRef: boolean\n}\n\nexport interface BaseParser {\n rule(rule: ParserRule, impl: RuleImpl): RuleResult;\n alternatives(idx: number, choices: Array>): void;\n optional(idx: number, callback: DSLMethodOpts): void;\n many(idx: number, callback: DSLMethodOpts): void;\n atLeastOne(idx: number, callback: DSLMethodOpts): void;\n consume(idx: number, tokenType: TokenType, feature: AbstractElement): void;\n subrule(idx: number, rule: RuleResult, feature: AbstractElement, args: Args): void;\n action($type: string, action: Action): void;\n construct(): unknown;\n isRecording(): boolean;\n get unorderedGroups(): Map;\n getRuleStack(): number[];\n}\n\nconst ruleSuffix = '\\u200B';\nconst withRuleSuffix = (name: string): string => name.endsWith(ruleSuffix) ? name : name + ruleSuffix;\n\nexport abstract class AbstractLangiumParser implements BaseParser {\n\n protected readonly lexer: Lexer;\n protected readonly wrapper: ChevrotainWrapper;\n protected _unorderedGroups: Map = new Map();\n\n constructor(services: LangiumCoreServices) {\n this.lexer = services.parser.Lexer;\n const tokens = this.lexer.definition;\n this.wrapper = new ChevrotainWrapper(tokens, {\n ...services.parser.ParserConfig,\n errorMessageProvider: services.parser.ParserErrorMessageProvider\n });\n }\n\n alternatives(idx: number, choices: Array>): void {\n this.wrapper.wrapOr(idx, choices);\n }\n\n optional(idx: number, callback: DSLMethodOpts): void {\n this.wrapper.wrapOption(idx, callback);\n }\n\n many(idx: number, callback: DSLMethodOpts): void {\n this.wrapper.wrapMany(idx, callback);\n }\n\n atLeastOne(idx: number, callback: DSLMethodOpts): void {\n this.wrapper.wrapAtLeastOne(idx, callback);\n }\n\n abstract rule(rule: ParserRule, impl: RuleImpl): RuleResult;\n abstract consume(idx: number, tokenType: TokenType, feature: AbstractElement): void;\n abstract subrule(idx: number, rule: RuleResult, feature: AbstractElement, args: Args): void;\n abstract action($type: string, action: Action): void;\n abstract construct(): unknown;\n\n isRecording(): boolean {\n return this.wrapper.IS_RECORDING;\n }\n\n get unorderedGroups(): Map {\n return this._unorderedGroups;\n }\n\n getRuleStack(): number[] {\n return (this.wrapper as any).RULE_STACK;\n }\n\n finalize(): void {\n this.wrapper.wrapSelfAnalysis();\n }\n}\n\nexport class LangiumParser extends AbstractLangiumParser {\n private readonly linker: Linker;\n private readonly converter: ValueConverter;\n private readonly astReflection: AstReflection;\n private readonly nodeBuilder = new CstNodeBuilder();\n private stack: any[] = [];\n private mainRule!: RuleResult;\n private assignmentMap = new Map();\n\n private get current(): any {\n return this.stack[this.stack.length - 1];\n }\n\n constructor(services: LangiumCoreServices) {\n super(services);\n this.linker = services.references.Linker;\n this.converter = services.parser.ValueConverter;\n this.astReflection = services.shared.AstReflection;\n }\n\n rule(rule: ParserRule, impl: RuleImpl): RuleResult {\n const type = rule.fragment ? undefined : isDataTypeRule(rule) ? DatatypeSymbol : getTypeName(rule);\n const ruleMethod = this.wrapper.DEFINE_RULE(withRuleSuffix(rule.name), this.startImplementation(type, impl).bind(this));\n if (rule.entry) {\n this.mainRule = ruleMethod;\n }\n return ruleMethod;\n }\n\n parse(input: string): ParseResult {\n this.nodeBuilder.buildRootNode(input);\n const lexerResult = this.lexer.tokenize(input);\n this.wrapper.input = lexerResult.tokens;\n const result = this.mainRule.call(this.wrapper, {});\n this.nodeBuilder.addHiddenTokens(lexerResult.hidden);\n this.unorderedGroups.clear();\n return {\n value: result,\n lexerErrors: lexerResult.errors,\n parserErrors: this.wrapper.errors\n };\n }\n\n private startImplementation($type: string | symbol | undefined, implementation: RuleImpl): RuleImpl {\n return (args) => {\n if (!this.isRecording()) {\n const node: any = { $type };\n this.stack.push(node);\n if ($type === DatatypeSymbol) {\n node.value = '';\n }\n }\n let result: unknown;\n try {\n result = implementation(args);\n } catch (err) {\n result = undefined;\n }\n if (!this.isRecording() && result === undefined) {\n result = this.construct();\n }\n return result;\n };\n }\n\n consume(idx: number, tokenType: TokenType, feature: AbstractElement): void {\n const token = this.wrapper.wrapConsume(idx, tokenType);\n if (!this.isRecording() && this.isValidToken(token)) {\n const leafNode = this.nodeBuilder.buildLeafNode(token, feature);\n const { assignment, isCrossRef } = this.getAssignment(feature);\n const current = this.current;\n if (assignment) {\n const convertedValue = isKeyword(feature) ? token.image : this.converter.convert(token.image, leafNode);\n this.assign(assignment.operator, assignment.feature, convertedValue, leafNode, isCrossRef);\n } else if (isDataTypeNode(current)) {\n let text = token.image;\n if (!isKeyword(feature)) {\n text = this.converter.convert(text, leafNode).toString();\n }\n current.value += text;\n }\n }\n }\n\n /**\n * Most consumed parser tokens are valid. However there are two cases in which they are not valid:\n *\n * 1. They were inserted during error recovery by the parser. These tokens don't really exist and should not be further processed\n * 2. They contain invalid token ranges. This might include the special EOF token, or other tokens produced by invalid token builders.\n */\n private isValidToken(token: IToken): boolean {\n return !token.isInsertedInRecovery && !isNaN(token.startOffset) && typeof token.endOffset === 'number' && !isNaN(token.endOffset);\n }\n\n subrule(idx: number, rule: RuleResult, feature: AbstractElement, args: Args): void {\n let cstNode: CompositeCstNode | undefined;\n if (!this.isRecording()) {\n cstNode = this.nodeBuilder.buildCompositeNode(feature);\n }\n const subruleResult = this.wrapper.wrapSubrule(idx, rule, args) as any;\n if (!this.isRecording() && cstNode && cstNode.length > 0) {\n this.performSubruleAssignment(subruleResult, feature, cstNode);\n }\n }\n\n private performSubruleAssignment(result: any, feature: AbstractElement, cstNode: CompositeCstNode): void {\n const { assignment, isCrossRef } = this.getAssignment(feature);\n if (assignment) {\n this.assign(assignment.operator, assignment.feature, result, cstNode, isCrossRef);\n } else if (!assignment) {\n // If we call a subrule without an assignment we either:\n // 1. append the result of the subrule (data type rule)\n // 2. override the current object with the newly parsed object\n // If the current element is an AST node and the result of the subrule\n // is a data type rule, we can safely discard the results.\n const current = this.current;\n if (isDataTypeNode(current)) {\n current.value += result.toString();\n } else if (typeof result === 'object' && result) {\n const resultKind = result.$type;\n const object = this.assignWithoutOverride(result, current);\n if (resultKind) {\n object.$type = resultKind;\n }\n const newItem = object;\n this.stack.pop();\n this.stack.push(newItem);\n }\n }\n }\n\n action($type: string, action: Action): void {\n if (!this.isRecording()) {\n let last = this.current;\n // This branch is used for left recursive grammar rules.\n // Those don't call `construct` before another action.\n // Therefore, we need to call it here.\n if (!last.$cstNode && action.feature && action.operator) {\n last = this.construct(false);\n const feature = last.$cstNode.feature;\n this.nodeBuilder.buildCompositeNode(feature);\n }\n const newItem = { $type };\n this.stack.pop();\n this.stack.push(newItem);\n if (action.feature && action.operator) {\n this.assign(action.operator, action.feature, last, last.$cstNode, false);\n }\n }\n }\n\n construct(pop = true): unknown {\n if (this.isRecording()) {\n return undefined;\n }\n const obj = this.current;\n linkContentToContainer(obj);\n this.nodeBuilder.construct(obj);\n if (pop) {\n this.stack.pop();\n }\n if (isDataTypeNode(obj)) {\n return this.converter.convert(obj.value, obj.$cstNode);\n } else {\n assignMandatoryProperties(this.astReflection, obj);\n }\n return obj;\n }\n\n private getAssignment(feature: AbstractElement): AssignmentElement {\n if (!this.assignmentMap.has(feature)) {\n const assignment = getContainerOfType(feature, isAssignment);\n this.assignmentMap.set(feature, {\n assignment: assignment,\n isCrossRef: assignment ? isCrossReference(assignment.terminal) : false\n });\n }\n return this.assignmentMap.get(feature)!;\n }\n\n private assign(operator: string, feature: string, value: unknown, cstNode: CstNode, isCrossRef: boolean): void {\n const obj = this.current;\n let item: unknown;\n if (isCrossRef && typeof value === 'string') {\n item = this.linker.buildReference(obj, feature, cstNode, value);\n } else {\n item = value;\n }\n switch (operator) {\n case '=': {\n obj[feature] = item;\n break;\n }\n case '?=': {\n obj[feature] = true;\n break;\n }\n case '+=': {\n if (!Array.isArray(obj[feature])) {\n obj[feature] = [];\n }\n obj[feature].push(item);\n }\n }\n }\n\n private assignWithoutOverride(target: any, source: any): any {\n for (const [name, existingValue] of Object.entries(source)) {\n const newValue = target[name];\n if (newValue === undefined) {\n target[name] = existingValue;\n } else if (Array.isArray(newValue) && Array.isArray(existingValue)) {\n existingValue.push(...newValue);\n target[name] = existingValue;\n }\n }\n return target;\n }\n\n get definitionErrors(): IParserDefinitionError[] {\n return this.wrapper.definitionErrors;\n }\n}\n\nexport interface IParserDefinitionError {\n message: string\n type: number\n ruleName?: string\n}\n\nexport abstract class AbstractParserErrorMessageProvider implements IParserErrorMessageProvider {\n\n buildMismatchTokenMessage(options: {\n expected: TokenType\n actual: IToken\n previous: IToken\n ruleName: string\n }): string {\n return defaultParserErrorProvider.buildMismatchTokenMessage(options);\n }\n\n buildNotAllInputParsedMessage(options: {\n firstRedundant: IToken\n ruleName: string\n }): string {\n return defaultParserErrorProvider.buildNotAllInputParsedMessage(options);\n }\n\n buildNoViableAltMessage(options: {\n expectedPathsPerAlt: TokenType[][][]\n actual: IToken[]\n previous: IToken\n customUserDescription: string\n ruleName: string\n }): string {\n return defaultParserErrorProvider.buildNoViableAltMessage(options);\n }\n\n buildEarlyExitMessage(options: {\n expectedIterationPaths: TokenType[][]\n actual: IToken[]\n previous: IToken\n customUserDescription: string\n ruleName: string\n }): string {\n return defaultParserErrorProvider.buildEarlyExitMessage(options);\n }\n\n}\n\nexport class LangiumParserErrorMessageProvider extends AbstractParserErrorMessageProvider {\n\n override buildMismatchTokenMessage({ expected, actual }: {\n expected: TokenType\n actual: IToken\n previous: IToken\n ruleName: string\n }): string {\n const expectedMsg = expected.LABEL\n ? '`' + expected.LABEL + '`'\n : expected.name.endsWith(':KW')\n ? `keyword '${expected.name.substring(0, expected.name.length - 3)}'`\n : `token of type '${expected.name}'`;\n return `Expecting ${expectedMsg} but found \\`${actual.image}\\`.`;\n }\n\n override buildNotAllInputParsedMessage({ firstRedundant }: {\n firstRedundant: IToken\n ruleName: string\n }): string {\n return `Expecting end of file but found \\`${firstRedundant.image}\\`.`;\n }\n}\n\nexport interface CompletionParserResult {\n tokens: IToken[]\n elementStack: AbstractElement[]\n tokenIndex: number\n}\n\nexport class LangiumCompletionParser extends AbstractLangiumParser {\n private mainRule!: RuleResult;\n private tokens: IToken[] = [];\n\n private elementStack: AbstractElement[] = [];\n private lastElementStack: AbstractElement[] = [];\n private nextTokenIndex = 0;\n private stackSize = 0;\n\n action(): void {\n // NOOP\n }\n\n construct(): unknown {\n // NOOP\n return undefined;\n }\n\n parse(input: string): CompletionParserResult {\n this.resetState();\n const tokens = this.lexer.tokenize(input);\n this.tokens = tokens.tokens;\n this.wrapper.input = [...this.tokens];\n this.mainRule.call(this.wrapper, {});\n this.unorderedGroups.clear();\n return {\n tokens: this.tokens,\n elementStack: [...this.lastElementStack],\n tokenIndex: this.nextTokenIndex\n };\n }\n\n rule(rule: ParserRule, impl: RuleImpl): RuleResult {\n const ruleMethod = this.wrapper.DEFINE_RULE(withRuleSuffix(rule.name), this.startImplementation(impl).bind(this));\n if (rule.entry) {\n this.mainRule = ruleMethod;\n }\n return ruleMethod;\n }\n\n private resetState(): void {\n this.elementStack = [];\n this.lastElementStack = [];\n this.nextTokenIndex = 0;\n this.stackSize = 0;\n }\n\n private startImplementation(implementation: RuleImpl): RuleImpl {\n return (args) => {\n const size = this.keepStackSize();\n try {\n implementation(args);\n } finally {\n this.resetStackSize(size);\n }\n };\n }\n\n private removeUnexpectedElements(): void {\n this.elementStack.splice(this.stackSize);\n }\n\n keepStackSize(): number {\n const size = this.elementStack.length;\n this.stackSize = size;\n return size;\n }\n\n resetStackSize(size: number): void {\n this.removeUnexpectedElements();\n this.stackSize = size;\n }\n\n consume(idx: number, tokenType: TokenType, feature: AbstractElement): void {\n this.wrapper.wrapConsume(idx, tokenType);\n if (!this.isRecording()) {\n this.lastElementStack = [...this.elementStack, feature];\n this.nextTokenIndex = this.currIdx + 1;\n }\n }\n\n subrule(idx: number, rule: RuleResult, feature: AbstractElement, args: Args): void {\n this.before(feature);\n this.wrapper.wrapSubrule(idx, rule, args);\n this.after(feature);\n }\n\n before(element: AbstractElement): void {\n if (!this.isRecording()) {\n this.elementStack.push(element);\n }\n }\n\n after(element: AbstractElement): void {\n if (!this.isRecording()) {\n const index = this.elementStack.lastIndexOf(element);\n if (index >= 0) {\n this.elementStack.splice(index);\n }\n }\n }\n\n get currIdx(): number {\n return (this.wrapper as any).currIdx;\n }\n}\n\nconst defaultConfig: IParserConfig = {\n recoveryEnabled: true,\n nodeLocationTracking: 'full',\n skipValidations: true,\n errorMessageProvider: new LangiumParserErrorMessageProvider()\n};\n\n/**\n * This class wraps the embedded actions parser of chevrotain and exposes protected methods.\n * This way, we can build the `LangiumParser` as a composition.\n */\nclass ChevrotainWrapper extends EmbeddedActionsParser {\n\n // This array is set in the base implementation of Chevrotain.\n definitionErrors: IParserDefinitionError[];\n\n constructor(tokens: TokenVocabulary, config?: IParserConfig) {\n const useDefaultLookahead = config && 'maxLookahead' in config;\n super(tokens, {\n ...defaultConfig,\n lookaheadStrategy: useDefaultLookahead\n ? new LLkLookaheadStrategy({ maxLookahead: config.maxLookahead })\n : new LLStarLookaheadStrategy(),\n ...config,\n });\n }\n\n get IS_RECORDING(): boolean {\n return this.RECORDING_PHASE;\n }\n\n DEFINE_RULE(name: string, impl: RuleImpl): RuleResult {\n return this.RULE(name, impl);\n }\n\n wrapSelfAnalysis(): void {\n this.performSelfAnalysis();\n }\n\n wrapConsume(idx: number, tokenType: TokenType): IToken {\n return this.consume(idx, tokenType);\n }\n\n wrapSubrule(idx: number, rule: RuleResult, args: Args): unknown {\n return this.subrule(idx, rule, {\n ARGS: [args]\n });\n }\n\n wrapOr(idx: number, choices: Array>): void {\n this.or(idx, choices);\n }\n\n wrapOption(idx: number, callback: DSLMethodOpts): void {\n this.option(idx, callback);\n }\n\n wrapMany(idx: number, callback: DSLMethodOpts): void {\n this.many(idx, callback);\n }\n\n wrapAtLeastOne(idx: number, callback: DSLMethodOpts): void {\n this.atLeastOne(idx, callback);\n }\n}\n", "/******************************************************************************\n * Copyright 2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { IOrAlt, TokenType, TokenTypeDictionary } from 'chevrotain';\nimport type { AbstractElement, Action, Alternatives, Condition, CrossReference, Grammar, Group, Keyword, NamedArgument, ParserRule, RuleCall, UnorderedGroup } from '../languages/generated/ast.js';\nimport type { BaseParser } from './langium-parser.js';\nimport type { AstNode } from '../syntax-tree.js';\nimport type { Cardinality } from '../utils/grammar-utils.js';\nimport { EMPTY_ALT, EOF } from 'chevrotain';\nimport { isAction, isAlternatives, isEndOfFile, isAssignment, isConjunction, isCrossReference, isDisjunction, isGroup, isKeyword, isNegation, isParameterReference, isParserRule, isRuleCall, isTerminalRule, isUnorderedGroup, isBooleanLiteral } from '../languages/generated/ast.js';\nimport { assertUnreachable, ErrorWithLocation } from '../utils/errors.js';\nimport { stream } from '../utils/stream.js';\nimport { findNameAssignment, getAllReachableRules, getTypeName } from '../utils/grammar-utils.js';\n\ntype RuleContext = {\n optional: number,\n consume: number,\n subrule: number,\n many: number,\n or: number\n} & ParserContext;\n\ntype ParserContext = {\n parser: BaseParser\n tokens: TokenTypeDictionary\n rules: Map\n ruleNames: Map\n}\n\ntype Rule = (args: Args) => unknown;\n\ntype Args = Record;\n\ntype Predicate = (args: Args) => boolean;\n\ntype Method = (args: Args) => void;\n\nexport function createParser(grammar: Grammar, parser: T, tokens: TokenTypeDictionary): T {\n const rules = new Map();\n const parserContext: ParserContext = {\n parser,\n tokens,\n rules,\n ruleNames: new Map()\n };\n buildRules(parserContext, grammar);\n return parser;\n}\n\nfunction buildRules(parserContext: ParserContext, grammar: Grammar): void {\n const reachable = getAllReachableRules(grammar, false);\n const parserRules = stream(grammar.rules).filter(isParserRule).filter(rule => reachable.has(rule));\n for (const rule of parserRules) {\n const ctx: RuleContext = {\n ...parserContext,\n consume: 1,\n optional: 1,\n subrule: 1,\n many: 1,\n or: 1\n };\n ctx.rules.set(\n rule.name,\n parserContext.parser.rule(rule, buildElement(ctx, rule.definition))\n );\n }\n}\n\nfunction buildElement(ctx: RuleContext, element: AbstractElement, ignoreGuard = false): Method {\n let method: Method;\n if (isKeyword(element)) {\n method = buildKeyword(ctx, element);\n } else if (isAction(element)) {\n method = buildAction(ctx, element);\n } else if (isAssignment(element)) {\n method = buildElement(ctx, element.terminal);\n } else if (isCrossReference(element)) {\n method = buildCrossReference(ctx, element);\n } else if (isRuleCall(element)) {\n method = buildRuleCall(ctx, element);\n } else if (isAlternatives(element)) {\n method = buildAlternatives(ctx, element);\n } else if (isUnorderedGroup(element)) {\n method = buildUnorderedGroup(ctx, element);\n } else if (isGroup(element)) {\n method = buildGroup(ctx, element);\n } else if(isEndOfFile(element)) {\n const idx = ctx.consume++;\n method = () => ctx.parser.consume(idx, EOF, element);\n } else {\n throw new ErrorWithLocation(element.$cstNode, `Unexpected element type: ${element.$type}`);\n }\n return wrap(ctx, ignoreGuard ? undefined : getGuardCondition(element), method, element.cardinality);\n}\n\nfunction buildAction(ctx: RuleContext, action: Action): Method {\n const actionType = getTypeName(action);\n return () => ctx.parser.action(actionType, action);\n}\n\nfunction buildRuleCall(ctx: RuleContext, ruleCall: RuleCall): Method {\n const rule = ruleCall.rule.ref;\n if (isParserRule(rule)) {\n const idx = ctx.subrule++;\n const predicate = ruleCall.arguments.length > 0 ? buildRuleCallPredicate(rule, ruleCall.arguments) : () => ({});\n return (args) => ctx.parser.subrule(idx, getRule(ctx, rule), ruleCall, predicate(args));\n } else if (isTerminalRule(rule)) {\n const idx = ctx.consume++;\n const method = getToken(ctx, rule.name);\n return () => ctx.parser.consume(idx, method, ruleCall);\n } else if (!rule) {\n throw new ErrorWithLocation(ruleCall.$cstNode, `Undefined rule type: ${ruleCall.$type}`);\n } else {\n assertUnreachable(rule);\n }\n}\n\nfunction buildRuleCallPredicate(rule: ParserRule, namedArgs: NamedArgument[]): (args: Args) => Args {\n const predicates = namedArgs.map(e => buildPredicate(e.value));\n return (args) => {\n const ruleArgs: Args = {};\n for (let i = 0; i < predicates.length; i++) {\n const ruleTarget = rule.parameters[i];\n const predicate = predicates[i];\n ruleArgs[ruleTarget.name] = predicate(args);\n }\n return ruleArgs;\n };\n}\n\ninterface PredicatedMethod {\n ALT: Method,\n GATE?: Predicate\n}\n\nfunction buildPredicate(condition: Condition): Predicate {\n if (isDisjunction(condition)) {\n const left = buildPredicate(condition.left);\n const right = buildPredicate(condition.right);\n return (args) => (left(args) || right(args));\n } else if (isConjunction(condition)) {\n const left = buildPredicate(condition.left);\n const right = buildPredicate(condition.right);\n return (args) => (left(args) && right(args));\n } else if (isNegation(condition)) {\n const value = buildPredicate(condition.value);\n return (args) => !value(args);\n } else if (isParameterReference(condition)) {\n const name = condition.parameter.ref!.name;\n return (args) => args !== undefined && args[name] === true;\n } else if (isBooleanLiteral(condition)) {\n const value = Boolean(condition.true);\n return () => value;\n }\n assertUnreachable(condition);\n}\n\nfunction buildAlternatives(ctx: RuleContext, alternatives: Alternatives): Method {\n if (alternatives.elements.length === 1) {\n return buildElement(ctx, alternatives.elements[0]);\n } else {\n const methods: PredicatedMethod[] = [];\n\n for (const element of alternatives.elements) {\n const predicatedMethod: PredicatedMethod = {\n // Since we handle the guard condition in the alternative already\n // We can ignore the group guard condition inside\n ALT: buildElement(ctx, element, true)\n };\n const guard = getGuardCondition(element);\n if (guard) {\n predicatedMethod.GATE = buildPredicate(guard);\n }\n methods.push(predicatedMethod);\n }\n\n const idx = ctx.or++;\n return (args) => ctx.parser.alternatives(idx, methods.map(method => {\n const alt: IOrAlt = {\n ALT: () => method.ALT(args)\n };\n const gate = method.GATE;\n if (gate) {\n alt.GATE = () => gate(args);\n }\n return alt;\n }));\n }\n}\n\nfunction buildUnorderedGroup(ctx: RuleContext, group: UnorderedGroup): Method {\n if (group.elements.length === 1) {\n return buildElement(ctx, group.elements[0]);\n }\n const methods: PredicatedMethod[] = [];\n\n for (const element of group.elements) {\n const predicatedMethod: PredicatedMethod = {\n // Since we handle the guard condition in the alternative already\n // We can ignore the group guard condition inside\n ALT: buildElement(ctx, element, true)\n };\n const guard = getGuardCondition(element);\n if (guard) {\n predicatedMethod.GATE = buildPredicate(guard);\n }\n methods.push(predicatedMethod);\n }\n\n const orIdx = ctx.or++;\n\n const idFunc = (groupIdx: number, lParser: BaseParser) => {\n const stackId = lParser.getRuleStack().join('-');\n return `uGroup_${groupIdx}_${stackId}`;\n };\n const alternatives: Method = (args) => ctx.parser.alternatives(orIdx, methods.map((method, idx) => {\n const alt: IOrAlt = { ALT: () => true };\n const parser = ctx.parser;\n alt.ALT = () => {\n method.ALT(args);\n if (!parser.isRecording()) {\n const key = idFunc(orIdx, parser);\n if (!parser.unorderedGroups.get(key)) {\n // init after clear state\n parser.unorderedGroups.set(key, []);\n }\n const groupState = parser.unorderedGroups.get(key)!;\n if (typeof groupState?.[idx] === 'undefined') {\n // Not accessed yet\n groupState[idx] = true;\n }\n }\n };\n const gate = method.GATE;\n if (gate) {\n alt.GATE = () => gate(args);\n } else {\n alt.GATE = () => {\n const trackedAlternatives = parser.unorderedGroups.get(idFunc(orIdx, parser));\n const allow = !trackedAlternatives?.[idx];\n return allow;\n };\n }\n return alt;\n }));\n const wrapped = wrap(ctx, getGuardCondition(group), alternatives, '*');\n return (args) => {\n wrapped(args);\n if (!ctx.parser.isRecording()) {\n ctx.parser.unorderedGroups.delete(idFunc(orIdx, ctx.parser));\n }\n };\n}\n\nfunction buildGroup(ctx: RuleContext, group: Group): Method {\n const methods = group.elements.map(e => buildElement(ctx, e));\n return (args) => methods.forEach(method => method(args));\n}\n\nfunction getGuardCondition(element: AbstractElement): Condition | undefined {\n if (isGroup(element)) {\n return element.guardCondition;\n }\n return undefined;\n}\n\nfunction buildCrossReference(ctx: RuleContext, crossRef: CrossReference, terminal = crossRef.terminal): Method {\n if (!terminal) {\n if (!crossRef.type.ref) {\n throw new Error('Could not resolve reference to type: ' + crossRef.type.$refText);\n }\n const assignment = findNameAssignment(crossRef.type.ref);\n const assignTerminal = assignment?.terminal;\n if (!assignTerminal) {\n throw new Error('Could not find name assignment for type: ' + getTypeName(crossRef.type.ref));\n }\n return buildCrossReference(ctx, crossRef, assignTerminal);\n } else if (isRuleCall(terminal) && isParserRule(terminal.rule.ref)) {\n const idx = ctx.subrule++;\n return (args) => ctx.parser.subrule(idx, getRule(ctx, terminal.rule.ref as ParserRule), crossRef, args);\n } else if (isRuleCall(terminal) && isTerminalRule(terminal.rule.ref)) {\n const idx = ctx.consume++;\n const terminalRule = getToken(ctx, terminal.rule.ref.name);\n return () => ctx.parser.consume(idx, terminalRule, crossRef);\n } else if (isKeyword(terminal)) {\n const idx = ctx.consume++;\n const keyword = getToken(ctx, terminal.value);\n return () => ctx.parser.consume(idx, keyword, crossRef);\n }\n else {\n throw new Error('Could not build cross reference parser');\n }\n}\n\nfunction buildKeyword(ctx: RuleContext, keyword: Keyword): Method {\n const idx = ctx.consume++;\n const token = ctx.tokens[keyword.value];\n if (!token) {\n throw new Error('Could not find token for keyword: ' + keyword.value);\n }\n return () => ctx.parser.consume(idx, token, keyword);\n}\n\nfunction wrap(ctx: RuleContext, guard: Condition | undefined, method: Method, cardinality: Cardinality): Method {\n const gate = guard && buildPredicate(guard);\n\n if (!cardinality) {\n if (gate) {\n const idx = ctx.or++;\n return (args) => ctx.parser.alternatives(idx, [\n {\n ALT: () => method(args),\n GATE: () => gate(args)\n },\n {\n ALT: EMPTY_ALT(),\n GATE: () => !gate(args)\n }\n ]);\n } else {\n return method;\n }\n }\n\n if (cardinality === '*') {\n const idx = ctx.many++;\n return (args) => ctx.parser.many(idx, {\n DEF: () => method(args),\n GATE: gate ? () => gate(args) : undefined\n });\n } else if (cardinality === '+') {\n const idx = ctx.many++;\n if (gate) {\n const orIdx = ctx.or++;\n // In the case of a guard condition for the `+` group\n // We combine it with an empty alternative\n // If the condition returns true, it needs to parse at least a single iteration\n // If its false, it is not allowed to parse anything\n return (args) => ctx.parser.alternatives(orIdx, [\n {\n ALT: () => ctx.parser.atLeastOne(idx, {\n DEF: () => method(args)\n }),\n GATE: () => gate(args)\n },\n {\n ALT: EMPTY_ALT(),\n GATE: () => !gate(args)\n }\n ]);\n } else {\n return (args) => ctx.parser.atLeastOne(idx, {\n DEF: () => method(args),\n });\n }\n } else if (cardinality === '?') {\n const idx = ctx.optional++;\n return (args) => ctx.parser.optional(idx, {\n DEF: () => method(args),\n GATE: gate ? () => gate(args) : undefined\n });\n } else {\n assertUnreachable(cardinality);\n }\n}\n\nfunction getRule(ctx: ParserContext, element: ParserRule | AbstractElement): Rule {\n const name = getRuleName(ctx, element);\n const rule = ctx.rules.get(name);\n if (!rule) throw new Error(`Rule \"${name}\" not found.\"`);\n return rule;\n}\n\nfunction getRuleName(ctx: ParserContext, element: ParserRule | AbstractElement): string {\n if (isParserRule(element)) {\n return element.name;\n } else if (ctx.ruleNames.has(element)) {\n return ctx.ruleNames.get(element)!;\n } else {\n let item: AstNode = element;\n let parent: AstNode = item.$container!;\n let ruleName: string = element.$type;\n while (!isParserRule(parent)) {\n if (isGroup(parent) || isAlternatives(parent) || isUnorderedGroup(parent)) {\n const index = parent.elements.indexOf(item as AbstractElement);\n ruleName = index.toString() + ':' + ruleName;\n }\n item = parent;\n parent = parent.$container!;\n }\n const rule = parent as ParserRule;\n ruleName = rule.name + ':' + ruleName;\n ctx.ruleNames.set(element, ruleName);\n return ruleName;\n }\n}\n\nfunction getToken(ctx: ParserContext, name: string): TokenType {\n const token = ctx.tokens[name];\n if (!token) throw new Error(`Token \"${name}\" not found.\"`);\n return token;\n}\n", "/******************************************************************************\n * Copyright 2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { LangiumCoreServices } from '../services.js';\nimport { LangiumCompletionParser } from './langium-parser.js';\nimport { createParser } from './parser-builder-base.js';\n\nexport function createCompletionParser(services: LangiumCoreServices): LangiumCompletionParser {\n const grammar = services.Grammar;\n const lexer = services.parser.Lexer;\n const parser = new LangiumCompletionParser(services);\n createParser(grammar, parser, lexer.definition);\n parser.finalize();\n return parser;\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { LangiumCoreServices } from '../services.js';\nimport { LangiumParser } from './langium-parser.js';\nimport { createParser } from './parser-builder-base.js';\n\n/**\n * Create and finalize a Langium parser. The parser rules are derived from the grammar, which is\n * available at `services.Grammar`.\n */\nexport function createLangiumParser(services: LangiumCoreServices): LangiumParser {\n const parser = prepareLangiumParser(services);\n parser.finalize();\n return parser;\n}\n\n/**\n * Create a Langium parser without finalizing it. This is used to extract more detailed error\n * information when the parser is initially validated.\n */\nexport function prepareLangiumParser(services: LangiumCoreServices): LangiumParser {\n const grammar = services.Grammar;\n const lexer = services.parser.Lexer;\n const parser = new LangiumParser(services);\n return createParser(grammar, parser, lexer.definition);\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { CustomPatternMatcherFunc, TokenPattern, TokenType, TokenVocabulary } from 'chevrotain';\nimport type { AbstractRule, Grammar, Keyword, TerminalRule } from '../languages/generated/ast.js';\nimport type { Stream } from '../utils/stream.js';\nimport { Lexer } from 'chevrotain';\nimport { isKeyword, isParserRule, isTerminalRule } from '../languages/generated/ast.js';\nimport { streamAllContents } from '../utils/ast-utils.js';\nimport { getAllReachableRules, terminalRegex } from '../utils/grammar-utils.js';\nimport { getCaseInsensitivePattern, isWhitespace, partialMatches } from '../utils/regexp-utils.js';\nimport { stream } from '../utils/stream.js';\n\nexport interface TokenBuilderOptions {\n caseInsensitive?: boolean\n}\n\nexport interface TokenBuilder {\n buildTokens(grammar: Grammar, options?: TokenBuilderOptions): TokenVocabulary;\n}\n\nexport class DefaultTokenBuilder implements TokenBuilder {\n\n buildTokens(grammar: Grammar, options?: TokenBuilderOptions): TokenVocabulary {\n const reachableRules = stream(getAllReachableRules(grammar, false));\n const terminalTokens: TokenType[] = this.buildTerminalTokens(reachableRules);\n const tokens: TokenType[] = this.buildKeywordTokens(reachableRules, terminalTokens, options);\n\n terminalTokens.forEach(terminalToken => {\n const pattern = terminalToken.PATTERN;\n if (typeof pattern === 'object' && pattern && 'test' in pattern && isWhitespace(pattern)) {\n tokens.unshift(terminalToken);\n } else {\n tokens.push(terminalToken);\n }\n });\n // We don't need to add the EOF token explicitly.\n // It is automatically available at the end of the token stream.\n return tokens;\n }\n\n protected buildTerminalTokens(rules: Stream): TokenType[] {\n return rules.filter(isTerminalRule).filter(e => !e.fragment)\n .map(terminal => this.buildTerminalToken(terminal)).toArray();\n }\n\n protected buildTerminalToken(terminal: TerminalRule): TokenType {\n const regex = terminalRegex(terminal);\n const pattern = this.requiresCustomPattern(regex) ? this.regexPatternFunction(regex) : regex;\n const tokenType: TokenType = {\n name: terminal.name,\n PATTERN: pattern,\n LINE_BREAKS: true\n };\n if (terminal.hidden) {\n // Only skip tokens that are able to accept whitespace\n tokenType.GROUP = isWhitespace(regex) ? Lexer.SKIPPED : 'hidden';\n }\n return tokenType;\n }\n\n protected requiresCustomPattern(regex: RegExp): boolean {\n if (regex.flags.includes('u')) {\n // Unicode regexes are not supported by Chevrotain.\n return true;\n } else if (regex.source.includes('?<=') || regex.source.includes('? {\n stickyRegex.lastIndex = offset;\n const execResult = stickyRegex.exec(text);\n return execResult;\n };\n }\n\n protected buildKeywordTokens(rules: Stream, terminalTokens: TokenType[], options?: TokenBuilderOptions): TokenType[] {\n return rules\n // We filter by parser rules, since keywords in terminal rules get transformed into regex and are not actual tokens\n .filter(isParserRule)\n .flatMap(rule => streamAllContents(rule).filter(isKeyword))\n .distinct(e => e.value).toArray()\n // Sort keywords by descending length\n .sort((a, b) => b.value.length - a.value.length)\n .map(keyword => this.buildKeywordToken(keyword, terminalTokens, Boolean(options?.caseInsensitive)));\n }\n\n protected buildKeywordToken(keyword: Keyword, terminalTokens: TokenType[], caseInsensitive: boolean): TokenType {\n return {\n name: keyword.value,\n PATTERN: this.buildKeywordPattern(keyword, caseInsensitive),\n LONGER_ALT: this.findLongerAlt(keyword, terminalTokens)\n };\n }\n\n protected buildKeywordPattern(keyword: Keyword, caseInsensitive: boolean): TokenPattern {\n return caseInsensitive ?\n new RegExp(getCaseInsensitivePattern(keyword.value)) :\n keyword.value;\n }\n\n protected findLongerAlt(keyword: Keyword, terminalTokens: TokenType[]): TokenType[] {\n return terminalTokens.reduce((longerAlts: TokenType[], token) => {\n const pattern = token?.PATTERN as RegExp;\n if (pattern?.source && partialMatches('^' + pattern.source + '$', keyword.value)) {\n longerAlts.push(token);\n }\n return longerAlts;\n }, []);\n }\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { AbstractElement, AbstractRule } from '../languages/generated/ast.js';\nimport type { CstNode } from '../syntax-tree.js';\nimport { isCrossReference, isRuleCall } from '../languages/generated/ast.js';\nimport { getCrossReferenceTerminal, getRuleType } from '../utils/grammar-utils.js';\n\n/**\n * Language-specific service for converting string values from the source text format into a value to be held in the AST.\n */\nexport interface ValueConverter {\n /**\n * Converts a string value from the source text format into a value to be held in the AST.\n */\n convert(input: string, cstNode: CstNode): ValueType;\n}\n\nexport type ValueType = string | number | boolean | bigint | Date;\n\nexport class DefaultValueConverter implements ValueConverter {\n\n convert(input: string, cstNode: CstNode): ValueType {\n let feature: AbstractElement | undefined = cstNode.grammarSource;\n if (isCrossReference(feature)) {\n feature = getCrossReferenceTerminal(feature);\n }\n if (isRuleCall(feature)) {\n const rule = feature.rule.ref;\n if (!rule) {\n throw new Error('This cst node was not parsed by a rule.');\n }\n return this.runConverter(rule, input, cstNode);\n }\n return input;\n }\n\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected runConverter(rule: AbstractRule, input: string, cstNode: CstNode): ValueType {\n switch (rule.name.toUpperCase()) {\n case 'INT': return ValueConverter.convertInt(input);\n case 'STRING': return ValueConverter.convertString(input);\n case 'ID': return ValueConverter.convertID(input);\n }\n switch (getRuleType(rule)?.toLowerCase()) {\n case 'number': return ValueConverter.convertNumber(input);\n case 'boolean': return ValueConverter.convertBoolean(input);\n case 'bigint': return ValueConverter.convertBigint(input);\n case 'date': return ValueConverter.convertDate(input);\n default: return input;\n }\n }\n}\n\nexport namespace ValueConverter {\n\n export function convertString(input: string): string {\n let result = '';\n for (let i = 1; i < input.length - 1; i++) {\n const c = input.charAt(i);\n if (c === '\\\\') {\n const c1 = input.charAt(++i);\n result += convertEscapeCharacter(c1);\n } else {\n result += c;\n }\n }\n return result;\n }\n\n function convertEscapeCharacter(char: string): string {\n switch (char) {\n case 'b': return '\\b';\n case 'f': return '\\f';\n case 'n': return '\\n';\n case 'r': return '\\r';\n case 't': return '\\t';\n case 'v': return '\\v';\n case '0': return '\\0';\n default: return char;\n }\n }\n\n export function convertID(input: string): string {\n if (input.charAt(0) === '^') {\n return input.substring(1);\n } else {\n return input;\n }\n }\n\n export function convertInt(input: string): number {\n return parseInt(input);\n }\n\n export function convertBigint(input: string): bigint {\n return BigInt(input);\n }\n\n export function convertDate(input: string): Date {\n return new Date(input);\n }\n\n export function convertNumber(input: string): number {\n return Number(input);\n }\n\n export function convertBoolean(input: string): boolean {\n return input.toLowerCase() === 'true';\n }\n\n}\n", "\"use strict\";\n/* --------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n * ------------------------------------------------------------------------------------------ */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nlet _ral;\nfunction RAL() {\n if (_ral === undefined) {\n throw new Error(`No runtime abstraction layer installed`);\n }\n return _ral;\n}\n(function (RAL) {\n function install(ral) {\n if (ral === undefined) {\n throw new Error(`No runtime abstraction layer provided`);\n }\n _ral = ral;\n }\n RAL.install = install;\n})(RAL || (RAL = {}));\nexports.default = RAL;\n", "\"use strict\";\n/* --------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n * ------------------------------------------------------------------------------------------ */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.stringArray = exports.array = exports.func = exports.error = exports.number = exports.string = exports.boolean = void 0;\nfunction boolean(value) {\n return value === true || value === false;\n}\nexports.boolean = boolean;\nfunction string(value) {\n return typeof value === 'string' || value instanceof String;\n}\nexports.string = string;\nfunction number(value) {\n return typeof value === 'number' || value instanceof Number;\n}\nexports.number = number;\nfunction error(value) {\n return value instanceof Error;\n}\nexports.error = error;\nfunction func(value) {\n return typeof value === 'function';\n}\nexports.func = func;\nfunction array(value) {\n return Array.isArray(value);\n}\nexports.array = array;\nfunction stringArray(value) {\n return array(value) && value.every(elem => string(elem));\n}\nexports.stringArray = stringArray;\n", "\"use strict\";\n/* --------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n * ------------------------------------------------------------------------------------------ */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Emitter = exports.Event = void 0;\nconst ral_1 = require(\"./ral\");\nvar Event;\n(function (Event) {\n const _disposable = { dispose() { } };\n Event.None = function () { return _disposable; };\n})(Event || (exports.Event = Event = {}));\nclass CallbackList {\n add(callback, context = null, bucket) {\n if (!this._callbacks) {\n this._callbacks = [];\n this._contexts = [];\n }\n this._callbacks.push(callback);\n this._contexts.push(context);\n if (Array.isArray(bucket)) {\n bucket.push({ dispose: () => this.remove(callback, context) });\n }\n }\n remove(callback, context = null) {\n if (!this._callbacks) {\n return;\n }\n let foundCallbackWithDifferentContext = false;\n for (let i = 0, len = this._callbacks.length; i < len; i++) {\n if (this._callbacks[i] === callback) {\n if (this._contexts[i] === context) {\n // callback & context match => remove it\n this._callbacks.splice(i, 1);\n this._contexts.splice(i, 1);\n return;\n }\n else {\n foundCallbackWithDifferentContext = true;\n }\n }\n }\n if (foundCallbackWithDifferentContext) {\n throw new Error('When adding a listener with a context, you should remove it with the same context');\n }\n }\n invoke(...args) {\n if (!this._callbacks) {\n return [];\n }\n const ret = [], callbacks = this._callbacks.slice(0), contexts = this._contexts.slice(0);\n for (let i = 0, len = callbacks.length; i < len; i++) {\n try {\n ret.push(callbacks[i].apply(contexts[i], args));\n }\n catch (e) {\n // eslint-disable-next-line no-console\n (0, ral_1.default)().console.error(e);\n }\n }\n return ret;\n }\n isEmpty() {\n return !this._callbacks || this._callbacks.length === 0;\n }\n dispose() {\n this._callbacks = undefined;\n this._contexts = undefined;\n }\n}\nclass Emitter {\n constructor(_options) {\n this._options = _options;\n }\n /**\n * For the public to allow to subscribe\n * to events from this Emitter\n */\n get event() {\n if (!this._event) {\n this._event = (listener, thisArgs, disposables) => {\n if (!this._callbacks) {\n this._callbacks = new CallbackList();\n }\n if (this._options && this._options.onFirstListenerAdd && this._callbacks.isEmpty()) {\n this._options.onFirstListenerAdd(this);\n }\n this._callbacks.add(listener, thisArgs);\n const result = {\n dispose: () => {\n if (!this._callbacks) {\n // disposable is disposed after emitter is disposed.\n return;\n }\n this._callbacks.remove(listener, thisArgs);\n result.dispose = Emitter._noop;\n if (this._options && this._options.onLastListenerRemove && this._callbacks.isEmpty()) {\n this._options.onLastListenerRemove(this);\n }\n }\n };\n if (Array.isArray(disposables)) {\n disposables.push(result);\n }\n return result;\n };\n }\n return this._event;\n }\n /**\n * To be kept private to fire an event to\n * subscribers\n */\n fire(event) {\n if (this._callbacks) {\n this._callbacks.invoke.call(this._callbacks, event);\n }\n }\n dispose() {\n if (this._callbacks) {\n this._callbacks.dispose();\n this._callbacks = undefined;\n }\n }\n}\nexports.Emitter = Emitter;\nEmitter._noop = function () { };\n", "\"use strict\";\n/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CancellationTokenSource = exports.CancellationToken = void 0;\nconst ral_1 = require(\"./ral\");\nconst Is = require(\"./is\");\nconst events_1 = require(\"./events\");\nvar CancellationToken;\n(function (CancellationToken) {\n CancellationToken.None = Object.freeze({\n isCancellationRequested: false,\n onCancellationRequested: events_1.Event.None\n });\n CancellationToken.Cancelled = Object.freeze({\n isCancellationRequested: true,\n onCancellationRequested: events_1.Event.None\n });\n function is(value) {\n const candidate = value;\n return candidate && (candidate === CancellationToken.None\n || candidate === CancellationToken.Cancelled\n || (Is.boolean(candidate.isCancellationRequested) && !!candidate.onCancellationRequested));\n }\n CancellationToken.is = is;\n})(CancellationToken || (exports.CancellationToken = CancellationToken = {}));\nconst shortcutEvent = Object.freeze(function (callback, context) {\n const handle = (0, ral_1.default)().timer.setTimeout(callback.bind(context), 0);\n return { dispose() { handle.dispose(); } };\n});\nclass MutableToken {\n constructor() {\n this._isCancelled = false;\n }\n cancel() {\n if (!this._isCancelled) {\n this._isCancelled = true;\n if (this._emitter) {\n this._emitter.fire(undefined);\n this.dispose();\n }\n }\n }\n get isCancellationRequested() {\n return this._isCancelled;\n }\n get onCancellationRequested() {\n if (this._isCancelled) {\n return shortcutEvent;\n }\n if (!this._emitter) {\n this._emitter = new events_1.Emitter();\n }\n return this._emitter.event;\n }\n dispose() {\n if (this._emitter) {\n this._emitter.dispose();\n this._emitter = undefined;\n }\n }\n}\nclass CancellationTokenSource {\n get token() {\n if (!this._token) {\n // be lazy and create the token only when\n // actually needed\n this._token = new MutableToken();\n }\n return this._token;\n }\n cancel() {\n if (!this._token) {\n // save an object by returning the default\n // cancelled token when cancellation happens\n // before someone asks for the token\n this._token = CancellationToken.Cancelled;\n }\n else {\n this._token.cancel();\n }\n }\n dispose() {\n if (!this._token) {\n // ensure to initialize with an empty token if we had none\n this._token = CancellationToken.None;\n }\n else if (this._token instanceof MutableToken) {\n // actually dispose\n this._token.dispose();\n }\n }\n}\nexports.CancellationTokenSource = CancellationTokenSource;\n", "/******************************************************************************\n * Copyright 2024 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\n// eslint-disable-next-line no-restricted-imports\nexport * from 'vscode-jsonrpc/lib/common/cancellation.js';\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport { CancellationToken, CancellationTokenSource, type AbstractCancellationTokenSource } from '../utils/cancellation.js';\n\nexport type MaybePromise = T | Promise\n\n/**\n * Delays the execution of the current code to the next tick of the event loop.\n * Don't call this method directly in a tight loop to prevent too many promises from being created.\n */\nexport function delayNextTick(): Promise {\n return new Promise(resolve => {\n // In case we are running in a non-node environment, `setImmediate` isn't available.\n // Using `setTimeout` of the browser API accomplishes the same result.\n if (typeof setImmediate === 'undefined') {\n setTimeout(resolve, 0);\n } else {\n setImmediate(resolve);\n }\n });\n}\n\nlet lastTick = 0;\nlet globalInterruptionPeriod = 10;\n\n/**\n * Reset the global interruption period and create a cancellation token source.\n */\nexport function startCancelableOperation(): AbstractCancellationTokenSource {\n lastTick = Date.now();\n return new CancellationTokenSource();\n}\n\n/**\n * Change the period duration for `interruptAndCheck` to the given number of milliseconds.\n * The default value is 10ms.\n */\nexport function setInterruptionPeriod(period: number): void {\n globalInterruptionPeriod = period;\n}\n\n/**\n * This symbol may be thrown in an asynchronous context by any Langium service that receives\n * a `CancellationToken`. This means that the promise returned by such a service is rejected with\n * this symbol as rejection reason.\n */\nexport const OperationCancelled = Symbol('OperationCancelled');\n\n/**\n * Use this in a `catch` block to check whether the thrown object indicates that the operation\n * has been cancelled.\n */\nexport function isOperationCancelled(err: unknown): err is typeof OperationCancelled {\n return err === OperationCancelled;\n}\n\n/**\n * This function does two things:\n * 1. Check the elapsed time since the last call to this function or to `startCancelableOperation`. If the predefined\n * period (configured with `setInterruptionPeriod`) is exceeded, execution is delayed with `delayNextTick`.\n * 2. If the predefined period is not met yet or execution is resumed after an interruption, the given cancellation\n * token is checked, and if cancellation is requested, `OperationCanceled` is thrown.\n *\n * All services in Langium that receive a `CancellationToken` may potentially call this function, so the\n * `CancellationToken` must be caught (with an `async` try-catch block or a `catch` callback attached to\n * the promise) to avoid that event being exposed as an error.\n */\nexport async function interruptAndCheck(token: CancellationToken): Promise {\n if (token === CancellationToken.None) {\n // Early exit in case cancellation was disabled by the caller\n return;\n }\n const current = Date.now();\n if (current - lastTick >= globalInterruptionPeriod) {\n lastTick = current;\n await delayNextTick();\n }\n if (token.isCancellationRequested) {\n throw OperationCancelled;\n }\n}\n\n/**\n * Simple implementation of the deferred pattern.\n * An object that exposes a promise and functions to resolve and reject it.\n */\nexport class Deferred {\n resolve: (value: T) => this;\n reject: (err?: unknown) => this;\n\n promise = new Promise((resolve, reject) => {\n this.resolve = (arg) => {\n resolve(arg);\n return this;\n };\n this.reject = (err) => {\n reject(err);\n return this;\n };\n });\n}\n", "/* --------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n * ------------------------------------------------------------------------------------------ */\n'use strict';\nclass FullTextDocument {\n constructor(uri, languageId, version, content) {\n this._uri = uri;\n this._languageId = languageId;\n this._version = version;\n this._content = content;\n this._lineOffsets = undefined;\n }\n get uri() {\n return this._uri;\n }\n get languageId() {\n return this._languageId;\n }\n get version() {\n return this._version;\n }\n getText(range) {\n if (range) {\n const start = this.offsetAt(range.start);\n const end = this.offsetAt(range.end);\n return this._content.substring(start, end);\n }\n return this._content;\n }\n update(changes, version) {\n for (const change of changes) {\n if (FullTextDocument.isIncremental(change)) {\n // makes sure start is before end\n const range = getWellformedRange(change.range);\n // update content\n const startOffset = this.offsetAt(range.start);\n const endOffset = this.offsetAt(range.end);\n this._content = this._content.substring(0, startOffset) + change.text + this._content.substring(endOffset, this._content.length);\n // update the offsets\n const startLine = Math.max(range.start.line, 0);\n const endLine = Math.max(range.end.line, 0);\n let lineOffsets = this._lineOffsets;\n const addedLineOffsets = computeLineOffsets(change.text, false, startOffset);\n if (endLine - startLine === addedLineOffsets.length) {\n for (let i = 0, len = addedLineOffsets.length; i < len; i++) {\n lineOffsets[i + startLine + 1] = addedLineOffsets[i];\n }\n }\n else {\n if (addedLineOffsets.length < 10000) {\n lineOffsets.splice(startLine + 1, endLine - startLine, ...addedLineOffsets);\n }\n else { // avoid too many arguments for splice\n this._lineOffsets = lineOffsets = lineOffsets.slice(0, startLine + 1).concat(addedLineOffsets, lineOffsets.slice(endLine + 1));\n }\n }\n const diff = change.text.length - (endOffset - startOffset);\n if (diff !== 0) {\n for (let i = startLine + 1 + addedLineOffsets.length, len = lineOffsets.length; i < len; i++) {\n lineOffsets[i] = lineOffsets[i] + diff;\n }\n }\n }\n else if (FullTextDocument.isFull(change)) {\n this._content = change.text;\n this._lineOffsets = undefined;\n }\n else {\n throw new Error('Unknown change event received');\n }\n }\n this._version = version;\n }\n getLineOffsets() {\n if (this._lineOffsets === undefined) {\n this._lineOffsets = computeLineOffsets(this._content, true);\n }\n return this._lineOffsets;\n }\n positionAt(offset) {\n offset = Math.max(Math.min(offset, this._content.length), 0);\n const lineOffsets = this.getLineOffsets();\n let low = 0, high = lineOffsets.length;\n if (high === 0) {\n return { line: 0, character: offset };\n }\n while (low < high) {\n const mid = Math.floor((low + high) / 2);\n if (lineOffsets[mid] > offset) {\n high = mid;\n }\n else {\n low = mid + 1;\n }\n }\n // low is the least x for which the line offset is larger than the current offset\n // or array.length if no line offset is larger than the current offset\n const line = low - 1;\n offset = this.ensureBeforeEOL(offset, lineOffsets[line]);\n return { line, character: offset - lineOffsets[line] };\n }\n offsetAt(position) {\n const lineOffsets = this.getLineOffsets();\n if (position.line >= lineOffsets.length) {\n return this._content.length;\n }\n else if (position.line < 0) {\n return 0;\n }\n const lineOffset = lineOffsets[position.line];\n if (position.character <= 0) {\n return lineOffset;\n }\n const nextLineOffset = (position.line + 1 < lineOffsets.length) ? lineOffsets[position.line + 1] : this._content.length;\n const offset = Math.min(lineOffset + position.character, nextLineOffset);\n return this.ensureBeforeEOL(offset, lineOffset);\n }\n ensureBeforeEOL(offset, lineOffset) {\n while (offset > lineOffset && isEOL(this._content.charCodeAt(offset - 1))) {\n offset--;\n }\n return offset;\n }\n get lineCount() {\n return this.getLineOffsets().length;\n }\n static isIncremental(event) {\n const candidate = event;\n return candidate !== undefined && candidate !== null &&\n typeof candidate.text === 'string' && candidate.range !== undefined &&\n (candidate.rangeLength === undefined || typeof candidate.rangeLength === 'number');\n }\n static isFull(event) {\n const candidate = event;\n return candidate !== undefined && candidate !== null &&\n typeof candidate.text === 'string' && candidate.range === undefined && candidate.rangeLength === undefined;\n }\n}\nexport var TextDocument;\n(function (TextDocument) {\n /**\n * Creates a new text document.\n *\n * @param uri The document's uri.\n * @param languageId The document's language Id.\n * @param version The document's initial version number.\n * @param content The document's content.\n */\n function create(uri, languageId, version, content) {\n return new FullTextDocument(uri, languageId, version, content);\n }\n TextDocument.create = create;\n /**\n * Updates a TextDocument by modifying its content.\n *\n * @param document the document to update. Only documents created by TextDocument.create are valid inputs.\n * @param changes the changes to apply to the document.\n * @param version the changes version for the document.\n * @returns The updated TextDocument. Note: That's the same document instance passed in as first parameter.\n *\n */\n function update(document, changes, version) {\n if (document instanceof FullTextDocument) {\n document.update(changes, version);\n return document;\n }\n else {\n throw new Error('TextDocument.update: document must be created by TextDocument.create');\n }\n }\n TextDocument.update = update;\n function applyEdits(document, edits) {\n const text = document.getText();\n const sortedEdits = mergeSort(edits.map(getWellformedEdit), (a, b) => {\n const diff = a.range.start.line - b.range.start.line;\n if (diff === 0) {\n return a.range.start.character - b.range.start.character;\n }\n return diff;\n });\n let lastModifiedOffset = 0;\n const spans = [];\n for (const e of sortedEdits) {\n const startOffset = document.offsetAt(e.range.start);\n if (startOffset < lastModifiedOffset) {\n throw new Error('Overlapping edit');\n }\n else if (startOffset > lastModifiedOffset) {\n spans.push(text.substring(lastModifiedOffset, startOffset));\n }\n if (e.newText.length) {\n spans.push(e.newText);\n }\n lastModifiedOffset = document.offsetAt(e.range.end);\n }\n spans.push(text.substr(lastModifiedOffset));\n return spans.join('');\n }\n TextDocument.applyEdits = applyEdits;\n})(TextDocument || (TextDocument = {}));\nfunction mergeSort(data, compare) {\n if (data.length <= 1) {\n // sorted\n return data;\n }\n const p = (data.length / 2) | 0;\n const left = data.slice(0, p);\n const right = data.slice(p);\n mergeSort(left, compare);\n mergeSort(right, compare);\n let leftIdx = 0;\n let rightIdx = 0;\n let i = 0;\n while (leftIdx < left.length && rightIdx < right.length) {\n const ret = compare(left[leftIdx], right[rightIdx]);\n if (ret <= 0) {\n // smaller_equal -> take left to preserve order\n data[i++] = left[leftIdx++];\n }\n else {\n // greater -> take right\n data[i++] = right[rightIdx++];\n }\n }\n while (leftIdx < left.length) {\n data[i++] = left[leftIdx++];\n }\n while (rightIdx < right.length) {\n data[i++] = right[rightIdx++];\n }\n return data;\n}\nfunction computeLineOffsets(text, isAtLineStart, textOffset = 0) {\n const result = isAtLineStart ? [textOffset] : [];\n for (let i = 0; i < text.length; i++) {\n const ch = text.charCodeAt(i);\n if (isEOL(ch)) {\n if (ch === 13 /* CharCode.CarriageReturn */ && i + 1 < text.length && text.charCodeAt(i + 1) === 10 /* CharCode.LineFeed */) {\n i++;\n }\n result.push(textOffset + i + 1);\n }\n }\n return result;\n}\nfunction isEOL(char) {\n return char === 13 /* CharCode.CarriageReturn */ || char === 10 /* CharCode.LineFeed */;\n}\nfunction getWellformedRange(range) {\n const start = range.start;\n const end = range.end;\n if (start.line > end.line || (start.line === end.line && start.character > end.character)) {\n return { start: end, end: start };\n }\n return range;\n}\nfunction getWellformedEdit(textEdit) {\n const range = getWellformedRange(textEdit.range);\n if (range !== textEdit.range) {\n return { newText: textEdit.newText, range };\n }\n return textEdit;\n}\n", "// 'path' module extracted from Node.js v8.11.1 (only the posix part)\n// transplited with Babel\n\n// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n'use strict';\n\nfunction assertPath(path) {\n if (typeof path !== 'string') {\n throw new TypeError('Path must be a string. Received ' + JSON.stringify(path));\n }\n}\n\n// Resolves . and .. elements in a path with directory names\nfunction normalizeStringPosix(path, allowAboveRoot) {\n var res = '';\n var lastSegmentLength = 0;\n var lastSlash = -1;\n var dots = 0;\n var code;\n for (var i = 0; i <= path.length; ++i) {\n if (i < path.length)\n code = path.charCodeAt(i);\n else if (code === 47 /*/*/)\n break;\n else\n code = 47 /*/*/;\n if (code === 47 /*/*/) {\n if (lastSlash === i - 1 || dots === 1) {\n // NOOP\n } else if (lastSlash !== i - 1 && dots === 2) {\n if (res.length < 2 || lastSegmentLength !== 2 || res.charCodeAt(res.length - 1) !== 46 /*.*/ || res.charCodeAt(res.length - 2) !== 46 /*.*/) {\n if (res.length > 2) {\n var lastSlashIndex = res.lastIndexOf('/');\n if (lastSlashIndex !== res.length - 1) {\n if (lastSlashIndex === -1) {\n res = '';\n lastSegmentLength = 0;\n } else {\n res = res.slice(0, lastSlashIndex);\n lastSegmentLength = res.length - 1 - res.lastIndexOf('/');\n }\n lastSlash = i;\n dots = 0;\n continue;\n }\n } else if (res.length === 2 || res.length === 1) {\n res = '';\n lastSegmentLength = 0;\n lastSlash = i;\n dots = 0;\n continue;\n }\n }\n if (allowAboveRoot) {\n if (res.length > 0)\n res += '/..';\n else\n res = '..';\n lastSegmentLength = 2;\n }\n } else {\n if (res.length > 0)\n res += '/' + path.slice(lastSlash + 1, i);\n else\n res = path.slice(lastSlash + 1, i);\n lastSegmentLength = i - lastSlash - 1;\n }\n lastSlash = i;\n dots = 0;\n } else if (code === 46 /*.*/ && dots !== -1) {\n ++dots;\n } else {\n dots = -1;\n }\n }\n return res;\n}\n\nfunction _format(sep, pathObject) {\n var dir = pathObject.dir || pathObject.root;\n var base = pathObject.base || (pathObject.name || '') + (pathObject.ext || '');\n if (!dir) {\n return base;\n }\n if (dir === pathObject.root) {\n return dir + base;\n }\n return dir + sep + base;\n}\n\nvar posix = {\n // path.resolve([from ...], to)\n resolve: function resolve() {\n var resolvedPath = '';\n var resolvedAbsolute = false;\n var cwd;\n\n for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {\n var path;\n if (i >= 0)\n path = arguments[i];\n else {\n if (cwd === undefined)\n cwd = process.cwd();\n path = cwd;\n }\n\n assertPath(path);\n\n // Skip empty entries\n if (path.length === 0) {\n continue;\n }\n\n resolvedPath = path + '/' + resolvedPath;\n resolvedAbsolute = path.charCodeAt(0) === 47 /*/*/;\n }\n\n // At this point the path should be resolved to a full absolute path, but\n // handle relative paths to be safe (might happen when process.cwd() fails)\n\n // Normalize the path\n resolvedPath = normalizeStringPosix(resolvedPath, !resolvedAbsolute);\n\n if (resolvedAbsolute) {\n if (resolvedPath.length > 0)\n return '/' + resolvedPath;\n else\n return '/';\n } else if (resolvedPath.length > 0) {\n return resolvedPath;\n } else {\n return '.';\n }\n },\n\n normalize: function normalize(path) {\n assertPath(path);\n\n if (path.length === 0) return '.';\n\n var isAbsolute = path.charCodeAt(0) === 47 /*/*/;\n var trailingSeparator = path.charCodeAt(path.length - 1) === 47 /*/*/;\n\n // Normalize the path\n path = normalizeStringPosix(path, !isAbsolute);\n\n if (path.length === 0 && !isAbsolute) path = '.';\n if (path.length > 0 && trailingSeparator) path += '/';\n\n if (isAbsolute) return '/' + path;\n return path;\n },\n\n isAbsolute: function isAbsolute(path) {\n assertPath(path);\n return path.length > 0 && path.charCodeAt(0) === 47 /*/*/;\n },\n\n join: function join() {\n if (arguments.length === 0)\n return '.';\n var joined;\n for (var i = 0; i < arguments.length; ++i) {\n var arg = arguments[i];\n assertPath(arg);\n if (arg.length > 0) {\n if (joined === undefined)\n joined = arg;\n else\n joined += '/' + arg;\n }\n }\n if (joined === undefined)\n return '.';\n return posix.normalize(joined);\n },\n\n relative: function relative(from, to) {\n assertPath(from);\n assertPath(to);\n\n if (from === to) return '';\n\n from = posix.resolve(from);\n to = posix.resolve(to);\n\n if (from === to) return '';\n\n // Trim any leading backslashes\n var fromStart = 1;\n for (; fromStart < from.length; ++fromStart) {\n if (from.charCodeAt(fromStart) !== 47 /*/*/)\n break;\n }\n var fromEnd = from.length;\n var fromLen = fromEnd - fromStart;\n\n // Trim any leading backslashes\n var toStart = 1;\n for (; toStart < to.length; ++toStart) {\n if (to.charCodeAt(toStart) !== 47 /*/*/)\n break;\n }\n var toEnd = to.length;\n var toLen = toEnd - toStart;\n\n // Compare paths to find the longest common path from root\n var length = fromLen < toLen ? fromLen : toLen;\n var lastCommonSep = -1;\n var i = 0;\n for (; i <= length; ++i) {\n if (i === length) {\n if (toLen > length) {\n if (to.charCodeAt(toStart + i) === 47 /*/*/) {\n // We get here if `from` is the exact base path for `to`.\n // For example: from='/foo/bar'; to='/foo/bar/baz'\n return to.slice(toStart + i + 1);\n } else if (i === 0) {\n // We get here if `from` is the root\n // For example: from='/'; to='/foo'\n return to.slice(toStart + i);\n }\n } else if (fromLen > length) {\n if (from.charCodeAt(fromStart + i) === 47 /*/*/) {\n // We get here if `to` is the exact base path for `from`.\n // For example: from='/foo/bar/baz'; to='/foo/bar'\n lastCommonSep = i;\n } else if (i === 0) {\n // We get here if `to` is the root.\n // For example: from='/foo'; to='/'\n lastCommonSep = 0;\n }\n }\n break;\n }\n var fromCode = from.charCodeAt(fromStart + i);\n var toCode = to.charCodeAt(toStart + i);\n if (fromCode !== toCode)\n break;\n else if (fromCode === 47 /*/*/)\n lastCommonSep = i;\n }\n\n var out = '';\n // Generate the relative path based on the path difference between `to`\n // and `from`\n for (i = fromStart + lastCommonSep + 1; i <= fromEnd; ++i) {\n if (i === fromEnd || from.charCodeAt(i) === 47 /*/*/) {\n if (out.length === 0)\n out += '..';\n else\n out += '/..';\n }\n }\n\n // Lastly, append the rest of the destination (`to`) path that comes after\n // the common path parts\n if (out.length > 0)\n return out + to.slice(toStart + lastCommonSep);\n else {\n toStart += lastCommonSep;\n if (to.charCodeAt(toStart) === 47 /*/*/)\n ++toStart;\n return to.slice(toStart);\n }\n },\n\n _makeLong: function _makeLong(path) {\n return path;\n },\n\n dirname: function dirname(path) {\n assertPath(path);\n if (path.length === 0) return '.';\n var code = path.charCodeAt(0);\n var hasRoot = code === 47 /*/*/;\n var end = -1;\n var matchedSlash = true;\n for (var i = path.length - 1; i >= 1; --i) {\n code = path.charCodeAt(i);\n if (code === 47 /*/*/) {\n if (!matchedSlash) {\n end = i;\n break;\n }\n } else {\n // We saw the first non-path separator\n matchedSlash = false;\n }\n }\n\n if (end === -1) return hasRoot ? '/' : '.';\n if (hasRoot && end === 1) return '//';\n return path.slice(0, end);\n },\n\n basename: function basename(path, ext) {\n if (ext !== undefined && typeof ext !== 'string') throw new TypeError('\"ext\" argument must be a string');\n assertPath(path);\n\n var start = 0;\n var end = -1;\n var matchedSlash = true;\n var i;\n\n if (ext !== undefined && ext.length > 0 && ext.length <= path.length) {\n if (ext.length === path.length && ext === path) return '';\n var extIdx = ext.length - 1;\n var firstNonSlashEnd = -1;\n for (i = path.length - 1; i >= 0; --i) {\n var code = path.charCodeAt(i);\n if (code === 47 /*/*/) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n } else {\n if (firstNonSlashEnd === -1) {\n // We saw the first non-path separator, remember this index in case\n // we need it if the extension ends up not matching\n matchedSlash = false;\n firstNonSlashEnd = i + 1;\n }\n if (extIdx >= 0) {\n // Try to match the explicit extension\n if (code === ext.charCodeAt(extIdx)) {\n if (--extIdx === -1) {\n // We matched the extension, so mark this as the end of our path\n // component\n end = i;\n }\n } else {\n // Extension does not match, so our result is the entire path\n // component\n extIdx = -1;\n end = firstNonSlashEnd;\n }\n }\n }\n }\n\n if (start === end) end = firstNonSlashEnd;else if (end === -1) end = path.length;\n return path.slice(start, end);\n } else {\n for (i = path.length - 1; i >= 0; --i) {\n if (path.charCodeAt(i) === 47 /*/*/) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n start = i + 1;\n break;\n }\n } else if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // path component\n matchedSlash = false;\n end = i + 1;\n }\n }\n\n if (end === -1) return '';\n return path.slice(start, end);\n }\n },\n\n extname: function extname(path) {\n assertPath(path);\n var startDot = -1;\n var startPart = 0;\n var end = -1;\n var matchedSlash = true;\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n var preDotState = 0;\n for (var i = path.length - 1; i >= 0; --i) {\n var code = path.charCodeAt(i);\n if (code === 47 /*/*/) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (code === 46 /*.*/) {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1)\n startDot = i;\n else if (preDotState !== 1)\n preDotState = 1;\n } else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n\n if (startDot === -1 || end === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {\n return '';\n }\n return path.slice(startDot, end);\n },\n\n format: function format(pathObject) {\n if (pathObject === null || typeof pathObject !== 'object') {\n throw new TypeError('The \"pathObject\" argument must be of type Object. Received type ' + typeof pathObject);\n }\n return _format('/', pathObject);\n },\n\n parse: function parse(path) {\n assertPath(path);\n\n var ret = { root: '', dir: '', base: '', ext: '', name: '' };\n if (path.length === 0) return ret;\n var code = path.charCodeAt(0);\n var isAbsolute = code === 47 /*/*/;\n var start;\n if (isAbsolute) {\n ret.root = '/';\n start = 1;\n } else {\n start = 0;\n }\n var startDot = -1;\n var startPart = 0;\n var end = -1;\n var matchedSlash = true;\n var i = path.length - 1;\n\n // Track the state of characters (if any) we see before our first dot and\n // after any path separator we find\n var preDotState = 0;\n\n // Get non-dir info\n for (; i >= start; --i) {\n code = path.charCodeAt(i);\n if (code === 47 /*/*/) {\n // If we reached a path separator that was not part of a set of path\n // separators at the end of the string, stop now\n if (!matchedSlash) {\n startPart = i + 1;\n break;\n }\n continue;\n }\n if (end === -1) {\n // We saw the first non-path separator, mark this as the end of our\n // extension\n matchedSlash = false;\n end = i + 1;\n }\n if (code === 46 /*.*/) {\n // If this is our first dot, mark it as the start of our extension\n if (startDot === -1) startDot = i;else if (preDotState !== 1) preDotState = 1;\n } else if (startDot !== -1) {\n // We saw a non-dot and non-path separator before our dot, so we should\n // have a good chance at having a non-empty extension\n preDotState = -1;\n }\n }\n\n if (startDot === -1 || end === -1 ||\n // We saw a non-dot character immediately before the dot\n preDotState === 0 ||\n // The (right-most) trimmed path component is exactly '..'\n preDotState === 1 && startDot === end - 1 && startDot === startPart + 1) {\n if (end !== -1) {\n if (startPart === 0 && isAbsolute) ret.base = ret.name = path.slice(1, end);else ret.base = ret.name = path.slice(startPart, end);\n }\n } else {\n if (startPart === 0 && isAbsolute) {\n ret.name = path.slice(1, startDot);\n ret.base = path.slice(1, end);\n } else {\n ret.name = path.slice(startPart, startDot);\n ret.base = path.slice(startPart, end);\n }\n ret.ext = path.slice(startDot, end);\n }\n\n if (startPart > 0) ret.dir = path.slice(0, startPart - 1);else if (isAbsolute) ret.dir = '/';\n\n return ret;\n },\n\n sep: '/',\n delimiter: ':',\n win32: null,\n posix: null\n};\n\nposix.posix = posix;\n\nmodule.exports = posix;\n", "// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n", "// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};", "__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))", "// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\n\n// !!!!!\n// SEE https://github.com/microsoft/vscode/blob/master/src/vs/base/common/platform.ts\n// !!!!!\n\ndeclare const process: { platform: 'win32' };\ndeclare const navigator: { userAgent: string };\n\nexport let isWindows: boolean;\n\nif (typeof process === 'object') {\n\tisWindows = process.platform === 'win32';\n} else if (typeof navigator === 'object') {\n\tlet userAgent = navigator.userAgent;\n\tisWindows = userAgent.indexOf('Windows') >= 0;\n}\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n'use strict';\n\nimport { CharCode } from './charCode'\nimport { isWindows } from './platform';\n\nconst _schemePattern = /^\\w[\\w\\d+.-]*$/;\nconst _singleSlashStart = /^\\//;\nconst _doubleSlashStart = /^\\/\\//;\n\nfunction _validateUri(ret: URI, _strict?: boolean): void {\n\n\t// scheme, must be set\n\tif (!ret.scheme && _strict) {\n\t\tthrow new Error(`[UriError]: Scheme is missing: {scheme: \"\", authority: \"${ret.authority}\", path: \"${ret.path}\", query: \"${ret.query}\", fragment: \"${ret.fragment}\"}`);\n\t}\n\n\t// scheme, https://tools.ietf.org/html/rfc3986#section-3.1\n\t// ALPHA *( ALPHA / DIGIT / \"+\" / \"-\" / \".\" )\n\tif (ret.scheme && !_schemePattern.test(ret.scheme)) {\n\t\tthrow new Error('[UriError]: Scheme contains illegal characters.');\n\t}\n\n\t// path, http://tools.ietf.org/html/rfc3986#section-3.3\n\t// If a URI contains an authority component, then the path component\n\t// must either be empty or begin with a slash (\"/\") character. If a URI\n\t// does not contain an authority component, then the path cannot begin\n\t// with two slash characters (\"//\").\n\tif (ret.path) {\n\t\tif (ret.authority) {\n\t\t\tif (!_singleSlashStart.test(ret.path)) {\n\t\t\t\tthrow new Error('[UriError]: If a URI contains an authority component, then the path component must either be empty or begin with a slash (\"/\") character');\n\t\t\t}\n\t\t} else {\n\t\t\tif (_doubleSlashStart.test(ret.path)) {\n\t\t\t\tthrow new Error('[UriError]: If a URI does not contain an authority component, then the path cannot begin with two slash characters (\"//\")');\n\t\t\t}\n\t\t}\n\t}\n}\n\n// for a while we allowed uris *without* schemes and this is the migration\n// for them, e.g. an uri without scheme and without strict-mode warns and falls\n// back to the file-scheme. that should cause the least carnage and still be a\n// clear warning\nfunction _schemeFix(scheme: string, _strict: boolean): string {\n\tif (!scheme && !_strict) {\n\t\treturn 'file';\n\t}\n\treturn scheme;\n}\n\n// implements a bit of https://tools.ietf.org/html/rfc3986#section-5\nfunction _referenceResolution(scheme: string, path: string): string {\n\n\t// the slash-character is our 'default base' as we don't\n\t// support constructing URIs relative to other URIs. This\n\t// also means that we alter and potentially break paths.\n\t// see https://tools.ietf.org/html/rfc3986#section-5.1.4\n\tswitch (scheme) {\n\t\tcase 'https':\n\t\tcase 'http':\n\t\tcase 'file':\n\t\t\tif (!path) {\n\t\t\t\tpath = _slash;\n\t\t\t} else if (path[0] !== _slash) {\n\t\t\t\tpath = _slash + path;\n\t\t\t}\n\t\t\tbreak;\n\t}\n\treturn path;\n}\n\nconst _empty = '';\nconst _slash = '/';\nconst _regexp = /^(([^:/?#]+?):)?(\\/\\/([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?/;\n\n/**\n * Uniform Resource Identifier (URI) http://tools.ietf.org/html/rfc3986.\n * This class is a simple parser which creates the basic component parts\n * (http://tools.ietf.org/html/rfc3986#section-3) with minimal validation\n * and encoding.\n *\n * ```txt\n * foo://example.com:8042/over/there?name=ferret#nose\n * \\_/ \\______________/\\_________/ \\_________/ \\__/\n * | | | | |\n * scheme authority path query fragment\n * | _____________________|__\n * / \\ / \\\n * urn:example:animal:ferret:nose\n * ```\n */\nexport class URI implements UriComponents {\n\n\tstatic isUri(thing: any): thing is URI {\n\t\tif (thing instanceof URI) {\n\t\t\treturn true;\n\t\t}\n\t\tif (!thing) {\n\t\t\treturn false;\n\t\t}\n\t\treturn typeof (thing).authority === 'string'\n\t\t\t&& typeof (thing).fragment === 'string'\n\t\t\t&& typeof (thing).path === 'string'\n\t\t\t&& typeof (thing).query === 'string'\n\t\t\t&& typeof (thing).scheme === 'string'\n\t\t\t&& typeof (thing).fsPath === 'string'\n\t\t\t&& typeof (thing).with === 'function'\n\t\t\t&& typeof (thing).toString === 'function';\n\t}\n\n\t/**\n\t * scheme is the 'http' part of 'http://www.example.com/some/path?query#fragment'.\n\t * The part before the first colon.\n\t */\n\treadonly scheme: string;\n\n\t/**\n\t * authority is the 'www.example.com' part of 'http://www.example.com/some/path?query#fragment'.\n\t * The part between the first double slashes and the next slash.\n\t */\n\treadonly authority: string;\n\n\t/**\n\t * path is the '/some/path' part of 'http://www.example.com/some/path?query#fragment'.\n\t */\n\treadonly path: string;\n\n\t/**\n\t * query is the 'query' part of 'http://www.example.com/some/path?query#fragment'.\n\t */\n\treadonly query: string;\n\n\t/**\n\t * fragment is the 'fragment' part of 'http://www.example.com/some/path?query#fragment'.\n\t */\n\treadonly fragment: string;\n\n\t/**\n\t * @internal\n\t */\n\tprotected constructor(scheme: string, authority?: string, path?: string, query?: string, fragment?: string, _strict?: boolean);\n\n\t/**\n\t * @internal\n\t */\n\tprotected constructor(components: UriComponents);\n\n\t/**\n\t * @internal\n\t */\n\tprotected constructor(schemeOrData: string | UriComponents, authority?: string, path?: string, query?: string, fragment?: string, _strict: boolean = false) {\n\n\t\tif (typeof schemeOrData === 'object') {\n\t\t\tthis.scheme = schemeOrData.scheme || _empty;\n\t\t\tthis.authority = schemeOrData.authority || _empty;\n\t\t\tthis.path = schemeOrData.path || _empty;\n\t\t\tthis.query = schemeOrData.query || _empty;\n\t\t\tthis.fragment = schemeOrData.fragment || _empty;\n\t\t\t// no validation because it's this URI\n\t\t\t// that creates uri components.\n\t\t\t// _validateUri(this);\n\t\t} else {\n\t\t\tthis.scheme = _schemeFix(schemeOrData, _strict);\n\t\t\tthis.authority = authority || _empty;\n\t\t\tthis.path = _referenceResolution(this.scheme, path || _empty);\n\t\t\tthis.query = query || _empty;\n\t\t\tthis.fragment = fragment || _empty;\n\n\t\t\t_validateUri(this, _strict);\n\t\t}\n\t}\n\n\t// ---- filesystem path -----------------------\n\n\t/**\n\t * Returns a string representing the corresponding file system path of this URI.\n\t * Will handle UNC paths, normalizes windows drive letters to lower-case, and uses the\n\t * platform specific path separator.\n\t *\n\t * * Will *not* validate the path for invalid characters and semantics.\n\t * * Will *not* look at the scheme of this URI.\n\t * * The result shall *not* be used for display purposes but for accessing a file on disk.\n\t *\n\t *\n\t * The *difference* to `URI#path` is the use of the platform specific separator and the handling\n\t * of UNC paths. See the below sample of a file-uri with an authority (UNC path).\n\t *\n\t * ```ts\n\t\tconst u = URI.parse('file://server/c$/folder/file.txt')\n\t\tu.authority === 'server'\n\t\tu.path === '/shares/c$/file.txt'\n\t\tu.fsPath === '\\\\server\\c$\\folder\\file.txt'\n\t```\n\t *\n\t * Using `URI#path` to read a file (using fs-apis) would not be enough because parts of the path,\n\t * namely the server name, would be missing. Therefore `URI#fsPath` exists - it's sugar to ease working\n\t * with URIs that represent files on disk (`file` scheme).\n\t */\n\tget fsPath(): string {\n\t\t// if (this.scheme !== 'file') {\n\t\t// \tconsole.warn(`[UriError] calling fsPath with scheme ${this.scheme}`);\n\t\t// }\n\t\treturn uriToFsPath(this, false);\n\t}\n\n\t// ---- modify to new -------------------------\n\n\twith(change: { scheme?: string; authority?: string | null; path?: string | null; query?: string | null; fragment?: string | null }): URI {\n\n\t\tif (!change) {\n\t\t\treturn this;\n\t\t}\n\n\t\tlet { scheme, authority, path, query, fragment } = change;\n\t\tif (scheme === undefined) {\n\t\t\tscheme = this.scheme;\n\t\t} else if (scheme === null) {\n\t\t\tscheme = _empty;\n\t\t}\n\t\tif (authority === undefined) {\n\t\t\tauthority = this.authority;\n\t\t} else if (authority === null) {\n\t\t\tauthority = _empty;\n\t\t}\n\t\tif (path === undefined) {\n\t\t\tpath = this.path;\n\t\t} else if (path === null) {\n\t\t\tpath = _empty;\n\t\t}\n\t\tif (query === undefined) {\n\t\t\tquery = this.query;\n\t\t} else if (query === null) {\n\t\t\tquery = _empty;\n\t\t}\n\t\tif (fragment === undefined) {\n\t\t\tfragment = this.fragment;\n\t\t} else if (fragment === null) {\n\t\t\tfragment = _empty;\n\t\t}\n\n\t\tif (scheme === this.scheme\n\t\t\t&& authority === this.authority\n\t\t\t&& path === this.path\n\t\t\t&& query === this.query\n\t\t\t&& fragment === this.fragment) {\n\n\t\t\treturn this;\n\t\t}\n\n\t\treturn new Uri(scheme, authority, path, query, fragment);\n\t}\n\n\t// ---- parse & validate ------------------------\n\n\t/**\n\t * Creates a new URI from a string, e.g. `http://www.example.com/some/path`,\n\t * `file:///usr/home`, or `scheme:with/path`.\n\t *\n\t * @param value A string which represents an URI (see `URI#toString`).\n\t */\n\tstatic parse(value: string, _strict: boolean = false): URI {\n\t\tconst match = _regexp.exec(value);\n\t\tif (!match) {\n\t\t\treturn new Uri(_empty, _empty, _empty, _empty, _empty);\n\t\t}\n\t\treturn new Uri(\n\t\t\tmatch[2] || _empty,\n\t\t\tpercentDecode(match[4] || _empty),\n\t\t\tpercentDecode(match[5] || _empty),\n\t\t\tpercentDecode(match[7] || _empty),\n\t\t\tpercentDecode(match[9] || _empty),\n\t\t\t_strict\n\t\t);\n\t}\n\n\t/**\n\t * Creates a new URI from a file system path, e.g. `c:\\my\\files`,\n\t * `/usr/home`, or `\\\\server\\share\\some\\path`.\n\t *\n\t * The *difference* between `URI#parse` and `URI#file` is that the latter treats the argument\n\t * as path, not as stringified-uri. E.g. `URI.file(path)` is **not the same as**\n\t * `URI.parse('file://' + path)` because the path might contain characters that are\n\t * interpreted (# and ?). See the following sample:\n\t * ```ts\n\tconst good = URI.file('/coding/c#/project1');\n\tgood.scheme === 'file';\n\tgood.path === '/coding/c#/project1';\n\tgood.fragment === '';\n\tconst bad = URI.parse('file://' + '/coding/c#/project1');\n\tbad.scheme === 'file';\n\tbad.path === '/coding/c'; // path is now broken\n\tbad.fragment === '/project1';\n\t```\n\t *\n\t * @param path A file system path (see `URI#fsPath`)\n\t */\n\tstatic file(path: string): URI {\n\n\t\tlet authority = _empty;\n\n\t\t// normalize to fwd-slashes on windows,\n\t\t// on other systems bwd-slashes are valid\n\t\t// filename character, eg /f\\oo/ba\\r.txt\n\t\tif (isWindows) {\n\t\t\tpath = path.replace(/\\\\/g, _slash);\n\t\t}\n\n\t\t// check for authority as used in UNC shares\n\t\t// or use the path as given\n\t\tif (path[0] === _slash && path[1] === _slash) {\n\t\t\tconst idx = path.indexOf(_slash, 2);\n\t\t\tif (idx === -1) {\n\t\t\t\tauthority = path.substring(2);\n\t\t\t\tpath = _slash;\n\t\t\t} else {\n\t\t\t\tauthority = path.substring(2, idx);\n\t\t\t\tpath = path.substring(idx) || _slash;\n\t\t\t}\n\t\t}\n\n\t\treturn new Uri('file', authority, path, _empty, _empty);\n\t}\n\n\tstatic from(components: { scheme: string; authority?: string; path?: string; query?: string; fragment?: string }): URI {\n\t\tconst result = new Uri(\n\t\t\tcomponents.scheme,\n\t\t\tcomponents.authority,\n\t\t\tcomponents.path,\n\t\t\tcomponents.query,\n\t\t\tcomponents.fragment,\n\t\t);\n\t\t_validateUri(result, true);\n\t\treturn result;\n\t}\n\n\t// ---- printing/externalize ---------------------------\n\n\t/**\n\t * Creates a string representation for this URI. It's guaranteed that calling\n\t * `URI.parse` with the result of this function creates an URI which is equal\n\t * to this URI.\n\t *\n\t * * The result shall *not* be used for display purposes but for externalization or transport.\n\t * * The result will be encoded using the percentage encoding and encoding happens mostly\n\t * ignore the scheme-specific encoding rules.\n\t *\n\t * @param skipEncoding Do not encode the result, default is `false`\n\t */\n\ttoString(skipEncoding: boolean = false): string {\n\t\treturn _asFormatted(this, skipEncoding);\n\t}\n\n\ttoJSON(): UriComponents {\n\t\treturn this;\n\t}\n\n\tstatic revive(data: UriComponents | URI): URI;\n\tstatic revive(data: UriComponents | URI | undefined): URI | undefined;\n\tstatic revive(data: UriComponents | URI | null): URI | null;\n\tstatic revive(data: UriComponents | URI | undefined | null): URI | undefined | null;\n\tstatic revive(data: UriComponents | URI | undefined | null): URI | undefined | null {\n\t\tif (!data) {\n\t\t\treturn data;\n\t\t} else if (data instanceof URI) {\n\t\t\treturn data;\n\t\t} else {\n\t\t\tconst result = new Uri(data);\n\t\t\tresult._formatted = (data).external;\n\t\t\tresult._fsPath = (data)._sep === _pathSepMarker ? (data).fsPath : null;\n\t\t\treturn result;\n\t\t}\n\t}\n}\n\nexport interface UriComponents {\n\tscheme: string;\n\tauthority: string;\n\tpath: string;\n\tquery: string;\n\tfragment: string;\n}\n\ninterface UriState extends UriComponents {\n\t$mid: number;\n\texternal: string;\n\tfsPath: string;\n\t_sep: 1 | undefined;\n}\n\nconst _pathSepMarker = isWindows ? 1 : undefined;\n\n// This class exists so that URI is compatible with vscode.Uri (API).\nclass Uri extends URI {\n\n\t_formatted: string | null = null;\n\t_fsPath: string | null = null;\n\n\toverride get fsPath(): string {\n\t\tif (!this._fsPath) {\n\t\t\tthis._fsPath = uriToFsPath(this, false);\n\t\t}\n\t\treturn this._fsPath;\n\t}\n\n\toverride toString(skipEncoding: boolean = false): string {\n\t\tif (!skipEncoding) {\n\t\t\tif (!this._formatted) {\n\t\t\t\tthis._formatted = _asFormatted(this, false);\n\t\t\t}\n\t\t\treturn this._formatted;\n\t\t} else {\n\t\t\t// we don't cache that\n\t\t\treturn _asFormatted(this, true);\n\t\t}\n\t}\n\n\toverride toJSON(): UriComponents {\n\t\tconst res = {\n\t\t\t$mid: 1\n\t\t};\n\t\t// cached state\n\t\tif (this._fsPath) {\n\t\t\tres.fsPath = this._fsPath;\n\t\t\tres._sep = _pathSepMarker;\n\t\t}\n\t\tif (this._formatted) {\n\t\t\tres.external = this._formatted;\n\t\t}\n\t\t// uri components\n\t\tif (this.path) {\n\t\t\tres.path = this.path;\n\t\t}\n\t\tif (this.scheme) {\n\t\t\tres.scheme = this.scheme;\n\t\t}\n\t\tif (this.authority) {\n\t\t\tres.authority = this.authority;\n\t\t}\n\t\tif (this.query) {\n\t\t\tres.query = this.query;\n\t\t}\n\t\tif (this.fragment) {\n\t\t\tres.fragment = this.fragment;\n\t\t}\n\t\treturn res;\n\t}\n}\n\n// reserved characters: https://tools.ietf.org/html/rfc3986#section-2.2\nconst encodeTable: { [ch: number]: string } = {\n\t[CharCode.Colon]: '%3A', // gen-delims\n\t[CharCode.Slash]: '%2F',\n\t[CharCode.QuestionMark]: '%3F',\n\t[CharCode.Hash]: '%23',\n\t[CharCode.OpenSquareBracket]: '%5B',\n\t[CharCode.CloseSquareBracket]: '%5D',\n\t[CharCode.AtSign]: '%40',\n\n\t[CharCode.ExclamationMark]: '%21', // sub-delims\n\t[CharCode.DollarSign]: '%24',\n\t[CharCode.Ampersand]: '%26',\n\t[CharCode.SingleQuote]: '%27',\n\t[CharCode.OpenParen]: '%28',\n\t[CharCode.CloseParen]: '%29',\n\t[CharCode.Asterisk]: '%2A',\n\t[CharCode.Plus]: '%2B',\n\t[CharCode.Comma]: '%2C',\n\t[CharCode.Semicolon]: '%3B',\n\t[CharCode.Equals]: '%3D',\n\n\t[CharCode.Space]: '%20',\n};\n\nfunction encodeURIComponentFast(uriComponent: string, isPath: boolean, isAuthority: boolean): string {\n\tlet res: string | undefined = undefined;\n\tlet nativeEncodePos = -1;\n\n\tfor (let pos = 0; pos < uriComponent.length; pos++) {\n\t\tconst code = uriComponent.charCodeAt(pos);\n\n\t\t// unreserved characters: https://tools.ietf.org/html/rfc3986#section-2.3\n\t\tif (\n\t\t\t(code >= CharCode.a && code <= CharCode.z)\n\t\t\t|| (code >= CharCode.A && code <= CharCode.Z)\n\t\t\t|| (code >= CharCode.Digit0 && code <= CharCode.Digit9)\n\t\t\t|| code === CharCode.Dash\n\t\t\t|| code === CharCode.Period\n\t\t\t|| code === CharCode.Underline\n\t\t\t|| code === CharCode.Tilde\n\t\t\t|| (isPath && code === CharCode.Slash)\n\t\t\t|| (isAuthority && code === CharCode.OpenSquareBracket)\n\t\t\t|| (isAuthority && code === CharCode.CloseSquareBracket)\n\t\t\t|| (isAuthority && code === CharCode.Colon)\n\t\t) {\n\t\t\t// check if we are delaying native encode\n\t\t\tif (nativeEncodePos !== -1) {\n\t\t\t\tres += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));\n\t\t\t\tnativeEncodePos = -1;\n\t\t\t}\n\t\t\t// check if we write into a new string (by default we try to return the param)\n\t\t\tif (res !== undefined) {\n\t\t\t\tres += uriComponent.charAt(pos);\n\t\t\t}\n\n\t\t} else {\n\t\t\t// encoding needed, we need to allocate a new string\n\t\t\tif (res === undefined) {\n\t\t\t\tres = uriComponent.substr(0, pos);\n\t\t\t}\n\n\t\t\t// check with default table first\n\t\t\tconst escaped = encodeTable[code];\n\t\t\tif (escaped !== undefined) {\n\n\t\t\t\t// check if we are delaying native encode\n\t\t\t\tif (nativeEncodePos !== -1) {\n\t\t\t\t\tres += encodeURIComponent(uriComponent.substring(nativeEncodePos, pos));\n\t\t\t\t\tnativeEncodePos = -1;\n\t\t\t\t}\n\n\t\t\t\t// append escaped variant to result\n\t\t\t\tres += escaped;\n\n\t\t\t} else if (nativeEncodePos === -1) {\n\t\t\t\t// use native encode only when needed\n\t\t\t\tnativeEncodePos = pos;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (nativeEncodePos !== -1) {\n\t\tres += encodeURIComponent(uriComponent.substring(nativeEncodePos));\n\t}\n\n\treturn res !== undefined ? res : uriComponent;\n}\n\nfunction encodeURIComponentMinimal(path: string): string {\n\tlet res: string | undefined = undefined;\n\tfor (let pos = 0; pos < path.length; pos++) {\n\t\tconst code = path.charCodeAt(pos);\n\t\tif (code === CharCode.Hash || code === CharCode.QuestionMark) {\n\t\t\tif (res === undefined) {\n\t\t\t\tres = path.substr(0, pos);\n\t\t\t}\n\t\t\tres += encodeTable[code];\n\t\t} else {\n\t\t\tif (res !== undefined) {\n\t\t\t\tres += path[pos];\n\t\t\t}\n\t\t}\n\t}\n\treturn res !== undefined ? res : path;\n}\n\n/**\n * Compute `fsPath` for the given uri\n */\nexport function uriToFsPath(uri: URI, keepDriveLetterCasing: boolean): string {\n\n\tlet value: string;\n\tif (uri.authority && uri.path.length > 1 && uri.scheme === 'file') {\n\t\t// unc path: file://shares/c$/far/boo\n\t\tvalue = `//${uri.authority}${uri.path}`;\n\t} else if (\n\t\turi.path.charCodeAt(0) === CharCode.Slash\n\t\t&& (uri.path.charCodeAt(1) >= CharCode.A && uri.path.charCodeAt(1) <= CharCode.Z || uri.path.charCodeAt(1) >= CharCode.a && uri.path.charCodeAt(1) <= CharCode.z)\n\t\t&& uri.path.charCodeAt(2) === CharCode.Colon\n\t) {\n\t\tif (!keepDriveLetterCasing) {\n\t\t\t// windows drive letter: file:///c:/far/boo\n\t\t\tvalue = uri.path[1].toLowerCase() + uri.path.substr(2);\n\t\t} else {\n\t\t\tvalue = uri.path.substr(1);\n\t\t}\n\t} else {\n\t\t// other path\n\t\tvalue = uri.path;\n\t}\n\tif (isWindows) {\n\t\tvalue = value.replace(/\\//g, '\\\\');\n\t}\n\treturn value;\n}\n\n/**\n * Create the external version of a uri\n */\nfunction _asFormatted(uri: URI, skipEncoding: boolean): string {\n\n\tconst encoder = !skipEncoding\n\t\t? encodeURIComponentFast\n\t\t: encodeURIComponentMinimal;\n\n\tlet res = '';\n\tlet { scheme, authority, path, query, fragment } = uri;\n\tif (scheme) {\n\t\tres += scheme;\n\t\tres += ':';\n\t}\n\tif (authority || scheme === 'file') {\n\t\tres += _slash;\n\t\tres += _slash;\n\t}\n\tif (authority) {\n\t\tlet idx = authority.indexOf('@');\n\t\tif (idx !== -1) {\n\t\t\t// @\n\t\t\tconst userinfo = authority.substr(0, idx);\n\t\t\tauthority = authority.substr(idx + 1);\n\t\t\tidx = userinfo.lastIndexOf(':');\n\t\t\tif (idx === -1) {\n\t\t\t\tres += encoder(userinfo, false, false);\n\t\t\t} else {\n\t\t\t\t// :@\n\t\t\t\tres += encoder(userinfo.substr(0, idx), false, false);\n\t\t\t\tres += ':';\n\t\t\t\tres += encoder(userinfo.substr(idx + 1), false, true);\n\t\t\t}\n\t\t\tres += '@';\n\t\t}\n\t\tauthority = authority.toLowerCase();\n\t\tidx = authority.lastIndexOf(':');\n\t\tif (idx === -1) {\n\t\t\tres += encoder(authority, false, true);\n\t\t} else {\n\t\t\t// :\n\t\t\tres += encoder(authority.substr(0, idx), false, true);\n\t\t\tres += authority.substr(idx);\n\t\t}\n\t}\n\tif (path) {\n\t\t// lower-case windows drive letters in /C:/fff or C:/fff\n\t\tif (path.length >= 3 && path.charCodeAt(0) === CharCode.Slash && path.charCodeAt(2) === CharCode.Colon) {\n\t\t\tconst code = path.charCodeAt(1);\n\t\t\tif (code >= CharCode.A && code <= CharCode.Z) {\n\t\t\t\tpath = `/${String.fromCharCode(code + 32)}:${path.substr(3)}`; // \"/c:\".length === 3\n\t\t\t}\n\t\t} else if (path.length >= 2 && path.charCodeAt(1) === CharCode.Colon) {\n\t\t\tconst code = path.charCodeAt(0);\n\t\t\tif (code >= CharCode.A && code <= CharCode.Z) {\n\t\t\t\tpath = `${String.fromCharCode(code + 32)}:${path.substr(2)}`; // \"/c:\".length === 3\n\t\t\t}\n\t\t}\n\t\t// encode the rest of the path\n\t\tres += encoder(path, true, false);\n\t}\n\tif (query) {\n\t\tres += '?';\n\t\tres += encoder(query, false, false);\n\t}\n\tif (fragment) {\n\t\tres += '#';\n\t\tres += !skipEncoding ? encodeURIComponentFast(fragment, false, false) : fragment;\n\t}\n\treturn res;\n}\n\n// --- decode\n\nfunction decodeURIComponentGraceful(str: string): string {\n\ttry {\n\t\treturn decodeURIComponent(str);\n\t} catch {\n\t\tif (str.length > 3) {\n\t\t\treturn str.substr(0, 3) + decodeURIComponentGraceful(str.substr(3));\n\t\t} else {\n\t\t\treturn str;\n\t\t}\n\t}\n}\n\nconst _rEncodedAsHex = /(%[0-9A-Za-z][0-9A-Za-z])+/g;\n\nfunction percentDecode(str: string): string {\n\tif (!str.match(_rEncodedAsHex)) {\n\t\treturn str;\n\t}\n\treturn str.replace(_rEncodedAsHex, (match) => decodeURIComponentGraceful(match));\n}\n\n/**\n * Mapped-type that replaces all occurrences of URI with UriComponents\n */\nexport type UriDto = { [K in keyof T]: T[K] extends URI\n\t? UriComponents\n\t: UriDto };\n", "/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\n'use strict';\n\nimport { CharCode } from './charCode';\nimport { URI } from './uri';\nimport * as nodePath from 'path';\n\nconst posixPath = nodePath.posix || nodePath;\nconst slash = '/';\n\nexport namespace Utils {\n\n /**\n * Joins one or more input paths to the path of URI. \n * '/' is used as the directory separation character. \n * \n * The resolved path will be normalized. That means:\n * - all '..' and '.' segments are resolved.\n * - multiple, sequential occurences of '/' are replaced by a single instance of '/'.\n * - trailing separators are preserved.\n * \n * @param uri The input URI.\n * @param paths The paths to be joined with the path of URI.\n * @returns A URI with the joined path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.\n */\n export function joinPath(uri: URI, ...paths: string[]): URI {\n return uri.with({ path: posixPath.join(uri.path, ...paths) });\n }\n\n\n /**\n * Resolves one or more paths against the path of a URI. \n * '/' is used as the directory separation character. \n * \n * The resolved path will be normalized. That means:\n * - all '..' and '.' segments are resolved. \n * - multiple, sequential occurences of '/' are replaced by a single instance of '/'.\n * - trailing separators are removed.\n * \n * @param uri The input URI.\n * @param paths The paths to resolve against the path of URI.\n * @returns A URI with the resolved path. All other properties of the URI (scheme, authority, query, fragments, ...) will be taken from the input URI.\n */\n export function resolvePath(uri: URI, ...paths: string[]): URI {\n let path = uri.path; \n let slashAdded = false;\n if (path[0] !== slash) {\n path = slash + path; // make the path abstract: for posixPath.resolve the first segments has to be absolute or cwd is used.\n slashAdded = true;\n }\n let resolvedPath = posixPath.resolve(path, ...paths);\n if (slashAdded && resolvedPath[0] === slash && !uri.authority) {\n resolvedPath = resolvedPath.substring(1);\n }\n return uri.with({ path: resolvedPath });\n }\n\n /**\n * Returns a URI where the path is the directory name of the input uri, similar to the Unix dirname command. \n * In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.\n * The orignal URI is returned if the URIs path is empty or does not contain any path segments.\n * \n * @param uri The input URI.\n * @return The last segment of the URIs path.\n */\n export function dirname(uri: URI): URI {\n if (uri.path.length === 0 || uri.path === slash) {\n return uri;\n }\n let path = posixPath.dirname(uri.path);\n if (path.length === 1 && path.charCodeAt(0) === CharCode.Period) {\n path = '';\n }\n return uri.with({ path });\n }\n\n /**\n * Returns the last segment of the path of a URI, similar to the Unix basename command. \n * In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.\n * The empty string is returned if the URIs path is empty or does not contain any path segments.\n * \n * @param uri The input URI.\n * @return The base name of the URIs path.\n */\n export function basename(uri: URI): string {\n return posixPath.basename(uri.path);\n }\n\n /**\n * Returns the extension name of the path of a URI, similar to the Unix extname command. \n * In the path, '/' is recognized as the directory separation character. Trailing directory separators are ignored.\n * The empty string is returned if the URIs path is empty or does not contain any path segments.\n * \n * @param uri The input URI.\n * @return The extension name of the URIs path.\n */\n export function extname(uri: URI): string {\n return posixPath.extname(uri.path);\n }\n}", "/******************************************************************************\n * Copyright 2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport { URI, Utils } from 'vscode-uri';\n\nexport { URI };\n\nexport namespace UriUtils {\n\n export const basename = Utils.basename;\n export const dirname = Utils.dirname;\n export const extname = Utils.extname;\n export const joinPath = Utils.joinPath;\n export const resolvePath = Utils.resolvePath;\n\n export function equals(a?: URI | string, b?: URI | string): boolean {\n return a?.toString() === b?.toString();\n }\n\n export function relative(from: URI | string, to: URI | string): string {\n const fromPath = typeof from === 'string' ? from : from.path;\n const toPath = typeof to === 'string' ? to : to.path;\n const fromParts = fromPath.split('/').filter(e => e.length > 0);\n const toParts = toPath.split('/').filter(e => e.length > 0);\n let i = 0;\n for (; i < fromParts.length; i++) {\n if (fromParts[i] !== toParts[i]) {\n break;\n }\n }\n const backPart = '../'.repeat(fromParts.length - i);\n const toPart = toParts.slice(i).join('/');\n return backPart + toPart;\n }\n\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\n/**\n * Re-export 'TextDocument' from 'vscode-languageserver-textdocument' for convenience,\n * including both type _and_ symbol (namespace), as we here and there also refer to the symbol,\n * the overhead is very small, just a few kilobytes.\n * Everything else of that package (at the time contributing) is also defined\n * in 'vscode-languageserver-protocol' or 'vscode-languageserver-types'.\n */\nexport { TextDocument } from 'vscode-languageserver-textdocument';\n\nimport type { Diagnostic, Range } from 'vscode-languageserver-types';\nimport type { FileSystemProvider } from './file-system-provider.js';\nimport type { ParseResult } from '../parser/langium-parser.js';\nimport type { ServiceRegistry } from '../service-registry.js';\nimport type { LangiumSharedCoreServices } from '../services.js';\nimport type { AstNode, AstNodeDescription, Mutable, Reference } from '../syntax-tree.js';\nimport type { MultiMap } from '../utils/collections.js';\nimport type { Stream } from '../utils/stream.js';\nimport { TextDocument } from './documents.js';\nimport { CancellationToken } from '../utils/cancellation.js';\nimport { stream } from '../utils/stream.js';\nimport { URI } from '../utils/uri-utils.js';\n\n/**\n * A Langium document holds the parse result (AST and CST) and any additional state that is derived\n * from the AST, e.g. the result of scope precomputation.\n */\nexport interface LangiumDocument {\n /** The Uniform Resource Identifier (URI) of the document */\n readonly uri: URI;\n /** The text document used to convert between offsets and positions */\n readonly textDocument: TextDocument;\n /** The current state of the document */\n state: DocumentState;\n /** The parse result holds the Abstract Syntax Tree (AST) and potentially also parser / lexer errors */\n parseResult: ParseResult;\n /** Result of the scope precomputation phase */\n precomputedScopes?: PrecomputedScopes;\n /** An array of all cross-references found in the AST while linking */\n references: Reference[];\n /** Result of the validation phase */\n diagnostics?: Diagnostic[]\n}\n\n/**\n * A document is subject to several phases that are run in predefined order. Any state value implies that\n * smaller state values are finished as well.\n */\nexport enum DocumentState {\n /**\n * The text content has changed and needs to be parsed again. The AST held by this outdated\n * document instance is no longer valid.\n */\n Changed = 0,\n /**\n * An AST has been created from the text content. The document structure can be traversed,\n * but cross-references cannot be resolved yet. If necessary, the structure can be manipulated\n * at this stage as a preprocessing step.\n */\n Parsed = 1,\n /**\n * The `IndexManager` service has processed AST nodes of this document. This means the\n * exported symbols are available in the global scope and can be resolved from other documents.\n */\n IndexedContent = 2,\n /**\n * The `ScopeComputation` service has processed this document. This means the local symbols\n * are stored in a MultiMap so they can be looked up by the `ScopeProvider` service.\n * Once a document has reached this state, you may follow every reference - it will lazily\n * resolve its `ref` property and yield either the target AST node or `undefined` in case\n * the target is not in scope.\n */\n ComputedScopes = 3,\n /**\n * The `Linker` service has processed this document. All outgoing references have been\n * resolved or marked as erroneous.\n */\n Linked = 4,\n /**\n * The `IndexManager` service has processed AST node references of this document. This is\n * necessary to determine which documents are affected by a change in one of the workspace\n * documents.\n */\n IndexedReferences = 5,\n /**\n * The `DocumentValidator` service has processed this document. The language server listens\n * to the results of this phase and sends diagnostics to the client.\n */\n Validated = 6\n}\n\n/**\n * Result of the scope precomputation phase (`ScopeComputation` service).\n * It maps every AST node to the set of symbols that are visible in the subtree of that node.\n */\nexport type PrecomputedScopes = MultiMap\n\nexport interface DocumentSegment {\n readonly range: Range\n readonly offset: number\n readonly length: number\n readonly end: number\n}\n\n/**\n * Surrogate definition of the `TextDocuments` interface from the `vscode-languageserver` package.\n * No implementation object is expected to be offered by `LangiumCoreServices`, but only by `LangiumLSPServices`.\n */\nexport type TextDocumentProvider = {\n get(uri: string): TextDocument | undefined\n}\n\n/**\n * Shared service for creating `LangiumDocument` instances.\n *\n * Register a custom implementation if special (additional) behavior is required for your language(s).\n * Note: If you specialize {@link fromString} or {@link fromTextDocument} you probably might want to\n * specialize {@link update}, too!\n */\nexport interface LangiumDocumentFactory {\n /**\n * Create a Langium document from a `TextDocument` (usually associated with a file).\n */\n fromTextDocument(textDocument: TextDocument, uri?: URI): LangiumDocument;\n /**\n * Create a Langium document from a `TextDocument` asynchronously. This action can be cancelled if a cancellable parser implementation has been provided.\n */\n fromTextDocument(textDocument: TextDocument, uri: URI | undefined, cancellationToken: CancellationToken): Promise>;\n\n /**\n * Create an Langium document from an in-memory string.\n */\n fromString(text: string, uri: URI): LangiumDocument;\n /**\n * Create a Langium document from an in-memory string asynchronously. This action can be cancelled if a cancellable parser implementation has been provided.\n */\n fromString(text: string, uri: URI, cancellationToken: CancellationToken): Promise>;\n\n /**\n * Create an Langium document from a model that has been constructed in memory.\n */\n fromModel(model: T, uri: URI): LangiumDocument;\n\n /**\n * Create an Langium document from a specified `URI`. The factory will use the `FileSystemAccess` service to read the file.\n */\n fromUri(uri: URI, cancellationToken?: CancellationToken): Promise>;\n\n /**\n * Update the given document after changes in the corresponding textual representation.\n * Method is called by the document builder after it has been requested to build an existing\n * document and the document's state is {@link DocumentState.Changed}.\n * The text parsing is expected to be done the same way as in {@link fromTextDocument}\n * and {@link fromString}.\n */\n update(document: LangiumDocument, cancellationToken: CancellationToken): Promise>\n}\n\nexport class DefaultLangiumDocumentFactory implements LangiumDocumentFactory {\n\n protected readonly serviceRegistry: ServiceRegistry;\n protected readonly textDocuments?: TextDocumentProvider;\n protected readonly fileSystemProvider: FileSystemProvider;\n\n constructor(services: LangiumSharedCoreServices) {\n this.serviceRegistry = services.ServiceRegistry;\n this.textDocuments = services.workspace.TextDocuments;\n this.fileSystemProvider = services.workspace.FileSystemProvider;\n }\n\n async fromUri(uri: URI, cancellationToken = CancellationToken.None): Promise> {\n const content = await this.fileSystemProvider.readFile(uri);\n return this.createAsync(uri, content, cancellationToken);\n }\n\n fromTextDocument(textDocument: TextDocument, uri?: URI): LangiumDocument;\n fromTextDocument(textDocument: TextDocument, uri: URI | undefined, cancellationToken: CancellationToken): Promise>;\n fromTextDocument(textDocument: TextDocument, uri?: URI, cancellationToken?: CancellationToken): LangiumDocument | Promise> {\n uri = uri ?? URI.parse(textDocument.uri);\n if (cancellationToken) {\n return this.createAsync(uri, textDocument, cancellationToken);\n } else {\n return this.create(uri, textDocument);\n }\n }\n\n fromString(text: string, uri: URI): LangiumDocument;\n fromString(text: string, uri: URI, cancellationToken: CancellationToken): Promise>;\n fromString(text: string, uri: URI, cancellationToken?: CancellationToken): LangiumDocument | Promise> {\n if (cancellationToken) {\n return this.createAsync(uri, text, cancellationToken);\n } else {\n return this.create(uri, text);\n }\n }\n\n fromModel(model: T, uri: URI): LangiumDocument {\n return this.create(uri, { $model: model });\n }\n\n protected create(uri: URI, content: string | TextDocument | { $model: T }): LangiumDocument {\n if (typeof content === 'string') {\n const parseResult = this.parse(uri, content);\n return this.createLangiumDocument(parseResult, uri, undefined, content);\n\n } else if ('$model' in content) {\n const parseResult = { value: content.$model, parserErrors: [], lexerErrors: [] };\n return this.createLangiumDocument(parseResult, uri);\n\n } else {\n const parseResult = this.parse(uri, content.getText());\n return this.createLangiumDocument(parseResult, uri, content);\n }\n }\n\n protected async createAsync(uri: URI, content: string | TextDocument, cancelToken: CancellationToken): Promise> {\n if (typeof content === 'string') {\n const parseResult = await this.parseAsync(uri, content, cancelToken);\n return this.createLangiumDocument(parseResult, uri, undefined, content);\n } else {\n const parseResult = await this.parseAsync(uri, content.getText(), cancelToken);\n return this.createLangiumDocument(parseResult, uri, content);\n }\n }\n\n /**\n * Create a LangiumDocument from a given parse result.\n *\n * A TextDocument is created on demand if it is not provided as argument here. Usually this\n * should not be necessary because the main purpose of the TextDocument is to convert between\n * text ranges and offsets, which is done solely in LSP request handling.\n *\n * With the introduction of {@link update} below this method is supposed to be mainly called\n * during workspace initialization and on addition/recognition of new files, while changes in\n * existing documents are processed via {@link update}.\n */\n protected createLangiumDocument(parseResult: ParseResult, uri: URI, textDocument?: TextDocument, text?: string): LangiumDocument {\n let document: LangiumDocument;\n if (textDocument) {\n document = {\n parseResult,\n uri,\n state: DocumentState.Parsed,\n references: [],\n textDocument\n };\n } else {\n const textDocumentGetter = this.createTextDocumentGetter(uri, text);\n document = {\n parseResult,\n uri,\n state: DocumentState.Parsed,\n references: [],\n get textDocument() {\n return textDocumentGetter();\n }\n };\n }\n (parseResult.value as Mutable).$document = document;\n return document;\n }\n\n async update(document: Mutable>, cancellationToken: CancellationToken): Promise> {\n // The CST full text property contains the original text that was used to create the AST.\n const oldText = document.parseResult.value.$cstNode?.root.fullText;\n const textDocument = this.textDocuments?.get(document.uri.toString());\n const text = textDocument ? textDocument.getText() : await this.fileSystemProvider.readFile(document.uri);\n\n if (textDocument) {\n Object.defineProperty(\n document,\n 'textDocument',\n {\n value: textDocument\n }\n );\n } else {\n const textDocumentGetter = this.createTextDocumentGetter(document.uri, text);\n Object.defineProperty(\n document,\n 'textDocument',\n {\n get: textDocumentGetter\n }\n );\n }\n\n // Some of these documents can be pretty large, so parsing them again can be quite expensive.\n // Therefore, we only parse if the text has actually changed.\n if (oldText !== text) {\n document.parseResult = await this.parseAsync(document.uri, text, cancellationToken);\n (document.parseResult.value as Mutable).$document = document;\n }\n document.state = DocumentState.Parsed;\n return document;\n }\n\n protected parse(uri: URI, text: string): ParseResult {\n const services = this.serviceRegistry.getServices(uri);\n return services.parser.LangiumParser.parse(text);\n }\n\n protected parseAsync(uri: URI, text: string, cancellationToken: CancellationToken): Promise> {\n const services = this.serviceRegistry.getServices(uri);\n return services.parser.AsyncParser.parse(text, cancellationToken);\n }\n\n protected createTextDocumentGetter(uri: URI, text?: string): () => TextDocument {\n const serviceRegistry = this.serviceRegistry;\n let textDoc: TextDocument | undefined = undefined;\n return () => {\n return textDoc ??= TextDocument.create(\n uri.toString(), serviceRegistry.getServices(uri).LanguageMetaData.languageId, 0, text ?? ''\n );\n };\n }\n}\n\n/**\n * Shared service for managing Langium documents.\n */\nexport interface LangiumDocuments {\n\n /**\n * A stream of all documents managed under this service.\n */\n readonly all: Stream\n\n /**\n * Manage a new document under this service.\n * @throws an error if a document with the same URI is already present.\n */\n addDocument(document: LangiumDocument): void;\n\n /**\n * Retrieve the document with the given URI, if present. Otherwise returns `undefined`.\n */\n getDocument(uri: URI): LangiumDocument | undefined;\n\n /**\n * Retrieve the document with the given URI. If not present, a new one will be created using the file system access.\n * The new document will be added to the list of documents managed under this service.\n */\n getOrCreateDocument(uri: URI, cancellationToken?: CancellationToken): Promise;\n\n /**\n * Creates a new document with the given URI and text content.\n * The new document is automatically added to this service and can be retrieved using {@link getDocument}.\n *\n * @throws an error if a document with the same URI is already present.\n */\n createDocument(uri: URI, text: string): LangiumDocument;\n\n /**\n * Creates a new document with the given URI and text content asynchronously.\n * The process can be interrupted with a cancellation token.\n * The new document is automatically added to this service and can be retrieved using {@link getDocument}.\n *\n * @throws an error if a document with the same URI is already present.\n */\n createDocument(uri: URI, text: string, cancellationToken: CancellationToken): Promise;\n\n /**\n * Returns `true` if a document with the given URI is managed under this service.\n */\n hasDocument(uri: URI): boolean;\n\n /**\n * Flag the document with the given URI as `Changed`, if present, meaning that its content\n * is no longer valid. The content (parseResult) stays untouched, while internal data may\n * be dropped to reduce memory footprint.\n *\n * @returns the affected {@link LangiumDocument} if existing for convenience\n */\n invalidateDocument(uri: URI): LangiumDocument | undefined;\n\n /**\n * Remove the document with the given URI, if present, and mark it as `Changed`, meaning\n * that its content is no longer valid. The next call to `getOrCreateDocument` with the same\n * URI will create a new document instance.\n *\n * @returns the affected {@link LangiumDocument} if existing for convenience\n */\n deleteDocument(uri: URI): LangiumDocument | undefined;\n}\n\nexport class DefaultLangiumDocuments implements LangiumDocuments {\n\n protected readonly langiumDocumentFactory: LangiumDocumentFactory;\n\n protected readonly documentMap: Map = new Map();\n\n constructor(services: LangiumSharedCoreServices) {\n this.langiumDocumentFactory = services.workspace.LangiumDocumentFactory;\n }\n\n get all(): Stream {\n return stream(this.documentMap.values());\n }\n\n addDocument(document: LangiumDocument): void {\n const uriString = document.uri.toString();\n if (this.documentMap.has(uriString)) {\n throw new Error(`A document with the URI '${uriString}' is already present.`);\n }\n this.documentMap.set(uriString, document);\n }\n\n getDocument(uri: URI): LangiumDocument | undefined {\n const uriString = uri.toString();\n return this.documentMap.get(uriString);\n }\n\n async getOrCreateDocument(uri: URI, cancellationToken?: CancellationToken): Promise {\n let document = this.getDocument(uri);\n if (document) {\n return document;\n }\n document = await this.langiumDocumentFactory.fromUri(uri, cancellationToken);\n this.addDocument(document);\n return document;\n }\n\n createDocument(uri: URI, text: string): LangiumDocument;\n createDocument(uri: URI, text: string, cancellationToken: CancellationToken): Promise;\n createDocument(uri: URI, text: string, cancellationToken?: CancellationToken): LangiumDocument | Promise {\n if (cancellationToken) {\n return this.langiumDocumentFactory.fromString(text, uri, cancellationToken).then(document => {\n this.addDocument(document);\n return document;\n });\n } else {\n const document = this.langiumDocumentFactory.fromString(text, uri);\n this.addDocument(document);\n return document;\n }\n }\n\n hasDocument(uri: URI): boolean {\n return this.documentMap.has(uri.toString());\n }\n\n invalidateDocument(uri: URI): LangiumDocument | undefined {\n const uriString = uri.toString();\n const langiumDoc = this.documentMap.get(uriString);\n if (langiumDoc) {\n langiumDoc.state = DocumentState.Changed;\n langiumDoc.precomputedScopes = undefined;\n langiumDoc.references = [];\n langiumDoc.diagnostics = undefined;\n }\n return langiumDoc;\n }\n\n deleteDocument(uri: URI): LangiumDocument | undefined {\n const uriString = uri.toString();\n const langiumDoc = this.documentMap.get(uriString);\n if (langiumDoc) {\n langiumDoc.state = DocumentState.Changed;\n this.documentMap.delete(uriString);\n }\n return langiumDoc;\n }\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, AstNodeDescription, AstReflection, CstNode, LinkingError, Reference, ReferenceInfo } from '../syntax-tree.js';\nimport type { AstNodeLocator } from '../workspace/ast-node-locator.js';\nimport type { LangiumDocument, LangiumDocuments } from '../workspace/documents.js';\nimport type { ScopeProvider } from './scope-provider.js';\nimport { CancellationToken } from '../utils/cancellation.js';\nimport { isAstNode, isAstNodeDescription, isLinkingError } from '../syntax-tree.js';\nimport { getDocument, streamAst, streamReferences } from '../utils/ast-utils.js';\nimport { interruptAndCheck } from '../utils/promise-utils.js';\nimport { DocumentState } from '../workspace/documents.js';\n\n/**\n * Language-specific service for resolving cross-references in the AST.\n */\nexport interface Linker {\n\n /**\n * Links all cross-references within the specified document. The default implementation loads only target\n * elements from documents that are present in the `LangiumDocuments` service. The linked references are\n * stored in the document's `references` property.\n *\n * @param document A LangiumDocument that shall be linked.\n * @param cancelToken A token for cancelling the operation.\n */\n link(document: LangiumDocument, cancelToken?: CancellationToken): Promise;\n\n /**\n * Unlinks all references within the specified document and removes them from the list of `references`.\n *\n * @param document A LangiumDocument that shall be unlinked.\n */\n unlink(document: LangiumDocument): void;\n\n /**\n * Determines a candidate AST node description for linking the given reference.\n *\n * @param node The AST node containing the reference.\n * @param refId The reference identifier used to build a scope.\n * @param reference The actual reference to resolve.\n */\n getCandidate(refInfo: ReferenceInfo): AstNodeDescription | LinkingError;\n\n /**\n * Creates a cross reference node being aware of its containing AstNode, the corresponding CstNode,\n * the cross reference text denoting the target AstNode being already extracted of the document text,\n * as well as the unique cross reference identifier.\n *\n * Default behavior:\n * - The returned Reference's 'ref' property pointing to the target AstNode is populated lazily on its\n * first visit.\n * - If the target AstNode cannot be resolved on the first visit, an error indicator will be installed\n * and further resolution attempts will *not* be performed.\n *\n * @param node The containing AST node\n * @param refNode The corresponding CST node\n * @param refId The cross reference identifier like ':'\n * @param refText The cross reference text denoting the target AstNode\n * @returns the desired Reference node, whose behavior wrt. resolving the cross reference is implementation specific.\n */\n buildReference(node: AstNode, property: string, refNode: CstNode | undefined, refText: string): Reference;\n\n}\n\ninterface DefaultReference extends Reference {\n _ref?: AstNode | LinkingError;\n _nodeDescription?: AstNodeDescription;\n}\n\nexport class DefaultLinker implements Linker {\n protected readonly reflection: AstReflection;\n protected readonly scopeProvider: ScopeProvider;\n protected readonly astNodeLocator: AstNodeLocator;\n protected readonly langiumDocuments: () => LangiumDocuments;\n\n constructor(services: LangiumCoreServices) {\n this.reflection = services.shared.AstReflection;\n this.langiumDocuments = () => services.shared.workspace.LangiumDocuments;\n this.scopeProvider = services.references.ScopeProvider;\n this.astNodeLocator = services.workspace.AstNodeLocator;\n }\n\n async link(document: LangiumDocument, cancelToken = CancellationToken.None): Promise {\n for (const node of streamAst(document.parseResult.value)) {\n await interruptAndCheck(cancelToken);\n streamReferences(node).forEach(ref => this.doLink(ref, document));\n }\n }\n\n protected doLink(refInfo: ReferenceInfo, document: LangiumDocument): void {\n const ref = refInfo.reference as DefaultReference;\n // The reference may already have been resolved lazily by accessing its `ref` property.\n if (ref._ref === undefined) {\n try {\n const description = this.getCandidate(refInfo);\n if (isLinkingError(description)) {\n ref._ref = description;\n } else {\n ref._nodeDescription = description;\n if (this.langiumDocuments().hasDocument(description.documentUri)) {\n // The target document is already loaded\n const linkedNode = this.loadAstNode(description);\n ref._ref = linkedNode ?? this.createLinkingError(refInfo, description);\n }\n }\n } catch (err) {\n ref._ref = {\n ...refInfo,\n message: `An error occurred while resolving reference to '${ref.$refText}': ${err}`\n };\n }\n }\n // Add the reference to the document's array of references\n document.references.push(ref);\n }\n\n unlink(document: LangiumDocument): void {\n for (const ref of document.references) {\n delete (ref as DefaultReference)._ref;\n delete (ref as DefaultReference)._nodeDescription;\n }\n document.references = [];\n }\n\n getCandidate(refInfo: ReferenceInfo): AstNodeDescription | LinkingError {\n const scope = this.scopeProvider.getScope(refInfo);\n const description = scope.getElement(refInfo.reference.$refText);\n return description ?? this.createLinkingError(refInfo);\n }\n\n buildReference(node: AstNode, property: string, refNode: CstNode | undefined, refText: string): Reference {\n // See behavior description in doc of Linker, update that on changes in here.\n // eslint-disable-next-line @typescript-eslint/no-this-alias\n const linker = this;\n const reference: DefaultReference = {\n $refNode: refNode,\n $refText: refText,\n\n get ref() {\n if (isAstNode(this._ref)) {\n // Most frequent case: the target is already resolved.\n return this._ref;\n } else if (isAstNodeDescription(this._nodeDescription)) {\n // A candidate has been found before, but it is not loaded yet.\n const linkedNode = linker.loadAstNode(this._nodeDescription);\n this._ref = linkedNode ??\n linker.createLinkingError({ reference, container: node, property }, this._nodeDescription);\n } else if (this._ref === undefined) {\n // The reference has not been linked yet, so do that now.\n const refData = linker.getLinkedNode({ reference, container: node, property });\n if (refData.error && getDocument(node).state < DocumentState.ComputedScopes) {\n // Document scope is not ready, don't set `this._ref` so linker can retry later.\n return undefined;\n }\n this._ref = refData.node ?? refData.error;\n this._nodeDescription = refData.descr;\n }\n return isAstNode(this._ref) ? this._ref : undefined;\n },\n get $nodeDescription() {\n return this._nodeDescription;\n },\n get error() {\n return isLinkingError(this._ref) ? this._ref : undefined;\n }\n };\n return reference;\n }\n\n protected getLinkedNode(refInfo: ReferenceInfo): { node?: AstNode, descr?: AstNodeDescription, error?: LinkingError } {\n try {\n const description = this.getCandidate(refInfo);\n if (isLinkingError(description)) {\n return { error: description };\n }\n const linkedNode = this.loadAstNode(description);\n if (linkedNode) {\n return { node: linkedNode, descr: description };\n }\n else {\n return {\n descr: description,\n error:\n this.createLinkingError(refInfo, description)\n };\n }\n } catch (err) {\n return {\n error: {\n ...refInfo,\n message: `An error occurred while resolving reference to '${refInfo.reference.$refText}': ${err}`\n }\n };\n }\n }\n\n protected loadAstNode(nodeDescription: AstNodeDescription): AstNode | undefined {\n if (nodeDescription.node) {\n return nodeDescription.node;\n }\n const doc = this.langiumDocuments().getDocument(nodeDescription.documentUri);\n if (!doc) {\n return undefined;\n }\n return this.astNodeLocator.getAstNode(doc.parseResult.value, nodeDescription.path);\n }\n\n protected createLinkingError(refInfo: ReferenceInfo, targetDescription?: AstNodeDescription): LinkingError {\n // Check whether the document is sufficiently processed by the DocumentBuilder. If not, this is a hint for a bug\n // in the language implementation.\n const document = getDocument(refInfo.container);\n if (document.state < DocumentState.ComputedScopes) {\n console.warn(`Attempted reference resolution before document reached ComputedScopes state (${document.uri}).`);\n }\n const referenceType = this.reflection.getReferenceType(refInfo);\n return {\n ...refInfo,\n message: `Could not resolve reference to ${referenceType} named '${refInfo.reference.$refText}'.`,\n targetDescription\n };\n }\n\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { AstNode, CstNode } from '../syntax-tree.js';\nimport { findNodeForProperty } from '../utils/grammar-utils.js';\n\nexport interface NamedAstNode extends AstNode {\n name: string;\n}\n\nexport function isNamed(node: AstNode): node is NamedAstNode {\n return typeof (node as NamedAstNode).name === 'string';\n}\n\n/**\n * Utility service for retrieving the `name` of an `AstNode` or the `CstNode` containing a `name`.\n */\nexport interface NameProvider {\n /**\n * Returns the `name` of a given AstNode.\n * @param node Specified `AstNode` whose name node shall be retrieved.\n */\n getName(node: AstNode): string | undefined;\n /**\n * Returns the `CstNode` which contains the parsed value of the `name` assignment.\n * @param node Specified `AstNode` whose name node shall be retrieved.\n */\n getNameNode(node: AstNode): CstNode | undefined;\n}\n\nexport class DefaultNameProvider implements NameProvider {\n getName(node: AstNode): string | undefined {\n if (isNamed(node)) {\n return node.name;\n }\n return undefined;\n }\n\n getNameNode(node: AstNode): CstNode | undefined {\n return findNodeForProperty(node.$cstNode, 'name');\n }\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, CstNode, GenericAstNode } from '../syntax-tree.js';\nimport type { Stream } from '../utils/stream.js';\nimport type { ReferenceDescription } from '../workspace/ast-descriptions.js';\nimport type { AstNodeLocator } from '../workspace/ast-node-locator.js';\nimport type { IndexManager } from '../workspace/index-manager.js';\nimport type { NameProvider } from './name-provider.js';\nimport type { URI } from '../utils/uri-utils.js';\nimport { findAssignment } from '../utils/grammar-utils.js';\nimport { isReference } from '../syntax-tree.js';\nimport { getDocument } from '../utils/ast-utils.js';\nimport { isChildNode, toDocumentSegment } from '../utils/cst-utils.js';\nimport { stream } from '../utils/stream.js';\nimport { UriUtils } from '../utils/uri-utils.js';\n\n/**\n * Language-specific service for finding references and declaration of a given `CstNode`.\n */\nexport interface References {\n\n /**\n * If the CstNode is a reference node the target CstNode will be returned.\n * If the CstNode is a significant node of the CstNode this CstNode will be returned.\n *\n * @param sourceCstNode CstNode that points to a AstNode\n */\n findDeclaration(sourceCstNode: CstNode): AstNode | undefined;\n\n /**\n * If the CstNode is a reference node the target CstNode will be returned.\n * If the CstNode is a significant node of the CstNode this CstNode will be returned.\n *\n * @param sourceCstNode CstNode that points to a AstNode\n */\n findDeclarationNode(sourceCstNode: CstNode): CstNode | undefined;\n\n /**\n * Finds all references to the target node as references (local references) or reference descriptions.\n *\n * @param targetNode Specified target node whose references should be returned\n */\n findReferences(targetNode: AstNode, options: FindReferencesOptions): Stream;\n}\n\nexport interface FindReferencesOptions {\n /**\n * @deprecated Since v1.2.0. Please use `documentUri` instead.\n */\n onlyLocal?: boolean;\n /**\n * When set, the `findReferences` method will only return references/declarations from the specified document.\n */\n documentUri?: URI;\n /**\n * Whether the returned list of references should include the declaration.\n */\n includeDeclaration?: boolean;\n}\n\nexport class DefaultReferences implements References {\n protected readonly nameProvider: NameProvider;\n protected readonly index: IndexManager;\n protected readonly nodeLocator: AstNodeLocator;\n\n constructor(services: LangiumCoreServices) {\n this.nameProvider = services.references.NameProvider;\n this.index = services.shared.workspace.IndexManager;\n this.nodeLocator = services.workspace.AstNodeLocator;\n }\n\n findDeclaration(sourceCstNode: CstNode): AstNode | undefined {\n if (sourceCstNode) {\n const assignment = findAssignment(sourceCstNode);\n const nodeElem = sourceCstNode.astNode;\n if (assignment && nodeElem) {\n const reference = (nodeElem as GenericAstNode)[assignment.feature];\n\n if (isReference(reference)) {\n return reference.ref;\n } else if (Array.isArray(reference)) {\n for (const ref of reference) {\n if (isReference(ref) && ref.$refNode\n && ref.$refNode.offset <= sourceCstNode.offset\n && ref.$refNode.end >= sourceCstNode.end) {\n return ref.ref;\n }\n }\n }\n }\n if (nodeElem) {\n const nameNode = this.nameProvider.getNameNode(nodeElem);\n // Only return the targeted node in case the targeted cst node is the name node or part of it\n if (nameNode && (nameNode === sourceCstNode || isChildNode(sourceCstNode, nameNode))) {\n return nodeElem;\n }\n }\n }\n return undefined;\n }\n\n findDeclarationNode(sourceCstNode: CstNode): CstNode | undefined {\n const astNode = this.findDeclaration(sourceCstNode);\n if (astNode?.$cstNode) {\n const targetNode = this.nameProvider.getNameNode(astNode);\n return targetNode ?? astNode.$cstNode;\n }\n return undefined;\n }\n\n findReferences(targetNode: AstNode, options: FindReferencesOptions): Stream {\n const refs: ReferenceDescription[] = [];\n if (options.includeDeclaration) {\n const ref = this.getReferenceToSelf(targetNode);\n if (ref) {\n refs.push(ref);\n }\n }\n let indexReferences = this.index.findAllReferences(targetNode, this.nodeLocator.getAstNodePath(targetNode));\n if (options.documentUri) {\n indexReferences = indexReferences.filter(ref => UriUtils.equals(ref.sourceUri, options.documentUri));\n }\n refs.push(...indexReferences);\n return stream(refs);\n }\n\n protected getReferenceToSelf(targetNode: AstNode): ReferenceDescription | undefined {\n const nameNode = this.nameProvider.getNameNode(targetNode);\n if (nameNode) {\n const doc = getDocument(targetNode);\n const path = this.nodeLocator.getAstNodePath(targetNode);\n return {\n sourceUri: doc.uri,\n sourcePath: path,\n targetUri: doc.uri,\n targetPath: path,\n segment: toDocumentSegment(nameNode),\n local: true\n };\n }\n return undefined;\n }\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { Stream } from './stream.js';\nimport { Reduction, stream } from './stream.js';\n\n/**\n * A multimap is a variation of a Map that has potentially multiple values for every key.\n */\nexport class MultiMap {\n\n private map = new Map();\n\n constructor()\n constructor(elements: Array<[K, V]>)\n constructor(elements?: Array<[K, V]>) {\n if (elements) {\n for (const [key, value] of elements) {\n this.add(key, value);\n }\n }\n }\n\n /**\n * The total number of values in the multimap.\n */\n get size(): number {\n return Reduction.sum(stream(this.map.values()).map(a => a.length));\n }\n\n /**\n * Clear all entries in the multimap.\n */\n clear(): void {\n this.map.clear();\n }\n\n /**\n * Operates differently depending on whether a `value` is given:\n * * With a value, this method deletes the specific key / value pair from the multimap.\n * * Without a value, all values associated with the given key are deleted.\n *\n * @returns `true` if a value existed and has been removed, or `false` if the specified\n * key / value does not exist.\n */\n delete(key: K, value?: V): boolean {\n if (value === undefined) {\n return this.map.delete(key);\n } else {\n const values = this.map.get(key);\n if (values) {\n const index = values.indexOf(value);\n if (index >= 0) {\n if (values.length === 1) {\n this.map.delete(key);\n } else {\n values.splice(index, 1);\n }\n return true;\n }\n }\n return false;\n }\n }\n\n /**\n * Returns an array of all values associated with the given key. If no value exists,\n * an empty array is returned.\n *\n * _Note:_ The returned array is assumed not to be modified. Use the `set` method to add a\n * value and `delete` to remove a value from the multimap.\n */\n get(key: K): readonly V[] {\n return this.map.get(key) ?? [];\n }\n\n /**\n * Operates differently depending on whether a `value` is given:\n * * With a value, this method returns `true` if the specific key / value pair is present in the multimap.\n * * Without a value, this method returns `true` if the given key is present in the multimap.\n */\n has(key: K, value?: V): boolean {\n if (value === undefined) {\n return this.map.has(key);\n } else {\n const values = this.map.get(key);\n if (values) {\n return values.indexOf(value) >= 0;\n }\n return false;\n }\n }\n\n /**\n * Add the given key / value pair to the multimap.\n */\n add(key: K, value: V): this {\n if (this.map.has(key)) {\n this.map.get(key)!.push(value);\n } else {\n this.map.set(key, [value]);\n }\n return this;\n }\n\n /**\n * Add the given set of key / value pairs to the multimap.\n */\n addAll(key: K, values: Iterable): this {\n if (this.map.has(key)) {\n this.map.get(key)!.push(...values);\n } else {\n this.map.set(key, Array.from(values));\n }\n return this;\n }\n\n /**\n * Invokes the given callback function for every key / value pair in the multimap.\n */\n forEach(callbackfn: (value: V, key: K, map: this) => void): void {\n this.map.forEach((array, key) =>\n array.forEach(value => callbackfn(value, key, this))\n );\n }\n\n /**\n * Returns an iterator of key, value pairs for every entry in the map.\n */\n [Symbol.iterator](): Iterator<[K, V]> {\n return this.entries().iterator();\n }\n\n /**\n * Returns a stream of key, value pairs for every entry in the map.\n */\n entries(): Stream<[K, V]> {\n return stream(this.map.entries())\n .flatMap(([key, array]) => array.map(value => [key, value] as [K, V]));\n }\n\n /**\n * Returns a stream of keys in the map.\n */\n keys(): Stream {\n return stream(this.map.keys());\n }\n\n /**\n * Returns a stream of values in the map.\n */\n values(): Stream {\n return stream(this.map.values()).flat();\n }\n\n /**\n * Returns a stream of key, value set pairs for every key in the map.\n */\n entriesGroupedByKey(): Stream<[K, V[]]> {\n return stream(this.map.entries());\n }\n\n}\n\nexport class BiMap {\n\n private map = new Map();\n private inverse = new Map();\n\n get size(): number {\n return this.map.size;\n }\n\n constructor()\n constructor(elements: Array<[K, V]>)\n constructor(elements?: Array<[K, V]>) {\n if (elements) {\n for (const [key, value] of elements) {\n this.set(key, value);\n }\n }\n }\n\n clear(): void {\n this.map.clear();\n this.inverse.clear();\n }\n\n set(key: K, value: V): this {\n this.map.set(key, value);\n this.inverse.set(value, key);\n return this;\n }\n\n get(key: K): V | undefined {\n return this.map.get(key);\n }\n\n getKey(value: V): K | undefined {\n return this.inverse.get(value);\n }\n\n delete(key: K): boolean {\n const value = this.map.get(key);\n if (value !== undefined) {\n this.map.delete(key);\n this.inverse.delete(value);\n return true;\n }\n return false;\n }\n}\n", "/******************************************************************************\n * Copyright 2021-2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, AstNodeDescription } from '../syntax-tree.js';\nimport type { AstNodeDescriptionProvider } from '../workspace/ast-descriptions.js';\nimport type { LangiumDocument, PrecomputedScopes } from '../workspace/documents.js';\nimport type { NameProvider } from './name-provider.js';\nimport { CancellationToken } from '../utils/cancellation.js';\nimport { streamAllContents, streamContents } from '../utils/ast-utils.js';\nimport { MultiMap } from '../utils/collections.js';\nimport { interruptAndCheck } from '../utils/promise-utils.js';\n\n/**\n * Language-specific service for precomputing global and local scopes. The service methods are executed\n * as the first and second phase in the `DocumentBuilder`.\n */\nexport interface ScopeComputation {\n\n /**\n * Creates descriptions of all AST nodes that shall be exported into the _global_ scope from the given\n * document. These descriptions are gathered by the `IndexManager` and stored in the global index so\n * they can be referenced from other documents.\n *\n * _Note:_ You should not resolve any cross-references in this service method. Cross-reference resolution\n * depends on the scope computation phase to be completed (`computeScope` method), which runs after the\n * initial indexing where this method is used.\n *\n * @param document The document from which to gather exported AST nodes.\n * @param cancelToken Indicates when to cancel the current operation.\n * @throws `OperationCanceled` if a user action occurs during execution\n */\n computeExports(document: LangiumDocument, cancelToken?: CancellationToken): Promise;\n\n /**\n * Precomputes the _local_ scopes for a document, which are necessary for the default way of\n * resolving references to symbols in the same document. The result is a multimap assigning a\n * set of AST node descriptions to every level of the AST. These data are used by the `ScopeProvider`\n * service to determine which target nodes are visible in the context of a specific cross-reference.\n *\n * _Note:_ You should not resolve any cross-references in this service method. Cross-reference\n * resolution depends on the scope computation phase to be completed.\n *\n * @param document The document in which to compute scopes.\n * @param cancelToken Indicates when to cancel the current operation.\n * @throws `OperationCanceled` if a user action occurs during execution\n */\n computeLocalScopes(document: LangiumDocument, cancelToken?: CancellationToken): Promise;\n\n}\n\n/**\n * The default scope computation creates and collectes descriptions of the AST nodes to be exported into the\n * _global_ scope from the given document. By default those are the document's root AST node and its directly\n * contained child nodes.\n *\n * Besides, it gathers all AST nodes that have a name (according to the `NameProvider` service) and includes them\n * in the local scope of their particular container nodes. As a result, for every cross-reference in the AST,\n * target elements from the same level (siblings) and further up towards the root (parents and siblings of parents)\n * are visible. Elements being nested inside lower levels (children, children of siblings and parents' siblings)\n * are _invisible_ by default, but that can be changed by customizing this service.\n */\nexport class DefaultScopeComputation implements ScopeComputation {\n\n protected readonly nameProvider: NameProvider;\n protected readonly descriptions: AstNodeDescriptionProvider;\n\n constructor(services: LangiumCoreServices) {\n this.nameProvider = services.references.NameProvider;\n this.descriptions = services.workspace.AstNodeDescriptionProvider;\n }\n\n async computeExports(document: LangiumDocument, cancelToken = CancellationToken.None): Promise {\n return this.computeExportsForNode(document.parseResult.value, document, undefined, cancelToken);\n }\n\n /**\n * Creates {@link AstNodeDescription AstNodeDescriptions} for the given {@link AstNode parentNode} and its children.\n * The list of children to be considered is determined by the function parameter {@link children}.\n * By default only the direct children of {@link parentNode} are visited, nested nodes are not exported.\n *\n * @param parentNode AST node to be exported, i.e., of which an {@link AstNodeDescription} shall be added to the returned list.\n * @param document The document containing the AST node to be exported.\n * @param children A function called with {@link parentNode} as single argument and returning an {@link Iterable} supplying the children to be visited, which must be directly or transitively contained in {@link parentNode}.\n * @param cancelToken Indicates when to cancel the current operation.\n * @throws `OperationCanceled` if a user action occurs during execution.\n * @returns A list of {@link AstNodeDescription AstNodeDescriptions} to be published to index.\n */\n async computeExportsForNode(parentNode: AstNode, document: LangiumDocument, children: (root: AstNode) => Iterable = streamContents, cancelToken: CancellationToken = CancellationToken.None): Promise {\n const exports: AstNodeDescription[] = [];\n\n this.exportNode(parentNode, exports, document);\n for (const node of children(parentNode)) {\n await interruptAndCheck(cancelToken);\n this.exportNode(node, exports, document);\n }\n return exports;\n }\n\n /**\n * Add a single node to the list of exports if it has a name. Override this method to change how\n * symbols are exported, e.g. by modifying their exported name.\n */\n protected exportNode(node: AstNode, exports: AstNodeDescription[], document: LangiumDocument): void {\n const name = this.nameProvider.getName(node);\n if (name) {\n exports.push(this.descriptions.createDescription(node, name, document));\n }\n }\n\n async computeLocalScopes(document: LangiumDocument, cancelToken = CancellationToken.None): Promise {\n const rootNode = document.parseResult.value;\n const scopes = new MultiMap();\n // Here we navigate the full AST - local scopes shall be available in the whole document\n for (const node of streamAllContents(rootNode)) {\n await interruptAndCheck(cancelToken);\n this.processNode(node, document, scopes);\n }\n return scopes;\n }\n\n /**\n * Process a single node during scopes computation. The default implementation makes the node visible\n * in the subtree of its container (if the node has a name). Override this method to change this,\n * e.g. by increasing the visibility to a higher level in the AST.\n */\n protected processNode(node: AstNode, document: LangiumDocument, scopes: PrecomputedScopes): void {\n const container = node.$container;\n if (container) {\n const name = this.nameProvider.getName(node);\n if (name) {\n scopes.add(container, this.descriptions.createDescription(node, name, document));\n }\n }\n }\n\n}\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { AstNodeDescription } from '../syntax-tree.js';\nimport type { Stream } from '../utils/stream.js';\nimport { EMPTY_STREAM, stream } from '../utils/stream.js';\n\n/**\n * A scope describes what target elements are visible from a specific cross-reference context.\n */\nexport interface Scope {\n\n /**\n * Find a target element matching the given name. If no element is found, `undefined` is returned.\n * If multiple matching elements are present, the selection of the returned element should be done\n * according to the semantics of your language. Usually it is the element that is most closely defined.\n *\n * @param name Name of the cross-reference target as it appears in the source text.\n */\n getElement(name: string): AstNodeDescription | undefined;\n\n /**\n * Create a stream of all elements in the scope. This is used to compute completion proposals to be\n * shown in the editor.\n */\n getAllElements(): Stream;\n\n}\n\nexport interface ScopeOptions {\n caseInsensitive?: boolean;\n}\n\n/**\n * The default scope implementation is based on a `Stream`. It has an optional _outer scope_ describing\n * the next level of elements, which are queried when a target element is not found in the stream provided\n * to this scope.\n */\nexport class StreamScope implements Scope {\n readonly elements: Stream;\n readonly outerScope?: Scope;\n readonly caseInsensitive: boolean;\n\n constructor(elements: Stream, outerScope?: Scope, options?: ScopeOptions) {\n this.elements = elements;\n this.outerScope = outerScope;\n this.caseInsensitive = options?.caseInsensitive ?? false;\n }\n\n getAllElements(): Stream {\n if (this.outerScope) {\n return this.elements.concat(this.outerScope.getAllElements());\n } else {\n return this.elements;\n }\n }\n\n getElement(name: string): AstNodeDescription | undefined {\n const local = this.caseInsensitive\n ? this.elements.find(e => e.name.toLowerCase() === name.toLowerCase())\n : this.elements.find(e => e.name === name);\n if (local) {\n return local;\n }\n if (this.outerScope) {\n return this.outerScope.getElement(name);\n }\n return undefined;\n }\n}\n\nexport class MapScope implements Scope {\n readonly elements: Map;\n readonly outerScope?: Scope;\n readonly caseInsensitive: boolean;\n\n constructor(elements: Iterable, outerScope?: Scope, options?: ScopeOptions) {\n this.elements = new Map();\n this.caseInsensitive = options?.caseInsensitive ?? false;\n for (const element of elements) {\n const name = this.caseInsensitive\n ? element.name.toLowerCase()\n : element.name;\n this.elements.set(name, element);\n }\n this.outerScope = outerScope;\n }\n\n getElement(name: string): AstNodeDescription | undefined {\n const localName = this.caseInsensitive ? name.toLowerCase() : name;\n const local = this.elements.get(localName);\n if (local) {\n return local;\n }\n if (this.outerScope) {\n return this.outerScope.getElement(name);\n }\n return undefined;\n }\n\n getAllElements(): Stream {\n let elementStream = stream(this.elements.values());\n if (this.outerScope) {\n elementStream = elementStream.concat(this.outerScope.getAllElements());\n }\n return elementStream;\n }\n\n}\n\nexport const EMPTY_SCOPE: Scope = {\n getElement(): undefined {\n return undefined;\n },\n getAllElements(): Stream {\n return EMPTY_STREAM;\n }\n};\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { Disposable } from './disposable.js';\nimport type { URI } from './uri-utils.js';\nimport type { LangiumSharedCoreServices } from '../services.js';\n\nexport abstract class DisposableCache implements Disposable {\n\n protected toDispose: Disposable[] = [];\n protected isDisposed = false;\n\n onDispose(disposable: Disposable): void {\n this.toDispose.push(disposable);\n }\n\n dispose(): void {\n this.throwIfDisposed();\n this.clear();\n this.isDisposed = true;\n this.toDispose.forEach(disposable => disposable.dispose());\n }\n\n protected throwIfDisposed(): void {\n if (this.isDisposed) {\n throw new Error('This cache has already been disposed');\n }\n }\n\n abstract clear(): void;\n}\n\nexport class SimpleCache extends DisposableCache {\n protected readonly cache = new Map();\n\n has(key: K): boolean {\n this.throwIfDisposed();\n return this.cache.has(key);\n }\n\n set(key: K, value: V): void {\n this.throwIfDisposed();\n this.cache.set(key, value);\n }\n\n get(key: K): V | undefined;\n get(key: K, provider: () => V): V;\n get(key: K, provider?: () => V): V | undefined {\n this.throwIfDisposed();\n if (this.cache.has(key)) {\n return this.cache.get(key);\n } else if (provider) {\n const value = provider();\n this.cache.set(key, value);\n return value;\n } else {\n return undefined;\n }\n }\n\n delete(key: K): boolean {\n this.throwIfDisposed();\n return this.cache.delete(key);\n }\n\n clear(): void {\n this.throwIfDisposed();\n this.cache.clear();\n }\n}\n\nexport class ContextCache extends DisposableCache {\n\n private readonly cache = new Map>();\n private readonly converter: (input: Context) => ContextKey | Context;\n\n constructor(converter?: (input: Context) => ContextKey) {\n super();\n this.converter = converter ?? (value => value);\n }\n\n has(contextKey: Context, key: Key): boolean {\n this.throwIfDisposed();\n return this.cacheForContext(contextKey).has(key);\n }\n\n set(contextKey: Context, key: Key, value: Value): void {\n this.throwIfDisposed();\n this.cacheForContext(contextKey).set(key, value);\n }\n\n get(contextKey: Context, key: Key): Value | undefined;\n get(contextKey: Context, key: Key, provider: () => Value): Value;\n get(contextKey: Context, key: Key, provider?: () => Value): Value | undefined {\n this.throwIfDisposed();\n const contextCache = this.cacheForContext(contextKey);\n if (contextCache.has(key)) {\n return contextCache.get(key);\n } else if (provider) {\n const value = provider();\n contextCache.set(key, value);\n return value;\n } else {\n return undefined;\n }\n }\n\n delete(contextKey: Context, key: Key): boolean {\n this.throwIfDisposed();\n return this.cacheForContext(contextKey).delete(key);\n }\n\n clear(): void;\n clear(contextKey: Context): void;\n clear(contextKey?: Context): void {\n this.throwIfDisposed();\n if (contextKey) {\n const mapKey = this.converter(contextKey);\n this.cache.delete(mapKey);\n } else {\n this.cache.clear();\n }\n }\n\n protected cacheForContext(contextKey: Context): Map {\n const mapKey = this.converter(contextKey);\n let documentCache = this.cache.get(mapKey);\n if (!documentCache) {\n documentCache = new Map();\n this.cache.set(mapKey, documentCache);\n }\n return documentCache;\n }\n}\n\n/**\n * Every key/value pair in this cache is scoped to a document.\n * If this document is changed or deleted, all associated key/value pairs are deleted.\n */\nexport class DocumentCache extends ContextCache {\n constructor(sharedServices: LangiumSharedCoreServices) {\n super(uri => uri.toString());\n this.onDispose(sharedServices.workspace.DocumentBuilder.onUpdate((changed, deleted) => {\n const allUris = changed.concat(deleted);\n for (const uri of allUris) {\n this.clear(uri);\n }\n }));\n }\n}\n\n/**\n * Every key/value pair in this cache is scoped to the whole workspace.\n * If any document in the workspace changes, the whole cache is evicted.\n */\nexport class WorkspaceCache extends SimpleCache {\n constructor(sharedServices: LangiumSharedCoreServices) {\n super();\n this.onDispose(sharedServices.workspace.DocumentBuilder.onUpdate(() => {\n this.clear();\n }));\n }\n}\n", "/******************************************************************************\n * Copyright 2021-2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, AstNodeDescription, AstReflection, ReferenceInfo } from '../syntax-tree.js';\nimport type { Stream } from '../utils/stream.js';\nimport type { AstNodeDescriptionProvider } from '../workspace/ast-descriptions.js';\nimport type { IndexManager } from '../workspace/index-manager.js';\nimport type { NameProvider } from './name-provider.js';\nimport type { Scope, ScopeOptions} from './scope.js';\nimport { MapScope, StreamScope } from './scope.js';\nimport { getDocument } from '../utils/ast-utils.js';\nimport { stream } from '../utils/stream.js';\nimport { WorkspaceCache } from '../utils/caching.js';\n\n/**\n * Language-specific service for determining the scope of target elements visible in a specific cross-reference context.\n */\nexport interface ScopeProvider {\n\n /**\n * Return a scope describing what elements are visible for the given AST node and cross-reference\n * identifier.\n *\n * @param context Information about the reference for which a scope is requested.\n */\n getScope(context: ReferenceInfo): Scope;\n\n}\n\nexport class DefaultScopeProvider implements ScopeProvider {\n\n protected readonly reflection: AstReflection;\n protected readonly nameProvider: NameProvider;\n protected readonly descriptions: AstNodeDescriptionProvider;\n protected readonly indexManager: IndexManager;\n\n protected readonly globalScopeCache: WorkspaceCache;\n\n constructor(services: LangiumCoreServices) {\n this.reflection = services.shared.AstReflection;\n this.nameProvider = services.references.NameProvider;\n this.descriptions = services.workspace.AstNodeDescriptionProvider;\n this.indexManager = services.shared.workspace.IndexManager;\n this.globalScopeCache = new WorkspaceCache(services.shared);\n }\n\n getScope(context: ReferenceInfo): Scope {\n const scopes: Array> = [];\n const referenceType = this.reflection.getReferenceType(context);\n\n const precomputed = getDocument(context.container).precomputedScopes;\n if (precomputed) {\n let currentNode: AstNode | undefined = context.container;\n do {\n const allDescriptions = precomputed.get(currentNode);\n if (allDescriptions.length > 0) {\n scopes.push(stream(allDescriptions).filter(\n desc => this.reflection.isSubtype(desc.type, referenceType)));\n }\n currentNode = currentNode.$container;\n } while (currentNode);\n }\n\n let result: Scope = this.getGlobalScope(referenceType, context);\n for (let i = scopes.length - 1; i >= 0; i--) {\n result = this.createScope(scopes[i], result);\n }\n return result;\n }\n\n /**\n * Create a scope for the given collection of AST node descriptions.\n */\n protected createScope(elements: Iterable, outerScope?: Scope, options?: ScopeOptions): Scope {\n return new StreamScope(stream(elements), outerScope, options);\n }\n\n /**\n * Create a scope for the given collection of AST nodes, which need to be transformed into respective\n * descriptions first. This is done using the `NameProvider` and `AstNodeDescriptionProvider` services.\n */\n protected createScopeForNodes(elements: Iterable, outerScope?: Scope, options?: ScopeOptions): Scope {\n const s = stream(elements).map(e => {\n const name = this.nameProvider.getName(e);\n if (name) {\n return this.descriptions.createDescription(e, name);\n }\n return undefined;\n }).nonNullable();\n return new StreamScope(s, outerScope, options);\n }\n\n /**\n * Create a global scope filtered for the given reference type.\n */\n protected getGlobalScope(referenceType: string, _context: ReferenceInfo): Scope {\n return this.globalScopeCache.get(referenceType, () => new MapScope(this.indexManager.allElements(referenceType)));\n }\n\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport { URI } from 'vscode-uri';\nimport type { CommentProvider } from '../documentation/comment-provider.js';\nimport type { NameProvider } from '../references/name-provider.js';\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, CstNode, GenericAstNode, Mutable, Reference } from '../syntax-tree.js';\nimport { isAstNode, isReference } from '../syntax-tree.js';\nimport { getDocument } from '../utils/ast-utils.js';\nimport { findNodesForProperty } from '../utils/grammar-utils.js';\nimport type { AstNodeLocator } from '../workspace/ast-node-locator.js';\nimport type { DocumentSegment, LangiumDocument, LangiumDocuments } from '../workspace/documents.js';\n\nexport interface JsonSerializeOptions {\n /** The space parameter for `JSON.stringify`, controlling whether and how to pretty-print the output. */\n space?: string | number;\n /** Whether to include the `$refText` property for references (the name used to identify the target node). */\n refText?: boolean;\n /** Whether to include the `$sourceText` property, which holds the full source text from which an AST node was parsed. */\n sourceText?: boolean;\n /** Whether to include the `$textRegion` property, which holds information to trace AST node properties to their respective source text regions. */\n textRegions?: boolean;\n /** Whether to include the `$comment` property, which holds comments according to the CommentProvider service. */\n comments?: boolean;\n /** The replacer parameter for `JSON.stringify`; the default replacer given as parameter should be used to apply basic replacements. */\n replacer?: (key: string, value: unknown, defaultReplacer: (key: string, value: unknown) => unknown) => unknown\n /** Used to convert and serialize URIs when the target of a cross-reference is in a different document. */\n uriConverter?: (uri: URI, reference: Reference) => string\n}\n\nexport interface JsonDeserializeOptions {\n /** Used to parse and convert URIs when the target of a cross-reference is in a different document. */\n uriConverter?: (uri: string) => URI\n}\n\n/**\n * {@link AstNode}s that may carry information on their definition area within the DSL text.\n */\nexport interface AstNodeWithTextRegion extends AstNode {\n $sourceText?: string;\n $textRegion?: AstNodeRegionWithAssignments;\n}\n\n/**\n * {@link AstNode}s that may carry a semantically relevant comment.\n */\nexport interface AstNodeWithComment extends AstNode {\n $comment?: string;\n}\n\nexport function isAstNodeWithComment(node: AstNode): node is AstNodeWithComment {\n return typeof (node as AstNodeWithComment).$comment === 'string';\n}\n\n/**\n * A {@DocumentSegment} representing the definition area of an AstNode within the DSL text.\n * Usually contains text region information on all assigned property values of the AstNode,\n * and may contain the defining file's URI as string.\n */\nexport interface AstNodeRegionWithAssignments extends DocumentSegment {\n /**\n * A record containing an entry for each assigned property of the AstNode.\n * The key is equal to the property name and the value is an array of the property values'\n * text regions, regardless of whether the property is a single value or list property.\n */\n assignments?: Record;\n /**\n * The AstNode defining file's URI as string\n */\n documentURI?: string;\n}\n\n/**\n * Utility service for transforming an `AstNode` into a JSON string and vice versa.\n */\nexport interface JsonSerializer {\n /**\n * Serialize an `AstNode` into a JSON `string`.\n * @param node The `AstNode` to be serialized.\n * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read.\n */\n serialize(node: AstNode, options?: JsonSerializeOptions): string;\n /**\n * Deserialize (parse) a JSON `string` into an `AstNode`.\n */\n deserialize(content: string, options?: JsonDeserializeOptions): T;\n}\n\n/**\n * A cross-reference in the serialized JSON representation of an AstNode.\n */\ninterface IntermediateReference {\n /** URI pointing to the target element. This is either `#${path}` if the target is in the same document, or `${documentURI}#${path}` otherwise. */\n $ref?: string\n /** The actual text used to look up the reference target in the surrounding scope. */\n $refText?: string\n /** If any problem occurred while resolving the reference, it is described by this property. */\n $error?: string\n}\n\nfunction isIntermediateReference(obj: unknown): obj is IntermediateReference {\n return typeof obj === 'object' && !!obj && ('$ref' in obj || '$error' in obj);\n}\n\nexport class DefaultJsonSerializer implements JsonSerializer {\n\n /** The set of AstNode properties to be ignored by the serializer. */\n ignoreProperties = new Set(['$container', '$containerProperty', '$containerIndex', '$document', '$cstNode']);\n\n /** The document that is currently processed by the serializer; this is used by the replacer function. */\n protected currentDocument: LangiumDocument | undefined;\n\n protected readonly langiumDocuments: LangiumDocuments;\n protected readonly astNodeLocator: AstNodeLocator;\n protected readonly nameProvider: NameProvider;\n protected readonly commentProvider: CommentProvider;\n\n constructor(services: LangiumCoreServices) {\n this.langiumDocuments = services.shared.workspace.LangiumDocuments;\n this.astNodeLocator = services.workspace.AstNodeLocator;\n this.nameProvider = services.references.NameProvider;\n this.commentProvider = services.documentation.CommentProvider;\n }\n\n serialize(node: AstNode, options: JsonSerializeOptions = {}): string {\n const specificReplacer = options?.replacer;\n const defaultReplacer = (key: string, value: unknown) => this.replacer(key, value, options);\n const replacer = specificReplacer ? (key: string, value: unknown) => specificReplacer(key, value, defaultReplacer) : defaultReplacer;\n\n try {\n this.currentDocument = getDocument(node);\n return JSON.stringify(node, replacer, options?.space);\n } finally {\n this.currentDocument = undefined;\n }\n }\n\n deserialize(content: string, options: JsonDeserializeOptions = {}): T {\n const root = JSON.parse(content);\n this.linkNode(root, root, options);\n return root;\n }\n\n protected replacer(key: string, value: unknown, { refText, sourceText, textRegions, comments, uriConverter }: JsonSerializeOptions): unknown {\n if (this.ignoreProperties.has(key)) {\n return undefined;\n } else if (isReference(value)) {\n const refValue = value.ref;\n const $refText = refText ? value.$refText : undefined;\n if (refValue) {\n const targetDocument = getDocument(refValue);\n let targetUri = '';\n if (this.currentDocument && this.currentDocument !== targetDocument) {\n if (uriConverter) {\n targetUri = uriConverter(targetDocument.uri, value);\n } else {\n targetUri = targetDocument.uri.toString();\n }\n }\n const targetPath = this.astNodeLocator.getAstNodePath(refValue);\n return {\n $ref: `${targetUri}#${targetPath}`,\n $refText\n } satisfies IntermediateReference;\n } else {\n return {\n $error: value.error?.message ?? 'Could not resolve reference',\n $refText\n } satisfies IntermediateReference;\n }\n } else if (isAstNode(value)) {\n let astNode: AstNodeWithTextRegion | undefined = undefined;\n if (textRegions) {\n astNode = this.addAstNodeRegionWithAssignmentsTo({ ...value });\n if ((!key || value.$document) && astNode?.$textRegion) {\n // The document URI is added to the root node of the resulting JSON tree\n astNode.$textRegion.documentURI = this.currentDocument?.uri.toString();\n }\n }\n if (sourceText && !key) {\n astNode ??= { ...value };\n astNode.$sourceText = value.$cstNode?.text;\n }\n if (comments) {\n astNode ??= { ...value };\n const comment = this.commentProvider.getComment(value);\n if (comment) {\n (astNode as AstNodeWithComment).$comment = comment.replace(/\\r/g, '');\n }\n }\n return astNode ?? value;\n } else {\n return value;\n }\n }\n\n protected addAstNodeRegionWithAssignmentsTo(node: AstNodeWithTextRegion) {\n const createDocumentSegment: (cstNode: CstNode) => AstNodeRegionWithAssignments = cstNode => {\n offset: cstNode.offset,\n end: cstNode.end,\n length: cstNode.length,\n range: cstNode.range,\n };\n\n if (node.$cstNode) {\n const textRegion = node.$textRegion = createDocumentSegment(node.$cstNode);\n const assignments: Record = textRegion.assignments = {};\n\n Object.keys(node).filter(key => !key.startsWith('$')).forEach(key => {\n const propertyAssignments = findNodesForProperty(node.$cstNode, key).map(createDocumentSegment);\n if (propertyAssignments.length !== 0) {\n assignments[key] = propertyAssignments;\n }\n });\n\n return node;\n }\n return undefined;\n }\n\n protected linkNode(node: GenericAstNode, root: AstNode, options: JsonDeserializeOptions, container?: AstNode, containerProperty?: string, containerIndex?: number) {\n for (const [propertyName, item] of Object.entries(node)) {\n if (Array.isArray(item)) {\n for (let index = 0; index < item.length; index++) {\n const element = item[index];\n if (isIntermediateReference(element)) {\n item[index] = this.reviveReference(node, propertyName, root, element, options);\n } else if (isAstNode(element)) {\n this.linkNode(element as GenericAstNode, root, options, node, propertyName, index);\n }\n }\n } else if (isIntermediateReference(item)) {\n node[propertyName] = this.reviveReference(node, propertyName, root, item, options);\n } else if (isAstNode(item)) {\n this.linkNode(item as GenericAstNode, root, options, node, propertyName);\n }\n }\n const mutable = node as Mutable;\n mutable.$container = container;\n mutable.$containerProperty = containerProperty;\n mutable.$containerIndex = containerIndex;\n }\n\n protected reviveReference(container: AstNode, property: string, root: AstNode, reference: IntermediateReference, options: JsonDeserializeOptions): Reference | undefined {\n let refText = reference.$refText;\n let error = reference.$error;\n if (reference.$ref) {\n const ref = this.getRefNode(root, reference.$ref, options.uriConverter);\n if (isAstNode(ref)) {\n if (!refText) {\n refText = this.nameProvider.getName(ref);\n }\n return {\n $refText: refText ?? '',\n ref\n };\n } else {\n error = ref;\n }\n }\n if (error) {\n const ref: Mutable = {\n $refText: refText ?? ''\n };\n ref.error = {\n container,\n property,\n message: error,\n reference: ref\n };\n return ref;\n } else {\n return undefined;\n }\n }\n\n protected getRefNode(root: AstNode, uri: string, uriConverter?: (uri: string) => URI): AstNode | string {\n try {\n const fragmentIndex = uri.indexOf('#');\n if (fragmentIndex === 0) {\n const node = this.astNodeLocator.getAstNode(root, uri.substring(1));\n if (!node) {\n return 'Could not resolve path: ' + uri;\n }\n return node;\n }\n if (fragmentIndex < 0) {\n const documentUri = uriConverter ? uriConverter(uri) : URI.parse(uri);\n const document = this.langiumDocuments.getDocument(documentUri);\n if (!document) {\n return 'Could not find document for URI: ' + uri;\n }\n return document.parseResult.value;\n }\n const documentUri = uriConverter ? uriConverter(uri.substring(0, fragmentIndex)) : URI.parse(uri.substring(0, fragmentIndex));\n const document = this.langiumDocuments.getDocument(documentUri);\n if (!document) {\n return 'Could not find document for URI: ' + uri;\n }\n if (fragmentIndex === uri.length - 1) {\n return document.parseResult.value;\n }\n const node = this.astNodeLocator.getAstNode(document.parseResult.value, uri.substring(fragmentIndex + 1));\n if (!node) {\n return 'Could not resolve URI: ' + uri;\n }\n return node;\n } catch (err) {\n return String(err);\n }\n }\n\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { LangiumCoreServices } from './services.js';\nimport { UriUtils, type URI } from './utils/uri-utils.js';\n\n/**\n * The service registry provides access to the language-specific {@link LangiumCoreServices} optionally including LSP-related services.\n * These are resolved via the URI of a text document.\n */\nexport interface ServiceRegistry {\n\n /**\n * Register a language via its injected services.\n */\n register(language: LangiumCoreServices): void;\n\n /**\n * Retrieve the language-specific services for the given URI. In case only one language is\n * registered, it may be used regardless of the URI format.\n */\n getServices(uri: URI): LangiumCoreServices;\n\n /**\n * The full set of registered language services.\n */\n readonly all: readonly LangiumCoreServices[];\n}\n\n/**\n * Generic registry for Langium services, but capable of being used with extending service sets as well (such as the lsp-complete LangiumCoreServices set)\n */\nexport class DefaultServiceRegistry implements ServiceRegistry {\n\n protected singleton?: LangiumCoreServices;\n protected map?: Record;\n\n register(language: LangiumCoreServices): void {\n if (!this.singleton && !this.map) {\n // This is the first language to be registered; store it as singleton.\n this.singleton = language;\n return;\n }\n if (!this.map) {\n this.map = {};\n if (this.singleton) {\n // Move the previous singleton instance to the new map.\n for (const ext of this.singleton.LanguageMetaData.fileExtensions) {\n this.map[ext] = this.singleton;\n }\n this.singleton = undefined;\n }\n }\n // Store the language services in the map.\n for (const ext of language.LanguageMetaData.fileExtensions) {\n if (this.map[ext] !== undefined && this.map[ext] !== language) {\n console.warn(`The file extension ${ext} is used by multiple languages. It is now assigned to '${language.LanguageMetaData.languageId}'.`);\n }\n this.map[ext] = language;\n }\n }\n\n getServices(uri: URI): LangiumCoreServices {\n if (this.singleton !== undefined) {\n return this.singleton;\n }\n if (this.map === undefined) {\n throw new Error('The service registry is empty. Use `register` to register the services of a language.');\n }\n const ext = UriUtils.extname(uri);\n const services = this.map[ext];\n if (!services) {\n throw new Error(`The service registry contains no services for the extension '${ext}'.`);\n }\n return services;\n }\n\n get all(): readonly LangiumCoreServices[] {\n if (this.singleton !== undefined) {\n return [this.singleton];\n }\n if (this.map !== undefined) {\n return Object.values(this.map);\n }\n return [];\n }\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { CodeDescription, DiagnosticRelatedInformation, DiagnosticTag, integer, Range } from 'vscode-languageserver-types';\nimport type { CancellationToken } from '../utils/cancellation.js';\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, AstReflection, Properties } from '../syntax-tree.js';\nimport type { MaybePromise } from '../utils/promise-utils.js';\nimport type { Stream } from '../utils/stream.js';\nimport type { DocumentSegment } from '../workspace/documents.js';\nimport { MultiMap } from '../utils/collections.js';\nimport { isOperationCancelled } from '../utils/promise-utils.js';\nimport { stream } from '../utils/stream.js';\n\nexport type DiagnosticInfo> = {\n /** The AST node to which the diagnostic is attached. */\n node: N;\n /** If a property name is given, the diagnostic is restricted to the corresponding text region. */\n property?: P;\n /** If the value of a keyword is given, the diagnostic will appear at its corresponding text region */\n keyword?: string;\n /** In case of a multi-value property (array), an index can be given to select a specific element. */\n index?: number;\n /** If you want to create a diagnostic independent to any property, use the range property. */\n range?: Range;\n /** The diagnostic's code, which usually appear in the user interface. */\n code?: integer | string;\n /** An optional property to describe the error code. */\n codeDescription?: CodeDescription;\n /** Additional metadata about the diagnostic. */\n tags?: DiagnosticTag[];\n /** An array of related diagnostic information, e.g. when symbol-names within a scope collide all definitions can be marked via this property. */\n relatedInformation?: DiagnosticRelatedInformation[];\n /** A data entry field that is preserved between a `textDocument/publishDiagnostics` notification and `textDocument/codeAction` request. */\n data?: unknown;\n}\n\n/**\n * Shape of information commonly used in the `data` field of diagnostics.\n */\nexport interface DiagnosticData {\n /** Diagnostic code for identifying which code action to apply. This code is _not_ shown in the user interface. */\n code: string\n /** Specifies where to apply the code action in the form of a `DocumentSegment`. */\n actionSegment?: DocumentSegment\n /** Specifies where to apply the code action in the form of a `Range`. */\n actionRange?: Range\n}\n\n/**\n * Create DiagnosticData for a given diagnostic code. The result can be put into the `data` field of a DiagnosticInfo.\n */\nexport function diagnosticData(code: string): DiagnosticData {\n return { code };\n}\n\nexport type ValidationAcceptor = (severity: 'error' | 'warning' | 'info' | 'hint', message: string, info: DiagnosticInfo) => void\n\nexport type ValidationCheck = (node: T, accept: ValidationAcceptor, cancelToken: CancellationToken) => MaybePromise;\n\n/**\n * A utility type for associating non-primitive AST types to corresponding validation checks. For example:\n *\n * ```ts\n * const checks: ValidationChecks = {\n * State: validator.checkStateNameStartsWithCapital\n * };\n * ```\n *\n * If an AST type does not extend AstNode, e.g. if it describes a union of string literals, that type's name must not occur as a key in objects of type `ValidationCheck<...>`.\n *\n * @param T a type definition mapping language specific type names (keys) to the corresponding types (values)\n */\nexport type ValidationChecks = {\n [K in keyof T]?: T[K] extends AstNode ? ValidationCheck | Array> : never\n} & {\n AstNode?: ValidationCheck | Array>;\n}\n\n/**\n * `fast` checks can be executed after every document change (i.e. as the user is typing). If a check\n * is too slow it can delay the response to document changes, yielding bad user experience. By marking\n * it as `slow`, it will be skipped for normal as-you-type validation. Then it's up to you when to\n * schedule these long-running checks: after the fast checks are done, or after saving a document,\n * or with an explicit command, etc.\n *\n * `built-in` checks are errors produced by the lexer, the parser, or the linker. They cannot be used\n * for custom validation checks.\n */\nexport type ValidationCategory = 'fast' | 'slow' | 'built-in'\n\nexport namespace ValidationCategory {\n export const all: readonly ValidationCategory[] = ['fast', 'slow', 'built-in'];\n}\n\ntype ValidationCheckEntry = {\n check: ValidationCheck\n category: ValidationCategory\n}\n\n/**\n * Manages a set of `ValidationCheck`s to be applied when documents are validated.\n */\nexport class ValidationRegistry {\n private readonly entries = new MultiMap();\n private readonly reflection: AstReflection;\n\n constructor(services: LangiumCoreServices) {\n this.reflection = services.shared.AstReflection;\n }\n\n /**\n * Register a set of validation checks. Each value in the record can be either a single validation check (i.e. a function)\n * or an array of validation checks.\n *\n * @param checksRecord Set of validation checks to register.\n * @param category Optional category for the validation checks (defaults to `'fast'`).\n * @param thisObj Optional object to be used as `this` when calling the validation check functions.\n */\n register(checksRecord: ValidationChecks, thisObj: ThisParameterType = this, category: ValidationCategory = 'fast'): void {\n if (category === 'built-in') {\n throw new Error(\"The 'built-in' category is reserved for lexer, parser, and linker errors.\");\n }\n for (const [type, ch] of Object.entries(checksRecord)) {\n const callbacks = ch as ValidationCheck | ValidationCheck[];\n if (Array.isArray(callbacks)) {\n for (const check of callbacks) {\n const entry: ValidationCheckEntry = {\n check: this.wrapValidationException(check, thisObj),\n category\n };\n this.addEntry(type, entry);\n }\n } else if (typeof callbacks === 'function') {\n const entry: ValidationCheckEntry = {\n check: this.wrapValidationException(callbacks, thisObj),\n category\n };\n this.addEntry(type, entry);\n }\n }\n }\n\n protected wrapValidationException(check: ValidationCheck, thisObj: unknown): ValidationCheck {\n return async (node, accept, cancelToken) => {\n try {\n await check.call(thisObj, node, accept, cancelToken);\n } catch (err) {\n if (isOperationCancelled(err)) {\n throw err;\n }\n console.error('An error occurred during validation:', err);\n const message = err instanceof Error ? err.message : String(err);\n if (err instanceof Error && err.stack) {\n console.error(err.stack);\n }\n accept('error', 'An error occurred during validation: ' + message, { node });\n }\n };\n }\n\n protected addEntry(type: string, entry: ValidationCheckEntry): void {\n if (type === 'AstNode') {\n this.entries.add('AstNode', entry);\n return;\n }\n for (const subtype of this.reflection.getAllSubTypes(type)) {\n this.entries.add(subtype, entry);\n }\n }\n\n getChecks(type: string, categories?: ValidationCategory[]): Stream {\n let checks = stream(this.entries.get(type))\n .concat(this.entries.get('AstNode'));\n if (categories) {\n checks = checks.filter(entry => categories.includes(entry.category));\n }\n return checks.map(entry => entry.check);\n }\n\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { MismatchedTokenException } from 'chevrotain';\nimport type { DiagnosticSeverity, Position, Range, Diagnostic } from 'vscode-languageserver-types';\nimport type { LanguageMetaData } from '../languages/language-meta-data.js';\nimport type { ParseResult } from '../parser/langium-parser.js';\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, CstNode } from '../syntax-tree.js';\nimport type { LangiumDocument } from '../workspace/documents.js';\nimport type { DiagnosticData, DiagnosticInfo, ValidationAcceptor, ValidationCategory, ValidationRegistry } from './validation-registry.js';\nimport { CancellationToken } from '../utils/cancellation.js';\nimport { findNodeForKeyword, findNodeForProperty } from '../utils/grammar-utils.js';\nimport { streamAst } from '../utils/ast-utils.js';\nimport { tokenToRange } from '../utils/cst-utils.js';\nimport { interruptAndCheck, isOperationCancelled } from '../utils/promise-utils.js';\nimport { diagnosticData } from './validation-registry.js';\n\nexport interface ValidationOptions {\n /**\n * If this is set, only the checks associated with these categories are executed; otherwise\n * all checks are executed. The default category if not specified to the registry is `'fast'`.\n */\n categories?: ValidationCategory[];\n /** If true, no further diagnostics are reported if there are lexing errors. */\n stopAfterLexingErrors?: boolean\n /** If true, no further diagnostics are reported if there are parsing errors. */\n stopAfterParsingErrors?: boolean\n /** If true, no further diagnostics are reported if there are linking errors. */\n stopAfterLinkingErrors?: boolean\n}\n\n/**\n * Language-specific service for validating `LangiumDocument`s.\n */\nexport interface DocumentValidator {\n /**\n * Validates the whole specified document.\n *\n * @param document specified document to validate\n * @param options options to control the validation process\n * @param cancelToken allows to cancel the current operation\n * @throws `OperationCanceled` if a user action occurs during execution\n */\n validateDocument(document: LangiumDocument, options?: ValidationOptions, cancelToken?: CancellationToken): Promise;\n}\n\nexport class DefaultDocumentValidator implements DocumentValidator {\n\n protected readonly validationRegistry: ValidationRegistry;\n protected readonly metadata: LanguageMetaData;\n\n constructor(services: LangiumCoreServices) {\n this.validationRegistry = services.validation.ValidationRegistry;\n this.metadata = services.LanguageMetaData;\n }\n\n async validateDocument(document: LangiumDocument, options: ValidationOptions = {}, cancelToken = CancellationToken.None): Promise {\n const parseResult = document.parseResult;\n const diagnostics: Diagnostic[] = [];\n\n await interruptAndCheck(cancelToken);\n\n if (!options.categories || options.categories.includes('built-in')) {\n this.processLexingErrors(parseResult, diagnostics, options);\n if (options.stopAfterLexingErrors && diagnostics.some(d => d.data?.code === DocumentValidator.LexingError)) {\n return diagnostics;\n }\n\n this.processParsingErrors(parseResult, diagnostics, options);\n if (options.stopAfterParsingErrors && diagnostics.some(d => d.data?.code === DocumentValidator.ParsingError)) {\n return diagnostics;\n }\n\n this.processLinkingErrors(document, diagnostics, options);\n if (options.stopAfterLinkingErrors && diagnostics.some(d => d.data?.code === DocumentValidator.LinkingError)) {\n return diagnostics;\n }\n }\n\n // Process custom validations\n try {\n diagnostics.push(...await this.validateAst(parseResult.value, options, cancelToken));\n } catch (err) {\n if (isOperationCancelled(err)) {\n throw err;\n }\n console.error('An error occurred during validation:', err);\n }\n\n await interruptAndCheck(cancelToken);\n\n return diagnostics;\n }\n\n protected processLexingErrors(parseResult: ParseResult, diagnostics: Diagnostic[], _options: ValidationOptions): void {\n for (const lexerError of parseResult.lexerErrors) {\n const diagnostic: Diagnostic = {\n severity: toDiagnosticSeverity('error'),\n range: {\n start: {\n line: lexerError.line! - 1,\n character: lexerError.column! - 1\n },\n end: {\n line: lexerError.line! - 1,\n character: lexerError.column! + lexerError.length - 1\n }\n },\n message: lexerError.message,\n data: diagnosticData(DocumentValidator.LexingError),\n source: this.getSource()\n };\n diagnostics.push(diagnostic);\n }\n }\n\n protected processParsingErrors(parseResult: ParseResult, diagnostics: Diagnostic[], _options: ValidationOptions): void {\n for (const parserError of parseResult.parserErrors) {\n let range: Range | undefined = undefined;\n // We can run into the chevrotain error recovery here\n // The token contained in the parser error might be automatically inserted\n // In this case every position value will be `NaN`\n if (isNaN(parserError.token.startOffset)) {\n // Some special parser error types contain a `previousToken`\n // We can simply append our diagnostic to that token\n if ('previousToken' in parserError) {\n const token = (parserError as MismatchedTokenException).previousToken;\n if (!isNaN(token.startOffset)) {\n const position: Position = { line: token.endLine! - 1, character: token.endColumn! };\n range = { start: position, end: position};\n } else {\n // No valid prev token. Might be empty document or containing only hidden tokens.\n // Point to document start\n const position: Position = { line: 0, character: 0 };\n range = { start: position, end: position};\n }\n }\n } else {\n range = tokenToRange(parserError.token);\n }\n if (range) {\n const diagnostic: Diagnostic = {\n severity: toDiagnosticSeverity('error'),\n range,\n message: parserError.message,\n data: diagnosticData(DocumentValidator.ParsingError),\n source: this.getSource()\n };\n diagnostics.push(diagnostic);\n }\n }\n }\n\n protected processLinkingErrors(document: LangiumDocument, diagnostics: Diagnostic[], _options: ValidationOptions): void {\n for (const reference of document.references) {\n const linkingError = reference.error;\n if (linkingError) {\n const info: DiagnosticInfo = {\n node: linkingError.container,\n property: linkingError.property,\n index: linkingError.index,\n data: {\n code: DocumentValidator.LinkingError,\n containerType: linkingError.container.$type,\n property: linkingError.property,\n refText: linkingError.reference.$refText\n } satisfies LinkingErrorData\n };\n diagnostics.push(this.toDiagnostic('error', linkingError.message, info));\n }\n }\n }\n\n protected async validateAst(rootNode: AstNode, options: ValidationOptions, cancelToken = CancellationToken.None): Promise {\n const validationItems: Diagnostic[] = [];\n const acceptor: ValidationAcceptor = (severity: 'error' | 'warning' | 'info' | 'hint', message: string, info: DiagnosticInfo) => {\n validationItems.push(this.toDiagnostic(severity, message, info));\n };\n\n await Promise.all(streamAst(rootNode).map(async node => {\n await interruptAndCheck(cancelToken);\n const checks = this.validationRegistry.getChecks(node.$type, options.categories);\n for (const check of checks) {\n await check(node, acceptor, cancelToken);\n }\n }));\n return validationItems;\n }\n\n protected toDiagnostic(severity: 'error' | 'warning' | 'info' | 'hint', message: string, info: DiagnosticInfo): Diagnostic {\n return {\n message,\n range: getDiagnosticRange(info),\n severity: toDiagnosticSeverity(severity),\n code: info.code,\n codeDescription: info.codeDescription,\n tags: info.tags,\n relatedInformation: info.relatedInformation,\n data: info.data,\n source: this.getSource()\n };\n }\n\n protected getSource(): string | undefined {\n return this.metadata.languageId;\n }\n}\n\nexport function getDiagnosticRange(info: DiagnosticInfo): Range {\n if (info.range) {\n return info.range;\n }\n let cstNode: CstNode | undefined;\n if (typeof info.property === 'string') {\n cstNode = findNodeForProperty(info.node.$cstNode, info.property, info.index);\n } else if (typeof info.keyword === 'string') {\n cstNode = findNodeForKeyword(info.node.$cstNode, info.keyword, info.index);\n }\n cstNode ??= info.node.$cstNode;\n if (!cstNode) {\n return {\n start: { line: 0, character: 0 },\n end: { line: 0, character: 0 }\n };\n }\n return cstNode.range;\n}\n\nexport function toDiagnosticSeverity(severity: 'error' | 'warning' | 'info' | 'hint'): DiagnosticSeverity {\n switch (severity) {\n case 'error':\n return 1; // according to vscode-languageserver-types/lib/esm/main.js#DiagnosticSeverity.Error\n case 'warning':\n return 2; // according to vscode-languageserver-types/lib/esm/main.js#DiagnosticSeverity.Warning\n case 'info':\n return 3; // according to vscode-languageserver-types/lib/esm/main.js#DiagnosticSeverity.Information\n case 'hint':\n return 4; // according to vscode-languageserver-types/lib/esm/main.js#DiagnosticSeverity.Hint\n default:\n throw new Error('Invalid diagnostic severity: ' + severity);\n }\n}\n\nexport namespace DocumentValidator {\n export const LexingError = 'lexing-error';\n export const ParsingError = 'parsing-error';\n export const LinkingError = 'linking-error';\n}\n\nexport interface LinkingErrorData extends DiagnosticData {\n containerType: string\n property: string\n refText: string\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { URI } from '../utils/uri-utils.js';\nimport type { NameProvider } from '../references/name-provider.js';\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, AstNodeDescription, ReferenceInfo } from '../syntax-tree.js';\nimport type { AstNodeLocator } from './ast-node-locator.js';\nimport type { DocumentSegment, LangiumDocument } from './documents.js';\nimport { CancellationToken } from '../utils/cancellation.js';\nimport { isLinkingError } from '../syntax-tree.js';\nimport { getDocument, streamAst, streamReferences } from '../utils/ast-utils.js';\nimport { toDocumentSegment } from '../utils/cst-utils.js';\nimport { interruptAndCheck } from '../utils/promise-utils.js';\nimport { UriUtils } from '../utils/uri-utils.js';\n\n/**\n * Language-specific service for creating descriptions of AST nodes to be used for cross-reference resolutions.\n */\nexport interface AstNodeDescriptionProvider {\n\n /**\n * Create a description for the given AST node. This service method is typically used while indexing\n * the contents of a document and during scope computation.\n *\n * @param node An AST node.\n * @param name The name to be used to refer to the AST node. By default, this is determined by the\n * `NameProvider` service, but alternative names may be provided according to the semantics\n * of your language.\n * @param document The document containing the AST node. If omitted, it is taken from the root AST node.\n */\n createDescription(node: AstNode, name: string | undefined, document?: LangiumDocument): AstNodeDescription;\n\n}\n\nexport class DefaultAstNodeDescriptionProvider implements AstNodeDescriptionProvider {\n\n protected readonly astNodeLocator: AstNodeLocator;\n protected readonly nameProvider: NameProvider;\n\n constructor(services: LangiumCoreServices) {\n this.astNodeLocator = services.workspace.AstNodeLocator;\n this.nameProvider = services.references.NameProvider;\n }\n\n createDescription(node: AstNode, name: string | undefined, document: LangiumDocument = getDocument(node)): AstNodeDescription {\n name ??= this.nameProvider.getName(node);\n const path = this.astNodeLocator.getAstNodePath(node);\n if (!name) {\n throw new Error(`Node at path ${path} has no name.`);\n }\n let nameNodeSegment: DocumentSegment | undefined;\n const nameSegmentGetter = () => nameNodeSegment ??= toDocumentSegment(this.nameProvider.getNameNode(node) ?? node.$cstNode);\n return {\n node,\n name,\n get nameSegment() {\n return nameSegmentGetter();\n },\n selectionSegment: toDocumentSegment(node.$cstNode),\n type: node.$type,\n documentUri: document.uri,\n path\n };\n }\n\n}\n\n/**\n * Describes a cross-reference within a document or between two documents.\n */\nexport interface ReferenceDescription {\n /** URI of the document that holds a reference */\n sourceUri: URI\n /** Path to AstNode that holds a reference */\n sourcePath: string\n /** Target document uri */\n targetUri: URI\n /** Path to the target AstNode inside the document */\n targetPath: string\n /** Segment of the reference text. */\n segment: DocumentSegment\n /** Marks a local reference i.e. a cross reference inside a document. */\n local?: boolean\n}\n\n/**\n * Language-specific service to create descriptions of all cross-references in a document. These are used by the `IndexManager`\n * to determine which documents are affected and should be rebuilt when a document is changed.\n */\nexport interface ReferenceDescriptionProvider {\n /**\n * Create descriptions of all cross-references found in the given document. These descriptions are\n * gathered by the `IndexManager` and stored in the global index so they can be considered when\n * a document change is reported by the client.\n *\n * @param document The document in which to gather cross-references.\n * @param cancelToken Indicates when to cancel the current operation.\n * @throws `OperationCanceled` if a user action occurs during execution\n */\n createDescriptions(document: LangiumDocument, cancelToken?: CancellationToken): Promise;\n}\n\nexport class DefaultReferenceDescriptionProvider implements ReferenceDescriptionProvider {\n\n protected readonly nodeLocator: AstNodeLocator;\n\n constructor(services: LangiumCoreServices) {\n this.nodeLocator = services.workspace.AstNodeLocator;\n }\n\n async createDescriptions(document: LangiumDocument, cancelToken = CancellationToken.None): Promise {\n const descr: ReferenceDescription[] = [];\n const rootNode = document.parseResult.value;\n for (const astNode of streamAst(rootNode)) {\n await interruptAndCheck(cancelToken);\n streamReferences(astNode).filter(refInfo => !isLinkingError(refInfo)).forEach(refInfo => {\n // TODO: Consider logging a warning or throw an exception when DocumentState is < than Linked\n const description = this.createDescription(refInfo);\n if (description) {\n descr.push(description);\n }\n });\n }\n return descr;\n }\n\n protected createDescription(refInfo: ReferenceInfo): ReferenceDescription | undefined {\n const targetNodeDescr = refInfo.reference.$nodeDescription;\n const refCstNode = refInfo.reference.$refNode;\n if (!targetNodeDescr || !refCstNode) {\n return undefined;\n }\n const docUri = getDocument(refInfo.container).uri;\n return {\n sourceUri: docUri,\n sourcePath: this.nodeLocator.getAstNodePath(refInfo.container),\n targetUri: targetNodeDescr.documentUri,\n targetPath: targetNodeDescr.path,\n segment: toDocumentSegment(refCstNode),\n local: UriUtils.equals(targetNodeDescr.documentUri, docUri)\n };\n }\n\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { AstNode } from '../syntax-tree.js';\n\n/**\n * Language-specific service for locating an `AstNode` in a document.\n */\nexport interface AstNodeLocator {\n\n /**\n * Creates a path represented by a `string` that identifies an `AstNode` inside its document.\n * It must be possible to retrieve exactly the same `AstNode` from the document using this path.\n *\n * @param node The `AstNode` for which to create the path.\n * @returns a path represented by a `string` that identifies `node` inside its document.\n * @see AstNodeLocator.getAstNode\n */\n getAstNodePath(node: AstNode): string;\n\n /**\n * Locates an `AstNode` inside another node by following the given path.\n *\n * @param node Parent element.\n * @param path Describes how to locate the `AstNode` inside the given `node`.\n * @returns The `AstNode` located under the given path, or `undefined` if the path cannot be resolved.\n * @see AstNodeLocator.getAstNodePath\n */\n getAstNode(node: AstNode, path: string): T | undefined;\n\n}\n\nexport class DefaultAstNodeLocator implements AstNodeLocator {\n protected segmentSeparator = '/';\n protected indexSeparator = '@';\n\n getAstNodePath(node: AstNode): string {\n if (node.$container) {\n const containerPath = this.getAstNodePath(node.$container);\n const newSegment = this.getPathSegment(node);\n const nodePath = containerPath + this.segmentSeparator + newSegment;\n return nodePath;\n }\n return '';\n }\n\n protected getPathSegment({ $containerProperty, $containerIndex }: AstNode): string {\n if (!$containerProperty) {\n throw new Error(\"Missing '$containerProperty' in AST node.\");\n }\n if ($containerIndex !== undefined) {\n return $containerProperty + this.indexSeparator + $containerIndex;\n }\n return $containerProperty;\n }\n\n getAstNode(node: AstNode, path: string): T | undefined {\n const segments = path.split(this.segmentSeparator);\n return segments.reduce((previousValue, currentValue) => {\n if (!previousValue || currentValue.length === 0) {\n return previousValue;\n }\n const propertyIndex = currentValue.indexOf(this.indexSeparator);\n if (propertyIndex > 0) {\n const property = currentValue.substring(0, propertyIndex);\n const arrayIndex = parseInt(currentValue.substring(propertyIndex + 1));\n const array = (previousValue as unknown as Record)[property];\n return array?.[arrayIndex];\n }\n return (previousValue as unknown as Record)[currentValue];\n }, node) as T;\n }\n\n}\n", "/******************************************************************************\n * Copyright 2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { ConfigurationItem, DidChangeConfigurationParams, DidChangeConfigurationRegistrationOptions, InitializeParams, InitializedParams } from 'vscode-languageserver-protocol';\nimport type { ServiceRegistry } from '../service-registry.js';\nimport type { LangiumSharedCoreServices } from '../services.js';\nimport { Deferred } from '../utils/promise-utils.js';\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nexport interface ConfigurationProvider {\n\n /**\n * A promise that resolves when the configuration provider is ready to be used.\n */\n readonly ready: Promise;\n\n /**\n * When used in a language server context, this method is called when the server receives\n * the `initialize` request.\n */\n initialize(params: InitializeParams): void;\n\n /**\n * When used in a language server context, this method is called when the server receives\n * the `initialized` notification.\n */\n initialized(params: ConfigurationInitializedParams): Promise;\n\n /**\n * Returns a configuration value stored for the given language.\n *\n * @param language The language id\n * @param configuration Configuration name\n */\n getConfiguration(language: string, configuration: string): Promise;\n\n /**\n * Updates the cached configurations using the `change` notification parameters.\n *\n * @param change The parameters of a change configuration notification.\n * `settings` property of the change object could be expressed as `Record>`\n */\n updateConfiguration(change: DidChangeConfigurationParams): void;\n}\n\nexport interface ConfigurationInitializedParams extends InitializedParams {\n register?: (params: DidChangeConfigurationRegistrationOptions) => void,\n fetchConfiguration?: (configuration: ConfigurationItem[]) => Promise\n}\n\n/**\n * Base configuration provider for building up other configuration providers\n */\nexport class DefaultConfigurationProvider implements ConfigurationProvider {\n\n protected readonly serviceRegistry: ServiceRegistry;\n protected readonly _ready = new Deferred();\n protected settings: Record> = {};\n protected workspaceConfig = false;\n\n constructor(services: LangiumSharedCoreServices) {\n this.serviceRegistry = services.ServiceRegistry;\n }\n\n get ready(): Promise {\n return this._ready.promise;\n }\n\n initialize(params: InitializeParams): void {\n this.workspaceConfig = params.capabilities.workspace?.configuration ?? false;\n }\n\n async initialized(params: ConfigurationInitializedParams): Promise {\n if (this.workspaceConfig) {\n if (params.register) {\n // params.register(...) is a function to be provided by the calling language server for the sake of\n // decoupling this implementation from the concrete LSP implementations, specifically the LSP Connection\n\n const languages = this.serviceRegistry.all;\n params.register({\n // Listen to configuration changes for all languages\n section: languages.map(lang => this.toSectionName(lang.LanguageMetaData.languageId))\n });\n }\n\n if (params.fetchConfiguration) {\n // params.fetchConfiguration(...) is a function to be provided by the calling language server for the sake of\n // decoupling this implementation from the concrete LSP implementations, specifically the LSP Connection\n const configToUpdate = this.serviceRegistry.all.map(lang => {\n // Fetch the configuration changes for all languages\n section: this.toSectionName(lang.LanguageMetaData.languageId)\n });\n\n // get workspace configurations (default scope URI)\n const configs = await params.fetchConfiguration(configToUpdate);\n configToUpdate.forEach((conf, idx) => {\n this.updateSectionConfiguration(conf.section!, configs[idx]);\n });\n }\n }\n this._ready.resolve();\n }\n\n /**\n * Updates the cached configurations using the `change` notification parameters.\n *\n * @param change The parameters of a change configuration notification.\n * `settings` property of the change object could be expressed as `Record>`\n */\n updateConfiguration(change: DidChangeConfigurationParams): void {\n if (!change.settings) {\n return;\n }\n Object.keys(change.settings).forEach(section => {\n this.updateSectionConfiguration(section, change.settings[section]);\n });\n }\n\n protected updateSectionConfiguration(section: string, configuration: any): void {\n this.settings[section] = configuration;\n }\n\n /**\n * Returns a configuration value stored for the given language.\n *\n * @param language The language id\n * @param configuration Configuration name\n */\n async getConfiguration(language: string, configuration: string): Promise {\n await this.ready;\n\n const sectionName = this.toSectionName(language);\n if (this.settings[sectionName]) {\n return this.settings[sectionName][configuration];\n }\n }\n\n protected toSectionName(languageId: string): string {\n return `${languageId}`;\n }\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport interface Disposable {\n /**\n * Dispose this object.\n */\n dispose(): void;\n}\n\nexport interface AsyncDisposable {\n /**\n * Dispose this object.\n */\n dispose(): Promise;\n}\n\nexport namespace Disposable {\n export function create(callback: () => Promise): AsyncDisposable;\n export function create(callback: () => void): Disposable;\n export function create(callback: () => void | Promise): Disposable | AsyncDisposable {\n return {\n dispose: async () => await callback()\n };\n }\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport { CancellationToken } from '../utils/cancellation.js';\nimport { Disposable } from '../utils/disposable.js';\nimport type { ServiceRegistry } from '../service-registry.js';\nimport type { LangiumSharedCoreServices } from '../services.js';\nimport type { AstNode } from '../syntax-tree.js';\nimport type { MaybePromise } from '../utils/promise-utils.js';\nimport type { Deferred } from '../utils/promise-utils.js';\nimport type { ValidationOptions } from '../validation/document-validator.js';\nimport type { IndexManager } from '../workspace/index-manager.js';\nimport type { LangiumDocument, LangiumDocuments, LangiumDocumentFactory } from './documents.js';\nimport { MultiMap } from '../utils/collections.js';\nimport { OperationCancelled, interruptAndCheck } from '../utils/promise-utils.js';\nimport { stream } from '../utils/stream.js';\nimport type { URI } from '../utils/uri-utils.js';\nimport { ValidationCategory } from '../validation/validation-registry.js';\nimport { DocumentState } from './documents.js';\n\nexport interface BuildOptions {\n /**\n * Control the validation phase with this option:\n * - `true` enables all validation checks and forces revalidating the documents\n * - `false` or `undefined` disables all validation checks\n * - An object runs only the necessary validation checks; the `categories` property restricts this to a specific subset\n */\n validation?: boolean | ValidationOptions\n}\n\nexport interface DocumentBuildState {\n /** Whether a document has completed its last build process. */\n completed: boolean\n /** The options used for the last build process. */\n options: BuildOptions\n /** Additional information about the last build result. */\n result?: {\n validationChecks?: ValidationCategory[]\n }\n}\n\n/**\n * Shared-service for building and updating `LangiumDocument`s.\n */\nexport interface DocumentBuilder {\n\n /** The options used for rebuilding documents after an update. */\n updateBuildOptions: BuildOptions;\n\n /**\n * Execute all necessary build steps for the given documents.\n *\n * @param documents Set of documents to be built.\n * @param options Options for the document builder.\n * @param cancelToken Indicates when to cancel the current operation.\n * @throws `OperationCanceled` if a user action occurs during execution\n */\n build(documents: Array>, options?: BuildOptions, cancelToken?: CancellationToken): Promise;\n\n /**\n * This method is called when a document change is detected. It updates the state of all\n * affected documents, including those with references to the changed ones, so they are rebuilt.\n *\n * @param changed URIs of changed or created documents\n * @param deleted URIs of deleted documents\n * @param cancelToken allows to cancel the current operation\n * @throws `OperationCancelled` if cancellation is detected during execution\n */\n update(changed: URI[], deleted: URI[], cancelToken?: CancellationToken): Promise;\n\n /**\n * Notify the given callback when a document update was triggered, but before any document\n * is rebuilt. Listeners to this event should not perform any long-running task.\n */\n onUpdate(callback: DocumentUpdateListener): Disposable;\n\n /**\n * Notify the given callback when a set of documents has been built reaching a desired target state.\n */\n onBuildPhase(targetState: DocumentState, callback: DocumentBuildListener): Disposable;\n\n /**\n * Wait until the workspace has reached the specified state for all documents.\n *\n * @param state The desired state. The promise won't resolve until all documents have reached this state\n * @param cancelToken Optionally allows to cancel the wait operation, disposing any listeners in the process\n * @throws `OperationCancelled` if cancellation has been requested before the state has been reached\n */\n waitUntil(state: DocumentState, cancelToken?: CancellationToken): Promise;\n\n /**\n * Wait until the document specified by the {@link uri} has reached the specified state.\n *\n * @param state The desired state. The promise won't resolve until the document has reached this state.\n * @param uri The specified URI that points to the document. If the URI does not exist, the promise will resolve once the workspace has reached the specified state.\n * @param cancelToken Optionally allows to cancel the wait operation, disposing any listeners in the process.\n * @return The URI of the document that has reached the desired state, or `undefined` if the document does not exist.\n * @throws `OperationCancelled` if cancellation has been requested before the state has been reached\n */\n waitUntil(state: DocumentState, uri?: URI, cancelToken?: CancellationToken): Promise;\n}\n\nexport type DocumentUpdateListener = (changed: URI[], deleted: URI[]) => void | Promise\nexport type DocumentBuildListener = (built: LangiumDocument[], cancelToken: CancellationToken) => void | Promise\nexport class DefaultDocumentBuilder implements DocumentBuilder {\n\n updateBuildOptions: BuildOptions = {\n // Default: run only the built-in validation checks and those in the _fast_ category (includes those without category)\n validation: {\n categories: ['built-in', 'fast']\n }\n };\n\n protected readonly langiumDocuments: LangiumDocuments;\n protected readonly langiumDocumentFactory: LangiumDocumentFactory;\n protected readonly indexManager: IndexManager;\n protected readonly serviceRegistry: ServiceRegistry;\n protected readonly updateListeners: DocumentUpdateListener[] = [];\n protected readonly buildPhaseListeners = new MultiMap();\n protected readonly buildState = new Map();\n protected readonly documentBuildWaiters = new Map>();\n protected currentState = DocumentState.Changed;\n\n constructor(services: LangiumSharedCoreServices) {\n this.langiumDocuments = services.workspace.LangiumDocuments;\n this.langiumDocumentFactory = services.workspace.LangiumDocumentFactory;\n this.indexManager = services.workspace.IndexManager;\n this.serviceRegistry = services.ServiceRegistry;\n }\n\n async build(documents: Array>, options: BuildOptions = {}, cancelToken = CancellationToken.None): Promise {\n for (const document of documents) {\n const key = document.uri.toString();\n if (document.state === DocumentState.Validated) {\n if (typeof options.validation === 'boolean' && options.validation) {\n // Force re-running all validation checks\n document.state = DocumentState.IndexedReferences;\n document.diagnostics = undefined;\n this.buildState.delete(key);\n } else if (typeof options.validation === 'object') {\n const buildState = this.buildState.get(key);\n const previousCategories = buildState?.result?.validationChecks;\n if (previousCategories) {\n // Validation with explicit options was requested for a document that has already been partly validated.\n // In this case, we need to merge the previous validation categories with the new ones.\n const newCategories = options.validation.categories ?? ValidationCategory.all as ValidationCategory[];\n const categories = newCategories.filter(c => !previousCategories.includes(c));\n if (categories.length > 0) {\n this.buildState.set(key, {\n completed: false,\n options: {\n validation: {\n ...options.validation,\n categories\n }\n },\n result: buildState.result\n });\n document.state = DocumentState.IndexedReferences;\n }\n }\n }\n } else {\n // Default: forget any previous build options\n this.buildState.delete(key);\n }\n }\n this.currentState = DocumentState.Changed;\n await this.emitUpdate(documents.map(e => e.uri), []);\n await this.buildDocuments(documents, options, cancelToken);\n }\n\n async update(changed: URI[], deleted: URI[], cancelToken = CancellationToken.None): Promise {\n this.currentState = DocumentState.Changed;\n // Remove all metadata of documents that are reported as deleted\n for (const deletedUri of deleted) {\n this.langiumDocuments.deleteDocument(deletedUri);\n this.buildState.delete(deletedUri.toString());\n this.indexManager.remove(deletedUri);\n }\n // Set the state of all changed documents to `Changed` so they are completely rebuilt\n for (const changedUri of changed) {\n const invalidated = this.langiumDocuments.invalidateDocument(changedUri);\n if (!invalidated) {\n // We create an unparsed, invalid document.\n // This will be parsed as soon as we reach the first document builder phase.\n // This allows to cancel the parsing process later in case we need it.\n const newDocument = this.langiumDocumentFactory.fromModel({ $type: 'INVALID' }, changedUri);\n newDocument.state = DocumentState.Changed;\n this.langiumDocuments.addDocument(newDocument);\n }\n this.buildState.delete(changedUri.toString());\n }\n // Set the state of all documents that should be relinked to `ComputedScopes` (if not already lower)\n const allChangedUris = stream(changed).concat(deleted).map(uri => uri.toString()).toSet();\n this.langiumDocuments.all\n .filter(doc => !allChangedUris.has(doc.uri.toString()) && this.shouldRelink(doc, allChangedUris))\n .forEach(doc => {\n const linker = this.serviceRegistry.getServices(doc.uri).references.Linker;\n linker.unlink(doc);\n doc.state = Math.min(doc.state, DocumentState.ComputedScopes);\n doc.diagnostics = undefined;\n });\n // Notify listeners of the update\n await this.emitUpdate(changed, deleted);\n // Only allow interrupting the execution after all state changes are done\n await interruptAndCheck(cancelToken);\n\n // Collect all documents that we should rebuild\n const rebuildDocuments = this.langiumDocuments.all\n .filter(doc =>\n // This includes those that were reported as changed and those that we selected for relinking\n doc.state < DocumentState.Linked\n // This includes those for which a previous build has been cancelled\n || !this.buildState.get(doc.uri.toString())?.completed\n )\n .toArray();\n await this.buildDocuments(rebuildDocuments, this.updateBuildOptions, cancelToken);\n }\n\n protected async emitUpdate(changed: URI[], deleted: URI[]): Promise {\n await Promise.all(this.updateListeners.map(listener => listener(changed, deleted)));\n }\n\n /**\n * Check whether the given document should be relinked after changes were found in the given URIs.\n */\n protected shouldRelink(document: LangiumDocument, changedUris: Set): boolean {\n // Relink documents with linking errors -- maybe those references can be resolved now\n if (document.references.some(ref => ref.error !== undefined)) {\n return true;\n }\n // Check whether the document is affected by any of the changed URIs\n return this.indexManager.isAffected(document, changedUris);\n }\n\n onUpdate(callback: DocumentUpdateListener): Disposable {\n this.updateListeners.push(callback);\n return Disposable.create(() => {\n const index = this.updateListeners.indexOf(callback);\n if (index >= 0) {\n this.updateListeners.splice(index, 1);\n }\n });\n }\n\n /**\n * Build the given documents by stepping through all build phases. If a document's state indicates\n * that a certain build phase is already done, the phase is skipped for that document.\n */\n protected async buildDocuments(documents: LangiumDocument[], options: BuildOptions, cancelToken: CancellationToken): Promise {\n this.prepareBuild(documents, options);\n // 0. Parse content\n await this.runCancelable(documents, DocumentState.Parsed, cancelToken, doc =>\n this.langiumDocumentFactory.update(doc, cancelToken)\n );\n // 1. Index content\n await this.runCancelable(documents, DocumentState.IndexedContent, cancelToken, doc =>\n this.indexManager.updateContent(doc, cancelToken)\n );\n // 2. Compute scopes\n await this.runCancelable(documents, DocumentState.ComputedScopes, cancelToken, async doc => {\n const scopeComputation = this.serviceRegistry.getServices(doc.uri).references.ScopeComputation;\n doc.precomputedScopes = await scopeComputation.computeLocalScopes(doc, cancelToken);\n });\n // 3. Linking\n await this.runCancelable(documents, DocumentState.Linked, cancelToken, doc => {\n const linker = this.serviceRegistry.getServices(doc.uri).references.Linker;\n return linker.link(doc, cancelToken);\n });\n // 4. Index references\n await this.runCancelable(documents, DocumentState.IndexedReferences, cancelToken, doc =>\n this.indexManager.updateReferences(doc, cancelToken)\n );\n // 5. Validation\n const toBeValidated = documents.filter(doc => this.shouldValidate(doc));\n await this.runCancelable(toBeValidated, DocumentState.Validated, cancelToken, doc =>\n this.validate(doc, cancelToken)\n );\n\n // If we've made it to this point without being cancelled, we can mark the build state as completed.\n for (const doc of documents) {\n const state = this.buildState.get(doc.uri.toString());\n if (state) {\n state.completed = true;\n }\n }\n }\n\n protected prepareBuild(documents: LangiumDocument[], options: BuildOptions): void {\n for (const doc of documents) {\n const key = doc.uri.toString();\n const state = this.buildState.get(key);\n // If the document has no previous build state, we set it. If it has one, but it's already marked\n // as completed, we overwrite it. If the previous build was not completed, we keep its state\n // and continue where it was cancelled.\n if (!state || state.completed) {\n this.buildState.set(key, {\n completed: false,\n options,\n result: state?.result\n });\n }\n }\n }\n\n protected async runCancelable(documents: LangiumDocument[], targetState: DocumentState, cancelToken: CancellationToken,\n callback: (document: LangiumDocument) => MaybePromise): Promise {\n const filtered = documents.filter(e => e.state < targetState);\n for (const document of filtered) {\n await interruptAndCheck(cancelToken);\n await callback(document);\n document.state = targetState;\n }\n await this.notifyBuildPhase(filtered, targetState, cancelToken);\n this.currentState = targetState;\n }\n\n onBuildPhase(targetState: DocumentState, callback: DocumentBuildListener): Disposable {\n this.buildPhaseListeners.add(targetState, callback);\n return Disposable.create(() => {\n this.buildPhaseListeners.delete(targetState, callback);\n });\n }\n\n waitUntil(state: DocumentState, cancelToken?: CancellationToken): Promise;\n waitUntil(state: DocumentState, uri?: URI, cancelToken?: CancellationToken): Promise;\n waitUntil(state: DocumentState, uriOrToken?: URI | CancellationToken, cancelToken?: CancellationToken): Promise {\n let uri: URI | undefined = undefined;\n if (uriOrToken && 'path' in uriOrToken) {\n uri = uriOrToken;\n } else {\n cancelToken = uriOrToken;\n }\n cancelToken ??= CancellationToken.None;\n if (uri) {\n const document = this.langiumDocuments.getDocument(uri);\n if (document && document.state > state) {\n return Promise.resolve(uri);\n }\n }\n if (this.currentState >= state) {\n return Promise.resolve(undefined);\n } else if (cancelToken.isCancellationRequested) {\n return Promise.reject(OperationCancelled);\n }\n return new Promise((resolve, reject) => {\n const buildDisposable = this.onBuildPhase(state, () => {\n buildDisposable.dispose();\n cancelDisposable.dispose();\n if (uri) {\n const document = this.langiumDocuments.getDocument(uri);\n resolve(document?.uri);\n } else {\n resolve(undefined);\n }\n });\n const cancelDisposable = cancelToken!.onCancellationRequested(() => {\n buildDisposable.dispose();\n cancelDisposable.dispose();\n reject(OperationCancelled);\n });\n });\n }\n\n protected async notifyBuildPhase(documents: LangiumDocument[], state: DocumentState, cancelToken: CancellationToken): Promise {\n if (documents.length === 0) {\n // Don't notify when no document has been processed\n return;\n }\n const listeners = this.buildPhaseListeners.get(state);\n for (const listener of listeners) {\n await interruptAndCheck(cancelToken);\n await listener(documents, cancelToken);\n }\n }\n\n /**\n * Determine whether the given document should be validated during a build. The default\n * implementation checks the `validation` property of the build options. If it's set to `true`\n * or a `ValidationOptions` object, the document is included in the validation phase.\n */\n protected shouldValidate(document: LangiumDocument): boolean {\n return Boolean(this.getBuildOptions(document).validation);\n }\n\n /**\n * Run validation checks on the given document and store the resulting diagnostics in the document.\n * If the document already contains diagnostics, the new ones are added to the list.\n */\n protected async validate(document: LangiumDocument, cancelToken: CancellationToken): Promise {\n const validator = this.serviceRegistry.getServices(document.uri).validation.DocumentValidator;\n const validationSetting = this.getBuildOptions(document).validation;\n const options = typeof validationSetting === 'object' ? validationSetting : undefined;\n const diagnostics = await validator.validateDocument(document, options, cancelToken);\n if (document.diagnostics) {\n document.diagnostics.push(...diagnostics);\n } else {\n document.diagnostics = diagnostics;\n }\n\n // Store information about the executed validation in the build state\n const state = this.buildState.get(document.uri.toString());\n if (state) {\n state.result ??= {};\n const newCategories = options?.categories ?? ValidationCategory.all;\n if (state.result.validationChecks) {\n state.result.validationChecks.push(...newCategories);\n } else {\n state.result.validationChecks = [...newCategories];\n }\n }\n }\n\n protected getBuildOptions(document: LangiumDocument): BuildOptions {\n return this.buildState.get(document.uri.toString())?.options ?? {};\n }\n\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { ServiceRegistry } from '../service-registry.js';\nimport type { LangiumSharedCoreServices } from '../services.js';\nimport type { AstNode, AstNodeDescription, AstReflection } from '../syntax-tree.js';\nimport { getDocument } from '../utils/ast-utils.js';\nimport { ContextCache } from '../utils/caching.js';\nimport { CancellationToken } from '../utils/cancellation.js';\nimport type { Stream } from '../utils/stream.js';\nimport { stream } from '../utils/stream.js';\nimport type { URI } from '../utils/uri-utils.js';\nimport { UriUtils } from '../utils/uri-utils.js';\nimport type { ReferenceDescription } from './ast-descriptions.js';\nimport type { LangiumDocument, LangiumDocuments } from './documents.js';\n\n/**\n * The index manager is responsible for keeping metadata about symbols and cross-references\n * in the workspace. It is used to look up symbols in the global scope, mostly during linking\n * and completion. This service is shared between all languages of a language server.\n */\nexport interface IndexManager {\n\n /**\n * Removes the specified document URI from the index.\n * Necessary when documents are deleted and not referenceable anymore.\n *\n * @param uri The URI of the document for which index data shall be removed\n */\n remove(uri: URI): void;\n\n /**\n * Updates the information about the exportable content of a document inside the index.\n *\n * @param document Document to be updated\n * @param cancelToken Indicates when to cancel the current operation.\n * @throws `OperationCanceled` if a user action occurs during execution\n */\n updateContent(document: LangiumDocument, cancelToken?: CancellationToken): Promise;\n\n /**\n * Updates the information about the cross-references of a document inside the index.\n *\n * @param document Document to be updated\n * @param cancelToken Indicates when to cancel the current operation.\n * @throws `OperationCanceled` if a user action occurs during execution\n */\n updateReferences(document: LangiumDocument, cancelToken?: CancellationToken): Promise;\n\n /**\n * Determine whether the given document could be affected by changes of the documents\n * identified by the given URIs (second parameter). The document is typically regarded as\n * affected if it contains a reference to any of the changed files.\n *\n * @param document Document to check whether it's affected\n * @param changedUris URIs of the changed documents\n */\n isAffected(document: LangiumDocument, changedUris: Set): boolean;\n\n /**\n * Compute a list of all exported elements, optionally filtered using a type identifier and document URIs.\n *\n * @param nodeType The type to filter with, or `undefined` to return descriptions of all types.\n * @param uris If specified, only returns elements from the given URIs.\n * @returns a `Stream` containing all globally visible nodes (of a given type).\n */\n allElements(nodeType?: string, uris?: Set): Stream;\n\n /**\n * Returns all known references that are pointing to the given `targetNode`.\n *\n * @param targetNode the `AstNode` to look up references for\n * @param astNodePath the path that points to the `targetNode` inside the document. See also `AstNodeLocator`\n *\n * @returns a `Stream` of references that are targeting the `targetNode`\n */\n findAllReferences(targetNode: AstNode, astNodePath: string): Stream;\n\n}\n\nexport class DefaultIndexManager implements IndexManager {\n\n protected readonly serviceRegistry: ServiceRegistry;\n protected readonly documents: LangiumDocuments;\n protected readonly astReflection: AstReflection;\n\n /**\n * The symbol index stores all `AstNodeDescription` items exported by a document.\n * The key used in this map is the string representation of the specific document URI.\n */\n protected readonly symbolIndex = new Map();\n /**\n * This is a cache for the `allElements()` method.\n * It caches the descriptions from `symbolIndex` grouped by types.\n */\n protected readonly symbolByTypeIndex = new ContextCache();\n /**\n * This index keeps track of all `ReferenceDescription` items exported by a document.\n * This is used to compute which elements are affected by a document change\n * and for finding references to an AST node.\n */\n protected readonly referenceIndex = new Map();\n\n constructor(services: LangiumSharedCoreServices) {\n this.documents = services.workspace.LangiumDocuments;\n this.serviceRegistry = services.ServiceRegistry;\n this.astReflection = services.AstReflection;\n }\n\n findAllReferences(targetNode: AstNode, astNodePath: string): Stream {\n const targetDocUri = getDocument(targetNode).uri;\n const result: ReferenceDescription[] = [];\n this.referenceIndex.forEach(docRefs => {\n docRefs.forEach(refDescr => {\n if (UriUtils.equals(refDescr.targetUri, targetDocUri) && refDescr.targetPath === astNodePath) {\n result.push(refDescr);\n }\n });\n });\n return stream(result);\n }\n\n allElements(nodeType?: string, uris?: Set): Stream {\n let documentUris = stream(this.symbolIndex.keys());\n if (uris) {\n documentUris = documentUris.filter(uri => !uris || uris.has(uri));\n }\n return documentUris\n .map(uri => this.getFileDescriptions(uri, nodeType))\n .flat();\n }\n\n protected getFileDescriptions(uri: string, nodeType?: string): AstNodeDescription[] {\n if (!nodeType) {\n return this.symbolIndex.get(uri) ?? [];\n }\n const descriptions = this.symbolByTypeIndex.get(uri, nodeType, () => {\n const allFileDescriptions = this.symbolIndex.get(uri) ?? [];\n return allFileDescriptions.filter(e => this.astReflection.isSubtype(e.type, nodeType));\n });\n return descriptions;\n }\n\n remove(uri: URI): void {\n const uriString = uri.toString();\n this.symbolIndex.delete(uriString);\n this.symbolByTypeIndex.clear(uriString);\n this.referenceIndex.delete(uriString);\n }\n\n async updateContent(document: LangiumDocument, cancelToken = CancellationToken.None): Promise {\n const services = this.serviceRegistry.getServices(document.uri);\n const exports = await services.references.ScopeComputation.computeExports(document, cancelToken);\n const uri = document.uri.toString();\n this.symbolIndex.set(uri, exports);\n this.symbolByTypeIndex.clear(uri);\n }\n\n async updateReferences(document: LangiumDocument, cancelToken = CancellationToken.None): Promise {\n const services = this.serviceRegistry.getServices(document.uri);\n const indexData = await services.workspace.ReferenceDescriptionProvider.createDescriptions(document, cancelToken);\n this.referenceIndex.set(document.uri.toString(), indexData);\n }\n\n isAffected(document: LangiumDocument, changedUris: Set): boolean {\n const references = this.referenceIndex.get(document.uri.toString());\n if (!references) {\n return false;\n }\n return references.some(ref => !ref.local && changedUris.has(ref.targetUri.toString()));\n }\n\n}\n", "/******************************************************************************\n * Copyright 2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { InitializeParams, InitializedParams } from 'vscode-languageserver-protocol';\nimport type { WorkspaceFolder } from 'vscode-languageserver-types';\nimport type { ServiceRegistry } from '../service-registry.js';\nimport type { LangiumSharedCoreServices } from '../services.js';\nimport { CancellationToken } from '../utils/cancellation.js';\nimport { Deferred, interruptAndCheck } from '../utils/promise-utils.js';\nimport { URI, UriUtils } from '../utils/uri-utils.js';\nimport type { BuildOptions, DocumentBuilder } from './document-builder.js';\nimport type { LangiumDocument, LangiumDocuments } from './documents.js';\nimport type { FileSystemNode, FileSystemProvider } from './file-system-provider.js';\nimport type { WorkspaceLock } from './workspace-lock.js';\n\n// export type WorkspaceFolder from 'vscode-languageserver-types' for convenience,\n// is supposed to avoid confusion as 'WorkspaceFolder' might accidentally be imported via 'vscode-languageclient'\nexport type { WorkspaceFolder };\n\n/**\n * The workspace manager is responsible for finding source files in the workspace.\n * This service is shared between all languages of a language server.\n */\nexport interface WorkspaceManager {\n\n /** The options used for the initial workspace build. */\n initialBuildOptions: BuildOptions | undefined;\n\n /**\n * A promise that resolves when the workspace manager is ready to be used.\n * Use this to ensure that the workspace manager has finished its initialization.\n */\n readonly ready: Promise;\n\n /**\n * When used in a language server context, this method is called when the server receives\n * the `initialize` request.\n */\n initialize(params: InitializeParams): void;\n\n /**\n * When used in a language server context, this method is called when the server receives\n * the `initialized` notification.\n */\n initialized(params: InitializedParams): Promise;\n\n /**\n * Does the initial indexing of workspace folders.\n * Collects information about exported and referenced AstNodes in\n * each language file and stores it locally.\n *\n * @param folders The set of workspace folders to be indexed.\n */\n initializeWorkspace(folders: WorkspaceFolder[], cancelToken?: CancellationToken): Promise;\n\n}\n\nexport class DefaultWorkspaceManager implements WorkspaceManager {\n\n initialBuildOptions: BuildOptions = {};\n\n protected readonly serviceRegistry: ServiceRegistry;\n protected readonly langiumDocuments: LangiumDocuments;\n protected readonly documentBuilder: DocumentBuilder;\n protected readonly fileSystemProvider: FileSystemProvider;\n protected readonly mutex: WorkspaceLock;\n protected readonly _ready = new Deferred();\n protected folders?: WorkspaceFolder[];\n\n constructor(services: LangiumSharedCoreServices) {\n this.serviceRegistry = services.ServiceRegistry;\n this.langiumDocuments = services.workspace.LangiumDocuments;\n this.documentBuilder = services.workspace.DocumentBuilder;\n this.fileSystemProvider = services.workspace.FileSystemProvider;\n this.mutex = services.workspace.WorkspaceLock;\n }\n\n get ready(): Promise {\n return this._ready.promise;\n }\n\n initialize(params: InitializeParams): void {\n this.folders = params.workspaceFolders ?? undefined;\n }\n\n initialized(_params: InitializedParams): Promise {\n // Initialize the workspace even if there are no workspace folders\n // We still want to load additional documents (language library or similar) during initialization\n return this.mutex.write(token => this.initializeWorkspace(this.folders ?? [], token));\n }\n\n async initializeWorkspace(folders: WorkspaceFolder[], cancelToken = CancellationToken.None): Promise {\n const documents = await this.performStartup(folders);\n // Only after creating all documents do we check whether we need to cancel the initialization\n // The document builder will later pick up on all unprocessed documents\n await interruptAndCheck(cancelToken);\n await this.documentBuilder.build(documents, this.initialBuildOptions, cancelToken);\n }\n\n /**\n * Performs the uninterruptable startup sequence of the workspace manager.\n * This methods loads all documents in the workspace and other documents and returns them.\n */\n protected async performStartup(folders: WorkspaceFolder[]): Promise {\n const fileExtensions = this.serviceRegistry.all.flatMap(e => e.LanguageMetaData.fileExtensions);\n const documents: LangiumDocument[] = [];\n const collector = (document: LangiumDocument) => {\n documents.push(document);\n if (!this.langiumDocuments.hasDocument(document.uri)) {\n this.langiumDocuments.addDocument(document);\n }\n };\n // Even though we don't await the initialization of the workspace manager,\n // we can still assume that all library documents and file documents are loaded by the time we start building documents.\n // The mutex prevents anything from performing a workspace build until we check the cancellation token\n await this.loadAdditionalDocuments(folders, collector);\n await Promise.all(\n folders.map(wf => [wf, this.getRootFolder(wf)] as [WorkspaceFolder, URI])\n .map(async entry => this.traverseFolder(...entry, fileExtensions, collector))\n );\n this._ready.resolve();\n return documents;\n }\n\n /**\n * Load all additional documents that shall be visible in the context of the given workspace\n * folders and add them to the collector. This can be used to include built-in libraries of\n * your language, which can be either loaded from provided files or constructed in memory.\n */\n protected loadAdditionalDocuments(_folders: WorkspaceFolder[], _collector: (document: LangiumDocument) => void): Promise {\n return Promise.resolve();\n }\n\n /**\n * Determine the root folder of the source documents in the given workspace folder.\n * The default implementation returns the URI of the workspace folder, but you can override\n * this to return a subfolder like `src` instead.\n */\n protected getRootFolder(workspaceFolder: WorkspaceFolder): URI {\n return URI.parse(workspaceFolder.uri);\n }\n\n /**\n * Traverse the file system folder identified by the given URI and its subfolders. All\n * contained files that match the file extensions are added to the collector.\n */\n protected async traverseFolder(workspaceFolder: WorkspaceFolder, folderPath: URI, fileExtensions: string[], collector: (document: LangiumDocument) => void): Promise {\n const content = await this.fileSystemProvider.readDirectory(folderPath);\n await Promise.all(content.map(async entry => {\n if (this.includeEntry(workspaceFolder, entry, fileExtensions)) {\n if (entry.isDirectory) {\n await this.traverseFolder(workspaceFolder, entry.uri, fileExtensions, collector);\n } else if (entry.isFile) {\n const document = await this.langiumDocuments.getOrCreateDocument(entry.uri);\n collector(document);\n }\n }\n }));\n }\n\n /**\n * Determine whether the given folder entry shall be included while indexing the workspace.\n */\n protected includeEntry(_workspaceFolder: WorkspaceFolder, entry: FileSystemNode, fileExtensions: string[]): boolean {\n const name = UriUtils.basename(entry.uri);\n if (name.startsWith('.')) {\n return false;\n }\n if (entry.isDirectory) {\n return name !== 'node_modules' && name !== 'out';\n } else if (entry.isFile) {\n const extname = UriUtils.extname(entry.uri);\n return fileExtensions.includes(extname);\n }\n return false;\n }\n\n}\n", "/******************************************************************************\n * Copyright 2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { ILexingError, IMultiModeLexerDefinition, IToken, TokenType, TokenTypeDictionary, TokenVocabulary } from 'chevrotain';\nimport type { LangiumCoreServices } from '../services.js';\nimport { Lexer as ChevrotainLexer } from 'chevrotain';\n\nexport interface LexerResult {\n /**\n * A list of all tokens that were lexed from the input.\n *\n * Note that Langium requires the optional properties\n * `startLine`, `startColumn`, `endOffset`, `endLine` and `endColumn` to be set on each token.\n */\n tokens: IToken[];\n /**\n * Contains hidden tokens, usually comments.\n */\n hidden: IToken[];\n errors: ILexingError[];\n}\n\nexport interface Lexer {\n readonly definition: TokenTypeDictionary;\n tokenize(text: string): LexerResult;\n}\n\nexport class DefaultLexer implements Lexer {\n\n protected chevrotainLexer: ChevrotainLexer;\n protected tokenTypes: TokenTypeDictionary;\n\n constructor(services: LangiumCoreServices) {\n const tokens = services.parser.TokenBuilder.buildTokens(services.Grammar, {\n caseInsensitive: services.LanguageMetaData.caseInsensitive\n });\n this.tokenTypes = this.toTokenTypeDictionary(tokens);\n const lexerTokens = isTokenTypeDictionary(tokens) ? Object.values(tokens) : tokens;\n this.chevrotainLexer = new ChevrotainLexer(lexerTokens, {\n positionTracking: 'full'\n });\n }\n\n get definition(): TokenTypeDictionary {\n return this.tokenTypes;\n }\n\n tokenize(text: string): LexerResult {\n const chevrotainResult = this.chevrotainLexer.tokenize(text);\n return {\n tokens: chevrotainResult.tokens,\n errors: chevrotainResult.errors,\n hidden: chevrotainResult.groups.hidden ?? []\n };\n }\n\n protected toTokenTypeDictionary(buildTokens: TokenVocabulary): TokenTypeDictionary {\n if (isTokenTypeDictionary(buildTokens)) return buildTokens;\n const tokens = isIMultiModeLexerDefinition(buildTokens) ? Object.values(buildTokens.modes).flat() : buildTokens;\n const res: TokenTypeDictionary = {};\n tokens.forEach(token => res[token.name] = token);\n return res;\n }\n}\n\n/**\n * Returns a check whether the given TokenVocabulary is TokenType array\n */\nexport function isTokenTypeArray(tokenVocabulary: TokenVocabulary): tokenVocabulary is TokenType[] {\n return Array.isArray(tokenVocabulary) && (tokenVocabulary.length === 0 || 'name' in tokenVocabulary[0]);\n}\n\n/**\n * Returns a check whether the given TokenVocabulary is IMultiModeLexerDefinition\n */\nexport function isIMultiModeLexerDefinition(tokenVocabulary: TokenVocabulary): tokenVocabulary is IMultiModeLexerDefinition {\n return tokenVocabulary && 'modes' in tokenVocabulary && 'defaultMode' in tokenVocabulary;\n}\n\n/**\n * Returns a check whether the given TokenVocabulary is TokenTypeDictionary\n */\nexport function isTokenTypeDictionary(tokenVocabulary: TokenVocabulary): tokenVocabulary is TokenTypeDictionary {\n return !isTokenTypeArray(tokenVocabulary) && !isIMultiModeLexerDefinition(tokenVocabulary);\n}\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport { Position, Range } from 'vscode-languageserver-types';\nimport type { CstNode } from '../syntax-tree.js';\nimport { NEWLINE_REGEXP, escapeRegExp } from '../utils/regexp-utils.js';\nimport { URI } from '../utils/uri-utils.js';\n\nexport interface JSDocComment extends JSDocValue {\n readonly elements: JSDocElement[]\n getTag(name: string): JSDocTag | undefined\n getTags(name: string): JSDocTag[]\n}\n\nexport type JSDocElement = JSDocParagraph | JSDocTag;\n\nexport type JSDocInline = JSDocTag | JSDocLine;\n\nexport interface JSDocValue {\n /**\n * Represents the range that this JSDoc element occupies.\n * If the JSDoc was parsed from a `CstNode`, the range will represent the location in the source document.\n */\n readonly range: Range\n /**\n * Renders this JSDoc element to a plain text representation.\n */\n toString(): string\n /**\n * Renders this JSDoc element to a markdown representation.\n *\n * @param options Rendering options to customize the markdown result.\n */\n toMarkdown(options?: JSDocRenderOptions): string\n}\n\nexport interface JSDocParagraph extends JSDocValue {\n readonly inlines: JSDocInline[]\n}\n\nexport interface JSDocLine extends JSDocValue {\n readonly text: string\n}\n\nexport interface JSDocTag extends JSDocValue {\n readonly name: string\n readonly content: JSDocParagraph\n readonly inline: boolean\n}\n\nexport interface JSDocParseOptions {\n /**\n * The start symbol of your comment format. Defaults to `/**`.\n */\n readonly start?: RegExp | string\n /**\n * The symbol that start a line of your comment format. Defaults to `*`.\n */\n readonly line?: RegExp | string\n /**\n * The end symbol of your comment format. Defaults to `*\\/`.\n */\n readonly end?: RegExp | string\n}\n\nexport interface JSDocRenderOptions {\n /**\n * Determines the style for rendering tags. Defaults to `italic`.\n */\n tag?: 'plain' | 'italic' | 'bold' | 'bold-italic'\n /**\n * Determines the default for rendering `@link` tags. Defaults to `plain`.\n */\n link?: 'code' | 'plain'\n /**\n * Custom tag rendering function.\n * Return a markdown formatted tag or `undefined` to fall back to the default rendering.\n */\n renderTag?(tag: JSDocTag): string | undefined\n /**\n * Custom link rendering function. Accepts a link target and a display value for the link.\n * Return a markdown formatted link with the format `[$display]($link)` or `undefined` if the link is not a valid target.\n */\n renderLink?(link: string, display: string): string | undefined\n}\n\n/**\n * Parses a JSDoc from a `CstNode` containing a comment.\n *\n * @param node A `CstNode` from a parsed Langium document.\n * @param options Parsing options specialized to your language. See {@link JSDocParseOptions}.\n */\nexport function parseJSDoc(node: CstNode, options?: JSDocParseOptions): JSDocComment;\n/**\n * Parses a JSDoc from a string comment.\n *\n * @param content A string containing the source of the JSDoc comment.\n * @param start The start position the comment occupies in the source document.\n * @param options Parsing options specialized to your language. See {@link JSDocParseOptions}.\n */\nexport function parseJSDoc(content: string, start?: Position, options?: JSDocParseOptions): JSDocComment;\nexport function parseJSDoc(node: CstNode | string, start?: Position | JSDocParseOptions, options?: JSDocParseOptions): JSDocComment {\n let opts: JSDocParseOptions | undefined;\n let position: Position | undefined;\n if (typeof node === 'string') {\n position = start as Position | undefined;\n opts = options as JSDocParseOptions | undefined;\n } else {\n position = node.range.start;\n opts = start as JSDocParseOptions | undefined;\n }\n if (!position) {\n position = Position.create(0, 0);\n }\n\n const lines = getLines(node);\n const normalizedOptions = normalizeOptions(opts);\n\n const tokens = tokenize({\n lines,\n position,\n options: normalizedOptions\n });\n\n return parseJSDocComment({\n index: 0,\n tokens,\n position\n });\n}\n\nexport function isJSDoc(node: CstNode | string, options?: JSDocParseOptions): boolean {\n const normalizedOptions = normalizeOptions(options);\n const lines = getLines(node);\n if (lines.length === 0) {\n return false;\n }\n\n const first = lines[0];\n const last = lines[lines.length - 1];\n const firstRegex = normalizedOptions.start;\n const lastRegex = normalizedOptions.end;\n\n return Boolean(firstRegex?.exec(first)) && Boolean(lastRegex?.exec(last));\n}\n\nfunction getLines(node: CstNode | string): string[] {\n let content = '';\n if (typeof node === 'string') {\n content = node;\n } else {\n content = node.text;\n }\n const lines = content.split(NEWLINE_REGEXP);\n return lines;\n}\n\n// Tokenization\n\ninterface JSDocToken {\n type: 'text' | 'tag' | 'inline-tag' | 'break'\n content: string\n range: Range\n}\n\nconst tagRegex = /\\s*(@([\\p{L}][\\p{L}\\p{N}]*)?)/uy;\nconst inlineTagRegex = /\\{(@[\\p{L}][\\p{L}\\p{N}]*)(\\s*)([^\\r\\n}]+)?\\}/gu;\n\nfunction tokenize(context: TokenizationContext): JSDocToken[] {\n const tokens: JSDocToken[] = [];\n let currentLine = context.position.line;\n let currentCharacter = context.position.character;\n for (let i = 0; i < context.lines.length; i++) {\n const first = i === 0;\n const last = i === context.lines.length - 1;\n let line = context.lines[i];\n let index = 0;\n\n if (first && context.options.start) {\n const match = context.options.start?.exec(line);\n if (match) {\n index = match.index + match[0].length;\n }\n } else {\n const match = context.options.line?.exec(line);\n if (match) {\n index = match.index + match[0].length;\n }\n }\n if (last) {\n const match = context.options.end?.exec(line);\n if (match) {\n line = line.substring(0, match.index);\n }\n }\n\n line = line.substring(0, lastCharacter(line));\n const whitespaceEnd = skipWhitespace(line, index);\n\n if (whitespaceEnd >= line.length) {\n // Only create a break token when we already have previous tokens\n if (tokens.length > 0) {\n const position = Position.create(currentLine, currentCharacter);\n tokens.push({\n type: 'break',\n content: '',\n range: Range.create(position, position)\n });\n }\n } else {\n tagRegex.lastIndex = index;\n const tagMatch = tagRegex.exec(line);\n if (tagMatch) {\n const fullMatch = tagMatch[0];\n const value = tagMatch[1];\n const start = Position.create(currentLine, currentCharacter + index);\n const end = Position.create(currentLine, currentCharacter + index + fullMatch.length);\n tokens.push({\n type: 'tag',\n content: value,\n range: Range.create(start, end)\n });\n index += fullMatch.length;\n index = skipWhitespace(line, index);\n }\n\n if (index < line.length) {\n const rest = line.substring(index);\n const inlineTagMatches = Array.from(rest.matchAll(inlineTagRegex));\n tokens.push(...buildInlineTokens(inlineTagMatches, rest, currentLine, currentCharacter + index));\n }\n }\n\n currentLine++;\n currentCharacter = 0;\n }\n\n // Remove last break token if there is one\n if (tokens.length > 0 && tokens[tokens.length - 1].type === 'break') {\n return tokens.slice(0, -1);\n }\n\n return tokens;\n}\n\nfunction buildInlineTokens(tags: RegExpMatchArray[], line: string, lineIndex: number, characterIndex: number): JSDocToken[] {\n const tokens: JSDocToken[] = [];\n\n if (tags.length === 0) {\n const start = Position.create(lineIndex, characterIndex);\n const end = Position.create(lineIndex, characterIndex + line.length);\n tokens.push({\n type: 'text',\n content: line,\n range: Range.create(start, end)\n });\n } else {\n let lastIndex = 0;\n for (const match of tags) {\n const matchIndex = match.index!;\n const startContent = line.substring(lastIndex, matchIndex);\n if (startContent.length > 0) {\n tokens.push({\n type: 'text',\n content: line.substring(lastIndex, matchIndex),\n range: Range.create(\n Position.create(lineIndex, lastIndex + characterIndex),\n Position.create(lineIndex, matchIndex + characterIndex)\n )\n });\n }\n let offset = startContent.length + 1;\n const tagName = match[1];\n tokens.push({\n type: 'inline-tag',\n content: tagName,\n range: Range.create(\n Position.create(lineIndex, lastIndex + offset + characterIndex),\n Position.create(lineIndex, lastIndex + offset + tagName.length + characterIndex)\n )\n });\n offset += tagName.length;\n if (match.length === 4) {\n offset += match[2].length;\n const value = match[3];\n tokens.push({\n type: 'text',\n content: value,\n range: Range.create(\n Position.create(lineIndex, lastIndex + offset + characterIndex),\n Position.create(lineIndex, lastIndex + offset + value.length + characterIndex)\n )\n });\n } else {\n tokens.push({\n type: 'text',\n content: '',\n range: Range.create(\n Position.create(lineIndex, lastIndex + offset + characterIndex),\n Position.create(lineIndex, lastIndex + offset + characterIndex)\n )\n });\n }\n lastIndex = matchIndex + match[0].length;\n }\n const endContent = line.substring(lastIndex);\n if (endContent.length > 0) {\n tokens.push({\n type: 'text',\n content: endContent,\n range: Range.create(\n Position.create(lineIndex, lastIndex + characterIndex),\n Position.create(lineIndex, lastIndex + characterIndex + endContent.length)\n )\n });\n }\n }\n\n return tokens;\n}\n\nconst nonWhitespaceRegex = /\\S/;\nconst whitespaceEndRegex = /\\s*$/;\n\nfunction skipWhitespace(line: string, index: number): number {\n const match = line.substring(index).match(nonWhitespaceRegex);\n if (match) {\n return index + match.index!;\n } else {\n return line.length;\n }\n}\n\nfunction lastCharacter(line: string): number | undefined {\n const match = line.match(whitespaceEndRegex);\n if (match && typeof match.index === 'number') {\n return match.index;\n }\n return undefined;\n}\n\n// Parsing\n\nfunction parseJSDocComment(context: ParseContext): JSDocComment {\n const startPosition: Position = Position.create(context.position.line, context.position.character);\n if (context.tokens.length === 0) {\n return new JSDocCommentImpl([], Range.create(startPosition, startPosition));\n }\n const elements: JSDocElement[] = [];\n while (context.index < context.tokens.length) {\n const element = parseJSDocElement(context, elements[elements.length - 1]);\n if (element) {\n elements.push(element);\n }\n }\n const start = elements[0]?.range.start ?? startPosition;\n const end = elements[elements.length - 1]?.range.end ?? startPosition;\n return new JSDocCommentImpl(elements, Range.create(start, end));\n}\n\nfunction parseJSDocElement(context: ParseContext, last?: JSDocElement): JSDocElement | undefined {\n const next = context.tokens[context.index];\n if (next.type === 'tag') {\n return parseJSDocTag(context, false);\n } else if (next.type === 'text' || next.type === 'inline-tag') {\n return parseJSDocText(context);\n } else {\n appendEmptyLine(next, last);\n context.index++;\n return undefined;\n }\n}\n\nfunction appendEmptyLine(token: JSDocToken, element?: JSDocElement): void {\n if (element) {\n const line = new JSDocLineImpl('', token.range);\n if ('inlines' in element) {\n element.inlines.push(line);\n } else {\n element.content.inlines.push(line);\n }\n }\n}\n\nfunction parseJSDocText(context: ParseContext): JSDocParagraph {\n let token = context.tokens[context.index];\n const firstToken = token;\n let lastToken = token;\n const lines: JSDocInline[] = [];\n while (token && token.type !== 'break' && token.type !== 'tag') {\n lines.push(parseJSDocInline(context));\n lastToken = token;\n token = context.tokens[context.index];\n }\n return new JSDocTextImpl(lines, Range.create(firstToken.range.start, lastToken.range.end));\n}\n\nfunction parseJSDocInline(context: ParseContext): JSDocInline {\n const token = context.tokens[context.index];\n if (token.type === 'inline-tag') {\n return parseJSDocTag(context, true);\n } else {\n return parseJSDocLine(context);\n }\n}\n\nfunction parseJSDocTag(context: ParseContext, inline: boolean): JSDocTag {\n const tagToken = context.tokens[context.index++];\n const name = tagToken.content.substring(1);\n const nextToken = context.tokens[context.index];\n if (nextToken?.type === 'text') {\n if (inline) {\n const docLine = parseJSDocLine(context);\n return new JSDocTagImpl(\n name,\n new JSDocTextImpl([docLine], docLine.range),\n inline,\n Range.create(tagToken.range.start, docLine.range.end)\n );\n } else {\n const textDoc = parseJSDocText(context);\n return new JSDocTagImpl(\n name,\n textDoc,\n inline,\n Range.create(tagToken.range.start, textDoc.range.end)\n );\n }\n } else {\n const range = tagToken.range;\n return new JSDocTagImpl(name, new JSDocTextImpl([], range), inline, range);\n }\n}\n\nfunction parseJSDocLine(context: ParseContext): JSDocLine {\n const token = context.tokens[context.index++];\n return new JSDocLineImpl(token.content, token.range);\n}\n\ninterface NormalizedOptions {\n start?: RegExp\n end?: RegExp\n line?: RegExp\n}\n\ninterface TokenizationContext {\n position: Position\n lines: string[]\n options: NormalizedOptions\n}\n\ninterface ParseContext {\n position: Position\n tokens: JSDocToken[]\n index: number\n}\n\nfunction normalizeOptions(options?: JSDocParseOptions): NormalizedOptions {\n if (!options) {\n return normalizeOptions({\n start: '/**',\n end: '*/',\n line: '*'\n });\n }\n const { start, end, line } = options;\n return {\n start: normalizeOption(start, true),\n end: normalizeOption(end, false),\n line: normalizeOption(line, true)\n };\n}\n\nfunction normalizeOption(option: RegExp | string | undefined, start: boolean): RegExp | undefined {\n if (typeof option === 'string' || typeof option === 'object') {\n const escaped = typeof option === 'string' ? escapeRegExp(option) : option.source;\n if (start) {\n return new RegExp(`^\\\\s*${escaped}`);\n } else {\n return new RegExp(`\\\\s*${escaped}\\\\s*$`);\n }\n } else {\n return option;\n }\n}\n\nclass JSDocCommentImpl implements JSDocComment {\n\n readonly elements: JSDocElement[];\n readonly range: Range;\n\n constructor(elements: JSDocElement[], range: Range) {\n this.elements = elements;\n this.range = range;\n }\n\n getTag(name: string): JSDocTag | undefined {\n return this.getAllTags().find(e => e.name === name);\n }\n\n getTags(name: string): JSDocTag[] {\n return this.getAllTags().filter(e => e.name === name);\n }\n\n private getAllTags(): JSDocTag[] {\n return this.elements.filter((e): e is JSDocTag => 'name' in e);\n }\n\n toString(): string {\n let value = '';\n for (const element of this.elements) {\n if (value.length === 0) {\n value = element.toString();\n } else {\n const text = element.toString();\n value += fillNewlines(value) + text;\n }\n }\n return value.trim();\n }\n\n toMarkdown(options?: JSDocRenderOptions): string {\n let value = '';\n for (const element of this.elements) {\n if (value.length === 0) {\n value = element.toMarkdown(options);\n } else {\n const text = element.toMarkdown(options);\n value += fillNewlines(value) + text;\n }\n }\n return value.trim();\n }\n}\n\nclass JSDocTagImpl implements JSDocTag {\n name: string;\n content: JSDocParagraph;\n range: Range;\n inline: boolean;\n\n constructor(name: string, content: JSDocParagraph, inline: boolean, range: Range) {\n this.name = name;\n this.content = content;\n this.inline = inline;\n this.range = range;\n }\n\n toString(): string {\n let text = `@${this.name}`;\n const content = this.content.toString();\n if (this.content.inlines.length === 1) {\n text = `${text} ${content}`;\n } else if (this.content.inlines.length > 1) {\n text = `${text}\\n${content}`;\n }\n if (this.inline) {\n // Inline tags are surrounded by curly braces\n return `{${text}}`;\n } else {\n return text;\n }\n }\n\n toMarkdown(options?: JSDocRenderOptions): string {\n return options?.renderTag?.(this) ?? this.toMarkdownDefault(options);\n }\n\n private toMarkdownDefault(options?: JSDocRenderOptions): string {\n const content = this.content.toMarkdown(options);\n if (this.inline) {\n const rendered = renderInlineTag(this.name, content, options ?? {});\n if (typeof rendered === 'string') {\n return rendered;\n }\n }\n let marker = '';\n if (options?.tag === 'italic' || options?.tag === undefined) {\n marker = '*';\n } else if (options?.tag === 'bold') {\n marker = '**';\n } else if (options?.tag === 'bold-italic') {\n marker = '***';\n }\n let text = `${marker}@${this.name}${marker}`;\n if (this.content.inlines.length === 1) {\n text = `${text} \u2014 ${content}`;\n } else if (this.content.inlines.length > 1) {\n text = `${text}\\n${content}`;\n }\n if (this.inline) {\n // Inline tags are surrounded by curly braces\n return `{${text}}`;\n } else {\n return text;\n }\n }\n}\n\nfunction renderInlineTag(tag: string, content: string, options: JSDocRenderOptions): string | undefined {\n if (tag === 'linkplain' || tag === 'linkcode' || tag === 'link') {\n const index = content.indexOf(' ');\n let display = content;\n if (index > 0) {\n const displayStart = skipWhitespace(content, index);\n display = content.substring(displayStart);\n content = content.substring(0, index);\n }\n if (tag === 'linkcode' || (tag === 'link' && options.link === 'code')) {\n // Surround the display value in a markdown inline code block\n display = `\\`${display}\\``;\n }\n const renderedLink = options.renderLink?.(content, display) ?? renderLinkDefault(content, display);\n return renderedLink;\n }\n return undefined;\n}\n\nfunction renderLinkDefault(content: string, display: string): string {\n try {\n URI.parse(content, true);\n return `[${display}](${content})`;\n } catch {\n return content;\n }\n}\n\nclass JSDocTextImpl implements JSDocParagraph {\n inlines: JSDocInline[];\n range: Range;\n\n constructor(lines: JSDocInline[], range: Range) {\n this.inlines = lines;\n this.range = range;\n }\n\n toString(): string {\n let text = '';\n for (let i = 0; i < this.inlines.length; i++) {\n const inline = this.inlines[i];\n const next = this.inlines[i + 1];\n text += inline.toString();\n if (next && next.range.start.line > inline.range.start.line) {\n text += '\\n';\n }\n }\n return text;\n }\n\n toMarkdown(options?: JSDocRenderOptions): string {\n let text = '';\n for (let i = 0; i < this.inlines.length; i++) {\n const inline = this.inlines[i];\n const next = this.inlines[i + 1];\n text += inline.toMarkdown(options);\n if (next && next.range.start.line > inline.range.start.line) {\n text += '\\n';\n }\n }\n return text;\n }\n}\n\nclass JSDocLineImpl implements JSDocLine {\n text: string;\n range: Range;\n\n constructor(text: string, range: Range) {\n this.text = text;\n this.range = range;\n }\n\n toString(): string {\n return this.text;\n }\n toMarkdown(): string {\n return this.text;\n }\n\n}\n\nfunction fillNewlines(text: string): string {\n if (text.endsWith('\\n')) {\n return '\\n';\n } else {\n return '\\n\\n';\n }\n}\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode, AstNodeDescription } from '../syntax-tree.js';\nimport type { IndexManager } from '../workspace/index-manager.js';\nimport type { CommentProvider } from './comment-provider.js';\nimport type { JSDocTag } from './jsdoc.js';\nimport { getDocument } from '../utils/ast-utils.js';\nimport { isJSDoc, parseJSDoc } from './jsdoc.js';\n\n/**\n * Provides documentation for AST nodes.\n */\nexport interface DocumentationProvider {\n /**\n * Returns a markdown documentation string for the specified AST node.\n *\n * The default implementation `JSDocDocumentationProvider` will inspect the comment associated with the specified node.\n */\n getDocumentation(node: AstNode): string | undefined;\n}\n\nexport class JSDocDocumentationProvider implements DocumentationProvider {\n\n protected readonly indexManager: IndexManager;\n protected readonly commentProvider: CommentProvider;\n\n constructor(services: LangiumCoreServices) {\n this.indexManager = services.shared.workspace.IndexManager;\n this.commentProvider = services.documentation.CommentProvider;\n }\n\n getDocumentation(node: AstNode): string | undefined {\n const comment = this.commentProvider.getComment(node);\n if (comment && isJSDoc(comment)) {\n const parsedJSDoc = parseJSDoc(comment);\n return parsedJSDoc.toMarkdown({\n renderLink: (link, display) => {\n return this.documentationLinkRenderer(node, link, display);\n },\n renderTag: (tag) => {\n return this.documentationTagRenderer(node, tag);\n }\n });\n }\n return undefined;\n }\n\n protected documentationLinkRenderer(node: AstNode, name: string, display: string): string | undefined {\n const description = this.findNameInPrecomputedScopes(node, name) ?? this.findNameInGlobalScope(node, name);\n if (description && description.nameSegment) {\n const line = description.nameSegment.range.start.line + 1;\n const character = description.nameSegment.range.start.character + 1;\n const uri = description.documentUri.with({ fragment: `L${line},${character}` });\n return `[${display}](${uri.toString()})`;\n } else {\n return undefined;\n }\n }\n\n protected documentationTagRenderer(_node: AstNode, _tag: JSDocTag): string | undefined {\n // Fall back to the default tag rendering\n return undefined;\n }\n\n protected findNameInPrecomputedScopes(node: AstNode, name: string): AstNodeDescription | undefined {\n const document = getDocument(node);\n const precomputed = document.precomputedScopes;\n if (!precomputed) {\n return undefined;\n }\n let currentNode: AstNode | undefined = node;\n do {\n const allDescriptions = precomputed.get(currentNode);\n const description = allDescriptions.find(e => e.name === name);\n if (description) {\n return description;\n }\n currentNode = currentNode.$container;\n } while (currentNode);\n\n return undefined;\n }\n\n protected findNameInGlobalScope(node: AstNode, name: string): AstNodeDescription | undefined {\n const description = this.indexManager.allElements().find(e => e.name === name);\n return description;\n }\n}\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { GrammarConfig } from '../languages/grammar-config.js';\nimport { isAstNodeWithComment } from '../serializer/json-serializer.js';\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode } from '../syntax-tree.js';\nimport { findCommentNode } from '../utils/cst-utils.js';\n\n/**\n * Provides comments for AST nodes.\n */\nexport interface CommentProvider {\n /**\n * Returns the comment associated with the specified AST node.\n * @param node The AST node to get the comment for.\n * @returns The comment associated with the specified AST node or `undefined` if there is no comment.\n */\n getComment(node: AstNode): string | undefined;\n}\n\nexport class DefaultCommentProvider implements CommentProvider {\n protected readonly grammarConfig: () => GrammarConfig;\n constructor(services: LangiumCoreServices) {\n this.grammarConfig = () => services.parser.GrammarConfig;\n }\n getComment(node: AstNode): string | undefined {\n if(isAstNodeWithComment(node)) {\n return node.$comment;\n }\n return findCommentNode(node.$cstNode, this.grammarConfig().multilineCommentRules)?.text;\n }\n}\n", "/******************************************************************************\n * Copyright 2024 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\n// eslint-disable-next-line no-restricted-imports\nexport * from 'vscode-jsonrpc/lib/common/events.js';\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { CancellationToken } from '../utils/cancellation.js';\nimport type { LangiumCoreServices } from '../services.js';\nimport type { AstNode } from '../syntax-tree.js';\nimport type { LangiumParser, ParseResult } from './langium-parser.js';\nimport type { Hydrator } from '../serializer/hydrator.js';\nimport type { Event } from '../utils/event.js';\nimport { Deferred, OperationCancelled } from '../utils/promise-utils.js';\nimport { Emitter } from '../utils/event.js';\n\n/**\n * Async parser that allows to cancel the current parsing process.\n * The sync parser implementation is blocking the event loop, which can become quite problematic for large files.\n *\n * Note that the default implementation is not actually async. It just wraps the sync parser in a promise.\n * A real implementation would create worker threads or web workers to offload the parsing work.\n */\nexport interface AsyncParser {\n parse(text: string, cancelToken: CancellationToken): Promise>;\n}\n\n/**\n * Default implementation of the async parser. This implementation only wraps the sync parser in a promise.\n *\n * A real implementation would create worker threads or web workers to offload the parsing work.\n */\nexport class DefaultAsyncParser implements AsyncParser {\n\n protected readonly syncParser: LangiumParser;\n\n constructor(services: LangiumCoreServices) {\n this.syncParser = services.parser.LangiumParser;\n }\n\n parse(text: string): Promise> {\n return Promise.resolve(this.syncParser.parse(text));\n }\n}\n\nexport abstract class AbstractThreadedAsyncParser implements AsyncParser {\n\n /**\n * The thread count determines how many threads are used to parse files in parallel.\n * The default value is 8. Decreasing this value increases startup performance, but decreases parallel parsing performance.\n */\n protected threadCount = 8;\n /**\n * The termination delay determines how long the parser waits for a thread to finish after a cancellation request.\n * The default value is 200(ms).\n */\n protected terminationDelay = 200;\n protected workerPool: ParserWorker[] = [];\n protected queue: Array> = [];\n\n protected readonly hydrator: Hydrator;\n\n constructor(services: LangiumCoreServices) {\n this.hydrator = services.serializer.Hydrator;\n }\n\n protected initializeWorkers(): void {\n while (this.workerPool.length < this.threadCount) {\n const worker = this.createWorker();\n worker.onReady(() => {\n if (this.queue.length > 0) {\n const deferred = this.queue.shift();\n if (deferred) {\n worker.lock();\n deferred.resolve(worker);\n }\n }\n });\n this.workerPool.push(worker);\n }\n }\n\n async parse(text: string, cancelToken: CancellationToken): Promise> {\n const worker = await this.acquireParserWorker(cancelToken);\n const deferred = new Deferred>();\n let timeout: NodeJS.Timeout | undefined;\n // If the cancellation token is requested, we wait for a certain time before terminating the worker.\n // Since the cancellation token lives longer than the parsing process, we need to dispose the event listener.\n // Otherwise, we might accidentally terminate the worker after the parsing process has finished.\n const cancellation = cancelToken.onCancellationRequested(() => {\n timeout = setTimeout(() => {\n this.terminateWorker(worker);\n }, this.terminationDelay);\n });\n worker.parse(text).then(result => {\n const hydrated = this.hydrator.hydrate(result);\n deferred.resolve(hydrated);\n }).catch(err => {\n deferred.reject(err);\n }).finally(() => {\n cancellation.dispose();\n clearTimeout(timeout);\n });\n return deferred.promise;\n }\n\n protected terminateWorker(worker: ParserWorker): void {\n worker.terminate();\n const index = this.workerPool.indexOf(worker);\n if (index >= 0) {\n this.workerPool.splice(index, 1);\n }\n }\n\n protected async acquireParserWorker(cancelToken: CancellationToken): Promise {\n this.initializeWorkers();\n for (const worker of this.workerPool) {\n if (worker.ready) {\n worker.lock();\n return worker;\n }\n }\n const deferred = new Deferred();\n cancelToken.onCancellationRequested(() => {\n const index = this.queue.indexOf(deferred);\n if (index >= 0) {\n this.queue.splice(index, 1);\n }\n deferred.reject(OperationCancelled);\n });\n this.queue.push(deferred);\n return deferred.promise;\n }\n\n protected abstract createWorker(): ParserWorker;\n}\n\nexport type WorkerMessagePost = (message: unknown) => void;\nexport type WorkerMessageCallback = (cb: (message: unknown) => void) => void;\n\nexport class ParserWorker {\n\n protected readonly sendMessage: WorkerMessagePost;\n protected readonly _terminate: () => void;\n protected readonly onReadyEmitter = new Emitter();\n\n protected deferred = new Deferred();\n protected _ready = true;\n protected _parsing = false;\n\n get ready(): boolean {\n return this._ready;\n }\n\n get onReady(): Event {\n return this.onReadyEmitter.event;\n }\n\n constructor(sendMessage: WorkerMessagePost, onMessage: WorkerMessageCallback, onError: WorkerMessageCallback, terminate: () => void) {\n this.sendMessage = sendMessage;\n this._terminate = terminate;\n onMessage(result => {\n const parseResult = result as ParseResult;\n this.deferred.resolve(parseResult);\n this.unlock();\n });\n onError(error => {\n this.deferred.reject(error);\n this.unlock();\n });\n }\n\n terminate(): void {\n this.deferred.reject(OperationCancelled);\n this._terminate();\n }\n\n lock(): void {\n this._ready = false;\n }\n\n unlock(): void {\n this._parsing = false;\n this._ready = true;\n this.onReadyEmitter.fire();\n }\n\n parse(text: string): Promise {\n if (this._parsing) {\n throw new Error('Parser worker is busy');\n }\n this._parsing = true;\n this.deferred = new Deferred();\n this.sendMessage(text);\n return this.deferred.promise;\n }\n}\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport { CancellationToken, CancellationTokenSource } from '../utils/cancellation.js';\nimport { Deferred, isOperationCancelled, type MaybePromise } from '../utils/promise-utils.js';\n\n/**\n * Utility service to execute mutually exclusive actions.\n */\nexport interface WorkspaceLock {\n /**\n * Performs a single async action, like initializing the workspace or processing document changes.\n * Only one action will be executed at a time.\n *\n * When another action is queued up, the token provided for the action will be cancelled.\n * Assuming the action makes use of this token, the next action only has to wait for the current action to finish cancellation.\n */\n write(action: (token: CancellationToken) => MaybePromise): Promise;\n\n /**\n * Performs a single action, like computing completion results or providing workspace symbols.\n * Read actions will only be executed after all write actions have finished. They will be executed in parallel if possible.\n *\n * If a write action is currently running, the read action will be queued up and executed afterwards.\n * If a new write action is queued up while a read action is waiting, the write action will receive priority and will be handled before the read action.\n *\n * Note that read actions are not allowed to modify anything in the workspace. Please use {@link write} instead.\n */\n read(action: () => MaybePromise): Promise;\n\n /**\n * Cancels the last queued write action. All previous write actions already have been cancelled.\n */\n cancelWrite(): void;\n}\n\ntype LockAction = (token: CancellationToken) => MaybePromise;\n\ninterface LockEntry {\n action: LockAction;\n deferred: Deferred;\n cancellationToken: CancellationToken;\n}\n\nexport class DefaultWorkspaceLock implements WorkspaceLock {\n\n private previousTokenSource = new CancellationTokenSource();\n private writeQueue: LockEntry[] = [];\n private readQueue: LockEntry[] = [];\n private done = true;\n\n write(action: (token: CancellationToken) => MaybePromise): Promise {\n this.cancelWrite();\n const tokenSource = new CancellationTokenSource();\n this.previousTokenSource = tokenSource;\n return this.enqueue(this.writeQueue, action, tokenSource.token);\n }\n\n read(action: () => MaybePromise): Promise {\n return this.enqueue(this.readQueue, action);\n }\n\n private enqueue(queue: LockEntry[], action: LockAction, cancellationToken?: CancellationToken): Promise {\n const deferred = new Deferred();\n const entry: LockEntry = {\n action,\n deferred,\n cancellationToken: cancellationToken ?? CancellationToken.None\n };\n queue.push(entry);\n this.performNextOperation();\n return deferred.promise as Promise;\n }\n\n private async performNextOperation(): Promise {\n if (!this.done) {\n return;\n }\n const entries: LockEntry[] = [];\n if (this.writeQueue.length > 0) {\n // Just perform the next write action\n entries.push(this.writeQueue.shift()!);\n } else if (this.readQueue.length > 0) {\n // Empty the read queue and perform all actions in parallel\n entries.push(...this.readQueue.splice(0, this.readQueue.length));\n } else {\n return;\n }\n this.done = false;\n await Promise.all(entries.map(async ({ action, deferred, cancellationToken }) => {\n try {\n // Move the execution of the action to the next event loop tick via `Promise.resolve()`\n const result = await Promise.resolve().then(() => action(cancellationToken));\n deferred.resolve(result);\n } catch (err) {\n if (isOperationCancelled(err)) {\n // If the operation was cancelled, we don't want to reject the promise\n deferred.resolve(undefined);\n } else {\n deferred.reject(err);\n }\n }\n }));\n this.done = true;\n this.performNextOperation();\n }\n\n cancelWrite(): void {\n this.previousTokenSource.cancel();\n }\n}\n", "/******************************************************************************\n * Copyright 2024 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport type { TokenType } from 'chevrotain';\nimport { CompositeCstNodeImpl, LeafCstNodeImpl, RootCstNodeImpl } from '../parser/cst-node-builder.js';\nimport { isAbstractElement, type AbstractElement, type Grammar } from '../languages/generated/ast.js';\nimport type { Linker } from '../references/linker.js';\nimport type { Lexer } from '../parser/lexer.js';\nimport type { LangiumCoreServices } from '../services.js';\nimport type { ParseResult } from '../parser/langium-parser.js';\nimport type { Reference, AstNode, CstNode, LeafCstNode, GenericAstNode, Mutable, RootCstNode } from '../syntax-tree.js';\nimport { isRootCstNode, isCompositeCstNode, isLeafCstNode, isAstNode, isReference } from '../syntax-tree.js';\nimport { streamAst } from '../utils/ast-utils.js';\nimport { BiMap } from '../utils/collections.js';\nimport { streamCst } from '../utils/cst-utils.js';\n\n/**\n * The hydrator service is responsible for allowing AST parse results to be sent across worker threads.\n */\nexport interface Hydrator {\n /**\n * Converts a parse result to a plain object. The resulting object can be sent across worker threads.\n */\n dehydrate(result: ParseResult): ParseResult;\n /**\n * Converts a plain object to a parse result. The included AST node can then be used in the main thread.\n * Calling this method on objects that have not been dehydrated first will result in undefined behavior.\n */\n hydrate(result: ParseResult): ParseResult;\n}\n\nexport interface DehydrateContext {\n astNodes: Map;\n cstNodes: Map;\n}\n\nexport interface HydrateContext {\n astNodes: Map;\n cstNodes: Map;\n}\n\nexport class DefaultHydrator implements Hydrator {\n\n protected readonly grammar: Grammar;\n protected readonly lexer: Lexer;\n protected readonly linker: Linker;\n\n protected readonly grammarElementIdMap = new BiMap();\n protected readonly tokenTypeIdMap = new BiMap();\n\n constructor(services: LangiumCoreServices) {\n this.grammar = services.Grammar;\n this.lexer = services.parser.Lexer;\n this.linker = services.references.Linker;\n }\n\n dehydrate(result: ParseResult): ParseResult {\n return {\n // We need to create shallow copies of the errors\n // The original errors inherit from the `Error` class, which is not transferable across worker threads\n lexerErrors: result.lexerErrors.map(e => ({ ...e })),\n parserErrors: result.parserErrors.map(e => ({ ...e })),\n value: this.dehydrateAstNode(result.value, this.createDehyrationContext(result.value))\n };\n }\n\n protected createDehyrationContext(node: AstNode): DehydrateContext {\n const astNodes = new Map();\n const cstNodes = new Map();\n for (const astNode of streamAst(node)) {\n astNodes.set(astNode, {});\n }\n if (node.$cstNode) {\n for (const cstNode of streamCst(node.$cstNode)) {\n cstNodes.set(cstNode, {});\n }\n }\n return {\n astNodes,\n cstNodes\n };\n }\n\n protected dehydrateAstNode(node: AstNode, context: DehydrateContext): object {\n const obj = context.astNodes.get(node) as Record;\n obj.$type = node.$type;\n obj.$containerIndex = node.$containerIndex;\n obj.$containerProperty = node.$containerProperty;\n if (node.$cstNode !== undefined) {\n obj.$cstNode = this.dehydrateCstNode(node.$cstNode, context);\n }\n for (const [name, value] of Object.entries(node)) {\n if (name.startsWith('$')) {\n continue;\n }\n if (Array.isArray(value)) {\n const arr: any[] = [];\n obj[name] = arr;\n for (const item of value) {\n if (isAstNode(item)) {\n arr.push(this.dehydrateAstNode(item, context));\n } else if (isReference(item)) {\n arr.push(this.dehydrateReference(item, context));\n } else {\n arr.push(item);\n }\n }\n } else if (isAstNode(value)) {\n obj[name] = this.dehydrateAstNode(value, context);\n } else if (isReference(value)) {\n obj[name] = this.dehydrateReference(value, context);\n } else if (value !== undefined) {\n obj[name] = value;\n }\n }\n return obj;\n }\n\n protected dehydrateReference(reference: Reference, context: DehydrateContext): any {\n const obj: Record = {};\n obj.$refText = reference.$refText;\n if (reference.$refNode) {\n obj.$refNode = context.cstNodes.get(reference.$refNode);\n }\n return obj;\n }\n\n protected dehydrateCstNode(node: CstNode, context: DehydrateContext): any {\n const cstNode = context.cstNodes.get(node) as Record;\n if (isRootCstNode(node)) {\n cstNode.fullText = node.fullText;\n } else {\n // Note: This returns undefined for hidden nodes (i.e. comments)\n cstNode.grammarSource = this.getGrammarElementId(node.grammarSource);\n }\n cstNode.hidden = node.hidden;\n cstNode.astNode = context.astNodes.get(node.astNode);\n if (isCompositeCstNode(node)) {\n cstNode.content = node.content.map(child => this.dehydrateCstNode(child, context));\n } else if (isLeafCstNode(node)) {\n cstNode.tokenType = node.tokenType.name;\n cstNode.offset = node.offset;\n cstNode.length = node.length;\n cstNode.startLine = node.range.start.line;\n cstNode.startColumn = node.range.start.character;\n cstNode.endLine = node.range.end.line;\n cstNode.endColumn = node.range.end.character;\n }\n return cstNode;\n }\n\n hydrate(result: ParseResult): ParseResult {\n const node = result.value;\n const context = this.createHydrationContext(node);\n if ('$cstNode' in node) {\n this.hydrateCstNode(node.$cstNode, context);\n }\n return {\n lexerErrors: result.lexerErrors,\n parserErrors: result.parserErrors,\n value: this.hydrateAstNode(node, context) as T\n };\n }\n\n protected createHydrationContext(node: any): HydrateContext {\n const astNodes = new Map();\n const cstNodes = new Map();\n for (const astNode of streamAst(node)) {\n astNodes.set(astNode, {} as AstNode);\n }\n let root: RootCstNode;\n if (node.$cstNode) {\n for (const cstNode of streamCst(node.$cstNode)) {\n let cst: Mutable | undefined;\n if ('fullText' in cstNode) {\n cst = new RootCstNodeImpl(cstNode.fullText as string);\n root = cst as RootCstNode;\n } else if ('content' in cstNode) {\n cst = new CompositeCstNodeImpl();\n } else if ('tokenType' in cstNode) {\n cst = this.hydrateCstLeafNode(cstNode);\n }\n if (cst) {\n cstNodes.set(cstNode, cst);\n cst.root = root!;\n }\n }\n }\n return {\n astNodes,\n cstNodes\n };\n }\n\n protected hydrateAstNode(node: any, context: HydrateContext): AstNode {\n const astNode = context.astNodes.get(node) as Mutable;\n astNode.$type = node.$type;\n astNode.$containerIndex = node.$containerIndex;\n astNode.$containerProperty = node.$containerProperty;\n if (node.$cstNode) {\n astNode.$cstNode = context.cstNodes.get(node.$cstNode);\n }\n for (const [name, value] of Object.entries(node)) {\n if (name.startsWith('$')) {\n continue;\n }\n if (Array.isArray(value)) {\n const arr: unknown[] = [];\n astNode[name] = arr;\n for (const item of value) {\n if (isAstNode(item)) {\n arr.push(this.setParent(this.hydrateAstNode(item, context), astNode));\n } else if (isReference(item)) {\n arr.push(this.hydrateReference(item, astNode, name, context));\n } else {\n arr.push(item);\n }\n }\n } else if (isAstNode(value)) {\n astNode[name] = this.setParent(this.hydrateAstNode(value, context), astNode);\n } else if (isReference(value)) {\n astNode[name] = this.hydrateReference(value, astNode, name, context);\n } else if (value !== undefined) {\n astNode[name] = value;\n }\n }\n return astNode;\n }\n\n protected setParent(node: any, parent: any): any {\n node.$container = parent as AstNode;\n return node;\n }\n\n protected hydrateReference(reference: any, node: AstNode, name: string, context: HydrateContext): Reference {\n return this.linker.buildReference(node, name, context.cstNodes.get(reference.$refNode)!, reference.$refText);\n }\n\n protected hydrateCstNode(cstNode: any, context: HydrateContext, num = 0): CstNode {\n const cstNodeObj = context.cstNodes.get(cstNode) as Mutable;\n if (typeof cstNode.grammarSource === 'number') {\n cstNodeObj.grammarSource = this.getGrammarElement(cstNode.grammarSource);\n }\n cstNodeObj.astNode = context.astNodes.get(cstNode.astNode)!;\n if (isCompositeCstNode(cstNodeObj)) {\n for (const child of cstNode.content) {\n const hydrated = this.hydrateCstNode(child, context, num++);\n cstNodeObj.content.push(hydrated);\n }\n }\n return cstNodeObj;\n }\n\n protected hydrateCstLeafNode(cstNode: any): LeafCstNode {\n const tokenType = this.getTokenType(cstNode.tokenType);\n const offset = cstNode.offset;\n const length = cstNode.length;\n const startLine = cstNode.startLine;\n const startColumn = cstNode.startColumn;\n const endLine = cstNode.endLine;\n const endColumn = cstNode.endColumn;\n const hidden = cstNode.hidden;\n const node = new LeafCstNodeImpl(\n offset,\n length,\n {\n start: {\n line: startLine,\n character: startColumn\n },\n end: {\n line: endLine,\n character: endColumn\n }\n },\n tokenType,\n hidden\n );\n return node;\n }\n\n protected getTokenType(name: string): TokenType {\n return this.lexer.definition[name];\n }\n\n protected getGrammarElementId(node: AbstractElement): number | undefined {\n if (this.grammarElementIdMap.size === 0) {\n this.createGrammarElementIdMap();\n }\n return this.grammarElementIdMap.get(node);\n }\n\n protected getGrammarElement(id: number): AbstractElement {\n if (this.grammarElementIdMap.size === 0) {\n this.createGrammarElementIdMap();\n }\n const element = this.grammarElementIdMap.getKey(id);\n if (element) {\n return element;\n } else {\n throw new Error('Invalid grammar element id: ' + id);\n }\n }\n\n protected createGrammarElementIdMap(): void {\n let id = 0;\n for (const element of streamAst(this.grammar)) {\n if (isAbstractElement(element)) {\n this.grammarElementIdMap.set(element, id++);\n }\n }\n }\n\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n******************************************************************************/\n\nimport type { Module } from './dependency-injection.js';\nimport type { LangiumDefaultCoreServices, LangiumDefaultSharedCoreServices, LangiumCoreServices, LangiumSharedCoreServices } from './services.js';\nimport type { FileSystemProvider } from './workspace/file-system-provider.js';\nimport { createGrammarConfig } from './languages/grammar-config.js';\nimport { createCompletionParser } from './parser/completion-parser-builder.js';\nimport { createLangiumParser } from './parser/langium-parser-builder.js';\nimport { DefaultTokenBuilder } from './parser/token-builder.js';\nimport { DefaultValueConverter } from './parser/value-converter.js';\nimport { DefaultLinker } from './references/linker.js';\nimport { DefaultNameProvider } from './references/name-provider.js';\nimport { DefaultReferences } from './references/references.js';\nimport { DefaultScopeComputation } from './references/scope-computation.js';\nimport { DefaultScopeProvider } from './references/scope-provider.js';\nimport { DefaultJsonSerializer } from './serializer/json-serializer.js';\nimport { DefaultServiceRegistry } from './service-registry.js';\nimport { DefaultDocumentValidator } from './validation/document-validator.js';\nimport { ValidationRegistry } from './validation/validation-registry.js';\nimport { DefaultAstNodeDescriptionProvider, DefaultReferenceDescriptionProvider } from './workspace/ast-descriptions.js';\nimport { DefaultAstNodeLocator } from './workspace/ast-node-locator.js';\nimport { DefaultConfigurationProvider } from './workspace/configuration.js';\nimport { DefaultDocumentBuilder } from './workspace/document-builder.js';\nimport { DefaultLangiumDocumentFactory, DefaultLangiumDocuments } from './workspace/documents.js';\nimport { DefaultIndexManager } from './workspace/index-manager.js';\nimport { DefaultWorkspaceManager } from './workspace/workspace-manager.js';\nimport { DefaultLexer } from './parser/lexer.js';\nimport { JSDocDocumentationProvider } from './documentation/documentation-provider.js';\nimport { DefaultCommentProvider } from './documentation/comment-provider.js';\nimport { LangiumParserErrorMessageProvider } from './parser/langium-parser.js';\nimport { DefaultAsyncParser } from './parser/async-parser.js';\nimport { DefaultWorkspaceLock } from './workspace/workspace-lock.js';\nimport { DefaultHydrator } from './serializer/hydrator.js';\n\n/**\n * Context required for creating the default language-specific dependency injection module.\n */\nexport interface DefaultCoreModuleContext {\n shared: LangiumSharedCoreServices;\n}\n\n/**\n * Creates a dependency injection module configuring the default core services.\n * This is a set of services that are dedicated to a specific language.\n */\nexport function createDefaultCoreModule(context: DefaultCoreModuleContext): Module {\n return {\n documentation: {\n CommentProvider: (services) => new DefaultCommentProvider(services),\n DocumentationProvider: (services) => new JSDocDocumentationProvider(services)\n },\n parser: {\n AsyncParser: (services) => new DefaultAsyncParser(services),\n GrammarConfig: (services) => createGrammarConfig(services),\n LangiumParser: (services) => createLangiumParser(services),\n CompletionParser: (services) => createCompletionParser(services),\n ValueConverter: () => new DefaultValueConverter(),\n TokenBuilder: () => new DefaultTokenBuilder(),\n Lexer: (services) => new DefaultLexer(services),\n ParserErrorMessageProvider: () => new LangiumParserErrorMessageProvider()\n },\n workspace: {\n AstNodeLocator: () => new DefaultAstNodeLocator(),\n AstNodeDescriptionProvider: (services) => new DefaultAstNodeDescriptionProvider(services),\n ReferenceDescriptionProvider: (services) => new DefaultReferenceDescriptionProvider(services)\n },\n references: {\n Linker: (services) => new DefaultLinker(services),\n NameProvider: () => new DefaultNameProvider(),\n ScopeProvider: (services) => new DefaultScopeProvider(services),\n ScopeComputation: (services) => new DefaultScopeComputation(services),\n References: (services) => new DefaultReferences(services)\n },\n serializer: {\n Hydrator: (services) => new DefaultHydrator(services),\n JsonSerializer: (services) => new DefaultJsonSerializer(services)\n },\n validation: {\n DocumentValidator: (services) => new DefaultDocumentValidator(services),\n ValidationRegistry: (services) => new ValidationRegistry(services)\n },\n shared: () => context.shared\n };\n}\n\n/**\n * Context required for creating the default shared dependency injection module.\n */\nexport interface DefaultSharedCoreModuleContext {\n /**\n * Factory function to create a {@link FileSystemProvider}.\n *\n * Langium exposes an `EmptyFileSystem` and `NodeFileSystem`, exported through `langium/node`.\n * When running Langium as part of a vscode language server or a Node.js app, using the `NodeFileSystem` is recommended,\n * the `EmptyFileSystem` in every other use case.\n */\n fileSystemProvider: (services: LangiumSharedCoreServices) => FileSystemProvider;\n}\n\n/**\n * Creates a dependency injection module configuring the default shared core services.\n * This is the set of services that are shared between multiple languages.\n */\nexport function createDefaultSharedCoreModule(context: DefaultSharedCoreModuleContext): Module {\n return {\n ServiceRegistry: () => new DefaultServiceRegistry(),\n workspace: {\n LangiumDocuments: (services) => new DefaultLangiumDocuments(services),\n LangiumDocumentFactory: (services) => new DefaultLangiumDocumentFactory(services),\n DocumentBuilder: (services) => new DefaultDocumentBuilder(services),\n IndexManager: (services) => new DefaultIndexManager(services),\n WorkspaceManager: (services) => new DefaultWorkspaceManager(services),\n FileSystemProvider: (services) => context.fileSystemProvider(services),\n WorkspaceLock: () => new DefaultWorkspaceLock(),\n ConfigurationProvider: (services) => new DefaultConfigurationProvider(services)\n }\n };\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\n/**\n * A `Module` is a description of possibly grouped service factories.\n *\n * Given a type I = { group: { service: A } },\n * Module := { group: { service: (injector: I) => A } }\n *\n * Making `I` available during the creation of `I` allows us to create cyclic\n * dependencies.\n */\nexport type Module = {\n [K in keyof T]: Module | ((injector: I) => T[K])\n}\n\nexport namespace Module {\n export const merge = (m1: Module, m2: Module) => (_merge(_merge({}, m1), m2) as Module);\n}\n\n/**\n * Given a set of modules, the inject function returns a lazily evaluated injector\n * that injects dependencies into the requested service when it is requested the\n * first time. Subsequent requests will return the same service.\n *\n * In the case of cyclic dependencies, an Error will be thrown. This can be fixed\n * by injecting a provider `() => T` instead of a `T`.\n *\n * Please note that the arguments may be objects or arrays. However, the result will\n * be an object. Using it with for..of will have no effect.\n *\n * @param module1 first Module\n * @param module2 (optional) second Module\n * @param module3 (optional) third Module\n * @param module4 (optional) fourth Module\n * @param module5 (optional) fifth Module\n * @param module6 (optional) sixth Module\n * @param module7 (optional) seventh Module\n * @param module8 (optional) eighth Module\n * @param module9 (optional) ninth Module\n * @returns a new object of type I\n */\nexport function inject(\n module1: Module, module2?: Module, module3?: Module, module4?: Module, module5?: Module, module6?: Module, module7?: Module, module8?: Module, module9?: Module\n): I {\n const module = [module1, module2, module3, module4, module5, module6, module7, module8, module9].reduce(_merge, {}) as Module;\n return _inject(module);\n}\n\nconst isProxy = Symbol('isProxy');\n\n/**\n * Eagerly load all services in the given dependency injection container. This is sometimes\n * necessary because services can register event listeners in their constructors.\n */\nexport function eagerLoad(item: T): T {\n if (item && (item as any)[isProxy]) {\n for (const value of Object.values(item)) {\n eagerLoad(value);\n }\n }\n return item;\n}\n\n/**\n * Helper function that returns an injector by creating a proxy.\n * Invariant: injector is of type I. If injector is undefined, then T = I.\n */\nfunction _inject(module: Module, injector?: any): T {\n const proxy: any = new Proxy({} as any, {\n deleteProperty: () => false,\n get: (obj, prop) => _resolve(obj, prop, module, injector || proxy),\n getOwnPropertyDescriptor: (obj, prop) => (_resolve(obj, prop, module, injector || proxy), Object.getOwnPropertyDescriptor(obj, prop)), // used by for..in\n has: (_, prop) => prop in module, // used by ..in..\n ownKeys: () => [...Reflect.ownKeys(module), isProxy] // used by for..in\n });\n proxy[isProxy] = true;\n return proxy;\n}\n\n/**\n * Internally used to tag a requested dependency, directly before calling the factory.\n * This allows us to find cycles during instance creation.\n */\nconst __requested__ = Symbol();\n\n/**\n * Returns the value `obj[prop]`. If the value does not exist, yet, it is resolved from\n * the module description. The result of service factories is cached. Groups are\n * recursively proxied.\n *\n * @param obj an object holding all group proxies and services\n * @param prop the key of a value within obj\n * @param module an object containing groups and service factories\n * @param injector the first level proxy that provides access to all values\n * @returns the requested value `obj[prop]`\n * @throws Error if a dependency cycle is detected\n */\nfunction _resolve(obj: any, prop: string | symbol | number, module: Module, injector: I): T[keyof T] | undefined {\n if (prop in obj) {\n if (obj[prop] instanceof Error) {\n throw new Error('Construction failure. Please make sure that your dependencies are constructable.', {cause: obj[prop]});\n }\n if (obj[prop] === __requested__) {\n throw new Error('Cycle detected. Please make \"' + String(prop) + '\" lazy. See https://langium.org/docs/configuration-services/#resolving-cyclic-dependencies');\n }\n return obj[prop];\n } else if (prop in module) {\n const value: Module | ((injector: I) => T[keyof T]) = module[prop as keyof T];\n obj[prop] = __requested__;\n try {\n obj[prop] = (typeof value === 'function') ? value(injector) : _inject(value, injector);\n } catch (error) {\n obj[prop] = error instanceof Error ? error : undefined;\n throw error;\n }\n return obj[prop];\n } else {\n return undefined;\n }\n}\n\n/**\n * Performs a deep-merge of two modules by writing source entries into the target module.\n *\n * @param target the module which is written\n * @param source the module which is read\n * @returns the target module\n */\nfunction _merge(target: Module, source?: Module): Module {\n if (source) {\n for (const [key, value2] of Object.entries(source)) {\n if (value2 !== undefined) {\n const value1 = target[key];\n if (value1 !== null && value2 !== null && typeof value1 === 'object' && typeof value2 === 'object') {\n target[key] = _merge(value1, value2);\n } else {\n target[key] = value2;\n }\n }\n }\n }\n return target;\n}\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\n// Ensure that all imports are erased at runtime to avoid circular dependencies.\nimport type { IParserErrorMessageProvider } from 'chevrotain';\nimport type { CommentProvider } from './documentation/comment-provider.js';\nimport type { DocumentationProvider } from './documentation/documentation-provider.js';\nimport type { Grammar } from './languages/generated/ast.js';\nimport type { GrammarConfig } from './languages/grammar-config.js';\nimport type { LanguageMetaData } from './languages/language-meta-data.js';\nimport type { AsyncParser } from './parser/async-parser.js';\nimport type { LangiumCompletionParser, LangiumParser } from './parser/langium-parser.js';\nimport type { Lexer } from './parser/lexer.js';\nimport type { IParserConfig } from './parser/parser-config.js';\nimport type { TokenBuilder } from './parser/token-builder.js';\nimport type { ValueConverter } from './parser/value-converter.js';\nimport type { Linker } from './references/linker.js';\nimport type { NameProvider } from './references/name-provider.js';\nimport type { References } from './references/references.js';\nimport type { ScopeComputation } from './references/scope-computation.js';\nimport type { ScopeProvider } from './references/scope-provider.js';\nimport type { JsonSerializer } from './serializer/json-serializer.js';\nimport type { ServiceRegistry } from './service-registry.js';\nimport type { AstReflection } from './syntax-tree.js';\nimport type { DocumentValidator } from './validation/document-validator.js';\nimport type { ValidationRegistry } from './validation/validation-registry.js';\nimport type { AstNodeDescriptionProvider, ReferenceDescriptionProvider } from './workspace/ast-descriptions.js';\nimport type { AstNodeLocator } from './workspace/ast-node-locator.js';\nimport type { ConfigurationProvider } from './workspace/configuration.js';\nimport type { DocumentBuilder } from './workspace/document-builder.js';\nimport type { LangiumDocumentFactory, LangiumDocuments, TextDocumentProvider } from './workspace/documents.js';\nimport type { FileSystemProvider } from './workspace/file-system-provider.js';\nimport type { IndexManager } from './workspace/index-manager.js';\nimport type { WorkspaceLock } from './workspace/workspace-lock.js';\nimport type { Hydrator } from './serializer/hydrator.js';\nimport type { WorkspaceManager } from './workspace/workspace-manager.js';\n\n/**\n * The services generated by `langium-cli` for a specific language. These are derived from the\n * grammar definition and the language configuration.\n */\nexport type LangiumGeneratedCoreServices = {\n Grammar: Grammar\n LanguageMetaData: LanguageMetaData\n parser: {\n ParserConfig?: IParserConfig\n }\n}\n\n/**\n * Core services for a specific language of which Langium provides default implementations.\n */\nexport type LangiumDefaultCoreServices = {\n parser: {\n AsyncParser: AsyncParser\n GrammarConfig: GrammarConfig\n ValueConverter: ValueConverter\n LangiumParser: LangiumParser\n ParserErrorMessageProvider: IParserErrorMessageProvider\n CompletionParser: LangiumCompletionParser\n TokenBuilder: TokenBuilder\n Lexer: Lexer\n }\n documentation: {\n CommentProvider: CommentProvider\n DocumentationProvider: DocumentationProvider\n }\n references: {\n Linker: Linker\n NameProvider: NameProvider\n References: References\n ScopeProvider: ScopeProvider\n ScopeComputation: ScopeComputation\n }\n serializer: {\n Hydrator: Hydrator\n JsonSerializer: JsonSerializer\n }\n validation: {\n DocumentValidator: DocumentValidator\n ValidationRegistry: ValidationRegistry\n }\n workspace: {\n AstNodeLocator: AstNodeLocator\n AstNodeDescriptionProvider: AstNodeDescriptionProvider\n ReferenceDescriptionProvider: ReferenceDescriptionProvider\n }\n shared: LangiumSharedCoreServices\n}\n\n/**\n * The core set of services available for a language. These are either generated by `langium-cli`\n * or provided as default implementations.\n */\nexport type LangiumCoreServices = LangiumGeneratedCoreServices & LangiumDefaultCoreServices\n\n/**\n * The services generated by `langium-cli` that are shared between multiple languages. These are\n * derived from the grammar definition.\n */\nexport type LangiumGeneratedSharedCoreServices = {\n AstReflection: AstReflection\n}\n\n/**\n * Core services shared between multiple languages where Langium provides default implementations.\n */\nexport type LangiumDefaultSharedCoreServices = {\n ServiceRegistry: ServiceRegistry\n workspace: {\n ConfigurationProvider: ConfigurationProvider\n DocumentBuilder: DocumentBuilder\n FileSystemProvider: FileSystemProvider\n IndexManager: IndexManager\n LangiumDocuments: LangiumDocuments\n LangiumDocumentFactory: LangiumDocumentFactory\n TextDocuments?: TextDocumentProvider\n WorkspaceLock: WorkspaceLock\n WorkspaceManager: WorkspaceManager\n }\n}\n\n/**\n * The shared core services are a set of services that are used by every language within a Langium project (excluding LSP services)\n * This is necessary to enable features like cross references across different languages.\n */\nexport type LangiumSharedCoreServices = LangiumDefaultSharedCoreServices & LangiumGeneratedSharedCoreServices\n\n/**\n * A deep partial type definition for services. We look into T to see whether its type definition contains\n * any methods. If it does, it's one of our services and therefore should not be partialized.\n */\n//eslint-disable-next-line @typescript-eslint/ban-types\nexport type DeepPartial = T[keyof T] extends Function ? T : {\n [P in keyof T]?: DeepPartial;\n}\n\n/**\n * Language-specific core services to be partially overridden via dependency injection.\n */\nexport type PartialLangiumCoreServices = DeepPartial\n\n/**\n * Shared core services to be partially overridden via dependency injection.\n */\nexport type PartialLangiumSharedCoreServices = DeepPartial\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './comment-provider.js';\nexport * from './documentation-provider.js';\nexport * from './jsdoc.js';\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport interface LanguageMetaData {\n languageId: string;\n fileExtensions: readonly string[];\n caseInsensitive: boolean;\n}\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './grammar-config.js';\nexport * from './language-meta-data.js';\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport type { IParserConfig } from 'chevrotain';\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './async-parser.js';\nexport * from './completion-parser-builder.js';\nexport * from './cst-node-builder.js';\nexport * from './langium-parser-builder.js';\nexport * from './langium-parser.js';\nexport * from './lexer.js';\nexport * from './parser-config.js';\nexport * from './token-builder.js';\nexport * from './value-converter.js';\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './linker.js';\nexport * from './name-provider.js';\nexport * from './references.js';\nexport * from './scope.js';\nexport * from './scope-computation.js';\nexport * from './scope-provider.js';\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './hydrator.js';\nexport * from './json-serializer.js';\n", "/******************************************************************************\n * Copyright 2022 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport type { URI } from '../utils/uri-utils.js';\n\nexport interface FileSystemNode {\n readonly isFile: boolean;\n readonly isDirectory: boolean;\n readonly uri: URI;\n}\n\nexport type FileSystemFilter = (node: FileSystemNode) => boolean;\n\n/**\n * Provides methods to interact with an abstract file system. The default implementation is based on the node.js `fs` API.\n */\nexport interface FileSystemProvider {\n /**\n * Reads a document asynchronously from a given URI.\n * @returns The string content of the file with the specified URI.\n */\n readFile(uri: URI): Promise;\n /**\n * Reads the directory information for the given URI.\n * @returns The list of file system entries that are contained within the specified directory.\n */\n readDirectory(uri: URI): Promise;\n}\n\nexport class EmptyFileSystemProvider implements FileSystemProvider {\n\n readFile(): Promise {\n throw new Error('No file system is available.');\n }\n\n async readDirectory(): Promise {\n return [];\n }\n\n}\n\nexport const EmptyFileSystem = {\n fileSystemProvider: () => new EmptyFileSystemProvider()\n};\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nimport { createDefaultCoreModule, createDefaultSharedCoreModule } from '../default-module.js';\nimport type { Module } from '../dependency-injection.js';\nimport { inject } from '../dependency-injection.js';\nimport * as ast from '../languages/generated/ast.js';\nimport type { LangiumCoreServices, LangiumSharedCoreServices, PartialLangiumCoreServices, PartialLangiumSharedCoreServices } from '../services.js';\nimport type { Mutable } from '../syntax-tree.js';\nimport { EmptyFileSystem } from '../workspace/file-system-provider.js';\nimport { URI } from './uri-utils.js';\n\nconst minimalGrammarModule: Module = {\n Grammar: () => undefined as unknown as ast.Grammar,\n LanguageMetaData: () => ({\n caseInsensitive: false,\n fileExtensions: ['.langium'],\n languageId: 'langium'\n })\n};\n\nconst minimalSharedGrammarModule: Module = {\n AstReflection: () => new ast.LangiumGrammarAstReflection()\n};\n\nfunction createMinimalGrammarServices(): LangiumCoreServices {\n const shared = inject(\n createDefaultSharedCoreModule(EmptyFileSystem),\n minimalSharedGrammarModule\n );\n const grammar = inject(\n createDefaultCoreModule({ shared }),\n minimalGrammarModule\n );\n shared.ServiceRegistry.register(grammar);\n return grammar;\n}\n\n/**\n * Load a Langium grammar for your language from a JSON string. This is used by several services,\n * most notably the parser builder which interprets the grammar to create a parser.\n */\nexport function loadGrammarFromJson(json: string): ast.Grammar {\n const services = createMinimalGrammarServices();\n const astNode = services.serializer.JsonSerializer.deserialize(json) as Mutable;\n services.shared.workspace.LangiumDocumentFactory.fromModel(astNode, URI.parse(`memory://${astNode.name ?? 'grammar'}.langium`));\n return astNode;\n}\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './caching.js';\nexport * from './event.js';\nexport * from './collections.js';\nexport * from './disposable.js';\nexport * from './errors.js';\nexport * from './grammar-loader.js';\nexport * from './promise-utils.js';\nexport * from './stream.js';\nexport * from './uri-utils.js';\n\nimport * as AstUtils from './ast-utils.js';\nimport * as Cancellation from './cancellation.js';\nimport * as CstUtils from './cst-utils.js';\nimport * as GrammarUtils from './grammar-utils.js';\nimport * as RegExpUtils from './regexp-utils.js';\nexport { AstUtils, Cancellation, CstUtils, GrammarUtils, RegExpUtils };\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './document-validator.js';\nexport * from './validation-registry.js';\n", "/******************************************************************************\n * Copyright 2023 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './ast-descriptions.js';\nexport * from './ast-node-locator.js';\nexport * from './configuration.js';\nexport * from './document-builder.js';\nexport * from './documents.js';\nexport * from './file-system-provider.js';\nexport * from './index-manager.js';\nexport * from './workspace-lock.js';\nexport * from './workspace-manager.js';\n", "/******************************************************************************\n * Copyright 2021 TypeFox GmbH\n * This program and the accompanying materials are made available under the\n * terms of the MIT License, which is available in the project root.\n ******************************************************************************/\n\nexport * from './default-module.js';\nexport * from './dependency-injection.js';\nexport * from './service-registry.js';\nexport * from './services.js';\nexport * from './syntax-tree.js';\nexport * from './documentation/index.js';\nexport * from './languages/index.js';\nexport * from './parser/index.js';\nexport * from './references/index.js';\nexport * from './serializer/index.js';\nexport * from './utils/index.js';\nexport * from './validation/index.js';\nexport * from './workspace/index.js';\n\n// Export the Langium Grammar AST definitions in the `GrammarAST` namespace\nimport * as GrammarAST from './languages/generated/ast.js';\nimport type { Grammar } from './languages/generated/ast.js';\nexport { Grammar, GrammarAST };\n", "var __defProp = Object.defineProperty;\nvar __name = (target, value) => __defProp(target, \"name\", { value, configurable: true });\n\n// src/language/generated/ast.ts\nimport { AbstractAstReflection } from \"langium\";\nvar Statement = \"Statement\";\nvar Architecture = \"Architecture\";\nfunction isArchitecture(item) {\n return reflection.isInstance(item, Architecture);\n}\n__name(isArchitecture, \"isArchitecture\");\nvar Branch = \"Branch\";\nfunction isBranch(item) {\n return reflection.isInstance(item, Branch);\n}\n__name(isBranch, \"isBranch\");\nvar Checkout = \"Checkout\";\nvar CherryPicking = \"CherryPicking\";\nvar Commit = \"Commit\";\nfunction isCommit(item) {\n return reflection.isInstance(item, Commit);\n}\n__name(isCommit, \"isCommit\");\nvar Common = \"Common\";\nfunction isCommon(item) {\n return reflection.isInstance(item, Common);\n}\n__name(isCommon, \"isCommon\");\nvar GitGraph = \"GitGraph\";\nfunction isGitGraph(item) {\n return reflection.isInstance(item, GitGraph);\n}\n__name(isGitGraph, \"isGitGraph\");\nvar Info = \"Info\";\nfunction isInfo(item) {\n return reflection.isInstance(item, Info);\n}\n__name(isInfo, \"isInfo\");\nvar Merge = \"Merge\";\nfunction isMerge(item) {\n return reflection.isInstance(item, Merge);\n}\n__name(isMerge, \"isMerge\");\nvar Packet = \"Packet\";\nfunction isPacket(item) {\n return reflection.isInstance(item, Packet);\n}\n__name(isPacket, \"isPacket\");\nvar PacketBlock = \"PacketBlock\";\nfunction isPacketBlock(item) {\n return reflection.isInstance(item, PacketBlock);\n}\n__name(isPacketBlock, \"isPacketBlock\");\nvar Pie = \"Pie\";\nfunction isPie(item) {\n return reflection.isInstance(item, Pie);\n}\n__name(isPie, \"isPie\");\nvar PieSection = \"PieSection\";\nfunction isPieSection(item) {\n return reflection.isInstance(item, PieSection);\n}\n__name(isPieSection, \"isPieSection\");\nvar Direction = \"Direction\";\nvar MermaidAstReflection = class extends AbstractAstReflection {\n static {\n __name(this, \"MermaidAstReflection\");\n }\n getAllTypes() {\n return [\"Architecture\", \"Branch\", \"Checkout\", \"CherryPicking\", \"Commit\", \"Common\", \"Direction\", \"Edge\", \"GitGraph\", \"Group\", \"Info\", \"Junction\", \"Merge\", \"Packet\", \"PacketBlock\", \"Pie\", \"PieSection\", \"Service\", \"Statement\"];\n }\n computeIsSubtype(subtype, supertype) {\n switch (subtype) {\n case Branch:\n case Checkout:\n case CherryPicking:\n case Commit:\n case Merge: {\n return this.isSubtype(Statement, supertype);\n }\n case Direction: {\n return this.isSubtype(GitGraph, supertype);\n }\n default: {\n return false;\n }\n }\n }\n getReferenceType(refInfo) {\n const referenceId = `${refInfo.container.$type}:${refInfo.property}`;\n switch (referenceId) {\n default: {\n throw new Error(`${referenceId} is not a valid reference id.`);\n }\n }\n }\n getTypeMetaData(type) {\n switch (type) {\n case \"Architecture\": {\n return {\n name: \"Architecture\",\n properties: [\n { name: \"accDescr\" },\n { name: \"accTitle\" },\n { name: \"edges\", defaultValue: [] },\n { name: \"groups\", defaultValue: [] },\n { name: \"junctions\", defaultValue: [] },\n { name: \"services\", defaultValue: [] },\n { name: \"title\" }\n ]\n };\n }\n case \"Branch\": {\n return {\n name: \"Branch\",\n properties: [\n { name: \"name\" },\n { name: \"order\" }\n ]\n };\n }\n case \"Checkout\": {\n return {\n name: \"Checkout\",\n properties: [\n { name: \"branch\" }\n ]\n };\n }\n case \"CherryPicking\": {\n return {\n name: \"CherryPicking\",\n properties: [\n { name: \"id\" },\n { name: \"parent\" },\n { name: \"tags\", defaultValue: [] }\n ]\n };\n }\n case \"Commit\": {\n return {\n name: \"Commit\",\n properties: [\n { name: \"id\" },\n { name: \"message\" },\n { name: \"tags\", defaultValue: [] },\n { name: \"type\" }\n ]\n };\n }\n case \"Common\": {\n return {\n name: \"Common\",\n properties: [\n { name: \"accDescr\" },\n { name: \"accTitle\" },\n { name: \"title\" }\n ]\n };\n }\n case \"Edge\": {\n return {\n name: \"Edge\",\n properties: [\n { name: \"lhsDir\" },\n { name: \"lhsGroup\", defaultValue: false },\n { name: \"lhsId\" },\n { name: \"lhsInto\", defaultValue: false },\n { name: \"rhsDir\" },\n { name: \"rhsGroup\", defaultValue: false },\n { name: \"rhsId\" },\n { name: \"rhsInto\", defaultValue: false },\n { name: \"title\" }\n ]\n };\n }\n case \"GitGraph\": {\n return {\n name: \"GitGraph\",\n properties: [\n { name: \"accDescr\" },\n { name: \"accTitle\" },\n { name: \"statements\", defaultValue: [] },\n { name: \"title\" }\n ]\n };\n }\n case \"Group\": {\n return {\n name: \"Group\",\n properties: [\n { name: \"icon\" },\n { name: \"id\" },\n { name: \"in\" },\n { name: \"title\" }\n ]\n };\n }\n case \"Info\": {\n return {\n name: \"Info\",\n properties: [\n { name: \"accDescr\" },\n { name: \"accTitle\" },\n { name: \"title\" }\n ]\n };\n }\n case \"Junction\": {\n return {\n name: \"Junction\",\n properties: [\n { name: \"id\" },\n { name: \"in\" }\n ]\n };\n }\n case \"Merge\": {\n return {\n name: \"Merge\",\n properties: [\n { name: \"branch\" },\n { name: \"id\" },\n { name: \"tags\", defaultValue: [] },\n { name: \"type\" }\n ]\n };\n }\n case \"Packet\": {\n return {\n name: \"Packet\",\n properties: [\n { name: \"accDescr\" },\n { name: \"accTitle\" },\n { name: \"blocks\", defaultValue: [] },\n { name: \"title\" }\n ]\n };\n }\n case \"PacketBlock\": {\n return {\n name: \"PacketBlock\",\n properties: [\n { name: \"end\" },\n { name: \"label\" },\n { name: \"start\" }\n ]\n };\n }\n case \"Pie\": {\n return {\n name: \"Pie\",\n properties: [\n { name: \"accDescr\" },\n { name: \"accTitle\" },\n { name: \"sections\", defaultValue: [] },\n { name: \"showData\", defaultValue: false },\n { name: \"title\" }\n ]\n };\n }\n case \"PieSection\": {\n return {\n name: \"PieSection\",\n properties: [\n { name: \"label\" },\n { name: \"value\" }\n ]\n };\n }\n case \"Service\": {\n return {\n name: \"Service\",\n properties: [\n { name: \"icon\" },\n { name: \"iconText\" },\n { name: \"id\" },\n { name: \"in\" },\n { name: \"title\" }\n ]\n };\n }\n case \"Direction\": {\n return {\n name: \"Direction\",\n properties: [\n { name: \"accDescr\" },\n { name: \"accTitle\" },\n { name: \"dir\" },\n { name: \"statements\", defaultValue: [] },\n { name: \"title\" }\n ]\n };\n }\n default: {\n return {\n name: type,\n properties: []\n };\n }\n }\n }\n};\nvar reflection = new MermaidAstReflection();\n\n// src/language/generated/grammar.ts\nimport { loadGrammarFromJson } from \"langium\";\nvar loadedInfoGrammar;\nvar InfoGrammar = /* @__PURE__ */ __name(() => loadedInfoGrammar ?? (loadedInfoGrammar = loadGrammarFromJson('{\"$type\":\"Grammar\",\"isDeclared\":true,\"name\":\"Info\",\"imports\":[],\"rules\":[{\"$type\":\"ParserRule\",\"name\":\"Info\",\"entry\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@3\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"Keyword\",\"value\":\"info\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@3\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"showInfo\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@3\"},\"arguments\":[],\"cardinality\":\"*\"}],\"cardinality\":\"?\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[],\"cardinality\":\"?\"}]},\"definesHiddenTokens\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"TitleAndAccessibilities\",\"fragment\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"accDescr\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@4\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"accTitle\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@5\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"title\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[]}}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[]}],\"cardinality\":\"+\"},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"EOL\",\"fragment\":true,\"dataType\":\"string\",\"definition\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@3\"},\"arguments\":[],\"cardinality\":\"+\"},{\"$type\":\"EndOfFile\"}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"NEWLINE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\r?\\\\\\\\n/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_DESCR\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accDescr(?:[\\\\\\\\t ]*:([^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)|\\\\\\\\s*{([^}]*)})/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accTitle[\\\\\\\\t ]*:(?:[^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*title(?:[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*|)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"WHITESPACE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]+/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"YAML\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/---[\\\\\\\\t ]*\\\\\\\\r?\\\\\\\\n(?:[\\\\\\\\S\\\\\\\\s]*?\\\\\\\\r?\\\\\\\\n)?---(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"DIRECTIVE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%{[\\\\\\\\S\\\\\\\\s]*?}%%(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"SINGLE_LINE_COMMENT\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%[^\\\\\\\\n\\\\\\\\r]*/\"},\"fragment\":false}],\"definesHiddenTokens\":false,\"hiddenTokens\":[],\"interfaces\":[{\"$type\":\"Interface\",\"name\":\"Common\",\"attributes\":[{\"$type\":\"TypeAttribute\",\"name\":\"accDescr\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"accTitle\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"title\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}}],\"superTypes\":[]}],\"types\":[],\"usedGrammars\":[]}')), \"InfoGrammar\");\nvar loadedPacketGrammar;\nvar PacketGrammar = /* @__PURE__ */ __name(() => loadedPacketGrammar ?? (loadedPacketGrammar = loadGrammarFromJson(`{\"$type\":\"Grammar\",\"isDeclared\":true,\"name\":\"Packet\",\"imports\":[],\"rules\":[{\"$type\":\"ParserRule\",\"name\":\"Packet\",\"entry\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"Keyword\",\"value\":\"packet-beta\"},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@4\"},\"arguments\":[]},{\"$type\":\"Assignment\",\"feature\":\"blocks\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]},\"cardinality\":\"*\"}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"+\"},{\"$type\":\"Assignment\",\"feature\":\"blocks\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]},\"cardinality\":\"+\"}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"*\"}]}]},\"definesHiddenTokens\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"PacketBlock\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"start\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[]}},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"-\"},{\"$type\":\"Assignment\",\"feature\":\"end\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[]}}],\"cardinality\":\"?\"},{\"$type\":\"Keyword\",\"value\":\":\"},{\"$type\":\"Assignment\",\"feature\":\"label\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@3\"},\"arguments\":[]}},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@5\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"INT\",\"type\":{\"$type\":\"ReturnType\",\"name\":\"number\"},\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/0|[1-9][0-9]*/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"STRING\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\"[^\\\\\"]*\\\\\"|'[^']*'/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"ParserRule\",\"name\":\"TitleAndAccessibilities\",\"fragment\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"accDescr\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@7\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"accTitle\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@8\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"title\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@9\"},\"arguments\":[]}}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@5\"},\"arguments\":[]}],\"cardinality\":\"+\"},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"EOL\",\"fragment\":true,\"dataType\":\"string\",\"definition\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"+\"},{\"$type\":\"EndOfFile\"}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"NEWLINE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\r?\\\\\\\\n/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_DESCR\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accDescr(?:[\\\\\\\\t ]*:([^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)|\\\\\\\\s*{([^}]*)})/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accTitle[\\\\\\\\t ]*:(?:[^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*title(?:[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*|)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"WHITESPACE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]+/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"YAML\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/---[\\\\\\\\t ]*\\\\\\\\r?\\\\\\\\n(?:[\\\\\\\\S\\\\\\\\s]*?\\\\\\\\r?\\\\\\\\n)?---(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"DIRECTIVE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%{[\\\\\\\\S\\\\\\\\s]*?}%%(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"SINGLE_LINE_COMMENT\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%[^\\\\\\\\n\\\\\\\\r]*/\"},\"fragment\":false}],\"definesHiddenTokens\":false,\"hiddenTokens\":[],\"interfaces\":[{\"$type\":\"Interface\",\"name\":\"Common\",\"attributes\":[{\"$type\":\"TypeAttribute\",\"name\":\"accDescr\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"accTitle\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"title\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}}],\"superTypes\":[]}],\"types\":[],\"usedGrammars\":[]}`)), \"PacketGrammar\");\nvar loadedPieGrammar;\nvar PieGrammar = /* @__PURE__ */ __name(() => loadedPieGrammar ?? (loadedPieGrammar = loadGrammarFromJson('{\"$type\":\"Grammar\",\"isDeclared\":true,\"name\":\"Pie\",\"imports\":[],\"rules\":[{\"$type\":\"ParserRule\",\"name\":\"Pie\",\"entry\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"Keyword\",\"value\":\"pie\"},{\"$type\":\"Assignment\",\"feature\":\"showData\",\"operator\":\"?=\",\"terminal\":{\"$type\":\"Keyword\",\"value\":\"showData\"},\"cardinality\":\"?\"},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@4\"},\"arguments\":[]},{\"$type\":\"Assignment\",\"feature\":\"sections\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]},\"cardinality\":\"*\"}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"+\"},{\"$type\":\"Assignment\",\"feature\":\"sections\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]},\"cardinality\":\"+\"}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"*\"}]}]},\"definesHiddenTokens\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"PieSection\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"label\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[]}},{\"$type\":\"Keyword\",\"value\":\":\"},{\"$type\":\"Assignment\",\"feature\":\"value\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@3\"},\"arguments\":[]}},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@5\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"PIE_SECTION_LABEL\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\"[^\\\\\"]+\\\\\"/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"PIE_SECTION_VALUE\",\"type\":{\"$type\":\"ReturnType\",\"name\":\"number\"},\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/(0|[1-9][0-9]*)(\\\\\\\\.[0-9]+)?/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"ParserRule\",\"name\":\"TitleAndAccessibilities\",\"fragment\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"accDescr\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@7\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"accTitle\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@8\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"title\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@9\"},\"arguments\":[]}}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@5\"},\"arguments\":[]}],\"cardinality\":\"+\"},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"EOL\",\"fragment\":true,\"dataType\":\"string\",\"definition\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[],\"cardinality\":\"+\"},{\"$type\":\"EndOfFile\"}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"NEWLINE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\r?\\\\\\\\n/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_DESCR\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accDescr(?:[\\\\\\\\t ]*:([^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)|\\\\\\\\s*{([^}]*)})/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accTitle[\\\\\\\\t ]*:(?:[^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*title(?:[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*|)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"WHITESPACE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]+/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"YAML\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/---[\\\\\\\\t ]*\\\\\\\\r?\\\\\\\\n(?:[\\\\\\\\S\\\\\\\\s]*?\\\\\\\\r?\\\\\\\\n)?---(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"DIRECTIVE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%{[\\\\\\\\S\\\\\\\\s]*?}%%(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"SINGLE_LINE_COMMENT\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%[^\\\\\\\\n\\\\\\\\r]*/\"},\"fragment\":false}],\"definesHiddenTokens\":false,\"hiddenTokens\":[],\"interfaces\":[{\"$type\":\"Interface\",\"name\":\"Common\",\"attributes\":[{\"$type\":\"TypeAttribute\",\"name\":\"accDescr\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"accTitle\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"title\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}}],\"superTypes\":[]}],\"types\":[],\"usedGrammars\":[]}')), \"PieGrammar\");\nvar loadedArchitectureGrammar;\nvar ArchitectureGrammar = /* @__PURE__ */ __name(() => loadedArchitectureGrammar ?? (loadedArchitectureGrammar = loadGrammarFromJson('{\"$type\":\"Grammar\",\"isDeclared\":true,\"name\":\"Architecture\",\"imports\":[],\"rules\":[{\"$type\":\"ParserRule\",\"name\":\"Architecture\",\"entry\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@18\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"Keyword\",\"value\":\"architecture-beta\"},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@18\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@16\"},\"arguments\":[]}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@18\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[],\"cardinality\":\"*\"}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@18\"},\"arguments\":[],\"cardinality\":\"*\"}]}]},\"definesHiddenTokens\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Statement\",\"fragment\":true,\"definition\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"groups\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@5\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"services\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@6\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"junctions\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@7\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"edges\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@8\"},\"arguments\":[]}}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"LeftPort\",\"fragment\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\":\"},{\"$type\":\"Assignment\",\"feature\":\"lhsDir\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@9\"},\"arguments\":[]}}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"RightPort\",\"fragment\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"rhsDir\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@9\"},\"arguments\":[]}},{\"$type\":\"Keyword\",\"value\":\":\"}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Arrow\",\"fragment\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[]},{\"$type\":\"Assignment\",\"feature\":\"lhsInto\",\"operator\":\"?=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@15\"},\"arguments\":[]},\"cardinality\":\"?\"},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"--\"},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"-\"},{\"$type\":\"Assignment\",\"feature\":\"title\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@13\"},\"arguments\":[]}},{\"$type\":\"Keyword\",\"value\":\"-\"}]}]},{\"$type\":\"Assignment\",\"feature\":\"rhsInto\",\"operator\":\"?=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@15\"},\"arguments\":[]},\"cardinality\":\"?\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@3\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Group\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"group\"},{\"$type\":\"Assignment\",\"feature\":\"id\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@10\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"icon\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@12\"},\"arguments\":[]},\"cardinality\":\"?\"},{\"$type\":\"Assignment\",\"feature\":\"title\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@13\"},\"arguments\":[]},\"cardinality\":\"?\"},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"in\"},{\"$type\":\"Assignment\",\"feature\":\"in\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@10\"},\"arguments\":[]}}],\"cardinality\":\"?\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@17\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Service\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"service\"},{\"$type\":\"Assignment\",\"feature\":\"id\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@10\"},\"arguments\":[]}},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"iconText\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@11\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"icon\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@12\"},\"arguments\":[]}}],\"cardinality\":\"?\"},{\"$type\":\"Assignment\",\"feature\":\"title\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@13\"},\"arguments\":[]},\"cardinality\":\"?\"},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"in\"},{\"$type\":\"Assignment\",\"feature\":\"in\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@10\"},\"arguments\":[]}}],\"cardinality\":\"?\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@17\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Junction\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"junction\"},{\"$type\":\"Assignment\",\"feature\":\"id\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@10\"},\"arguments\":[]}},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"in\"},{\"$type\":\"Assignment\",\"feature\":\"in\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@10\"},\"arguments\":[]}}],\"cardinality\":\"?\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@17\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Edge\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"lhsId\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@10\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"lhsGroup\",\"operator\":\"?=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@14\"},\"arguments\":[]},\"cardinality\":\"?\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@4\"},\"arguments\":[]},{\"$type\":\"Assignment\",\"feature\":\"rhsId\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@10\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"rhsGroup\",\"operator\":\"?=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@14\"},\"arguments\":[]},\"cardinality\":\"?\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@17\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"ARROW_DIRECTION\",\"definition\":{\"$type\":\"TerminalAlternatives\",\"elements\":[{\"$type\":\"TerminalAlternatives\",\"elements\":[{\"$type\":\"TerminalAlternatives\",\"elements\":[{\"$type\":\"CharacterRange\",\"left\":{\"$type\":\"Keyword\",\"value\":\"L\"}},{\"$type\":\"CharacterRange\",\"left\":{\"$type\":\"Keyword\",\"value\":\"R\"}}]},{\"$type\":\"CharacterRange\",\"left\":{\"$type\":\"Keyword\",\"value\":\"T\"}}]},{\"$type\":\"CharacterRange\",\"left\":{\"$type\":\"Keyword\",\"value\":\"B\"}}]},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ARCH_ID\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\w]+/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ARCH_TEXT_ICON\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\(\\\\\"[^\\\\\"]+\\\\\"\\\\\\\\)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ARCH_ICON\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\([\\\\\\\\w-:]+\\\\\\\\)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ARCH_TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\[[\\\\\\\\w ]+\\\\\\\\]/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ARROW_GROUP\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\{group\\\\\\\\}/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ARROW_INTO\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/<|>/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"ParserRule\",\"name\":\"TitleAndAccessibilities\",\"fragment\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"accDescr\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@19\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"accTitle\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"title\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@21\"},\"arguments\":[]}}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@17\"},\"arguments\":[]}],\"cardinality\":\"+\"},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"EOL\",\"fragment\":true,\"dataType\":\"string\",\"definition\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@18\"},\"arguments\":[],\"cardinality\":\"+\"},{\"$type\":\"EndOfFile\"}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"NEWLINE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\r?\\\\\\\\n/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_DESCR\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accDescr(?:[\\\\\\\\t ]*:([^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)|\\\\\\\\s*{([^}]*)})/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accTitle[\\\\\\\\t ]*:(?:[^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*title(?:[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*|)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"WHITESPACE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]+/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"YAML\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/---[\\\\\\\\t ]*\\\\\\\\r?\\\\\\\\n(?:[\\\\\\\\S\\\\\\\\s]*?\\\\\\\\r?\\\\\\\\n)?---(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"DIRECTIVE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%{[\\\\\\\\S\\\\\\\\s]*?}%%(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"SINGLE_LINE_COMMENT\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%[^\\\\\\\\n\\\\\\\\r]*/\"},\"fragment\":false}],\"definesHiddenTokens\":false,\"hiddenTokens\":[],\"interfaces\":[{\"$type\":\"Interface\",\"name\":\"Common\",\"attributes\":[{\"$type\":\"TypeAttribute\",\"name\":\"accDescr\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"accTitle\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"title\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}}],\"superTypes\":[]}],\"types\":[],\"usedGrammars\":[]}')), \"ArchitectureGrammar\");\nvar loadedGitGraphGrammar;\nvar GitGraphGrammar = /* @__PURE__ */ __name(() => loadedGitGraphGrammar ?? (loadedGitGraphGrammar = loadGrammarFromJson(`{\"$type\":\"Grammar\",\"isDeclared\":true,\"name\":\"GitGraph\",\"interfaces\":[{\"$type\":\"Interface\",\"name\":\"Common\",\"attributes\":[{\"$type\":\"TypeAttribute\",\"name\":\"accDescr\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"accTitle\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}},{\"$type\":\"TypeAttribute\",\"name\":\"title\",\"isOptional\":true,\"type\":{\"$type\":\"SimpleType\",\"primitiveType\":\"string\"}}],\"superTypes\":[]}],\"rules\":[{\"$type\":\"ParserRule\",\"name\":\"TitleAndAccessibilities\",\"fragment\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Assignment\",\"feature\":\"accDescr\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@3\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"accTitle\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@4\"},\"arguments\":[]}},{\"$type\":\"Assignment\",\"feature\":\"title\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@5\"},\"arguments\":[]}}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]}],\"cardinality\":\"+\"},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"EOL\",\"fragment\":true,\"dataType\":\"string\",\"definition\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[],\"cardinality\":\"+\"},{\"$type\":\"EndOfFile\"}]},\"definesHiddenTokens\":false,\"entry\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"NEWLINE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\r?\\\\\\\\n/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_DESCR\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accDescr(?:[\\\\\\\\t ]*:([^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)|\\\\\\\\s*{([^}]*)})/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ACC_TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*accTitle[\\\\\\\\t ]*:(?:[^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[^\\\\\\\\n\\\\\\\\r]*)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"TITLE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*title(?:[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*?(?=%%)|[\\\\\\\\t ][^\\\\\\\\n\\\\\\\\r]*|)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"WHITESPACE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]+/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"YAML\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/---[\\\\\\\\t ]*\\\\\\\\r?\\\\\\\\n(?:[\\\\\\\\S\\\\\\\\s]*?\\\\\\\\r?\\\\\\\\n)?---(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"DIRECTIVE\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%{[\\\\\\\\S\\\\\\\\s]*?}%%(?:\\\\\\\\r?\\\\\\\\n|(?!\\\\\\\\S))/\"},\"fragment\":false},{\"$type\":\"TerminalRule\",\"hidden\":true,\"name\":\"SINGLE_LINE_COMMENT\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[\\\\\\\\t ]*%%[^\\\\\\\\n\\\\\\\\r]*/\"},\"fragment\":false},{\"$type\":\"ParserRule\",\"name\":\"GitGraph\",\"entry\":true,\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"gitGraph\"},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"gitGraph\"},{\"$type\":\"Keyword\",\"value\":\":\"}]},{\"$type\":\"Keyword\",\"value\":\"gitGraph:\"},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"gitGraph\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@12\"},\"arguments\":[]},{\"$type\":\"Keyword\",\"value\":\":\"}]}]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[],\"cardinality\":\"*\"},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@0\"},\"arguments\":[]},{\"$type\":\"Assignment\",\"feature\":\"statements\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@11\"},\"arguments\":[]}},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@2\"},\"arguments\":[]}],\"cardinality\":\"*\"}]}]},\"definesHiddenTokens\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Statement\",\"definition\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@13\"},\"arguments\":[]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@14\"},\"arguments\":[]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@15\"},\"arguments\":[]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@16\"},\"arguments\":[]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@17\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Direction\",\"definition\":{\"$type\":\"Assignment\",\"feature\":\"dir\",\"operator\":\"=\",\"terminal\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"LR\"},{\"$type\":\"Keyword\",\"value\":\"TB\"},{\"$type\":\"Keyword\",\"value\":\"BT\"}]}},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Commit\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"commit\"},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"id:\"},{\"$type\":\"Assignment\",\"feature\":\"id\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"msg:\",\"cardinality\":\"?\"},{\"$type\":\"Assignment\",\"feature\":\"message\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"tag:\"},{\"$type\":\"Assignment\",\"feature\":\"tags\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"type:\"},{\"$type\":\"Assignment\",\"feature\":\"type\",\"operator\":\"=\",\"terminal\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"NORMAL\"},{\"$type\":\"Keyword\",\"value\":\"REVERSE\"},{\"$type\":\"Keyword\",\"value\":\"HIGHLIGHT\"}]}}]}],\"cardinality\":\"*\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Branch\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"branch\"},{\"$type\":\"Assignment\",\"feature\":\"name\",\"operator\":\"=\",\"terminal\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@19\"},\"arguments\":[]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}]}},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"order:\"},{\"$type\":\"Assignment\",\"feature\":\"order\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@18\"},\"arguments\":[]}}],\"cardinality\":\"?\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Merge\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"merge\"},{\"$type\":\"Assignment\",\"feature\":\"branch\",\"operator\":\"=\",\"terminal\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@19\"},\"arguments\":[]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}]}},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"id:\"},{\"$type\":\"Assignment\",\"feature\":\"id\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"tag:\"},{\"$type\":\"Assignment\",\"feature\":\"tags\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"type:\"},{\"$type\":\"Assignment\",\"feature\":\"type\",\"operator\":\"=\",\"terminal\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"NORMAL\"},{\"$type\":\"Keyword\",\"value\":\"REVERSE\"},{\"$type\":\"Keyword\",\"value\":\"HIGHLIGHT\"}]}}]}],\"cardinality\":\"*\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"Checkout\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"checkout\"},{\"$type\":\"Keyword\",\"value\":\"switch\"}]},{\"$type\":\"Assignment\",\"feature\":\"branch\",\"operator\":\"=\",\"terminal\":{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@19\"},\"arguments\":[]},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}]}},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"ParserRule\",\"name\":\"CherryPicking\",\"definition\":{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"cherry-pick\"},{\"$type\":\"Alternatives\",\"elements\":[{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"id:\"},{\"$type\":\"Assignment\",\"feature\":\"id\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"tag:\"},{\"$type\":\"Assignment\",\"feature\":\"tags\",\"operator\":\"+=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}}]},{\"$type\":\"Group\",\"elements\":[{\"$type\":\"Keyword\",\"value\":\"parent:\"},{\"$type\":\"Assignment\",\"feature\":\"parent\",\"operator\":\"=\",\"terminal\":{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@20\"},\"arguments\":[]}}]}],\"cardinality\":\"*\"},{\"$type\":\"RuleCall\",\"rule\":{\"$ref\":\"#/rules@1\"},\"arguments\":[]}]},\"definesHiddenTokens\":false,\"entry\":false,\"fragment\":false,\"hiddenTokens\":[],\"parameters\":[],\"wildcard\":false},{\"$type\":\"TerminalRule\",\"name\":\"INT\",\"type\":{\"$type\":\"ReturnType\",\"name\":\"number\"},\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/[0-9]+(?=\\\\\\\\s)/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"ID\",\"type\":{\"$type\":\"ReturnType\",\"name\":\"string\"},\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\\\\w([-\\\\\\\\./\\\\\\\\w]*[-\\\\\\\\w])?/\"},\"fragment\":false,\"hidden\":false},{\"$type\":\"TerminalRule\",\"name\":\"STRING\",\"definition\":{\"$type\":\"RegexToken\",\"regex\":\"/\\\\\"[^\\\\\"]*\\\\\"|'[^']*'/\"},\"fragment\":false,\"hidden\":false}],\"definesHiddenTokens\":false,\"hiddenTokens\":[],\"imports\":[],\"types\":[],\"usedGrammars\":[]}`)), \"GitGraphGrammar\");\n\n// src/language/generated/module.ts\nvar InfoLanguageMetaData = {\n languageId: \"info\",\n fileExtensions: [\".mmd\", \".mermaid\"],\n caseInsensitive: false\n};\nvar PacketLanguageMetaData = {\n languageId: \"packet\",\n fileExtensions: [\".mmd\", \".mermaid\"],\n caseInsensitive: false\n};\nvar PieLanguageMetaData = {\n languageId: \"pie\",\n fileExtensions: [\".mmd\", \".mermaid\"],\n caseInsensitive: false\n};\nvar ArchitectureLanguageMetaData = {\n languageId: \"architecture\",\n fileExtensions: [\".mmd\", \".mermaid\"],\n caseInsensitive: false\n};\nvar GitGraphLanguageMetaData = {\n languageId: \"gitGraph\",\n fileExtensions: [\".mmd\", \".mermaid\"],\n caseInsensitive: false\n};\nvar MermaidGeneratedSharedModule = {\n AstReflection: /* @__PURE__ */ __name(() => new MermaidAstReflection(), \"AstReflection\")\n};\nvar InfoGeneratedModule = {\n Grammar: /* @__PURE__ */ __name(() => InfoGrammar(), \"Grammar\"),\n LanguageMetaData: /* @__PURE__ */ __name(() => InfoLanguageMetaData, \"LanguageMetaData\"),\n parser: {}\n};\nvar PacketGeneratedModule = {\n Grammar: /* @__PURE__ */ __name(() => PacketGrammar(), \"Grammar\"),\n LanguageMetaData: /* @__PURE__ */ __name(() => PacketLanguageMetaData, \"LanguageMetaData\"),\n parser: {}\n};\nvar PieGeneratedModule = {\n Grammar: /* @__PURE__ */ __name(() => PieGrammar(), \"Grammar\"),\n LanguageMetaData: /* @__PURE__ */ __name(() => PieLanguageMetaData, \"LanguageMetaData\"),\n parser: {}\n};\nvar ArchitectureGeneratedModule = {\n Grammar: /* @__PURE__ */ __name(() => ArchitectureGrammar(), \"Grammar\"),\n LanguageMetaData: /* @__PURE__ */ __name(() => ArchitectureLanguageMetaData, \"LanguageMetaData\"),\n parser: {}\n};\nvar GitGraphGeneratedModule = {\n Grammar: /* @__PURE__ */ __name(() => GitGraphGrammar(), \"Grammar\"),\n LanguageMetaData: /* @__PURE__ */ __name(() => GitGraphLanguageMetaData, \"LanguageMetaData\"),\n parser: {}\n};\n\n// src/language/common/valueConverter.ts\nimport { DefaultValueConverter } from \"langium\";\n\n// src/language/common/matcher.ts\nvar accessibilityDescrRegex = /accDescr(?:[\\t ]*:([^\\n\\r]*)|\\s*{([^}]*)})/;\nvar accessibilityTitleRegex = /accTitle[\\t ]*:([^\\n\\r]*)/;\nvar titleRegex = /title([\\t ][^\\n\\r]*|)/;\n\n// src/language/common/valueConverter.ts\nvar rulesRegexes = {\n ACC_DESCR: accessibilityDescrRegex,\n ACC_TITLE: accessibilityTitleRegex,\n TITLE: titleRegex\n};\nvar AbstractMermaidValueConverter = class extends DefaultValueConverter {\n static {\n __name(this, \"AbstractMermaidValueConverter\");\n }\n runConverter(rule, input, cstNode) {\n let value = this.runCommonConverter(rule, input, cstNode);\n if (value === void 0) {\n value = this.runCustomConverter(rule, input, cstNode);\n }\n if (value === void 0) {\n return super.runConverter(rule, input, cstNode);\n }\n return value;\n }\n runCommonConverter(rule, input, _cstNode) {\n const regex = rulesRegexes[rule.name];\n if (regex === void 0) {\n return void 0;\n }\n const match = regex.exec(input);\n if (match === null) {\n return void 0;\n }\n if (match[1] !== void 0) {\n return match[1].trim().replace(/[\\t ]{2,}/gm, \" \");\n }\n if (match[2] !== void 0) {\n return match[2].replace(/^\\s*/gm, \"\").replace(/\\s+$/gm, \"\").replace(/[\\t ]{2,}/gm, \" \").replace(/[\\n\\r]{2,}/gm, \"\\n\");\n }\n return void 0;\n }\n};\nvar CommonValueConverter = class extends AbstractMermaidValueConverter {\n static {\n __name(this, \"CommonValueConverter\");\n }\n runCustomConverter(_rule, _input, _cstNode) {\n return void 0;\n }\n};\n\n// src/language/common/tokenBuilder.ts\nimport { DefaultTokenBuilder } from \"langium\";\nvar AbstractMermaidTokenBuilder = class extends DefaultTokenBuilder {\n static {\n __name(this, \"AbstractMermaidTokenBuilder\");\n }\n constructor(keywords) {\n super();\n this.keywords = new Set(keywords);\n }\n buildKeywordTokens(rules, terminalTokens, options) {\n const tokenTypes = super.buildKeywordTokens(rules, terminalTokens, options);\n tokenTypes.forEach((tokenType) => {\n if (this.keywords.has(tokenType.name) && tokenType.PATTERN !== void 0) {\n tokenType.PATTERN = new RegExp(tokenType.PATTERN.toString() + \"(?:(?=%%)|(?!\\\\S))\");\n }\n });\n return tokenTypes;\n }\n};\nvar CommonTokenBuilder = class extends AbstractMermaidTokenBuilder {\n static {\n __name(this, \"CommonTokenBuilder\");\n }\n};\n\nexport {\n __name,\n Statement,\n Architecture,\n isArchitecture,\n Branch,\n isBranch,\n Commit,\n isCommit,\n isCommon,\n GitGraph,\n isGitGraph,\n Info,\n isInfo,\n Merge,\n isMerge,\n Packet,\n isPacket,\n PacketBlock,\n isPacketBlock,\n Pie,\n isPie,\n PieSection,\n isPieSection,\n MermaidGeneratedSharedModule,\n InfoGeneratedModule,\n PacketGeneratedModule,\n PieGeneratedModule,\n ArchitectureGeneratedModule,\n GitGraphGeneratedModule,\n AbstractMermaidValueConverter,\n CommonValueConverter,\n AbstractMermaidTokenBuilder,\n CommonTokenBuilder\n};\n", "import {\n AbstractMermaidTokenBuilder,\n CommonValueConverter,\n GitGraphGeneratedModule,\n MermaidGeneratedSharedModule,\n __name\n} from \"./chunk-Y27MQZ3U.mjs\";\n\n// src/language/gitGraph/module.ts\nimport {\n inject,\n createDefaultCoreModule,\n createDefaultSharedCoreModule,\n EmptyFileSystem\n} from \"langium\";\n\n// src/language/gitGraph/tokenBuilder.ts\nvar GitGraphTokenBuilder = class extends AbstractMermaidTokenBuilder {\n static {\n __name(this, \"GitGraphTokenBuilder\");\n }\n constructor() {\n super([\"gitGraph\"]);\n }\n};\n\n// src/language/gitGraph/module.ts\nvar GitGraphModule = {\n parser: {\n TokenBuilder: /* @__PURE__ */ __name(() => new GitGraphTokenBuilder(), \"TokenBuilder\"),\n ValueConverter: /* @__PURE__ */ __name(() => new CommonValueConverter(), \"ValueConverter\")\n }\n};\nfunction createGitGraphServices(context = EmptyFileSystem) {\n const shared = inject(\n createDefaultSharedCoreModule(context),\n MermaidGeneratedSharedModule\n );\n const GitGraph = inject(\n createDefaultCoreModule({ shared }),\n GitGraphGeneratedModule,\n GitGraphModule\n );\n shared.ServiceRegistry.register(GitGraph);\n return { shared, GitGraph };\n}\n__name(createGitGraphServices, \"createGitGraphServices\");\n\nexport {\n GitGraphModule,\n createGitGraphServices\n};\n", "import {\n AbstractMermaidTokenBuilder,\n CommonValueConverter,\n InfoGeneratedModule,\n MermaidGeneratedSharedModule,\n __name\n} from \"./chunk-Y27MQZ3U.mjs\";\n\n// src/language/info/module.ts\nimport {\n EmptyFileSystem,\n createDefaultCoreModule,\n createDefaultSharedCoreModule,\n inject\n} from \"langium\";\n\n// src/language/info/tokenBuilder.ts\nvar InfoTokenBuilder = class extends AbstractMermaidTokenBuilder {\n static {\n __name(this, \"InfoTokenBuilder\");\n }\n constructor() {\n super([\"info\", \"showInfo\"]);\n }\n};\n\n// src/language/info/module.ts\nvar InfoModule = {\n parser: {\n TokenBuilder: /* @__PURE__ */ __name(() => new InfoTokenBuilder(), \"TokenBuilder\"),\n ValueConverter: /* @__PURE__ */ __name(() => new CommonValueConverter(), \"ValueConverter\")\n }\n};\nfunction createInfoServices(context = EmptyFileSystem) {\n const shared = inject(\n createDefaultSharedCoreModule(context),\n MermaidGeneratedSharedModule\n );\n const Info = inject(\n createDefaultCoreModule({ shared }),\n InfoGeneratedModule,\n InfoModule\n );\n shared.ServiceRegistry.register(Info);\n return { shared, Info };\n}\n__name(createInfoServices, \"createInfoServices\");\n\nexport {\n InfoModule,\n createInfoServices\n};\n", "import {\n AbstractMermaidTokenBuilder,\n CommonValueConverter,\n MermaidGeneratedSharedModule,\n PacketGeneratedModule,\n __name\n} from \"./chunk-Y27MQZ3U.mjs\";\n\n// src/language/packet/module.ts\nimport {\n EmptyFileSystem,\n createDefaultCoreModule,\n createDefaultSharedCoreModule,\n inject\n} from \"langium\";\n\n// src/language/packet/tokenBuilder.ts\nvar PacketTokenBuilder = class extends AbstractMermaidTokenBuilder {\n static {\n __name(this, \"PacketTokenBuilder\");\n }\n constructor() {\n super([\"packet-beta\"]);\n }\n};\n\n// src/language/packet/module.ts\nvar PacketModule = {\n parser: {\n TokenBuilder: /* @__PURE__ */ __name(() => new PacketTokenBuilder(), \"TokenBuilder\"),\n ValueConverter: /* @__PURE__ */ __name(() => new CommonValueConverter(), \"ValueConverter\")\n }\n};\nfunction createPacketServices(context = EmptyFileSystem) {\n const shared = inject(\n createDefaultSharedCoreModule(context),\n MermaidGeneratedSharedModule\n );\n const Packet = inject(\n createDefaultCoreModule({ shared }),\n PacketGeneratedModule,\n PacketModule\n );\n shared.ServiceRegistry.register(Packet);\n return { shared, Packet };\n}\n__name(createPacketServices, \"createPacketServices\");\n\nexport {\n PacketModule,\n createPacketServices\n};\n", "import {\n AbstractMermaidTokenBuilder,\n AbstractMermaidValueConverter,\n MermaidGeneratedSharedModule,\n PieGeneratedModule,\n __name\n} from \"./chunk-Y27MQZ3U.mjs\";\n\n// src/language/pie/module.ts\nimport {\n EmptyFileSystem,\n createDefaultCoreModule,\n createDefaultSharedCoreModule,\n inject\n} from \"langium\";\n\n// src/language/pie/tokenBuilder.ts\nvar PieTokenBuilder = class extends AbstractMermaidTokenBuilder {\n static {\n __name(this, \"PieTokenBuilder\");\n }\n constructor() {\n super([\"pie\", \"showData\"]);\n }\n};\n\n// src/language/pie/valueConverter.ts\nvar PieValueConverter = class extends AbstractMermaidValueConverter {\n static {\n __name(this, \"PieValueConverter\");\n }\n runCustomConverter(rule, input, _cstNode) {\n if (rule.name !== \"PIE_SECTION_LABEL\") {\n return void 0;\n }\n return input.replace(/\"/g, \"\").trim();\n }\n};\n\n// src/language/pie/module.ts\nvar PieModule = {\n parser: {\n TokenBuilder: /* @__PURE__ */ __name(() => new PieTokenBuilder(), \"TokenBuilder\"),\n ValueConverter: /* @__PURE__ */ __name(() => new PieValueConverter(), \"ValueConverter\")\n }\n};\nfunction createPieServices(context = EmptyFileSystem) {\n const shared = inject(\n createDefaultSharedCoreModule(context),\n MermaidGeneratedSharedModule\n );\n const Pie = inject(\n createDefaultCoreModule({ shared }),\n PieGeneratedModule,\n PieModule\n );\n shared.ServiceRegistry.register(Pie);\n return { shared, Pie };\n}\n__name(createPieServices, \"createPieServices\");\n\nexport {\n PieModule,\n createPieServices\n};\n", "import {\n AbstractMermaidTokenBuilder,\n AbstractMermaidValueConverter,\n ArchitectureGeneratedModule,\n MermaidGeneratedSharedModule,\n __name\n} from \"./chunk-Y27MQZ3U.mjs\";\n\n// src/language/architecture/module.ts\nimport {\n EmptyFileSystem,\n createDefaultCoreModule,\n createDefaultSharedCoreModule,\n inject\n} from \"langium\";\n\n// src/language/architecture/tokenBuilder.ts\nvar ArchitectureTokenBuilder = class extends AbstractMermaidTokenBuilder {\n static {\n __name(this, \"ArchitectureTokenBuilder\");\n }\n constructor() {\n super([\"architecture\"]);\n }\n};\n\n// src/language/architecture/valueConverter.ts\nvar ArchitectureValueConverter = class extends AbstractMermaidValueConverter {\n static {\n __name(this, \"ArchitectureValueConverter\");\n }\n runCustomConverter(rule, input, _cstNode) {\n if (rule.name === \"ARCH_ICON\") {\n return input.replace(/[()]/g, \"\").trim();\n } else if (rule.name === \"ARCH_TEXT_ICON\") {\n return input.replace(/[\"()]/g, \"\");\n } else if (rule.name === \"ARCH_TITLE\") {\n return input.replace(/[[\\]]/g, \"\").trim();\n }\n return void 0;\n }\n};\n\n// src/language/architecture/module.ts\nvar ArchitectureModule = {\n parser: {\n TokenBuilder: /* @__PURE__ */ __name(() => new ArchitectureTokenBuilder(), \"TokenBuilder\"),\n ValueConverter: /* @__PURE__ */ __name(() => new ArchitectureValueConverter(), \"ValueConverter\")\n }\n};\nfunction createArchitectureServices(context = EmptyFileSystem) {\n const shared = inject(\n createDefaultSharedCoreModule(context),\n MermaidGeneratedSharedModule\n );\n const Architecture = inject(\n createDefaultCoreModule({ shared }),\n ArchitectureGeneratedModule,\n ArchitectureModule\n );\n shared.ServiceRegistry.register(Architecture);\n return { shared, Architecture };\n}\n__name(createArchitectureServices, \"createArchitectureServices\");\n\nexport {\n ArchitectureModule,\n createArchitectureServices\n};\n", "import {\n InfoModule,\n createInfoServices\n} from \"./chunk-4YFB5VUC.mjs\";\nimport \"./chunk-Y27MQZ3U.mjs\";\nexport {\n InfoModule,\n createInfoServices\n};\n", "import {\n PacketModule,\n createPacketServices\n} from \"./chunk-EQFLFMNE.mjs\";\nimport \"./chunk-Y27MQZ3U.mjs\";\nexport {\n PacketModule,\n createPacketServices\n};\n", "import {\n PieModule,\n createPieServices\n} from \"./chunk-BI6EQKOQ.mjs\";\nimport \"./chunk-Y27MQZ3U.mjs\";\nexport {\n PieModule,\n createPieServices\n};\n", "import {\n ArchitectureModule,\n createArchitectureServices\n} from \"./chunk-FF7BQXOH.mjs\";\nimport \"./chunk-Y27MQZ3U.mjs\";\nexport {\n ArchitectureModule,\n createArchitectureServices\n};\n", "import {\n GitGraphModule,\n createGitGraphServices\n} from \"./chunk-NCMFTTUW.mjs\";\nimport \"./chunk-Y27MQZ3U.mjs\";\nexport {\n GitGraphModule,\n createGitGraphServices\n};\n", "import {\n GitGraphModule,\n createGitGraphServices\n} from \"./chunks/mermaid-parser.core/chunk-NCMFTTUW.mjs\";\nimport {\n InfoModule,\n createInfoServices\n} from \"./chunks/mermaid-parser.core/chunk-4YFB5VUC.mjs\";\nimport {\n PacketModule,\n createPacketServices\n} from \"./chunks/mermaid-parser.core/chunk-EQFLFMNE.mjs\";\nimport {\n PieModule,\n createPieServices\n} from \"./chunks/mermaid-parser.core/chunk-BI6EQKOQ.mjs\";\nimport {\n ArchitectureModule,\n createArchitectureServices\n} from \"./chunks/mermaid-parser.core/chunk-FF7BQXOH.mjs\";\nimport {\n AbstractMermaidTokenBuilder,\n AbstractMermaidValueConverter,\n Architecture,\n ArchitectureGeneratedModule,\n Branch,\n Commit,\n CommonTokenBuilder,\n CommonValueConverter,\n GitGraph,\n GitGraphGeneratedModule,\n Info,\n InfoGeneratedModule,\n Merge,\n MermaidGeneratedSharedModule,\n Packet,\n PacketBlock,\n PacketGeneratedModule,\n Pie,\n PieGeneratedModule,\n PieSection,\n Statement,\n __name,\n isArchitecture,\n isBranch,\n isCommit,\n isCommon,\n isGitGraph,\n isInfo,\n isMerge,\n isPacket,\n isPacketBlock,\n isPie,\n isPieSection\n} from \"./chunks/mermaid-parser.core/chunk-Y27MQZ3U.mjs\";\n\n// src/parse.ts\nvar parsers = {};\nvar initializers = {\n info: /* @__PURE__ */ __name(async () => {\n const { createInfoServices: createInfoServices2 } = await import(\"./chunks/mermaid-parser.core/info-46DW6VJ7.mjs\");\n const parser = createInfoServices2().Info.parser.LangiumParser;\n parsers.info = parser;\n }, \"info\"),\n packet: /* @__PURE__ */ __name(async () => {\n const { createPacketServices: createPacketServices2 } = await import(\"./chunks/mermaid-parser.core/packet-W2GHVCYJ.mjs\");\n const parser = createPacketServices2().Packet.parser.LangiumParser;\n parsers.packet = parser;\n }, \"packet\"),\n pie: /* @__PURE__ */ __name(async () => {\n const { createPieServices: createPieServices2 } = await import(\"./chunks/mermaid-parser.core/pie-BEWT4RHE.mjs\");\n const parser = createPieServices2().Pie.parser.LangiumParser;\n parsers.pie = parser;\n }, \"pie\"),\n architecture: /* @__PURE__ */ __name(async () => {\n const { createArchitectureServices: createArchitectureServices2 } = await import(\"./chunks/mermaid-parser.core/architecture-I3QFYML2.mjs\");\n const parser = createArchitectureServices2().Architecture.parser.LangiumParser;\n parsers.architecture = parser;\n }, \"architecture\"),\n gitGraph: /* @__PURE__ */ __name(async () => {\n const { createGitGraphServices: createGitGraphServices2 } = await import(\"./chunks/mermaid-parser.core/gitGraph-YCYPL57B.mjs\");\n const parser = createGitGraphServices2().GitGraph.parser.LangiumParser;\n parsers.gitGraph = parser;\n }, \"gitGraph\")\n};\nasync function parse(diagramType, text) {\n const initializer = initializers[diagramType];\n if (!initializer) {\n throw new Error(`Unknown diagram type: ${diagramType}`);\n }\n if (!parsers[diagramType]) {\n await initializer();\n }\n const parser = parsers[diagramType];\n const result = parser.parse(text);\n if (result.lexerErrors.length > 0 || result.parserErrors.length > 0) {\n throw new MermaidParseError(result);\n }\n return result.value;\n}\n__name(parse, \"parse\");\nvar MermaidParseError = class extends Error {\n constructor(result) {\n const lexerErrors = result.lexerErrors.map((err) => err.message).join(\"\\n\");\n const parserErrors = result.parserErrors.map((err) => err.message).join(\"\\n\");\n super(`Parsing failed: ${lexerErrors} ${parserErrors}`);\n this.result = result;\n }\n static {\n __name(this, \"MermaidParseError\");\n }\n};\nexport {\n AbstractMermaidTokenBuilder,\n AbstractMermaidValueConverter,\n Architecture,\n ArchitectureGeneratedModule,\n ArchitectureModule,\n Branch,\n Commit,\n CommonTokenBuilder,\n CommonValueConverter,\n GitGraph,\n GitGraphGeneratedModule,\n GitGraphModule,\n Info,\n InfoGeneratedModule,\n InfoModule,\n Merge,\n MermaidGeneratedSharedModule,\n MermaidParseError,\n Packet,\n PacketBlock,\n PacketGeneratedModule,\n PacketModule,\n Pie,\n PieGeneratedModule,\n PieModule,\n PieSection,\n Statement,\n createArchitectureServices,\n createGitGraphServices,\n createInfoServices,\n createPacketServices,\n createPieServices,\n isArchitecture,\n isBranch,\n isCommit,\n isCommon,\n isGitGraph,\n isInfo,\n isMerge,\n isPacket,\n isPacketBlock,\n isPie,\n isPieSection,\n parse\n};\n", "import {\n populateCommonDb\n} from \"./chunk-OQCM5LHU.mjs\";\nimport {\n ImperativeState\n} from \"./chunk-2RYQ3QTB.mjs\";\nimport {\n cleanAndMerge,\n random,\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n clear,\n common_default,\n defaultConfig_default,\n getAccDescription,\n getAccTitle,\n getConfig,\n getConfig2,\n getDiagramTitle,\n log,\n setAccDescription,\n setAccTitle,\n setDiagramTitle,\n setupGraphViewbox2 as setupGraphViewbox\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/git/gitGraphParser.ts\nimport { parse } from \"@mermaid-js/parser\";\n\n// src/diagrams/git/gitGraphTypes.ts\nvar commitType = {\n NORMAL: 0,\n REVERSE: 1,\n HIGHLIGHT: 2,\n MERGE: 3,\n CHERRY_PICK: 4\n};\n\n// src/diagrams/git/gitGraphAst.ts\nvar DEFAULT_GITGRAPH_CONFIG = defaultConfig_default.gitGraph;\nvar getConfig3 = /* @__PURE__ */ __name(() => {\n const config = cleanAndMerge({\n ...DEFAULT_GITGRAPH_CONFIG,\n ...getConfig().gitGraph\n });\n return config;\n}, \"getConfig\");\nvar state = new ImperativeState(() => {\n const config = getConfig3();\n const mainBranchName = config.mainBranchName;\n const mainBranchOrder = config.mainBranchOrder;\n return {\n mainBranchName,\n commits: /* @__PURE__ */ new Map(),\n head: null,\n branchConfig: /* @__PURE__ */ new Map([[mainBranchName, { name: mainBranchName, order: mainBranchOrder }]]),\n branches: /* @__PURE__ */ new Map([[mainBranchName, null]]),\n currBranch: mainBranchName,\n direction: \"LR\",\n seq: 0,\n options: {}\n };\n});\nfunction getID() {\n return random({ length: 7 });\n}\n__name(getID, \"getID\");\nfunction uniqBy(list, fn) {\n const recordMap = /* @__PURE__ */ Object.create(null);\n return list.reduce((out, item) => {\n const key = fn(item);\n if (!recordMap[key]) {\n recordMap[key] = true;\n out.push(item);\n }\n return out;\n }, []);\n}\n__name(uniqBy, \"uniqBy\");\nvar setDirection = /* @__PURE__ */ __name(function(dir2) {\n state.records.direction = dir2;\n}, \"setDirection\");\nvar setOptions = /* @__PURE__ */ __name(function(rawOptString) {\n log.debug(\"options str\", rawOptString);\n rawOptString = rawOptString?.trim();\n rawOptString = rawOptString || \"{}\";\n try {\n state.records.options = JSON.parse(rawOptString);\n } catch (e) {\n log.error(\"error while parsing gitGraph options\", e.message);\n }\n}, \"setOptions\");\nvar getOptions = /* @__PURE__ */ __name(function() {\n return state.records.options;\n}, \"getOptions\");\nvar commit = /* @__PURE__ */ __name(function(commitDB) {\n let msg = commitDB.msg;\n let id = commitDB.id;\n const type = commitDB.type;\n let tags = commitDB.tags;\n log.info(\"commit\", msg, id, type, tags);\n log.debug(\"Entering commit:\", msg, id, type, tags);\n const config = getConfig3();\n id = common_default.sanitizeText(id, config);\n msg = common_default.sanitizeText(msg, config);\n tags = tags?.map((tag) => common_default.sanitizeText(tag, config));\n const newCommit = {\n id: id ? id : state.records.seq + \"-\" + getID(),\n message: msg,\n seq: state.records.seq++,\n type: type ?? commitType.NORMAL,\n tags: tags ?? [],\n parents: state.records.head == null ? [] : [state.records.head.id],\n branch: state.records.currBranch\n };\n state.records.head = newCommit;\n log.info(\"main branch\", config.mainBranchName);\n state.records.commits.set(newCommit.id, newCommit);\n state.records.branches.set(state.records.currBranch, newCommit.id);\n log.debug(\"in pushCommit \" + newCommit.id);\n}, \"commit\");\nvar branch = /* @__PURE__ */ __name(function(branchDB) {\n let name = branchDB.name;\n const order = branchDB.order;\n name = common_default.sanitizeText(name, getConfig3());\n if (state.records.branches.has(name)) {\n throw new Error(\n `Trying to create an existing branch. (Help: Either use a new name if you want create a new branch or try using \"checkout ${name}\")`\n );\n }\n state.records.branches.set(name, state.records.head != null ? state.records.head.id : null);\n state.records.branchConfig.set(name, { name, order });\n checkout(name);\n log.debug(\"in createBranch\");\n}, \"branch\");\nvar merge = /* @__PURE__ */ __name((mergeDB) => {\n let otherBranch = mergeDB.branch;\n let customId = mergeDB.id;\n const overrideType = mergeDB.type;\n const customTags = mergeDB.tags;\n const config = getConfig3();\n otherBranch = common_default.sanitizeText(otherBranch, config);\n if (customId) {\n customId = common_default.sanitizeText(customId, config);\n }\n const currentBranchCheck = state.records.branches.get(state.records.currBranch);\n const otherBranchCheck = state.records.branches.get(otherBranch);\n const currentCommit = currentBranchCheck ? state.records.commits.get(currentBranchCheck) : void 0;\n const otherCommit = otherBranchCheck ? state.records.commits.get(otherBranchCheck) : void 0;\n if (currentCommit && otherCommit && currentCommit.branch === otherBranch) {\n throw new Error(`Cannot merge branch '${otherBranch}' into itself.`);\n }\n if (state.records.currBranch === otherBranch) {\n const error = new Error('Incorrect usage of \"merge\". Cannot merge a branch to itself');\n error.hash = {\n text: `merge ${otherBranch}`,\n token: `merge ${otherBranch}`,\n expected: [\"branch abc\"]\n };\n throw error;\n }\n if (currentCommit === void 0 || !currentCommit) {\n const error = new Error(\n `Incorrect usage of \"merge\". Current branch (${state.records.currBranch})has no commits`\n );\n error.hash = {\n text: `merge ${otherBranch}`,\n token: `merge ${otherBranch}`,\n expected: [\"commit\"]\n };\n throw error;\n }\n if (!state.records.branches.has(otherBranch)) {\n const error = new Error(\n 'Incorrect usage of \"merge\". Branch to be merged (' + otherBranch + \") does not exist\"\n );\n error.hash = {\n text: `merge ${otherBranch}`,\n token: `merge ${otherBranch}`,\n expected: [`branch ${otherBranch}`]\n };\n throw error;\n }\n if (otherCommit === void 0 || !otherCommit) {\n const error = new Error(\n 'Incorrect usage of \"merge\". Branch to be merged (' + otherBranch + \") has no commits\"\n );\n error.hash = {\n text: `merge ${otherBranch}`,\n token: `merge ${otherBranch}`,\n expected: ['\"commit\"']\n };\n throw error;\n }\n if (currentCommit === otherCommit) {\n const error = new Error('Incorrect usage of \"merge\". Both branches have same head');\n error.hash = {\n text: `merge ${otherBranch}`,\n token: `merge ${otherBranch}`,\n expected: [\"branch abc\"]\n };\n throw error;\n }\n if (customId && state.records.commits.has(customId)) {\n const error = new Error(\n 'Incorrect usage of \"merge\". Commit with id:' + customId + \" already exists, use different custom Id\"\n );\n error.hash = {\n text: `merge ${otherBranch} ${customId} ${overrideType} ${customTags?.join(\" \")}`,\n token: `merge ${otherBranch} ${customId} ${overrideType} ${customTags?.join(\" \")}`,\n expected: [\n `merge ${otherBranch} ${customId}_UNIQUE ${overrideType} ${customTags?.join(\" \")}`\n ]\n };\n throw error;\n }\n const verifiedBranch = otherBranchCheck ? otherBranchCheck : \"\";\n const commit2 = {\n id: customId || `${state.records.seq}-${getID()}`,\n message: `merged branch ${otherBranch} into ${state.records.currBranch}`,\n seq: state.records.seq++,\n parents: state.records.head == null ? [] : [state.records.head.id, verifiedBranch],\n branch: state.records.currBranch,\n type: commitType.MERGE,\n customType: overrideType,\n customId: customId ? true : false,\n tags: customTags ?? []\n };\n state.records.head = commit2;\n state.records.commits.set(commit2.id, commit2);\n state.records.branches.set(state.records.currBranch, commit2.id);\n log.debug(state.records.branches);\n log.debug(\"in mergeBranch\");\n}, \"merge\");\nvar cherryPick = /* @__PURE__ */ __name(function(cherryPickDB) {\n let sourceId = cherryPickDB.id;\n let targetId = cherryPickDB.targetId;\n let tags = cherryPickDB.tags;\n let parentCommitId = cherryPickDB.parent;\n log.debug(\"Entering cherryPick:\", sourceId, targetId, tags);\n const config = getConfig3();\n sourceId = common_default.sanitizeText(sourceId, config);\n targetId = common_default.sanitizeText(targetId, config);\n tags = tags?.map((tag) => common_default.sanitizeText(tag, config));\n parentCommitId = common_default.sanitizeText(parentCommitId, config);\n if (!sourceId || !state.records.commits.has(sourceId)) {\n const error = new Error(\n 'Incorrect usage of \"cherryPick\". Source commit id should exist and provided'\n );\n error.hash = {\n text: `cherryPick ${sourceId} ${targetId}`,\n token: `cherryPick ${sourceId} ${targetId}`,\n expected: [\"cherry-pick abc\"]\n };\n throw error;\n }\n const sourceCommit = state.records.commits.get(sourceId);\n if (sourceCommit === void 0 || !sourceCommit) {\n throw new Error('Incorrect usage of \"cherryPick\". Source commit id should exist and provided');\n }\n if (parentCommitId && !(Array.isArray(sourceCommit.parents) && sourceCommit.parents.includes(parentCommitId))) {\n const error = new Error(\n \"Invalid operation: The specified parent commit is not an immediate parent of the cherry-picked commit.\"\n );\n throw error;\n }\n const sourceCommitBranch = sourceCommit.branch;\n if (sourceCommit.type === commitType.MERGE && !parentCommitId) {\n const error = new Error(\n \"Incorrect usage of cherry-pick: If the source commit is a merge commit, an immediate parent commit must be specified.\"\n );\n throw error;\n }\n if (!targetId || !state.records.commits.has(targetId)) {\n if (sourceCommitBranch === state.records.currBranch) {\n const error = new Error(\n 'Incorrect usage of \"cherryPick\". Source commit is already on current branch'\n );\n error.hash = {\n text: `cherryPick ${sourceId} ${targetId}`,\n token: `cherryPick ${sourceId} ${targetId}`,\n expected: [\"cherry-pick abc\"]\n };\n throw error;\n }\n const currentCommitId = state.records.branches.get(state.records.currBranch);\n if (currentCommitId === void 0 || !currentCommitId) {\n const error = new Error(\n `Incorrect usage of \"cherry-pick\". Current branch (${state.records.currBranch})has no commits`\n );\n error.hash = {\n text: `cherryPick ${sourceId} ${targetId}`,\n token: `cherryPick ${sourceId} ${targetId}`,\n expected: [\"cherry-pick abc\"]\n };\n throw error;\n }\n const currentCommit = state.records.commits.get(currentCommitId);\n if (currentCommit === void 0 || !currentCommit) {\n const error = new Error(\n `Incorrect usage of \"cherry-pick\". Current branch (${state.records.currBranch})has no commits`\n );\n error.hash = {\n text: `cherryPick ${sourceId} ${targetId}`,\n token: `cherryPick ${sourceId} ${targetId}`,\n expected: [\"cherry-pick abc\"]\n };\n throw error;\n }\n const commit2 = {\n id: state.records.seq + \"-\" + getID(),\n message: `cherry-picked ${sourceCommit?.message} into ${state.records.currBranch}`,\n seq: state.records.seq++,\n parents: state.records.head == null ? [] : [state.records.head.id, sourceCommit.id],\n branch: state.records.currBranch,\n type: commitType.CHERRY_PICK,\n tags: tags ? tags.filter(Boolean) : [\n `cherry-pick:${sourceCommit.id}${sourceCommit.type === commitType.MERGE ? `|parent:${parentCommitId}` : \"\"}`\n ]\n };\n state.records.head = commit2;\n state.records.commits.set(commit2.id, commit2);\n state.records.branches.set(state.records.currBranch, commit2.id);\n log.debug(state.records.branches);\n log.debug(\"in cherryPick\");\n }\n}, \"cherryPick\");\nvar checkout = /* @__PURE__ */ __name(function(branch2) {\n branch2 = common_default.sanitizeText(branch2, getConfig3());\n if (!state.records.branches.has(branch2)) {\n const error = new Error(\n `Trying to checkout branch which is not yet created. (Help try using \"branch ${branch2}\")`\n );\n error.hash = {\n text: `checkout ${branch2}`,\n token: `checkout ${branch2}`,\n expected: [`branch ${branch2}`]\n };\n throw error;\n } else {\n state.records.currBranch = branch2;\n const id = state.records.branches.get(state.records.currBranch);\n if (id === void 0 || !id) {\n state.records.head = null;\n } else {\n state.records.head = state.records.commits.get(id) ?? null;\n }\n }\n}, \"checkout\");\nfunction upsert(arr, key, newVal) {\n const index = arr.indexOf(key);\n if (index === -1) {\n arr.push(newVal);\n } else {\n arr.splice(index, 1, newVal);\n }\n}\n__name(upsert, \"upsert\");\nfunction prettyPrintCommitHistory(commitArr) {\n const commit2 = commitArr.reduce((out, commit3) => {\n if (out.seq > commit3.seq) {\n return out;\n }\n return commit3;\n }, commitArr[0]);\n let line = \"\";\n commitArr.forEach(function(c) {\n if (c === commit2) {\n line += \"\t*\";\n } else {\n line += \"\t|\";\n }\n });\n const label = [line, commit2.id, commit2.seq];\n for (const branch2 in state.records.branches) {\n if (state.records.branches.get(branch2) === commit2.id) {\n label.push(branch2);\n }\n }\n log.debug(label.join(\" \"));\n if (commit2.parents && commit2.parents.length == 2 && commit2.parents[0] && commit2.parents[1]) {\n const newCommit = state.records.commits.get(commit2.parents[0]);\n upsert(commitArr, commit2, newCommit);\n if (commit2.parents[1]) {\n commitArr.push(state.records.commits.get(commit2.parents[1]));\n }\n } else if (commit2.parents.length == 0) {\n return;\n } else {\n if (commit2.parents[0]) {\n const newCommit = state.records.commits.get(commit2.parents[0]);\n upsert(commitArr, commit2, newCommit);\n }\n }\n commitArr = uniqBy(commitArr, (c) => c.id);\n prettyPrintCommitHistory(commitArr);\n}\n__name(prettyPrintCommitHistory, \"prettyPrintCommitHistory\");\nvar prettyPrint = /* @__PURE__ */ __name(function() {\n log.debug(state.records.commits);\n const node = getCommitsArray()[0];\n prettyPrintCommitHistory([node]);\n}, \"prettyPrint\");\nvar clear2 = /* @__PURE__ */ __name(function() {\n state.reset();\n clear();\n}, \"clear\");\nvar getBranchesAsObjArray = /* @__PURE__ */ __name(function() {\n const branchesArray = [...state.records.branchConfig.values()].map((branchConfig, i) => {\n if (branchConfig.order !== null && branchConfig.order !== void 0) {\n return branchConfig;\n }\n return {\n ...branchConfig,\n order: parseFloat(`0.${i}`)\n };\n }).sort((a, b) => (a.order ?? 0) - (b.order ?? 0)).map(({ name }) => ({ name }));\n return branchesArray;\n}, \"getBranchesAsObjArray\");\nvar getBranches = /* @__PURE__ */ __name(function() {\n return state.records.branches;\n}, \"getBranches\");\nvar getCommits = /* @__PURE__ */ __name(function() {\n return state.records.commits;\n}, \"getCommits\");\nvar getCommitsArray = /* @__PURE__ */ __name(function() {\n const commitArr = [...state.records.commits.values()];\n commitArr.forEach(function(o) {\n log.debug(o.id);\n });\n commitArr.sort((a, b) => a.seq - b.seq);\n return commitArr;\n}, \"getCommitsArray\");\nvar getCurrentBranch = /* @__PURE__ */ __name(function() {\n return state.records.currBranch;\n}, \"getCurrentBranch\");\nvar getDirection = /* @__PURE__ */ __name(function() {\n return state.records.direction;\n}, \"getDirection\");\nvar getHead = /* @__PURE__ */ __name(function() {\n return state.records.head;\n}, \"getHead\");\nvar db = {\n commitType,\n getConfig: getConfig3,\n setDirection,\n setOptions,\n getOptions,\n commit,\n branch,\n merge,\n cherryPick,\n checkout,\n //reset,\n prettyPrint,\n clear: clear2,\n getBranchesAsObjArray,\n getBranches,\n getCommits,\n getCommitsArray,\n getCurrentBranch,\n getDirection,\n getHead,\n setAccTitle,\n getAccTitle,\n getAccDescription,\n setAccDescription,\n setDiagramTitle,\n getDiagramTitle\n};\n\n// src/diagrams/git/gitGraphParser.ts\nvar populate = /* @__PURE__ */ __name((ast, db2) => {\n populateCommonDb(ast, db2);\n if (ast.dir) {\n db2.setDirection(ast.dir);\n }\n for (const statement of ast.statements) {\n parseStatement(statement, db2);\n }\n}, \"populate\");\nvar parseStatement = /* @__PURE__ */ __name((statement, db2) => {\n const parsers = {\n Commit: /* @__PURE__ */ __name((stmt) => db2.commit(parseCommit(stmt)), \"Commit\"),\n Branch: /* @__PURE__ */ __name((stmt) => db2.branch(parseBranch(stmt)), \"Branch\"),\n Merge: /* @__PURE__ */ __name((stmt) => db2.merge(parseMerge(stmt)), \"Merge\"),\n Checkout: /* @__PURE__ */ __name((stmt) => db2.checkout(parseCheckout(stmt)), \"Checkout\"),\n CherryPicking: /* @__PURE__ */ __name((stmt) => db2.cherryPick(parseCherryPicking(stmt)), \"CherryPicking\")\n };\n const parser2 = parsers[statement.$type];\n if (parser2) {\n parser2(statement);\n } else {\n log.error(`Unknown statement type: ${statement.$type}`);\n }\n}, \"parseStatement\");\nvar parseCommit = /* @__PURE__ */ __name((commit2) => {\n const commitDB = {\n id: commit2.id,\n msg: commit2.message ?? \"\",\n type: commit2.type !== void 0 ? commitType[commit2.type] : commitType.NORMAL,\n tags: commit2.tags ?? void 0\n };\n return commitDB;\n}, \"parseCommit\");\nvar parseBranch = /* @__PURE__ */ __name((branch2) => {\n const branchDB = {\n name: branch2.name,\n order: branch2.order ?? 0\n };\n return branchDB;\n}, \"parseBranch\");\nvar parseMerge = /* @__PURE__ */ __name((merge2) => {\n const mergeDB = {\n branch: merge2.branch,\n id: merge2.id ?? \"\",\n type: merge2.type !== void 0 ? commitType[merge2.type] : void 0,\n tags: merge2.tags ?? void 0\n };\n return mergeDB;\n}, \"parseMerge\");\nvar parseCheckout = /* @__PURE__ */ __name((checkout2) => {\n const branch2 = checkout2.branch;\n return branch2;\n}, \"parseCheckout\");\nvar parseCherryPicking = /* @__PURE__ */ __name((cherryPicking) => {\n const cherryPickDB = {\n id: cherryPicking.id,\n targetId: \"\",\n tags: cherryPicking.tags?.length === 0 ? void 0 : cherryPicking.tags,\n parent: cherryPicking.parent\n };\n return cherryPickDB;\n}, \"parseCherryPicking\");\nvar parser = {\n parse: /* @__PURE__ */ __name(async (input) => {\n const ast = await parse(\"gitGraph\", input);\n log.debug(ast);\n populate(ast, db);\n }, \"parse\")\n};\nif (void 0) {\n const { it, expect, describe } = void 0;\n const mockDB = {\n commitType,\n setDirection: vi.fn(),\n commit: vi.fn(),\n branch: vi.fn(),\n merge: vi.fn(),\n cherryPick: vi.fn(),\n checkout: vi.fn()\n };\n describe(\"GitGraph Parser\", () => {\n it(\"should parse a commit statement\", () => {\n const commit2 = {\n $type: \"Commit\",\n id: \"1\",\n message: \"test\",\n tags: [\"tag1\", \"tag2\"],\n type: \"NORMAL\"\n };\n parseStatement(commit2, mockDB);\n expect(mockDB.commit).toHaveBeenCalledWith({\n id: \"1\",\n msg: \"test\",\n tags: [\"tag1\", \"tag2\"],\n type: 0\n });\n });\n it(\"should parse a branch statement\", () => {\n const branch2 = {\n $type: \"Branch\",\n name: \"newBranch\",\n order: 1\n };\n parseStatement(branch2, mockDB);\n expect(mockDB.branch).toHaveBeenCalledWith({ name: \"newBranch\", order: 1 });\n });\n it(\"should parse a checkout statement\", () => {\n const checkout2 = {\n $type: \"Checkout\",\n branch: \"newBranch\"\n };\n parseStatement(checkout2, mockDB);\n expect(mockDB.checkout).toHaveBeenCalledWith(\"newBranch\");\n });\n it(\"should parse a merge statement\", () => {\n const merge2 = {\n $type: \"Merge\",\n branch: \"newBranch\",\n id: \"1\",\n tags: [\"tag1\", \"tag2\"],\n type: \"NORMAL\"\n };\n parseStatement(merge2, mockDB);\n expect(mockDB.merge).toHaveBeenCalledWith({\n branch: \"newBranch\",\n id: \"1\",\n tags: [\"tag1\", \"tag2\"],\n type: 0\n });\n });\n it(\"should parse a cherry picking statement\", () => {\n const cherryPick2 = {\n $type: \"CherryPicking\",\n id: \"1\",\n tags: [\"tag1\", \"tag2\"],\n parent: \"2\"\n };\n parseStatement(cherryPick2, mockDB);\n expect(mockDB.cherryPick).toHaveBeenCalledWith({\n id: \"1\",\n targetId: \"\",\n parent: \"2\",\n tags: [\"tag1\", \"tag2\"]\n });\n });\n it(\"should parse a langium generated gitGraph ast\", () => {\n const dummy = {\n $type: \"GitGraph\",\n statements: []\n };\n const gitGraphAst = {\n $type: \"GitGraph\",\n statements: [\n {\n $container: dummy,\n $type: \"Commit\",\n id: \"1\",\n message: \"test\",\n tags: [\"tag1\", \"tag2\"],\n type: \"NORMAL\"\n },\n {\n $container: dummy,\n $type: \"Branch\",\n name: \"newBranch\",\n order: 1\n },\n {\n $container: dummy,\n $type: \"Merge\",\n branch: \"newBranch\",\n id: \"1\",\n tags: [\"tag1\", \"tag2\"],\n type: \"NORMAL\"\n },\n {\n $container: dummy,\n $type: \"Checkout\",\n branch: \"newBranch\"\n },\n {\n $container: dummy,\n $type: \"CherryPicking\",\n id: \"1\",\n tags: [\"tag1\", \"tag2\"],\n parent: \"2\"\n }\n ]\n };\n populate(gitGraphAst, mockDB);\n expect(mockDB.commit).toHaveBeenCalledWith({\n id: \"1\",\n msg: \"test\",\n tags: [\"tag1\", \"tag2\"],\n type: 0\n });\n expect(mockDB.branch).toHaveBeenCalledWith({ name: \"newBranch\", order: 1 });\n expect(mockDB.merge).toHaveBeenCalledWith({\n branch: \"newBranch\",\n id: \"1\",\n tags: [\"tag1\", \"tag2\"],\n type: 0\n });\n expect(mockDB.checkout).toHaveBeenCalledWith(\"newBranch\");\n });\n });\n}\n\n// src/diagrams/git/gitGraphRenderer.ts\nimport { select } from \"d3\";\nvar DEFAULT_CONFIG = getConfig2();\nvar DEFAULT_GITGRAPH_CONFIG2 = DEFAULT_CONFIG?.gitGraph;\nvar LAYOUT_OFFSET = 10;\nvar COMMIT_STEP = 40;\nvar PX = 4;\nvar PY = 2;\nvar THEME_COLOR_LIMIT = 8;\nvar branchPos = /* @__PURE__ */ new Map();\nvar commitPos = /* @__PURE__ */ new Map();\nvar defaultPos = 30;\nvar allCommitsDict = /* @__PURE__ */ new Map();\nvar lanes = [];\nvar maxPos = 0;\nvar dir = \"LR\";\nvar clear3 = /* @__PURE__ */ __name(() => {\n branchPos.clear();\n commitPos.clear();\n allCommitsDict.clear();\n maxPos = 0;\n lanes = [];\n dir = \"LR\";\n}, \"clear\");\nvar drawText = /* @__PURE__ */ __name((txt) => {\n const svgLabel = document.createElementNS(\"http://www.w3.org/2000/svg\", \"text\");\n const rows = typeof txt === \"string\" ? txt.split(/\\\\n|\\n|/gi) : txt;\n rows.forEach((row) => {\n const tspan = document.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n tspan.setAttributeNS(\"http://www.w3.org/XML/1998/namespace\", \"xml:space\", \"preserve\");\n tspan.setAttribute(\"dy\", \"1em\");\n tspan.setAttribute(\"x\", \"0\");\n tspan.setAttribute(\"class\", \"row\");\n tspan.textContent = row.trim();\n svgLabel.appendChild(tspan);\n });\n return svgLabel;\n}, \"drawText\");\nvar findClosestParent = /* @__PURE__ */ __name((parents) => {\n let closestParent;\n let comparisonFunc;\n let targetPosition;\n if (dir === \"BT\") {\n comparisonFunc = /* @__PURE__ */ __name((a, b) => a <= b, \"comparisonFunc\");\n targetPosition = Infinity;\n } else {\n comparisonFunc = /* @__PURE__ */ __name((a, b) => a >= b, \"comparisonFunc\");\n targetPosition = 0;\n }\n parents.forEach((parent) => {\n const parentPosition = dir === \"TB\" || dir == \"BT\" ? commitPos.get(parent)?.y : commitPos.get(parent)?.x;\n if (parentPosition !== void 0 && comparisonFunc(parentPosition, targetPosition)) {\n closestParent = parent;\n targetPosition = parentPosition;\n }\n });\n return closestParent;\n}, \"findClosestParent\");\nvar findClosestParentBT = /* @__PURE__ */ __name((parents) => {\n let closestParent = \"\";\n let maxPosition = Infinity;\n parents.forEach((parent) => {\n const parentPosition = commitPos.get(parent).y;\n if (parentPosition <= maxPosition) {\n closestParent = parent;\n maxPosition = parentPosition;\n }\n });\n return closestParent || void 0;\n}, \"findClosestParentBT\");\nvar setParallelBTPos = /* @__PURE__ */ __name((sortedKeys, commits, defaultPos2) => {\n let curPos = defaultPos2;\n let maxPosition = defaultPos2;\n const roots = [];\n sortedKeys.forEach((key) => {\n const commit2 = commits.get(key);\n if (!commit2) {\n throw new Error(`Commit not found for key ${key}`);\n }\n if (commit2.parents.length) {\n curPos = calculateCommitPosition(commit2);\n maxPosition = Math.max(curPos, maxPosition);\n } else {\n roots.push(commit2);\n }\n setCommitPosition(commit2, curPos);\n });\n curPos = maxPosition;\n roots.forEach((commit2) => {\n setRootPosition(commit2, curPos, defaultPos2);\n });\n sortedKeys.forEach((key) => {\n const commit2 = commits.get(key);\n if (commit2?.parents.length) {\n const closestParent = findClosestParentBT(commit2.parents);\n curPos = commitPos.get(closestParent).y - COMMIT_STEP;\n if (curPos <= maxPosition) {\n maxPosition = curPos;\n }\n const x = branchPos.get(commit2.branch).pos;\n const y = curPos - LAYOUT_OFFSET;\n commitPos.set(commit2.id, { x, y });\n }\n });\n}, \"setParallelBTPos\");\nvar findClosestParentPos = /* @__PURE__ */ __name((commit2) => {\n const closestParent = findClosestParent(commit2.parents.filter((p) => p !== null));\n if (!closestParent) {\n throw new Error(`Closest parent not found for commit ${commit2.id}`);\n }\n const closestParentPos = commitPos.get(closestParent)?.y;\n if (closestParentPos === void 0) {\n throw new Error(`Closest parent position not found for commit ${commit2.id}`);\n }\n return closestParentPos;\n}, \"findClosestParentPos\");\nvar calculateCommitPosition = /* @__PURE__ */ __name((commit2) => {\n const closestParentPos = findClosestParentPos(commit2);\n return closestParentPos + COMMIT_STEP;\n}, \"calculateCommitPosition\");\nvar setCommitPosition = /* @__PURE__ */ __name((commit2, curPos) => {\n const branch2 = branchPos.get(commit2.branch);\n if (!branch2) {\n throw new Error(`Branch not found for commit ${commit2.id}`);\n }\n const x = branch2.pos;\n const y = curPos + LAYOUT_OFFSET;\n commitPos.set(commit2.id, { x, y });\n return { x, y };\n}, \"setCommitPosition\");\nvar setRootPosition = /* @__PURE__ */ __name((commit2, curPos, defaultPos2) => {\n const branch2 = branchPos.get(commit2.branch);\n if (!branch2) {\n throw new Error(`Branch not found for commit ${commit2.id}`);\n }\n const y = curPos + defaultPos2;\n const x = branch2.pos;\n commitPos.set(commit2.id, { x, y });\n}, \"setRootPosition\");\nvar drawCommitBullet = /* @__PURE__ */ __name((gBullets, commit2, commitPosition, typeClass, branchIndex, commitSymbolType) => {\n if (commitSymbolType === commitType.HIGHLIGHT) {\n gBullets.append(\"rect\").attr(\"x\", commitPosition.x - 10).attr(\"y\", commitPosition.y - 10).attr(\"width\", 20).attr(\"height\", 20).attr(\n \"class\",\n `commit ${commit2.id} commit-highlight${branchIndex % THEME_COLOR_LIMIT} ${typeClass}-outer`\n );\n gBullets.append(\"rect\").attr(\"x\", commitPosition.x - 6).attr(\"y\", commitPosition.y - 6).attr(\"width\", 12).attr(\"height\", 12).attr(\n \"class\",\n `commit ${commit2.id} commit${branchIndex % THEME_COLOR_LIMIT} ${typeClass}-inner`\n );\n } else if (commitSymbolType === commitType.CHERRY_PICK) {\n gBullets.append(\"circle\").attr(\"cx\", commitPosition.x).attr(\"cy\", commitPosition.y).attr(\"r\", 10).attr(\"class\", `commit ${commit2.id} ${typeClass}`);\n gBullets.append(\"circle\").attr(\"cx\", commitPosition.x - 3).attr(\"cy\", commitPosition.y + 2).attr(\"r\", 2.75).attr(\"fill\", \"#fff\").attr(\"class\", `commit ${commit2.id} ${typeClass}`);\n gBullets.append(\"circle\").attr(\"cx\", commitPosition.x + 3).attr(\"cy\", commitPosition.y + 2).attr(\"r\", 2.75).attr(\"fill\", \"#fff\").attr(\"class\", `commit ${commit2.id} ${typeClass}`);\n gBullets.append(\"line\").attr(\"x1\", commitPosition.x + 3).attr(\"y1\", commitPosition.y + 1).attr(\"x2\", commitPosition.x).attr(\"y2\", commitPosition.y - 5).attr(\"stroke\", \"#fff\").attr(\"class\", `commit ${commit2.id} ${typeClass}`);\n gBullets.append(\"line\").attr(\"x1\", commitPosition.x - 3).attr(\"y1\", commitPosition.y + 1).attr(\"x2\", commitPosition.x).attr(\"y2\", commitPosition.y - 5).attr(\"stroke\", \"#fff\").attr(\"class\", `commit ${commit2.id} ${typeClass}`);\n } else {\n const circle = gBullets.append(\"circle\");\n circle.attr(\"cx\", commitPosition.x);\n circle.attr(\"cy\", commitPosition.y);\n circle.attr(\"r\", commit2.type === commitType.MERGE ? 9 : 10);\n circle.attr(\"class\", `commit ${commit2.id} commit${branchIndex % THEME_COLOR_LIMIT}`);\n if (commitSymbolType === commitType.MERGE) {\n const circle2 = gBullets.append(\"circle\");\n circle2.attr(\"cx\", commitPosition.x);\n circle2.attr(\"cy\", commitPosition.y);\n circle2.attr(\"r\", 6);\n circle2.attr(\n \"class\",\n `commit ${typeClass} ${commit2.id} commit${branchIndex % THEME_COLOR_LIMIT}`\n );\n }\n if (commitSymbolType === commitType.REVERSE) {\n const cross = gBullets.append(\"path\");\n cross.attr(\n \"d\",\n `M ${commitPosition.x - 5},${commitPosition.y - 5}L${commitPosition.x + 5},${commitPosition.y + 5}M${commitPosition.x - 5},${commitPosition.y + 5}L${commitPosition.x + 5},${commitPosition.y - 5}`\n ).attr(\"class\", `commit ${typeClass} ${commit2.id} commit${branchIndex % THEME_COLOR_LIMIT}`);\n }\n }\n}, \"drawCommitBullet\");\nvar drawCommitLabel = /* @__PURE__ */ __name((gLabels, commit2, commitPosition, pos) => {\n if (commit2.type !== commitType.CHERRY_PICK && (commit2.customId && commit2.type === commitType.MERGE || commit2.type !== commitType.MERGE) && DEFAULT_GITGRAPH_CONFIG2?.showCommitLabel) {\n const wrapper = gLabels.append(\"g\");\n const labelBkg = wrapper.insert(\"rect\").attr(\"class\", \"commit-label-bkg\");\n const text = wrapper.append(\"text\").attr(\"x\", pos).attr(\"y\", commitPosition.y + 25).attr(\"class\", \"commit-label\").text(commit2.id);\n const bbox = text.node()?.getBBox();\n if (bbox) {\n labelBkg.attr(\"x\", commitPosition.posWithOffset - bbox.width / 2 - PY).attr(\"y\", commitPosition.y + 13.5).attr(\"width\", bbox.width + 2 * PY).attr(\"height\", bbox.height + 2 * PY);\n if (dir === \"TB\" || dir === \"BT\") {\n labelBkg.attr(\"x\", commitPosition.x - (bbox.width + 4 * PX + 5)).attr(\"y\", commitPosition.y - 12);\n text.attr(\"x\", commitPosition.x - (bbox.width + 4 * PX)).attr(\"y\", commitPosition.y + bbox.height - 12);\n } else {\n text.attr(\"x\", commitPosition.posWithOffset - bbox.width / 2);\n }\n if (DEFAULT_GITGRAPH_CONFIG2.rotateCommitLabel) {\n if (dir === \"TB\" || dir === \"BT\") {\n text.attr(\n \"transform\",\n \"rotate(-45, \" + commitPosition.x + \", \" + commitPosition.y + \")\"\n );\n labelBkg.attr(\n \"transform\",\n \"rotate(-45, \" + commitPosition.x + \", \" + commitPosition.y + \")\"\n );\n } else {\n const r_x = -7.5 - (bbox.width + 10) / 25 * 9.5;\n const r_y = 10 + bbox.width / 25 * 8.5;\n wrapper.attr(\n \"transform\",\n \"translate(\" + r_x + \", \" + r_y + \") rotate(-45, \" + pos + \", \" + commitPosition.y + \")\"\n );\n }\n }\n }\n }\n}, \"drawCommitLabel\");\nvar drawCommitTags = /* @__PURE__ */ __name((gLabels, commit2, commitPosition, pos) => {\n if (commit2.tags.length > 0) {\n let yOffset = 0;\n let maxTagBboxWidth = 0;\n let maxTagBboxHeight = 0;\n const tagElements = [];\n for (const tagValue of commit2.tags.reverse()) {\n const rect = gLabels.insert(\"polygon\");\n const hole = gLabels.append(\"circle\");\n const tag = gLabels.append(\"text\").attr(\"y\", commitPosition.y - 16 - yOffset).attr(\"class\", \"tag-label\").text(tagValue);\n const tagBbox = tag.node()?.getBBox();\n if (!tagBbox) {\n throw new Error(\"Tag bbox not found\");\n }\n maxTagBboxWidth = Math.max(maxTagBboxWidth, tagBbox.width);\n maxTagBboxHeight = Math.max(maxTagBboxHeight, tagBbox.height);\n tag.attr(\"x\", commitPosition.posWithOffset - tagBbox.width / 2);\n tagElements.push({\n tag,\n hole,\n rect,\n yOffset\n });\n yOffset += 20;\n }\n for (const { tag, hole, rect, yOffset: yOffset2 } of tagElements) {\n const h2 = maxTagBboxHeight / 2;\n const ly = commitPosition.y - 19.2 - yOffset2;\n rect.attr(\"class\", \"tag-label-bkg\").attr(\n \"points\",\n `\n ${pos - maxTagBboxWidth / 2 - PX / 2},${ly + PY} \n ${pos - maxTagBboxWidth / 2 - PX / 2},${ly - PY}\n ${commitPosition.posWithOffset - maxTagBboxWidth / 2 - PX},${ly - h2 - PY}\n ${commitPosition.posWithOffset + maxTagBboxWidth / 2 + PX},${ly - h2 - PY}\n ${commitPosition.posWithOffset + maxTagBboxWidth / 2 + PX},${ly + h2 + PY}\n ${commitPosition.posWithOffset - maxTagBboxWidth / 2 - PX},${ly + h2 + PY}`\n );\n hole.attr(\"cy\", ly).attr(\"cx\", pos - maxTagBboxWidth / 2 + PX / 2).attr(\"r\", 1.5).attr(\"class\", \"tag-hole\");\n if (dir === \"TB\" || dir === \"BT\") {\n const yOrigin = pos + yOffset2;\n rect.attr(\"class\", \"tag-label-bkg\").attr(\n \"points\",\n `\n ${commitPosition.x},${yOrigin + 2}\n ${commitPosition.x},${yOrigin - 2}\n ${commitPosition.x + LAYOUT_OFFSET},${yOrigin - h2 - 2}\n ${commitPosition.x + LAYOUT_OFFSET + maxTagBboxWidth + 4},${yOrigin - h2 - 2}\n ${commitPosition.x + LAYOUT_OFFSET + maxTagBboxWidth + 4},${yOrigin + h2 + 2}\n ${commitPosition.x + LAYOUT_OFFSET},${yOrigin + h2 + 2}`\n ).attr(\"transform\", \"translate(12,12) rotate(45, \" + commitPosition.x + \",\" + pos + \")\");\n hole.attr(\"cx\", commitPosition.x + PX / 2).attr(\"cy\", yOrigin).attr(\"transform\", \"translate(12,12) rotate(45, \" + commitPosition.x + \",\" + pos + \")\");\n tag.attr(\"x\", commitPosition.x + 5).attr(\"y\", yOrigin + 3).attr(\"transform\", \"translate(14,14) rotate(45, \" + commitPosition.x + \",\" + pos + \")\");\n }\n }\n }\n}, \"drawCommitTags\");\nvar getCommitClassType = /* @__PURE__ */ __name((commit2) => {\n const commitSymbolType = commit2.customType ?? commit2.type;\n switch (commitSymbolType) {\n case commitType.NORMAL:\n return \"commit-normal\";\n case commitType.REVERSE:\n return \"commit-reverse\";\n case commitType.HIGHLIGHT:\n return \"commit-highlight\";\n case commitType.MERGE:\n return \"commit-merge\";\n case commitType.CHERRY_PICK:\n return \"commit-cherry-pick\";\n default:\n return \"commit-normal\";\n }\n}, \"getCommitClassType\");\nvar calculatePosition = /* @__PURE__ */ __name((commit2, dir2, pos, commitPos2) => {\n const defaultCommitPosition = { x: 0, y: 0 };\n if (commit2.parents.length > 0) {\n const closestParent = findClosestParent(commit2.parents);\n if (closestParent) {\n const parentPosition = commitPos2.get(closestParent) ?? defaultCommitPosition;\n if (dir2 === \"TB\") {\n return parentPosition.y + COMMIT_STEP;\n } else if (dir2 === \"BT\") {\n const currentPosition = commitPos2.get(commit2.id) ?? defaultCommitPosition;\n return currentPosition.y - COMMIT_STEP;\n } else {\n return parentPosition.x + COMMIT_STEP;\n }\n }\n } else {\n if (dir2 === \"TB\") {\n return defaultPos;\n } else if (dir2 === \"BT\") {\n const currentPosition = commitPos2.get(commit2.id) ?? defaultCommitPosition;\n return currentPosition.y - COMMIT_STEP;\n } else {\n return 0;\n }\n }\n return 0;\n}, \"calculatePosition\");\nvar getCommitPosition = /* @__PURE__ */ __name((commit2, pos, isParallelCommits) => {\n const posWithOffset = dir === \"BT\" && isParallelCommits ? pos : pos + LAYOUT_OFFSET;\n const y = dir === \"TB\" || dir === \"BT\" ? posWithOffset : branchPos.get(commit2.branch)?.pos;\n const x = dir === \"TB\" || dir === \"BT\" ? branchPos.get(commit2.branch)?.pos : posWithOffset;\n if (x === void 0 || y === void 0) {\n throw new Error(`Position were undefined for commit ${commit2.id}`);\n }\n return { x, y, posWithOffset };\n}, \"getCommitPosition\");\nvar drawCommits = /* @__PURE__ */ __name((svg, commits, modifyGraph) => {\n if (!DEFAULT_GITGRAPH_CONFIG2) {\n throw new Error(\"GitGraph config not found\");\n }\n const gBullets = svg.append(\"g\").attr(\"class\", \"commit-bullets\");\n const gLabels = svg.append(\"g\").attr(\"class\", \"commit-labels\");\n let pos = dir === \"TB\" || dir === \"BT\" ? defaultPos : 0;\n const keys = [...commits.keys()];\n const isParallelCommits = DEFAULT_GITGRAPH_CONFIG2?.parallelCommits ?? false;\n const sortKeys = /* @__PURE__ */ __name((a, b) => {\n const seqA = commits.get(a)?.seq;\n const seqB = commits.get(b)?.seq;\n return seqA !== void 0 && seqB !== void 0 ? seqA - seqB : 0;\n }, \"sortKeys\");\n let sortedKeys = keys.sort(sortKeys);\n if (dir === \"BT\") {\n if (isParallelCommits) {\n setParallelBTPos(sortedKeys, commits, pos);\n }\n sortedKeys = sortedKeys.reverse();\n }\n sortedKeys.forEach((key) => {\n const commit2 = commits.get(key);\n if (!commit2) {\n throw new Error(`Commit not found for key ${key}`);\n }\n if (isParallelCommits) {\n pos = calculatePosition(commit2, dir, pos, commitPos);\n }\n const commitPosition = getCommitPosition(commit2, pos, isParallelCommits);\n if (modifyGraph) {\n const typeClass = getCommitClassType(commit2);\n const commitSymbolType = commit2.customType ?? commit2.type;\n const branchIndex = branchPos.get(commit2.branch)?.index ?? 0;\n drawCommitBullet(gBullets, commit2, commitPosition, typeClass, branchIndex, commitSymbolType);\n drawCommitLabel(gLabels, commit2, commitPosition, pos);\n drawCommitTags(gLabels, commit2, commitPosition, pos);\n }\n if (dir === \"TB\" || dir === \"BT\") {\n commitPos.set(commit2.id, { x: commitPosition.x, y: commitPosition.posWithOffset });\n } else {\n commitPos.set(commit2.id, { x: commitPosition.posWithOffset, y: commitPosition.y });\n }\n pos = dir === \"BT\" && isParallelCommits ? pos + COMMIT_STEP : pos + COMMIT_STEP + LAYOUT_OFFSET;\n if (pos > maxPos) {\n maxPos = pos;\n }\n });\n}, \"drawCommits\");\nvar shouldRerouteArrow = /* @__PURE__ */ __name((commitA, commitB, p1, p2, allCommits) => {\n const commitBIsFurthest = dir === \"TB\" || dir === \"BT\" ? p1.x < p2.x : p1.y < p2.y;\n const branchToGetCurve = commitBIsFurthest ? commitB.branch : commitA.branch;\n const isOnBranchToGetCurve = /* @__PURE__ */ __name((x) => x.branch === branchToGetCurve, \"isOnBranchToGetCurve\");\n const isBetweenCommits = /* @__PURE__ */ __name((x) => x.seq > commitA.seq && x.seq < commitB.seq, \"isBetweenCommits\");\n return [...allCommits.values()].some((commitX) => {\n return isBetweenCommits(commitX) && isOnBranchToGetCurve(commitX);\n });\n}, \"shouldRerouteArrow\");\nvar findLane = /* @__PURE__ */ __name((y1, y2, depth = 0) => {\n const candidate = y1 + Math.abs(y1 - y2) / 2;\n if (depth > 5) {\n return candidate;\n }\n const ok = lanes.every((lane) => Math.abs(lane - candidate) >= 10);\n if (ok) {\n lanes.push(candidate);\n return candidate;\n }\n const diff = Math.abs(y1 - y2);\n return findLane(y1, y2 - diff / 5, depth + 1);\n}, \"findLane\");\nvar drawArrow = /* @__PURE__ */ __name((svg, commitA, commitB, allCommits) => {\n const p1 = commitPos.get(commitA.id);\n const p2 = commitPos.get(commitB.id);\n if (p1 === void 0 || p2 === void 0) {\n throw new Error(`Commit positions not found for commits ${commitA.id} and ${commitB.id}`);\n }\n const arrowNeedsRerouting = shouldRerouteArrow(commitA, commitB, p1, p2, allCommits);\n let arc = \"\";\n let arc2 = \"\";\n let radius = 0;\n let offset = 0;\n let colorClassNum = branchPos.get(commitB.branch)?.index;\n if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) {\n colorClassNum = branchPos.get(commitA.branch)?.index;\n }\n let lineDef;\n if (arrowNeedsRerouting) {\n arc = \"A 10 10, 0, 0, 0,\";\n arc2 = \"A 10 10, 0, 0, 1,\";\n radius = 10;\n offset = 10;\n const lineY = p1.y < p2.y ? findLane(p1.y, p2.y) : findLane(p2.y, p1.y);\n const lineX = p1.x < p2.x ? findLane(p1.x, p2.x) : findLane(p2.x, p1.x);\n if (dir === \"TB\") {\n if (p1.x < p2.x) {\n lineDef = `M ${p1.x} ${p1.y} L ${lineX - radius} ${p1.y} ${arc2} ${lineX} ${p1.y + offset} L ${lineX} ${p2.y - radius} ${arc} ${lineX + offset} ${p2.y} L ${p2.x} ${p2.y}`;\n } else {\n colorClassNum = branchPos.get(commitA.branch)?.index;\n lineDef = `M ${p1.x} ${p1.y} L ${lineX + radius} ${p1.y} ${arc} ${lineX} ${p1.y + offset} L ${lineX} ${p2.y - radius} ${arc2} ${lineX - offset} ${p2.y} L ${p2.x} ${p2.y}`;\n }\n } else if (dir === \"BT\") {\n if (p1.x < p2.x) {\n lineDef = `M ${p1.x} ${p1.y} L ${lineX - radius} ${p1.y} ${arc} ${lineX} ${p1.y - offset} L ${lineX} ${p2.y + radius} ${arc2} ${lineX + offset} ${p2.y} L ${p2.x} ${p2.y}`;\n } else {\n colorClassNum = branchPos.get(commitA.branch)?.index;\n lineDef = `M ${p1.x} ${p1.y} L ${lineX + radius} ${p1.y} ${arc2} ${lineX} ${p1.y - offset} L ${lineX} ${p2.y + radius} ${arc} ${lineX - offset} ${p2.y} L ${p2.x} ${p2.y}`;\n }\n } else {\n if (p1.y < p2.y) {\n lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${lineY - radius} ${arc} ${p1.x + offset} ${lineY} L ${p2.x - radius} ${lineY} ${arc2} ${p2.x} ${lineY + offset} L ${p2.x} ${p2.y}`;\n } else {\n colorClassNum = branchPos.get(commitA.branch)?.index;\n lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${lineY + radius} ${arc2} ${p1.x + offset} ${lineY} L ${p2.x - radius} ${lineY} ${arc} ${p2.x} ${lineY - offset} L ${p2.x} ${p2.y}`;\n }\n }\n } else {\n arc = \"A 20 20, 0, 0, 0,\";\n arc2 = \"A 20 20, 0, 0, 1,\";\n radius = 20;\n offset = 20;\n if (dir === \"TB\") {\n if (p1.x < p2.x) {\n if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) {\n lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`;\n } else {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc2} ${p2.x} ${p1.y + offset} L ${p2.x} ${p2.y}`;\n }\n }\n if (p1.x > p2.x) {\n arc = \"A 20 20, 0, 0, 0,\";\n arc2 = \"A 20 20, 0, 0, 1,\";\n radius = 20;\n offset = 20;\n if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) {\n lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc2} ${p1.x - offset} ${p2.y} L ${p2.x} ${p2.y}`;\n } else {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x + radius} ${p1.y} ${arc} ${p2.x} ${p1.y + offset} L ${p2.x} ${p2.y}`;\n }\n }\n if (p1.x === p2.x) {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x} ${p2.y}`;\n }\n } else if (dir === \"BT\") {\n if (p1.x < p2.x) {\n if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) {\n lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y + radius} ${arc2} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`;\n } else {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc} ${p2.x} ${p1.y - offset} L ${p2.x} ${p2.y}`;\n }\n }\n if (p1.x > p2.x) {\n arc = \"A 20 20, 0, 0, 0,\";\n arc2 = \"A 20 20, 0, 0, 1,\";\n radius = 20;\n offset = 20;\n if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) {\n lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y + radius} ${arc} ${p1.x - offset} ${p2.y} L ${p2.x} ${p2.y}`;\n } else {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc} ${p2.x} ${p1.y - offset} L ${p2.x} ${p2.y}`;\n }\n }\n if (p1.x === p2.x) {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x} ${p2.y}`;\n }\n } else {\n if (p1.y < p2.y) {\n if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc2} ${p2.x} ${p1.y + offset} L ${p2.x} ${p2.y}`;\n } else {\n lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y - radius} ${arc} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`;\n }\n }\n if (p1.y > p2.y) {\n if (commitB.type === commitType.MERGE && commitA.id !== commitB.parents[0]) {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x - radius} ${p1.y} ${arc} ${p2.x} ${p1.y - offset} L ${p2.x} ${p2.y}`;\n } else {\n lineDef = `M ${p1.x} ${p1.y} L ${p1.x} ${p2.y + radius} ${arc2} ${p1.x + offset} ${p2.y} L ${p2.x} ${p2.y}`;\n }\n }\n if (p1.y === p2.y) {\n lineDef = `M ${p1.x} ${p1.y} L ${p2.x} ${p2.y}`;\n }\n }\n }\n if (lineDef === void 0) {\n throw new Error(\"Line definition not found\");\n }\n svg.append(\"path\").attr(\"d\", lineDef).attr(\"class\", \"arrow arrow\" + colorClassNum % THEME_COLOR_LIMIT);\n}, \"drawArrow\");\nvar drawArrows = /* @__PURE__ */ __name((svg, commits) => {\n const gArrows = svg.append(\"g\").attr(\"class\", \"commit-arrows\");\n [...commits.keys()].forEach((key) => {\n const commit2 = commits.get(key);\n if (commit2.parents && commit2.parents.length > 0) {\n commit2.parents.forEach((parent) => {\n drawArrow(gArrows, commits.get(parent), commit2, commits);\n });\n }\n });\n}, \"drawArrows\");\nvar drawBranches = /* @__PURE__ */ __name((svg, branches) => {\n const g = svg.append(\"g\");\n branches.forEach((branch2, index) => {\n const adjustIndexForTheme = index % THEME_COLOR_LIMIT;\n const pos = branchPos.get(branch2.name)?.pos;\n if (pos === void 0) {\n throw new Error(`Position not found for branch ${branch2.name}`);\n }\n const line = g.append(\"line\");\n line.attr(\"x1\", 0);\n line.attr(\"y1\", pos);\n line.attr(\"x2\", maxPos);\n line.attr(\"y2\", pos);\n line.attr(\"class\", \"branch branch\" + adjustIndexForTheme);\n if (dir === \"TB\") {\n line.attr(\"y1\", defaultPos);\n line.attr(\"x1\", pos);\n line.attr(\"y2\", maxPos);\n line.attr(\"x2\", pos);\n } else if (dir === \"BT\") {\n line.attr(\"y1\", maxPos);\n line.attr(\"x1\", pos);\n line.attr(\"y2\", defaultPos);\n line.attr(\"x2\", pos);\n }\n lanes.push(pos);\n const name = branch2.name;\n const labelElement = drawText(name);\n const bkg = g.insert(\"rect\");\n const branchLabel = g.insert(\"g\").attr(\"class\", \"branchLabel\");\n const label = branchLabel.insert(\"g\").attr(\"class\", \"label branch-label\" + adjustIndexForTheme);\n label.node().appendChild(labelElement);\n const bbox = labelElement.getBBox();\n bkg.attr(\"class\", \"branchLabelBkg label\" + adjustIndexForTheme).attr(\"rx\", 4).attr(\"ry\", 4).attr(\"x\", -bbox.width - 4 - (DEFAULT_GITGRAPH_CONFIG2?.rotateCommitLabel === true ? 30 : 0)).attr(\"y\", -bbox.height / 2 + 8).attr(\"width\", bbox.width + 18).attr(\"height\", bbox.height + 4);\n label.attr(\n \"transform\",\n \"translate(\" + (-bbox.width - 14 - (DEFAULT_GITGRAPH_CONFIG2?.rotateCommitLabel === true ? 30 : 0)) + \", \" + (pos - bbox.height / 2 - 1) + \")\"\n );\n if (dir === \"TB\") {\n bkg.attr(\"x\", pos - bbox.width / 2 - 10).attr(\"y\", 0);\n label.attr(\"transform\", \"translate(\" + (pos - bbox.width / 2 - 5) + \", 0)\");\n } else if (dir === \"BT\") {\n bkg.attr(\"x\", pos - bbox.width / 2 - 10).attr(\"y\", maxPos);\n label.attr(\"transform\", \"translate(\" + (pos - bbox.width / 2 - 5) + \", \" + maxPos + \")\");\n } else {\n bkg.attr(\"transform\", \"translate(-19, \" + (pos - bbox.height / 2) + \")\");\n }\n });\n}, \"drawBranches\");\nvar setBranchPosition = /* @__PURE__ */ __name(function(name, pos, index, bbox, rotateCommitLabel) {\n branchPos.set(name, { pos, index });\n pos += 50 + (rotateCommitLabel ? 40 : 0) + (dir === \"TB\" || dir === \"BT\" ? bbox.width / 2 : 0);\n return pos;\n}, \"setBranchPosition\");\nvar draw = /* @__PURE__ */ __name(function(txt, id, ver, diagObj) {\n clear3();\n log.debug(\"in gitgraph renderer\", txt + \"\\n\", \"id:\", id, ver);\n if (!DEFAULT_GITGRAPH_CONFIG2) {\n throw new Error(\"GitGraph config not found\");\n }\n const rotateCommitLabel = DEFAULT_GITGRAPH_CONFIG2.rotateCommitLabel ?? false;\n const db2 = diagObj.db;\n allCommitsDict = db2.getCommits();\n const branches = db2.getBranchesAsObjArray();\n dir = db2.getDirection();\n const diagram2 = select(`[id=\"${id}\"]`);\n let pos = 0;\n branches.forEach((branch2, index) => {\n const labelElement = drawText(branch2.name);\n const g = diagram2.append(\"g\");\n const branchLabel = g.insert(\"g\").attr(\"class\", \"branchLabel\");\n const label = branchLabel.insert(\"g\").attr(\"class\", \"label branch-label\");\n label.node()?.appendChild(labelElement);\n const bbox = labelElement.getBBox();\n pos = setBranchPosition(branch2.name, pos, index, bbox, rotateCommitLabel);\n label.remove();\n branchLabel.remove();\n g.remove();\n });\n drawCommits(diagram2, allCommitsDict, false);\n if (DEFAULT_GITGRAPH_CONFIG2.showBranches) {\n drawBranches(diagram2, branches);\n }\n drawArrows(diagram2, allCommitsDict);\n drawCommits(diagram2, allCommitsDict, true);\n utils_default.insertTitle(\n diagram2,\n \"gitTitleText\",\n DEFAULT_GITGRAPH_CONFIG2.titleTopMargin ?? 0,\n db2.getDiagramTitle()\n );\n setupGraphViewbox(\n void 0,\n diagram2,\n DEFAULT_GITGRAPH_CONFIG2.diagramPadding,\n DEFAULT_GITGRAPH_CONFIG2.useMaxWidth\n );\n}, \"draw\");\nvar gitGraphRenderer_default = {\n draw\n};\nif (void 0) {\n const { it, expect, describe } = void 0;\n describe(\"drawText\", () => {\n it(\"should drawText\", () => {\n const svgLabel = drawText(\"main\");\n expect(svgLabel).toBeDefined();\n expect(svgLabel.children[0].innerHTML).toBe(\"main\");\n });\n });\n describe(\"branchPosition\", () => {\n const bbox = {\n x: 0,\n y: 0,\n width: 10,\n height: 10,\n top: 0,\n right: 0,\n bottom: 0,\n left: 0,\n toJSON: /* @__PURE__ */ __name(() => \"\", \"toJSON\")\n };\n it(\"should setBranchPositions LR with two branches\", () => {\n dir = \"LR\";\n const pos = setBranchPosition(\"main\", 0, 0, bbox, true);\n expect(pos).toBe(90);\n expect(branchPos.get(\"main\")).toEqual({ pos: 0, index: 0 });\n const posNext = setBranchPosition(\"develop\", pos, 1, bbox, true);\n expect(posNext).toBe(180);\n expect(branchPos.get(\"develop\")).toEqual({ pos, index: 1 });\n });\n it(\"should setBranchPositions TB with two branches\", () => {\n dir = \"TB\";\n bbox.width = 34.9921875;\n const pos = setBranchPosition(\"main\", 0, 0, bbox, true);\n expect(pos).toBe(107.49609375);\n expect(branchPos.get(\"main\")).toEqual({ pos: 0, index: 0 });\n bbox.width = 56.421875;\n const posNext = setBranchPosition(\"develop\", pos, 1, bbox, true);\n expect(posNext).toBe(225.70703125);\n expect(branchPos.get(\"develop\")).toEqual({ pos, index: 1 });\n });\n });\n describe(\"commitPosition\", () => {\n const commits = /* @__PURE__ */ new Map([\n [\n \"commitZero\",\n {\n id: \"ZERO\",\n message: \"\",\n seq: 0,\n type: commitType.NORMAL,\n tags: [],\n parents: [],\n branch: \"main\"\n }\n ],\n [\n \"commitA\",\n {\n id: \"A\",\n message: \"\",\n seq: 1,\n type: commitType.NORMAL,\n tags: [],\n parents: [\"ZERO\"],\n branch: \"feature\"\n }\n ],\n [\n \"commitB\",\n {\n id: \"B\",\n message: \"\",\n seq: 2,\n type: commitType.NORMAL,\n tags: [],\n parents: [\"A\"],\n branch: \"feature\"\n }\n ],\n [\n \"commitM\",\n {\n id: \"M\",\n message: \"merged branch feature into main\",\n seq: 3,\n type: commitType.MERGE,\n tags: [],\n parents: [\"ZERO\", \"B\"],\n branch: \"main\",\n customId: true\n }\n ],\n [\n \"commitC\",\n {\n id: \"C\",\n message: \"\",\n seq: 4,\n type: commitType.NORMAL,\n tags: [],\n parents: [\"ZERO\"],\n branch: \"release\"\n }\n ],\n [\n \"commit5_8928ea0\",\n {\n id: \"5-8928ea0\",\n message: \"cherry-picked [object Object] into release\",\n seq: 5,\n type: commitType.CHERRY_PICK,\n tags: [],\n parents: [\"C\", \"M\"],\n branch: \"release\"\n }\n ],\n [\n \"commitD\",\n {\n id: \"D\",\n message: \"\",\n seq: 6,\n type: commitType.NORMAL,\n tags: [],\n parents: [\"5-8928ea0\"],\n branch: \"release\"\n }\n ],\n [\n \"commit7_ed848ba\",\n {\n id: \"7-ed848ba\",\n message: \"cherry-picked [object Object] into release\",\n seq: 7,\n type: commitType.CHERRY_PICK,\n tags: [],\n parents: [\"D\", \"M\"],\n branch: \"release\"\n }\n ]\n ]);\n let pos = 0;\n branchPos.set(\"main\", { pos: 0, index: 0 });\n branchPos.set(\"feature\", { pos: 107.49609375, index: 1 });\n branchPos.set(\"release\", { pos: 224.03515625, index: 2 });\n describe(\"TB\", () => {\n pos = 30;\n dir = \"TB\";\n const expectedCommitPositionTB = /* @__PURE__ */ new Map([\n [\"commitZero\", { x: 0, y: 40, posWithOffset: 40 }],\n [\"commitA\", { x: 107.49609375, y: 90, posWithOffset: 90 }],\n [\"commitB\", { x: 107.49609375, y: 140, posWithOffset: 140 }],\n [\"commitM\", { x: 0, y: 190, posWithOffset: 190 }],\n [\"commitC\", { x: 224.03515625, y: 240, posWithOffset: 240 }],\n [\"commit5_8928ea0\", { x: 224.03515625, y: 290, posWithOffset: 290 }],\n [\"commitD\", { x: 224.03515625, y: 340, posWithOffset: 340 }],\n [\"commit7_ed848ba\", { x: 224.03515625, y: 390, posWithOffset: 390 }]\n ]);\n commits.forEach((commit2, key) => {\n it(`should give the correct position for commit ${key}`, () => {\n const position = getCommitPosition(commit2, pos, false);\n expect(position).toEqual(expectedCommitPositionTB.get(key));\n pos += 50;\n });\n });\n });\n describe(\"LR\", () => {\n let pos2 = 30;\n dir = \"LR\";\n const expectedCommitPositionLR = /* @__PURE__ */ new Map([\n [\"commitZero\", { x: 0, y: 40, posWithOffset: 40 }],\n [\"commitA\", { x: 107.49609375, y: 90, posWithOffset: 90 }],\n [\"commitB\", { x: 107.49609375, y: 140, posWithOffset: 140 }],\n [\"commitM\", { x: 0, y: 190, posWithOffset: 190 }],\n [\"commitC\", { x: 224.03515625, y: 240, posWithOffset: 240 }],\n [\"commit5_8928ea0\", { x: 224.03515625, y: 290, posWithOffset: 290 }],\n [\"commitD\", { x: 224.03515625, y: 340, posWithOffset: 340 }],\n [\"commit7_ed848ba\", { x: 224.03515625, y: 390, posWithOffset: 390 }]\n ]);\n commits.forEach((commit2, key) => {\n it(`should give the correct position for commit ${key}`, () => {\n const position = getCommitPosition(commit2, pos2, false);\n expect(position).toEqual(expectedCommitPositionLR.get(key));\n pos2 += 50;\n });\n });\n });\n describe(\"getCommitClassType\", () => {\n const expectedCommitClassType = /* @__PURE__ */ new Map([\n [\"commitZero\", \"commit-normal\"],\n [\"commitA\", \"commit-normal\"],\n [\"commitB\", \"commit-normal\"],\n [\"commitM\", \"commit-merge\"],\n [\"commitC\", \"commit-normal\"],\n [\"commit5_8928ea0\", \"commit-cherry-pick\"],\n [\"commitD\", \"commit-normal\"],\n [\"commit7_ed848ba\", \"commit-cherry-pick\"]\n ]);\n commits.forEach((commit2, key) => {\n it(`should give the correct class type for commit ${key}`, () => {\n const classType = getCommitClassType(commit2);\n expect(classType).toBe(expectedCommitClassType.get(key));\n });\n });\n });\n });\n describe(\"building BT parallel commit diagram\", () => {\n const commits = /* @__PURE__ */ new Map([\n [\n \"1-abcdefg\",\n {\n id: \"1-abcdefg\",\n message: \"\",\n seq: 0,\n type: 0,\n tags: [],\n parents: [],\n branch: \"main\"\n }\n ],\n [\n \"2-abcdefg\",\n {\n id: \"2-abcdefg\",\n message: \"\",\n seq: 1,\n type: 0,\n tags: [],\n parents: [\"1-abcdefg\"],\n branch: \"main\"\n }\n ],\n [\n \"3-abcdefg\",\n {\n id: \"3-abcdefg\",\n message: \"\",\n seq: 2,\n type: 0,\n tags: [],\n parents: [\"2-abcdefg\"],\n branch: \"develop\"\n }\n ],\n [\n \"4-abcdefg\",\n {\n id: \"4-abcdefg\",\n message: \"\",\n seq: 3,\n type: 0,\n tags: [],\n parents: [\"3-abcdefg\"],\n branch: \"develop\"\n }\n ],\n [\n \"5-abcdefg\",\n {\n id: \"5-abcdefg\",\n message: \"\",\n seq: 4,\n type: 0,\n tags: [],\n parents: [\"2-abcdefg\"],\n branch: \"feature\"\n }\n ],\n [\n \"6-abcdefg\",\n {\n id: \"6-abcdefg\",\n message: \"\",\n seq: 5,\n type: 0,\n tags: [],\n parents: [\"5-abcdefg\"],\n branch: \"feature\"\n }\n ],\n [\n \"7-abcdefg\",\n {\n id: \"7-abcdefg\",\n message: \"\",\n seq: 6,\n type: 0,\n tags: [],\n parents: [\"2-abcdefg\"],\n branch: \"main\"\n }\n ],\n [\n \"8-abcdefg\",\n {\n id: \"8-abcdefg\",\n message: \"\",\n seq: 7,\n type: 0,\n tags: [],\n parents: [\"7-abcdefg\"],\n branch: \"main\"\n }\n ]\n ]);\n const expectedCommitPosition = /* @__PURE__ */ new Map([\n [\"1-abcdefg\", { x: 0, y: 40 }],\n [\"2-abcdefg\", { x: 0, y: 90 }],\n [\"3-abcdefg\", { x: 107.49609375, y: 140 }],\n [\"4-abcdefg\", { x: 107.49609375, y: 190 }],\n [\"5-abcdefg\", { x: 225.70703125, y: 140 }],\n [\"6-abcdefg\", { x: 225.70703125, y: 190 }],\n [\"7-abcdefg\", { x: 0, y: 140 }],\n [\"8-abcdefg\", { x: 0, y: 190 }]\n ]);\n const expectedCommitPositionAfterParallel = /* @__PURE__ */ new Map([\n [\"1-abcdefg\", { x: 0, y: 210 }],\n [\"2-abcdefg\", { x: 0, y: 160 }],\n [\"3-abcdefg\", { x: 107.49609375, y: 110 }],\n [\"4-abcdefg\", { x: 107.49609375, y: 60 }],\n [\"5-abcdefg\", { x: 225.70703125, y: 110 }],\n [\"6-abcdefg\", { x: 225.70703125, y: 60 }],\n [\"7-abcdefg\", { x: 0, y: 110 }],\n [\"8-abcdefg\", { x: 0, y: 60 }]\n ]);\n const expectedCommitCurrentPosition = /* @__PURE__ */ new Map([\n [\"1-abcdefg\", 30],\n [\"2-abcdefg\", 80],\n [\"3-abcdefg\", 130],\n [\"4-abcdefg\", 180],\n [\"5-abcdefg\", 130],\n [\"6-abcdefg\", 180],\n [\"7-abcdefg\", 130],\n [\"8-abcdefg\", 180]\n ]);\n const sortedKeys = [...expectedCommitPosition.keys()];\n it(\"should get the correct commit position and current position\", () => {\n dir = \"BT\";\n let curPos = 30;\n commitPos.clear();\n branchPos.clear();\n branchPos.set(\"main\", { pos: 0, index: 0 });\n branchPos.set(\"develop\", { pos: 107.49609375, index: 1 });\n branchPos.set(\"feature\", { pos: 225.70703125, index: 2 });\n DEFAULT_GITGRAPH_CONFIG2.parallelCommits = true;\n commits.forEach((commit2, key) => {\n if (commit2.parents.length > 0) {\n curPos = calculateCommitPosition(commit2);\n }\n const position = setCommitPosition(commit2, curPos);\n expect(position).toEqual(expectedCommitPosition.get(key));\n expect(curPos).toEqual(expectedCommitCurrentPosition.get(key));\n });\n });\n it(\"should get the correct commit position after parallel commits\", () => {\n commitPos.clear();\n branchPos.clear();\n dir = \"BT\";\n const curPos = 30;\n commitPos.clear();\n branchPos.clear();\n branchPos.set(\"main\", { pos: 0, index: 0 });\n branchPos.set(\"develop\", { pos: 107.49609375, index: 1 });\n branchPos.set(\"feature\", { pos: 225.70703125, index: 2 });\n setParallelBTPos(sortedKeys, commits, curPos);\n sortedKeys.forEach((commit2) => {\n const position = commitPos.get(commit2);\n expect(position).toEqual(expectedCommitPositionAfterParallel.get(commit2));\n });\n });\n });\n DEFAULT_GITGRAPH_CONFIG2.parallelCommits = false;\n it(\"add\", () => {\n commitPos.set(\"parent1\", { x: 1, y: 1 });\n commitPos.set(\"parent2\", { x: 2, y: 2 });\n commitPos.set(\"parent3\", { x: 3, y: 3 });\n dir = \"LR\";\n const parents = [\"parent1\", \"parent2\", \"parent3\"];\n const closestParent = findClosestParent(parents);\n expect(closestParent).toBe(\"parent3\");\n commitPos.clear();\n });\n}\n\n// src/diagrams/git/styles.js\nvar getStyles = /* @__PURE__ */ __name((options) => `\n .commit-id,\n .commit-msg,\n .branch-label {\n fill: lightgrey;\n color: lightgrey;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n }\n ${[0, 1, 2, 3, 4, 5, 6, 7].map(\n (i) => `\n .branch-label${i} { fill: ${options[\"gitBranchLabel\" + i]}; }\n .commit${i} { stroke: ${options[\"git\" + i]}; fill: ${options[\"git\" + i]}; }\n .commit-highlight${i} { stroke: ${options[\"gitInv\" + i]}; fill: ${options[\"gitInv\" + i]}; }\n .label${i} { fill: ${options[\"git\" + i]}; }\n .arrow${i} { stroke: ${options[\"git\" + i]}; }\n `\n).join(\"\\n\")}\n\n .branch {\n stroke-width: 1;\n stroke: ${options.lineColor};\n stroke-dasharray: 2;\n }\n .commit-label { font-size: ${options.commitLabelFontSize}; fill: ${options.commitLabelColor};}\n .commit-label-bkg { font-size: ${options.commitLabelFontSize}; fill: ${options.commitLabelBackground}; opacity: 0.5; }\n .tag-label { font-size: ${options.tagLabelFontSize}; fill: ${options.tagLabelColor};}\n .tag-label-bkg { fill: ${options.tagLabelBackground}; stroke: ${options.tagLabelBorder}; }\n .tag-hole { fill: ${options.textColor}; }\n\n .commit-merge {\n stroke: ${options.primaryColor};\n fill: ${options.primaryColor};\n }\n .commit-reverse {\n stroke: ${options.primaryColor};\n fill: ${options.primaryColor};\n stroke-width: 3;\n }\n .commit-highlight-outer {\n }\n .commit-highlight-inner {\n stroke: ${options.primaryColor};\n fill: ${options.primaryColor};\n }\n\n .arrow { stroke-width: 8; stroke-linecap: round; fill: none}\n .gitTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${options.textColor};\n }\n`, \"getStyles\");\nvar styles_default = getStyles;\n\n// src/diagrams/git/gitGraphDiagram.ts\nvar diagram = {\n parser,\n db,\n renderer: gitGraphRenderer_default,\n styles: styles_default\n};\nexport {\n diagram\n};\n", "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_isoWeek=t()}(this,(function(){\"use strict\";var e=\"day\";return function(t,i,s){var a=function(t){return t.add(4-t.isoWeekday(),e)},d=i.prototype;d.isoWeekYear=function(){return a(this).year()},d.isoWeek=function(t){if(!this.$utils().u(t))return this.add(7*(t-this.isoWeek()),e);var i,d,n,o,r=a(this),u=(i=this.isoWeekYear(),d=this.$u,n=(d?s.utc:s)().year(i).startOf(\"year\"),o=4-n.isoWeekday(),n.isoWeekday()>4&&(o+=7),n.add(o,e));return r.diff(u,\"week\")+1},d.isoWeekday=function(e){return this.$utils().u(e)?this.day()||7:this.day(this.day()%7?e:e-7)};var n=d.startOf;d.startOf=function(e,t){var i=this.$utils(),s=!!i.u(t)||t;return\"isoweek\"===i.p(e)?s?this.date(this.date()-(this.isoWeekday()-1)).startOf(\"day\"):this.date(this.date()-1-(this.isoWeekday()-1)+7).endOf(\"day\"):n.bind(this)(e,t)}}}));", "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_customParseFormat=t()}(this,(function(){\"use strict\";var e={LTS:\"h:mm:ss A\",LT:\"h:mm A\",L:\"MM/DD/YYYY\",LL:\"MMMM D, YYYY\",LLL:\"MMMM D, YYYY h:mm A\",LLLL:\"dddd, MMMM D, YYYY h:mm A\"},t=/(\\[[^[]*\\])|([-_:/.,()\\s]+)|(A|a|Q|YYYY|YY?|ww?|MM?M?M?|Do|DD?|hh?|HH?|mm?|ss?|S{1,3}|z|ZZ?)/g,n=/\\d/,r=/\\d\\d/,i=/\\d\\d?/,o=/\\d*[^-_:/,()\\s\\d]+/,s={},a=function(e){return(e=+e)+(e>68?1900:2e3)};var f=function(e){return function(t){this[e]=+t}},h=[/[+-]\\d\\d:?(\\d\\d)?|Z/,function(e){(this.zone||(this.zone={})).offset=function(e){if(!e)return 0;if(\"Z\"===e)return 0;var t=e.match(/([+-]|\\d\\d)/g),n=60*t[1]+(+t[2]||0);return 0===n?0:\"+\"===t[0]?-n:n}(e)}],u=function(e){var t=s[e];return t&&(t.indexOf?t:t.s.concat(t.f))},d=function(e,t){var n,r=s.meridiem;if(r){for(var i=1;i<=24;i+=1)if(e.indexOf(r(i,0,t))>-1){n=i>12;break}}else n=e===(t?\"pm\":\"PM\");return n},c={A:[o,function(e){this.afternoon=d(e,!1)}],a:[o,function(e){this.afternoon=d(e,!0)}],Q:[n,function(e){this.month=3*(e-1)+1}],S:[n,function(e){this.milliseconds=100*+e}],SS:[r,function(e){this.milliseconds=10*+e}],SSS:[/\\d{3}/,function(e){this.milliseconds=+e}],s:[i,f(\"seconds\")],ss:[i,f(\"seconds\")],m:[i,f(\"minutes\")],mm:[i,f(\"minutes\")],H:[i,f(\"hours\")],h:[i,f(\"hours\")],HH:[i,f(\"hours\")],hh:[i,f(\"hours\")],D:[i,f(\"day\")],DD:[r,f(\"day\")],Do:[o,function(e){var t=s.ordinal,n=e.match(/\\d+/);if(this.day=n[0],t)for(var r=1;r<=31;r+=1)t(r).replace(/\\[|\\]/g,\"\")===e&&(this.day=r)}],w:[i,f(\"week\")],ww:[r,f(\"week\")],M:[i,f(\"month\")],MM:[r,f(\"month\")],MMM:[o,function(e){var t=u(\"months\"),n=(u(\"monthsShort\")||t.map((function(e){return e.slice(0,3)}))).indexOf(e)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[o,function(e){var t=u(\"months\").indexOf(e)+1;if(t<1)throw new Error;this.month=t%12||t}],Y:[/[+-]?\\d+/,f(\"year\")],YY:[r,function(e){this.year=a(e)}],YYYY:[/\\d{4}/,f(\"year\")],Z:h,ZZ:h};function l(n){var r,i;r=n,i=s&&s.formats;for(var o=(n=r.replace(/(\\[[^\\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(t,n,r){var o=r&&r.toUpperCase();return n||i[r]||e[r]||i[o].replace(/(\\[[^\\]]+])|(MMMM|MM|DD|dddd)/g,(function(e,t,n){return t||n.slice(1)}))}))).match(t),a=o.length,f=0;f-1)return new Date((\"X\"===t?1e3:1)*e);var i=l(t)(e),o=i.year,s=i.month,a=i.day,f=i.hours,h=i.minutes,u=i.seconds,d=i.milliseconds,c=i.zone,m=i.week,M=new Date,Y=a||(o||s?1:M.getDate()),p=o||M.getFullYear(),v=0;o&&!s||(v=s>0?s-1:M.getMonth());var D,w=f||0,g=h||0,y=u||0,L=d||0;return c?new Date(Date.UTC(p,v,Y,w,g,y,L+60*c.offset*1e3)):n?new Date(Date.UTC(p,v,Y,w,g,y,L)):(D=new Date(p,v,Y,w,g,y,L),m&&(D=r(D).week(m).toDate()),D)}catch(e){return new Date(\"\")}}(t,a,r,n),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&t!=this.format(a)&&(this.$d=new Date(\"\")),s={}}else if(a instanceof Array)for(var c=a.length,m=1;m<=c;m+=1){o[1]=a[m-1];var M=n.apply(this,o);if(M.isValid()){this.$d=M.$d,this.$L=M.$L,this.init();break}m===c&&(this.$d=new Date(\"\"))}else i.call(this,e)}}}));", "!function(e,t){\"object\"==typeof exports&&\"undefined\"!=typeof module?module.exports=t():\"function\"==typeof define&&define.amd?define(t):(e=\"undefined\"!=typeof globalThis?globalThis:e||self).dayjs_plugin_advancedFormat=t()}(this,(function(){\"use strict\";return function(e,t){var r=t.prototype,n=r.format;r.format=function(e){var t=this,r=this.$locale();if(!this.isValid())return n.bind(this)(e);var s=this.$utils(),a=(e||\"YYYY-MM-DDTHH:mm:ssZ\").replace(/\\[([^\\]]+)]|Q|wo|ww|w|WW|W|zzz|z|gggg|GGGG|Do|X|x|k{1,2}|S/g,(function(e){switch(e){case\"Q\":return Math.ceil((t.$M+1)/3);case\"Do\":return r.ordinal(t.$D);case\"gggg\":return t.weekYear();case\"GGGG\":return t.isoWeekYear();case\"wo\":return r.ordinal(t.week(),\"W\");case\"w\":case\"ww\":return s.s(t.week(),\"w\"===e?1:2,\"0\");case\"W\":case\"WW\":return s.s(t.isoWeek(),\"W\"===e?1:2,\"0\");case\"k\":case\"kk\":return s.s(String(0===t.$H?24:t.$H),\"k\"===e?1:2,\"0\");case\"X\":return Math.floor(t.$d.getTime()/1e3);case\"x\":return t.$d.getTime();case\"z\":return\"[\"+t.offsetName()+\"]\";case\"zzz\":return\"[\"+t.offsetName(\"long\")+\"]\";default:return e}}));return n.bind(this)(a)}}}));", "import {\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n clear,\n common_default,\n configureSvgSize,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n getDiagramTitle,\n log,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/gantt/parser/gantt.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [6, 8, 10, 12, 13, 14, 15, 16, 17, 18, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 33, 35, 36, 38, 40], $V1 = [1, 26], $V2 = [1, 27], $V3 = [1, 28], $V4 = [1, 29], $V5 = [1, 30], $V6 = [1, 31], $V7 = [1, 32], $V8 = [1, 33], $V9 = [1, 34], $Va = [1, 9], $Vb = [1, 10], $Vc = [1, 11], $Vd = [1, 12], $Ve = [1, 13], $Vf = [1, 14], $Vg = [1, 15], $Vh = [1, 16], $Vi = [1, 19], $Vj = [1, 20], $Vk = [1, 21], $Vl = [1, 22], $Vm = [1, 23], $Vn = [1, 25], $Vo = [1, 35];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"gantt\": 4, \"document\": 5, \"EOF\": 6, \"line\": 7, \"SPACE\": 8, \"statement\": 9, \"NL\": 10, \"weekday\": 11, \"weekday_monday\": 12, \"weekday_tuesday\": 13, \"weekday_wednesday\": 14, \"weekday_thursday\": 15, \"weekday_friday\": 16, \"weekday_saturday\": 17, \"weekday_sunday\": 18, \"weekend\": 19, \"weekend_friday\": 20, \"weekend_saturday\": 21, \"dateFormat\": 22, \"inclusiveEndDates\": 23, \"topAxis\": 24, \"axisFormat\": 25, \"tickInterval\": 26, \"excludes\": 27, \"includes\": 28, \"todayMarker\": 29, \"title\": 30, \"acc_title\": 31, \"acc_title_value\": 32, \"acc_descr\": 33, \"acc_descr_value\": 34, \"acc_descr_multiline_value\": 35, \"section\": 36, \"clickStatement\": 37, \"taskTxt\": 38, \"taskData\": 39, \"click\": 40, \"callbackname\": 41, \"callbackargs\": 42, \"href\": 43, \"clickStatementDebug\": 44, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 4: \"gantt\", 6: \"EOF\", 8: \"SPACE\", 10: \"NL\", 12: \"weekday_monday\", 13: \"weekday_tuesday\", 14: \"weekday_wednesday\", 15: \"weekday_thursday\", 16: \"weekday_friday\", 17: \"weekday_saturday\", 18: \"weekday_sunday\", 20: \"weekend_friday\", 21: \"weekend_saturday\", 22: \"dateFormat\", 23: \"inclusiveEndDates\", 24: \"topAxis\", 25: \"axisFormat\", 26: \"tickInterval\", 27: \"excludes\", 28: \"includes\", 29: \"todayMarker\", 30: \"title\", 31: \"acc_title\", 32: \"acc_title_value\", 33: \"acc_descr\", 34: \"acc_descr_value\", 35: \"acc_descr_multiline_value\", 36: \"section\", 38: \"taskTxt\", 39: \"taskData\", 40: \"click\", 41: \"callbackname\", 42: \"callbackargs\", 43: \"href\" },\n productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [11, 1], [19, 1], [19, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 1], [9, 2], [37, 2], [37, 3], [37, 3], [37, 4], [37, 3], [37, 4], [37, 2], [44, 2], [44, 3], [44, 3], [44, 4], [44, 3], [44, 4], [44, 2]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 1:\n return $$[$0 - 1];\n break;\n case 2:\n this.$ = [];\n break;\n case 3:\n $$[$0 - 1].push($$[$0]);\n this.$ = $$[$0 - 1];\n break;\n case 4:\n case 5:\n this.$ = $$[$0];\n break;\n case 6:\n case 7:\n this.$ = [];\n break;\n case 8:\n yy.setWeekday(\"monday\");\n break;\n case 9:\n yy.setWeekday(\"tuesday\");\n break;\n case 10:\n yy.setWeekday(\"wednesday\");\n break;\n case 11:\n yy.setWeekday(\"thursday\");\n break;\n case 12:\n yy.setWeekday(\"friday\");\n break;\n case 13:\n yy.setWeekday(\"saturday\");\n break;\n case 14:\n yy.setWeekday(\"sunday\");\n break;\n case 15:\n yy.setWeekend(\"friday\");\n break;\n case 16:\n yy.setWeekend(\"saturday\");\n break;\n case 17:\n yy.setDateFormat($$[$0].substr(11));\n this.$ = $$[$0].substr(11);\n break;\n case 18:\n yy.enableInclusiveEndDates();\n this.$ = $$[$0].substr(18);\n break;\n case 19:\n yy.TopAxis();\n this.$ = $$[$0].substr(8);\n break;\n case 20:\n yy.setAxisFormat($$[$0].substr(11));\n this.$ = $$[$0].substr(11);\n break;\n case 21:\n yy.setTickInterval($$[$0].substr(13));\n this.$ = $$[$0].substr(13);\n break;\n case 22:\n yy.setExcludes($$[$0].substr(9));\n this.$ = $$[$0].substr(9);\n break;\n case 23:\n yy.setIncludes($$[$0].substr(9));\n this.$ = $$[$0].substr(9);\n break;\n case 24:\n yy.setTodayMarker($$[$0].substr(12));\n this.$ = $$[$0].substr(12);\n break;\n case 27:\n yy.setDiagramTitle($$[$0].substr(6));\n this.$ = $$[$0].substr(6);\n break;\n case 28:\n this.$ = $$[$0].trim();\n yy.setAccTitle(this.$);\n break;\n case 29:\n case 30:\n this.$ = $$[$0].trim();\n yy.setAccDescription(this.$);\n break;\n case 31:\n yy.addSection($$[$0].substr(8));\n this.$ = $$[$0].substr(8);\n break;\n case 33:\n yy.addTask($$[$0 - 1], $$[$0]);\n this.$ = \"task\";\n break;\n case 34:\n this.$ = $$[$0 - 1];\n yy.setClickEvent($$[$0 - 1], $$[$0], null);\n break;\n case 35:\n this.$ = $$[$0 - 2];\n yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]);\n break;\n case 36:\n this.$ = $$[$0 - 2];\n yy.setClickEvent($$[$0 - 2], $$[$0 - 1], null);\n yy.setLink($$[$0 - 2], $$[$0]);\n break;\n case 37:\n this.$ = $$[$0 - 3];\n yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]);\n yy.setLink($$[$0 - 3], $$[$0]);\n break;\n case 38:\n this.$ = $$[$0 - 2];\n yy.setClickEvent($$[$0 - 2], $$[$0], null);\n yy.setLink($$[$0 - 2], $$[$0 - 1]);\n break;\n case 39:\n this.$ = $$[$0 - 3];\n yy.setClickEvent($$[$0 - 3], $$[$0 - 1], $$[$0]);\n yy.setLink($$[$0 - 3], $$[$0 - 2]);\n break;\n case 40:\n this.$ = $$[$0 - 1];\n yy.setLink($$[$0 - 1], $$[$0]);\n break;\n case 41:\n case 47:\n this.$ = $$[$0 - 1] + \" \" + $$[$0];\n break;\n case 42:\n case 43:\n case 45:\n this.$ = $$[$0 - 2] + \" \" + $$[$0 - 1] + \" \" + $$[$0];\n break;\n case 44:\n case 46:\n this.$ = $$[$0 - 3] + \" \" + $$[$0 - 2] + \" \" + $$[$0 - 1] + \" \" + $$[$0];\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: 17, 12: $V1, 13: $V2, 14: $V3, 15: $V4, 16: $V5, 17: $V6, 18: $V7, 19: 18, 20: $V8, 21: $V9, 22: $Va, 23: $Vb, 24: $Vc, 25: $Vd, 26: $Ve, 27: $Vf, 28: $Vg, 29: $Vh, 30: $Vi, 31: $Vj, 33: $Vk, 35: $Vl, 36: $Vm, 37: 24, 38: $Vn, 40: $Vo }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 36, 11: 17, 12: $V1, 13: $V2, 14: $V3, 15: $V4, 16: $V5, 17: $V6, 18: $V7, 19: 18, 20: $V8, 21: $V9, 22: $Va, 23: $Vb, 24: $Vc, 25: $Vd, 26: $Ve, 27: $Vf, 28: $Vg, 29: $Vh, 30: $Vi, 31: $Vj, 33: $Vk, 35: $Vl, 36: $Vm, 37: 24, 38: $Vn, 40: $Vo }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 17]), o($V0, [2, 18]), o($V0, [2, 19]), o($V0, [2, 20]), o($V0, [2, 21]), o($V0, [2, 22]), o($V0, [2, 23]), o($V0, [2, 24]), o($V0, [2, 25]), o($V0, [2, 26]), o($V0, [2, 27]), { 32: [1, 37] }, { 34: [1, 38] }, o($V0, [2, 30]), o($V0, [2, 31]), o($V0, [2, 32]), { 39: [1, 39] }, o($V0, [2, 8]), o($V0, [2, 9]), o($V0, [2, 10]), o($V0, [2, 11]), o($V0, [2, 12]), o($V0, [2, 13]), o($V0, [2, 14]), o($V0, [2, 15]), o($V0, [2, 16]), { 41: [1, 40], 43: [1, 41] }, o($V0, [2, 4]), o($V0, [2, 28]), o($V0, [2, 29]), o($V0, [2, 33]), o($V0, [2, 34], { 42: [1, 42], 43: [1, 43] }), o($V0, [2, 40], { 41: [1, 44] }), o($V0, [2, 35], { 43: [1, 45] }), o($V0, [2, 36]), o($V0, [2, 38], { 42: [1, 46] }), o($V0, [2, 37]), o($V0, [2, 39])],\n defaultActions: {},\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n this.begin(\"open_directive\");\n return \"open_directive\";\n break;\n case 1:\n this.begin(\"acc_title\");\n return 31;\n break;\n case 2:\n this.popState();\n return \"acc_title_value\";\n break;\n case 3:\n this.begin(\"acc_descr\");\n return 33;\n break;\n case 4:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 5:\n this.begin(\"acc_descr_multiline\");\n break;\n case 6:\n this.popState();\n break;\n case 7:\n return \"acc_descr_multiline_value\";\n break;\n case 8:\n break;\n case 9:\n break;\n case 10:\n break;\n case 11:\n return 10;\n break;\n case 12:\n break;\n case 13:\n break;\n case 14:\n this.begin(\"href\");\n break;\n case 15:\n this.popState();\n break;\n case 16:\n return 43;\n break;\n case 17:\n this.begin(\"callbackname\");\n break;\n case 18:\n this.popState();\n break;\n case 19:\n this.popState();\n this.begin(\"callbackargs\");\n break;\n case 20:\n return 41;\n break;\n case 21:\n this.popState();\n break;\n case 22:\n return 42;\n break;\n case 23:\n this.begin(\"click\");\n break;\n case 24:\n this.popState();\n break;\n case 25:\n return 40;\n break;\n case 26:\n return 4;\n break;\n case 27:\n return 22;\n break;\n case 28:\n return 23;\n break;\n case 29:\n return 24;\n break;\n case 30:\n return 25;\n break;\n case 31:\n return 26;\n break;\n case 32:\n return 28;\n break;\n case 33:\n return 27;\n break;\n case 34:\n return 29;\n break;\n case 35:\n return 12;\n break;\n case 36:\n return 13;\n break;\n case 37:\n return 14;\n break;\n case 38:\n return 15;\n break;\n case 39:\n return 16;\n break;\n case 40:\n return 17;\n break;\n case 41:\n return 18;\n break;\n case 42:\n return 20;\n break;\n case 43:\n return 21;\n break;\n case 44:\n return \"date\";\n break;\n case 45:\n return 30;\n break;\n case 46:\n return \"accDescription\";\n break;\n case 47:\n return 36;\n break;\n case 48:\n return 38;\n break;\n case 49:\n return 39;\n break;\n case 50:\n return \":\";\n break;\n case 51:\n return 6;\n break;\n case 52:\n return \"INVALID\";\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:%%\\{)/i, /^(?:accTitle\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*\\{\\s*)/i, /^(?:[\\}])/i, /^(?:[^\\}]*)/i, /^(?:%%(?!\\{)*[^\\n]*)/i, /^(?:[^\\}]%%*[^\\n]*)/i, /^(?:%%*[^\\n]*[\\n]*)/i, /^(?:[\\n]+)/i, /^(?:\\s+)/i, /^(?:%[^\\n]*)/i, /^(?:href[\\s]+[\"])/i, /^(?:[\"])/i, /^(?:[^\"]*)/i, /^(?:call[\\s]+)/i, /^(?:\\([\\s]*\\))/i, /^(?:\\()/i, /^(?:[^(]*)/i, /^(?:\\))/i, /^(?:[^)]*)/i, /^(?:click[\\s]+)/i, /^(?:[\\s\\n])/i, /^(?:[^\\s\\n]*)/i, /^(?:gantt\\b)/i, /^(?:dateFormat\\s[^#\\n;]+)/i, /^(?:inclusiveEndDates\\b)/i, /^(?:topAxis\\b)/i, /^(?:axisFormat\\s[^#\\n;]+)/i, /^(?:tickInterval\\s[^#\\n;]+)/i, /^(?:includes\\s[^#\\n;]+)/i, /^(?:excludes\\s[^#\\n;]+)/i, /^(?:todayMarker\\s[^\\n;]+)/i, /^(?:weekday\\s+monday\\b)/i, /^(?:weekday\\s+tuesday\\b)/i, /^(?:weekday\\s+wednesday\\b)/i, /^(?:weekday\\s+thursday\\b)/i, /^(?:weekday\\s+friday\\b)/i, /^(?:weekday\\s+saturday\\b)/i, /^(?:weekday\\s+sunday\\b)/i, /^(?:weekend\\s+friday\\b)/i, /^(?:weekend\\s+saturday\\b)/i, /^(?:\\d\\d\\d\\d-\\d\\d-\\d\\d\\b)/i, /^(?:title\\s[^\\n]+)/i, /^(?:accDescription\\s[^#\\n;]+)/i, /^(?:section\\s[^\\n]+)/i, /^(?:[^:\\n]+)/i, /^(?::[^#\\n;]+)/i, /^(?::)/i, /^(?:$)/i, /^(?:.)/i],\n conditions: { \"acc_descr_multiline\": { \"rules\": [6, 7], \"inclusive\": false }, \"acc_descr\": { \"rules\": [4], \"inclusive\": false }, \"acc_title\": { \"rules\": [2], \"inclusive\": false }, \"callbackargs\": { \"rules\": [21, 22], \"inclusive\": false }, \"callbackname\": { \"rules\": [18, 19, 20], \"inclusive\": false }, \"href\": { \"rules\": [15, 16], \"inclusive\": false }, \"click\": { \"rules\": [24, 25], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 17, 23, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar gantt_default = parser;\n\n// src/diagrams/gantt/ganttDb.js\nimport { sanitizeUrl } from \"@braintree/sanitize-url\";\nimport dayjs from \"dayjs\";\nimport dayjsIsoWeek from \"dayjs/plugin/isoWeek.js\";\nimport dayjsCustomParseFormat from \"dayjs/plugin/customParseFormat.js\";\nimport dayjsAdvancedFormat from \"dayjs/plugin/advancedFormat.js\";\ndayjs.extend(dayjsIsoWeek);\ndayjs.extend(dayjsCustomParseFormat);\ndayjs.extend(dayjsAdvancedFormat);\nvar WEEKEND_START_DAY = { friday: 5, saturday: 6 };\nvar dateFormat = \"\";\nvar axisFormat = \"\";\nvar tickInterval = void 0;\nvar todayMarker = \"\";\nvar includes = [];\nvar excludes = [];\nvar links = /* @__PURE__ */ new Map();\nvar sections = [];\nvar tasks = [];\nvar currentSection = \"\";\nvar displayMode = \"\";\nvar tags = [\"active\", \"done\", \"crit\", \"milestone\"];\nvar funs = [];\nvar inclusiveEndDates = false;\nvar topAxis = false;\nvar weekday = \"sunday\";\nvar weekend = \"saturday\";\nvar lastOrder = 0;\nvar clear2 = /* @__PURE__ */ __name(function() {\n sections = [];\n tasks = [];\n currentSection = \"\";\n funs = [];\n taskCnt = 0;\n lastTask = void 0;\n lastTaskID = void 0;\n rawTasks = [];\n dateFormat = \"\";\n axisFormat = \"\";\n displayMode = \"\";\n tickInterval = void 0;\n todayMarker = \"\";\n includes = [];\n excludes = [];\n inclusiveEndDates = false;\n topAxis = false;\n lastOrder = 0;\n links = /* @__PURE__ */ new Map();\n clear();\n weekday = \"sunday\";\n weekend = \"saturday\";\n}, \"clear\");\nvar setAxisFormat = /* @__PURE__ */ __name(function(txt) {\n axisFormat = txt;\n}, \"setAxisFormat\");\nvar getAxisFormat = /* @__PURE__ */ __name(function() {\n return axisFormat;\n}, \"getAxisFormat\");\nvar setTickInterval = /* @__PURE__ */ __name(function(txt) {\n tickInterval = txt;\n}, \"setTickInterval\");\nvar getTickInterval = /* @__PURE__ */ __name(function() {\n return tickInterval;\n}, \"getTickInterval\");\nvar setTodayMarker = /* @__PURE__ */ __name(function(txt) {\n todayMarker = txt;\n}, \"setTodayMarker\");\nvar getTodayMarker = /* @__PURE__ */ __name(function() {\n return todayMarker;\n}, \"getTodayMarker\");\nvar setDateFormat = /* @__PURE__ */ __name(function(txt) {\n dateFormat = txt;\n}, \"setDateFormat\");\nvar enableInclusiveEndDates = /* @__PURE__ */ __name(function() {\n inclusiveEndDates = true;\n}, \"enableInclusiveEndDates\");\nvar endDatesAreInclusive = /* @__PURE__ */ __name(function() {\n return inclusiveEndDates;\n}, \"endDatesAreInclusive\");\nvar enableTopAxis = /* @__PURE__ */ __name(function() {\n topAxis = true;\n}, \"enableTopAxis\");\nvar topAxisEnabled = /* @__PURE__ */ __name(function() {\n return topAxis;\n}, \"topAxisEnabled\");\nvar setDisplayMode = /* @__PURE__ */ __name(function(txt) {\n displayMode = txt;\n}, \"setDisplayMode\");\nvar getDisplayMode = /* @__PURE__ */ __name(function() {\n return displayMode;\n}, \"getDisplayMode\");\nvar getDateFormat = /* @__PURE__ */ __name(function() {\n return dateFormat;\n}, \"getDateFormat\");\nvar setIncludes = /* @__PURE__ */ __name(function(txt) {\n includes = txt.toLowerCase().split(/[\\s,]+/);\n}, \"setIncludes\");\nvar getIncludes = /* @__PURE__ */ __name(function() {\n return includes;\n}, \"getIncludes\");\nvar setExcludes = /* @__PURE__ */ __name(function(txt) {\n excludes = txt.toLowerCase().split(/[\\s,]+/);\n}, \"setExcludes\");\nvar getExcludes = /* @__PURE__ */ __name(function() {\n return excludes;\n}, \"getExcludes\");\nvar getLinks = /* @__PURE__ */ __name(function() {\n return links;\n}, \"getLinks\");\nvar addSection = /* @__PURE__ */ __name(function(txt) {\n currentSection = txt;\n sections.push(txt);\n}, \"addSection\");\nvar getSections = /* @__PURE__ */ __name(function() {\n return sections;\n}, \"getSections\");\nvar getTasks = /* @__PURE__ */ __name(function() {\n let allItemsProcessed = compileTasks();\n const maxDepth = 10;\n let iterationCount = 0;\n while (!allItemsProcessed && iterationCount < maxDepth) {\n allItemsProcessed = compileTasks();\n iterationCount++;\n }\n tasks = rawTasks;\n return tasks;\n}, \"getTasks\");\nvar isInvalidDate = /* @__PURE__ */ __name(function(date, dateFormat2, excludes2, includes2) {\n if (includes2.includes(date.format(dateFormat2.trim()))) {\n return false;\n }\n if (excludes2.includes(\"weekends\") && (date.isoWeekday() === WEEKEND_START_DAY[weekend] || date.isoWeekday() === WEEKEND_START_DAY[weekend] + 1)) {\n return true;\n }\n if (excludes2.includes(date.format(\"dddd\").toLowerCase())) {\n return true;\n }\n return excludes2.includes(date.format(dateFormat2.trim()));\n}, \"isInvalidDate\");\nvar setWeekday = /* @__PURE__ */ __name(function(txt) {\n weekday = txt;\n}, \"setWeekday\");\nvar getWeekday = /* @__PURE__ */ __name(function() {\n return weekday;\n}, \"getWeekday\");\nvar setWeekend = /* @__PURE__ */ __name(function(startDay) {\n weekend = startDay;\n}, \"setWeekend\");\nvar checkTaskDates = /* @__PURE__ */ __name(function(task, dateFormat2, excludes2, includes2) {\n if (!excludes2.length || task.manualEndTime) {\n return;\n }\n let startTime;\n if (task.startTime instanceof Date) {\n startTime = dayjs(task.startTime);\n } else {\n startTime = dayjs(task.startTime, dateFormat2, true);\n }\n startTime = startTime.add(1, \"d\");\n let originalEndTime;\n if (task.endTime instanceof Date) {\n originalEndTime = dayjs(task.endTime);\n } else {\n originalEndTime = dayjs(task.endTime, dateFormat2, true);\n }\n const [fixedEndTime, renderEndTime] = fixTaskDates(\n startTime,\n originalEndTime,\n dateFormat2,\n excludes2,\n includes2\n );\n task.endTime = fixedEndTime.toDate();\n task.renderEndTime = renderEndTime;\n}, \"checkTaskDates\");\nvar fixTaskDates = /* @__PURE__ */ __name(function(startTime, endTime, dateFormat2, excludes2, includes2) {\n let invalid = false;\n let renderEndTime = null;\n while (startTime <= endTime) {\n if (!invalid) {\n renderEndTime = endTime.toDate();\n }\n invalid = isInvalidDate(startTime, dateFormat2, excludes2, includes2);\n if (invalid) {\n endTime = endTime.add(1, \"d\");\n }\n startTime = startTime.add(1, \"d\");\n }\n return [endTime, renderEndTime];\n}, \"fixTaskDates\");\nvar getStartDate = /* @__PURE__ */ __name(function(prevTime, dateFormat2, str) {\n str = str.trim();\n const afterRePattern = /^after\\s+(?[\\d\\w- ]+)/;\n const afterStatement = afterRePattern.exec(str);\n if (afterStatement !== null) {\n let latestTask = null;\n for (const id of afterStatement.groups.ids.split(\" \")) {\n let task = findTaskById(id);\n if (task !== void 0 && (!latestTask || task.endTime > latestTask.endTime)) {\n latestTask = task;\n }\n }\n if (latestTask) {\n return latestTask.endTime;\n }\n const today = /* @__PURE__ */ new Date();\n today.setHours(0, 0, 0, 0);\n return today;\n }\n let mDate = dayjs(str, dateFormat2.trim(), true);\n if (mDate.isValid()) {\n return mDate.toDate();\n } else {\n log.debug(\"Invalid date:\" + str);\n log.debug(\"With date format:\" + dateFormat2.trim());\n const d = new Date(str);\n if (d === void 0 || isNaN(d.getTime()) || // WebKit browsers can mis-parse invalid dates to be ridiculously\n // huge numbers, e.g. new Date('202304') gets parsed as January 1, 202304.\n // This can cause virtually infinite loops while rendering, so for the\n // purposes of Gantt charts we'll just treat any date beyond 10,000 AD/BC as\n // invalid.\n d.getFullYear() < -1e4 || d.getFullYear() > 1e4) {\n throw new Error(\"Invalid date:\" + str);\n }\n return d;\n }\n}, \"getStartDate\");\nvar parseDuration = /* @__PURE__ */ __name(function(str) {\n const statement = /^(\\d+(?:\\.\\d+)?)([Mdhmswy]|ms)$/.exec(str.trim());\n if (statement !== null) {\n return [Number.parseFloat(statement[1]), statement[2]];\n }\n return [NaN, \"ms\"];\n}, \"parseDuration\");\nvar getEndDate = /* @__PURE__ */ __name(function(prevTime, dateFormat2, str, inclusive = false) {\n str = str.trim();\n const untilRePattern = /^until\\s+(?[\\d\\w- ]+)/;\n const untilStatement = untilRePattern.exec(str);\n if (untilStatement !== null) {\n let earliestTask = null;\n for (const id of untilStatement.groups.ids.split(\" \")) {\n let task = findTaskById(id);\n if (task !== void 0 && (!earliestTask || task.startTime < earliestTask.startTime)) {\n earliestTask = task;\n }\n }\n if (earliestTask) {\n return earliestTask.startTime;\n }\n const today = /* @__PURE__ */ new Date();\n today.setHours(0, 0, 0, 0);\n return today;\n }\n let parsedDate = dayjs(str, dateFormat2.trim(), true);\n if (parsedDate.isValid()) {\n if (inclusive) {\n parsedDate = parsedDate.add(1, \"d\");\n }\n return parsedDate.toDate();\n }\n let endTime = dayjs(prevTime);\n const [durationValue, durationUnit] = parseDuration(str);\n if (!Number.isNaN(durationValue)) {\n const newEndTime = endTime.add(durationValue, durationUnit);\n if (newEndTime.isValid()) {\n endTime = newEndTime;\n }\n }\n return endTime.toDate();\n}, \"getEndDate\");\nvar taskCnt = 0;\nvar parseId = /* @__PURE__ */ __name(function(idStr) {\n if (idStr === void 0) {\n taskCnt = taskCnt + 1;\n return \"task\" + taskCnt;\n }\n return idStr;\n}, \"parseId\");\nvar compileData = /* @__PURE__ */ __name(function(prevTask, dataStr) {\n let ds;\n if (dataStr.substr(0, 1) === \":\") {\n ds = dataStr.substr(1, dataStr.length);\n } else {\n ds = dataStr;\n }\n const data = ds.split(\",\");\n const task = {};\n getTaskTags(data, task, tags);\n for (let i = 0; i < data.length; i++) {\n data[i] = data[i].trim();\n }\n let endTimeData = \"\";\n switch (data.length) {\n case 1:\n task.id = parseId();\n task.startTime = prevTask.endTime;\n endTimeData = data[0];\n break;\n case 2:\n task.id = parseId();\n task.startTime = getStartDate(void 0, dateFormat, data[0]);\n endTimeData = data[1];\n break;\n case 3:\n task.id = parseId(data[0]);\n task.startTime = getStartDate(void 0, dateFormat, data[1]);\n endTimeData = data[2];\n break;\n default:\n }\n if (endTimeData) {\n task.endTime = getEndDate(task.startTime, dateFormat, endTimeData, inclusiveEndDates);\n task.manualEndTime = dayjs(endTimeData, \"YYYY-MM-DD\", true).isValid();\n checkTaskDates(task, dateFormat, excludes, includes);\n }\n return task;\n}, \"compileData\");\nvar parseData = /* @__PURE__ */ __name(function(prevTaskId, dataStr) {\n let ds;\n if (dataStr.substr(0, 1) === \":\") {\n ds = dataStr.substr(1, dataStr.length);\n } else {\n ds = dataStr;\n }\n const data = ds.split(\",\");\n const task = {};\n getTaskTags(data, task, tags);\n for (let i = 0; i < data.length; i++) {\n data[i] = data[i].trim();\n }\n switch (data.length) {\n case 1:\n task.id = parseId();\n task.startTime = {\n type: \"prevTaskEnd\",\n id: prevTaskId\n };\n task.endTime = {\n data: data[0]\n };\n break;\n case 2:\n task.id = parseId();\n task.startTime = {\n type: \"getStartDate\",\n startData: data[0]\n };\n task.endTime = {\n data: data[1]\n };\n break;\n case 3:\n task.id = parseId(data[0]);\n task.startTime = {\n type: \"getStartDate\",\n startData: data[1]\n };\n task.endTime = {\n data: data[2]\n };\n break;\n default:\n }\n return task;\n}, \"parseData\");\nvar lastTask;\nvar lastTaskID;\nvar rawTasks = [];\nvar taskDb = {};\nvar addTask = /* @__PURE__ */ __name(function(descr, data) {\n const rawTask = {\n section: currentSection,\n type: currentSection,\n processed: false,\n manualEndTime: false,\n renderEndTime: null,\n raw: { data },\n task: descr,\n classes: []\n };\n const taskInfo = parseData(lastTaskID, data);\n rawTask.raw.startTime = taskInfo.startTime;\n rawTask.raw.endTime = taskInfo.endTime;\n rawTask.id = taskInfo.id;\n rawTask.prevTaskId = lastTaskID;\n rawTask.active = taskInfo.active;\n rawTask.done = taskInfo.done;\n rawTask.crit = taskInfo.crit;\n rawTask.milestone = taskInfo.milestone;\n rawTask.order = lastOrder;\n lastOrder++;\n const pos = rawTasks.push(rawTask);\n lastTaskID = rawTask.id;\n taskDb[rawTask.id] = pos - 1;\n}, \"addTask\");\nvar findTaskById = /* @__PURE__ */ __name(function(id) {\n const pos = taskDb[id];\n return rawTasks[pos];\n}, \"findTaskById\");\nvar addTaskOrg = /* @__PURE__ */ __name(function(descr, data) {\n const newTask = {\n section: currentSection,\n type: currentSection,\n description: descr,\n task: descr,\n classes: []\n };\n const taskInfo = compileData(lastTask, data);\n newTask.startTime = taskInfo.startTime;\n newTask.endTime = taskInfo.endTime;\n newTask.id = taskInfo.id;\n newTask.active = taskInfo.active;\n newTask.done = taskInfo.done;\n newTask.crit = taskInfo.crit;\n newTask.milestone = taskInfo.milestone;\n lastTask = newTask;\n tasks.push(newTask);\n}, \"addTaskOrg\");\nvar compileTasks = /* @__PURE__ */ __name(function() {\n const compileTask = /* @__PURE__ */ __name(function(pos) {\n const task = rawTasks[pos];\n let startTime = \"\";\n switch (rawTasks[pos].raw.startTime.type) {\n case \"prevTaskEnd\": {\n const prevTask = findTaskById(task.prevTaskId);\n task.startTime = prevTask.endTime;\n break;\n }\n case \"getStartDate\":\n startTime = getStartDate(void 0, dateFormat, rawTasks[pos].raw.startTime.startData);\n if (startTime) {\n rawTasks[pos].startTime = startTime;\n }\n break;\n }\n if (rawTasks[pos].startTime) {\n rawTasks[pos].endTime = getEndDate(\n rawTasks[pos].startTime,\n dateFormat,\n rawTasks[pos].raw.endTime.data,\n inclusiveEndDates\n );\n if (rawTasks[pos].endTime) {\n rawTasks[pos].processed = true;\n rawTasks[pos].manualEndTime = dayjs(\n rawTasks[pos].raw.endTime.data,\n \"YYYY-MM-DD\",\n true\n ).isValid();\n checkTaskDates(rawTasks[pos], dateFormat, excludes, includes);\n }\n }\n return rawTasks[pos].processed;\n }, \"compileTask\");\n let allProcessed = true;\n for (const [i, rawTask] of rawTasks.entries()) {\n compileTask(i);\n allProcessed = allProcessed && rawTask.processed;\n }\n return allProcessed;\n}, \"compileTasks\");\nvar setLink = /* @__PURE__ */ __name(function(ids, _linkStr) {\n let linkStr = _linkStr;\n if (getConfig().securityLevel !== \"loose\") {\n linkStr = sanitizeUrl(_linkStr);\n }\n ids.split(\",\").forEach(function(id) {\n let rawTask = findTaskById(id);\n if (rawTask !== void 0) {\n pushFun(id, () => {\n window.open(linkStr, \"_self\");\n });\n links.set(id, linkStr);\n }\n });\n setClass(ids, \"clickable\");\n}, \"setLink\");\nvar setClass = /* @__PURE__ */ __name(function(ids, className) {\n ids.split(\",\").forEach(function(id) {\n let rawTask = findTaskById(id);\n if (rawTask !== void 0) {\n rawTask.classes.push(className);\n }\n });\n}, \"setClass\");\nvar setClickFun = /* @__PURE__ */ __name(function(id, functionName, functionArgs) {\n if (getConfig().securityLevel !== \"loose\") {\n return;\n }\n if (functionName === void 0) {\n return;\n }\n let argList = [];\n if (typeof functionArgs === \"string\") {\n argList = functionArgs.split(/,(?=(?:(?:[^\"]*\"){2})*[^\"]*$)/);\n for (let i = 0; i < argList.length; i++) {\n let item = argList[i].trim();\n if (item.startsWith('\"') && item.endsWith('\"')) {\n item = item.substr(1, item.length - 2);\n }\n argList[i] = item;\n }\n }\n if (argList.length === 0) {\n argList.push(id);\n }\n let rawTask = findTaskById(id);\n if (rawTask !== void 0) {\n pushFun(id, () => {\n utils_default.runFunc(functionName, ...argList);\n });\n }\n}, \"setClickFun\");\nvar pushFun = /* @__PURE__ */ __name(function(id, callbackFunction) {\n funs.push(\n function() {\n const elem = document.querySelector(`[id=\"${id}\"]`);\n if (elem !== null) {\n elem.addEventListener(\"click\", function() {\n callbackFunction();\n });\n }\n },\n function() {\n const elem = document.querySelector(`[id=\"${id}-text\"]`);\n if (elem !== null) {\n elem.addEventListener(\"click\", function() {\n callbackFunction();\n });\n }\n }\n );\n}, \"pushFun\");\nvar setClickEvent = /* @__PURE__ */ __name(function(ids, functionName, functionArgs) {\n ids.split(\",\").forEach(function(id) {\n setClickFun(id, functionName, functionArgs);\n });\n setClass(ids, \"clickable\");\n}, \"setClickEvent\");\nvar bindFunctions = /* @__PURE__ */ __name(function(element) {\n funs.forEach(function(fun) {\n fun(element);\n });\n}, \"bindFunctions\");\nvar ganttDb_default = {\n getConfig: /* @__PURE__ */ __name(() => getConfig().gantt, \"getConfig\"),\n clear: clear2,\n setDateFormat,\n getDateFormat,\n enableInclusiveEndDates,\n endDatesAreInclusive,\n enableTopAxis,\n topAxisEnabled,\n setAxisFormat,\n getAxisFormat,\n setTickInterval,\n getTickInterval,\n setTodayMarker,\n getTodayMarker,\n setAccTitle,\n getAccTitle,\n setDiagramTitle,\n getDiagramTitle,\n setDisplayMode,\n getDisplayMode,\n setAccDescription,\n getAccDescription,\n addSection,\n getSections,\n getTasks,\n addTask,\n findTaskById,\n addTaskOrg,\n setIncludes,\n getIncludes,\n setExcludes,\n getExcludes,\n setClickEvent,\n setLink,\n getLinks,\n bindFunctions,\n parseDuration,\n isInvalidDate,\n setWeekday,\n getWeekday,\n setWeekend\n};\nfunction getTaskTags(data, task, tags2) {\n let matchFound = true;\n while (matchFound) {\n matchFound = false;\n tags2.forEach(function(t) {\n const pattern = \"^\\\\s*\" + t + \"\\\\s*$\";\n const regex = new RegExp(pattern);\n if (data[0].match(regex)) {\n task[t] = true;\n data.shift(1);\n matchFound = true;\n }\n });\n }\n}\n__name(getTaskTags, \"getTaskTags\");\n\n// src/diagrams/gantt/ganttRenderer.js\nimport dayjs2 from \"dayjs\";\nimport {\n select,\n scaleTime,\n min,\n max,\n scaleLinear,\n interpolateHcl,\n axisBottom,\n axisTop,\n timeFormat,\n timeMillisecond,\n timeSecond,\n timeMinute,\n timeHour,\n timeDay,\n timeMonday,\n timeTuesday,\n timeWednesday,\n timeThursday,\n timeFriday,\n timeSaturday,\n timeSunday,\n timeMonth\n} from \"d3\";\nvar setConf = /* @__PURE__ */ __name(function() {\n log.debug(\"Something is calling, setConf, remove the call\");\n}, \"setConf\");\nvar mapWeekdayToTimeFunction = {\n monday: timeMonday,\n tuesday: timeTuesday,\n wednesday: timeWednesday,\n thursday: timeThursday,\n friday: timeFriday,\n saturday: timeSaturday,\n sunday: timeSunday\n};\nvar getMaxIntersections = /* @__PURE__ */ __name((tasks2, orderOffset) => {\n let timeline = [...tasks2].map(() => -Infinity);\n let sorted = [...tasks2].sort((a, b) => a.startTime - b.startTime || a.order - b.order);\n let maxIntersections = 0;\n for (const element of sorted) {\n for (let j = 0; j < timeline.length; j++) {\n if (element.startTime >= timeline[j]) {\n timeline[j] = element.endTime;\n element.order = j + orderOffset;\n if (j > maxIntersections) {\n maxIntersections = j;\n }\n break;\n }\n }\n }\n return maxIntersections;\n}, \"getMaxIntersections\");\nvar w;\nvar draw = /* @__PURE__ */ __name(function(text, id, version, diagObj) {\n const conf = getConfig().gantt;\n const securityLevel = getConfig().securityLevel;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select(sandboxElement.nodes()[0].contentDocument.body) : select(\"body\");\n const doc = securityLevel === \"sandbox\" ? sandboxElement.nodes()[0].contentDocument : document;\n const elem = doc.getElementById(id);\n w = elem.parentElement.offsetWidth;\n if (w === void 0) {\n w = 1200;\n }\n if (conf.useWidth !== void 0) {\n w = conf.useWidth;\n }\n const taskArray = diagObj.db.getTasks();\n let categories = [];\n for (const element of taskArray) {\n categories.push(element.type);\n }\n categories = checkUnique(categories);\n const categoryHeights = {};\n let h = 2 * conf.topPadding;\n if (diagObj.db.getDisplayMode() === \"compact\" || conf.displayMode === \"compact\") {\n const categoryElements = {};\n for (const element of taskArray) {\n if (categoryElements[element.section] === void 0) {\n categoryElements[element.section] = [element];\n } else {\n categoryElements[element.section].push(element);\n }\n }\n let intersections = 0;\n for (const category of Object.keys(categoryElements)) {\n const categoryHeight = getMaxIntersections(categoryElements[category], intersections) + 1;\n intersections += categoryHeight;\n h += categoryHeight * (conf.barHeight + conf.barGap);\n categoryHeights[category] = categoryHeight;\n }\n } else {\n h += taskArray.length * (conf.barHeight + conf.barGap);\n for (const category of categories) {\n categoryHeights[category] = taskArray.filter((task) => task.type === category).length;\n }\n }\n elem.setAttribute(\"viewBox\", \"0 0 \" + w + \" \" + h);\n const svg = root.select(`[id=\"${id}\"]`);\n const timeScale = scaleTime().domain([\n min(taskArray, function(d) {\n return d.startTime;\n }),\n max(taskArray, function(d) {\n return d.endTime;\n })\n ]).rangeRound([0, w - conf.leftPadding - conf.rightPadding]);\n function taskCompare(a, b) {\n const taskA = a.startTime;\n const taskB = b.startTime;\n let result = 0;\n if (taskA > taskB) {\n result = 1;\n } else if (taskA < taskB) {\n result = -1;\n }\n return result;\n }\n __name(taskCompare, \"taskCompare\");\n taskArray.sort(taskCompare);\n makeGantt(taskArray, w, h);\n configureSvgSize(svg, h, w, conf.useMaxWidth);\n svg.append(\"text\").text(diagObj.db.getDiagramTitle()).attr(\"x\", w / 2).attr(\"y\", conf.titleTopMargin).attr(\"class\", \"titleText\");\n function makeGantt(tasks2, pageWidth, pageHeight) {\n const barHeight = conf.barHeight;\n const gap = barHeight + conf.barGap;\n const topPadding = conf.topPadding;\n const leftPadding = conf.leftPadding;\n const colorScale = scaleLinear().domain([0, categories.length]).range([\"#00B9FA\", \"#F95002\"]).interpolate(interpolateHcl);\n drawExcludeDays(\n gap,\n topPadding,\n leftPadding,\n pageWidth,\n pageHeight,\n tasks2,\n diagObj.db.getExcludes(),\n diagObj.db.getIncludes()\n );\n makeGrid(leftPadding, topPadding, pageWidth, pageHeight);\n drawRects(tasks2, gap, topPadding, leftPadding, barHeight, colorScale, pageWidth, pageHeight);\n vertLabels(gap, topPadding, leftPadding, barHeight, colorScale);\n drawToday(leftPadding, topPadding, pageWidth, pageHeight);\n }\n __name(makeGantt, \"makeGantt\");\n function drawRects(theArray, theGap, theTopPad, theSidePad, theBarHeight, theColorScale, w2) {\n const uniqueTaskOrderIds = [...new Set(theArray.map((item) => item.order))];\n const uniqueTasks = uniqueTaskOrderIds.map((id2) => theArray.find((item) => item.order === id2));\n svg.append(\"g\").selectAll(\"rect\").data(uniqueTasks).enter().append(\"rect\").attr(\"x\", 0).attr(\"y\", function(d, i) {\n i = d.order;\n return i * theGap + theTopPad - 2;\n }).attr(\"width\", function() {\n return w2 - conf.rightPadding / 2;\n }).attr(\"height\", theGap).attr(\"class\", function(d) {\n for (const [i, category] of categories.entries()) {\n if (d.type === category) {\n return \"section section\" + i % conf.numberSectionStyles;\n }\n }\n return \"section section0\";\n });\n const rectangles = svg.append(\"g\").selectAll(\"rect\").data(theArray).enter();\n const links2 = diagObj.db.getLinks();\n rectangles.append(\"rect\").attr(\"id\", function(d) {\n return d.id;\n }).attr(\"rx\", 3).attr(\"ry\", 3).attr(\"x\", function(d) {\n if (d.milestone) {\n return timeScale(d.startTime) + theSidePad + 0.5 * (timeScale(d.endTime) - timeScale(d.startTime)) - 0.5 * theBarHeight;\n }\n return timeScale(d.startTime) + theSidePad;\n }).attr(\"y\", function(d, i) {\n i = d.order;\n return i * theGap + theTopPad;\n }).attr(\"width\", function(d) {\n if (d.milestone) {\n return theBarHeight;\n }\n return timeScale(d.renderEndTime || d.endTime) - timeScale(d.startTime);\n }).attr(\"height\", theBarHeight).attr(\"transform-origin\", function(d, i) {\n i = d.order;\n return (timeScale(d.startTime) + theSidePad + 0.5 * (timeScale(d.endTime) - timeScale(d.startTime))).toString() + \"px \" + (i * theGap + theTopPad + 0.5 * theBarHeight).toString() + \"px\";\n }).attr(\"class\", function(d) {\n const res = \"task\";\n let classStr = \"\";\n if (d.classes.length > 0) {\n classStr = d.classes.join(\" \");\n }\n let secNum = 0;\n for (const [i, category] of categories.entries()) {\n if (d.type === category) {\n secNum = i % conf.numberSectionStyles;\n }\n }\n let taskClass = \"\";\n if (d.active) {\n if (d.crit) {\n taskClass += \" activeCrit\";\n } else {\n taskClass = \" active\";\n }\n } else if (d.done) {\n if (d.crit) {\n taskClass = \" doneCrit\";\n } else {\n taskClass = \" done\";\n }\n } else {\n if (d.crit) {\n taskClass += \" crit\";\n }\n }\n if (taskClass.length === 0) {\n taskClass = \" task\";\n }\n if (d.milestone) {\n taskClass = \" milestone \" + taskClass;\n }\n taskClass += secNum;\n taskClass += \" \" + classStr;\n return res + taskClass;\n });\n rectangles.append(\"text\").attr(\"id\", function(d) {\n return d.id + \"-text\";\n }).text(function(d) {\n return d.task;\n }).attr(\"font-size\", conf.fontSize).attr(\"x\", function(d) {\n let startX = timeScale(d.startTime);\n let endX = timeScale(d.renderEndTime || d.endTime);\n if (d.milestone) {\n startX += 0.5 * (timeScale(d.endTime) - timeScale(d.startTime)) - 0.5 * theBarHeight;\n }\n if (d.milestone) {\n endX = startX + theBarHeight;\n }\n const textWidth = this.getBBox().width;\n if (textWidth > endX - startX) {\n if (endX + textWidth + 1.5 * conf.leftPadding > w2) {\n return startX + theSidePad - 5;\n } else {\n return endX + theSidePad + 5;\n }\n } else {\n return (endX - startX) / 2 + startX + theSidePad;\n }\n }).attr(\"y\", function(d, i) {\n i = d.order;\n return i * theGap + conf.barHeight / 2 + (conf.fontSize / 2 - 2) + theTopPad;\n }).attr(\"text-height\", theBarHeight).attr(\"class\", function(d) {\n const startX = timeScale(d.startTime);\n let endX = timeScale(d.endTime);\n if (d.milestone) {\n endX = startX + theBarHeight;\n }\n const textWidth = this.getBBox().width;\n let classStr = \"\";\n if (d.classes.length > 0) {\n classStr = d.classes.join(\" \");\n }\n let secNum = 0;\n for (const [i, category] of categories.entries()) {\n if (d.type === category) {\n secNum = i % conf.numberSectionStyles;\n }\n }\n let taskType = \"\";\n if (d.active) {\n if (d.crit) {\n taskType = \"activeCritText\" + secNum;\n } else {\n taskType = \"activeText\" + secNum;\n }\n }\n if (d.done) {\n if (d.crit) {\n taskType = taskType + \" doneCritText\" + secNum;\n } else {\n taskType = taskType + \" doneText\" + secNum;\n }\n } else {\n if (d.crit) {\n taskType = taskType + \" critText\" + secNum;\n }\n }\n if (d.milestone) {\n taskType += \" milestoneText\";\n }\n if (textWidth > endX - startX) {\n if (endX + textWidth + 1.5 * conf.leftPadding > w2) {\n return classStr + \" taskTextOutsideLeft taskTextOutside\" + secNum + \" \" + taskType;\n } else {\n return classStr + \" taskTextOutsideRight taskTextOutside\" + secNum + \" \" + taskType + \" width-\" + textWidth;\n }\n } else {\n return classStr + \" taskText taskText\" + secNum + \" \" + taskType + \" width-\" + textWidth;\n }\n });\n const securityLevel2 = getConfig().securityLevel;\n if (securityLevel2 === \"sandbox\") {\n let sandboxElement2;\n sandboxElement2 = select(\"#i\" + id);\n const doc2 = sandboxElement2.nodes()[0].contentDocument;\n rectangles.filter(function(d) {\n return links2.has(d.id);\n }).each(function(o) {\n var taskRect = doc2.querySelector(\"#\" + o.id);\n var taskText = doc2.querySelector(\"#\" + o.id + \"-text\");\n const oldParent = taskRect.parentNode;\n var Link = doc2.createElement(\"a\");\n Link.setAttribute(\"xlink:href\", links2.get(o.id));\n Link.setAttribute(\"target\", \"_top\");\n oldParent.appendChild(Link);\n Link.appendChild(taskRect);\n Link.appendChild(taskText);\n });\n }\n }\n __name(drawRects, \"drawRects\");\n function drawExcludeDays(theGap, theTopPad, theSidePad, w2, h2, tasks2, excludes2, includes2) {\n if (excludes2.length === 0 && includes2.length === 0) {\n return;\n }\n let minTime;\n let maxTime;\n for (const { startTime, endTime } of tasks2) {\n if (minTime === void 0 || startTime < minTime) {\n minTime = startTime;\n }\n if (maxTime === void 0 || endTime > maxTime) {\n maxTime = endTime;\n }\n }\n if (!minTime || !maxTime) {\n return;\n }\n if (dayjs2(maxTime).diff(dayjs2(minTime), \"year\") > 5) {\n log.warn(\n \"The difference between the min and max time is more than 5 years. This will cause performance issues. Skipping drawing exclude days.\"\n );\n return;\n }\n const dateFormat2 = diagObj.db.getDateFormat();\n const excludeRanges = [];\n let range = null;\n let d = dayjs2(minTime);\n while (d.valueOf() <= maxTime) {\n if (diagObj.db.isInvalidDate(d, dateFormat2, excludes2, includes2)) {\n if (!range) {\n range = {\n start: d,\n end: d\n };\n } else {\n range.end = d;\n }\n } else {\n if (range) {\n excludeRanges.push(range);\n range = null;\n }\n }\n d = d.add(1, \"d\");\n }\n const rectangles = svg.append(\"g\").selectAll(\"rect\").data(excludeRanges).enter();\n rectangles.append(\"rect\").attr(\"id\", function(d2) {\n return \"exclude-\" + d2.start.format(\"YYYY-MM-DD\");\n }).attr(\"x\", function(d2) {\n return timeScale(d2.start) + theSidePad;\n }).attr(\"y\", conf.gridLineStartPadding).attr(\"width\", function(d2) {\n const renderEnd = d2.end.add(1, \"day\");\n return timeScale(renderEnd) - timeScale(d2.start);\n }).attr(\"height\", h2 - theTopPad - conf.gridLineStartPadding).attr(\"transform-origin\", function(d2, i) {\n return (timeScale(d2.start) + theSidePad + 0.5 * (timeScale(d2.end) - timeScale(d2.start))).toString() + \"px \" + (i * theGap + 0.5 * h2).toString() + \"px\";\n }).attr(\"class\", \"exclude-range\");\n }\n __name(drawExcludeDays, \"drawExcludeDays\");\n function makeGrid(theSidePad, theTopPad, w2, h2) {\n let bottomXAxis = axisBottom(timeScale).tickSize(-h2 + theTopPad + conf.gridLineStartPadding).tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || \"%Y-%m-%d\"));\n const reTickInterval = /^([1-9]\\d*)(millisecond|second|minute|hour|day|week|month)$/;\n const resultTickInterval = reTickInterval.exec(\n diagObj.db.getTickInterval() || conf.tickInterval\n );\n if (resultTickInterval !== null) {\n const every = resultTickInterval[1];\n const interval = resultTickInterval[2];\n const weekday2 = diagObj.db.getWeekday() || conf.weekday;\n switch (interval) {\n case \"millisecond\":\n bottomXAxis.ticks(timeMillisecond.every(every));\n break;\n case \"second\":\n bottomXAxis.ticks(timeSecond.every(every));\n break;\n case \"minute\":\n bottomXAxis.ticks(timeMinute.every(every));\n break;\n case \"hour\":\n bottomXAxis.ticks(timeHour.every(every));\n break;\n case \"day\":\n bottomXAxis.ticks(timeDay.every(every));\n break;\n case \"week\":\n bottomXAxis.ticks(mapWeekdayToTimeFunction[weekday2].every(every));\n break;\n case \"month\":\n bottomXAxis.ticks(timeMonth.every(every));\n break;\n }\n }\n svg.append(\"g\").attr(\"class\", \"grid\").attr(\"transform\", \"translate(\" + theSidePad + \", \" + (h2 - 50) + \")\").call(bottomXAxis).selectAll(\"text\").style(\"text-anchor\", \"middle\").attr(\"fill\", \"#000\").attr(\"stroke\", \"none\").attr(\"font-size\", 10).attr(\"dy\", \"1em\");\n if (diagObj.db.topAxisEnabled() || conf.topAxis) {\n let topXAxis = axisTop(timeScale).tickSize(-h2 + theTopPad + conf.gridLineStartPadding).tickFormat(timeFormat(diagObj.db.getAxisFormat() || conf.axisFormat || \"%Y-%m-%d\"));\n if (resultTickInterval !== null) {\n const every = resultTickInterval[1];\n const interval = resultTickInterval[2];\n const weekday2 = diagObj.db.getWeekday() || conf.weekday;\n switch (interval) {\n case \"millisecond\":\n topXAxis.ticks(timeMillisecond.every(every));\n break;\n case \"second\":\n topXAxis.ticks(timeSecond.every(every));\n break;\n case \"minute\":\n topXAxis.ticks(timeMinute.every(every));\n break;\n case \"hour\":\n topXAxis.ticks(timeHour.every(every));\n break;\n case \"day\":\n topXAxis.ticks(timeDay.every(every));\n break;\n case \"week\":\n topXAxis.ticks(mapWeekdayToTimeFunction[weekday2].every(every));\n break;\n case \"month\":\n topXAxis.ticks(timeMonth.every(every));\n break;\n }\n }\n svg.append(\"g\").attr(\"class\", \"grid\").attr(\"transform\", \"translate(\" + theSidePad + \", \" + theTopPad + \")\").call(topXAxis).selectAll(\"text\").style(\"text-anchor\", \"middle\").attr(\"fill\", \"#000\").attr(\"stroke\", \"none\").attr(\"font-size\", 10);\n }\n }\n __name(makeGrid, \"makeGrid\");\n function vertLabels(theGap, theTopPad) {\n let prevGap = 0;\n const numOccurrences = Object.keys(categoryHeights).map((d) => [d, categoryHeights[d]]);\n svg.append(\"g\").selectAll(\"text\").data(numOccurrences).enter().append(function(d) {\n const rows = d[0].split(common_default.lineBreakRegex);\n const dy = -(rows.length - 1) / 2;\n const svgLabel = doc.createElementNS(\"http://www.w3.org/2000/svg\", \"text\");\n svgLabel.setAttribute(\"dy\", dy + \"em\");\n for (const [j, row] of rows.entries()) {\n const tspan = doc.createElementNS(\"http://www.w3.org/2000/svg\", \"tspan\");\n tspan.setAttribute(\"alignment-baseline\", \"central\");\n tspan.setAttribute(\"x\", \"10\");\n if (j > 0) {\n tspan.setAttribute(\"dy\", \"1em\");\n }\n tspan.textContent = row;\n svgLabel.appendChild(tspan);\n }\n return svgLabel;\n }).attr(\"x\", 10).attr(\"y\", function(d, i) {\n if (i > 0) {\n for (let j = 0; j < i; j++) {\n prevGap += numOccurrences[i - 1][1];\n return d[1] * theGap / 2 + prevGap * theGap + theTopPad;\n }\n } else {\n return d[1] * theGap / 2 + theTopPad;\n }\n }).attr(\"font-size\", conf.sectionFontSize).attr(\"class\", function(d) {\n for (const [i, category] of categories.entries()) {\n if (d[0] === category) {\n return \"sectionTitle sectionTitle\" + i % conf.numberSectionStyles;\n }\n }\n return \"sectionTitle\";\n });\n }\n __name(vertLabels, \"vertLabels\");\n function drawToday(theSidePad, theTopPad, w2, h2) {\n const todayMarker2 = diagObj.db.getTodayMarker();\n if (todayMarker2 === \"off\") {\n return;\n }\n const todayG = svg.append(\"g\").attr(\"class\", \"today\");\n const today = /* @__PURE__ */ new Date();\n const todayLine = todayG.append(\"line\");\n todayLine.attr(\"x1\", timeScale(today) + theSidePad).attr(\"x2\", timeScale(today) + theSidePad).attr(\"y1\", conf.titleTopMargin).attr(\"y2\", h2 - conf.titleTopMargin).attr(\"class\", \"today\");\n if (todayMarker2 !== \"\") {\n todayLine.attr(\"style\", todayMarker2.replace(/,/g, \";\"));\n }\n }\n __name(drawToday, \"drawToday\");\n function checkUnique(arr) {\n const hash = {};\n const result = [];\n for (let i = 0, l = arr.length; i < l; ++i) {\n if (!Object.prototype.hasOwnProperty.call(hash, arr[i])) {\n hash[arr[i]] = true;\n result.push(arr[i]);\n }\n }\n return result;\n }\n __name(checkUnique, \"checkUnique\");\n}, \"draw\");\nvar ganttRenderer_default = {\n setConf,\n draw\n};\n\n// src/diagrams/gantt/styles.js\nvar getStyles = /* @__PURE__ */ __name((options) => `\n .mermaid-main-font {\n font-family: var(--mermaid-font-family, \"trebuchet ms\", verdana, arial, sans-serif);\n }\n\n .exclude-range {\n fill: ${options.excludeBkgColor};\n }\n\n .section {\n stroke: none;\n opacity: 0.2;\n }\n\n .section0 {\n fill: ${options.sectionBkgColor};\n }\n\n .section2 {\n fill: ${options.sectionBkgColor2};\n }\n\n .section1,\n .section3 {\n fill: ${options.altSectionBkgColor};\n opacity: 0.2;\n }\n\n .sectionTitle0 {\n fill: ${options.titleColor};\n }\n\n .sectionTitle1 {\n fill: ${options.titleColor};\n }\n\n .sectionTitle2 {\n fill: ${options.titleColor};\n }\n\n .sectionTitle3 {\n fill: ${options.titleColor};\n }\n\n .sectionTitle {\n text-anchor: start;\n font-family: var(--mermaid-font-family, \"trebuchet ms\", verdana, arial, sans-serif);\n }\n\n\n /* Grid and axis */\n\n .grid .tick {\n stroke: ${options.gridColor};\n opacity: 0.8;\n shape-rendering: crispEdges;\n }\n\n .grid .tick text {\n font-family: ${options.fontFamily};\n fill: ${options.textColor};\n }\n\n .grid path {\n stroke-width: 0;\n }\n\n\n /* Today line */\n\n .today {\n fill: none;\n stroke: ${options.todayLineColor};\n stroke-width: 2px;\n }\n\n\n /* Task styling */\n\n /* Default task */\n\n .task {\n stroke-width: 2;\n }\n\n .taskText {\n text-anchor: middle;\n font-family: var(--mermaid-font-family, \"trebuchet ms\", verdana, arial, sans-serif);\n }\n\n .taskTextOutsideRight {\n fill: ${options.taskTextDarkColor};\n text-anchor: start;\n font-family: var(--mermaid-font-family, \"trebuchet ms\", verdana, arial, sans-serif);\n }\n\n .taskTextOutsideLeft {\n fill: ${options.taskTextDarkColor};\n text-anchor: end;\n }\n\n\n /* Special case clickable */\n\n .task.clickable {\n cursor: pointer;\n }\n\n .taskText.clickable {\n cursor: pointer;\n fill: ${options.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideLeft.clickable {\n cursor: pointer;\n fill: ${options.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n .taskTextOutsideRight.clickable {\n cursor: pointer;\n fill: ${options.taskTextClickableColor} !important;\n font-weight: bold;\n }\n\n\n /* Specific task settings for the sections*/\n\n .taskText0,\n .taskText1,\n .taskText2,\n .taskText3 {\n fill: ${options.taskTextColor};\n }\n\n .task0,\n .task1,\n .task2,\n .task3 {\n fill: ${options.taskBkgColor};\n stroke: ${options.taskBorderColor};\n }\n\n .taskTextOutside0,\n .taskTextOutside2\n {\n fill: ${options.taskTextOutsideColor};\n }\n\n .taskTextOutside1,\n .taskTextOutside3 {\n fill: ${options.taskTextOutsideColor};\n }\n\n\n /* Active task */\n\n .active0,\n .active1,\n .active2,\n .active3 {\n fill: ${options.activeTaskBkgColor};\n stroke: ${options.activeTaskBorderColor};\n }\n\n .activeText0,\n .activeText1,\n .activeText2,\n .activeText3 {\n fill: ${options.taskTextDarkColor} !important;\n }\n\n\n /* Completed task */\n\n .done0,\n .done1,\n .done2,\n .done3 {\n stroke: ${options.doneTaskBorderColor};\n fill: ${options.doneTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneText0,\n .doneText1,\n .doneText2,\n .doneText3 {\n fill: ${options.taskTextDarkColor} !important;\n }\n\n\n /* Tasks on the critical line */\n\n .crit0,\n .crit1,\n .crit2,\n .crit3 {\n stroke: ${options.critBorderColor};\n fill: ${options.critBkgColor};\n stroke-width: 2;\n }\n\n .activeCrit0,\n .activeCrit1,\n .activeCrit2,\n .activeCrit3 {\n stroke: ${options.critBorderColor};\n fill: ${options.activeTaskBkgColor};\n stroke-width: 2;\n }\n\n .doneCrit0,\n .doneCrit1,\n .doneCrit2,\n .doneCrit3 {\n stroke: ${options.critBorderColor};\n fill: ${options.doneTaskBkgColor};\n stroke-width: 2;\n cursor: pointer;\n shape-rendering: crispEdges;\n }\n\n .milestone {\n transform: rotate(45deg) scale(0.8,0.8);\n }\n\n .milestoneText {\n font-style: italic;\n }\n .doneCritText0,\n .doneCritText1,\n .doneCritText2,\n .doneCritText3 {\n fill: ${options.taskTextDarkColor} !important;\n }\n\n .activeCritText0,\n .activeCritText1,\n .activeCritText2,\n .activeCritText3 {\n fill: ${options.taskTextDarkColor} !important;\n }\n\n .titleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${options.titleColor || options.textColor};\n font-family: var(--mermaid-font-family, \"trebuchet ms\", verdana, arial, sans-serif);\n }\n`, \"getStyles\");\nvar styles_default = getStyles;\n\n// src/diagrams/gantt/ganttDiagram.ts\nvar diagram = {\n parser: gantt_default,\n db: ganttDb_default,\n renderer: ganttRenderer_default,\n styles: styles_default\n};\nexport {\n diagram\n};\n", "import {\n version\n} from \"./chunk-QZ6ES4KD.mjs\";\nimport {\n selectSvgElement\n} from \"./chunk-F2XFN3BY.mjs\";\nimport {\n __name,\n configureSvgSize,\n log\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/info/infoParser.ts\nimport { parse } from \"@mermaid-js/parser\";\nvar parser = {\n parse: /* @__PURE__ */ __name(async (input) => {\n const ast = await parse(\"info\", input);\n log.debug(ast);\n }, \"parse\")\n};\n\n// src/diagrams/info/infoDb.ts\nvar DEFAULT_INFO_DB = { version };\nvar getVersion = /* @__PURE__ */ __name(() => DEFAULT_INFO_DB.version, \"getVersion\");\nvar db = {\n getVersion\n};\n\n// src/diagrams/info/infoRenderer.ts\nvar draw = /* @__PURE__ */ __name((text, id, version2) => {\n log.debug(\"rendering info diagram\\n\" + text);\n const svg = selectSvgElement(id);\n configureSvgSize(svg, 100, 400, true);\n const group = svg.append(\"g\");\n group.append(\"text\").attr(\"x\", 100).attr(\"y\", 40).attr(\"class\", \"version\").attr(\"font-size\", 32).style(\"text-anchor\", \"middle\").text(`v${version2}`);\n}, \"draw\");\nvar renderer = { draw };\n\n// src/diagrams/info/infoDiagram.ts\nvar diagram = {\n parser,\n db,\n renderer\n};\nexport {\n diagram\n};\n", "import {\n populateCommonDb\n} from \"./chunk-OQCM5LHU.mjs\";\nimport {\n cleanAndMerge,\n parseFontSize\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n selectSvgElement\n} from \"./chunk-F2XFN3BY.mjs\";\nimport {\n __name,\n clear,\n configureSvgSize,\n defaultConfig_default,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n getDiagramTitle,\n log,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/pie/pieParser.ts\nimport { parse } from \"@mermaid-js/parser\";\n\n// src/diagrams/pie/pieDb.ts\nvar DEFAULT_PIE_CONFIG = defaultConfig_default.pie;\nvar DEFAULT_PIE_DB = {\n sections: /* @__PURE__ */ new Map(),\n showData: false,\n config: DEFAULT_PIE_CONFIG\n};\nvar sections = DEFAULT_PIE_DB.sections;\nvar showData = DEFAULT_PIE_DB.showData;\nvar config = structuredClone(DEFAULT_PIE_CONFIG);\nvar getConfig2 = /* @__PURE__ */ __name(() => structuredClone(config), \"getConfig\");\nvar clear2 = /* @__PURE__ */ __name(() => {\n sections = /* @__PURE__ */ new Map();\n showData = DEFAULT_PIE_DB.showData;\n clear();\n}, \"clear\");\nvar addSection = /* @__PURE__ */ __name(({ label, value }) => {\n if (!sections.has(label)) {\n sections.set(label, value);\n log.debug(`added new section: ${label}, with value: ${value}`);\n }\n}, \"addSection\");\nvar getSections = /* @__PURE__ */ __name(() => sections, \"getSections\");\nvar setShowData = /* @__PURE__ */ __name((toggle) => {\n showData = toggle;\n}, \"setShowData\");\nvar getShowData = /* @__PURE__ */ __name(() => showData, \"getShowData\");\nvar db = {\n getConfig: getConfig2,\n clear: clear2,\n setDiagramTitle,\n getDiagramTitle,\n setAccTitle,\n getAccTitle,\n setAccDescription,\n getAccDescription,\n addSection,\n getSections,\n setShowData,\n getShowData\n};\n\n// src/diagrams/pie/pieParser.ts\nvar populateDb = /* @__PURE__ */ __name((ast, db2) => {\n populateCommonDb(ast, db2);\n db2.setShowData(ast.showData);\n ast.sections.map(db2.addSection);\n}, \"populateDb\");\nvar parser = {\n parse: /* @__PURE__ */ __name(async (input) => {\n const ast = await parse(\"pie\", input);\n log.debug(ast);\n populateDb(ast, db);\n }, \"parse\")\n};\n\n// src/diagrams/pie/pieStyles.ts\nvar getStyles = /* @__PURE__ */ __name((options) => `\n .pieCircle{\n stroke: ${options.pieStrokeColor};\n stroke-width : ${options.pieStrokeWidth};\n opacity : ${options.pieOpacity};\n }\n .pieOuterCircle{\n stroke: ${options.pieOuterStrokeColor};\n stroke-width: ${options.pieOuterStrokeWidth};\n fill: none;\n }\n .pieTitleText {\n text-anchor: middle;\n font-size: ${options.pieTitleTextSize};\n fill: ${options.pieTitleTextColor};\n font-family: ${options.fontFamily};\n }\n .slice {\n font-family: ${options.fontFamily};\n fill: ${options.pieSectionTextColor};\n font-size:${options.pieSectionTextSize};\n // fill: white;\n }\n .legend text {\n fill: ${options.pieLegendTextColor};\n font-family: ${options.fontFamily};\n font-size: ${options.pieLegendTextSize};\n }\n`, \"getStyles\");\nvar pieStyles_default = getStyles;\n\n// src/diagrams/pie/pieRenderer.ts\nimport { arc, pie as d3pie, scaleOrdinal } from \"d3\";\nvar createPieArcs = /* @__PURE__ */ __name((sections2) => {\n const pieData = [...sections2.entries()].map((element) => {\n return {\n label: element[0],\n value: element[1]\n };\n }).sort((a, b) => {\n return b.value - a.value;\n });\n const pie = d3pie().value(\n (d3Section) => d3Section.value\n );\n return pie(pieData);\n}, \"createPieArcs\");\nvar draw = /* @__PURE__ */ __name((text, id, _version, diagObj) => {\n log.debug(\"rendering pie chart\\n\" + text);\n const db2 = diagObj.db;\n const globalConfig = getConfig();\n const pieConfig = cleanAndMerge(db2.getConfig(), globalConfig.pie);\n const MARGIN = 40;\n const LEGEND_RECT_SIZE = 18;\n const LEGEND_SPACING = 4;\n const height = 450;\n const pieWidth = height;\n const svg = selectSvgElement(id);\n const group = svg.append(\"g\");\n group.attr(\"transform\", \"translate(\" + pieWidth / 2 + \",\" + height / 2 + \")\");\n const { themeVariables } = globalConfig;\n let [outerStrokeWidth] = parseFontSize(themeVariables.pieOuterStrokeWidth);\n outerStrokeWidth ??= 2;\n const textPosition = pieConfig.textPosition;\n const radius = Math.min(pieWidth, height) / 2 - MARGIN;\n const arcGenerator = arc().innerRadius(0).outerRadius(radius);\n const labelArcGenerator = arc().innerRadius(radius * textPosition).outerRadius(radius * textPosition);\n group.append(\"circle\").attr(\"cx\", 0).attr(\"cy\", 0).attr(\"r\", radius + outerStrokeWidth / 2).attr(\"class\", \"pieOuterCircle\");\n const sections2 = db2.getSections();\n const arcs = createPieArcs(sections2);\n const myGeneratedColors = [\n themeVariables.pie1,\n themeVariables.pie2,\n themeVariables.pie3,\n themeVariables.pie4,\n themeVariables.pie5,\n themeVariables.pie6,\n themeVariables.pie7,\n themeVariables.pie8,\n themeVariables.pie9,\n themeVariables.pie10,\n themeVariables.pie11,\n themeVariables.pie12\n ];\n const color = scaleOrdinal(myGeneratedColors);\n group.selectAll(\"mySlices\").data(arcs).enter().append(\"path\").attr(\"d\", arcGenerator).attr(\"fill\", (datum) => {\n return color(datum.data.label);\n }).attr(\"class\", \"pieCircle\");\n let sum = 0;\n sections2.forEach((section) => {\n sum += section;\n });\n group.selectAll(\"mySlices\").data(arcs).enter().append(\"text\").text((datum) => {\n return (datum.data.value / sum * 100).toFixed(0) + \"%\";\n }).attr(\"transform\", (datum) => {\n return \"translate(\" + labelArcGenerator.centroid(datum) + \")\";\n }).style(\"text-anchor\", \"middle\").attr(\"class\", \"slice\");\n group.append(\"text\").text(db2.getDiagramTitle()).attr(\"x\", 0).attr(\"y\", -(height - 50) / 2).attr(\"class\", \"pieTitleText\");\n const legend = group.selectAll(\".legend\").data(color.domain()).enter().append(\"g\").attr(\"class\", \"legend\").attr(\"transform\", (_datum, index) => {\n const height2 = LEGEND_RECT_SIZE + LEGEND_SPACING;\n const offset = height2 * color.domain().length / 2;\n const horizontal = 12 * LEGEND_RECT_SIZE;\n const vertical = index * height2 - offset;\n return \"translate(\" + horizontal + \",\" + vertical + \")\";\n });\n legend.append(\"rect\").attr(\"width\", LEGEND_RECT_SIZE).attr(\"height\", LEGEND_RECT_SIZE).style(\"fill\", color).style(\"stroke\", color);\n legend.data(arcs).append(\"text\").attr(\"x\", LEGEND_RECT_SIZE + LEGEND_SPACING).attr(\"y\", LEGEND_RECT_SIZE - LEGEND_SPACING).text((datum) => {\n const { label, value } = datum.data;\n if (db2.getShowData()) {\n return `${label} [${value}]`;\n }\n return label;\n });\n const longestTextWidth = Math.max(\n ...legend.selectAll(\"text\").nodes().map((node) => node?.getBoundingClientRect().width ?? 0)\n );\n const totalWidth = pieWidth + MARGIN + LEGEND_RECT_SIZE + LEGEND_SPACING + longestTextWidth;\n svg.attr(\"viewBox\", `0 0 ${totalWidth} ${height}`);\n configureSvgSize(svg, height, totalWidth, pieConfig.useMaxWidth);\n}, \"draw\");\nvar renderer = { draw };\n\n// src/diagrams/pie/pieDiagram.ts\nvar diagram = {\n parser,\n db,\n renderer,\n styles: pieStyles_default\n};\nexport {\n diagram\n};\n", "import {\n __name,\n clear,\n configureSvgSize,\n defaultConfig_default,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n getDiagramTitle,\n getThemeVariables,\n log,\n sanitizeText,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/quadrant-chart/parser/quadrant.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 3], $V1 = [1, 4], $V2 = [1, 5], $V3 = [1, 6], $V4 = [1, 7], $V5 = [1, 4, 5, 10, 12, 13, 14, 18, 25, 35, 37, 39, 41, 42, 48, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61, 63, 64, 65, 66, 67], $V6 = [1, 4, 5, 10, 12, 13, 14, 18, 25, 28, 35, 37, 39, 41, 42, 48, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61, 63, 64, 65, 66, 67], $V7 = [55, 56, 57], $V8 = [2, 36], $V9 = [1, 37], $Va = [1, 36], $Vb = [1, 38], $Vc = [1, 35], $Vd = [1, 43], $Ve = [1, 41], $Vf = [1, 14], $Vg = [1, 23], $Vh = [1, 18], $Vi = [1, 19], $Vj = [1, 20], $Vk = [1, 21], $Vl = [1, 22], $Vm = [1, 24], $Vn = [1, 25], $Vo = [1, 26], $Vp = [1, 27], $Vq = [1, 28], $Vr = [1, 29], $Vs = [1, 32], $Vt = [1, 33], $Vu = [1, 34], $Vv = [1, 39], $Vw = [1, 40], $Vx = [1, 42], $Vy = [1, 44], $Vz = [1, 62], $VA = [1, 61], $VB = [4, 5, 8, 10, 12, 13, 14, 18, 44, 47, 49, 55, 56, 57, 63, 64, 65, 66, 67], $VC = [1, 65], $VD = [1, 66], $VE = [1, 67], $VF = [1, 68], $VG = [1, 69], $VH = [1, 70], $VI = [1, 71], $VJ = [1, 72], $VK = [1, 73], $VL = [1, 74], $VM = [1, 75], $VN = [1, 76], $VO = [4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 18], $VP = [1, 90], $VQ = [1, 91], $VR = [1, 92], $VS = [1, 99], $VT = [1, 93], $VU = [1, 96], $VV = [1, 94], $VW = [1, 95], $VX = [1, 97], $VY = [1, 98], $VZ = [1, 102], $V_ = [10, 55, 56, 57], $V$ = [4, 5, 6, 8, 10, 11, 13, 17, 18, 19, 20, 55, 56, 57];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"idStringToken\": 3, \"ALPHA\": 4, \"NUM\": 5, \"NODE_STRING\": 6, \"DOWN\": 7, \"MINUS\": 8, \"DEFAULT\": 9, \"COMMA\": 10, \"COLON\": 11, \"AMP\": 12, \"BRKT\": 13, \"MULT\": 14, \"UNICODE_TEXT\": 15, \"styleComponent\": 16, \"UNIT\": 17, \"SPACE\": 18, \"STYLE\": 19, \"PCT\": 20, \"idString\": 21, \"style\": 22, \"stylesOpt\": 23, \"classDefStatement\": 24, \"CLASSDEF\": 25, \"start\": 26, \"eol\": 27, \"QUADRANT\": 28, \"document\": 29, \"line\": 30, \"statement\": 31, \"axisDetails\": 32, \"quadrantDetails\": 33, \"points\": 34, \"title\": 35, \"title_value\": 36, \"acc_title\": 37, \"acc_title_value\": 38, \"acc_descr\": 39, \"acc_descr_value\": 40, \"acc_descr_multiline_value\": 41, \"section\": 42, \"text\": 43, \"point_start\": 44, \"point_x\": 45, \"point_y\": 46, \"class_name\": 47, \"X-AXIS\": 48, \"AXIS-TEXT-DELIMITER\": 49, \"Y-AXIS\": 50, \"QUADRANT_1\": 51, \"QUADRANT_2\": 52, \"QUADRANT_3\": 53, \"QUADRANT_4\": 54, \"NEWLINE\": 55, \"SEMI\": 56, \"EOF\": 57, \"alphaNumToken\": 58, \"textNoTagsToken\": 59, \"STR\": 60, \"MD_STR\": 61, \"alphaNum\": 62, \"PUNCTUATION\": 63, \"PLUS\": 64, \"EQUALS\": 65, \"DOT\": 66, \"UNDERSCORE\": 67, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 4: \"ALPHA\", 5: \"NUM\", 6: \"NODE_STRING\", 7: \"DOWN\", 8: \"MINUS\", 9: \"DEFAULT\", 10: \"COMMA\", 11: \"COLON\", 12: \"AMP\", 13: \"BRKT\", 14: \"MULT\", 15: \"UNICODE_TEXT\", 17: \"UNIT\", 18: \"SPACE\", 19: \"STYLE\", 20: \"PCT\", 25: \"CLASSDEF\", 28: \"QUADRANT\", 35: \"title\", 36: \"title_value\", 37: \"acc_title\", 38: \"acc_title_value\", 39: \"acc_descr\", 40: \"acc_descr_value\", 41: \"acc_descr_multiline_value\", 42: \"section\", 44: \"point_start\", 45: \"point_x\", 46: \"point_y\", 47: \"class_name\", 48: \"X-AXIS\", 49: \"AXIS-TEXT-DELIMITER\", 50: \"Y-AXIS\", 51: \"QUADRANT_1\", 52: \"QUADRANT_2\", 53: \"QUADRANT_3\", 54: \"QUADRANT_4\", 55: \"NEWLINE\", 56: \"SEMI\", 57: \"EOF\", 60: \"STR\", 61: \"MD_STR\", 63: \"PUNCTUATION\", 64: \"PLUS\", 65: \"EQUALS\", 66: \"DOT\", 67: \"UNDERSCORE\" },\n productions_: [0, [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [3, 1], [16, 1], [16, 1], [16, 1], [16, 1], [16, 1], [16, 1], [16, 1], [16, 1], [16, 1], [16, 1], [21, 1], [21, 2], [22, 1], [22, 2], [23, 1], [23, 3], [24, 5], [26, 2], [26, 2], [26, 2], [29, 0], [29, 2], [30, 2], [31, 0], [31, 1], [31, 2], [31, 1], [31, 1], [31, 1], [31, 2], [31, 2], [31, 2], [31, 1], [31, 1], [34, 4], [34, 5], [34, 5], [34, 6], [32, 4], [32, 3], [32, 2], [32, 4], [32, 3], [32, 2], [33, 2], [33, 2], [33, 2], [33, 2], [27, 1], [27, 1], [27, 1], [43, 1], [43, 2], [43, 1], [43, 1], [62, 1], [62, 2], [58, 1], [58, 1], [58, 1], [58, 1], [58, 1], [58, 1], [58, 1], [58, 1], [58, 1], [58, 1], [58, 1], [59, 1], [59, 1], [59, 1]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 23:\n this.$ = $$[$0];\n break;\n case 24:\n this.$ = $$[$0 - 1] + \"\" + $$[$0];\n break;\n case 26:\n this.$ = $$[$0 - 1] + $$[$0];\n break;\n case 27:\n this.$ = [$$[$0].trim()];\n break;\n case 28:\n $$[$0 - 2].push($$[$0].trim());\n this.$ = $$[$0 - 2];\n break;\n case 29:\n this.$ = $$[$0 - 4];\n yy.addClass($$[$0 - 2], $$[$0]);\n break;\n case 37:\n this.$ = [];\n break;\n case 42:\n this.$ = $$[$0].trim();\n yy.setDiagramTitle(this.$);\n break;\n case 43:\n this.$ = $$[$0].trim();\n yy.setAccTitle(this.$);\n break;\n case 44:\n case 45:\n this.$ = $$[$0].trim();\n yy.setAccDescription(this.$);\n break;\n case 46:\n yy.addSection($$[$0].substr(8));\n this.$ = $$[$0].substr(8);\n break;\n case 47:\n yy.addPoint($$[$0 - 3], \"\", $$[$0 - 1], $$[$0], []);\n break;\n case 48:\n yy.addPoint($$[$0 - 4], $$[$0 - 3], $$[$0 - 1], $$[$0], []);\n break;\n case 49:\n yy.addPoint($$[$0 - 4], \"\", $$[$0 - 2], $$[$0 - 1], $$[$0]);\n break;\n case 50:\n yy.addPoint($$[$0 - 5], $$[$0 - 4], $$[$0 - 2], $$[$0 - 1], $$[$0]);\n break;\n case 51:\n yy.setXAxisLeftText($$[$0 - 2]);\n yy.setXAxisRightText($$[$0]);\n break;\n case 52:\n $$[$0 - 1].text += \" \\u27F6 \";\n yy.setXAxisLeftText($$[$0 - 1]);\n break;\n case 53:\n yy.setXAxisLeftText($$[$0]);\n break;\n case 54:\n yy.setYAxisBottomText($$[$0 - 2]);\n yy.setYAxisTopText($$[$0]);\n break;\n case 55:\n $$[$0 - 1].text += \" \\u27F6 \";\n yy.setYAxisBottomText($$[$0 - 1]);\n break;\n case 56:\n yy.setYAxisBottomText($$[$0]);\n break;\n case 57:\n yy.setQuadrant1Text($$[$0]);\n break;\n case 58:\n yy.setQuadrant2Text($$[$0]);\n break;\n case 59:\n yy.setQuadrant3Text($$[$0]);\n break;\n case 60:\n yy.setQuadrant4Text($$[$0]);\n break;\n case 64:\n this.$ = { text: $$[$0], type: \"text\" };\n break;\n case 65:\n this.$ = { text: $$[$0 - 1].text + \"\" + $$[$0], type: $$[$0 - 1].type };\n break;\n case 66:\n this.$ = { text: $$[$0], type: \"text\" };\n break;\n case 67:\n this.$ = { text: $$[$0], type: \"markdown\" };\n break;\n case 68:\n this.$ = $$[$0];\n break;\n case 69:\n this.$ = $$[$0 - 1] + \"\" + $$[$0];\n break;\n }\n }, \"anonymous\"),\n table: [{ 18: $V0, 26: 1, 27: 2, 28: $V1, 55: $V2, 56: $V3, 57: $V4 }, { 1: [3] }, { 18: $V0, 26: 8, 27: 2, 28: $V1, 55: $V2, 56: $V3, 57: $V4 }, { 18: $V0, 26: 9, 27: 2, 28: $V1, 55: $V2, 56: $V3, 57: $V4 }, o($V5, [2, 33], { 29: 10 }), o($V6, [2, 61]), o($V6, [2, 62]), o($V6, [2, 63]), { 1: [2, 30] }, { 1: [2, 31] }, o($V7, $V8, { 30: 11, 31: 12, 24: 13, 32: 15, 33: 16, 34: 17, 43: 30, 58: 31, 1: [2, 32], 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $Vf, 25: $Vg, 35: $Vh, 37: $Vi, 39: $Vj, 41: $Vk, 42: $Vl, 48: $Vm, 50: $Vn, 51: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V5, [2, 34]), { 27: 45, 55: $V2, 56: $V3, 57: $V4 }, o($V7, [2, 37]), o($V7, $V8, { 24: 13, 32: 15, 33: 16, 34: 17, 43: 30, 58: 31, 31: 46, 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $Vf, 25: $Vg, 35: $Vh, 37: $Vi, 39: $Vj, 41: $Vk, 42: $Vl, 48: $Vm, 50: $Vn, 51: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 39]), o($V7, [2, 40]), o($V7, [2, 41]), { 36: [1, 47] }, { 38: [1, 48] }, { 40: [1, 49] }, o($V7, [2, 45]), o($V7, [2, 46]), { 18: [1, 50] }, { 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 43: 51, 58: 31, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }, { 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 43: 52, 58: 31, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }, { 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 43: 53, 58: 31, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }, { 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 43: 54, 58: 31, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }, { 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 43: 55, 58: 31, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }, { 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 43: 56, 58: 31, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }, { 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 44: [1, 57], 47: [1, 58], 58: 60, 59: 59, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }, o($VB, [2, 64]), o($VB, [2, 66]), o($VB, [2, 67]), o($VB, [2, 70]), o($VB, [2, 71]), o($VB, [2, 72]), o($VB, [2, 73]), o($VB, [2, 74]), o($VB, [2, 75]), o($VB, [2, 76]), o($VB, [2, 77]), o($VB, [2, 78]), o($VB, [2, 79]), o($VB, [2, 80]), o($V5, [2, 35]), o($V7, [2, 38]), o($V7, [2, 42]), o($V7, [2, 43]), o($V7, [2, 44]), { 3: 64, 4: $VC, 5: $VD, 6: $VE, 7: $VF, 8: $VG, 9: $VH, 10: $VI, 11: $VJ, 12: $VK, 13: $VL, 14: $VM, 15: $VN, 21: 63 }, o($V7, [2, 53], { 59: 59, 58: 60, 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 49: [1, 77], 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 56], { 59: 59, 58: 60, 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 49: [1, 78], 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 57], { 59: 59, 58: 60, 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 58], { 59: 59, 58: 60, 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 59], { 59: 59, 58: 60, 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 60], { 59: 59, 58: 60, 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), { 45: [1, 79] }, { 44: [1, 80] }, o($VB, [2, 65]), o($VB, [2, 81]), o($VB, [2, 82]), o($VB, [2, 83]), { 3: 82, 4: $VC, 5: $VD, 6: $VE, 7: $VF, 8: $VG, 9: $VH, 10: $VI, 11: $VJ, 12: $VK, 13: $VL, 14: $VM, 15: $VN, 18: [1, 81] }, o($VO, [2, 23]), o($VO, [2, 1]), o($VO, [2, 2]), o($VO, [2, 3]), o($VO, [2, 4]), o($VO, [2, 5]), o($VO, [2, 6]), o($VO, [2, 7]), o($VO, [2, 8]), o($VO, [2, 9]), o($VO, [2, 10]), o($VO, [2, 11]), o($VO, [2, 12]), o($V7, [2, 52], { 58: 31, 43: 83, 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 55], { 58: 31, 43: 84, 4: $V9, 5: $Va, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 60: $Vs, 61: $Vt, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), { 46: [1, 85] }, { 45: [1, 86] }, { 4: $VP, 5: $VQ, 6: $VR, 8: $VS, 11: $VT, 13: $VU, 16: 89, 17: $VV, 18: $VW, 19: $VX, 20: $VY, 22: 88, 23: 87 }, o($VO, [2, 24]), o($V7, [2, 51], { 59: 59, 58: 60, 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 54], { 59: 59, 58: 60, 4: $V9, 5: $Va, 8: $Vz, 10: $Vb, 12: $Vc, 13: $Vd, 14: $Ve, 18: $VA, 63: $Vu, 64: $Vv, 65: $Vw, 66: $Vx, 67: $Vy }), o($V7, [2, 47], { 22: 88, 16: 89, 23: 100, 4: $VP, 5: $VQ, 6: $VR, 8: $VS, 11: $VT, 13: $VU, 17: $VV, 18: $VW, 19: $VX, 20: $VY }), { 46: [1, 101] }, o($V7, [2, 29], { 10: $VZ }), o($V_, [2, 27], { 16: 103, 4: $VP, 5: $VQ, 6: $VR, 8: $VS, 11: $VT, 13: $VU, 17: $VV, 18: $VW, 19: $VX, 20: $VY }), o($V$, [2, 25]), o($V$, [2, 13]), o($V$, [2, 14]), o($V$, [2, 15]), o($V$, [2, 16]), o($V$, [2, 17]), o($V$, [2, 18]), o($V$, [2, 19]), o($V$, [2, 20]), o($V$, [2, 21]), o($V$, [2, 22]), o($V7, [2, 49], { 10: $VZ }), o($V7, [2, 48], { 22: 88, 16: 89, 23: 104, 4: $VP, 5: $VQ, 6: $VR, 8: $VS, 11: $VT, 13: $VU, 17: $VV, 18: $VW, 19: $VX, 20: $VY }), { 4: $VP, 5: $VQ, 6: $VR, 8: $VS, 11: $VT, 13: $VU, 16: 89, 17: $VV, 18: $VW, 19: $VX, 20: $VY, 22: 105 }, o($V$, [2, 26]), o($V7, [2, 50], { 10: $VZ }), o($V_, [2, 28], { 16: 103, 4: $VP, 5: $VQ, 6: $VR, 8: $VS, 11: $VT, 13: $VU, 17: $VV, 18: $VW, 19: $VX, 20: $VY })],\n defaultActions: { 8: [2, 30], 9: [2, 31] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n break;\n case 1:\n break;\n case 2:\n return 55;\n break;\n case 3:\n break;\n case 4:\n this.begin(\"title\");\n return 35;\n break;\n case 5:\n this.popState();\n return \"title_value\";\n break;\n case 6:\n this.begin(\"acc_title\");\n return 37;\n break;\n case 7:\n this.popState();\n return \"acc_title_value\";\n break;\n case 8:\n this.begin(\"acc_descr\");\n return 39;\n break;\n case 9:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 10:\n this.begin(\"acc_descr_multiline\");\n break;\n case 11:\n this.popState();\n break;\n case 12:\n return \"acc_descr_multiline_value\";\n break;\n case 13:\n return 48;\n break;\n case 14:\n return 50;\n break;\n case 15:\n return 49;\n break;\n case 16:\n return 51;\n break;\n case 17:\n return 52;\n break;\n case 18:\n return 53;\n break;\n case 19:\n return 54;\n break;\n case 20:\n return 25;\n break;\n case 21:\n this.begin(\"md_string\");\n break;\n case 22:\n return \"MD_STR\";\n break;\n case 23:\n this.popState();\n break;\n case 24:\n this.begin(\"string\");\n break;\n case 25:\n this.popState();\n break;\n case 26:\n return \"STR\";\n break;\n case 27:\n this.begin(\"class_name\");\n break;\n case 28:\n this.popState();\n return 47;\n break;\n case 29:\n this.begin(\"point_start\");\n return 44;\n break;\n case 30:\n this.begin(\"point_x\");\n return 45;\n break;\n case 31:\n this.popState();\n break;\n case 32:\n this.popState();\n this.begin(\"point_y\");\n break;\n case 33:\n this.popState();\n return 46;\n break;\n case 34:\n return 28;\n break;\n case 35:\n return 4;\n break;\n case 36:\n return 11;\n break;\n case 37:\n return 64;\n break;\n case 38:\n return 10;\n break;\n case 39:\n return 65;\n break;\n case 40:\n return 65;\n break;\n case 41:\n return 14;\n break;\n case 42:\n return 13;\n break;\n case 43:\n return 67;\n break;\n case 44:\n return 66;\n break;\n case 45:\n return 12;\n break;\n case 46:\n return 8;\n break;\n case 47:\n return 5;\n break;\n case 48:\n return 18;\n break;\n case 49:\n return 56;\n break;\n case 50:\n return 63;\n break;\n case 51:\n return 57;\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:%%(?!\\{)[^\\n]*)/i, /^(?:[^\\}]%%[^\\n]*)/i, /^(?:[\\n\\r]+)/i, /^(?:%%[^\\n]*)/i, /^(?:title\\b)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accTitle\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*\\{\\s*)/i, /^(?:[\\}])/i, /^(?:[^\\}]*)/i, /^(?: *x-axis *)/i, /^(?: *y-axis *)/i, /^(?: *--+> *)/i, /^(?: *quadrant-1 *)/i, /^(?: *quadrant-2 *)/i, /^(?: *quadrant-3 *)/i, /^(?: *quadrant-4 *)/i, /^(?:classDef\\b)/i, /^(?:[\"][`])/i, /^(?:[^`\"]+)/i, /^(?:[`][\"])/i, /^(?:[\"])/i, /^(?:[\"])/i, /^(?:[^\"]*)/i, /^(?::::)/i, /^(?:^\\w+)/i, /^(?:\\s*:\\s*\\[\\s*)/i, /^(?:(1)|(0(.\\d+)?))/i, /^(?:\\s*\\] *)/i, /^(?:\\s*,\\s*)/i, /^(?:(1)|(0(.\\d+)?))/i, /^(?: *quadrantChart *)/i, /^(?:[A-Za-z]+)/i, /^(?::)/i, /^(?:\\+)/i, /^(?:,)/i, /^(?:=)/i, /^(?:=)/i, /^(?:\\*)/i, /^(?:#)/i, /^(?:[\\_])/i, /^(?:\\.)/i, /^(?:&)/i, /^(?:-)/i, /^(?:[0-9]+)/i, /^(?:\\s)/i, /^(?:;)/i, /^(?:[!\"#$%&'*+,-.`?\\\\_/])/i, /^(?:$)/i],\n conditions: { \"class_name\": { \"rules\": [28], \"inclusive\": false }, \"point_y\": { \"rules\": [33], \"inclusive\": false }, \"point_x\": { \"rules\": [32], \"inclusive\": false }, \"point_start\": { \"rules\": [30, 31], \"inclusive\": false }, \"acc_descr_multiline\": { \"rules\": [11, 12], \"inclusive\": false }, \"acc_descr\": { \"rules\": [9], \"inclusive\": false }, \"acc_title\": { \"rules\": [7], \"inclusive\": false }, \"title\": { \"rules\": [5], \"inclusive\": false }, \"md_string\": { \"rules\": [22, 23], \"inclusive\": false }, \"string\": { \"rules\": [25, 26], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 2, 3, 4, 6, 8, 10, 13, 14, 15, 16, 17, 18, 19, 20, 21, 24, 27, 29, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar quadrant_default = parser;\n\n// src/diagrams/quadrant-chart/quadrantBuilder.ts\nimport { scaleLinear } from \"d3\";\nvar defaultThemeVariables = getThemeVariables();\nvar QuadrantBuilder = class {\n constructor() {\n this.classes = /* @__PURE__ */ new Map();\n this.config = this.getDefaultConfig();\n this.themeConfig = this.getDefaultThemeConfig();\n this.data = this.getDefaultData();\n }\n static {\n __name(this, \"QuadrantBuilder\");\n }\n getDefaultData() {\n return {\n titleText: \"\",\n quadrant1Text: \"\",\n quadrant2Text: \"\",\n quadrant3Text: \"\",\n quadrant4Text: \"\",\n xAxisLeftText: \"\",\n xAxisRightText: \"\",\n yAxisBottomText: \"\",\n yAxisTopText: \"\",\n points: []\n };\n }\n getDefaultConfig() {\n return {\n showXAxis: true,\n showYAxis: true,\n showTitle: true,\n chartHeight: defaultConfig_default.quadrantChart?.chartWidth || 500,\n chartWidth: defaultConfig_default.quadrantChart?.chartHeight || 500,\n titlePadding: defaultConfig_default.quadrantChart?.titlePadding || 10,\n titleFontSize: defaultConfig_default.quadrantChart?.titleFontSize || 20,\n quadrantPadding: defaultConfig_default.quadrantChart?.quadrantPadding || 5,\n xAxisLabelPadding: defaultConfig_default.quadrantChart?.xAxisLabelPadding || 5,\n yAxisLabelPadding: defaultConfig_default.quadrantChart?.yAxisLabelPadding || 5,\n xAxisLabelFontSize: defaultConfig_default.quadrantChart?.xAxisLabelFontSize || 16,\n yAxisLabelFontSize: defaultConfig_default.quadrantChart?.yAxisLabelFontSize || 16,\n quadrantLabelFontSize: defaultConfig_default.quadrantChart?.quadrantLabelFontSize || 16,\n quadrantTextTopPadding: defaultConfig_default.quadrantChart?.quadrantTextTopPadding || 5,\n pointTextPadding: defaultConfig_default.quadrantChart?.pointTextPadding || 5,\n pointLabelFontSize: defaultConfig_default.quadrantChart?.pointLabelFontSize || 12,\n pointRadius: defaultConfig_default.quadrantChart?.pointRadius || 5,\n xAxisPosition: defaultConfig_default.quadrantChart?.xAxisPosition || \"top\",\n yAxisPosition: defaultConfig_default.quadrantChart?.yAxisPosition || \"left\",\n quadrantInternalBorderStrokeWidth: defaultConfig_default.quadrantChart?.quadrantInternalBorderStrokeWidth || 1,\n quadrantExternalBorderStrokeWidth: defaultConfig_default.quadrantChart?.quadrantExternalBorderStrokeWidth || 2\n };\n }\n getDefaultThemeConfig() {\n return {\n quadrant1Fill: defaultThemeVariables.quadrant1Fill,\n quadrant2Fill: defaultThemeVariables.quadrant2Fill,\n quadrant3Fill: defaultThemeVariables.quadrant3Fill,\n quadrant4Fill: defaultThemeVariables.quadrant4Fill,\n quadrant1TextFill: defaultThemeVariables.quadrant1TextFill,\n quadrant2TextFill: defaultThemeVariables.quadrant2TextFill,\n quadrant3TextFill: defaultThemeVariables.quadrant3TextFill,\n quadrant4TextFill: defaultThemeVariables.quadrant4TextFill,\n quadrantPointFill: defaultThemeVariables.quadrantPointFill,\n quadrantPointTextFill: defaultThemeVariables.quadrantPointTextFill,\n quadrantXAxisTextFill: defaultThemeVariables.quadrantXAxisTextFill,\n quadrantYAxisTextFill: defaultThemeVariables.quadrantYAxisTextFill,\n quadrantTitleFill: defaultThemeVariables.quadrantTitleFill,\n quadrantInternalBorderStrokeFill: defaultThemeVariables.quadrantInternalBorderStrokeFill,\n quadrantExternalBorderStrokeFill: defaultThemeVariables.quadrantExternalBorderStrokeFill\n };\n }\n clear() {\n this.config = this.getDefaultConfig();\n this.themeConfig = this.getDefaultThemeConfig();\n this.data = this.getDefaultData();\n this.classes = /* @__PURE__ */ new Map();\n log.info(\"clear called\");\n }\n setData(data) {\n this.data = { ...this.data, ...data };\n }\n addPoints(points) {\n this.data.points = [...points, ...this.data.points];\n }\n addClass(className, styles) {\n this.classes.set(className, styles);\n }\n setConfig(config2) {\n log.trace(\"setConfig called with: \", config2);\n this.config = { ...this.config, ...config2 };\n }\n setThemeConfig(themeConfig) {\n log.trace(\"setThemeConfig called with: \", themeConfig);\n this.themeConfig = { ...this.themeConfig, ...themeConfig };\n }\n calculateSpace(xAxisPosition, showXAxis, showYAxis, showTitle) {\n const xAxisSpaceCalculation = this.config.xAxisLabelPadding * 2 + this.config.xAxisLabelFontSize;\n const xAxisSpace = {\n top: xAxisPosition === \"top\" && showXAxis ? xAxisSpaceCalculation : 0,\n bottom: xAxisPosition === \"bottom\" && showXAxis ? xAxisSpaceCalculation : 0\n };\n const yAxisSpaceCalculation = this.config.yAxisLabelPadding * 2 + this.config.yAxisLabelFontSize;\n const yAxisSpace = {\n left: this.config.yAxisPosition === \"left\" && showYAxis ? yAxisSpaceCalculation : 0,\n right: this.config.yAxisPosition === \"right\" && showYAxis ? yAxisSpaceCalculation : 0\n };\n const titleSpaceCalculation = this.config.titleFontSize + this.config.titlePadding * 2;\n const titleSpace = {\n top: showTitle ? titleSpaceCalculation : 0\n };\n const quadrantLeft = this.config.quadrantPadding + yAxisSpace.left;\n const quadrantTop = this.config.quadrantPadding + xAxisSpace.top + titleSpace.top;\n const quadrantWidth = this.config.chartWidth - this.config.quadrantPadding * 2 - yAxisSpace.left - yAxisSpace.right;\n const quadrantHeight = this.config.chartHeight - this.config.quadrantPadding * 2 - xAxisSpace.top - xAxisSpace.bottom - titleSpace.top;\n const quadrantHalfWidth = quadrantWidth / 2;\n const quadrantHalfHeight = quadrantHeight / 2;\n const quadrantSpace = {\n quadrantLeft,\n quadrantTop,\n quadrantWidth,\n quadrantHalfWidth,\n quadrantHeight,\n quadrantHalfHeight\n };\n return {\n xAxisSpace,\n yAxisSpace,\n titleSpace,\n quadrantSpace\n };\n }\n getAxisLabels(xAxisPosition, showXAxis, showYAxis, spaceData) {\n const { quadrantSpace, titleSpace } = spaceData;\n const {\n quadrantHalfHeight,\n quadrantHeight,\n quadrantLeft,\n quadrantHalfWidth,\n quadrantTop,\n quadrantWidth\n } = quadrantSpace;\n const drawXAxisLabelsInMiddle = Boolean(this.data.xAxisRightText);\n const drawYAxisLabelsInMiddle = Boolean(this.data.yAxisTopText);\n const axisLabels = [];\n if (this.data.xAxisLeftText && showXAxis) {\n axisLabels.push({\n text: this.data.xAxisLeftText,\n fill: this.themeConfig.quadrantXAxisTextFill,\n x: quadrantLeft + (drawXAxisLabelsInMiddle ? quadrantHalfWidth / 2 : 0),\n y: xAxisPosition === \"top\" ? this.config.xAxisLabelPadding + titleSpace.top : this.config.xAxisLabelPadding + quadrantTop + quadrantHeight + this.config.quadrantPadding,\n fontSize: this.config.xAxisLabelFontSize,\n verticalPos: drawXAxisLabelsInMiddle ? \"center\" : \"left\",\n horizontalPos: \"top\",\n rotation: 0\n });\n }\n if (this.data.xAxisRightText && showXAxis) {\n axisLabels.push({\n text: this.data.xAxisRightText,\n fill: this.themeConfig.quadrantXAxisTextFill,\n x: quadrantLeft + quadrantHalfWidth + (drawXAxisLabelsInMiddle ? quadrantHalfWidth / 2 : 0),\n y: xAxisPosition === \"top\" ? this.config.xAxisLabelPadding + titleSpace.top : this.config.xAxisLabelPadding + quadrantTop + quadrantHeight + this.config.quadrantPadding,\n fontSize: this.config.xAxisLabelFontSize,\n verticalPos: drawXAxisLabelsInMiddle ? \"center\" : \"left\",\n horizontalPos: \"top\",\n rotation: 0\n });\n }\n if (this.data.yAxisBottomText && showYAxis) {\n axisLabels.push({\n text: this.data.yAxisBottomText,\n fill: this.themeConfig.quadrantYAxisTextFill,\n x: this.config.yAxisPosition === \"left\" ? this.config.yAxisLabelPadding : this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth + this.config.quadrantPadding,\n y: quadrantTop + quadrantHeight - (drawYAxisLabelsInMiddle ? quadrantHalfHeight / 2 : 0),\n fontSize: this.config.yAxisLabelFontSize,\n verticalPos: drawYAxisLabelsInMiddle ? \"center\" : \"left\",\n horizontalPos: \"top\",\n rotation: -90\n });\n }\n if (this.data.yAxisTopText && showYAxis) {\n axisLabels.push({\n text: this.data.yAxisTopText,\n fill: this.themeConfig.quadrantYAxisTextFill,\n x: this.config.yAxisPosition === \"left\" ? this.config.yAxisLabelPadding : this.config.yAxisLabelPadding + quadrantLeft + quadrantWidth + this.config.quadrantPadding,\n y: quadrantTop + quadrantHalfHeight - (drawYAxisLabelsInMiddle ? quadrantHalfHeight / 2 : 0),\n fontSize: this.config.yAxisLabelFontSize,\n verticalPos: drawYAxisLabelsInMiddle ? \"center\" : \"left\",\n horizontalPos: \"top\",\n rotation: -90\n });\n }\n return axisLabels;\n }\n getQuadrants(spaceData) {\n const { quadrantSpace } = spaceData;\n const { quadrantHalfHeight, quadrantLeft, quadrantHalfWidth, quadrantTop } = quadrantSpace;\n const quadrants = [\n {\n text: {\n text: this.data.quadrant1Text,\n fill: this.themeConfig.quadrant1TextFill,\n x: 0,\n y: 0,\n fontSize: this.config.quadrantLabelFontSize,\n verticalPos: \"center\",\n horizontalPos: \"middle\",\n rotation: 0\n },\n x: quadrantLeft + quadrantHalfWidth,\n y: quadrantTop,\n width: quadrantHalfWidth,\n height: quadrantHalfHeight,\n fill: this.themeConfig.quadrant1Fill\n },\n {\n text: {\n text: this.data.quadrant2Text,\n fill: this.themeConfig.quadrant2TextFill,\n x: 0,\n y: 0,\n fontSize: this.config.quadrantLabelFontSize,\n verticalPos: \"center\",\n horizontalPos: \"middle\",\n rotation: 0\n },\n x: quadrantLeft,\n y: quadrantTop,\n width: quadrantHalfWidth,\n height: quadrantHalfHeight,\n fill: this.themeConfig.quadrant2Fill\n },\n {\n text: {\n text: this.data.quadrant3Text,\n fill: this.themeConfig.quadrant3TextFill,\n x: 0,\n y: 0,\n fontSize: this.config.quadrantLabelFontSize,\n verticalPos: \"center\",\n horizontalPos: \"middle\",\n rotation: 0\n },\n x: quadrantLeft,\n y: quadrantTop + quadrantHalfHeight,\n width: quadrantHalfWidth,\n height: quadrantHalfHeight,\n fill: this.themeConfig.quadrant3Fill\n },\n {\n text: {\n text: this.data.quadrant4Text,\n fill: this.themeConfig.quadrant4TextFill,\n x: 0,\n y: 0,\n fontSize: this.config.quadrantLabelFontSize,\n verticalPos: \"center\",\n horizontalPos: \"middle\",\n rotation: 0\n },\n x: quadrantLeft + quadrantHalfWidth,\n y: quadrantTop + quadrantHalfHeight,\n width: quadrantHalfWidth,\n height: quadrantHalfHeight,\n fill: this.themeConfig.quadrant4Fill\n }\n ];\n for (const quadrant of quadrants) {\n quadrant.text.x = quadrant.x + quadrant.width / 2;\n if (this.data.points.length === 0) {\n quadrant.text.y = quadrant.y + quadrant.height / 2;\n quadrant.text.horizontalPos = \"middle\";\n } else {\n quadrant.text.y = quadrant.y + this.config.quadrantTextTopPadding;\n quadrant.text.horizontalPos = \"top\";\n }\n }\n return quadrants;\n }\n getQuadrantPoints(spaceData) {\n const { quadrantSpace } = spaceData;\n const { quadrantHeight, quadrantLeft, quadrantTop, quadrantWidth } = quadrantSpace;\n const xAxis = scaleLinear().domain([0, 1]).range([quadrantLeft, quadrantWidth + quadrantLeft]);\n const yAxis = scaleLinear().domain([0, 1]).range([quadrantHeight + quadrantTop, quadrantTop]);\n const points = this.data.points.map((point) => {\n const classStyles = this.classes.get(point.className);\n if (classStyles) {\n point = { ...classStyles, ...point };\n }\n const props = {\n x: xAxis(point.x),\n y: yAxis(point.y),\n fill: point.color ?? this.themeConfig.quadrantPointFill,\n radius: point.radius ?? this.config.pointRadius,\n text: {\n text: point.text,\n fill: this.themeConfig.quadrantPointTextFill,\n x: xAxis(point.x),\n y: yAxis(point.y) + this.config.pointTextPadding,\n verticalPos: \"center\",\n horizontalPos: \"top\",\n fontSize: this.config.pointLabelFontSize,\n rotation: 0\n },\n strokeColor: point.strokeColor ?? this.themeConfig.quadrantPointFill,\n strokeWidth: point.strokeWidth ?? \"0px\"\n };\n return props;\n });\n return points;\n }\n getBorders(spaceData) {\n const halfExternalBorderWidth = this.config.quadrantExternalBorderStrokeWidth / 2;\n const { quadrantSpace } = spaceData;\n const {\n quadrantHalfHeight,\n quadrantHeight,\n quadrantLeft,\n quadrantHalfWidth,\n quadrantTop,\n quadrantWidth\n } = quadrantSpace;\n const borderLines = [\n // top border\n {\n strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill,\n strokeWidth: this.config.quadrantExternalBorderStrokeWidth,\n x1: quadrantLeft - halfExternalBorderWidth,\n y1: quadrantTop,\n x2: quadrantLeft + quadrantWidth + halfExternalBorderWidth,\n y2: quadrantTop\n },\n // right border\n {\n strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill,\n strokeWidth: this.config.quadrantExternalBorderStrokeWidth,\n x1: quadrantLeft + quadrantWidth,\n y1: quadrantTop + halfExternalBorderWidth,\n x2: quadrantLeft + quadrantWidth,\n y2: quadrantTop + quadrantHeight - halfExternalBorderWidth\n },\n // bottom border\n {\n strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill,\n strokeWidth: this.config.quadrantExternalBorderStrokeWidth,\n x1: quadrantLeft - halfExternalBorderWidth,\n y1: quadrantTop + quadrantHeight,\n x2: quadrantLeft + quadrantWidth + halfExternalBorderWidth,\n y2: quadrantTop + quadrantHeight\n },\n // left border\n {\n strokeFill: this.themeConfig.quadrantExternalBorderStrokeFill,\n strokeWidth: this.config.quadrantExternalBorderStrokeWidth,\n x1: quadrantLeft,\n y1: quadrantTop + halfExternalBorderWidth,\n x2: quadrantLeft,\n y2: quadrantTop + quadrantHeight - halfExternalBorderWidth\n },\n // vertical inner border\n {\n strokeFill: this.themeConfig.quadrantInternalBorderStrokeFill,\n strokeWidth: this.config.quadrantInternalBorderStrokeWidth,\n x1: quadrantLeft + quadrantHalfWidth,\n y1: quadrantTop + halfExternalBorderWidth,\n x2: quadrantLeft + quadrantHalfWidth,\n y2: quadrantTop + quadrantHeight - halfExternalBorderWidth\n },\n // horizontal inner border\n {\n strokeFill: this.themeConfig.quadrantInternalBorderStrokeFill,\n strokeWidth: this.config.quadrantInternalBorderStrokeWidth,\n x1: quadrantLeft + halfExternalBorderWidth,\n y1: quadrantTop + quadrantHalfHeight,\n x2: quadrantLeft + quadrantWidth - halfExternalBorderWidth,\n y2: quadrantTop + quadrantHalfHeight\n }\n ];\n return borderLines;\n }\n getTitle(showTitle) {\n if (showTitle) {\n return {\n text: this.data.titleText,\n fill: this.themeConfig.quadrantTitleFill,\n fontSize: this.config.titleFontSize,\n horizontalPos: \"top\",\n verticalPos: \"center\",\n rotation: 0,\n y: this.config.titlePadding,\n x: this.config.chartWidth / 2\n };\n }\n return;\n }\n build() {\n const showXAxis = this.config.showXAxis && !!(this.data.xAxisLeftText || this.data.xAxisRightText);\n const showYAxis = this.config.showYAxis && !!(this.data.yAxisTopText || this.data.yAxisBottomText);\n const showTitle = this.config.showTitle && !!this.data.titleText;\n const xAxisPosition = this.data.points.length > 0 ? \"bottom\" : this.config.xAxisPosition;\n const calculatedSpace = this.calculateSpace(xAxisPosition, showXAxis, showYAxis, showTitle);\n return {\n points: this.getQuadrantPoints(calculatedSpace),\n quadrants: this.getQuadrants(calculatedSpace),\n axisLabels: this.getAxisLabels(xAxisPosition, showXAxis, showYAxis, calculatedSpace),\n borderLines: this.getBorders(calculatedSpace),\n title: this.getTitle(showTitle)\n };\n }\n};\n\n// src/diagrams/quadrant-chart/utils.ts\nvar InvalidStyleError = class extends Error {\n static {\n __name(this, \"InvalidStyleError\");\n }\n constructor(style, value, type) {\n super(`value for ${style} ${value} is invalid, please use a valid ${type}`);\n this.name = \"InvalidStyleError\";\n }\n};\nfunction validateHexCode(value) {\n return !/^#?([\\dA-Fa-f]{6}|[\\dA-Fa-f]{3})$/.test(value);\n}\n__name(validateHexCode, \"validateHexCode\");\nfunction validateNumber(value) {\n return !/^\\d+$/.test(value);\n}\n__name(validateNumber, \"validateNumber\");\nfunction validateSizeInPixels(value) {\n return !/^\\d+px$/.test(value);\n}\n__name(validateSizeInPixels, \"validateSizeInPixels\");\n\n// src/diagrams/quadrant-chart/quadrantDb.ts\nvar config = getConfig();\nfunction textSanitizer(text) {\n return sanitizeText(text.trim(), config);\n}\n__name(textSanitizer, \"textSanitizer\");\nvar quadrantBuilder = new QuadrantBuilder();\nfunction setQuadrant1Text(textObj) {\n quadrantBuilder.setData({ quadrant1Text: textSanitizer(textObj.text) });\n}\n__name(setQuadrant1Text, \"setQuadrant1Text\");\nfunction setQuadrant2Text(textObj) {\n quadrantBuilder.setData({ quadrant2Text: textSanitizer(textObj.text) });\n}\n__name(setQuadrant2Text, \"setQuadrant2Text\");\nfunction setQuadrant3Text(textObj) {\n quadrantBuilder.setData({ quadrant3Text: textSanitizer(textObj.text) });\n}\n__name(setQuadrant3Text, \"setQuadrant3Text\");\nfunction setQuadrant4Text(textObj) {\n quadrantBuilder.setData({ quadrant4Text: textSanitizer(textObj.text) });\n}\n__name(setQuadrant4Text, \"setQuadrant4Text\");\nfunction setXAxisLeftText(textObj) {\n quadrantBuilder.setData({ xAxisLeftText: textSanitizer(textObj.text) });\n}\n__name(setXAxisLeftText, \"setXAxisLeftText\");\nfunction setXAxisRightText(textObj) {\n quadrantBuilder.setData({ xAxisRightText: textSanitizer(textObj.text) });\n}\n__name(setXAxisRightText, \"setXAxisRightText\");\nfunction setYAxisTopText(textObj) {\n quadrantBuilder.setData({ yAxisTopText: textSanitizer(textObj.text) });\n}\n__name(setYAxisTopText, \"setYAxisTopText\");\nfunction setYAxisBottomText(textObj) {\n quadrantBuilder.setData({ yAxisBottomText: textSanitizer(textObj.text) });\n}\n__name(setYAxisBottomText, \"setYAxisBottomText\");\nfunction parseStyles(styles) {\n const stylesObject = {};\n for (const style of styles) {\n const [key, value] = style.trim().split(/\\s*:\\s*/);\n if (key === \"radius\") {\n if (validateNumber(value)) {\n throw new InvalidStyleError(key, value, \"number\");\n }\n stylesObject.radius = parseInt(value);\n } else if (key === \"color\") {\n if (validateHexCode(value)) {\n throw new InvalidStyleError(key, value, \"hex code\");\n }\n stylesObject.color = value;\n } else if (key === \"stroke-color\") {\n if (validateHexCode(value)) {\n throw new InvalidStyleError(key, value, \"hex code\");\n }\n stylesObject.strokeColor = value;\n } else if (key === \"stroke-width\") {\n if (validateSizeInPixels(value)) {\n throw new InvalidStyleError(key, value, \"number of pixels (eg. 10px)\");\n }\n stylesObject.strokeWidth = value;\n } else {\n throw new Error(`style named ${key} is not supported.`);\n }\n }\n return stylesObject;\n}\n__name(parseStyles, \"parseStyles\");\nfunction addPoint(textObj, className, x, y, styles) {\n const stylesObject = parseStyles(styles);\n quadrantBuilder.addPoints([\n {\n x,\n y,\n text: textSanitizer(textObj.text),\n className,\n ...stylesObject\n }\n ]);\n}\n__name(addPoint, \"addPoint\");\nfunction addClass(className, styles) {\n quadrantBuilder.addClass(className, parseStyles(styles));\n}\n__name(addClass, \"addClass\");\nfunction setWidth(width) {\n quadrantBuilder.setConfig({ chartWidth: width });\n}\n__name(setWidth, \"setWidth\");\nfunction setHeight(height) {\n quadrantBuilder.setConfig({ chartHeight: height });\n}\n__name(setHeight, \"setHeight\");\nfunction getQuadrantData() {\n const config2 = getConfig();\n const { themeVariables, quadrantChart: quadrantChartConfig } = config2;\n if (quadrantChartConfig) {\n quadrantBuilder.setConfig(quadrantChartConfig);\n }\n quadrantBuilder.setThemeConfig({\n quadrant1Fill: themeVariables.quadrant1Fill,\n quadrant2Fill: themeVariables.quadrant2Fill,\n quadrant3Fill: themeVariables.quadrant3Fill,\n quadrant4Fill: themeVariables.quadrant4Fill,\n quadrant1TextFill: themeVariables.quadrant1TextFill,\n quadrant2TextFill: themeVariables.quadrant2TextFill,\n quadrant3TextFill: themeVariables.quadrant3TextFill,\n quadrant4TextFill: themeVariables.quadrant4TextFill,\n quadrantPointFill: themeVariables.quadrantPointFill,\n quadrantPointTextFill: themeVariables.quadrantPointTextFill,\n quadrantXAxisTextFill: themeVariables.quadrantXAxisTextFill,\n quadrantYAxisTextFill: themeVariables.quadrantYAxisTextFill,\n quadrantExternalBorderStrokeFill: themeVariables.quadrantExternalBorderStrokeFill,\n quadrantInternalBorderStrokeFill: themeVariables.quadrantInternalBorderStrokeFill,\n quadrantTitleFill: themeVariables.quadrantTitleFill\n });\n quadrantBuilder.setData({ titleText: getDiagramTitle() });\n return quadrantBuilder.build();\n}\n__name(getQuadrantData, \"getQuadrantData\");\nvar clear2 = /* @__PURE__ */ __name(function() {\n quadrantBuilder.clear();\n clear();\n}, \"clear\");\nvar quadrantDb_default = {\n setWidth,\n setHeight,\n setQuadrant1Text,\n setQuadrant2Text,\n setQuadrant3Text,\n setQuadrant4Text,\n setXAxisLeftText,\n setXAxisRightText,\n setYAxisTopText,\n setYAxisBottomText,\n parseStyles,\n addPoint,\n addClass,\n getQuadrantData,\n clear: clear2,\n setAccTitle,\n getAccTitle,\n setDiagramTitle,\n getDiagramTitle,\n getAccDescription,\n setAccDescription\n};\n\n// src/diagrams/quadrant-chart/quadrantRenderer.ts\nimport { select } from \"d3\";\nvar draw = /* @__PURE__ */ __name((txt, id, _version, diagObj) => {\n function getDominantBaseLine(horizontalPos) {\n return horizontalPos === \"top\" ? \"hanging\" : \"middle\";\n }\n __name(getDominantBaseLine, \"getDominantBaseLine\");\n function getTextAnchor(verticalPos) {\n return verticalPos === \"left\" ? \"start\" : \"middle\";\n }\n __name(getTextAnchor, \"getTextAnchor\");\n function getTransformation(data) {\n return `translate(${data.x}, ${data.y}) rotate(${data.rotation || 0})`;\n }\n __name(getTransformation, \"getTransformation\");\n const conf = getConfig();\n log.debug(\"Rendering quadrant chart\\n\" + txt);\n const securityLevel = conf.securityLevel;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select(sandboxElement.nodes()[0].contentDocument.body) : select(\"body\");\n const svg = root.select(`[id=\"${id}\"]`);\n const group = svg.append(\"g\").attr(\"class\", \"main\");\n const width = conf.quadrantChart?.chartWidth ?? 500;\n const height = conf.quadrantChart?.chartHeight ?? 500;\n configureSvgSize(svg, height, width, conf.quadrantChart?.useMaxWidth ?? true);\n svg.attr(\"viewBox\", \"0 0 \" + width + \" \" + height);\n diagObj.db.setHeight(height);\n diagObj.db.setWidth(width);\n const quadrantData = diagObj.db.getQuadrantData();\n const quadrantsGroup = group.append(\"g\").attr(\"class\", \"quadrants\");\n const borderGroup = group.append(\"g\").attr(\"class\", \"border\");\n const dataPointGroup = group.append(\"g\").attr(\"class\", \"data-points\");\n const labelGroup = group.append(\"g\").attr(\"class\", \"labels\");\n const titleGroup = group.append(\"g\").attr(\"class\", \"title\");\n if (quadrantData.title) {\n titleGroup.append(\"text\").attr(\"x\", 0).attr(\"y\", 0).attr(\"fill\", quadrantData.title.fill).attr(\"font-size\", quadrantData.title.fontSize).attr(\"dominant-baseline\", getDominantBaseLine(quadrantData.title.horizontalPos)).attr(\"text-anchor\", getTextAnchor(quadrantData.title.verticalPos)).attr(\"transform\", getTransformation(quadrantData.title)).text(quadrantData.title.text);\n }\n if (quadrantData.borderLines) {\n borderGroup.selectAll(\"line\").data(quadrantData.borderLines).enter().append(\"line\").attr(\"x1\", (data) => data.x1).attr(\"y1\", (data) => data.y1).attr(\"x2\", (data) => data.x2).attr(\"y2\", (data) => data.y2).style(\"stroke\", (data) => data.strokeFill).style(\"stroke-width\", (data) => data.strokeWidth);\n }\n const quadrants = quadrantsGroup.selectAll(\"g.quadrant\").data(quadrantData.quadrants).enter().append(\"g\").attr(\"class\", \"quadrant\");\n quadrants.append(\"rect\").attr(\"x\", (data) => data.x).attr(\"y\", (data) => data.y).attr(\"width\", (data) => data.width).attr(\"height\", (data) => data.height).attr(\"fill\", (data) => data.fill);\n quadrants.append(\"text\").attr(\"x\", 0).attr(\"y\", 0).attr(\"fill\", (data) => data.text.fill).attr(\"font-size\", (data) => data.text.fontSize).attr(\n \"dominant-baseline\",\n (data) => getDominantBaseLine(data.text.horizontalPos)\n ).attr(\"text-anchor\", (data) => getTextAnchor(data.text.verticalPos)).attr(\"transform\", (data) => getTransformation(data.text)).text((data) => data.text.text);\n const labels = labelGroup.selectAll(\"g.label\").data(quadrantData.axisLabels).enter().append(\"g\").attr(\"class\", \"label\");\n labels.append(\"text\").attr(\"x\", 0).attr(\"y\", 0).text((data) => data.text).attr(\"fill\", (data) => data.fill).attr(\"font-size\", (data) => data.fontSize).attr(\"dominant-baseline\", (data) => getDominantBaseLine(data.horizontalPos)).attr(\"text-anchor\", (data) => getTextAnchor(data.verticalPos)).attr(\"transform\", (data) => getTransformation(data));\n const dataPoints = dataPointGroup.selectAll(\"g.data-point\").data(quadrantData.points).enter().append(\"g\").attr(\"class\", \"data-point\");\n dataPoints.append(\"circle\").attr(\"cx\", (data) => data.x).attr(\"cy\", (data) => data.y).attr(\"r\", (data) => data.radius).attr(\"fill\", (data) => data.fill).attr(\"stroke\", (data) => data.strokeColor).attr(\"stroke-width\", (data) => data.strokeWidth);\n dataPoints.append(\"text\").attr(\"x\", 0).attr(\"y\", 0).text((data) => data.text.text).attr(\"fill\", (data) => data.text.fill).attr(\"font-size\", (data) => data.text.fontSize).attr(\n \"dominant-baseline\",\n (data) => getDominantBaseLine(data.text.horizontalPos)\n ).attr(\"text-anchor\", (data) => getTextAnchor(data.text.verticalPos)).attr(\"transform\", (data) => getTransformation(data.text));\n}, \"draw\");\nvar quadrantRenderer_default = {\n draw\n};\n\n// src/diagrams/quadrant-chart/quadrantDiagram.ts\nvar diagram = {\n parser: quadrant_default,\n db: quadrantDb_default,\n renderer: quadrantRenderer_default,\n styles: /* @__PURE__ */ __name(() => \"\", \"styles\")\n};\nexport {\n diagram\n};\n", "import {\n computeDimensionOfText\n} from \"./chunk-5N55DQE6.mjs\";\nimport {\n cleanAndMerge\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n selectSvgElement\n} from \"./chunk-F2XFN3BY.mjs\";\nimport {\n __name,\n clear,\n configureSvgSize,\n defaultConfig_default,\n getAccDescription,\n getAccTitle,\n getConfig,\n getDiagramTitle,\n getThemeVariables,\n log,\n sanitizeText,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/xychart/parser/xychart.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 10, 12, 14, 16, 18, 19, 21, 23], $V1 = [2, 6], $V2 = [1, 3], $V3 = [1, 5], $V4 = [1, 6], $V5 = [1, 7], $V6 = [1, 5, 10, 12, 14, 16, 18, 19, 21, 23, 34, 35, 36], $V7 = [1, 25], $V8 = [1, 26], $V9 = [1, 28], $Va = [1, 29], $Vb = [1, 30], $Vc = [1, 31], $Vd = [1, 32], $Ve = [1, 33], $Vf = [1, 34], $Vg = [1, 35], $Vh = [1, 36], $Vi = [1, 37], $Vj = [1, 43], $Vk = [1, 42], $Vl = [1, 47], $Vm = [1, 50], $Vn = [1, 10, 12, 14, 16, 18, 19, 21, 23, 34, 35, 36], $Vo = [1, 10, 12, 14, 16, 18, 19, 21, 23, 24, 26, 27, 28, 34, 35, 36], $Vp = [1, 10, 12, 14, 16, 18, 19, 21, 23, 24, 26, 27, 28, 34, 35, 36, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50], $Vq = [1, 64];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"eol\": 4, \"XYCHART\": 5, \"chartConfig\": 6, \"document\": 7, \"CHART_ORIENTATION\": 8, \"statement\": 9, \"title\": 10, \"text\": 11, \"X_AXIS\": 12, \"parseXAxis\": 13, \"Y_AXIS\": 14, \"parseYAxis\": 15, \"LINE\": 16, \"plotData\": 17, \"BAR\": 18, \"acc_title\": 19, \"acc_title_value\": 20, \"acc_descr\": 21, \"acc_descr_value\": 22, \"acc_descr_multiline_value\": 23, \"SQUARE_BRACES_START\": 24, \"commaSeparatedNumbers\": 25, \"SQUARE_BRACES_END\": 26, \"NUMBER_WITH_DECIMAL\": 27, \"COMMA\": 28, \"xAxisData\": 29, \"bandData\": 30, \"ARROW_DELIMITER\": 31, \"commaSeparatedTexts\": 32, \"yAxisData\": 33, \"NEWLINE\": 34, \"SEMI\": 35, \"EOF\": 36, \"alphaNum\": 37, \"STR\": 38, \"MD_STR\": 39, \"alphaNumToken\": 40, \"AMP\": 41, \"NUM\": 42, \"ALPHA\": 43, \"PLUS\": 44, \"EQUALS\": 45, \"MULT\": 46, \"DOT\": 47, \"BRKT\": 48, \"MINUS\": 49, \"UNDERSCORE\": 50, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 5: \"XYCHART\", 8: \"CHART_ORIENTATION\", 10: \"title\", 12: \"X_AXIS\", 14: \"Y_AXIS\", 16: \"LINE\", 18: \"BAR\", 19: \"acc_title\", 20: \"acc_title_value\", 21: \"acc_descr\", 22: \"acc_descr_value\", 23: \"acc_descr_multiline_value\", 24: \"SQUARE_BRACES_START\", 26: \"SQUARE_BRACES_END\", 27: \"NUMBER_WITH_DECIMAL\", 28: \"COMMA\", 31: \"ARROW_DELIMITER\", 34: \"NEWLINE\", 35: \"SEMI\", 36: \"EOF\", 38: \"STR\", 39: \"MD_STR\", 41: \"AMP\", 42: \"NUM\", 43: \"ALPHA\", 44: \"PLUS\", 45: \"EQUALS\", 46: \"MULT\", 47: \"DOT\", 48: \"BRKT\", 49: \"MINUS\", 50: \"UNDERSCORE\" },\n productions_: [0, [3, 2], [3, 3], [3, 2], [3, 1], [6, 1], [7, 0], [7, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 3], [9, 2], [9, 3], [9, 2], [9, 2], [9, 1], [17, 3], [25, 3], [25, 1], [13, 1], [13, 2], [13, 1], [29, 1], [29, 3], [30, 3], [32, 3], [32, 1], [15, 1], [15, 2], [15, 1], [33, 3], [4, 1], [4, 1], [4, 1], [11, 1], [11, 1], [11, 1], [37, 1], [37, 2], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1], [40, 1]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 5:\n yy.setOrientation($$[$0]);\n break;\n case 9:\n yy.setDiagramTitle($$[$0].text.trim());\n break;\n case 12:\n yy.setLineData({ text: \"\", type: \"text\" }, $$[$0]);\n break;\n case 13:\n yy.setLineData($$[$0 - 1], $$[$0]);\n break;\n case 14:\n yy.setBarData({ text: \"\", type: \"text\" }, $$[$0]);\n break;\n case 15:\n yy.setBarData($$[$0 - 1], $$[$0]);\n break;\n case 16:\n this.$ = $$[$0].trim();\n yy.setAccTitle(this.$);\n break;\n case 17:\n case 18:\n this.$ = $$[$0].trim();\n yy.setAccDescription(this.$);\n break;\n case 19:\n this.$ = $$[$0 - 1];\n break;\n case 20:\n this.$ = [Number($$[$0 - 2]), ...$$[$0]];\n break;\n case 21:\n this.$ = [Number($$[$0])];\n break;\n case 22:\n yy.setXAxisTitle($$[$0]);\n break;\n case 23:\n yy.setXAxisTitle($$[$0 - 1]);\n break;\n case 24:\n yy.setXAxisTitle({ type: \"text\", text: \"\" });\n break;\n case 25:\n yy.setXAxisBand($$[$0]);\n break;\n case 26:\n yy.setXAxisRangeData(Number($$[$0 - 2]), Number($$[$0]));\n break;\n case 27:\n this.$ = $$[$0 - 1];\n break;\n case 28:\n this.$ = [$$[$0 - 2], ...$$[$0]];\n break;\n case 29:\n this.$ = [$$[$0]];\n break;\n case 30:\n yy.setYAxisTitle($$[$0]);\n break;\n case 31:\n yy.setYAxisTitle($$[$0 - 1]);\n break;\n case 32:\n yy.setYAxisTitle({ type: \"text\", text: \"\" });\n break;\n case 33:\n yy.setYAxisRangeData(Number($$[$0 - 2]), Number($$[$0]));\n break;\n case 37:\n this.$ = { text: $$[$0], type: \"text\" };\n break;\n case 38:\n this.$ = { text: $$[$0], type: \"text\" };\n break;\n case 39:\n this.$ = { text: $$[$0], type: \"markdown\" };\n break;\n case 40:\n this.$ = $$[$0];\n break;\n case 41:\n this.$ = $$[$0 - 1] + \"\" + $$[$0];\n break;\n }\n }, \"anonymous\"),\n table: [o($V0, $V1, { 3: 1, 4: 2, 7: 4, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), { 1: [3] }, o($V0, $V1, { 4: 2, 7: 4, 3: 8, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), o($V0, $V1, { 4: 2, 7: 4, 6: 9, 3: 10, 5: $V2, 8: [1, 11], 34: $V3, 35: $V4, 36: $V5 }), { 1: [2, 4], 9: 12, 10: [1, 13], 12: [1, 14], 14: [1, 15], 16: [1, 16], 18: [1, 17], 19: [1, 18], 21: [1, 19], 23: [1, 20] }, o($V6, [2, 34]), o($V6, [2, 35]), o($V6, [2, 36]), { 1: [2, 1] }, o($V0, $V1, { 4: 2, 7: 4, 3: 21, 5: $V2, 34: $V3, 35: $V4, 36: $V5 }), { 1: [2, 3] }, o($V6, [2, 5]), o($V0, [2, 7], { 4: 22, 34: $V3, 35: $V4, 36: $V5 }), { 11: 23, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 39, 13: 38, 24: $Vj, 27: $Vk, 29: 40, 30: 41, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 45, 15: 44, 27: $Vl, 33: 46, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 49, 17: 48, 24: $Vm, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 11: 52, 17: 51, 24: $Vm, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, { 20: [1, 53] }, { 22: [1, 54] }, o($Vn, [2, 18]), { 1: [2, 2] }, o($Vn, [2, 8]), o($Vn, [2, 9]), o($Vo, [2, 37], { 40: 55, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }), o($Vo, [2, 38]), o($Vo, [2, 39]), o($Vp, [2, 40]), o($Vp, [2, 42]), o($Vp, [2, 43]), o($Vp, [2, 44]), o($Vp, [2, 45]), o($Vp, [2, 46]), o($Vp, [2, 47]), o($Vp, [2, 48]), o($Vp, [2, 49]), o($Vp, [2, 50]), o($Vp, [2, 51]), o($Vn, [2, 10]), o($Vn, [2, 22], { 30: 41, 29: 56, 24: $Vj, 27: $Vk }), o($Vn, [2, 24]), o($Vn, [2, 25]), { 31: [1, 57] }, { 11: 59, 32: 58, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, o($Vn, [2, 11]), o($Vn, [2, 30], { 33: 60, 27: $Vl }), o($Vn, [2, 32]), { 31: [1, 61] }, o($Vn, [2, 12]), { 17: 62, 24: $Vm }, { 25: 63, 27: $Vq }, o($Vn, [2, 14]), { 17: 65, 24: $Vm }, o($Vn, [2, 16]), o($Vn, [2, 17]), o($Vp, [2, 41]), o($Vn, [2, 23]), { 27: [1, 66] }, { 26: [1, 67] }, { 26: [2, 29], 28: [1, 68] }, o($Vn, [2, 31]), { 27: [1, 69] }, o($Vn, [2, 13]), { 26: [1, 70] }, { 26: [2, 21], 28: [1, 71] }, o($Vn, [2, 15]), o($Vn, [2, 26]), o($Vn, [2, 27]), { 11: 59, 32: 72, 37: 24, 38: $V7, 39: $V8, 40: 27, 41: $V9, 42: $Va, 43: $Vb, 44: $Vc, 45: $Vd, 46: $Ve, 47: $Vf, 48: $Vg, 49: $Vh, 50: $Vi }, o($Vn, [2, 33]), o($Vn, [2, 19]), { 25: 73, 27: $Vq }, { 26: [2, 28] }, { 26: [2, 20] }],\n defaultActions: { 8: [2, 1], 10: [2, 3], 21: [2, 2], 72: [2, 28], 73: [2, 20] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n break;\n case 1:\n break;\n case 2:\n this.popState();\n return 34;\n break;\n case 3:\n this.popState();\n return 34;\n break;\n case 4:\n return 34;\n break;\n case 5:\n break;\n case 6:\n return 10;\n break;\n case 7:\n this.pushState(\"acc_title\");\n return 19;\n break;\n case 8:\n this.popState();\n return \"acc_title_value\";\n break;\n case 9:\n this.pushState(\"acc_descr\");\n return 21;\n break;\n case 10:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 11:\n this.pushState(\"acc_descr_multiline\");\n break;\n case 12:\n this.popState();\n break;\n case 13:\n return \"acc_descr_multiline_value\";\n break;\n case 14:\n return 5;\n break;\n case 15:\n return 8;\n break;\n case 16:\n this.pushState(\"axis_data\");\n return \"X_AXIS\";\n break;\n case 17:\n this.pushState(\"axis_data\");\n return \"Y_AXIS\";\n break;\n case 18:\n this.pushState(\"axis_band_data\");\n return 24;\n break;\n case 19:\n return 31;\n break;\n case 20:\n this.pushState(\"data\");\n return 16;\n break;\n case 21:\n this.pushState(\"data\");\n return 18;\n break;\n case 22:\n this.pushState(\"data_inner\");\n return 24;\n break;\n case 23:\n return 27;\n break;\n case 24:\n this.popState();\n return 26;\n break;\n case 25:\n this.popState();\n break;\n case 26:\n this.pushState(\"string\");\n break;\n case 27:\n this.popState();\n break;\n case 28:\n return \"STR\";\n break;\n case 29:\n return 24;\n break;\n case 30:\n return 26;\n break;\n case 31:\n return 43;\n break;\n case 32:\n return \"COLON\";\n break;\n case 33:\n return 44;\n break;\n case 34:\n return 28;\n break;\n case 35:\n return 45;\n break;\n case 36:\n return 46;\n break;\n case 37:\n return 48;\n break;\n case 38:\n return 50;\n break;\n case 39:\n return 47;\n break;\n case 40:\n return 41;\n break;\n case 41:\n return 49;\n break;\n case 42:\n return 42;\n break;\n case 43:\n break;\n case 44:\n return 35;\n break;\n case 45:\n return 36;\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:%%(?!\\{)[^\\n]*)/i, /^(?:[^\\}]%%[^\\n]*)/i, /^(?:(\\r?\\n))/i, /^(?:(\\r?\\n))/i, /^(?:[\\n\\r]+)/i, /^(?:%%[^\\n]*)/i, /^(?:title\\b)/i, /^(?:accTitle\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*\\{\\s*)/i, /^(?:\\{)/i, /^(?:[^\\}]*)/i, /^(?:xychart-beta\\b)/i, /^(?:(?:vertical|horizontal))/i, /^(?:x-axis\\b)/i, /^(?:y-axis\\b)/i, /^(?:\\[)/i, /^(?:-->)/i, /^(?:line\\b)/i, /^(?:bar\\b)/i, /^(?:\\[)/i, /^(?:[+-]?(?:\\d+(?:\\.\\d+)?|\\.\\d+))/i, /^(?:\\])/i, /^(?:(?:`\\) \\{ this\\.pushState\\(md_string\\); \\}\\n\\(\\?:\\(\\?!`\"\\)\\.\\)\\+ \\{ return MD_STR; \\}\\n\\(\\?:`))/i, /^(?:[\"])/i, /^(?:[\"])/i, /^(?:[^\"]*)/i, /^(?:\\[)/i, /^(?:\\])/i, /^(?:[A-Za-z]+)/i, /^(?::)/i, /^(?:\\+)/i, /^(?:,)/i, /^(?:=)/i, /^(?:\\*)/i, /^(?:#)/i, /^(?:[\\_])/i, /^(?:\\.)/i, /^(?:&)/i, /^(?:-)/i, /^(?:[0-9]+)/i, /^(?:\\s+)/i, /^(?:;)/i, /^(?:$)/i],\n conditions: { \"data_inner\": { \"rules\": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 23, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], \"inclusive\": true }, \"data\": { \"rules\": [0, 1, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 22, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], \"inclusive\": true }, \"axis_band_data\": { \"rules\": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 24, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], \"inclusive\": true }, \"axis_data\": { \"rules\": [0, 1, 2, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18, 19, 20, 21, 23, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], \"inclusive\": true }, \"acc_descr_multiline\": { \"rules\": [12, 13], \"inclusive\": false }, \"acc_descr\": { \"rules\": [10], \"inclusive\": false }, \"acc_title\": { \"rules\": [8], \"inclusive\": false }, \"title\": { \"rules\": [], \"inclusive\": false }, \"md_string\": { \"rules\": [], \"inclusive\": false }, \"string\": { \"rules\": [27, 28], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 20, 21, 25, 26, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar xychart_default = parser;\n\n// src/diagrams/xychart/chartBuilder/interfaces.ts\nfunction isBarPlot(data) {\n return data.type === \"bar\";\n}\n__name(isBarPlot, \"isBarPlot\");\nfunction isBandAxisData(data) {\n return data.type === \"band\";\n}\n__name(isBandAxisData, \"isBandAxisData\");\nfunction isLinearAxisData(data) {\n return data.type === \"linear\";\n}\n__name(isLinearAxisData, \"isLinearAxisData\");\n\n// src/diagrams/xychart/chartBuilder/textDimensionCalculator.ts\nvar TextDimensionCalculatorWithFont = class {\n constructor(parentGroup) {\n this.parentGroup = parentGroup;\n }\n static {\n __name(this, \"TextDimensionCalculatorWithFont\");\n }\n getMaxDimension(texts, fontSize) {\n if (!this.parentGroup) {\n return {\n width: texts.reduce((acc, cur) => Math.max(cur.length, acc), 0) * fontSize,\n height: fontSize\n };\n }\n const dimension = {\n width: 0,\n height: 0\n };\n const elem = this.parentGroup.append(\"g\").attr(\"visibility\", \"hidden\").attr(\"font-size\", fontSize);\n for (const t of texts) {\n const bbox = computeDimensionOfText(elem, 1, t);\n const width = bbox ? bbox.width : t.length * fontSize;\n const height = bbox ? bbox.height : fontSize;\n dimension.width = Math.max(dimension.width, width);\n dimension.height = Math.max(dimension.height, height);\n }\n elem.remove();\n return dimension;\n }\n};\n\n// src/diagrams/xychart/chartBuilder/components/axis/bandAxis.ts\nimport { scaleBand } from \"d3\";\n\n// src/diagrams/xychart/chartBuilder/components/axis/baseAxis.ts\nvar BAR_WIDTH_TO_TICK_WIDTH_RATIO = 0.7;\nvar MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL = 0.2;\nvar BaseAxis = class {\n constructor(axisConfig, title, textDimensionCalculator, axisThemeConfig) {\n this.axisConfig = axisConfig;\n this.title = title;\n this.textDimensionCalculator = textDimensionCalculator;\n this.axisThemeConfig = axisThemeConfig;\n this.boundingRect = { x: 0, y: 0, width: 0, height: 0 };\n this.axisPosition = \"left\";\n this.showTitle = false;\n this.showLabel = false;\n this.showTick = false;\n this.showAxisLine = false;\n this.outerPadding = 0;\n this.titleTextHeight = 0;\n this.labelTextHeight = 0;\n this.range = [0, 10];\n this.boundingRect = { x: 0, y: 0, width: 0, height: 0 };\n this.axisPosition = \"left\";\n }\n static {\n __name(this, \"BaseAxis\");\n }\n setRange(range) {\n this.range = range;\n if (this.axisPosition === \"left\" || this.axisPosition === \"right\") {\n this.boundingRect.height = range[1] - range[0];\n } else {\n this.boundingRect.width = range[1] - range[0];\n }\n this.recalculateScale();\n }\n getRange() {\n return [this.range[0] + this.outerPadding, this.range[1] - this.outerPadding];\n }\n setAxisPosition(axisPosition) {\n this.axisPosition = axisPosition;\n this.setRange(this.range);\n }\n getTickDistance() {\n const range = this.getRange();\n return Math.abs(range[0] - range[1]) / this.getTickValues().length;\n }\n getAxisOuterPadding() {\n return this.outerPadding;\n }\n getLabelDimension() {\n return this.textDimensionCalculator.getMaxDimension(\n this.getTickValues().map((tick) => tick.toString()),\n this.axisConfig.labelFontSize\n );\n }\n recalculateOuterPaddingToDrawBar() {\n if (BAR_WIDTH_TO_TICK_WIDTH_RATIO * this.getTickDistance() > this.outerPadding * 2) {\n this.outerPadding = Math.floor(BAR_WIDTH_TO_TICK_WIDTH_RATIO * this.getTickDistance() / 2);\n }\n this.recalculateScale();\n }\n calculateSpaceIfDrawnHorizontally(availableSpace) {\n let availableHeight = availableSpace.height;\n if (this.axisConfig.showAxisLine && availableHeight > this.axisConfig.axisLineWidth) {\n availableHeight -= this.axisConfig.axisLineWidth;\n this.showAxisLine = true;\n }\n if (this.axisConfig.showLabel) {\n const spaceRequired = this.getLabelDimension();\n const maxPadding = MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL * availableSpace.width;\n this.outerPadding = Math.min(spaceRequired.width / 2, maxPadding);\n const heightRequired = spaceRequired.height + this.axisConfig.labelPadding * 2;\n this.labelTextHeight = spaceRequired.height;\n if (heightRequired <= availableHeight) {\n availableHeight -= heightRequired;\n this.showLabel = true;\n }\n }\n if (this.axisConfig.showTick && availableHeight >= this.axisConfig.tickLength) {\n this.showTick = true;\n availableHeight -= this.axisConfig.tickLength;\n }\n if (this.axisConfig.showTitle && this.title) {\n const spaceRequired = this.textDimensionCalculator.getMaxDimension(\n [this.title],\n this.axisConfig.titleFontSize\n );\n const heightRequired = spaceRequired.height + this.axisConfig.titlePadding * 2;\n this.titleTextHeight = spaceRequired.height;\n if (heightRequired <= availableHeight) {\n availableHeight -= heightRequired;\n this.showTitle = true;\n }\n }\n this.boundingRect.width = availableSpace.width;\n this.boundingRect.height = availableSpace.height - availableHeight;\n }\n calculateSpaceIfDrawnVertical(availableSpace) {\n let availableWidth = availableSpace.width;\n if (this.axisConfig.showAxisLine && availableWidth > this.axisConfig.axisLineWidth) {\n availableWidth -= this.axisConfig.axisLineWidth;\n this.showAxisLine = true;\n }\n if (this.axisConfig.showLabel) {\n const spaceRequired = this.getLabelDimension();\n const maxPadding = MAX_OUTER_PADDING_PERCENT_FOR_WRT_LABEL * availableSpace.height;\n this.outerPadding = Math.min(spaceRequired.height / 2, maxPadding);\n const widthRequired = spaceRequired.width + this.axisConfig.labelPadding * 2;\n if (widthRequired <= availableWidth) {\n availableWidth -= widthRequired;\n this.showLabel = true;\n }\n }\n if (this.axisConfig.showTick && availableWidth >= this.axisConfig.tickLength) {\n this.showTick = true;\n availableWidth -= this.axisConfig.tickLength;\n }\n if (this.axisConfig.showTitle && this.title) {\n const spaceRequired = this.textDimensionCalculator.getMaxDimension(\n [this.title],\n this.axisConfig.titleFontSize\n );\n const widthRequired = spaceRequired.height + this.axisConfig.titlePadding * 2;\n this.titleTextHeight = spaceRequired.height;\n if (widthRequired <= availableWidth) {\n availableWidth -= widthRequired;\n this.showTitle = true;\n }\n }\n this.boundingRect.width = availableSpace.width - availableWidth;\n this.boundingRect.height = availableSpace.height;\n }\n calculateSpace(availableSpace) {\n if (this.axisPosition === \"left\" || this.axisPosition === \"right\") {\n this.calculateSpaceIfDrawnVertical(availableSpace);\n } else {\n this.calculateSpaceIfDrawnHorizontally(availableSpace);\n }\n this.recalculateScale();\n return {\n width: this.boundingRect.width,\n height: this.boundingRect.height\n };\n }\n setBoundingBoxXY(point) {\n this.boundingRect.x = point.x;\n this.boundingRect.y = point.y;\n }\n getDrawableElementsForLeftAxis() {\n const drawableElement = [];\n if (this.showAxisLine) {\n const x = this.boundingRect.x + this.boundingRect.width - this.axisConfig.axisLineWidth / 2;\n drawableElement.push({\n type: \"path\",\n groupTexts: [\"left-axis\", \"axisl-line\"],\n data: [\n {\n path: `M ${x},${this.boundingRect.y} L ${x},${this.boundingRect.y + this.boundingRect.height} `,\n strokeFill: this.axisThemeConfig.axisLineColor,\n strokeWidth: this.axisConfig.axisLineWidth\n }\n ]\n });\n }\n if (this.showLabel) {\n drawableElement.push({\n type: \"text\",\n groupTexts: [\"left-axis\", \"label\"],\n data: this.getTickValues().map((tick) => ({\n text: tick.toString(),\n x: this.boundingRect.x + this.boundingRect.width - (this.showLabel ? this.axisConfig.labelPadding : 0) - (this.showTick ? this.axisConfig.tickLength : 0) - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0),\n y: this.getScaleValue(tick),\n fill: this.axisThemeConfig.labelColor,\n fontSize: this.axisConfig.labelFontSize,\n rotation: 0,\n verticalPos: \"middle\",\n horizontalPos: \"right\"\n }))\n });\n }\n if (this.showTick) {\n const x = this.boundingRect.x + this.boundingRect.width - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0);\n drawableElement.push({\n type: \"path\",\n groupTexts: [\"left-axis\", \"ticks\"],\n data: this.getTickValues().map((tick) => ({\n path: `M ${x},${this.getScaleValue(tick)} L ${x - this.axisConfig.tickLength},${this.getScaleValue(tick)}`,\n strokeFill: this.axisThemeConfig.tickColor,\n strokeWidth: this.axisConfig.tickWidth\n }))\n });\n }\n if (this.showTitle) {\n drawableElement.push({\n type: \"text\",\n groupTexts: [\"left-axis\", \"title\"],\n data: [\n {\n text: this.title,\n x: this.boundingRect.x + this.axisConfig.titlePadding,\n y: this.boundingRect.y + this.boundingRect.height / 2,\n fill: this.axisThemeConfig.titleColor,\n fontSize: this.axisConfig.titleFontSize,\n rotation: 270,\n verticalPos: \"top\",\n horizontalPos: \"center\"\n }\n ]\n });\n }\n return drawableElement;\n }\n getDrawableElementsForBottomAxis() {\n const drawableElement = [];\n if (this.showAxisLine) {\n const y = this.boundingRect.y + this.axisConfig.axisLineWidth / 2;\n drawableElement.push({\n type: \"path\",\n groupTexts: [\"bottom-axis\", \"axis-line\"],\n data: [\n {\n path: `M ${this.boundingRect.x},${y} L ${this.boundingRect.x + this.boundingRect.width},${y}`,\n strokeFill: this.axisThemeConfig.axisLineColor,\n strokeWidth: this.axisConfig.axisLineWidth\n }\n ]\n });\n }\n if (this.showLabel) {\n drawableElement.push({\n type: \"text\",\n groupTexts: [\"bottom-axis\", \"label\"],\n data: this.getTickValues().map((tick) => ({\n text: tick.toString(),\n x: this.getScaleValue(tick),\n y: this.boundingRect.y + this.axisConfig.labelPadding + (this.showTick ? this.axisConfig.tickLength : 0) + (this.showAxisLine ? this.axisConfig.axisLineWidth : 0),\n fill: this.axisThemeConfig.labelColor,\n fontSize: this.axisConfig.labelFontSize,\n rotation: 0,\n verticalPos: \"top\",\n horizontalPos: \"center\"\n }))\n });\n }\n if (this.showTick) {\n const y = this.boundingRect.y + (this.showAxisLine ? this.axisConfig.axisLineWidth : 0);\n drawableElement.push({\n type: \"path\",\n groupTexts: [\"bottom-axis\", \"ticks\"],\n data: this.getTickValues().map((tick) => ({\n path: `M ${this.getScaleValue(tick)},${y} L ${this.getScaleValue(tick)},${y + this.axisConfig.tickLength}`,\n strokeFill: this.axisThemeConfig.tickColor,\n strokeWidth: this.axisConfig.tickWidth\n }))\n });\n }\n if (this.showTitle) {\n drawableElement.push({\n type: \"text\",\n groupTexts: [\"bottom-axis\", \"title\"],\n data: [\n {\n text: this.title,\n x: this.range[0] + (this.range[1] - this.range[0]) / 2,\n y: this.boundingRect.y + this.boundingRect.height - this.axisConfig.titlePadding - this.titleTextHeight,\n fill: this.axisThemeConfig.titleColor,\n fontSize: this.axisConfig.titleFontSize,\n rotation: 0,\n verticalPos: \"top\",\n horizontalPos: \"center\"\n }\n ]\n });\n }\n return drawableElement;\n }\n getDrawableElementsForTopAxis() {\n const drawableElement = [];\n if (this.showAxisLine) {\n const y = this.boundingRect.y + this.boundingRect.height - this.axisConfig.axisLineWidth / 2;\n drawableElement.push({\n type: \"path\",\n groupTexts: [\"top-axis\", \"axis-line\"],\n data: [\n {\n path: `M ${this.boundingRect.x},${y} L ${this.boundingRect.x + this.boundingRect.width},${y}`,\n strokeFill: this.axisThemeConfig.axisLineColor,\n strokeWidth: this.axisConfig.axisLineWidth\n }\n ]\n });\n }\n if (this.showLabel) {\n drawableElement.push({\n type: \"text\",\n groupTexts: [\"top-axis\", \"label\"],\n data: this.getTickValues().map((tick) => ({\n text: tick.toString(),\n x: this.getScaleValue(tick),\n y: this.boundingRect.y + (this.showTitle ? this.titleTextHeight + this.axisConfig.titlePadding * 2 : 0) + this.axisConfig.labelPadding,\n fill: this.axisThemeConfig.labelColor,\n fontSize: this.axisConfig.labelFontSize,\n rotation: 0,\n verticalPos: \"top\",\n horizontalPos: \"center\"\n }))\n });\n }\n if (this.showTick) {\n const y = this.boundingRect.y;\n drawableElement.push({\n type: \"path\",\n groupTexts: [\"top-axis\", \"ticks\"],\n data: this.getTickValues().map((tick) => ({\n path: `M ${this.getScaleValue(tick)},${y + this.boundingRect.height - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0)} L ${this.getScaleValue(tick)},${y + this.boundingRect.height - this.axisConfig.tickLength - (this.showAxisLine ? this.axisConfig.axisLineWidth : 0)}`,\n strokeFill: this.axisThemeConfig.tickColor,\n strokeWidth: this.axisConfig.tickWidth\n }))\n });\n }\n if (this.showTitle) {\n drawableElement.push({\n type: \"text\",\n groupTexts: [\"top-axis\", \"title\"],\n data: [\n {\n text: this.title,\n x: this.boundingRect.x + this.boundingRect.width / 2,\n y: this.boundingRect.y + this.axisConfig.titlePadding,\n fill: this.axisThemeConfig.titleColor,\n fontSize: this.axisConfig.titleFontSize,\n rotation: 0,\n verticalPos: \"top\",\n horizontalPos: \"center\"\n }\n ]\n });\n }\n return drawableElement;\n }\n getDrawableElements() {\n if (this.axisPosition === \"left\") {\n return this.getDrawableElementsForLeftAxis();\n }\n if (this.axisPosition === \"right\") {\n throw Error(\"Drawing of right axis is not implemented\");\n }\n if (this.axisPosition === \"bottom\") {\n return this.getDrawableElementsForBottomAxis();\n }\n if (this.axisPosition === \"top\") {\n return this.getDrawableElementsForTopAxis();\n }\n return [];\n }\n};\n\n// src/diagrams/xychart/chartBuilder/components/axis/bandAxis.ts\nvar BandAxis = class extends BaseAxis {\n static {\n __name(this, \"BandAxis\");\n }\n constructor(axisConfig, axisThemeConfig, categories, title, textDimensionCalculator) {\n super(axisConfig, title, textDimensionCalculator, axisThemeConfig);\n this.categories = categories;\n this.scale = scaleBand().domain(this.categories).range(this.getRange());\n }\n setRange(range) {\n super.setRange(range);\n }\n recalculateScale() {\n this.scale = scaleBand().domain(this.categories).range(this.getRange()).paddingInner(1).paddingOuter(0).align(0.5);\n log.trace(\"BandAxis axis final categories, range: \", this.categories, this.getRange());\n }\n getTickValues() {\n return this.categories;\n }\n getScaleValue(value) {\n return this.scale(value) ?? this.getRange()[0];\n }\n};\n\n// src/diagrams/xychart/chartBuilder/components/axis/linearAxis.ts\nimport { scaleLinear } from \"d3\";\nvar LinearAxis = class extends BaseAxis {\n static {\n __name(this, \"LinearAxis\");\n }\n constructor(axisConfig, axisThemeConfig, domain, title, textDimensionCalculator) {\n super(axisConfig, title, textDimensionCalculator, axisThemeConfig);\n this.domain = domain;\n this.scale = scaleLinear().domain(this.domain).range(this.getRange());\n }\n getTickValues() {\n return this.scale.ticks();\n }\n recalculateScale() {\n const domain = [...this.domain];\n if (this.axisPosition === \"left\") {\n domain.reverse();\n }\n this.scale = scaleLinear().domain(domain).range(this.getRange());\n }\n getScaleValue(value) {\n return this.scale(value);\n }\n};\n\n// src/diagrams/xychart/chartBuilder/components/axis/index.ts\nfunction getAxis(data, axisConfig, axisThemeConfig, tmpSVGGroup2) {\n const textDimensionCalculator = new TextDimensionCalculatorWithFont(tmpSVGGroup2);\n if (isBandAxisData(data)) {\n return new BandAxis(\n axisConfig,\n axisThemeConfig,\n data.categories,\n data.title,\n textDimensionCalculator\n );\n }\n return new LinearAxis(\n axisConfig,\n axisThemeConfig,\n [data.min, data.max],\n data.title,\n textDimensionCalculator\n );\n}\n__name(getAxis, \"getAxis\");\n\n// src/diagrams/xychart/chartBuilder/components/chartTitle.ts\nvar ChartTitle = class {\n constructor(textDimensionCalculator, chartConfig, chartData, chartThemeConfig) {\n this.textDimensionCalculator = textDimensionCalculator;\n this.chartConfig = chartConfig;\n this.chartData = chartData;\n this.chartThemeConfig = chartThemeConfig;\n this.boundingRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0\n };\n this.showChartTitle = false;\n }\n static {\n __name(this, \"ChartTitle\");\n }\n setBoundingBoxXY(point) {\n this.boundingRect.x = point.x;\n this.boundingRect.y = point.y;\n }\n calculateSpace(availableSpace) {\n const titleDimension = this.textDimensionCalculator.getMaxDimension(\n [this.chartData.title],\n this.chartConfig.titleFontSize\n );\n const widthRequired = Math.max(titleDimension.width, availableSpace.width);\n const heightRequired = titleDimension.height + 2 * this.chartConfig.titlePadding;\n if (titleDimension.width <= widthRequired && titleDimension.height <= heightRequired && this.chartConfig.showTitle && this.chartData.title) {\n this.boundingRect.width = widthRequired;\n this.boundingRect.height = heightRequired;\n this.showChartTitle = true;\n }\n return {\n width: this.boundingRect.width,\n height: this.boundingRect.height\n };\n }\n getDrawableElements() {\n const drawableElem = [];\n if (this.showChartTitle) {\n drawableElem.push({\n groupTexts: [\"chart-title\"],\n type: \"text\",\n data: [\n {\n fontSize: this.chartConfig.titleFontSize,\n text: this.chartData.title,\n verticalPos: \"middle\",\n horizontalPos: \"center\",\n x: this.boundingRect.x + this.boundingRect.width / 2,\n y: this.boundingRect.y + this.boundingRect.height / 2,\n fill: this.chartThemeConfig.titleColor,\n rotation: 0\n }\n ]\n });\n }\n return drawableElem;\n }\n};\nfunction getChartTitleComponent(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2) {\n const textDimensionCalculator = new TextDimensionCalculatorWithFont(tmpSVGGroup2);\n return new ChartTitle(textDimensionCalculator, chartConfig, chartData, chartThemeConfig);\n}\n__name(getChartTitleComponent, \"getChartTitleComponent\");\n\n// src/diagrams/xychart/chartBuilder/components/plot/linePlot.ts\nimport { line } from \"d3\";\nvar LinePlot = class {\n constructor(plotData, xAxis, yAxis, orientation, plotIndex2) {\n this.plotData = plotData;\n this.xAxis = xAxis;\n this.yAxis = yAxis;\n this.orientation = orientation;\n this.plotIndex = plotIndex2;\n }\n static {\n __name(this, \"LinePlot\");\n }\n getDrawableElement() {\n const finalData = this.plotData.data.map((d) => [\n this.xAxis.getScaleValue(d[0]),\n this.yAxis.getScaleValue(d[1])\n ]);\n let path;\n if (this.orientation === \"horizontal\") {\n path = line().y((d) => d[0]).x((d) => d[1])(finalData);\n } else {\n path = line().x((d) => d[0]).y((d) => d[1])(finalData);\n }\n if (!path) {\n return [];\n }\n return [\n {\n groupTexts: [\"plot\", `line-plot-${this.plotIndex}`],\n type: \"path\",\n data: [\n {\n path,\n strokeFill: this.plotData.strokeFill,\n strokeWidth: this.plotData.strokeWidth\n }\n ]\n }\n ];\n }\n};\n\n// src/diagrams/xychart/chartBuilder/components/plot/barPlot.ts\nvar BarPlot = class {\n constructor(barData, boundingRect, xAxis, yAxis, orientation, plotIndex2) {\n this.barData = barData;\n this.boundingRect = boundingRect;\n this.xAxis = xAxis;\n this.yAxis = yAxis;\n this.orientation = orientation;\n this.plotIndex = plotIndex2;\n }\n static {\n __name(this, \"BarPlot\");\n }\n getDrawableElement() {\n const finalData = this.barData.data.map((d) => [\n this.xAxis.getScaleValue(d[0]),\n this.yAxis.getScaleValue(d[1])\n ]);\n const barPaddingPercent = 0.05;\n const barWidth = Math.min(this.xAxis.getAxisOuterPadding() * 2, this.xAxis.getTickDistance()) * (1 - barPaddingPercent);\n const barWidthHalf = barWidth / 2;\n if (this.orientation === \"horizontal\") {\n return [\n {\n groupTexts: [\"plot\", `bar-plot-${this.plotIndex}`],\n type: \"rect\",\n data: finalData.map((data) => ({\n x: this.boundingRect.x,\n y: data[0] - barWidthHalf,\n height: barWidth,\n width: data[1] - this.boundingRect.x,\n fill: this.barData.fill,\n strokeWidth: 0,\n strokeFill: this.barData.fill\n }))\n }\n ];\n }\n return [\n {\n groupTexts: [\"plot\", `bar-plot-${this.plotIndex}`],\n type: \"rect\",\n data: finalData.map((data) => ({\n x: data[0] - barWidthHalf,\n y: data[1],\n width: barWidth,\n height: this.boundingRect.y + this.boundingRect.height - data[1],\n fill: this.barData.fill,\n strokeWidth: 0,\n strokeFill: this.barData.fill\n }))\n }\n ];\n }\n};\n\n// src/diagrams/xychart/chartBuilder/components/plot/index.ts\nvar BasePlot = class {\n constructor(chartConfig, chartData, chartThemeConfig) {\n this.chartConfig = chartConfig;\n this.chartData = chartData;\n this.chartThemeConfig = chartThemeConfig;\n this.boundingRect = {\n x: 0,\n y: 0,\n width: 0,\n height: 0\n };\n }\n static {\n __name(this, \"BasePlot\");\n }\n setAxes(xAxis, yAxis) {\n this.xAxis = xAxis;\n this.yAxis = yAxis;\n }\n setBoundingBoxXY(point) {\n this.boundingRect.x = point.x;\n this.boundingRect.y = point.y;\n }\n calculateSpace(availableSpace) {\n this.boundingRect.width = availableSpace.width;\n this.boundingRect.height = availableSpace.height;\n return {\n width: this.boundingRect.width,\n height: this.boundingRect.height\n };\n }\n getDrawableElements() {\n if (!(this.xAxis && this.yAxis)) {\n throw Error(\"Axes must be passed to render Plots\");\n }\n const drawableElem = [];\n for (const [i, plot] of this.chartData.plots.entries()) {\n switch (plot.type) {\n case \"line\":\n {\n const linePlot = new LinePlot(\n plot,\n this.xAxis,\n this.yAxis,\n this.chartConfig.chartOrientation,\n i\n );\n drawableElem.push(...linePlot.getDrawableElement());\n }\n break;\n case \"bar\":\n {\n const barPlot = new BarPlot(\n plot,\n this.boundingRect,\n this.xAxis,\n this.yAxis,\n this.chartConfig.chartOrientation,\n i\n );\n drawableElem.push(...barPlot.getDrawableElement());\n }\n break;\n }\n }\n return drawableElem;\n }\n};\nfunction getPlotComponent(chartConfig, chartData, chartThemeConfig) {\n return new BasePlot(chartConfig, chartData, chartThemeConfig);\n}\n__name(getPlotComponent, \"getPlotComponent\");\n\n// src/diagrams/xychart/chartBuilder/orchestrator.ts\nvar Orchestrator = class {\n constructor(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2) {\n this.chartConfig = chartConfig;\n this.chartData = chartData;\n this.componentStore = {\n title: getChartTitleComponent(chartConfig, chartData, chartThemeConfig, tmpSVGGroup2),\n plot: getPlotComponent(chartConfig, chartData, chartThemeConfig),\n xAxis: getAxis(\n chartData.xAxis,\n chartConfig.xAxis,\n {\n titleColor: chartThemeConfig.xAxisTitleColor,\n labelColor: chartThemeConfig.xAxisLabelColor,\n tickColor: chartThemeConfig.xAxisTickColor,\n axisLineColor: chartThemeConfig.xAxisLineColor\n },\n tmpSVGGroup2\n ),\n yAxis: getAxis(\n chartData.yAxis,\n chartConfig.yAxis,\n {\n titleColor: chartThemeConfig.yAxisTitleColor,\n labelColor: chartThemeConfig.yAxisLabelColor,\n tickColor: chartThemeConfig.yAxisTickColor,\n axisLineColor: chartThemeConfig.yAxisLineColor\n },\n tmpSVGGroup2\n )\n };\n }\n static {\n __name(this, \"Orchestrator\");\n }\n calculateVerticalSpace() {\n let availableWidth = this.chartConfig.width;\n let availableHeight = this.chartConfig.height;\n let plotX = 0;\n let plotY = 0;\n let chartWidth = Math.floor(availableWidth * this.chartConfig.plotReservedSpacePercent / 100);\n let chartHeight = Math.floor(\n availableHeight * this.chartConfig.plotReservedSpacePercent / 100\n );\n let spaceUsed = this.componentStore.plot.calculateSpace({\n width: chartWidth,\n height: chartHeight\n });\n availableWidth -= spaceUsed.width;\n availableHeight -= spaceUsed.height;\n spaceUsed = this.componentStore.title.calculateSpace({\n width: this.chartConfig.width,\n height: availableHeight\n });\n plotY = spaceUsed.height;\n availableHeight -= spaceUsed.height;\n this.componentStore.xAxis.setAxisPosition(\"bottom\");\n spaceUsed = this.componentStore.xAxis.calculateSpace({\n width: availableWidth,\n height: availableHeight\n });\n availableHeight -= spaceUsed.height;\n this.componentStore.yAxis.setAxisPosition(\"left\");\n spaceUsed = this.componentStore.yAxis.calculateSpace({\n width: availableWidth,\n height: availableHeight\n });\n plotX = spaceUsed.width;\n availableWidth -= spaceUsed.width;\n if (availableWidth > 0) {\n chartWidth += availableWidth;\n availableWidth = 0;\n }\n if (availableHeight > 0) {\n chartHeight += availableHeight;\n availableHeight = 0;\n }\n this.componentStore.plot.calculateSpace({\n width: chartWidth,\n height: chartHeight\n });\n this.componentStore.plot.setBoundingBoxXY({ x: plotX, y: plotY });\n this.componentStore.xAxis.setRange([plotX, plotX + chartWidth]);\n this.componentStore.xAxis.setBoundingBoxXY({ x: plotX, y: plotY + chartHeight });\n this.componentStore.yAxis.setRange([plotY, plotY + chartHeight]);\n this.componentStore.yAxis.setBoundingBoxXY({ x: 0, y: plotY });\n if (this.chartData.plots.some((p) => isBarPlot(p))) {\n this.componentStore.xAxis.recalculateOuterPaddingToDrawBar();\n }\n }\n calculateHorizontalSpace() {\n let availableWidth = this.chartConfig.width;\n let availableHeight = this.chartConfig.height;\n let titleYEnd = 0;\n let plotX = 0;\n let plotY = 0;\n let chartWidth = Math.floor(availableWidth * this.chartConfig.plotReservedSpacePercent / 100);\n let chartHeight = Math.floor(\n availableHeight * this.chartConfig.plotReservedSpacePercent / 100\n );\n let spaceUsed = this.componentStore.plot.calculateSpace({\n width: chartWidth,\n height: chartHeight\n });\n availableWidth -= spaceUsed.width;\n availableHeight -= spaceUsed.height;\n spaceUsed = this.componentStore.title.calculateSpace({\n width: this.chartConfig.width,\n height: availableHeight\n });\n titleYEnd = spaceUsed.height;\n availableHeight -= spaceUsed.height;\n this.componentStore.xAxis.setAxisPosition(\"left\");\n spaceUsed = this.componentStore.xAxis.calculateSpace({\n width: availableWidth,\n height: availableHeight\n });\n availableWidth -= spaceUsed.width;\n plotX = spaceUsed.width;\n this.componentStore.yAxis.setAxisPosition(\"top\");\n spaceUsed = this.componentStore.yAxis.calculateSpace({\n width: availableWidth,\n height: availableHeight\n });\n availableHeight -= spaceUsed.height;\n plotY = titleYEnd + spaceUsed.height;\n if (availableWidth > 0) {\n chartWidth += availableWidth;\n availableWidth = 0;\n }\n if (availableHeight > 0) {\n chartHeight += availableHeight;\n availableHeight = 0;\n }\n this.componentStore.plot.calculateSpace({\n width: chartWidth,\n height: chartHeight\n });\n this.componentStore.plot.setBoundingBoxXY({ x: plotX, y: plotY });\n this.componentStore.yAxis.setRange([plotX, plotX + chartWidth]);\n this.componentStore.yAxis.setBoundingBoxXY({ x: plotX, y: titleYEnd });\n this.componentStore.xAxis.setRange([plotY, plotY + chartHeight]);\n this.componentStore.xAxis.setBoundingBoxXY({ x: 0, y: plotY });\n if (this.chartData.plots.some((p) => isBarPlot(p))) {\n this.componentStore.xAxis.recalculateOuterPaddingToDrawBar();\n }\n }\n calculateSpace() {\n if (this.chartConfig.chartOrientation === \"horizontal\") {\n this.calculateHorizontalSpace();\n } else {\n this.calculateVerticalSpace();\n }\n }\n getDrawableElement() {\n this.calculateSpace();\n const drawableElem = [];\n this.componentStore.plot.setAxes(this.componentStore.xAxis, this.componentStore.yAxis);\n for (const component of Object.values(this.componentStore)) {\n drawableElem.push(...component.getDrawableElements());\n }\n return drawableElem;\n }\n};\n\n// src/diagrams/xychart/chartBuilder/index.ts\nvar XYChartBuilder = class {\n static {\n __name(this, \"XYChartBuilder\");\n }\n static build(config, chartData, chartThemeConfig, tmpSVGGroup2) {\n const orchestrator = new Orchestrator(config, chartData, chartThemeConfig, tmpSVGGroup2);\n return orchestrator.getDrawableElement();\n }\n};\n\n// src/diagrams/xychart/xychartDb.ts\nvar plotIndex = 0;\nvar tmpSVGGroup;\nvar xyChartConfig = getChartDefaultConfig();\nvar xyChartThemeConfig = getChartDefaultThemeConfig();\nvar xyChartData = getChartDefaultData();\nvar plotColorPalette = xyChartThemeConfig.plotColorPalette.split(\",\").map((color) => color.trim());\nvar hasSetXAxis = false;\nvar hasSetYAxis = false;\nfunction getChartDefaultThemeConfig() {\n const defaultThemeVariables = getThemeVariables();\n const config = getConfig();\n return cleanAndMerge(defaultThemeVariables.xyChart, config.themeVariables.xyChart);\n}\n__name(getChartDefaultThemeConfig, \"getChartDefaultThemeConfig\");\nfunction getChartDefaultConfig() {\n const config = getConfig();\n return cleanAndMerge(\n defaultConfig_default.xyChart,\n config.xyChart\n );\n}\n__name(getChartDefaultConfig, \"getChartDefaultConfig\");\nfunction getChartDefaultData() {\n return {\n yAxis: {\n type: \"linear\",\n title: \"\",\n min: Infinity,\n max: -Infinity\n },\n xAxis: {\n type: \"band\",\n title: \"\",\n categories: []\n },\n title: \"\",\n plots: []\n };\n}\n__name(getChartDefaultData, \"getChartDefaultData\");\nfunction textSanitizer(text) {\n const config = getConfig();\n return sanitizeText(text.trim(), config);\n}\n__name(textSanitizer, \"textSanitizer\");\nfunction setTmpSVGG(SVGG) {\n tmpSVGGroup = SVGG;\n}\n__name(setTmpSVGG, \"setTmpSVGG\");\nfunction setOrientation(orientation) {\n if (orientation === \"horizontal\") {\n xyChartConfig.chartOrientation = \"horizontal\";\n } else {\n xyChartConfig.chartOrientation = \"vertical\";\n }\n}\n__name(setOrientation, \"setOrientation\");\nfunction setXAxisTitle(title) {\n xyChartData.xAxis.title = textSanitizer(title.text);\n}\n__name(setXAxisTitle, \"setXAxisTitle\");\nfunction setXAxisRangeData(min, max) {\n xyChartData.xAxis = { type: \"linear\", title: xyChartData.xAxis.title, min, max };\n hasSetXAxis = true;\n}\n__name(setXAxisRangeData, \"setXAxisRangeData\");\nfunction setXAxisBand(categories) {\n xyChartData.xAxis = {\n type: \"band\",\n title: xyChartData.xAxis.title,\n categories: categories.map((c) => textSanitizer(c.text))\n };\n hasSetXAxis = true;\n}\n__name(setXAxisBand, \"setXAxisBand\");\nfunction setYAxisTitle(title) {\n xyChartData.yAxis.title = textSanitizer(title.text);\n}\n__name(setYAxisTitle, \"setYAxisTitle\");\nfunction setYAxisRangeData(min, max) {\n xyChartData.yAxis = { type: \"linear\", title: xyChartData.yAxis.title, min, max };\n hasSetYAxis = true;\n}\n__name(setYAxisRangeData, \"setYAxisRangeData\");\nfunction setYAxisRangeFromPlotData(data) {\n const minValue = Math.min(...data);\n const maxValue = Math.max(...data);\n const prevMinValue = isLinearAxisData(xyChartData.yAxis) ? xyChartData.yAxis.min : Infinity;\n const prevMaxValue = isLinearAxisData(xyChartData.yAxis) ? xyChartData.yAxis.max : -Infinity;\n xyChartData.yAxis = {\n type: \"linear\",\n title: xyChartData.yAxis.title,\n min: Math.min(prevMinValue, minValue),\n max: Math.max(prevMaxValue, maxValue)\n };\n}\n__name(setYAxisRangeFromPlotData, \"setYAxisRangeFromPlotData\");\nfunction transformDataWithoutCategory(data) {\n let retData = [];\n if (data.length === 0) {\n return retData;\n }\n if (!hasSetXAxis) {\n const prevMinValue = isLinearAxisData(xyChartData.xAxis) ? xyChartData.xAxis.min : Infinity;\n const prevMaxValue = isLinearAxisData(xyChartData.xAxis) ? xyChartData.xAxis.max : -Infinity;\n setXAxisRangeData(Math.min(prevMinValue, 1), Math.max(prevMaxValue, data.length));\n }\n if (!hasSetYAxis) {\n setYAxisRangeFromPlotData(data);\n }\n if (isBandAxisData(xyChartData.xAxis)) {\n retData = xyChartData.xAxis.categories.map((c, i) => [c, data[i]]);\n }\n if (isLinearAxisData(xyChartData.xAxis)) {\n const min = xyChartData.xAxis.min;\n const max = xyChartData.xAxis.max;\n const step = (max - min) / (data.length - 1);\n const categories = [];\n for (let i = min; i <= max; i += step) {\n categories.push(`${i}`);\n }\n retData = categories.map((c, i) => [c, data[i]]);\n }\n return retData;\n}\n__name(transformDataWithoutCategory, \"transformDataWithoutCategory\");\nfunction getPlotColorFromPalette(plotIndex2) {\n return plotColorPalette[plotIndex2 === 0 ? 0 : plotIndex2 % plotColorPalette.length];\n}\n__name(getPlotColorFromPalette, \"getPlotColorFromPalette\");\nfunction setLineData(title, data) {\n const plotData = transformDataWithoutCategory(data);\n xyChartData.plots.push({\n type: \"line\",\n strokeFill: getPlotColorFromPalette(plotIndex),\n strokeWidth: 2,\n data: plotData\n });\n plotIndex++;\n}\n__name(setLineData, \"setLineData\");\nfunction setBarData(title, data) {\n const plotData = transformDataWithoutCategory(data);\n xyChartData.plots.push({\n type: \"bar\",\n fill: getPlotColorFromPalette(plotIndex),\n data: plotData\n });\n plotIndex++;\n}\n__name(setBarData, \"setBarData\");\nfunction getDrawableElem() {\n if (xyChartData.plots.length === 0) {\n throw Error(\"No Plot to render, please provide a plot with some data\");\n }\n xyChartData.title = getDiagramTitle();\n return XYChartBuilder.build(xyChartConfig, xyChartData, xyChartThemeConfig, tmpSVGGroup);\n}\n__name(getDrawableElem, \"getDrawableElem\");\nfunction getChartThemeConfig() {\n return xyChartThemeConfig;\n}\n__name(getChartThemeConfig, \"getChartThemeConfig\");\nfunction getChartConfig() {\n return xyChartConfig;\n}\n__name(getChartConfig, \"getChartConfig\");\nvar clear2 = /* @__PURE__ */ __name(function() {\n clear();\n plotIndex = 0;\n xyChartConfig = getChartDefaultConfig();\n xyChartData = getChartDefaultData();\n xyChartThemeConfig = getChartDefaultThemeConfig();\n plotColorPalette = xyChartThemeConfig.plotColorPalette.split(\",\").map((color) => color.trim());\n hasSetXAxis = false;\n hasSetYAxis = false;\n}, \"clear\");\nvar xychartDb_default = {\n getDrawableElem,\n clear: clear2,\n setAccTitle,\n getAccTitle,\n setDiagramTitle,\n getDiagramTitle,\n getAccDescription,\n setAccDescription,\n setOrientation,\n setXAxisTitle,\n setXAxisRangeData,\n setXAxisBand,\n setYAxisTitle,\n setYAxisRangeData,\n setLineData,\n setBarData,\n setTmpSVGG,\n getChartThemeConfig,\n getChartConfig\n};\n\n// src/diagrams/xychart/xychartRenderer.ts\nvar draw = /* @__PURE__ */ __name((txt, id, _version, diagObj) => {\n const db = diagObj.db;\n const themeConfig = db.getChartThemeConfig();\n const chartConfig = db.getChartConfig();\n function getDominantBaseLine(horizontalPos) {\n return horizontalPos === \"top\" ? \"text-before-edge\" : \"middle\";\n }\n __name(getDominantBaseLine, \"getDominantBaseLine\");\n function getTextAnchor(verticalPos) {\n return verticalPos === \"left\" ? \"start\" : verticalPos === \"right\" ? \"end\" : \"middle\";\n }\n __name(getTextAnchor, \"getTextAnchor\");\n function getTextTransformation(data) {\n return `translate(${data.x}, ${data.y}) rotate(${data.rotation || 0})`;\n }\n __name(getTextTransformation, \"getTextTransformation\");\n log.debug(\"Rendering xychart chart\\n\" + txt);\n const svg = selectSvgElement(id);\n const group = svg.append(\"g\").attr(\"class\", \"main\");\n const background = group.append(\"rect\").attr(\"width\", chartConfig.width).attr(\"height\", chartConfig.height).attr(\"class\", \"background\");\n configureSvgSize(svg, chartConfig.height, chartConfig.width, true);\n svg.attr(\"viewBox\", `0 0 ${chartConfig.width} ${chartConfig.height}`);\n background.attr(\"fill\", themeConfig.backgroundColor);\n db.setTmpSVGG(svg.append(\"g\").attr(\"class\", \"mermaid-tmp-group\"));\n const shapes = db.getDrawableElem();\n const groups = {};\n function getGroup(gList) {\n let elem = group;\n let prefix = \"\";\n for (const [i] of gList.entries()) {\n let parent = group;\n if (i > 0 && groups[prefix]) {\n parent = groups[prefix];\n }\n prefix += gList[i];\n elem = groups[prefix];\n if (!elem) {\n elem = groups[prefix] = parent.append(\"g\").attr(\"class\", gList[i]);\n }\n }\n return elem;\n }\n __name(getGroup, \"getGroup\");\n for (const shape of shapes) {\n if (shape.data.length === 0) {\n continue;\n }\n const shapeGroup = getGroup(shape.groupTexts);\n switch (shape.type) {\n case \"rect\":\n shapeGroup.selectAll(\"rect\").data(shape.data).enter().append(\"rect\").attr(\"x\", (data) => data.x).attr(\"y\", (data) => data.y).attr(\"width\", (data) => data.width).attr(\"height\", (data) => data.height).attr(\"fill\", (data) => data.fill).attr(\"stroke\", (data) => data.strokeFill).attr(\"stroke-width\", (data) => data.strokeWidth);\n break;\n case \"text\":\n shapeGroup.selectAll(\"text\").data(shape.data).enter().append(\"text\").attr(\"x\", 0).attr(\"y\", 0).attr(\"fill\", (data) => data.fill).attr(\"font-size\", (data) => data.fontSize).attr(\"dominant-baseline\", (data) => getDominantBaseLine(data.verticalPos)).attr(\"text-anchor\", (data) => getTextAnchor(data.horizontalPos)).attr(\"transform\", (data) => getTextTransformation(data)).text((data) => data.text);\n break;\n case \"path\":\n shapeGroup.selectAll(\"path\").data(shape.data).enter().append(\"path\").attr(\"d\", (data) => data.path).attr(\"fill\", (data) => data.fill ? data.fill : \"none\").attr(\"stroke\", (data) => data.strokeFill).attr(\"stroke-width\", (data) => data.strokeWidth);\n break;\n }\n }\n}, \"draw\");\nvar xychartRenderer_default = {\n draw\n};\n\n// src/diagrams/xychart/xychartDiagram.ts\nvar diagram = {\n parser: xychart_default,\n db: xychartDb_default,\n renderer: xychartRenderer_default\n};\nexport {\n diagram\n};\n", "import {\n __name,\n clear,\n common_default,\n configureSvgSize,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n log,\n setAccDescription,\n setAccTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/requirement/parser/requirementDiagram.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 3], $V1 = [1, 4], $V2 = [1, 5], $V3 = [1, 6], $V4 = [5, 6, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 62, 63], $V5 = [1, 18], $V6 = [2, 7], $V7 = [1, 22], $V8 = [1, 23], $V9 = [1, 24], $Va = [1, 25], $Vb = [1, 26], $Vc = [1, 27], $Vd = [1, 20], $Ve = [1, 28], $Vf = [1, 29], $Vg = [62, 63], $Vh = [5, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 51, 53, 62, 63], $Vi = [1, 47], $Vj = [1, 48], $Vk = [1, 49], $Vl = [1, 50], $Vm = [1, 51], $Vn = [1, 52], $Vo = [1, 53], $Vp = [53, 54], $Vq = [1, 64], $Vr = [1, 60], $Vs = [1, 61], $Vt = [1, 62], $Vu = [1, 63], $Vv = [1, 65], $Vw = [1, 69], $Vx = [1, 70], $Vy = [1, 67], $Vz = [1, 68], $VA = [5, 8, 9, 11, 13, 31, 32, 33, 34, 35, 36, 44, 62, 63];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"directive\": 4, \"NEWLINE\": 5, \"RD\": 6, \"diagram\": 7, \"EOF\": 8, \"acc_title\": 9, \"acc_title_value\": 10, \"acc_descr\": 11, \"acc_descr_value\": 12, \"acc_descr_multiline_value\": 13, \"requirementDef\": 14, \"elementDef\": 15, \"relationshipDef\": 16, \"requirementType\": 17, \"requirementName\": 18, \"STRUCT_START\": 19, \"requirementBody\": 20, \"ID\": 21, \"COLONSEP\": 22, \"id\": 23, \"TEXT\": 24, \"text\": 25, \"RISK\": 26, \"riskLevel\": 27, \"VERIFYMTHD\": 28, \"verifyType\": 29, \"STRUCT_STOP\": 30, \"REQUIREMENT\": 31, \"FUNCTIONAL_REQUIREMENT\": 32, \"INTERFACE_REQUIREMENT\": 33, \"PERFORMANCE_REQUIREMENT\": 34, \"PHYSICAL_REQUIREMENT\": 35, \"DESIGN_CONSTRAINT\": 36, \"LOW_RISK\": 37, \"MED_RISK\": 38, \"HIGH_RISK\": 39, \"VERIFY_ANALYSIS\": 40, \"VERIFY_DEMONSTRATION\": 41, \"VERIFY_INSPECTION\": 42, \"VERIFY_TEST\": 43, \"ELEMENT\": 44, \"elementName\": 45, \"elementBody\": 46, \"TYPE\": 47, \"type\": 48, \"DOCREF\": 49, \"ref\": 50, \"END_ARROW_L\": 51, \"relationship\": 52, \"LINE\": 53, \"END_ARROW_R\": 54, \"CONTAINS\": 55, \"COPIES\": 56, \"DERIVES\": 57, \"SATISFIES\": 58, \"VERIFIES\": 59, \"REFINES\": 60, \"TRACES\": 61, \"unqString\": 62, \"qString\": 63, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 5: \"NEWLINE\", 6: \"RD\", 8: \"EOF\", 9: \"acc_title\", 10: \"acc_title_value\", 11: \"acc_descr\", 12: \"acc_descr_value\", 13: \"acc_descr_multiline_value\", 19: \"STRUCT_START\", 21: \"ID\", 22: \"COLONSEP\", 24: \"TEXT\", 26: \"RISK\", 28: \"VERIFYMTHD\", 30: \"STRUCT_STOP\", 31: \"REQUIREMENT\", 32: \"FUNCTIONAL_REQUIREMENT\", 33: \"INTERFACE_REQUIREMENT\", 34: \"PERFORMANCE_REQUIREMENT\", 35: \"PHYSICAL_REQUIREMENT\", 36: \"DESIGN_CONSTRAINT\", 37: \"LOW_RISK\", 38: \"MED_RISK\", 39: \"HIGH_RISK\", 40: \"VERIFY_ANALYSIS\", 41: \"VERIFY_DEMONSTRATION\", 42: \"VERIFY_INSPECTION\", 43: \"VERIFY_TEST\", 44: \"ELEMENT\", 47: \"TYPE\", 49: \"DOCREF\", 51: \"END_ARROW_L\", 53: \"LINE\", 54: \"END_ARROW_R\", 55: \"CONTAINS\", 56: \"COPIES\", 57: \"DERIVES\", 58: \"SATISFIES\", 59: \"VERIFIES\", 60: \"REFINES\", 61: \"TRACES\", 62: \"unqString\", 63: \"qString\" },\n productions_: [0, [3, 3], [3, 2], [3, 4], [4, 2], [4, 2], [4, 1], [7, 0], [7, 2], [7, 2], [7, 2], [7, 2], [7, 2], [14, 5], [20, 5], [20, 5], [20, 5], [20, 5], [20, 2], [20, 1], [17, 1], [17, 1], [17, 1], [17, 1], [17, 1], [17, 1], [27, 1], [27, 1], [27, 1], [29, 1], [29, 1], [29, 1], [29, 1], [15, 5], [46, 5], [46, 5], [46, 2], [46, 1], [16, 5], [16, 5], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [52, 1], [18, 1], [18, 1], [23, 1], [23, 1], [25, 1], [25, 1], [45, 1], [45, 1], [48, 1], [48, 1], [50, 1], [50, 1]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 4:\n this.$ = $$[$0].trim();\n yy.setAccTitle(this.$);\n break;\n case 5:\n case 6:\n this.$ = $$[$0].trim();\n yy.setAccDescription(this.$);\n break;\n case 7:\n this.$ = [];\n break;\n case 13:\n yy.addRequirement($$[$0 - 3], $$[$0 - 4]);\n break;\n case 14:\n yy.setNewReqId($$[$0 - 2]);\n break;\n case 15:\n yy.setNewReqText($$[$0 - 2]);\n break;\n case 16:\n yy.setNewReqRisk($$[$0 - 2]);\n break;\n case 17:\n yy.setNewReqVerifyMethod($$[$0 - 2]);\n break;\n case 20:\n this.$ = yy.RequirementType.REQUIREMENT;\n break;\n case 21:\n this.$ = yy.RequirementType.FUNCTIONAL_REQUIREMENT;\n break;\n case 22:\n this.$ = yy.RequirementType.INTERFACE_REQUIREMENT;\n break;\n case 23:\n this.$ = yy.RequirementType.PERFORMANCE_REQUIREMENT;\n break;\n case 24:\n this.$ = yy.RequirementType.PHYSICAL_REQUIREMENT;\n break;\n case 25:\n this.$ = yy.RequirementType.DESIGN_CONSTRAINT;\n break;\n case 26:\n this.$ = yy.RiskLevel.LOW_RISK;\n break;\n case 27:\n this.$ = yy.RiskLevel.MED_RISK;\n break;\n case 28:\n this.$ = yy.RiskLevel.HIGH_RISK;\n break;\n case 29:\n this.$ = yy.VerifyType.VERIFY_ANALYSIS;\n break;\n case 30:\n this.$ = yy.VerifyType.VERIFY_DEMONSTRATION;\n break;\n case 31:\n this.$ = yy.VerifyType.VERIFY_INSPECTION;\n break;\n case 32:\n this.$ = yy.VerifyType.VERIFY_TEST;\n break;\n case 33:\n yy.addElement($$[$0 - 3]);\n break;\n case 34:\n yy.setNewElementType($$[$0 - 2]);\n break;\n case 35:\n yy.setNewElementDocRef($$[$0 - 2]);\n break;\n case 38:\n yy.addRelationship($$[$0 - 2], $$[$0], $$[$0 - 4]);\n break;\n case 39:\n yy.addRelationship($$[$0 - 2], $$[$0 - 4], $$[$0]);\n break;\n case 40:\n this.$ = yy.Relationships.CONTAINS;\n break;\n case 41:\n this.$ = yy.Relationships.COPIES;\n break;\n case 42:\n this.$ = yy.Relationships.DERIVES;\n break;\n case 43:\n this.$ = yy.Relationships.SATISFIES;\n break;\n case 44:\n this.$ = yy.Relationships.VERIFIES;\n break;\n case 45:\n this.$ = yy.Relationships.REFINES;\n break;\n case 46:\n this.$ = yy.Relationships.TRACES;\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: 2, 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 1: [3] }, { 3: 8, 4: 2, 5: [1, 7], 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 5: [1, 9] }, { 10: [1, 10] }, { 12: [1, 11] }, o($V4, [2, 6]), { 3: 12, 4: 2, 6: $V0, 9: $V1, 11: $V2, 13: $V3 }, { 1: [2, 2] }, { 4: 17, 5: $V5, 7: 13, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, o($V4, [2, 4]), o($V4, [2, 5]), { 1: [2, 1] }, { 8: [1, 30] }, { 4: 17, 5: $V5, 7: 31, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 32, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 33, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 34, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 4: 17, 5: $V5, 7: 35, 8: $V6, 9: $V1, 11: $V2, 13: $V3, 14: 14, 15: 15, 16: 16, 17: 19, 23: 21, 31: $V7, 32: $V8, 33: $V9, 34: $Va, 35: $Vb, 36: $Vc, 44: $Vd, 62: $Ve, 63: $Vf }, { 18: 36, 62: [1, 37], 63: [1, 38] }, { 45: 39, 62: [1, 40], 63: [1, 41] }, { 51: [1, 42], 53: [1, 43] }, o($Vg, [2, 20]), o($Vg, [2, 21]), o($Vg, [2, 22]), o($Vg, [2, 23]), o($Vg, [2, 24]), o($Vg, [2, 25]), o($Vh, [2, 49]), o($Vh, [2, 50]), { 1: [2, 3] }, { 8: [2, 8] }, { 8: [2, 9] }, { 8: [2, 10] }, { 8: [2, 11] }, { 8: [2, 12] }, { 19: [1, 44] }, { 19: [2, 47] }, { 19: [2, 48] }, { 19: [1, 45] }, { 19: [2, 53] }, { 19: [2, 54] }, { 52: 46, 55: $Vi, 56: $Vj, 57: $Vk, 58: $Vl, 59: $Vm, 60: $Vn, 61: $Vo }, { 52: 54, 55: $Vi, 56: $Vj, 57: $Vk, 58: $Vl, 59: $Vm, 60: $Vn, 61: $Vo }, { 5: [1, 55] }, { 5: [1, 56] }, { 53: [1, 57] }, o($Vp, [2, 40]), o($Vp, [2, 41]), o($Vp, [2, 42]), o($Vp, [2, 43]), o($Vp, [2, 44]), o($Vp, [2, 45]), o($Vp, [2, 46]), { 54: [1, 58] }, { 5: $Vq, 20: 59, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vw, 30: $Vx, 46: 66, 47: $Vy, 49: $Vz }, { 23: 71, 62: $Ve, 63: $Vf }, { 23: 72, 62: $Ve, 63: $Vf }, o($VA, [2, 13]), { 22: [1, 73] }, { 22: [1, 74] }, { 22: [1, 75] }, { 22: [1, 76] }, { 5: $Vq, 20: 77, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, o($VA, [2, 19]), o($VA, [2, 33]), { 22: [1, 78] }, { 22: [1, 79] }, { 5: $Vw, 30: $Vx, 46: 80, 47: $Vy, 49: $Vz }, o($VA, [2, 37]), o($VA, [2, 38]), o($VA, [2, 39]), { 23: 81, 62: $Ve, 63: $Vf }, { 25: 82, 62: [1, 83], 63: [1, 84] }, { 27: 85, 37: [1, 86], 38: [1, 87], 39: [1, 88] }, { 29: 89, 40: [1, 90], 41: [1, 91], 42: [1, 92], 43: [1, 93] }, o($VA, [2, 18]), { 48: 94, 62: [1, 95], 63: [1, 96] }, { 50: 97, 62: [1, 98], 63: [1, 99] }, o($VA, [2, 36]), { 5: [1, 100] }, { 5: [1, 101] }, { 5: [2, 51] }, { 5: [2, 52] }, { 5: [1, 102] }, { 5: [2, 26] }, { 5: [2, 27] }, { 5: [2, 28] }, { 5: [1, 103] }, { 5: [2, 29] }, { 5: [2, 30] }, { 5: [2, 31] }, { 5: [2, 32] }, { 5: [1, 104] }, { 5: [2, 55] }, { 5: [2, 56] }, { 5: [1, 105] }, { 5: [2, 57] }, { 5: [2, 58] }, { 5: $Vq, 20: 106, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 107, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 108, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vq, 20: 109, 21: $Vr, 24: $Vs, 26: $Vt, 28: $Vu, 30: $Vv }, { 5: $Vw, 30: $Vx, 46: 110, 47: $Vy, 49: $Vz }, { 5: $Vw, 30: $Vx, 46: 111, 47: $Vy, 49: $Vz }, o($VA, [2, 14]), o($VA, [2, 15]), o($VA, [2, 16]), o($VA, [2, 17]), o($VA, [2, 34]), o($VA, [2, 35])],\n defaultActions: { 8: [2, 2], 12: [2, 1], 30: [2, 3], 31: [2, 8], 32: [2, 9], 33: [2, 10], 34: [2, 11], 35: [2, 12], 37: [2, 47], 38: [2, 48], 40: [2, 53], 41: [2, 54], 83: [2, 51], 84: [2, 52], 86: [2, 26], 87: [2, 27], 88: [2, 28], 90: [2, 29], 91: [2, 30], 92: [2, 31], 93: [2, 32], 95: [2, 55], 96: [2, 56], 98: [2, 57], 99: [2, 58] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n return \"title\";\n break;\n case 1:\n this.begin(\"acc_title\");\n return 9;\n break;\n case 2:\n this.popState();\n return \"acc_title_value\";\n break;\n case 3:\n this.begin(\"acc_descr\");\n return 11;\n break;\n case 4:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 5:\n this.begin(\"acc_descr_multiline\");\n break;\n case 6:\n this.popState();\n break;\n case 7:\n return \"acc_descr_multiline_value\";\n break;\n case 8:\n return 5;\n break;\n case 9:\n break;\n case 10:\n break;\n case 11:\n break;\n case 12:\n return 8;\n break;\n case 13:\n return 6;\n break;\n case 14:\n return 19;\n break;\n case 15:\n return 30;\n break;\n case 16:\n return 22;\n break;\n case 17:\n return 21;\n break;\n case 18:\n return 24;\n break;\n case 19:\n return 26;\n break;\n case 20:\n return 28;\n break;\n case 21:\n return 31;\n break;\n case 22:\n return 32;\n break;\n case 23:\n return 33;\n break;\n case 24:\n return 34;\n break;\n case 25:\n return 35;\n break;\n case 26:\n return 36;\n break;\n case 27:\n return 37;\n break;\n case 28:\n return 38;\n break;\n case 29:\n return 39;\n break;\n case 30:\n return 40;\n break;\n case 31:\n return 41;\n break;\n case 32:\n return 42;\n break;\n case 33:\n return 43;\n break;\n case 34:\n return 44;\n break;\n case 35:\n return 55;\n break;\n case 36:\n return 56;\n break;\n case 37:\n return 57;\n break;\n case 38:\n return 58;\n break;\n case 39:\n return 59;\n break;\n case 40:\n return 60;\n break;\n case 41:\n return 61;\n break;\n case 42:\n return 47;\n break;\n case 43:\n return 49;\n break;\n case 44:\n return 51;\n break;\n case 45:\n return 54;\n break;\n case 46:\n return 53;\n break;\n case 47:\n this.begin(\"string\");\n break;\n case 48:\n this.popState();\n break;\n case 49:\n return \"qString\";\n break;\n case 50:\n yy_.yytext = yy_.yytext.trim();\n return 62;\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:title\\s[^#\\n;]+)/i, /^(?:accTitle\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*\\{\\s*)/i, /^(?:[\\}])/i, /^(?:[^\\}]*)/i, /^(?:(\\r?\\n)+)/i, /^(?:\\s+)/i, /^(?:#[^\\n]*)/i, /^(?:%[^\\n]*)/i, /^(?:$)/i, /^(?:requirementDiagram\\b)/i, /^(?:\\{)/i, /^(?:\\})/i, /^(?::)/i, /^(?:id\\b)/i, /^(?:text\\b)/i, /^(?:risk\\b)/i, /^(?:verifyMethod\\b)/i, /^(?:requirement\\b)/i, /^(?:functionalRequirement\\b)/i, /^(?:interfaceRequirement\\b)/i, /^(?:performanceRequirement\\b)/i, /^(?:physicalRequirement\\b)/i, /^(?:designConstraint\\b)/i, /^(?:low\\b)/i, /^(?:medium\\b)/i, /^(?:high\\b)/i, /^(?:analysis\\b)/i, /^(?:demonstration\\b)/i, /^(?:inspection\\b)/i, /^(?:test\\b)/i, /^(?:element\\b)/i, /^(?:contains\\b)/i, /^(?:copies\\b)/i, /^(?:derives\\b)/i, /^(?:satisfies\\b)/i, /^(?:verifies\\b)/i, /^(?:refines\\b)/i, /^(?:traces\\b)/i, /^(?:type\\b)/i, /^(?:docref\\b)/i, /^(?:<-)/i, /^(?:->)/i, /^(?:-)/i, /^(?:[\"])/i, /^(?:[\"])/i, /^(?:[^\"]*)/i, /^(?:[\\w][^\\r\\n\\{\\<\\>\\-\\=]*)/i],\n conditions: { \"acc_descr_multiline\": { \"rules\": [6, 7], \"inclusive\": false }, \"acc_descr\": { \"rules\": [4], \"inclusive\": false }, \"acc_title\": { \"rules\": [2], \"inclusive\": false }, \"unqString\": { \"rules\": [], \"inclusive\": false }, \"token\": { \"rules\": [], \"inclusive\": false }, \"string\": { \"rules\": [48, 49], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 3, 5, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 50], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar requirementDiagram_default = parser;\n\n// src/diagrams/requirement/requirementDb.js\nvar relations = [];\nvar latestRequirement = {};\nvar requirements = /* @__PURE__ */ new Map();\nvar latestElement = {};\nvar elements = /* @__PURE__ */ new Map();\nvar RequirementType = {\n REQUIREMENT: \"Requirement\",\n FUNCTIONAL_REQUIREMENT: \"Functional Requirement\",\n INTERFACE_REQUIREMENT: \"Interface Requirement\",\n PERFORMANCE_REQUIREMENT: \"Performance Requirement\",\n PHYSICAL_REQUIREMENT: \"Physical Requirement\",\n DESIGN_CONSTRAINT: \"Design Constraint\"\n};\nvar RiskLevel = {\n LOW_RISK: \"Low\",\n MED_RISK: \"Medium\",\n HIGH_RISK: \"High\"\n};\nvar VerifyType = {\n VERIFY_ANALYSIS: \"Analysis\",\n VERIFY_DEMONSTRATION: \"Demonstration\",\n VERIFY_INSPECTION: \"Inspection\",\n VERIFY_TEST: \"Test\"\n};\nvar Relationships = {\n CONTAINS: \"contains\",\n COPIES: \"copies\",\n DERIVES: \"derives\",\n SATISFIES: \"satisfies\",\n VERIFIES: \"verifies\",\n REFINES: \"refines\",\n TRACES: \"traces\"\n};\nvar addRequirement = /* @__PURE__ */ __name((name, type) => {\n if (!requirements.has(name)) {\n requirements.set(name, {\n name,\n type,\n id: latestRequirement.id,\n text: latestRequirement.text,\n risk: latestRequirement.risk,\n verifyMethod: latestRequirement.verifyMethod\n });\n }\n latestRequirement = {};\n return requirements.get(name);\n}, \"addRequirement\");\nvar getRequirements = /* @__PURE__ */ __name(() => requirements, \"getRequirements\");\nvar setNewReqId = /* @__PURE__ */ __name((id) => {\n if (latestRequirement !== void 0) {\n latestRequirement.id = id;\n }\n}, \"setNewReqId\");\nvar setNewReqText = /* @__PURE__ */ __name((text) => {\n if (latestRequirement !== void 0) {\n latestRequirement.text = text;\n }\n}, \"setNewReqText\");\nvar setNewReqRisk = /* @__PURE__ */ __name((risk) => {\n if (latestRequirement !== void 0) {\n latestRequirement.risk = risk;\n }\n}, \"setNewReqRisk\");\nvar setNewReqVerifyMethod = /* @__PURE__ */ __name((verifyMethod) => {\n if (latestRequirement !== void 0) {\n latestRequirement.verifyMethod = verifyMethod;\n }\n}, \"setNewReqVerifyMethod\");\nvar addElement = /* @__PURE__ */ __name((name) => {\n if (!elements.has(name)) {\n elements.set(name, {\n name,\n type: latestElement.type,\n docRef: latestElement.docRef\n });\n log.info(\"Added new requirement: \", name);\n }\n latestElement = {};\n return elements.get(name);\n}, \"addElement\");\nvar getElements = /* @__PURE__ */ __name(() => elements, \"getElements\");\nvar setNewElementType = /* @__PURE__ */ __name((type) => {\n if (latestElement !== void 0) {\n latestElement.type = type;\n }\n}, \"setNewElementType\");\nvar setNewElementDocRef = /* @__PURE__ */ __name((docRef) => {\n if (latestElement !== void 0) {\n latestElement.docRef = docRef;\n }\n}, \"setNewElementDocRef\");\nvar addRelationship = /* @__PURE__ */ __name((type, src, dst) => {\n relations.push({\n type,\n src,\n dst\n });\n}, \"addRelationship\");\nvar getRelationships = /* @__PURE__ */ __name(() => relations, \"getRelationships\");\nvar clear2 = /* @__PURE__ */ __name(() => {\n relations = [];\n latestRequirement = {};\n requirements = /* @__PURE__ */ new Map();\n latestElement = {};\n elements = /* @__PURE__ */ new Map();\n clear();\n}, \"clear\");\nvar requirementDb_default = {\n RequirementType,\n RiskLevel,\n VerifyType,\n Relationships,\n getConfig: /* @__PURE__ */ __name(() => getConfig().req, \"getConfig\"),\n addRequirement,\n getRequirements,\n setNewReqId,\n setNewReqText,\n setNewReqRisk,\n setNewReqVerifyMethod,\n setAccTitle,\n getAccTitle,\n setAccDescription,\n getAccDescription,\n addElement,\n getElements,\n setNewElementType,\n setNewElementDocRef,\n addRelationship,\n getRelationships,\n clear: clear2\n};\n\n// src/diagrams/requirement/styles.js\nvar getStyles = /* @__PURE__ */ __name((options) => `\n\n marker {\n fill: ${options.relationColor};\n stroke: ${options.relationColor};\n }\n\n marker.cross {\n stroke: ${options.lineColor};\n }\n\n svg {\n font-family: ${options.fontFamily};\n font-size: ${options.fontSize};\n }\n\n .reqBox {\n fill: ${options.requirementBackground};\n fill-opacity: 1.0;\n stroke: ${options.requirementBorderColor};\n stroke-width: ${options.requirementBorderSize};\n }\n \n .reqTitle, .reqLabel{\n fill: ${options.requirementTextColor};\n }\n .reqLabelBox {\n fill: ${options.relationLabelBackground};\n fill-opacity: 1.0;\n }\n\n .req-title-line {\n stroke: ${options.requirementBorderColor};\n stroke-width: ${options.requirementBorderSize};\n }\n .relationshipLine {\n stroke: ${options.relationColor};\n stroke-width: 1;\n }\n .relationshipLabel {\n fill: ${options.relationLabelColor};\n }\n\n`, \"getStyles\");\nvar styles_default = getStyles;\n\n// src/diagrams/requirement/requirementRenderer.js\nimport { line, select } from \"d3\";\nimport { layout as dagreLayout } from \"dagre-d3-es/src/dagre/index.js\";\nimport * as graphlib from \"dagre-d3-es/src/graphlib/index.js\";\n\n// src/diagrams/requirement/requirementMarkers.js\nvar ReqMarkers = {\n CONTAINS: \"contains\",\n ARROW: \"arrow\"\n};\nvar insertLineEndings = /* @__PURE__ */ __name((parentNode, conf2) => {\n let containsNode = parentNode.append(\"defs\").append(\"marker\").attr(\"id\", ReqMarkers.CONTAINS + \"_line_ending\").attr(\"refX\", 0).attr(\"refY\", conf2.line_height / 2).attr(\"markerWidth\", conf2.line_height).attr(\"markerHeight\", conf2.line_height).attr(\"orient\", \"auto\").append(\"g\");\n containsNode.append(\"circle\").attr(\"cx\", conf2.line_height / 2).attr(\"cy\", conf2.line_height / 2).attr(\"r\", conf2.line_height / 2).attr(\"fill\", \"none\");\n containsNode.append(\"line\").attr(\"x1\", 0).attr(\"x2\", conf2.line_height).attr(\"y1\", conf2.line_height / 2).attr(\"y2\", conf2.line_height / 2).attr(\"stroke-width\", 1);\n containsNode.append(\"line\").attr(\"y1\", 0).attr(\"y2\", conf2.line_height).attr(\"x1\", conf2.line_height / 2).attr(\"x2\", conf2.line_height / 2).attr(\"stroke-width\", 1);\n parentNode.append(\"defs\").append(\"marker\").attr(\"id\", ReqMarkers.ARROW + \"_line_ending\").attr(\"refX\", conf2.line_height).attr(\"refY\", 0.5 * conf2.line_height).attr(\"markerWidth\", conf2.line_height).attr(\"markerHeight\", conf2.line_height).attr(\"orient\", \"auto\").append(\"path\").attr(\n \"d\",\n `M0,0\n L${conf2.line_height},${conf2.line_height / 2}\n M${conf2.line_height},${conf2.line_height / 2}\n L0,${conf2.line_height}`\n ).attr(\"stroke-width\", 1);\n}, \"insertLineEndings\");\nvar requirementMarkers_default = {\n ReqMarkers,\n insertLineEndings\n};\n\n// src/diagrams/requirement/requirementRenderer.js\nvar conf = {};\nvar relCnt = 0;\nvar newRectNode = /* @__PURE__ */ __name((parentNode, id) => {\n return parentNode.insert(\"rect\", \"#\" + id).attr(\"class\", \"req reqBox\").attr(\"x\", 0).attr(\"y\", 0).attr(\"width\", conf.rect_min_width + \"px\").attr(\"height\", conf.rect_min_height + \"px\");\n}, \"newRectNode\");\nvar newTitleNode = /* @__PURE__ */ __name((parentNode, id, txts) => {\n let x = conf.rect_min_width / 2;\n let title = parentNode.append(\"text\").attr(\"class\", \"req reqLabel reqTitle\").attr(\"id\", id).attr(\"x\", x).attr(\"y\", conf.rect_padding).attr(\"dominant-baseline\", \"hanging\");\n let i = 0;\n txts.forEach((textStr) => {\n if (i == 0) {\n title.append(\"tspan\").attr(\"text-anchor\", \"middle\").attr(\"x\", conf.rect_min_width / 2).attr(\"dy\", 0).text(textStr);\n } else {\n title.append(\"tspan\").attr(\"text-anchor\", \"middle\").attr(\"x\", conf.rect_min_width / 2).attr(\"dy\", conf.line_height * 0.75).text(textStr);\n }\n i++;\n });\n let yPadding = 1.5 * conf.rect_padding;\n let linePadding = i * conf.line_height * 0.75;\n let totalY = yPadding + linePadding;\n parentNode.append(\"line\").attr(\"class\", \"req-title-line\").attr(\"x1\", \"0\").attr(\"x2\", conf.rect_min_width).attr(\"y1\", totalY).attr(\"y2\", totalY);\n return {\n titleNode: title,\n y: totalY\n };\n}, \"newTitleNode\");\nvar newBodyNode = /* @__PURE__ */ __name((parentNode, id, txts, yStart) => {\n let body = parentNode.append(\"text\").attr(\"class\", \"req reqLabel\").attr(\"id\", id).attr(\"x\", conf.rect_padding).attr(\"y\", yStart).attr(\"dominant-baseline\", \"hanging\");\n let currentRow = 0;\n const charLimit = 30;\n let wrappedTxts = [];\n txts.forEach((textStr) => {\n let currentTextLen = textStr.length;\n while (currentTextLen > charLimit && currentRow < 3) {\n let firstPart = textStr.substring(0, charLimit);\n textStr = textStr.substring(charLimit, textStr.length);\n currentTextLen = textStr.length;\n wrappedTxts[wrappedTxts.length] = firstPart;\n currentRow++;\n }\n if (currentRow == 3) {\n let lastStr = wrappedTxts[wrappedTxts.length - 1];\n wrappedTxts[wrappedTxts.length - 1] = lastStr.substring(0, lastStr.length - 4) + \"...\";\n } else {\n wrappedTxts[wrappedTxts.length] = textStr;\n }\n currentRow = 0;\n });\n wrappedTxts.forEach((textStr) => {\n body.append(\"tspan\").attr(\"x\", conf.rect_padding).attr(\"dy\", conf.line_height).text(textStr);\n });\n return body;\n}, \"newBodyNode\");\nvar addEdgeLabel = /* @__PURE__ */ __name((parentNode, svgPath, conf2, txt) => {\n const len = svgPath.node().getTotalLength();\n const labelPoint = svgPath.node().getPointAtLength(len * 0.5);\n const labelId = \"rel\" + relCnt;\n relCnt++;\n const labelNode = parentNode.append(\"text\").attr(\"class\", \"req relationshipLabel\").attr(\"id\", labelId).attr(\"x\", labelPoint.x).attr(\"y\", labelPoint.y).attr(\"text-anchor\", \"middle\").attr(\"dominant-baseline\", \"middle\").text(txt);\n const labelBBox = labelNode.node().getBBox();\n parentNode.insert(\"rect\", \"#\" + labelId).attr(\"class\", \"req reqLabelBox\").attr(\"x\", labelPoint.x - labelBBox.width / 2).attr(\"y\", labelPoint.y - labelBBox.height / 2).attr(\"width\", labelBBox.width).attr(\"height\", labelBBox.height).attr(\"fill\", \"white\").attr(\"fill-opacity\", \"85%\");\n}, \"addEdgeLabel\");\nvar drawRelationshipFromLayout = /* @__PURE__ */ __name(function(svg, rel, g, insert, diagObj) {\n const edge = g.edge(elementString(rel.src), elementString(rel.dst));\n const lineFunction = line().x(function(d) {\n return d.x;\n }).y(function(d) {\n return d.y;\n });\n const svgPath = svg.insert(\"path\", \"#\" + insert).attr(\"class\", \"er relationshipLine\").attr(\"d\", lineFunction(edge.points)).attr(\"fill\", \"none\");\n if (rel.type == diagObj.db.Relationships.CONTAINS) {\n svgPath.attr(\n \"marker-start\",\n \"url(\" + common_default.getUrl(conf.arrowMarkerAbsolute) + \"#\" + rel.type + \"_line_ending)\"\n );\n } else {\n svgPath.attr(\"stroke-dasharray\", \"10,7\");\n svgPath.attr(\n \"marker-end\",\n \"url(\" + common_default.getUrl(conf.arrowMarkerAbsolute) + \"#\" + requirementMarkers_default.ReqMarkers.ARROW + \"_line_ending)\"\n );\n }\n addEdgeLabel(svg, svgPath, conf, `<<${rel.type}>>`);\n return;\n}, \"drawRelationshipFromLayout\");\nvar drawReqs = /* @__PURE__ */ __name((reqs, graph, svgNode) => {\n reqs.forEach((req, reqName) => {\n reqName = elementString(reqName);\n log.info(\"Added new requirement: \", reqName);\n const groupNode = svgNode.append(\"g\").attr(\"id\", reqName);\n const textId = \"req-\" + reqName;\n const rectNode = newRectNode(groupNode, textId);\n let nodes = [];\n let titleNodeInfo = newTitleNode(groupNode, reqName + \"_title\", [\n `<<${req.type}>>`,\n `${req.name}`\n ]);\n nodes.push(titleNodeInfo.titleNode);\n let bodyNode = newBodyNode(\n groupNode,\n reqName + \"_body\",\n [\n `Id: ${req.id}`,\n `Text: ${req.text}`,\n `Risk: ${req.risk}`,\n `Verification: ${req.verifyMethod}`\n ],\n titleNodeInfo.y\n );\n nodes.push(bodyNode);\n const rectBBox = rectNode.node().getBBox();\n graph.setNode(reqName, {\n width: rectBBox.width,\n height: rectBBox.height,\n shape: \"rect\",\n id: reqName\n });\n });\n}, \"drawReqs\");\nvar drawElements = /* @__PURE__ */ __name((els, graph, svgNode) => {\n els.forEach((el, elName) => {\n const id = elementString(elName);\n const groupNode = svgNode.append(\"g\").attr(\"id\", id);\n const textId = \"element-\" + id;\n const rectNode = newRectNode(groupNode, textId);\n let nodes = [];\n let titleNodeInfo = newTitleNode(groupNode, textId + \"_title\", [`<>`, `${elName}`]);\n nodes.push(titleNodeInfo.titleNode);\n let bodyNode = newBodyNode(\n groupNode,\n textId + \"_body\",\n [`Type: ${el.type || \"Not Specified\"}`, `Doc Ref: ${el.docRef || \"None\"}`],\n titleNodeInfo.y\n );\n nodes.push(bodyNode);\n const rectBBox = rectNode.node().getBBox();\n graph.setNode(id, {\n width: rectBBox.width,\n height: rectBBox.height,\n shape: \"rect\",\n id\n });\n });\n}, \"drawElements\");\nvar addRelationships = /* @__PURE__ */ __name((relationships, g) => {\n relationships.forEach(function(r) {\n let src = elementString(r.src);\n let dst = elementString(r.dst);\n g.setEdge(src, dst, { relationship: r });\n });\n return relationships;\n}, \"addRelationships\");\nvar adjustEntities = /* @__PURE__ */ __name(function(svgNode, graph) {\n graph.nodes().forEach(function(v) {\n if (v !== void 0 && graph.node(v) !== void 0) {\n svgNode.select(\"#\" + v);\n svgNode.select(\"#\" + v).attr(\n \"transform\",\n \"translate(\" + (graph.node(v).x - graph.node(v).width / 2) + \",\" + (graph.node(v).y - graph.node(v).height / 2) + \" )\"\n );\n }\n });\n return;\n}, \"adjustEntities\");\nvar elementString = /* @__PURE__ */ __name((str) => {\n return str.replace(/\\s/g, \"\").replace(/\\./g, \"_\");\n}, \"elementString\");\nvar draw = /* @__PURE__ */ __name((text, id, _version, diagObj) => {\n conf = getConfig().requirement;\n const securityLevel = conf.securityLevel;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select(sandboxElement.nodes()[0].contentDocument.body) : select(\"body\");\n const svg = root.select(`[id='${id}']`);\n requirementMarkers_default.insertLineEndings(svg, conf);\n const g = new graphlib.Graph({\n multigraph: false,\n compound: false,\n directed: true\n }).setGraph({\n rankdir: conf.layoutDirection,\n marginx: 20,\n marginy: 20,\n nodesep: 100,\n edgesep: 100,\n ranksep: 100\n }).setDefaultEdgeLabel(function() {\n return {};\n });\n let requirements2 = diagObj.db.getRequirements();\n let elements2 = diagObj.db.getElements();\n let relationships = diagObj.db.getRelationships();\n drawReqs(requirements2, g, svg);\n drawElements(elements2, g, svg);\n addRelationships(relationships, g);\n dagreLayout(g);\n adjustEntities(svg, g);\n relationships.forEach(function(rel) {\n drawRelationshipFromLayout(svg, rel, g, id, diagObj);\n });\n const padding = conf.rect_padding;\n const svgBounds = svg.node().getBBox();\n const width = svgBounds.width + padding * 2;\n const height = svgBounds.height + padding * 2;\n configureSvgSize(svg, height, width, conf.useMaxWidth);\n svg.attr(\"viewBox\", `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`);\n}, \"draw\");\nvar requirementRenderer_default = {\n draw\n};\n\n// src/diagrams/requirement/requirementDiagram.ts\nvar diagram = {\n parser: requirementDiagram_default,\n db: requirementDb_default,\n renderer: requirementRenderer_default,\n styles: styles_default\n};\nexport {\n diagram\n};\n", "import {\n drawBackgroundRect,\n drawEmbeddedImage,\n drawImage,\n drawRect,\n getNoteRect,\n getTextObj\n} from \"./chunk-XVOYOM2C.mjs\";\nimport {\n ImperativeState\n} from \"./chunk-2RYQ3QTB.mjs\";\nimport {\n ZERO_WIDTH_SPACE,\n parseFontSize,\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n assignWithDepth_default,\n calculateMathMLDimensions,\n clear,\n common_default,\n configureSvgSize,\n getAccDescription,\n getAccTitle,\n getConfig,\n getConfig2,\n getDiagramTitle,\n hasKatex,\n log,\n renderKatex,\n sanitizeText,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/sequence/parser/sequenceDiagram.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 2], $V1 = [1, 3], $V2 = [1, 4], $V3 = [2, 4], $V4 = [1, 9], $V5 = [1, 11], $V6 = [1, 13], $V7 = [1, 14], $V8 = [1, 16], $V9 = [1, 17], $Va = [1, 18], $Vb = [1, 24], $Vc = [1, 25], $Vd = [1, 26], $Ve = [1, 27], $Vf = [1, 28], $Vg = [1, 29], $Vh = [1, 30], $Vi = [1, 31], $Vj = [1, 32], $Vk = [1, 33], $Vl = [1, 34], $Vm = [1, 35], $Vn = [1, 36], $Vo = [1, 37], $Vp = [1, 38], $Vq = [1, 39], $Vr = [1, 41], $Vs = [1, 42], $Vt = [1, 43], $Vu = [1, 44], $Vv = [1, 45], $Vw = [1, 46], $Vx = [1, 4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 47, 48, 49, 50, 52, 53, 54, 59, 60, 61, 62, 70], $Vy = [4, 5, 16, 50, 52, 53], $Vz = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VA = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 49, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VB = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 48, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VC = [4, 5, 13, 14, 16, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 47, 50, 52, 53, 54, 59, 60, 61, 62, 70], $VD = [68, 69, 70], $VE = [1, 122];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"SPACE\": 4, \"NEWLINE\": 5, \"SD\": 6, \"document\": 7, \"line\": 8, \"statement\": 9, \"box_section\": 10, \"box_line\": 11, \"participant_statement\": 12, \"create\": 13, \"box\": 14, \"restOfLine\": 15, \"end\": 16, \"signal\": 17, \"autonumber\": 18, \"NUM\": 19, \"off\": 20, \"activate\": 21, \"actor\": 22, \"deactivate\": 23, \"note_statement\": 24, \"links_statement\": 25, \"link_statement\": 26, \"properties_statement\": 27, \"details_statement\": 28, \"title\": 29, \"legacy_title\": 30, \"acc_title\": 31, \"acc_title_value\": 32, \"acc_descr\": 33, \"acc_descr_value\": 34, \"acc_descr_multiline_value\": 35, \"loop\": 36, \"rect\": 37, \"opt\": 38, \"alt\": 39, \"else_sections\": 40, \"par\": 41, \"par_sections\": 42, \"par_over\": 43, \"critical\": 44, \"option_sections\": 45, \"break\": 46, \"option\": 47, \"and\": 48, \"else\": 49, \"participant\": 50, \"AS\": 51, \"participant_actor\": 52, \"destroy\": 53, \"note\": 54, \"placement\": 55, \"text2\": 56, \"over\": 57, \"actor_pair\": 58, \"links\": 59, \"link\": 60, \"properties\": 61, \"details\": 62, \"spaceList\": 63, \",\": 64, \"left_of\": 65, \"right_of\": 66, \"signaltype\": 67, \"+\": 68, \"-\": 69, \"ACTOR\": 70, \"SOLID_OPEN_ARROW\": 71, \"DOTTED_OPEN_ARROW\": 72, \"SOLID_ARROW\": 73, \"BIDIRECTIONAL_SOLID_ARROW\": 74, \"DOTTED_ARROW\": 75, \"BIDIRECTIONAL_DOTTED_ARROW\": 76, \"SOLID_CROSS\": 77, \"DOTTED_CROSS\": 78, \"SOLID_POINT\": 79, \"DOTTED_POINT\": 80, \"TXT\": 81, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 4: \"SPACE\", 5: \"NEWLINE\", 6: \"SD\", 13: \"create\", 14: \"box\", 15: \"restOfLine\", 16: \"end\", 18: \"autonumber\", 19: \"NUM\", 20: \"off\", 21: \"activate\", 23: \"deactivate\", 29: \"title\", 30: \"legacy_title\", 31: \"acc_title\", 32: \"acc_title_value\", 33: \"acc_descr\", 34: \"acc_descr_value\", 35: \"acc_descr_multiline_value\", 36: \"loop\", 37: \"rect\", 38: \"opt\", 39: \"alt\", 41: \"par\", 43: \"par_over\", 44: \"critical\", 46: \"break\", 47: \"option\", 48: \"and\", 49: \"else\", 50: \"participant\", 51: \"AS\", 52: \"participant_actor\", 53: \"destroy\", 54: \"note\", 57: \"over\", 59: \"links\", 60: \"link\", 61: \"properties\", 62: \"details\", 64: \",\", 65: \"left_of\", 66: \"right_of\", 68: \"+\", 69: \"-\", 70: \"ACTOR\", 71: \"SOLID_OPEN_ARROW\", 72: \"DOTTED_OPEN_ARROW\", 73: \"SOLID_ARROW\", 74: \"BIDIRECTIONAL_SOLID_ARROW\", 75: \"DOTTED_ARROW\", 76: \"BIDIRECTIONAL_DOTTED_ARROW\", 77: \"SOLID_CROSS\", 78: \"DOTTED_CROSS\", 79: \"SOLID_POINT\", 80: \"DOTTED_POINT\", 81: \"TXT\" },\n productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [8, 1], [8, 1], [10, 0], [10, 2], [11, 2], [11, 1], [11, 1], [9, 1], [9, 2], [9, 4], [9, 2], [9, 4], [9, 3], [9, 3], [9, 2], [9, 3], [9, 3], [9, 2], [9, 2], [9, 2], [9, 2], [9, 2], [9, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [9, 4], [45, 1], [45, 4], [42, 1], [42, 4], [40, 1], [40, 4], [12, 5], [12, 3], [12, 5], [12, 3], [12, 3], [24, 4], [24, 4], [25, 3], [26, 3], [27, 3], [28, 3], [63, 2], [63, 1], [58, 3], [58, 1], [55, 1], [55, 1], [17, 5], [17, 5], [17, 4], [22, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [67, 1], [56, 1]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 3:\n yy.apply($$[$0]);\n return $$[$0];\n break;\n case 4:\n case 9:\n this.$ = [];\n break;\n case 5:\n case 10:\n $$[$0 - 1].push($$[$0]);\n this.$ = $$[$0 - 1];\n break;\n case 6:\n case 7:\n case 11:\n case 12:\n this.$ = $$[$0];\n break;\n case 8:\n case 13:\n this.$ = [];\n break;\n case 15:\n $$[$0].type = \"createParticipant\";\n this.$ = $$[$0];\n break;\n case 16:\n $$[$0 - 1].unshift({ type: \"boxStart\", boxData: yy.parseBoxData($$[$0 - 2]) });\n $$[$0 - 1].push({ type: \"boxEnd\", boxText: $$[$0 - 2] });\n this.$ = $$[$0 - 1];\n break;\n case 18:\n this.$ = { type: \"sequenceIndex\", sequenceIndex: Number($$[$0 - 2]), sequenceIndexStep: Number($$[$0 - 1]), sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER };\n break;\n case 19:\n this.$ = { type: \"sequenceIndex\", sequenceIndex: Number($$[$0 - 1]), sequenceIndexStep: 1, sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER };\n break;\n case 20:\n this.$ = { type: \"sequenceIndex\", sequenceVisible: false, signalType: yy.LINETYPE.AUTONUMBER };\n break;\n case 21:\n this.$ = { type: \"sequenceIndex\", sequenceVisible: true, signalType: yy.LINETYPE.AUTONUMBER };\n break;\n case 22:\n this.$ = { type: \"activeStart\", signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0 - 1].actor };\n break;\n case 23:\n this.$ = { type: \"activeEnd\", signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0 - 1].actor };\n break;\n case 29:\n yy.setDiagramTitle($$[$0].substring(6));\n this.$ = $$[$0].substring(6);\n break;\n case 30:\n yy.setDiagramTitle($$[$0].substring(7));\n this.$ = $$[$0].substring(7);\n break;\n case 31:\n this.$ = $$[$0].trim();\n yy.setAccTitle(this.$);\n break;\n case 32:\n case 33:\n this.$ = $$[$0].trim();\n yy.setAccDescription(this.$);\n break;\n case 34:\n $$[$0 - 1].unshift({ type: \"loopStart\", loopText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.LOOP_START });\n $$[$0 - 1].push({ type: \"loopEnd\", loopText: $$[$0 - 2], signalType: yy.LINETYPE.LOOP_END });\n this.$ = $$[$0 - 1];\n break;\n case 35:\n $$[$0 - 1].unshift({ type: \"rectStart\", color: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.RECT_START });\n $$[$0 - 1].push({ type: \"rectEnd\", color: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.RECT_END });\n this.$ = $$[$0 - 1];\n break;\n case 36:\n $$[$0 - 1].unshift({ type: \"optStart\", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.OPT_START });\n $$[$0 - 1].push({ type: \"optEnd\", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.OPT_END });\n this.$ = $$[$0 - 1];\n break;\n case 37:\n $$[$0 - 1].unshift({ type: \"altStart\", altText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.ALT_START });\n $$[$0 - 1].push({ type: \"altEnd\", signalType: yy.LINETYPE.ALT_END });\n this.$ = $$[$0 - 1];\n break;\n case 38:\n $$[$0 - 1].unshift({ type: \"parStart\", parText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.PAR_START });\n $$[$0 - 1].push({ type: \"parEnd\", signalType: yy.LINETYPE.PAR_END });\n this.$ = $$[$0 - 1];\n break;\n case 39:\n $$[$0 - 1].unshift({ type: \"parStart\", parText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.PAR_OVER_START });\n $$[$0 - 1].push({ type: \"parEnd\", signalType: yy.LINETYPE.PAR_END });\n this.$ = $$[$0 - 1];\n break;\n case 40:\n $$[$0 - 1].unshift({ type: \"criticalStart\", criticalText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.CRITICAL_START });\n $$[$0 - 1].push({ type: \"criticalEnd\", signalType: yy.LINETYPE.CRITICAL_END });\n this.$ = $$[$0 - 1];\n break;\n case 41:\n $$[$0 - 1].unshift({ type: \"breakStart\", breakText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.BREAK_START });\n $$[$0 - 1].push({ type: \"breakEnd\", optText: yy.parseMessage($$[$0 - 2]), signalType: yy.LINETYPE.BREAK_END });\n this.$ = $$[$0 - 1];\n break;\n case 43:\n this.$ = $$[$0 - 3].concat([{ type: \"option\", optionText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.CRITICAL_OPTION }, $$[$0]]);\n break;\n case 45:\n this.$ = $$[$0 - 3].concat([{ type: \"and\", parText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.PAR_AND }, $$[$0]]);\n break;\n case 47:\n this.$ = $$[$0 - 3].concat([{ type: \"else\", altText: yy.parseMessage($$[$0 - 1]), signalType: yy.LINETYPE.ALT_ELSE }, $$[$0]]);\n break;\n case 48:\n $$[$0 - 3].draw = \"participant\";\n $$[$0 - 3].type = \"addParticipant\";\n $$[$0 - 3].description = yy.parseMessage($$[$0 - 1]);\n this.$ = $$[$0 - 3];\n break;\n case 49:\n $$[$0 - 1].draw = \"participant\";\n $$[$0 - 1].type = \"addParticipant\";\n this.$ = $$[$0 - 1];\n break;\n case 50:\n $$[$0 - 3].draw = \"actor\";\n $$[$0 - 3].type = \"addParticipant\";\n $$[$0 - 3].description = yy.parseMessage($$[$0 - 1]);\n this.$ = $$[$0 - 3];\n break;\n case 51:\n $$[$0 - 1].draw = \"actor\";\n $$[$0 - 1].type = \"addParticipant\";\n this.$ = $$[$0 - 1];\n break;\n case 52:\n $$[$0 - 1].type = \"destroyParticipant\";\n this.$ = $$[$0 - 1];\n break;\n case 53:\n this.$ = [$$[$0 - 1], { type: \"addNote\", placement: $$[$0 - 2], actor: $$[$0 - 1].actor, text: $$[$0] }];\n break;\n case 54:\n $$[$0 - 2] = [].concat($$[$0 - 1], $$[$0 - 1]).slice(0, 2);\n $$[$0 - 2][0] = $$[$0 - 2][0].actor;\n $$[$0 - 2][1] = $$[$0 - 2][1].actor;\n this.$ = [$$[$0 - 1], { type: \"addNote\", placement: yy.PLACEMENT.OVER, actor: $$[$0 - 2].slice(0, 2), text: $$[$0] }];\n break;\n case 55:\n this.$ = [$$[$0 - 1], { type: \"addLinks\", actor: $$[$0 - 1].actor, text: $$[$0] }];\n break;\n case 56:\n this.$ = [$$[$0 - 1], { type: \"addALink\", actor: $$[$0 - 1].actor, text: $$[$0] }];\n break;\n case 57:\n this.$ = [$$[$0 - 1], { type: \"addProperties\", actor: $$[$0 - 1].actor, text: $$[$0] }];\n break;\n case 58:\n this.$ = [$$[$0 - 1], { type: \"addDetails\", actor: $$[$0 - 1].actor, text: $$[$0] }];\n break;\n case 61:\n this.$ = [$$[$0 - 2], $$[$0]];\n break;\n case 62:\n this.$ = $$[$0];\n break;\n case 63:\n this.$ = yy.PLACEMENT.LEFTOF;\n break;\n case 64:\n this.$ = yy.PLACEMENT.RIGHTOF;\n break;\n case 65:\n this.$ = [\n $$[$0 - 4],\n $$[$0 - 1],\n { type: \"addMessage\", from: $$[$0 - 4].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 3], msg: $$[$0], activate: true },\n { type: \"activeStart\", signalType: yy.LINETYPE.ACTIVE_START, actor: $$[$0 - 1].actor }\n ];\n break;\n case 66:\n this.$ = [\n $$[$0 - 4],\n $$[$0 - 1],\n { type: \"addMessage\", from: $$[$0 - 4].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 3], msg: $$[$0] },\n { type: \"activeEnd\", signalType: yy.LINETYPE.ACTIVE_END, actor: $$[$0 - 4].actor }\n ];\n break;\n case 67:\n this.$ = [$$[$0 - 3], $$[$0 - 1], { type: \"addMessage\", from: $$[$0 - 3].actor, to: $$[$0 - 1].actor, signalType: $$[$0 - 2], msg: $$[$0] }];\n break;\n case 68:\n this.$ = { type: \"addParticipant\", actor: $$[$0] };\n break;\n case 69:\n this.$ = yy.LINETYPE.SOLID_OPEN;\n break;\n case 70:\n this.$ = yy.LINETYPE.DOTTED_OPEN;\n break;\n case 71:\n this.$ = yy.LINETYPE.SOLID;\n break;\n case 72:\n this.$ = yy.LINETYPE.BIDIRECTIONAL_SOLID;\n break;\n case 73:\n this.$ = yy.LINETYPE.DOTTED;\n break;\n case 74:\n this.$ = yy.LINETYPE.BIDIRECTIONAL_DOTTED;\n break;\n case 75:\n this.$ = yy.LINETYPE.SOLID_CROSS;\n break;\n case 76:\n this.$ = yy.LINETYPE.DOTTED_CROSS;\n break;\n case 77:\n this.$ = yy.LINETYPE.SOLID_POINT;\n break;\n case 78:\n this.$ = yy.LINETYPE.DOTTED_POINT;\n break;\n case 79:\n this.$ = yy.parseMessage($$[$0].trim().substring(1));\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: $V0, 5: $V1, 6: $V2 }, { 1: [3] }, { 3: 5, 4: $V0, 5: $V1, 6: $V2 }, { 3: 6, 4: $V0, 5: $V1, 6: $V2 }, o([1, 4, 5, 13, 14, 18, 21, 23, 29, 30, 31, 33, 35, 36, 37, 38, 39, 41, 43, 44, 46, 50, 52, 53, 54, 59, 60, 61, 62, 70], $V3, { 7: 7 }), { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3], 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, o($Vx, [2, 5]), { 9: 47, 12: 12, 13: $V6, 14: $V7, 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, o($Vx, [2, 7]), o($Vx, [2, 8]), o($Vx, [2, 14]), { 12: 48, 50: $Vo, 52: $Vp, 53: $Vq }, { 15: [1, 49] }, { 5: [1, 50] }, { 5: [1, 53], 19: [1, 51], 20: [1, 52] }, { 22: 54, 70: $Vw }, { 22: 55, 70: $Vw }, { 5: [1, 56] }, { 5: [1, 57] }, { 5: [1, 58] }, { 5: [1, 59] }, { 5: [1, 60] }, o($Vx, [2, 29]), o($Vx, [2, 30]), { 32: [1, 61] }, { 34: [1, 62] }, o($Vx, [2, 33]), { 15: [1, 63] }, { 15: [1, 64] }, { 15: [1, 65] }, { 15: [1, 66] }, { 15: [1, 67] }, { 15: [1, 68] }, { 15: [1, 69] }, { 15: [1, 70] }, { 22: 71, 70: $Vw }, { 22: 72, 70: $Vw }, { 22: 73, 70: $Vw }, { 67: 74, 71: [1, 75], 72: [1, 76], 73: [1, 77], 74: [1, 78], 75: [1, 79], 76: [1, 80], 77: [1, 81], 78: [1, 82], 79: [1, 83], 80: [1, 84] }, { 55: 85, 57: [1, 86], 65: [1, 87], 66: [1, 88] }, { 22: 89, 70: $Vw }, { 22: 90, 70: $Vw }, { 22: 91, 70: $Vw }, { 22: 92, 70: $Vw }, o([5, 51, 64, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81], [2, 68]), o($Vx, [2, 6]), o($Vx, [2, 15]), o($Vy, [2, 9], { 10: 93 }), o($Vx, [2, 17]), { 5: [1, 95], 19: [1, 94] }, { 5: [1, 96] }, o($Vx, [2, 21]), { 5: [1, 97] }, { 5: [1, 98] }, o($Vx, [2, 24]), o($Vx, [2, 25]), o($Vx, [2, 26]), o($Vx, [2, 27]), o($Vx, [2, 28]), o($Vx, [2, 31]), o($Vx, [2, 32]), o($Vz, $V3, { 7: 99 }), o($Vz, $V3, { 7: 100 }), o($Vz, $V3, { 7: 101 }), o($VA, $V3, { 40: 102, 7: 103 }), o($VB, $V3, { 42: 104, 7: 105 }), o($VB, $V3, { 7: 105, 42: 106 }), o($VC, $V3, { 45: 107, 7: 108 }), o($Vz, $V3, { 7: 109 }), { 5: [1, 111], 51: [1, 110] }, { 5: [1, 113], 51: [1, 112] }, { 5: [1, 114] }, { 22: 117, 68: [1, 115], 69: [1, 116], 70: $Vw }, o($VD, [2, 69]), o($VD, [2, 70]), o($VD, [2, 71]), o($VD, [2, 72]), o($VD, [2, 73]), o($VD, [2, 74]), o($VD, [2, 75]), o($VD, [2, 76]), o($VD, [2, 77]), o($VD, [2, 78]), { 22: 118, 70: $Vw }, { 22: 120, 58: 119, 70: $Vw }, { 70: [2, 63] }, { 70: [2, 64] }, { 56: 121, 81: $VE }, { 56: 123, 81: $VE }, { 56: 124, 81: $VE }, { 56: 125, 81: $VE }, { 4: [1, 128], 5: [1, 130], 11: 127, 12: 129, 16: [1, 126], 50: $Vo, 52: $Vp, 53: $Vq }, { 5: [1, 131] }, o($Vx, [2, 19]), o($Vx, [2, 20]), o($Vx, [2, 22]), o($Vx, [2, 23]), { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 132], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 133], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 134], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 135] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 46], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 49: [1, 136], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 137] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 44], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 48: [1, 138], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 16: [1, 139] }, { 16: [1, 140] }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [2, 42], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 47: [1, 141], 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 4: $V4, 5: $V5, 8: 8, 9: 10, 12: 12, 13: $V6, 14: $V7, 16: [1, 142], 17: 15, 18: $V8, 21: $V9, 22: 40, 23: $Va, 24: 19, 25: 20, 26: 21, 27: 22, 28: 23, 29: $Vb, 30: $Vc, 31: $Vd, 33: $Ve, 35: $Vf, 36: $Vg, 37: $Vh, 38: $Vi, 39: $Vj, 41: $Vk, 43: $Vl, 44: $Vm, 46: $Vn, 50: $Vo, 52: $Vp, 53: $Vq, 54: $Vr, 59: $Vs, 60: $Vt, 61: $Vu, 62: $Vv, 70: $Vw }, { 15: [1, 143] }, o($Vx, [2, 49]), { 15: [1, 144] }, o($Vx, [2, 51]), o($Vx, [2, 52]), { 22: 145, 70: $Vw }, { 22: 146, 70: $Vw }, { 56: 147, 81: $VE }, { 56: 148, 81: $VE }, { 56: 149, 81: $VE }, { 64: [1, 150], 81: [2, 62] }, { 5: [2, 55] }, { 5: [2, 79] }, { 5: [2, 56] }, { 5: [2, 57] }, { 5: [2, 58] }, o($Vx, [2, 16]), o($Vy, [2, 10]), { 12: 151, 50: $Vo, 52: $Vp, 53: $Vq }, o($Vy, [2, 12]), o($Vy, [2, 13]), o($Vx, [2, 18]), o($Vx, [2, 34]), o($Vx, [2, 35]), o($Vx, [2, 36]), o($Vx, [2, 37]), { 15: [1, 152] }, o($Vx, [2, 38]), { 15: [1, 153] }, o($Vx, [2, 39]), o($Vx, [2, 40]), { 15: [1, 154] }, o($Vx, [2, 41]), { 5: [1, 155] }, { 5: [1, 156] }, { 56: 157, 81: $VE }, { 56: 158, 81: $VE }, { 5: [2, 67] }, { 5: [2, 53] }, { 5: [2, 54] }, { 22: 159, 70: $Vw }, o($Vy, [2, 11]), o($VA, $V3, { 7: 103, 40: 160 }), o($VB, $V3, { 7: 105, 42: 161 }), o($VC, $V3, { 7: 108, 45: 162 }), o($Vx, [2, 48]), o($Vx, [2, 50]), { 5: [2, 65] }, { 5: [2, 66] }, { 81: [2, 61] }, { 16: [2, 47] }, { 16: [2, 45] }, { 16: [2, 43] }],\n defaultActions: { 5: [2, 1], 6: [2, 2], 87: [2, 63], 88: [2, 64], 121: [2, 55], 122: [2, 79], 123: [2, 56], 124: [2, 57], 125: [2, 58], 147: [2, 67], 148: [2, 53], 149: [2, 54], 157: [2, 65], 158: [2, 66], 159: [2, 61], 160: [2, 47], 161: [2, 45], 162: [2, 43] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state2, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state2 = stack[stack.length - 1];\n if (this.defaultActions[state2]) {\n action = this.defaultActions[state2];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state2] && table[state2][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state2]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state2 + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n return 5;\n break;\n case 1:\n break;\n case 2:\n break;\n case 3:\n break;\n case 4:\n break;\n case 5:\n break;\n case 6:\n return 19;\n break;\n case 7:\n this.begin(\"LINE\");\n return 14;\n break;\n case 8:\n this.begin(\"ID\");\n return 50;\n break;\n case 9:\n this.begin(\"ID\");\n return 52;\n break;\n case 10:\n return 13;\n break;\n case 11:\n this.begin(\"ID\");\n return 53;\n break;\n case 12:\n yy_.yytext = yy_.yytext.trim();\n this.begin(\"ALIAS\");\n return 70;\n break;\n case 13:\n this.popState();\n this.popState();\n this.begin(\"LINE\");\n return 51;\n break;\n case 14:\n this.popState();\n this.popState();\n return 5;\n break;\n case 15:\n this.begin(\"LINE\");\n return 36;\n break;\n case 16:\n this.begin(\"LINE\");\n return 37;\n break;\n case 17:\n this.begin(\"LINE\");\n return 38;\n break;\n case 18:\n this.begin(\"LINE\");\n return 39;\n break;\n case 19:\n this.begin(\"LINE\");\n return 49;\n break;\n case 20:\n this.begin(\"LINE\");\n return 41;\n break;\n case 21:\n this.begin(\"LINE\");\n return 43;\n break;\n case 22:\n this.begin(\"LINE\");\n return 48;\n break;\n case 23:\n this.begin(\"LINE\");\n return 44;\n break;\n case 24:\n this.begin(\"LINE\");\n return 47;\n break;\n case 25:\n this.begin(\"LINE\");\n return 46;\n break;\n case 26:\n this.popState();\n return 15;\n break;\n case 27:\n return 16;\n break;\n case 28:\n return 65;\n break;\n case 29:\n return 66;\n break;\n case 30:\n return 59;\n break;\n case 31:\n return 60;\n break;\n case 32:\n return 61;\n break;\n case 33:\n return 62;\n break;\n case 34:\n return 57;\n break;\n case 35:\n return 54;\n break;\n case 36:\n this.begin(\"ID\");\n return 21;\n break;\n case 37:\n this.begin(\"ID\");\n return 23;\n break;\n case 38:\n return 29;\n break;\n case 39:\n return 30;\n break;\n case 40:\n this.begin(\"acc_title\");\n return 31;\n break;\n case 41:\n this.popState();\n return \"acc_title_value\";\n break;\n case 42:\n this.begin(\"acc_descr\");\n return 33;\n break;\n case 43:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 44:\n this.begin(\"acc_descr_multiline\");\n break;\n case 45:\n this.popState();\n break;\n case 46:\n return \"acc_descr_multiline_value\";\n break;\n case 47:\n return 6;\n break;\n case 48:\n return 18;\n break;\n case 49:\n return 20;\n break;\n case 50:\n return 64;\n break;\n case 51:\n return 5;\n break;\n case 52:\n yy_.yytext = yy_.yytext.trim();\n return 70;\n break;\n case 53:\n return 73;\n break;\n case 54:\n return 74;\n break;\n case 55:\n return 75;\n break;\n case 56:\n return 76;\n break;\n case 57:\n return 71;\n break;\n case 58:\n return 72;\n break;\n case 59:\n return 77;\n break;\n case 60:\n return 78;\n break;\n case 61:\n return 79;\n break;\n case 62:\n return 80;\n break;\n case 63:\n return 81;\n break;\n case 64:\n return 68;\n break;\n case 65:\n return 69;\n break;\n case 66:\n return 5;\n break;\n case 67:\n return \"INVALID\";\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:[\\n]+)/i, /^(?:\\s+)/i, /^(?:((?!\\n)\\s)+)/i, /^(?:#[^\\n]*)/i, /^(?:%(?!\\{)[^\\n]*)/i, /^(?:[^\\}]%%[^\\n]*)/i, /^(?:[0-9]+(?=[ \\n]+))/i, /^(?:box\\b)/i, /^(?:participant\\b)/i, /^(?:actor\\b)/i, /^(?:create\\b)/i, /^(?:destroy\\b)/i, /^(?:[^\\<->\\->:\\n,;]+?([\\-]*[^\\<->\\->:\\n,;]+?)*?(?=((?!\\n)\\s)+as(?!\\n)\\s|[#\\n;]|$))/i, /^(?:as\\b)/i, /^(?:(?:))/i, /^(?:loop\\b)/i, /^(?:rect\\b)/i, /^(?:opt\\b)/i, /^(?:alt\\b)/i, /^(?:else\\b)/i, /^(?:par\\b)/i, /^(?:par_over\\b)/i, /^(?:and\\b)/i, /^(?:critical\\b)/i, /^(?:option\\b)/i, /^(?:break\\b)/i, /^(?:(?:[:]?(?:no)?wrap)?[^#\\n;]*)/i, /^(?:end\\b)/i, /^(?:left of\\b)/i, /^(?:right of\\b)/i, /^(?:links\\b)/i, /^(?:link\\b)/i, /^(?:properties\\b)/i, /^(?:details\\b)/i, /^(?:over\\b)/i, /^(?:note\\b)/i, /^(?:activate\\b)/i, /^(?:deactivate\\b)/i, /^(?:title\\s[^#\\n;]+)/i, /^(?:title:\\s[^#\\n;]+)/i, /^(?:accTitle\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*\\{\\s*)/i, /^(?:[\\}])/i, /^(?:[^\\}]*)/i, /^(?:sequenceDiagram\\b)/i, /^(?:autonumber\\b)/i, /^(?:off\\b)/i, /^(?:,)/i, /^(?:;)/i, /^(?:[^\\+\\<->\\->:\\n,;]+((?!(-x|--x|-\\)|--\\)))[\\-]*[^\\+\\<->\\->:\\n,;]+)*)/i, /^(?:->>)/i, /^(?:<<->>)/i, /^(?:-->>)/i, /^(?:<<-->>)/i, /^(?:->)/i, /^(?:-->)/i, /^(?:-[x])/i, /^(?:--[x])/i, /^(?:-[\\)])/i, /^(?:--[\\)])/i, /^(?::(?:(?:no)?wrap)?[^#\\n;]+)/i, /^(?:\\+)/i, /^(?:-)/i, /^(?:$)/i, /^(?:.)/i],\n conditions: { \"acc_descr_multiline\": { \"rules\": [45, 46], \"inclusive\": false }, \"acc_descr\": { \"rules\": [43], \"inclusive\": false }, \"acc_title\": { \"rules\": [41], \"inclusive\": false }, \"ID\": { \"rules\": [2, 3, 12], \"inclusive\": false }, \"ALIAS\": { \"rules\": [2, 3, 13, 14], \"inclusive\": false }, \"LINE\": { \"rules\": [2, 3, 26], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 42, 44, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar sequenceDiagram_default = parser;\n\n// src/diagrams/sequence/sequenceDb.ts\nvar state = new ImperativeState(() => ({\n prevActor: void 0,\n actors: /* @__PURE__ */ new Map(),\n createdActors: /* @__PURE__ */ new Map(),\n destroyedActors: /* @__PURE__ */ new Map(),\n boxes: [],\n messages: [],\n notes: [],\n sequenceNumbersEnabled: false,\n wrapEnabled: void 0,\n currentBox: void 0,\n lastCreated: void 0,\n lastDestroyed: void 0\n}));\nvar addBox = /* @__PURE__ */ __name(function(data) {\n state.records.boxes.push({\n name: data.text,\n wrap: data.wrap ?? autoWrap(),\n fill: data.color,\n actorKeys: []\n });\n state.records.currentBox = state.records.boxes.slice(-1)[0];\n}, \"addBox\");\nvar addActor = /* @__PURE__ */ __name(function(id, name, description, type) {\n let assignedBox = state.records.currentBox;\n const old = state.records.actors.get(id);\n if (old) {\n if (state.records.currentBox && old.box && state.records.currentBox !== old.box) {\n throw new Error(\n `A same participant should only be defined in one Box: ${old.name} can't be in '${old.box.name}' and in '${state.records.currentBox.name}' at the same time.`\n );\n }\n assignedBox = old.box ? old.box : state.records.currentBox;\n old.box = assignedBox;\n if (old && name === old.name && description == null) {\n return;\n }\n }\n if (description?.text == null) {\n description = { text: name, type };\n }\n if (type == null || description.text == null) {\n description = { text: name, type };\n }\n state.records.actors.set(id, {\n box: assignedBox,\n name,\n description: description.text,\n wrap: description.wrap ?? autoWrap(),\n prevActor: state.records.prevActor,\n links: {},\n properties: {},\n actorCnt: null,\n rectData: null,\n type: type ?? \"participant\"\n });\n if (state.records.prevActor) {\n const prevActorInRecords = state.records.actors.get(state.records.prevActor);\n if (prevActorInRecords) {\n prevActorInRecords.nextActor = id;\n }\n }\n if (state.records.currentBox) {\n state.records.currentBox.actorKeys.push(id);\n }\n state.records.prevActor = id;\n}, \"addActor\");\nvar activationCount = /* @__PURE__ */ __name((part) => {\n let i;\n let count = 0;\n if (!part) {\n return 0;\n }\n for (i = 0; i < state.records.messages.length; i++) {\n if (state.records.messages[i].type === LINETYPE.ACTIVE_START && state.records.messages[i].from === part) {\n count++;\n }\n if (state.records.messages[i].type === LINETYPE.ACTIVE_END && state.records.messages[i].from === part) {\n count--;\n }\n }\n return count;\n}, \"activationCount\");\nvar addMessage = /* @__PURE__ */ __name(function(idFrom, idTo, message, answer) {\n state.records.messages.push({\n from: idFrom,\n to: idTo,\n message: message.text,\n wrap: message.wrap ?? autoWrap(),\n answer\n });\n}, \"addMessage\");\nvar addSignal = /* @__PURE__ */ __name(function(idFrom, idTo, message, messageType, activate = false) {\n if (messageType === LINETYPE.ACTIVE_END) {\n const cnt = activationCount(idFrom ?? \"\");\n if (cnt < 1) {\n const error = new Error(\"Trying to inactivate an inactive participant (\" + idFrom + \")\");\n error.hash = {\n text: \"->>-\",\n token: \"->>-\",\n line: \"1\",\n loc: { first_line: 1, last_line: 1, first_column: 1, last_column: 1 },\n expected: [\"'ACTIVE_PARTICIPANT'\"]\n };\n throw error;\n }\n }\n state.records.messages.push({\n from: idFrom,\n to: idTo,\n message: message?.text ?? \"\",\n wrap: message?.wrap ?? autoWrap(),\n type: messageType,\n activate\n });\n return true;\n}, \"addSignal\");\nvar hasAtLeastOneBox = /* @__PURE__ */ __name(function() {\n return state.records.boxes.length > 0;\n}, \"hasAtLeastOneBox\");\nvar hasAtLeastOneBoxWithTitle = /* @__PURE__ */ __name(function() {\n return state.records.boxes.some((b) => b.name);\n}, \"hasAtLeastOneBoxWithTitle\");\nvar getMessages = /* @__PURE__ */ __name(function() {\n return state.records.messages;\n}, \"getMessages\");\nvar getBoxes = /* @__PURE__ */ __name(function() {\n return state.records.boxes;\n}, \"getBoxes\");\nvar getActors = /* @__PURE__ */ __name(function() {\n return state.records.actors;\n}, \"getActors\");\nvar getCreatedActors = /* @__PURE__ */ __name(function() {\n return state.records.createdActors;\n}, \"getCreatedActors\");\nvar getDestroyedActors = /* @__PURE__ */ __name(function() {\n return state.records.destroyedActors;\n}, \"getDestroyedActors\");\nvar getActor = /* @__PURE__ */ __name(function(id) {\n return state.records.actors.get(id);\n}, \"getActor\");\nvar getActorKeys = /* @__PURE__ */ __name(function() {\n return [...state.records.actors.keys()];\n}, \"getActorKeys\");\nvar enableSequenceNumbers = /* @__PURE__ */ __name(function() {\n state.records.sequenceNumbersEnabled = true;\n}, \"enableSequenceNumbers\");\nvar disableSequenceNumbers = /* @__PURE__ */ __name(function() {\n state.records.sequenceNumbersEnabled = false;\n}, \"disableSequenceNumbers\");\nvar showSequenceNumbers = /* @__PURE__ */ __name(() => state.records.sequenceNumbersEnabled, \"showSequenceNumbers\");\nvar setWrap = /* @__PURE__ */ __name(function(wrapSetting) {\n state.records.wrapEnabled = wrapSetting;\n}, \"setWrap\");\nvar extractWrap = /* @__PURE__ */ __name((text) => {\n if (text === void 0) {\n return {};\n }\n text = text.trim();\n const wrap = /^:?wrap:/.exec(text) !== null ? true : /^:?nowrap:/.exec(text) !== null ? false : void 0;\n const cleanedText = (wrap === void 0 ? text : text.replace(/^:?(?:no)?wrap:/, \"\")).trim();\n return { cleanedText, wrap };\n}, \"extractWrap\");\nvar autoWrap = /* @__PURE__ */ __name(() => {\n if (state.records.wrapEnabled !== void 0) {\n return state.records.wrapEnabled;\n }\n return getConfig2().sequence?.wrap ?? false;\n}, \"autoWrap\");\nvar clear2 = /* @__PURE__ */ __name(function() {\n state.reset();\n clear();\n}, \"clear\");\nvar parseMessage = /* @__PURE__ */ __name(function(str) {\n const trimmedStr = str.trim();\n const { wrap, cleanedText } = extractWrap(trimmedStr);\n const message = {\n text: cleanedText,\n wrap\n };\n log.debug(`parseMessage: ${JSON.stringify(message)}`);\n return message;\n}, \"parseMessage\");\nvar parseBoxData = /* @__PURE__ */ __name(function(str) {\n const match = /^((?:rgba?|hsla?)\\s*\\(.*\\)|\\w*)(.*)$/.exec(str);\n let color = match?.[1] ? match[1].trim() : \"transparent\";\n let title = match?.[2] ? match[2].trim() : void 0;\n if (window?.CSS) {\n if (!window.CSS.supports(\"color\", color)) {\n color = \"transparent\";\n title = str.trim();\n }\n } else {\n const style = new Option().style;\n style.color = color;\n if (style.color !== color) {\n color = \"transparent\";\n title = str.trim();\n }\n }\n const { wrap, cleanedText } = extractWrap(title);\n return {\n text: cleanedText ? sanitizeText(cleanedText, getConfig2()) : void 0,\n color,\n wrap\n };\n}, \"parseBoxData\");\nvar LINETYPE = {\n SOLID: 0,\n DOTTED: 1,\n NOTE: 2,\n SOLID_CROSS: 3,\n DOTTED_CROSS: 4,\n SOLID_OPEN: 5,\n DOTTED_OPEN: 6,\n LOOP_START: 10,\n LOOP_END: 11,\n ALT_START: 12,\n ALT_ELSE: 13,\n ALT_END: 14,\n OPT_START: 15,\n OPT_END: 16,\n ACTIVE_START: 17,\n ACTIVE_END: 18,\n PAR_START: 19,\n PAR_AND: 20,\n PAR_END: 21,\n RECT_START: 22,\n RECT_END: 23,\n SOLID_POINT: 24,\n DOTTED_POINT: 25,\n AUTONUMBER: 26,\n CRITICAL_START: 27,\n CRITICAL_OPTION: 28,\n CRITICAL_END: 29,\n BREAK_START: 30,\n BREAK_END: 31,\n PAR_OVER_START: 32,\n BIDIRECTIONAL_SOLID: 33,\n BIDIRECTIONAL_DOTTED: 34\n};\nvar ARROWTYPE = {\n FILLED: 0,\n OPEN: 1\n};\nvar PLACEMENT = {\n LEFTOF: 0,\n RIGHTOF: 1,\n OVER: 2\n};\nvar addNote = /* @__PURE__ */ __name(function(actor, placement, message) {\n const note = {\n actor,\n placement,\n message: message.text,\n wrap: message.wrap ?? autoWrap()\n };\n const actors = [].concat(actor, actor);\n state.records.notes.push(note);\n state.records.messages.push({\n from: actors[0],\n to: actors[1],\n message: message.text,\n wrap: message.wrap ?? autoWrap(),\n type: LINETYPE.NOTE,\n placement\n });\n}, \"addNote\");\nvar addLinks = /* @__PURE__ */ __name(function(actorId, text) {\n const actor = getActor(actorId);\n try {\n let sanitizedText = sanitizeText(text.text, getConfig2());\n sanitizedText = sanitizedText.replace(/&/g, \"&\");\n sanitizedText = sanitizedText.replace(/=/g, \"=\");\n const links = JSON.parse(sanitizedText);\n insertLinks(actor, links);\n } catch (e) {\n log.error(\"error while parsing actor link text\", e);\n }\n}, \"addLinks\");\nvar addALink = /* @__PURE__ */ __name(function(actorId, text) {\n const actor = getActor(actorId);\n try {\n const links = {};\n let sanitizedText = sanitizeText(text.text, getConfig2());\n const sep = sanitizedText.indexOf(\"@\");\n sanitizedText = sanitizedText.replace(/&/g, \"&\");\n sanitizedText = sanitizedText.replace(/=/g, \"=\");\n const label = sanitizedText.slice(0, sep - 1).trim();\n const link = sanitizedText.slice(sep + 1).trim();\n links[label] = link;\n insertLinks(actor, links);\n } catch (e) {\n log.error(\"error while parsing actor link text\", e);\n }\n}, \"addALink\");\nfunction insertLinks(actor, links) {\n if (actor.links == null) {\n actor.links = links;\n } else {\n for (const key in links) {\n actor.links[key] = links[key];\n }\n }\n}\n__name(insertLinks, \"insertLinks\");\nvar addProperties = /* @__PURE__ */ __name(function(actorId, text) {\n const actor = getActor(actorId);\n try {\n const sanitizedText = sanitizeText(text.text, getConfig2());\n const properties = JSON.parse(sanitizedText);\n insertProperties(actor, properties);\n } catch (e) {\n log.error(\"error while parsing actor properties text\", e);\n }\n}, \"addProperties\");\nfunction insertProperties(actor, properties) {\n if (actor.properties == null) {\n actor.properties = properties;\n } else {\n for (const key in properties) {\n actor.properties[key] = properties[key];\n }\n }\n}\n__name(insertProperties, \"insertProperties\");\nfunction boxEnd() {\n state.records.currentBox = void 0;\n}\n__name(boxEnd, \"boxEnd\");\nvar addDetails = /* @__PURE__ */ __name(function(actorId, text) {\n const actor = getActor(actorId);\n const elem = document.getElementById(text.text);\n try {\n const text2 = elem.innerHTML;\n const details = JSON.parse(text2);\n if (details.properties) {\n insertProperties(actor, details.properties);\n }\n if (details.links) {\n insertLinks(actor, details.links);\n }\n } catch (e) {\n log.error(\"error while parsing actor details text\", e);\n }\n}, \"addDetails\");\nvar getActorProperty = /* @__PURE__ */ __name(function(actor, key) {\n if (actor?.properties !== void 0) {\n return actor.properties[key];\n }\n return void 0;\n}, \"getActorProperty\");\nvar apply = /* @__PURE__ */ __name(function(param) {\n if (Array.isArray(param)) {\n param.forEach(function(item) {\n apply(item);\n });\n } else {\n switch (param.type) {\n case \"sequenceIndex\":\n state.records.messages.push({\n from: void 0,\n to: void 0,\n message: {\n start: param.sequenceIndex,\n step: param.sequenceIndexStep,\n visible: param.sequenceVisible\n },\n wrap: false,\n type: param.signalType\n });\n break;\n case \"addParticipant\":\n addActor(param.actor, param.actor, param.description, param.draw);\n break;\n case \"createParticipant\":\n if (state.records.actors.has(param.actor)) {\n throw new Error(\n \"It is not possible to have actors with the same id, even if one is destroyed before the next is created. Use 'AS' aliases to simulate the behavior\"\n );\n }\n state.records.lastCreated = param.actor;\n addActor(param.actor, param.actor, param.description, param.draw);\n state.records.createdActors.set(param.actor, state.records.messages.length);\n break;\n case \"destroyParticipant\":\n state.records.lastDestroyed = param.actor;\n state.records.destroyedActors.set(param.actor, state.records.messages.length);\n break;\n case \"activeStart\":\n addSignal(param.actor, void 0, void 0, param.signalType);\n break;\n case \"activeEnd\":\n addSignal(param.actor, void 0, void 0, param.signalType);\n break;\n case \"addNote\":\n addNote(param.actor, param.placement, param.text);\n break;\n case \"addLinks\":\n addLinks(param.actor, param.text);\n break;\n case \"addALink\":\n addALink(param.actor, param.text);\n break;\n case \"addProperties\":\n addProperties(param.actor, param.text);\n break;\n case \"addDetails\":\n addDetails(param.actor, param.text);\n break;\n case \"addMessage\":\n if (state.records.lastCreated) {\n if (param.to !== state.records.lastCreated) {\n throw new Error(\n \"The created participant \" + state.records.lastCreated.name + \" does not have an associated creating message after its declaration. Please check the sequence diagram.\"\n );\n } else {\n state.records.lastCreated = void 0;\n }\n } else if (state.records.lastDestroyed) {\n if (param.to !== state.records.lastDestroyed && param.from !== state.records.lastDestroyed) {\n throw new Error(\n \"The destroyed participant \" + state.records.lastDestroyed.name + \" does not have an associated destroying message after its declaration. Please check the sequence diagram.\"\n );\n } else {\n state.records.lastDestroyed = void 0;\n }\n }\n addSignal(param.from, param.to, param.msg, param.signalType, param.activate);\n break;\n case \"boxStart\":\n addBox(param.boxData);\n break;\n case \"boxEnd\":\n boxEnd();\n break;\n case \"loopStart\":\n addSignal(void 0, void 0, param.loopText, param.signalType);\n break;\n case \"loopEnd\":\n addSignal(void 0, void 0, void 0, param.signalType);\n break;\n case \"rectStart\":\n addSignal(void 0, void 0, param.color, param.signalType);\n break;\n case \"rectEnd\":\n addSignal(void 0, void 0, void 0, param.signalType);\n break;\n case \"optStart\":\n addSignal(void 0, void 0, param.optText, param.signalType);\n break;\n case \"optEnd\":\n addSignal(void 0, void 0, void 0, param.signalType);\n break;\n case \"altStart\":\n addSignal(void 0, void 0, param.altText, param.signalType);\n break;\n case \"else\":\n addSignal(void 0, void 0, param.altText, param.signalType);\n break;\n case \"altEnd\":\n addSignal(void 0, void 0, void 0, param.signalType);\n break;\n case \"setAccTitle\":\n setAccTitle(param.text);\n break;\n case \"parStart\":\n addSignal(void 0, void 0, param.parText, param.signalType);\n break;\n case \"and\":\n addSignal(void 0, void 0, param.parText, param.signalType);\n break;\n case \"parEnd\":\n addSignal(void 0, void 0, void 0, param.signalType);\n break;\n case \"criticalStart\":\n addSignal(void 0, void 0, param.criticalText, param.signalType);\n break;\n case \"option\":\n addSignal(void 0, void 0, param.optionText, param.signalType);\n break;\n case \"criticalEnd\":\n addSignal(void 0, void 0, void 0, param.signalType);\n break;\n case \"breakStart\":\n addSignal(void 0, void 0, param.breakText, param.signalType);\n break;\n case \"breakEnd\":\n addSignal(void 0, void 0, void 0, param.signalType);\n break;\n }\n }\n}, \"apply\");\nvar sequenceDb_default = {\n addActor,\n addMessage,\n addSignal,\n addLinks,\n addDetails,\n addProperties,\n autoWrap,\n setWrap,\n enableSequenceNumbers,\n disableSequenceNumbers,\n showSequenceNumbers,\n getMessages,\n getActors,\n getCreatedActors,\n getDestroyedActors,\n getActor,\n getActorKeys,\n getActorProperty,\n getAccTitle,\n getBoxes,\n getDiagramTitle,\n setDiagramTitle,\n getConfig: /* @__PURE__ */ __name(() => getConfig2().sequence, \"getConfig\"),\n clear: clear2,\n parseMessage,\n parseBoxData,\n LINETYPE,\n ARROWTYPE,\n PLACEMENT,\n addNote,\n setAccTitle,\n apply,\n setAccDescription,\n getAccDescription,\n hasAtLeastOneBox,\n hasAtLeastOneBoxWithTitle\n};\n\n// src/diagrams/sequence/styles.js\nvar getStyles = /* @__PURE__ */ __name((options) => `.actor {\n stroke: ${options.actorBorder};\n fill: ${options.actorBkg};\n }\n\n text.actor > tspan {\n fill: ${options.actorTextColor};\n stroke: none;\n }\n\n .actor-line {\n stroke: ${options.actorLineColor};\n }\n\n .messageLine0 {\n stroke-width: 1.5;\n stroke-dasharray: none;\n stroke: ${options.signalColor};\n }\n\n .messageLine1 {\n stroke-width: 1.5;\n stroke-dasharray: 2, 2;\n stroke: ${options.signalColor};\n }\n\n #arrowhead path {\n fill: ${options.signalColor};\n stroke: ${options.signalColor};\n }\n\n .sequenceNumber {\n fill: ${options.sequenceNumberColor};\n }\n\n #sequencenumber {\n fill: ${options.signalColor};\n }\n\n #crosshead path {\n fill: ${options.signalColor};\n stroke: ${options.signalColor};\n }\n\n .messageText {\n fill: ${options.signalTextColor};\n stroke: none;\n }\n\n .labelBox {\n stroke: ${options.labelBoxBorderColor};\n fill: ${options.labelBoxBkgColor};\n }\n\n .labelText, .labelText > tspan {\n fill: ${options.labelTextColor};\n stroke: none;\n }\n\n .loopText, .loopText > tspan {\n fill: ${options.loopTextColor};\n stroke: none;\n }\n\n .loopLine {\n stroke-width: 2px;\n stroke-dasharray: 2, 2;\n stroke: ${options.labelBoxBorderColor};\n fill: ${options.labelBoxBorderColor};\n }\n\n .note {\n //stroke: #decc93;\n stroke: ${options.noteBorderColor};\n fill: ${options.noteBkgColor};\n }\n\n .noteText, .noteText > tspan {\n fill: ${options.noteTextColor};\n stroke: none;\n }\n\n .activation0 {\n fill: ${options.activationBkgColor};\n stroke: ${options.activationBorderColor};\n }\n\n .activation1 {\n fill: ${options.activationBkgColor};\n stroke: ${options.activationBorderColor};\n }\n\n .activation2 {\n fill: ${options.activationBkgColor};\n stroke: ${options.activationBorderColor};\n }\n\n .actorPopupMenu {\n position: absolute;\n }\n\n .actorPopupMenuPanel {\n position: absolute;\n fill: ${options.actorBkg};\n box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2);\n filter: drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));\n}\n .actor-man line {\n stroke: ${options.actorBorder};\n fill: ${options.actorBkg};\n }\n .actor-man circle, line {\n stroke: ${options.actorBorder};\n fill: ${options.actorBkg};\n stroke-width: 2px;\n }\n`, \"getStyles\");\nvar styles_default = getStyles;\n\n// src/diagrams/sequence/sequenceRenderer.ts\nimport { select } from \"d3\";\n\n// src/diagrams/sequence/svgDraw.js\nimport { sanitizeUrl } from \"@braintree/sanitize-url\";\nvar ACTOR_TYPE_WIDTH = 18 * 2;\nvar TOP_ACTOR_CLASS = \"actor-top\";\nvar BOTTOM_ACTOR_CLASS = \"actor-bottom\";\nvar ACTOR_BOX_CLASS = \"actor-box\";\nvar ACTOR_MAN_FIGURE_CLASS = \"actor-man\";\nvar drawRect2 = /* @__PURE__ */ __name(function(elem, rectData) {\n return drawRect(elem, rectData);\n}, \"drawRect\");\nvar drawPopup = /* @__PURE__ */ __name(function(elem, actor, minMenuWidth, textAttrs, forceMenus) {\n if (actor.links === void 0 || actor.links === null || Object.keys(actor.links).length === 0) {\n return { height: 0, width: 0 };\n }\n const links = actor.links;\n const actorCnt2 = actor.actorCnt;\n const rectData = actor.rectData;\n var displayValue = \"none\";\n if (forceMenus) {\n displayValue = \"block !important\";\n }\n const g = elem.append(\"g\");\n g.attr(\"id\", \"actor\" + actorCnt2 + \"_popup\");\n g.attr(\"class\", \"actorPopupMenu\");\n g.attr(\"display\", displayValue);\n var actorClass = \"\";\n if (rectData.class !== void 0) {\n actorClass = \" \" + rectData.class;\n }\n let menuWidth = rectData.width > minMenuWidth ? rectData.width : minMenuWidth;\n const rectElem = g.append(\"rect\");\n rectElem.attr(\"class\", \"actorPopupMenuPanel\" + actorClass);\n rectElem.attr(\"x\", rectData.x);\n rectElem.attr(\"y\", rectData.height);\n rectElem.attr(\"fill\", rectData.fill);\n rectElem.attr(\"stroke\", rectData.stroke);\n rectElem.attr(\"width\", menuWidth);\n rectElem.attr(\"height\", rectData.height);\n rectElem.attr(\"rx\", rectData.rx);\n rectElem.attr(\"ry\", rectData.ry);\n if (links != null) {\n var linkY = 20;\n for (let key in links) {\n var linkElem = g.append(\"a\");\n var sanitizedLink = sanitizeUrl(links[key]);\n linkElem.attr(\"xlink:href\", sanitizedLink);\n linkElem.attr(\"target\", \"_blank\");\n _drawMenuItemTextCandidateFunc(textAttrs)(\n key,\n linkElem,\n rectData.x + 10,\n rectData.height + linkY,\n menuWidth,\n 20,\n { class: \"actor\" },\n textAttrs\n );\n linkY += 30;\n }\n }\n rectElem.attr(\"height\", linkY);\n return { height: rectData.height + linkY, width: menuWidth };\n}, \"drawPopup\");\nvar popupMenuToggle = /* @__PURE__ */ __name(function(popId) {\n return \"var pu = document.getElementById('\" + popId + \"'); if (pu != null) { pu.style.display = pu.style.display == 'block' ? 'none' : 'block'; }\";\n}, \"popupMenuToggle\");\nvar drawKatex = /* @__PURE__ */ __name(async function(elem, textData, msgModel = null) {\n let textElem = elem.append(\"foreignObject\");\n const lines = await renderKatex(textData.text, getConfig());\n const divElem = textElem.append(\"xhtml:div\").attr(\"style\", \"width: fit-content;\").attr(\"xmlns\", \"http://www.w3.org/1999/xhtml\").html(lines);\n const dim = divElem.node().getBoundingClientRect();\n textElem.attr(\"height\", Math.round(dim.height)).attr(\"width\", Math.round(dim.width));\n if (textData.class === \"noteText\") {\n const rectElem = elem.node().firstChild;\n rectElem.setAttribute(\"height\", dim.height + 2 * textData.textMargin);\n const rectDim = rectElem.getBBox();\n textElem.attr(\"x\", Math.round(rectDim.x + rectDim.width / 2 - dim.width / 2)).attr(\"y\", Math.round(rectDim.y + rectDim.height / 2 - dim.height / 2));\n } else if (msgModel) {\n let { startx, stopx, starty } = msgModel;\n if (startx > stopx) {\n const temp = startx;\n startx = stopx;\n stopx = temp;\n }\n textElem.attr(\"x\", Math.round(startx + Math.abs(startx - stopx) / 2 - dim.width / 2));\n if (textData.class === \"loopText\") {\n textElem.attr(\"y\", Math.round(starty));\n } else {\n textElem.attr(\"y\", Math.round(starty - dim.height));\n }\n }\n return [textElem];\n}, \"drawKatex\");\nvar drawText = /* @__PURE__ */ __name(function(elem, textData) {\n let prevTextHeight = 0;\n let textHeight = 0;\n const lines = textData.text.split(common_default.lineBreakRegex);\n const [_textFontSize, _textFontSizePx] = parseFontSize(textData.fontSize);\n let textElems = [];\n let dy = 0;\n let yfunc = /* @__PURE__ */ __name(() => textData.y, \"yfunc\");\n if (textData.valign !== void 0 && textData.textMargin !== void 0 && textData.textMargin > 0) {\n switch (textData.valign) {\n case \"top\":\n case \"start\":\n yfunc = /* @__PURE__ */ __name(() => Math.round(textData.y + textData.textMargin), \"yfunc\");\n break;\n case \"middle\":\n case \"center\":\n yfunc = /* @__PURE__ */ __name(() => Math.round(textData.y + (prevTextHeight + textHeight + textData.textMargin) / 2), \"yfunc\");\n break;\n case \"bottom\":\n case \"end\":\n yfunc = /* @__PURE__ */ __name(() => Math.round(\n textData.y + (prevTextHeight + textHeight + 2 * textData.textMargin) - textData.textMargin\n ), \"yfunc\");\n break;\n }\n }\n if (textData.anchor !== void 0 && textData.textMargin !== void 0 && textData.width !== void 0) {\n switch (textData.anchor) {\n case \"left\":\n case \"start\":\n textData.x = Math.round(textData.x + textData.textMargin);\n textData.anchor = \"start\";\n textData.dominantBaseline = \"middle\";\n textData.alignmentBaseline = \"middle\";\n break;\n case \"middle\":\n case \"center\":\n textData.x = Math.round(textData.x + textData.width / 2);\n textData.anchor = \"middle\";\n textData.dominantBaseline = \"middle\";\n textData.alignmentBaseline = \"middle\";\n break;\n case \"right\":\n case \"end\":\n textData.x = Math.round(textData.x + textData.width - textData.textMargin);\n textData.anchor = \"end\";\n textData.dominantBaseline = \"middle\";\n textData.alignmentBaseline = \"middle\";\n break;\n }\n }\n for (let [i, line] of lines.entries()) {\n if (textData.textMargin !== void 0 && textData.textMargin === 0 && _textFontSize !== void 0) {\n dy = i * _textFontSize;\n }\n const textElem = elem.append(\"text\");\n textElem.attr(\"x\", textData.x);\n textElem.attr(\"y\", yfunc());\n if (textData.anchor !== void 0) {\n textElem.attr(\"text-anchor\", textData.anchor).attr(\"dominant-baseline\", textData.dominantBaseline).attr(\"alignment-baseline\", textData.alignmentBaseline);\n }\n if (textData.fontFamily !== void 0) {\n textElem.style(\"font-family\", textData.fontFamily);\n }\n if (_textFontSizePx !== void 0) {\n textElem.style(\"font-size\", _textFontSizePx);\n }\n if (textData.fontWeight !== void 0) {\n textElem.style(\"font-weight\", textData.fontWeight);\n }\n if (textData.fill !== void 0) {\n textElem.attr(\"fill\", textData.fill);\n }\n if (textData.class !== void 0) {\n textElem.attr(\"class\", textData.class);\n }\n if (textData.dy !== void 0) {\n textElem.attr(\"dy\", textData.dy);\n } else if (dy !== 0) {\n textElem.attr(\"dy\", dy);\n }\n const text = line || ZERO_WIDTH_SPACE;\n if (textData.tspan) {\n const span = textElem.append(\"tspan\");\n span.attr(\"x\", textData.x);\n if (textData.fill !== void 0) {\n span.attr(\"fill\", textData.fill);\n }\n span.text(text);\n } else {\n textElem.text(text);\n }\n if (textData.valign !== void 0 && textData.textMargin !== void 0 && textData.textMargin > 0) {\n textHeight += (textElem._groups || textElem)[0][0].getBBox().height;\n prevTextHeight = textHeight;\n }\n textElems.push(textElem);\n }\n return textElems;\n}, \"drawText\");\nvar drawLabel = /* @__PURE__ */ __name(function(elem, txtObject) {\n function genPoints(x, y, width, height, cut) {\n return x + \",\" + y + \" \" + (x + width) + \",\" + y + \" \" + (x + width) + \",\" + (y + height - cut) + \" \" + (x + width - cut * 1.2) + \",\" + (y + height) + \" \" + x + \",\" + (y + height);\n }\n __name(genPoints, \"genPoints\");\n const polygon = elem.append(\"polygon\");\n polygon.attr(\"points\", genPoints(txtObject.x, txtObject.y, txtObject.width, txtObject.height, 7));\n polygon.attr(\"class\", \"labelBox\");\n txtObject.y = txtObject.y + txtObject.height / 2;\n drawText(elem, txtObject);\n return polygon;\n}, \"drawLabel\");\nvar actorCnt = -1;\nvar fixLifeLineHeights = /* @__PURE__ */ __name((diagram2, actors, actorKeys, conf2) => {\n if (!diagram2.select) {\n return;\n }\n actorKeys.forEach((actorKey) => {\n const actor = actors.get(actorKey);\n const actorDOM = diagram2.select(\"#actor\" + actor.actorCnt);\n if (!conf2.mirrorActors && actor.stopy) {\n actorDOM.attr(\"y2\", actor.stopy + actor.height / 2);\n } else if (conf2.mirrorActors) {\n actorDOM.attr(\"y2\", actor.stopy);\n }\n });\n}, \"fixLifeLineHeights\");\nvar drawActorTypeParticipant = /* @__PURE__ */ __name(function(elem, actor, conf2, isFooter) {\n const actorY = isFooter ? actor.stopy : actor.starty;\n const center = actor.x + actor.width / 2;\n const centerY = actorY + actor.height;\n const boxplusLineGroup = elem.append(\"g\").lower();\n var g = boxplusLineGroup;\n if (!isFooter) {\n actorCnt++;\n if (Object.keys(actor.links || {}).length && !conf2.forceMenus) {\n g.attr(\"onclick\", popupMenuToggle(`actor${actorCnt}_popup`)).attr(\"cursor\", \"pointer\");\n }\n g.append(\"line\").attr(\"id\", \"actor\" + actorCnt).attr(\"x1\", center).attr(\"y1\", centerY).attr(\"x2\", center).attr(\"y2\", 2e3).attr(\"class\", \"actor-line 200\").attr(\"stroke-width\", \"0.5px\").attr(\"stroke\", \"#999\").attr(\"name\", actor.name);\n g = boxplusLineGroup.append(\"g\");\n actor.actorCnt = actorCnt;\n if (actor.links != null) {\n g.attr(\"id\", \"root-\" + actorCnt);\n }\n }\n const rect = getNoteRect();\n var cssclass = \"actor\";\n if (actor.properties?.class) {\n cssclass = actor.properties.class;\n } else {\n rect.fill = \"#eaeaea\";\n }\n if (isFooter) {\n cssclass += ` ${BOTTOM_ACTOR_CLASS}`;\n } else {\n cssclass += ` ${TOP_ACTOR_CLASS}`;\n }\n rect.x = actor.x;\n rect.y = actorY;\n rect.width = actor.width;\n rect.height = actor.height;\n rect.class = cssclass;\n rect.rx = 3;\n rect.ry = 3;\n rect.name = actor.name;\n const rectElem = drawRect2(g, rect);\n actor.rectData = rect;\n if (actor.properties?.icon) {\n const iconSrc = actor.properties.icon.trim();\n if (iconSrc.charAt(0) === \"@\") {\n drawEmbeddedImage(g, rect.x + rect.width - 20, rect.y + 10, iconSrc.substr(1));\n } else {\n drawImage(g, rect.x + rect.width - 20, rect.y + 10, iconSrc);\n }\n }\n _drawTextCandidateFunc(conf2, hasKatex(actor.description))(\n actor.description,\n g,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n { class: `actor ${ACTOR_BOX_CLASS}` },\n conf2\n );\n let height = actor.height;\n if (rectElem.node) {\n const bounds2 = rectElem.node().getBBox();\n actor.height = bounds2.height;\n height = bounds2.height;\n }\n return height;\n}, \"drawActorTypeParticipant\");\nvar drawActorTypeActor = /* @__PURE__ */ __name(function(elem, actor, conf2, isFooter) {\n const actorY = isFooter ? actor.stopy : actor.starty;\n const center = actor.x + actor.width / 2;\n const centerY = actorY + 80;\n const line = elem.append(\"g\").lower();\n if (!isFooter) {\n actorCnt++;\n line.append(\"line\").attr(\"id\", \"actor\" + actorCnt).attr(\"x1\", center).attr(\"y1\", centerY).attr(\"x2\", center).attr(\"y2\", 2e3).attr(\"class\", \"actor-line 200\").attr(\"stroke-width\", \"0.5px\").attr(\"stroke\", \"#999\").attr(\"name\", actor.name);\n actor.actorCnt = actorCnt;\n }\n const actElem = elem.append(\"g\");\n let cssClass = ACTOR_MAN_FIGURE_CLASS;\n if (isFooter) {\n cssClass += ` ${BOTTOM_ACTOR_CLASS}`;\n } else {\n cssClass += ` ${TOP_ACTOR_CLASS}`;\n }\n actElem.attr(\"class\", cssClass);\n actElem.attr(\"name\", actor.name);\n const rect = getNoteRect();\n rect.x = actor.x;\n rect.y = actorY;\n rect.fill = \"#eaeaea\";\n rect.width = actor.width;\n rect.height = actor.height;\n rect.class = \"actor\";\n rect.rx = 3;\n rect.ry = 3;\n actElem.append(\"line\").attr(\"id\", \"actor-man-torso\" + actorCnt).attr(\"x1\", center).attr(\"y1\", actorY + 25).attr(\"x2\", center).attr(\"y2\", actorY + 45);\n actElem.append(\"line\").attr(\"id\", \"actor-man-arms\" + actorCnt).attr(\"x1\", center - ACTOR_TYPE_WIDTH / 2).attr(\"y1\", actorY + 33).attr(\"x2\", center + ACTOR_TYPE_WIDTH / 2).attr(\"y2\", actorY + 33);\n actElem.append(\"line\").attr(\"x1\", center - ACTOR_TYPE_WIDTH / 2).attr(\"y1\", actorY + 60).attr(\"x2\", center).attr(\"y2\", actorY + 45);\n actElem.append(\"line\").attr(\"x1\", center).attr(\"y1\", actorY + 45).attr(\"x2\", center + ACTOR_TYPE_WIDTH / 2 - 2).attr(\"y2\", actorY + 60);\n const circle = actElem.append(\"circle\");\n circle.attr(\"cx\", actor.x + actor.width / 2);\n circle.attr(\"cy\", actorY + 10);\n circle.attr(\"r\", 15);\n circle.attr(\"width\", actor.width);\n circle.attr(\"height\", actor.height);\n const bounds2 = actElem.node().getBBox();\n actor.height = bounds2.height;\n _drawTextCandidateFunc(conf2, hasKatex(actor.description))(\n actor.description,\n actElem,\n rect.x,\n rect.y + 35,\n rect.width,\n rect.height,\n { class: `actor ${ACTOR_MAN_FIGURE_CLASS}` },\n conf2\n );\n return actor.height;\n}, \"drawActorTypeActor\");\nvar drawActor = /* @__PURE__ */ __name(async function(elem, actor, conf2, isFooter) {\n switch (actor.type) {\n case \"actor\":\n return await drawActorTypeActor(elem, actor, conf2, isFooter);\n case \"participant\":\n return await drawActorTypeParticipant(elem, actor, conf2, isFooter);\n }\n}, \"drawActor\");\nvar drawBox = /* @__PURE__ */ __name(function(elem, box, conf2) {\n const boxplusTextGroup = elem.append(\"g\");\n const g = boxplusTextGroup;\n drawBackgroundRect2(g, box);\n if (box.name) {\n _drawTextCandidateFunc(conf2)(\n box.name,\n g,\n box.x,\n box.y + (box.textMaxHeight || 0) / 2,\n box.width,\n 0,\n { class: \"text\" },\n conf2\n );\n }\n g.lower();\n}, \"drawBox\");\nvar anchorElement = /* @__PURE__ */ __name(function(elem) {\n return elem.append(\"g\");\n}, \"anchorElement\");\nvar drawActivation = /* @__PURE__ */ __name(function(elem, bounds2, verticalPos, conf2, actorActivations2) {\n const rect = getNoteRect();\n const g = bounds2.anchored;\n rect.x = bounds2.startx;\n rect.y = bounds2.starty;\n rect.class = \"activation\" + actorActivations2 % 3;\n rect.width = bounds2.stopx - bounds2.startx;\n rect.height = verticalPos - bounds2.starty;\n drawRect2(g, rect);\n}, \"drawActivation\");\nvar drawLoop = /* @__PURE__ */ __name(async function(elem, loopModel, labelText, conf2) {\n const {\n boxMargin,\n boxTextMargin,\n labelBoxHeight,\n labelBoxWidth,\n messageFontFamily: fontFamily,\n messageFontSize: fontSize,\n messageFontWeight: fontWeight\n } = conf2;\n const g = elem.append(\"g\");\n const drawLoopLine = /* @__PURE__ */ __name(function(startx, starty, stopx, stopy) {\n return g.append(\"line\").attr(\"x1\", startx).attr(\"y1\", starty).attr(\"x2\", stopx).attr(\"y2\", stopy).attr(\"class\", \"loopLine\");\n }, \"drawLoopLine\");\n drawLoopLine(loopModel.startx, loopModel.starty, loopModel.stopx, loopModel.starty);\n drawLoopLine(loopModel.stopx, loopModel.starty, loopModel.stopx, loopModel.stopy);\n drawLoopLine(loopModel.startx, loopModel.stopy, loopModel.stopx, loopModel.stopy);\n drawLoopLine(loopModel.startx, loopModel.starty, loopModel.startx, loopModel.stopy);\n if (loopModel.sections !== void 0) {\n loopModel.sections.forEach(function(item) {\n drawLoopLine(loopModel.startx, item.y, loopModel.stopx, item.y).style(\n \"stroke-dasharray\",\n \"3, 3\"\n );\n });\n }\n let txt = getTextObj();\n txt.text = labelText;\n txt.x = loopModel.startx;\n txt.y = loopModel.starty;\n txt.fontFamily = fontFamily;\n txt.fontSize = fontSize;\n txt.fontWeight = fontWeight;\n txt.anchor = \"middle\";\n txt.valign = \"middle\";\n txt.tspan = false;\n txt.width = labelBoxWidth || 50;\n txt.height = labelBoxHeight || 20;\n txt.textMargin = boxTextMargin;\n txt.class = \"labelText\";\n drawLabel(g, txt);\n txt = getTextObj2();\n txt.text = loopModel.title;\n txt.x = loopModel.startx + labelBoxWidth / 2 + (loopModel.stopx - loopModel.startx) / 2;\n txt.y = loopModel.starty + boxMargin + boxTextMargin;\n txt.anchor = \"middle\";\n txt.valign = \"middle\";\n txt.textMargin = boxTextMargin;\n txt.class = \"loopText\";\n txt.fontFamily = fontFamily;\n txt.fontSize = fontSize;\n txt.fontWeight = fontWeight;\n txt.wrap = true;\n let textElem = hasKatex(txt.text) ? await drawKatex(g, txt, loopModel) : drawText(g, txt);\n if (loopModel.sectionTitles !== void 0) {\n for (const [idx, item] of Object.entries(loopModel.sectionTitles)) {\n if (item.message) {\n txt.text = item.message;\n txt.x = loopModel.startx + (loopModel.stopx - loopModel.startx) / 2;\n txt.y = loopModel.sections[idx].y + boxMargin + boxTextMargin;\n txt.class = \"loopText\";\n txt.anchor = \"middle\";\n txt.valign = \"middle\";\n txt.tspan = false;\n txt.fontFamily = fontFamily;\n txt.fontSize = fontSize;\n txt.fontWeight = fontWeight;\n txt.wrap = loopModel.wrap;\n if (hasKatex(txt.text)) {\n loopModel.starty = loopModel.sections[idx].y;\n await drawKatex(g, txt, loopModel);\n } else {\n drawText(g, txt);\n }\n let sectionHeight = Math.round(\n textElem.map((te) => (te._groups || te)[0][0].getBBox().height).reduce((acc, curr) => acc + curr)\n );\n loopModel.sections[idx].height += sectionHeight - (boxMargin + boxTextMargin);\n }\n }\n }\n loopModel.height = Math.round(loopModel.stopy - loopModel.starty);\n return g;\n}, \"drawLoop\");\nvar drawBackgroundRect2 = /* @__PURE__ */ __name(function(elem, bounds2) {\n drawBackgroundRect(elem, bounds2);\n}, \"drawBackgroundRect\");\nvar insertDatabaseIcon = /* @__PURE__ */ __name(function(elem) {\n elem.append(\"defs\").append(\"symbol\").attr(\"id\", \"database\").attr(\"fill-rule\", \"evenodd\").attr(\"clip-rule\", \"evenodd\").append(\"path\").attr(\"transform\", \"scale(.5)\").attr(\n \"d\",\n \"M12.258.001l.256.004.255.005.253.008.251.01.249.012.247.015.246.016.242.019.241.02.239.023.236.024.233.027.231.028.229.031.225.032.223.034.22.036.217.038.214.04.211.041.208.043.205.045.201.046.198.048.194.05.191.051.187.053.183.054.18.056.175.057.172.059.168.06.163.061.16.063.155.064.15.066.074.033.073.033.071.034.07.034.069.035.068.035.067.035.066.035.064.036.064.036.062.036.06.036.06.037.058.037.058.037.055.038.055.038.053.038.052.038.051.039.05.039.048.039.047.039.045.04.044.04.043.04.041.04.04.041.039.041.037.041.036.041.034.041.033.042.032.042.03.042.029.042.027.042.026.043.024.043.023.043.021.043.02.043.018.044.017.043.015.044.013.044.012.044.011.045.009.044.007.045.006.045.004.045.002.045.001.045v17l-.001.045-.002.045-.004.045-.006.045-.007.045-.009.044-.011.045-.012.044-.013.044-.015.044-.017.043-.018.044-.02.043-.021.043-.023.043-.024.043-.026.043-.027.042-.029.042-.03.042-.032.042-.033.042-.034.041-.036.041-.037.041-.039.041-.04.041-.041.04-.043.04-.044.04-.045.04-.047.039-.048.039-.05.039-.051.039-.052.038-.053.038-.055.038-.055.038-.058.037-.058.037-.06.037-.06.036-.062.036-.064.036-.064.036-.066.035-.067.035-.068.035-.069.035-.07.034-.071.034-.073.033-.074.033-.15.066-.155.064-.16.063-.163.061-.168.06-.172.059-.175.057-.18.056-.183.054-.187.053-.191.051-.194.05-.198.048-.201.046-.205.045-.208.043-.211.041-.214.04-.217.038-.22.036-.223.034-.225.032-.229.031-.231.028-.233.027-.236.024-.239.023-.241.02-.242.019-.246.016-.247.015-.249.012-.251.01-.253.008-.255.005-.256.004-.258.001-.258-.001-.256-.004-.255-.005-.253-.008-.251-.01-.249-.012-.247-.015-.245-.016-.243-.019-.241-.02-.238-.023-.236-.024-.234-.027-.231-.028-.228-.031-.226-.032-.223-.034-.22-.036-.217-.038-.214-.04-.211-.041-.208-.043-.204-.045-.201-.046-.198-.048-.195-.05-.19-.051-.187-.053-.184-.054-.179-.056-.176-.057-.172-.059-.167-.06-.164-.061-.159-.063-.155-.064-.151-.066-.074-.033-.072-.033-.072-.034-.07-.034-.069-.035-.068-.035-.067-.035-.066-.035-.064-.036-.063-.036-.062-.036-.061-.036-.06-.037-.058-.037-.057-.037-.056-.038-.055-.038-.053-.038-.052-.038-.051-.039-.049-.039-.049-.039-.046-.039-.046-.04-.044-.04-.043-.04-.041-.04-.04-.041-.039-.041-.037-.041-.036-.041-.034-.041-.033-.042-.032-.042-.03-.042-.029-.042-.027-.042-.026-.043-.024-.043-.023-.043-.021-.043-.02-.043-.018-.044-.017-.043-.015-.044-.013-.044-.012-.044-.011-.045-.009-.044-.007-.045-.006-.045-.004-.045-.002-.045-.001-.045v-17l.001-.045.002-.045.004-.045.006-.045.007-.045.009-.044.011-.045.012-.044.013-.044.015-.044.017-.043.018-.044.02-.043.021-.043.023-.043.024-.043.026-.043.027-.042.029-.042.03-.042.032-.042.033-.042.034-.041.036-.041.037-.041.039-.041.04-.041.041-.04.043-.04.044-.04.046-.04.046-.039.049-.039.049-.039.051-.039.052-.038.053-.038.055-.038.056-.038.057-.037.058-.037.06-.037.061-.036.062-.036.063-.036.064-.036.066-.035.067-.035.068-.035.069-.035.07-.034.072-.034.072-.033.074-.033.151-.066.155-.064.159-.063.164-.061.167-.06.172-.059.176-.057.179-.056.184-.054.187-.053.19-.051.195-.05.198-.048.201-.046.204-.045.208-.043.211-.041.214-.04.217-.038.22-.036.223-.034.226-.032.228-.031.231-.028.234-.027.236-.024.238-.023.241-.02.243-.019.245-.016.247-.015.249-.012.251-.01.253-.008.255-.005.256-.004.258-.001.258.001zm-9.258 20.499v.01l.001.021.003.021.004.022.005.021.006.022.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.023.018.024.019.024.021.024.022.025.023.024.024.025.052.049.056.05.061.051.066.051.07.051.075.051.079.052.084.052.088.052.092.052.097.052.102.051.105.052.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.048.144.049.147.047.152.047.155.047.16.045.163.045.167.043.171.043.176.041.178.041.183.039.187.039.19.037.194.035.197.035.202.033.204.031.209.03.212.029.216.027.219.025.222.024.226.021.23.02.233.018.236.016.24.015.243.012.246.01.249.008.253.005.256.004.259.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.021.224-.024.22-.026.216-.027.212-.028.21-.031.205-.031.202-.034.198-.034.194-.036.191-.037.187-.039.183-.04.179-.04.175-.042.172-.043.168-.044.163-.045.16-.046.155-.046.152-.047.148-.048.143-.049.139-.049.136-.05.131-.05.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.053.083-.051.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.05.023-.024.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.023.01-.022.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.127l-.077.055-.08.053-.083.054-.085.053-.087.052-.09.052-.093.051-.095.05-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.045-.118.044-.12.043-.122.042-.124.042-.126.041-.128.04-.13.04-.132.038-.134.038-.135.037-.138.037-.139.035-.142.035-.143.034-.144.033-.147.032-.148.031-.15.03-.151.03-.153.029-.154.027-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.01-.179.008-.179.008-.181.006-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.006-.179-.008-.179-.008-.178-.01-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.027-.153-.029-.151-.03-.15-.03-.148-.031-.146-.032-.145-.033-.143-.034-.141-.035-.14-.035-.137-.037-.136-.037-.134-.038-.132-.038-.13-.04-.128-.04-.126-.041-.124-.042-.122-.042-.12-.044-.117-.043-.116-.045-.113-.045-.112-.046-.109-.047-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.05-.093-.052-.09-.051-.087-.052-.085-.053-.083-.054-.08-.054-.077-.054v4.127zm0-5.654v.011l.001.021.003.021.004.021.005.022.006.022.007.022.009.022.01.022.011.023.012.023.013.023.015.024.016.023.017.024.018.024.019.024.021.024.022.024.023.025.024.024.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.052.11.051.114.051.119.052.123.05.127.051.131.05.135.049.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.044.171.042.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.022.23.02.233.018.236.016.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.012.241-.015.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.048.139-.05.136-.049.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.051.051-.049.023-.025.023-.024.021-.025.02-.024.019-.024.018-.024.017-.024.015-.023.014-.023.013-.024.012-.022.01-.023.01-.023.008-.022.006-.022.006-.022.004-.021.004-.022.001-.021.001-.021v-4.139l-.077.054-.08.054-.083.054-.085.052-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.049-.105.048-.106.047-.109.047-.111.046-.114.045-.115.044-.118.044-.12.044-.122.042-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.035-.143.033-.144.033-.147.033-.148.031-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.025-.161.024-.162.023-.163.022-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.011-.178.009-.179.009-.179.007-.181.007-.182.005-.182.004-.184.003-.184.002h-.37l-.184-.002-.184-.003-.182-.004-.182-.005-.181-.007-.179-.007-.179-.009-.178-.009-.176-.011-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.022-.162-.023-.161-.024-.159-.025-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.031-.146-.033-.145-.033-.143-.033-.141-.035-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.04-.126-.041-.124-.042-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.047-.105-.048-.102-.049-.1-.049-.097-.05-.095-.051-.093-.051-.09-.051-.087-.053-.085-.052-.083-.054-.08-.054-.077-.054v4.139zm0-5.666v.011l.001.02.003.022.004.021.005.022.006.021.007.022.009.023.01.022.011.023.012.023.013.023.015.023.016.024.017.024.018.023.019.024.021.025.022.024.023.024.024.025.052.05.056.05.061.05.066.051.07.051.075.052.079.051.084.052.088.052.092.052.097.052.102.052.105.051.11.052.114.051.119.051.123.051.127.05.131.05.135.05.139.049.144.048.147.048.152.047.155.046.16.045.163.045.167.043.171.043.176.042.178.04.183.04.187.038.19.037.194.036.197.034.202.033.204.032.209.03.212.028.216.027.219.025.222.024.226.021.23.02.233.018.236.017.24.014.243.012.246.01.249.008.253.006.256.003.259.001.26-.001.257-.003.254-.006.25-.008.247-.01.244-.013.241-.014.237-.016.233-.018.231-.02.226-.022.224-.024.22-.025.216-.027.212-.029.21-.03.205-.032.202-.033.198-.035.194-.036.191-.037.187-.039.183-.039.179-.041.175-.042.172-.043.168-.044.163-.045.16-.045.155-.047.152-.047.148-.048.143-.049.139-.049.136-.049.131-.051.126-.05.123-.051.118-.052.114-.051.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.052.07-.051.065-.051.06-.051.056-.05.051-.049.023-.025.023-.025.021-.024.02-.024.019-.024.018-.024.017-.024.015-.023.014-.024.013-.023.012-.023.01-.022.01-.023.008-.022.006-.022.006-.022.004-.022.004-.021.001-.021.001-.021v-4.153l-.077.054-.08.054-.083.053-.085.053-.087.053-.09.051-.093.051-.095.051-.097.05-.1.049-.102.048-.105.048-.106.048-.109.046-.111.046-.114.046-.115.044-.118.044-.12.043-.122.043-.124.042-.126.041-.128.04-.13.039-.132.039-.134.038-.135.037-.138.036-.139.036-.142.034-.143.034-.144.033-.147.032-.148.032-.15.03-.151.03-.153.028-.154.028-.156.027-.158.026-.159.024-.161.024-.162.023-.163.023-.165.021-.166.02-.167.019-.169.018-.169.017-.171.016-.173.015-.173.014-.175.013-.175.012-.177.01-.178.01-.179.009-.179.007-.181.006-.182.006-.182.004-.184.003-.184.001-.185.001-.185-.001-.184-.001-.184-.003-.182-.004-.182-.006-.181-.006-.179-.007-.179-.009-.178-.01-.176-.01-.176-.012-.175-.013-.173-.014-.172-.015-.171-.016-.17-.017-.169-.018-.167-.019-.166-.02-.165-.021-.163-.023-.162-.023-.161-.024-.159-.024-.157-.026-.156-.027-.155-.028-.153-.028-.151-.03-.15-.03-.148-.032-.146-.032-.145-.033-.143-.034-.141-.034-.14-.036-.137-.036-.136-.037-.134-.038-.132-.039-.13-.039-.128-.041-.126-.041-.124-.041-.122-.043-.12-.043-.117-.044-.116-.044-.113-.046-.112-.046-.109-.046-.106-.048-.105-.048-.102-.048-.1-.05-.097-.049-.095-.051-.093-.051-.09-.052-.087-.052-.085-.053-.083-.053-.08-.054-.077-.054v4.153zm8.74-8.179l-.257.004-.254.005-.25.008-.247.011-.244.012-.241.014-.237.016-.233.018-.231.021-.226.022-.224.023-.22.026-.216.027-.212.028-.21.031-.205.032-.202.033-.198.034-.194.036-.191.038-.187.038-.183.04-.179.041-.175.042-.172.043-.168.043-.163.045-.16.046-.155.046-.152.048-.148.048-.143.048-.139.049-.136.05-.131.05-.126.051-.123.051-.118.051-.114.052-.11.052-.106.052-.101.052-.096.052-.092.052-.088.052-.083.052-.079.052-.074.051-.07.052-.065.051-.06.05-.056.05-.051.05-.023.025-.023.024-.021.024-.02.025-.019.024-.018.024-.017.023-.015.024-.014.023-.013.023-.012.023-.01.023-.01.022-.008.022-.006.023-.006.021-.004.022-.004.021-.001.021-.001.021.001.021.001.021.004.021.004.022.006.021.006.023.008.022.01.022.01.023.012.023.013.023.014.023.015.024.017.023.018.024.019.024.02.025.021.024.023.024.023.025.051.05.056.05.06.05.065.051.07.052.074.051.079.052.083.052.088.052.092.052.096.052.101.052.106.052.11.052.114.052.118.051.123.051.126.051.131.05.136.05.139.049.143.048.148.048.152.048.155.046.16.046.163.045.168.043.172.043.175.042.179.041.183.04.187.038.191.038.194.036.198.034.202.033.205.032.21.031.212.028.216.027.22.026.224.023.226.022.231.021.233.018.237.016.241.014.244.012.247.011.25.008.254.005.257.004.26.001.26-.001.257-.004.254-.005.25-.008.247-.011.244-.012.241-.014.237-.016.233-.018.231-.021.226-.022.224-.023.22-.026.216-.027.212-.028.21-.031.205-.032.202-.033.198-.034.194-.036.191-.038.187-.038.183-.04.179-.041.175-.042.172-.043.168-.043.163-.045.16-.046.155-.046.152-.048.148-.048.143-.048.139-.049.136-.05.131-.05.126-.051.123-.051.118-.051.114-.052.11-.052.106-.052.101-.052.096-.052.092-.052.088-.052.083-.052.079-.052.074-.051.07-.052.065-.051.06-.05.056-.05.051-.05.023-.025.023-.024.021-.024.02-.025.019-.024.018-.024.017-.023.015-.024.014-.023.013-.023.012-.023.01-.023.01-.022.008-.022.006-.023.006-.021.004-.022.004-.021.001-.021.001-.021-.001-.021-.001-.021-.004-.021-.004-.022-.006-.021-.006-.023-.008-.022-.01-.022-.01-.023-.012-.023-.013-.023-.014-.023-.015-.024-.017-.023-.018-.024-.019-.024-.02-.025-.021-.024-.023-.024-.023-.025-.051-.05-.056-.05-.06-.05-.065-.051-.07-.052-.074-.051-.079-.052-.083-.052-.088-.052-.092-.052-.096-.052-.101-.052-.106-.052-.11-.052-.114-.052-.118-.051-.123-.051-.126-.051-.131-.05-.136-.05-.139-.049-.143-.048-.148-.048-.152-.048-.155-.046-.16-.046-.163-.045-.168-.043-.172-.043-.175-.042-.179-.041-.183-.04-.187-.038-.191-.038-.194-.036-.198-.034-.202-.033-.205-.032-.21-.031-.212-.028-.216-.027-.22-.026-.224-.023-.226-.022-.231-.021-.233-.018-.237-.016-.241-.014-.244-.012-.247-.011-.25-.008-.254-.005-.257-.004-.26-.001-.26.001z\"\n );\n}, \"insertDatabaseIcon\");\nvar insertComputerIcon = /* @__PURE__ */ __name(function(elem) {\n elem.append(\"defs\").append(\"symbol\").attr(\"id\", \"computer\").attr(\"width\", \"24\").attr(\"height\", \"24\").append(\"path\").attr(\"transform\", \"scale(.5)\").attr(\n \"d\",\n \"M2 2v13h20v-13h-20zm18 11h-16v-9h16v9zm-10.228 6l.466-1h3.524l.467 1h-4.457zm14.228 3h-24l2-6h2.104l-1.33 4h18.45l-1.297-4h2.073l2 6zm-5-10h-14v-7h14v7z\"\n );\n}, \"insertComputerIcon\");\nvar insertClockIcon = /* @__PURE__ */ __name(function(elem) {\n elem.append(\"defs\").append(\"symbol\").attr(\"id\", \"clock\").attr(\"width\", \"24\").attr(\"height\", \"24\").append(\"path\").attr(\"transform\", \"scale(.5)\").attr(\n \"d\",\n \"M12 2c5.514 0 10 4.486 10 10s-4.486 10-10 10-10-4.486-10-10 4.486-10 10-10zm0-2c-6.627 0-12 5.373-12 12s5.373 12 12 12 12-5.373 12-12-5.373-12-12-12zm5.848 12.459c.202.038.202.333.001.372-1.907.361-6.045 1.111-6.547 1.111-.719 0-1.301-.582-1.301-1.301 0-.512.77-5.447 1.125-7.445.034-.192.312-.181.343.014l.985 6.238 5.394 1.011z\"\n );\n}, \"insertClockIcon\");\nvar insertArrowHead = /* @__PURE__ */ __name(function(elem) {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"arrowhead\").attr(\"refX\", 7.9).attr(\"refY\", 5).attr(\"markerUnits\", \"userSpaceOnUse\").attr(\"markerWidth\", 12).attr(\"markerHeight\", 12).attr(\"orient\", \"auto-start-reverse\").append(\"path\").attr(\"d\", \"M -1 0 L 10 5 L 0 10 z\");\n}, \"insertArrowHead\");\nvar insertArrowFilledHead = /* @__PURE__ */ __name(function(elem) {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"filled-head\").attr(\"refX\", 15.5).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L14,7 L9,1 Z\");\n}, \"insertArrowFilledHead\");\nvar insertSequenceNumber = /* @__PURE__ */ __name(function(elem) {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"sequencenumber\").attr(\"refX\", 15).attr(\"refY\", 15).attr(\"markerWidth\", 60).attr(\"markerHeight\", 40).attr(\"orient\", \"auto\").append(\"circle\").attr(\"cx\", 15).attr(\"cy\", 15).attr(\"r\", 6);\n}, \"insertSequenceNumber\");\nvar insertArrowCrossHead = /* @__PURE__ */ __name(function(elem) {\n const defs = elem.append(\"defs\");\n const marker = defs.append(\"marker\").attr(\"id\", \"crosshead\").attr(\"markerWidth\", 15).attr(\"markerHeight\", 8).attr(\"orient\", \"auto\").attr(\"refX\", 4).attr(\"refY\", 4.5);\n marker.append(\"path\").attr(\"fill\", \"none\").attr(\"stroke\", \"#000000\").style(\"stroke-dasharray\", \"0, 0\").attr(\"stroke-width\", \"1pt\").attr(\"d\", \"M 1,2 L 6,7 M 6,2 L 1,7\");\n}, \"insertArrowCrossHead\");\nvar getTextObj2 = /* @__PURE__ */ __name(function() {\n return {\n x: 0,\n y: 0,\n fill: void 0,\n anchor: void 0,\n style: \"#666\",\n width: void 0,\n height: void 0,\n textMargin: 0,\n rx: 0,\n ry: 0,\n tspan: true,\n valign: void 0\n };\n}, \"getTextObj\");\nvar getNoteRect2 = /* @__PURE__ */ __name(function() {\n return {\n x: 0,\n y: 0,\n fill: \"#EDF2AE\",\n stroke: \"#666\",\n width: 100,\n anchor: \"start\",\n height: 100,\n rx: 0,\n ry: 0\n };\n}, \"getNoteRect\");\nvar _drawTextCandidateFunc = /* @__PURE__ */ function() {\n function byText(content, g, x, y, width, height, textAttrs) {\n const text = g.append(\"text\").attr(\"x\", x + width / 2).attr(\"y\", y + height / 2 + 5).style(\"text-anchor\", \"middle\").text(content);\n _setTextAttrs(text, textAttrs);\n }\n __name(byText, \"byText\");\n function byTspan(content, g, x, y, width, height, textAttrs, conf2) {\n const { actorFontSize, actorFontFamily, actorFontWeight } = conf2;\n const [_actorFontSize, _actorFontSizePx] = parseFontSize(actorFontSize);\n const lines = content.split(common_default.lineBreakRegex);\n for (let i = 0; i < lines.length; i++) {\n const dy = i * _actorFontSize - _actorFontSize * (lines.length - 1) / 2;\n const text = g.append(\"text\").attr(\"x\", x + width / 2).attr(\"y\", y).style(\"text-anchor\", \"middle\").style(\"font-size\", _actorFontSizePx).style(\"font-weight\", actorFontWeight).style(\"font-family\", actorFontFamily);\n text.append(\"tspan\").attr(\"x\", x + width / 2).attr(\"dy\", dy).text(lines[i]);\n text.attr(\"y\", y + height / 2).attr(\"dominant-baseline\", \"central\").attr(\"alignment-baseline\", \"central\");\n _setTextAttrs(text, textAttrs);\n }\n }\n __name(byTspan, \"byTspan\");\n function byFo(content, g, x, y, width, height, textAttrs, conf2) {\n const s = g.append(\"switch\");\n const f = s.append(\"foreignObject\").attr(\"x\", x).attr(\"y\", y).attr(\"width\", width).attr(\"height\", height);\n const text = f.append(\"xhtml:div\").style(\"display\", \"table\").style(\"height\", \"100%\").style(\"width\", \"100%\");\n text.append(\"div\").style(\"display\", \"table-cell\").style(\"text-align\", \"center\").style(\"vertical-align\", \"middle\").text(content);\n byTspan(content, s, x, y, width, height, textAttrs, conf2);\n _setTextAttrs(text, textAttrs);\n }\n __name(byFo, \"byFo\");\n async function byKatex(content, g, x, y, width, height, textAttrs, conf2) {\n const dim = await calculateMathMLDimensions(content, getConfig());\n const s = g.append(\"switch\");\n const f = s.append(\"foreignObject\").attr(\"x\", x + width / 2 - dim.width / 2).attr(\"y\", y + height / 2 - dim.height / 2).attr(\"width\", dim.width).attr(\"height\", dim.height);\n const text = f.append(\"xhtml:div\").style(\"height\", \"100%\").style(\"width\", \"100%\");\n text.append(\"div\").style(\"text-align\", \"center\").style(\"vertical-align\", \"middle\").html(await renderKatex(content, getConfig()));\n byTspan(content, s, x, y, width, height, textAttrs, conf2);\n _setTextAttrs(text, textAttrs);\n }\n __name(byKatex, \"byKatex\");\n function _setTextAttrs(toText, fromTextAttrsDict) {\n for (const key in fromTextAttrsDict) {\n if (fromTextAttrsDict.hasOwnProperty(key)) {\n toText.attr(key, fromTextAttrsDict[key]);\n }\n }\n }\n __name(_setTextAttrs, \"_setTextAttrs\");\n return function(conf2, hasKatex2 = false) {\n if (hasKatex2) {\n return byKatex;\n }\n return conf2.textPlacement === \"fo\" ? byFo : conf2.textPlacement === \"old\" ? byText : byTspan;\n };\n}();\nvar _drawMenuItemTextCandidateFunc = /* @__PURE__ */ function() {\n function byText(content, g, x, y, width, height, textAttrs) {\n const text = g.append(\"text\").attr(\"x\", x).attr(\"y\", y).style(\"text-anchor\", \"start\").text(content);\n _setTextAttrs(text, textAttrs);\n }\n __name(byText, \"byText\");\n function byTspan(content, g, x, y, width, height, textAttrs, conf2) {\n const { actorFontSize, actorFontFamily, actorFontWeight } = conf2;\n const lines = content.split(common_default.lineBreakRegex);\n for (let i = 0; i < lines.length; i++) {\n const dy = i * actorFontSize - actorFontSize * (lines.length - 1) / 2;\n const text = g.append(\"text\").attr(\"x\", x).attr(\"y\", y).style(\"text-anchor\", \"start\").style(\"font-size\", actorFontSize).style(\"font-weight\", actorFontWeight).style(\"font-family\", actorFontFamily);\n text.append(\"tspan\").attr(\"x\", x).attr(\"dy\", dy).text(lines[i]);\n text.attr(\"y\", y + height / 2).attr(\"dominant-baseline\", \"central\").attr(\"alignment-baseline\", \"central\");\n _setTextAttrs(text, textAttrs);\n }\n }\n __name(byTspan, \"byTspan\");\n function byFo(content, g, x, y, width, height, textAttrs, conf2) {\n const s = g.append(\"switch\");\n const f = s.append(\"foreignObject\").attr(\"x\", x).attr(\"y\", y).attr(\"width\", width).attr(\"height\", height);\n const text = f.append(\"xhtml:div\").style(\"display\", \"table\").style(\"height\", \"100%\").style(\"width\", \"100%\");\n text.append(\"div\").style(\"display\", \"table-cell\").style(\"text-align\", \"center\").style(\"vertical-align\", \"middle\").text(content);\n byTspan(content, s, x, y, width, height, textAttrs, conf2);\n _setTextAttrs(text, textAttrs);\n }\n __name(byFo, \"byFo\");\n function _setTextAttrs(toText, fromTextAttrsDict) {\n for (const key in fromTextAttrsDict) {\n if (fromTextAttrsDict.hasOwnProperty(key)) {\n toText.attr(key, fromTextAttrsDict[key]);\n }\n }\n }\n __name(_setTextAttrs, \"_setTextAttrs\");\n return function(conf2) {\n return conf2.textPlacement === \"fo\" ? byFo : conf2.textPlacement === \"old\" ? byText : byTspan;\n };\n}();\nvar svgDraw_default = {\n drawRect: drawRect2,\n drawText,\n drawLabel,\n drawActor,\n drawBox,\n drawPopup,\n anchorElement,\n drawActivation,\n drawLoop,\n drawBackgroundRect: drawBackgroundRect2,\n insertArrowHead,\n insertArrowFilledHead,\n insertSequenceNumber,\n insertArrowCrossHead,\n insertDatabaseIcon,\n insertComputerIcon,\n insertClockIcon,\n getTextObj: getTextObj2,\n getNoteRect: getNoteRect2,\n fixLifeLineHeights,\n sanitizeUrl\n};\n\n// src/diagrams/sequence/sequenceRenderer.ts\nvar conf = {};\nvar bounds = {\n data: {\n startx: void 0,\n stopx: void 0,\n starty: void 0,\n stopy: void 0\n },\n verticalPos: 0,\n sequenceItems: [],\n activations: [],\n models: {\n getHeight: /* @__PURE__ */ __name(function() {\n return Math.max.apply(\n null,\n this.actors.length === 0 ? [0] : this.actors.map((actor) => actor.height || 0)\n ) + (this.loops.length === 0 ? 0 : this.loops.map((it) => it.height || 0).reduce((acc, h) => acc + h)) + (this.messages.length === 0 ? 0 : this.messages.map((it) => it.height || 0).reduce((acc, h) => acc + h)) + (this.notes.length === 0 ? 0 : this.notes.map((it) => it.height || 0).reduce((acc, h) => acc + h));\n }, \"getHeight\"),\n clear: /* @__PURE__ */ __name(function() {\n this.actors = [];\n this.boxes = [];\n this.loops = [];\n this.messages = [];\n this.notes = [];\n }, \"clear\"),\n addBox: /* @__PURE__ */ __name(function(boxModel) {\n this.boxes.push(boxModel);\n }, \"addBox\"),\n addActor: /* @__PURE__ */ __name(function(actorModel) {\n this.actors.push(actorModel);\n }, \"addActor\"),\n addLoop: /* @__PURE__ */ __name(function(loopModel) {\n this.loops.push(loopModel);\n }, \"addLoop\"),\n addMessage: /* @__PURE__ */ __name(function(msgModel) {\n this.messages.push(msgModel);\n }, \"addMessage\"),\n addNote: /* @__PURE__ */ __name(function(noteModel) {\n this.notes.push(noteModel);\n }, \"addNote\"),\n lastActor: /* @__PURE__ */ __name(function() {\n return this.actors[this.actors.length - 1];\n }, \"lastActor\"),\n lastLoop: /* @__PURE__ */ __name(function() {\n return this.loops[this.loops.length - 1];\n }, \"lastLoop\"),\n lastMessage: /* @__PURE__ */ __name(function() {\n return this.messages[this.messages.length - 1];\n }, \"lastMessage\"),\n lastNote: /* @__PURE__ */ __name(function() {\n return this.notes[this.notes.length - 1];\n }, \"lastNote\"),\n actors: [],\n boxes: [],\n loops: [],\n messages: [],\n notes: []\n },\n init: /* @__PURE__ */ __name(function() {\n this.sequenceItems = [];\n this.activations = [];\n this.models.clear();\n this.data = {\n startx: void 0,\n stopx: void 0,\n starty: void 0,\n stopy: void 0\n };\n this.verticalPos = 0;\n setConf(getConfig2());\n }, \"init\"),\n updateVal: /* @__PURE__ */ __name(function(obj, key, val, fun) {\n if (obj[key] === void 0) {\n obj[key] = val;\n } else {\n obj[key] = fun(val, obj[key]);\n }\n }, \"updateVal\"),\n updateBounds: /* @__PURE__ */ __name(function(startx, starty, stopx, stopy) {\n const _self = this;\n let cnt = 0;\n function updateFn(type) {\n return /* @__PURE__ */ __name(function updateItemBounds(item) {\n cnt++;\n const n = _self.sequenceItems.length - cnt + 1;\n _self.updateVal(item, \"starty\", starty - n * conf.boxMargin, Math.min);\n _self.updateVal(item, \"stopy\", stopy + n * conf.boxMargin, Math.max);\n _self.updateVal(bounds.data, \"startx\", startx - n * conf.boxMargin, Math.min);\n _self.updateVal(bounds.data, \"stopx\", stopx + n * conf.boxMargin, Math.max);\n if (!(type === \"activation\")) {\n _self.updateVal(item, \"startx\", startx - n * conf.boxMargin, Math.min);\n _self.updateVal(item, \"stopx\", stopx + n * conf.boxMargin, Math.max);\n _self.updateVal(bounds.data, \"starty\", starty - n * conf.boxMargin, Math.min);\n _self.updateVal(bounds.data, \"stopy\", stopy + n * conf.boxMargin, Math.max);\n }\n }, \"updateItemBounds\");\n }\n __name(updateFn, \"updateFn\");\n this.sequenceItems.forEach(updateFn());\n this.activations.forEach(updateFn(\"activation\"));\n }, \"updateBounds\"),\n insert: /* @__PURE__ */ __name(function(startx, starty, stopx, stopy) {\n const _startx = common_default.getMin(startx, stopx);\n const _stopx = common_default.getMax(startx, stopx);\n const _starty = common_default.getMin(starty, stopy);\n const _stopy = common_default.getMax(starty, stopy);\n this.updateVal(bounds.data, \"startx\", _startx, Math.min);\n this.updateVal(bounds.data, \"starty\", _starty, Math.min);\n this.updateVal(bounds.data, \"stopx\", _stopx, Math.max);\n this.updateVal(bounds.data, \"stopy\", _stopy, Math.max);\n this.updateBounds(_startx, _starty, _stopx, _stopy);\n }, \"insert\"),\n newActivation: /* @__PURE__ */ __name(function(message, diagram2, actors) {\n const actorRect = actors.get(message.from);\n const stackedSize = actorActivations(message.from).length || 0;\n const x = actorRect.x + actorRect.width / 2 + (stackedSize - 1) * conf.activationWidth / 2;\n this.activations.push({\n startx: x,\n starty: this.verticalPos + 2,\n stopx: x + conf.activationWidth,\n stopy: void 0,\n actor: message.from,\n anchored: svgDraw_default.anchorElement(diagram2)\n });\n }, \"newActivation\"),\n endActivation: /* @__PURE__ */ __name(function(message) {\n const lastActorActivationIdx = this.activations.map(function(activation) {\n return activation.actor;\n }).lastIndexOf(message.from);\n return this.activations.splice(lastActorActivationIdx, 1)[0];\n }, \"endActivation\"),\n createLoop: /* @__PURE__ */ __name(function(title = { message: void 0, wrap: false, width: void 0 }, fill) {\n return {\n startx: void 0,\n starty: this.verticalPos,\n stopx: void 0,\n stopy: void 0,\n title: title.message,\n wrap: title.wrap,\n width: title.width,\n height: 0,\n fill\n };\n }, \"createLoop\"),\n newLoop: /* @__PURE__ */ __name(function(title = { message: void 0, wrap: false, width: void 0 }, fill) {\n this.sequenceItems.push(this.createLoop(title, fill));\n }, \"newLoop\"),\n endLoop: /* @__PURE__ */ __name(function() {\n return this.sequenceItems.pop();\n }, \"endLoop\"),\n isLoopOverlap: /* @__PURE__ */ __name(function() {\n return this.sequenceItems.length ? this.sequenceItems[this.sequenceItems.length - 1].overlap : false;\n }, \"isLoopOverlap\"),\n addSectionToLoop: /* @__PURE__ */ __name(function(message) {\n const loop = this.sequenceItems.pop();\n loop.sections = loop.sections || [];\n loop.sectionTitles = loop.sectionTitles || [];\n loop.sections.push({ y: bounds.getVerticalPos(), height: 0 });\n loop.sectionTitles.push(message);\n this.sequenceItems.push(loop);\n }, \"addSectionToLoop\"),\n saveVerticalPos: /* @__PURE__ */ __name(function() {\n if (this.isLoopOverlap()) {\n this.savedVerticalPos = this.verticalPos;\n }\n }, \"saveVerticalPos\"),\n resetVerticalPos: /* @__PURE__ */ __name(function() {\n if (this.isLoopOverlap()) {\n this.verticalPos = this.savedVerticalPos;\n }\n }, \"resetVerticalPos\"),\n bumpVerticalPos: /* @__PURE__ */ __name(function(bump) {\n this.verticalPos = this.verticalPos + bump;\n this.data.stopy = common_default.getMax(this.data.stopy, this.verticalPos);\n }, \"bumpVerticalPos\"),\n getVerticalPos: /* @__PURE__ */ __name(function() {\n return this.verticalPos;\n }, \"getVerticalPos\"),\n getBounds: /* @__PURE__ */ __name(function() {\n return { bounds: this.data, models: this.models };\n }, \"getBounds\")\n};\nvar drawNote = /* @__PURE__ */ __name(async function(elem, noteModel) {\n bounds.bumpVerticalPos(conf.boxMargin);\n noteModel.height = conf.boxMargin;\n noteModel.starty = bounds.getVerticalPos();\n const rect = getNoteRect();\n rect.x = noteModel.startx;\n rect.y = noteModel.starty;\n rect.width = noteModel.width || conf.width;\n rect.class = \"note\";\n const g = elem.append(\"g\");\n const rectElem = svgDraw_default.drawRect(g, rect);\n const textObj = getTextObj();\n textObj.x = noteModel.startx;\n textObj.y = noteModel.starty;\n textObj.width = rect.width;\n textObj.dy = \"1em\";\n textObj.text = noteModel.message;\n textObj.class = \"noteText\";\n textObj.fontFamily = conf.noteFontFamily;\n textObj.fontSize = conf.noteFontSize;\n textObj.fontWeight = conf.noteFontWeight;\n textObj.anchor = conf.noteAlign;\n textObj.textMargin = conf.noteMargin;\n textObj.valign = \"center\";\n const textElem = hasKatex(textObj.text) ? await drawKatex(g, textObj) : drawText(g, textObj);\n const textHeight = Math.round(\n textElem.map((te) => (te._groups || te)[0][0].getBBox().height).reduce((acc, curr) => acc + curr)\n );\n rectElem.attr(\"height\", textHeight + 2 * conf.noteMargin);\n noteModel.height += textHeight + 2 * conf.noteMargin;\n bounds.bumpVerticalPos(textHeight + 2 * conf.noteMargin);\n noteModel.stopy = noteModel.starty + textHeight + 2 * conf.noteMargin;\n noteModel.stopx = noteModel.startx + rect.width;\n bounds.insert(noteModel.startx, noteModel.starty, noteModel.stopx, noteModel.stopy);\n bounds.models.addNote(noteModel);\n}, \"drawNote\");\nvar messageFont = /* @__PURE__ */ __name((cnf) => {\n return {\n fontFamily: cnf.messageFontFamily,\n fontSize: cnf.messageFontSize,\n fontWeight: cnf.messageFontWeight\n };\n}, \"messageFont\");\nvar noteFont = /* @__PURE__ */ __name((cnf) => {\n return {\n fontFamily: cnf.noteFontFamily,\n fontSize: cnf.noteFontSize,\n fontWeight: cnf.noteFontWeight\n };\n}, \"noteFont\");\nvar actorFont = /* @__PURE__ */ __name((cnf) => {\n return {\n fontFamily: cnf.actorFontFamily,\n fontSize: cnf.actorFontSize,\n fontWeight: cnf.actorFontWeight\n };\n}, \"actorFont\");\nasync function boundMessage(_diagram, msgModel) {\n bounds.bumpVerticalPos(10);\n const { startx, stopx, message } = msgModel;\n const lines = common_default.splitBreaks(message).length;\n const isKatexMsg = hasKatex(message);\n const textDims = isKatexMsg ? await calculateMathMLDimensions(message, getConfig2()) : utils_default.calculateTextDimensions(message, messageFont(conf));\n if (!isKatexMsg) {\n const lineHeight = textDims.height / lines;\n msgModel.height += lineHeight;\n bounds.bumpVerticalPos(lineHeight);\n }\n let lineStartY;\n let totalOffset = textDims.height - 10;\n const textWidth = textDims.width;\n if (startx === stopx) {\n lineStartY = bounds.getVerticalPos() + totalOffset;\n if (!conf.rightAngles) {\n totalOffset += conf.boxMargin;\n lineStartY = bounds.getVerticalPos() + totalOffset;\n }\n totalOffset += 30;\n const dx = common_default.getMax(textWidth / 2, conf.width / 2);\n bounds.insert(\n startx - dx,\n bounds.getVerticalPos() - 10 + totalOffset,\n stopx + dx,\n bounds.getVerticalPos() + 30 + totalOffset\n );\n } else {\n totalOffset += conf.boxMargin;\n lineStartY = bounds.getVerticalPos() + totalOffset;\n bounds.insert(startx, lineStartY - 10, stopx, lineStartY);\n }\n bounds.bumpVerticalPos(totalOffset);\n msgModel.height += totalOffset;\n msgModel.stopy = msgModel.starty + msgModel.height;\n bounds.insert(msgModel.fromBounds, msgModel.starty, msgModel.toBounds, msgModel.stopy);\n return lineStartY;\n}\n__name(boundMessage, \"boundMessage\");\nvar drawMessage = /* @__PURE__ */ __name(async function(diagram2, msgModel, lineStartY, diagObj) {\n const { startx, stopx, starty, message, type, sequenceIndex, sequenceVisible } = msgModel;\n const textDims = utils_default.calculateTextDimensions(message, messageFont(conf));\n const textObj = getTextObj();\n textObj.x = startx;\n textObj.y = starty + 10;\n textObj.width = stopx - startx;\n textObj.class = \"messageText\";\n textObj.dy = \"1em\";\n textObj.text = message;\n textObj.fontFamily = conf.messageFontFamily;\n textObj.fontSize = conf.messageFontSize;\n textObj.fontWeight = conf.messageFontWeight;\n textObj.anchor = conf.messageAlign;\n textObj.valign = \"center\";\n textObj.textMargin = conf.wrapPadding;\n textObj.tspan = false;\n if (hasKatex(textObj.text)) {\n await drawKatex(diagram2, textObj, { startx, stopx, starty: lineStartY });\n } else {\n drawText(diagram2, textObj);\n }\n const textWidth = textDims.width;\n let line;\n if (startx === stopx) {\n if (conf.rightAngles) {\n line = diagram2.append(\"path\").attr(\n \"d\",\n `M ${startx},${lineStartY} H ${startx + common_default.getMax(conf.width / 2, textWidth / 2)} V ${lineStartY + 25} H ${startx}`\n );\n } else {\n line = diagram2.append(\"path\").attr(\n \"d\",\n \"M \" + startx + \",\" + lineStartY + \" C \" + (startx + 60) + \",\" + (lineStartY - 10) + \" \" + (startx + 60) + \",\" + (lineStartY + 30) + \" \" + startx + \",\" + (lineStartY + 20)\n );\n }\n } else {\n line = diagram2.append(\"line\");\n line.attr(\"x1\", startx);\n line.attr(\"y1\", lineStartY);\n line.attr(\"x2\", stopx);\n line.attr(\"y2\", lineStartY);\n }\n if (type === diagObj.db.LINETYPE.DOTTED || type === diagObj.db.LINETYPE.DOTTED_CROSS || type === diagObj.db.LINETYPE.DOTTED_POINT || type === diagObj.db.LINETYPE.DOTTED_OPEN || type === diagObj.db.LINETYPE.BIDIRECTIONAL_DOTTED) {\n line.style(\"stroke-dasharray\", \"3, 3\");\n line.attr(\"class\", \"messageLine1\");\n } else {\n line.attr(\"class\", \"messageLine0\");\n }\n let url = \"\";\n if (conf.arrowMarkerAbsolute) {\n url = window.location.protocol + \"//\" + window.location.host + window.location.pathname + window.location.search;\n url = url.replace(/\\(/g, \"\\\\(\");\n url = url.replace(/\\)/g, \"\\\\)\");\n }\n line.attr(\"stroke-width\", 2);\n line.attr(\"stroke\", \"none\");\n line.style(\"fill\", \"none\");\n if (type === diagObj.db.LINETYPE.SOLID || type === diagObj.db.LINETYPE.DOTTED) {\n line.attr(\"marker-end\", \"url(\" + url + \"#arrowhead)\");\n }\n if (type === diagObj.db.LINETYPE.BIDIRECTIONAL_SOLID || type === diagObj.db.LINETYPE.BIDIRECTIONAL_DOTTED) {\n line.attr(\"marker-start\", \"url(\" + url + \"#arrowhead)\");\n line.attr(\"marker-end\", \"url(\" + url + \"#arrowhead)\");\n }\n if (type === diagObj.db.LINETYPE.SOLID_POINT || type === diagObj.db.LINETYPE.DOTTED_POINT) {\n line.attr(\"marker-end\", \"url(\" + url + \"#filled-head)\");\n }\n if (type === diagObj.db.LINETYPE.SOLID_CROSS || type === diagObj.db.LINETYPE.DOTTED_CROSS) {\n line.attr(\"marker-end\", \"url(\" + url + \"#crosshead)\");\n }\n if (sequenceVisible || conf.showSequenceNumbers) {\n line.attr(\"marker-start\", \"url(\" + url + \"#sequencenumber)\");\n diagram2.append(\"text\").attr(\"x\", startx).attr(\"y\", lineStartY + 4).attr(\"font-family\", \"sans-serif\").attr(\"font-size\", \"12px\").attr(\"text-anchor\", \"middle\").attr(\"class\", \"sequenceNumber\").text(sequenceIndex);\n }\n}, \"drawMessage\");\nvar addActorRenderingData = /* @__PURE__ */ __name(function(diagram2, actors, createdActors, actorKeys, verticalPos, messages, isFooter) {\n let prevWidth = 0;\n let prevMargin = 0;\n let prevBox = void 0;\n let maxHeight = 0;\n for (const actorKey of actorKeys) {\n const actor = actors.get(actorKey);\n const box = actor.box;\n if (prevBox && prevBox != box) {\n if (!isFooter) {\n bounds.models.addBox(prevBox);\n }\n prevMargin += conf.boxMargin + prevBox.margin;\n }\n if (box && box != prevBox) {\n if (!isFooter) {\n box.x = prevWidth + prevMargin;\n box.y = verticalPos;\n }\n prevMargin += box.margin;\n }\n actor.width = actor.width || conf.width;\n actor.height = common_default.getMax(actor.height || conf.height, conf.height);\n actor.margin = actor.margin || conf.actorMargin;\n maxHeight = common_default.getMax(maxHeight, actor.height);\n if (createdActors.get(actor.name)) {\n prevMargin += actor.width / 2;\n }\n actor.x = prevWidth + prevMargin;\n actor.starty = bounds.getVerticalPos();\n bounds.insert(actor.x, verticalPos, actor.x + actor.width, actor.height);\n prevWidth += actor.width + prevMargin;\n if (actor.box) {\n actor.box.width = prevWidth + box.margin - actor.box.x;\n }\n prevMargin = actor.margin;\n prevBox = actor.box;\n bounds.models.addActor(actor);\n }\n if (prevBox && !isFooter) {\n bounds.models.addBox(prevBox);\n }\n bounds.bumpVerticalPos(maxHeight);\n}, \"addActorRenderingData\");\nvar drawActors = /* @__PURE__ */ __name(async function(diagram2, actors, actorKeys, isFooter) {\n if (!isFooter) {\n for (const actorKey of actorKeys) {\n const actor = actors.get(actorKey);\n await svgDraw_default.drawActor(diagram2, actor, conf, false);\n }\n } else {\n let maxHeight = 0;\n bounds.bumpVerticalPos(conf.boxMargin * 2);\n for (const actorKey of actorKeys) {\n const actor = actors.get(actorKey);\n if (!actor.stopy) {\n actor.stopy = bounds.getVerticalPos();\n }\n const height = await svgDraw_default.drawActor(diagram2, actor, conf, true);\n maxHeight = common_default.getMax(maxHeight, height);\n }\n bounds.bumpVerticalPos(maxHeight + conf.boxMargin);\n }\n}, \"drawActors\");\nvar drawActorsPopup = /* @__PURE__ */ __name(function(diagram2, actors, actorKeys, doc) {\n let maxHeight = 0;\n let maxWidth = 0;\n for (const actorKey of actorKeys) {\n const actor = actors.get(actorKey);\n const minMenuWidth = getRequiredPopupWidth(actor);\n const menuDimensions = svgDraw_default.drawPopup(\n diagram2,\n actor,\n minMenuWidth,\n conf,\n conf.forceMenus,\n doc\n );\n if (menuDimensions.height > maxHeight) {\n maxHeight = menuDimensions.height;\n }\n if (menuDimensions.width + actor.x > maxWidth) {\n maxWidth = menuDimensions.width + actor.x;\n }\n }\n return { maxHeight, maxWidth };\n}, \"drawActorsPopup\");\nvar setConf = /* @__PURE__ */ __name(function(cnf) {\n assignWithDepth_default(conf, cnf);\n if (cnf.fontFamily) {\n conf.actorFontFamily = conf.noteFontFamily = conf.messageFontFamily = cnf.fontFamily;\n }\n if (cnf.fontSize) {\n conf.actorFontSize = conf.noteFontSize = conf.messageFontSize = cnf.fontSize;\n }\n if (cnf.fontWeight) {\n conf.actorFontWeight = conf.noteFontWeight = conf.messageFontWeight = cnf.fontWeight;\n }\n}, \"setConf\");\nvar actorActivations = /* @__PURE__ */ __name(function(actor) {\n return bounds.activations.filter(function(activation) {\n return activation.actor === actor;\n });\n}, \"actorActivations\");\nvar activationBounds = /* @__PURE__ */ __name(function(actor, actors) {\n const actorObj = actors.get(actor);\n const activations = actorActivations(actor);\n const left = activations.reduce(\n function(acc, activation) {\n return common_default.getMin(acc, activation.startx);\n },\n actorObj.x + actorObj.width / 2 - 1\n );\n const right = activations.reduce(\n function(acc, activation) {\n return common_default.getMax(acc, activation.stopx);\n },\n actorObj.x + actorObj.width / 2 + 1\n );\n return [left, right];\n}, \"activationBounds\");\nfunction adjustLoopHeightForWrap(loopWidths, msg, preMargin, postMargin, addLoopFn) {\n bounds.bumpVerticalPos(preMargin);\n let heightAdjust = postMargin;\n if (msg.id && msg.message && loopWidths[msg.id]) {\n const loopWidth = loopWidths[msg.id].width;\n const textConf = messageFont(conf);\n msg.message = utils_default.wrapLabel(`[${msg.message}]`, loopWidth - 2 * conf.wrapPadding, textConf);\n msg.width = loopWidth;\n msg.wrap = true;\n const textDims = utils_default.calculateTextDimensions(msg.message, textConf);\n const totalOffset = common_default.getMax(textDims.height, conf.labelBoxHeight);\n heightAdjust = postMargin + totalOffset;\n log.debug(`${totalOffset} - ${msg.message}`);\n }\n addLoopFn(msg);\n bounds.bumpVerticalPos(heightAdjust);\n}\n__name(adjustLoopHeightForWrap, \"adjustLoopHeightForWrap\");\nfunction adjustCreatedDestroyedData(msg, msgModel, lineStartY, index, actors, createdActors, destroyedActors) {\n function receiverAdjustment(actor, adjustment) {\n if (actor.x < actors.get(msg.from).x) {\n bounds.insert(\n msgModel.stopx - adjustment,\n msgModel.starty,\n msgModel.startx,\n msgModel.stopy + actor.height / 2 + conf.noteMargin\n );\n msgModel.stopx = msgModel.stopx + adjustment;\n } else {\n bounds.insert(\n msgModel.startx,\n msgModel.starty,\n msgModel.stopx + adjustment,\n msgModel.stopy + actor.height / 2 + conf.noteMargin\n );\n msgModel.stopx = msgModel.stopx - adjustment;\n }\n }\n __name(receiverAdjustment, \"receiverAdjustment\");\n function senderAdjustment(actor, adjustment) {\n if (actor.x < actors.get(msg.to).x) {\n bounds.insert(\n msgModel.startx - adjustment,\n msgModel.starty,\n msgModel.stopx,\n msgModel.stopy + actor.height / 2 + conf.noteMargin\n );\n msgModel.startx = msgModel.startx + adjustment;\n } else {\n bounds.insert(\n msgModel.stopx,\n msgModel.starty,\n msgModel.startx + adjustment,\n msgModel.stopy + actor.height / 2 + conf.noteMargin\n );\n msgModel.startx = msgModel.startx - adjustment;\n }\n }\n __name(senderAdjustment, \"senderAdjustment\");\n if (createdActors.get(msg.to) == index) {\n const actor = actors.get(msg.to);\n const adjustment = actor.type == \"actor\" ? ACTOR_TYPE_WIDTH / 2 + 3 : actor.width / 2 + 3;\n receiverAdjustment(actor, adjustment);\n actor.starty = lineStartY - actor.height / 2;\n bounds.bumpVerticalPos(actor.height / 2);\n } else if (destroyedActors.get(msg.from) == index) {\n const actor = actors.get(msg.from);\n if (conf.mirrorActors) {\n const adjustment = actor.type == \"actor\" ? ACTOR_TYPE_WIDTH / 2 : actor.width / 2;\n senderAdjustment(actor, adjustment);\n }\n actor.stopy = lineStartY - actor.height / 2;\n bounds.bumpVerticalPos(actor.height / 2);\n } else if (destroyedActors.get(msg.to) == index) {\n const actor = actors.get(msg.to);\n if (conf.mirrorActors) {\n const adjustment = actor.type == \"actor\" ? ACTOR_TYPE_WIDTH / 2 + 3 : actor.width / 2 + 3;\n receiverAdjustment(actor, adjustment);\n }\n actor.stopy = lineStartY - actor.height / 2;\n bounds.bumpVerticalPos(actor.height / 2);\n }\n}\n__name(adjustCreatedDestroyedData, \"adjustCreatedDestroyedData\");\nvar draw = /* @__PURE__ */ __name(async function(_text, id, _version, diagObj) {\n const { securityLevel, sequence } = getConfig2();\n conf = sequence;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select(sandboxElement.nodes()[0].contentDocument.body) : select(\"body\");\n const doc = securityLevel === \"sandbox\" ? sandboxElement.nodes()[0].contentDocument : document;\n bounds.init();\n log.debug(diagObj.db);\n const diagram2 = securityLevel === \"sandbox\" ? root.select(`[id=\"${id}\"]`) : select(`[id=\"${id}\"]`);\n const actors = diagObj.db.getActors();\n const createdActors = diagObj.db.getCreatedActors();\n const destroyedActors = diagObj.db.getDestroyedActors();\n const boxes = diagObj.db.getBoxes();\n let actorKeys = diagObj.db.getActorKeys();\n const messages = diagObj.db.getMessages();\n const title = diagObj.db.getDiagramTitle();\n const hasBoxes = diagObj.db.hasAtLeastOneBox();\n const hasBoxTitles = diagObj.db.hasAtLeastOneBoxWithTitle();\n const maxMessageWidthPerActor = await getMaxMessageWidthPerActor(actors, messages, diagObj);\n conf.height = await calculateActorMargins(actors, maxMessageWidthPerActor, boxes);\n svgDraw_default.insertComputerIcon(diagram2);\n svgDraw_default.insertDatabaseIcon(diagram2);\n svgDraw_default.insertClockIcon(diagram2);\n if (hasBoxes) {\n bounds.bumpVerticalPos(conf.boxMargin);\n if (hasBoxTitles) {\n bounds.bumpVerticalPos(boxes[0].textMaxHeight);\n }\n }\n if (conf.hideUnusedParticipants === true) {\n const newActors = /* @__PURE__ */ new Set();\n messages.forEach((message) => {\n newActors.add(message.from);\n newActors.add(message.to);\n });\n actorKeys = actorKeys.filter((actorKey) => newActors.has(actorKey));\n }\n addActorRenderingData(diagram2, actors, createdActors, actorKeys, 0, messages, false);\n const loopWidths = await calculateLoopBounds(messages, actors, maxMessageWidthPerActor, diagObj);\n svgDraw_default.insertArrowHead(diagram2);\n svgDraw_default.insertArrowCrossHead(diagram2);\n svgDraw_default.insertArrowFilledHead(diagram2);\n svgDraw_default.insertSequenceNumber(diagram2);\n function activeEnd(msg, verticalPos) {\n const activationData = bounds.endActivation(msg);\n if (activationData.starty + 18 > verticalPos) {\n activationData.starty = verticalPos - 6;\n verticalPos += 12;\n }\n svgDraw_default.drawActivation(\n diagram2,\n activationData,\n verticalPos,\n conf,\n actorActivations(msg.from).length\n );\n bounds.insert(activationData.startx, verticalPos - 10, activationData.stopx, verticalPos);\n }\n __name(activeEnd, \"activeEnd\");\n let sequenceIndex = 1;\n let sequenceIndexStep = 1;\n const messagesToDraw = [];\n const backgrounds = [];\n let index = 0;\n for (const msg of messages) {\n let loopModel, noteModel, msgModel;\n switch (msg.type) {\n case diagObj.db.LINETYPE.NOTE:\n bounds.resetVerticalPos();\n noteModel = msg.noteModel;\n await drawNote(diagram2, noteModel);\n break;\n case diagObj.db.LINETYPE.ACTIVE_START:\n bounds.newActivation(msg, diagram2, actors);\n break;\n case diagObj.db.LINETYPE.ACTIVE_END:\n activeEnd(msg, bounds.getVerticalPos());\n break;\n case diagObj.db.LINETYPE.LOOP_START:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin,\n conf.boxMargin + conf.boxTextMargin,\n (message) => bounds.newLoop(message)\n );\n break;\n case diagObj.db.LINETYPE.LOOP_END:\n loopModel = bounds.endLoop();\n await svgDraw_default.drawLoop(diagram2, loopModel, \"loop\", conf);\n bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());\n bounds.models.addLoop(loopModel);\n break;\n case diagObj.db.LINETYPE.RECT_START:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin,\n conf.boxMargin,\n (message) => bounds.newLoop(void 0, message.message)\n );\n break;\n case diagObj.db.LINETYPE.RECT_END:\n loopModel = bounds.endLoop();\n backgrounds.push(loopModel);\n bounds.models.addLoop(loopModel);\n bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());\n break;\n case diagObj.db.LINETYPE.OPT_START:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin,\n conf.boxMargin + conf.boxTextMargin,\n (message) => bounds.newLoop(message)\n );\n break;\n case diagObj.db.LINETYPE.OPT_END:\n loopModel = bounds.endLoop();\n await svgDraw_default.drawLoop(diagram2, loopModel, \"opt\", conf);\n bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());\n bounds.models.addLoop(loopModel);\n break;\n case diagObj.db.LINETYPE.ALT_START:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin,\n conf.boxMargin + conf.boxTextMargin,\n (message) => bounds.newLoop(message)\n );\n break;\n case diagObj.db.LINETYPE.ALT_ELSE:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin + conf.boxTextMargin,\n conf.boxMargin,\n (message) => bounds.addSectionToLoop(message)\n );\n break;\n case diagObj.db.LINETYPE.ALT_END:\n loopModel = bounds.endLoop();\n await svgDraw_default.drawLoop(diagram2, loopModel, \"alt\", conf);\n bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());\n bounds.models.addLoop(loopModel);\n break;\n case diagObj.db.LINETYPE.PAR_START:\n case diagObj.db.LINETYPE.PAR_OVER_START:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin,\n conf.boxMargin + conf.boxTextMargin,\n (message) => bounds.newLoop(message)\n );\n bounds.saveVerticalPos();\n break;\n case diagObj.db.LINETYPE.PAR_AND:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin + conf.boxTextMargin,\n conf.boxMargin,\n (message) => bounds.addSectionToLoop(message)\n );\n break;\n case diagObj.db.LINETYPE.PAR_END:\n loopModel = bounds.endLoop();\n await svgDraw_default.drawLoop(diagram2, loopModel, \"par\", conf);\n bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());\n bounds.models.addLoop(loopModel);\n break;\n case diagObj.db.LINETYPE.AUTONUMBER:\n sequenceIndex = msg.message.start || sequenceIndex;\n sequenceIndexStep = msg.message.step || sequenceIndexStep;\n if (msg.message.visible) {\n diagObj.db.enableSequenceNumbers();\n } else {\n diagObj.db.disableSequenceNumbers();\n }\n break;\n case diagObj.db.LINETYPE.CRITICAL_START:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin,\n conf.boxMargin + conf.boxTextMargin,\n (message) => bounds.newLoop(message)\n );\n break;\n case diagObj.db.LINETYPE.CRITICAL_OPTION:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin + conf.boxTextMargin,\n conf.boxMargin,\n (message) => bounds.addSectionToLoop(message)\n );\n break;\n case diagObj.db.LINETYPE.CRITICAL_END:\n loopModel = bounds.endLoop();\n await svgDraw_default.drawLoop(diagram2, loopModel, \"critical\", conf);\n bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());\n bounds.models.addLoop(loopModel);\n break;\n case diagObj.db.LINETYPE.BREAK_START:\n adjustLoopHeightForWrap(\n loopWidths,\n msg,\n conf.boxMargin,\n conf.boxMargin + conf.boxTextMargin,\n (message) => bounds.newLoop(message)\n );\n break;\n case diagObj.db.LINETYPE.BREAK_END:\n loopModel = bounds.endLoop();\n await svgDraw_default.drawLoop(diagram2, loopModel, \"break\", conf);\n bounds.bumpVerticalPos(loopModel.stopy - bounds.getVerticalPos());\n bounds.models.addLoop(loopModel);\n break;\n default:\n try {\n msgModel = msg.msgModel;\n msgModel.starty = bounds.getVerticalPos();\n msgModel.sequenceIndex = sequenceIndex;\n msgModel.sequenceVisible = diagObj.db.showSequenceNumbers();\n const lineStartY = await boundMessage(diagram2, msgModel);\n adjustCreatedDestroyedData(\n msg,\n msgModel,\n lineStartY,\n index,\n actors,\n createdActors,\n destroyedActors\n );\n messagesToDraw.push({ messageModel: msgModel, lineStartY });\n bounds.models.addMessage(msgModel);\n } catch (e) {\n log.error(\"error while drawing message\", e);\n }\n }\n if ([\n diagObj.db.LINETYPE.SOLID_OPEN,\n diagObj.db.LINETYPE.DOTTED_OPEN,\n diagObj.db.LINETYPE.SOLID,\n diagObj.db.LINETYPE.DOTTED,\n diagObj.db.LINETYPE.SOLID_CROSS,\n diagObj.db.LINETYPE.DOTTED_CROSS,\n diagObj.db.LINETYPE.SOLID_POINT,\n diagObj.db.LINETYPE.DOTTED_POINT,\n diagObj.db.LINETYPE.BIDIRECTIONAL_SOLID,\n diagObj.db.LINETYPE.BIDIRECTIONAL_DOTTED\n ].includes(msg.type)) {\n sequenceIndex = sequenceIndex + sequenceIndexStep;\n }\n index++;\n }\n log.debug(\"createdActors\", createdActors);\n log.debug(\"destroyedActors\", destroyedActors);\n await drawActors(diagram2, actors, actorKeys, false);\n for (const e of messagesToDraw) {\n await drawMessage(diagram2, e.messageModel, e.lineStartY, diagObj);\n }\n if (conf.mirrorActors) {\n await drawActors(diagram2, actors, actorKeys, true);\n }\n backgrounds.forEach((e) => svgDraw_default.drawBackgroundRect(diagram2, e));\n fixLifeLineHeights(diagram2, actors, actorKeys, conf);\n for (const box2 of bounds.models.boxes) {\n box2.height = bounds.getVerticalPos() - box2.y;\n bounds.insert(box2.x, box2.y, box2.x + box2.width, box2.height);\n box2.startx = box2.x;\n box2.starty = box2.y;\n box2.stopx = box2.startx + box2.width;\n box2.stopy = box2.starty + box2.height;\n box2.stroke = \"rgb(0,0,0, 0.5)\";\n svgDraw_default.drawBox(diagram2, box2, conf);\n }\n if (hasBoxes) {\n bounds.bumpVerticalPos(conf.boxMargin);\n }\n const requiredBoxSize = drawActorsPopup(diagram2, actors, actorKeys, doc);\n const { bounds: box } = bounds.getBounds();\n if (box.startx === void 0) {\n box.startx = 0;\n }\n if (box.starty === void 0) {\n box.starty = 0;\n }\n if (box.stopx === void 0) {\n box.stopx = 0;\n }\n if (box.stopy === void 0) {\n box.stopy = 0;\n }\n let boxHeight = box.stopy - box.starty;\n if (boxHeight < requiredBoxSize.maxHeight) {\n boxHeight = requiredBoxSize.maxHeight;\n }\n let height = boxHeight + 2 * conf.diagramMarginY;\n if (conf.mirrorActors) {\n height = height - conf.boxMargin + conf.bottomMarginAdj;\n }\n let boxWidth = box.stopx - box.startx;\n if (boxWidth < requiredBoxSize.maxWidth) {\n boxWidth = requiredBoxSize.maxWidth;\n }\n const width = boxWidth + 2 * conf.diagramMarginX;\n if (title) {\n diagram2.append(\"text\").text(title).attr(\"x\", (box.stopx - box.startx) / 2 - 2 * conf.diagramMarginX).attr(\"y\", -25);\n }\n configureSvgSize(diagram2, height, width, conf.useMaxWidth);\n const extraVertForTitle = title ? 40 : 0;\n diagram2.attr(\n \"viewBox\",\n box.startx - conf.diagramMarginX + \" -\" + (conf.diagramMarginY + extraVertForTitle) + \" \" + width + \" \" + (height + extraVertForTitle)\n );\n log.debug(`models:`, bounds.models);\n}, \"draw\");\nasync function getMaxMessageWidthPerActor(actors, messages, diagObj) {\n const maxMessageWidthPerActor = {};\n for (const msg of messages) {\n if (actors.get(msg.to) && actors.get(msg.from)) {\n const actor = actors.get(msg.to);\n if (msg.placement === diagObj.db.PLACEMENT.LEFTOF && !actor.prevActor) {\n continue;\n }\n if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF && !actor.nextActor) {\n continue;\n }\n const isNote = msg.placement !== void 0;\n const isMessage = !isNote;\n const textFont = isNote ? noteFont(conf) : messageFont(conf);\n const wrappedMessage = msg.wrap ? utils_default.wrapLabel(msg.message, conf.width - 2 * conf.wrapPadding, textFont) : msg.message;\n const messageDimensions = hasKatex(wrappedMessage) ? await calculateMathMLDimensions(msg.message, getConfig2()) : utils_default.calculateTextDimensions(wrappedMessage, textFont);\n const messageWidth = messageDimensions.width + 2 * conf.wrapPadding;\n if (isMessage && msg.from === actor.nextActor) {\n maxMessageWidthPerActor[msg.to] = common_default.getMax(\n maxMessageWidthPerActor[msg.to] || 0,\n messageWidth\n );\n } else if (isMessage && msg.from === actor.prevActor) {\n maxMessageWidthPerActor[msg.from] = common_default.getMax(\n maxMessageWidthPerActor[msg.from] || 0,\n messageWidth\n );\n } else if (isMessage && msg.from === msg.to) {\n maxMessageWidthPerActor[msg.from] = common_default.getMax(\n maxMessageWidthPerActor[msg.from] || 0,\n messageWidth / 2\n );\n maxMessageWidthPerActor[msg.to] = common_default.getMax(\n maxMessageWidthPerActor[msg.to] || 0,\n messageWidth / 2\n );\n } else if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF) {\n maxMessageWidthPerActor[msg.from] = common_default.getMax(\n maxMessageWidthPerActor[msg.from] || 0,\n messageWidth\n );\n } else if (msg.placement === diagObj.db.PLACEMENT.LEFTOF) {\n maxMessageWidthPerActor[actor.prevActor] = common_default.getMax(\n maxMessageWidthPerActor[actor.prevActor] || 0,\n messageWidth\n );\n } else if (msg.placement === diagObj.db.PLACEMENT.OVER) {\n if (actor.prevActor) {\n maxMessageWidthPerActor[actor.prevActor] = common_default.getMax(\n maxMessageWidthPerActor[actor.prevActor] || 0,\n messageWidth / 2\n );\n }\n if (actor.nextActor) {\n maxMessageWidthPerActor[msg.from] = common_default.getMax(\n maxMessageWidthPerActor[msg.from] || 0,\n messageWidth / 2\n );\n }\n }\n }\n }\n log.debug(\"maxMessageWidthPerActor:\", maxMessageWidthPerActor);\n return maxMessageWidthPerActor;\n}\n__name(getMaxMessageWidthPerActor, \"getMaxMessageWidthPerActor\");\nvar getRequiredPopupWidth = /* @__PURE__ */ __name(function(actor) {\n let requiredPopupWidth = 0;\n const textFont = actorFont(conf);\n for (const key in actor.links) {\n const labelDimensions = utils_default.calculateTextDimensions(key, textFont);\n const labelWidth = labelDimensions.width + 2 * conf.wrapPadding + 2 * conf.boxMargin;\n if (requiredPopupWidth < labelWidth) {\n requiredPopupWidth = labelWidth;\n }\n }\n return requiredPopupWidth;\n}, \"getRequiredPopupWidth\");\nasync function calculateActorMargins(actors, actorToMessageWidth, boxes) {\n let maxHeight = 0;\n for (const prop of actors.keys()) {\n const actor = actors.get(prop);\n if (actor.wrap) {\n actor.description = utils_default.wrapLabel(\n actor.description,\n conf.width - 2 * conf.wrapPadding,\n actorFont(conf)\n );\n }\n const actDims = hasKatex(actor.description) ? await calculateMathMLDimensions(actor.description, getConfig2()) : utils_default.calculateTextDimensions(actor.description, actorFont(conf));\n actor.width = actor.wrap ? conf.width : common_default.getMax(conf.width, actDims.width + 2 * conf.wrapPadding);\n actor.height = actor.wrap ? common_default.getMax(actDims.height, conf.height) : conf.height;\n maxHeight = common_default.getMax(maxHeight, actor.height);\n }\n for (const actorKey in actorToMessageWidth) {\n const actor = actors.get(actorKey);\n if (!actor) {\n continue;\n }\n const nextActor = actors.get(actor.nextActor);\n if (!nextActor) {\n const messageWidth2 = actorToMessageWidth[actorKey];\n const actorWidth2 = messageWidth2 + conf.actorMargin - actor.width / 2;\n actor.margin = common_default.getMax(actorWidth2, conf.actorMargin);\n continue;\n }\n const messageWidth = actorToMessageWidth[actorKey];\n const actorWidth = messageWidth + conf.actorMargin - actor.width / 2 - nextActor.width / 2;\n actor.margin = common_default.getMax(actorWidth, conf.actorMargin);\n }\n let maxBoxHeight = 0;\n boxes.forEach((box) => {\n const textFont = messageFont(conf);\n let totalWidth = box.actorKeys.reduce((total, aKey) => {\n return total += actors.get(aKey).width + (actors.get(aKey).margin || 0);\n }, 0);\n totalWidth -= 2 * conf.boxTextMargin;\n if (box.wrap) {\n box.name = utils_default.wrapLabel(box.name, totalWidth - 2 * conf.wrapPadding, textFont);\n }\n const boxMsgDimensions = utils_default.calculateTextDimensions(box.name, textFont);\n maxBoxHeight = common_default.getMax(boxMsgDimensions.height, maxBoxHeight);\n const minWidth = common_default.getMax(totalWidth, boxMsgDimensions.width + 2 * conf.wrapPadding);\n box.margin = conf.boxTextMargin;\n if (totalWidth < minWidth) {\n const missing = (minWidth - totalWidth) / 2;\n box.margin += missing;\n }\n });\n boxes.forEach((box) => box.textMaxHeight = maxBoxHeight);\n return common_default.getMax(maxHeight, conf.height);\n}\n__name(calculateActorMargins, \"calculateActorMargins\");\nvar buildNoteModel = /* @__PURE__ */ __name(async function(msg, actors, diagObj) {\n const fromActor = actors.get(msg.from);\n const toActor = actors.get(msg.to);\n const startx = fromActor.x;\n const stopx = toActor.x;\n const shouldWrap = msg.wrap && msg.message;\n let textDimensions = hasKatex(msg.message) ? await calculateMathMLDimensions(msg.message, getConfig2()) : utils_default.calculateTextDimensions(\n shouldWrap ? utils_default.wrapLabel(msg.message, conf.width, noteFont(conf)) : msg.message,\n noteFont(conf)\n );\n const noteModel = {\n width: shouldWrap ? conf.width : common_default.getMax(conf.width, textDimensions.width + 2 * conf.noteMargin),\n height: 0,\n startx: fromActor.x,\n stopx: 0,\n starty: 0,\n stopy: 0,\n message: msg.message\n };\n if (msg.placement === diagObj.db.PLACEMENT.RIGHTOF) {\n noteModel.width = shouldWrap ? common_default.getMax(conf.width, textDimensions.width) : common_default.getMax(\n fromActor.width / 2 + toActor.width / 2,\n textDimensions.width + 2 * conf.noteMargin\n );\n noteModel.startx = startx + (fromActor.width + conf.actorMargin) / 2;\n } else if (msg.placement === diagObj.db.PLACEMENT.LEFTOF) {\n noteModel.width = shouldWrap ? common_default.getMax(conf.width, textDimensions.width + 2 * conf.noteMargin) : common_default.getMax(\n fromActor.width / 2 + toActor.width / 2,\n textDimensions.width + 2 * conf.noteMargin\n );\n noteModel.startx = startx - noteModel.width + (fromActor.width - conf.actorMargin) / 2;\n } else if (msg.to === msg.from) {\n textDimensions = utils_default.calculateTextDimensions(\n shouldWrap ? utils_default.wrapLabel(msg.message, common_default.getMax(conf.width, fromActor.width), noteFont(conf)) : msg.message,\n noteFont(conf)\n );\n noteModel.width = shouldWrap ? common_default.getMax(conf.width, fromActor.width) : common_default.getMax(fromActor.width, conf.width, textDimensions.width + 2 * conf.noteMargin);\n noteModel.startx = startx + (fromActor.width - noteModel.width) / 2;\n } else {\n noteModel.width = Math.abs(startx + fromActor.width / 2 - (stopx + toActor.width / 2)) + conf.actorMargin;\n noteModel.startx = startx < stopx ? startx + fromActor.width / 2 - conf.actorMargin / 2 : stopx + toActor.width / 2 - conf.actorMargin / 2;\n }\n if (shouldWrap) {\n noteModel.message = utils_default.wrapLabel(\n msg.message,\n noteModel.width - 2 * conf.wrapPadding,\n noteFont(conf)\n );\n }\n log.debug(\n `NM:[${noteModel.startx},${noteModel.stopx},${noteModel.starty},${noteModel.stopy}:${noteModel.width},${noteModel.height}=${msg.message}]`\n );\n return noteModel;\n}, \"buildNoteModel\");\nvar buildMessageModel = /* @__PURE__ */ __name(function(msg, actors, diagObj) {\n if (![\n diagObj.db.LINETYPE.SOLID_OPEN,\n diagObj.db.LINETYPE.DOTTED_OPEN,\n diagObj.db.LINETYPE.SOLID,\n diagObj.db.LINETYPE.DOTTED,\n diagObj.db.LINETYPE.SOLID_CROSS,\n diagObj.db.LINETYPE.DOTTED_CROSS,\n diagObj.db.LINETYPE.SOLID_POINT,\n diagObj.db.LINETYPE.DOTTED_POINT,\n diagObj.db.LINETYPE.BIDIRECTIONAL_SOLID,\n diagObj.db.LINETYPE.BIDIRECTIONAL_DOTTED\n ].includes(msg.type)) {\n return {};\n }\n const [fromLeft, fromRight] = activationBounds(msg.from, actors);\n const [toLeft, toRight] = activationBounds(msg.to, actors);\n const isArrowToRight = fromLeft <= toLeft;\n let startx = isArrowToRight ? fromRight : fromLeft;\n let stopx = isArrowToRight ? toLeft : toRight;\n const isArrowToActivation = Math.abs(toLeft - toRight) > 2;\n const adjustValue = /* @__PURE__ */ __name((value) => {\n return isArrowToRight ? -value : value;\n }, \"adjustValue\");\n if (msg.from === msg.to) {\n stopx = startx;\n } else {\n if (msg.activate && !isArrowToActivation) {\n stopx += adjustValue(conf.activationWidth / 2 - 1);\n }\n if (![diagObj.db.LINETYPE.SOLID_OPEN, diagObj.db.LINETYPE.DOTTED_OPEN].includes(msg.type)) {\n stopx += adjustValue(3);\n }\n if ([diagObj.db.LINETYPE.BIDIRECTIONAL_SOLID, diagObj.db.LINETYPE.BIDIRECTIONAL_DOTTED].includes(\n msg.type\n )) {\n startx -= adjustValue(3);\n }\n }\n const allBounds = [fromLeft, fromRight, toLeft, toRight];\n const boundedWidth = Math.abs(startx - stopx);\n if (msg.wrap && msg.message) {\n msg.message = utils_default.wrapLabel(\n msg.message,\n common_default.getMax(boundedWidth + 2 * conf.wrapPadding, conf.width),\n messageFont(conf)\n );\n }\n const msgDims = utils_default.calculateTextDimensions(msg.message, messageFont(conf));\n return {\n width: common_default.getMax(\n msg.wrap ? 0 : msgDims.width + 2 * conf.wrapPadding,\n boundedWidth + 2 * conf.wrapPadding,\n conf.width\n ),\n height: 0,\n startx,\n stopx,\n starty: 0,\n stopy: 0,\n message: msg.message,\n type: msg.type,\n wrap: msg.wrap,\n fromBounds: Math.min.apply(null, allBounds),\n toBounds: Math.max.apply(null, allBounds)\n };\n}, \"buildMessageModel\");\nvar calculateLoopBounds = /* @__PURE__ */ __name(async function(messages, actors, _maxWidthPerActor, diagObj) {\n const loops = {};\n const stack = [];\n let current, noteModel, msgModel;\n for (const msg of messages) {\n msg.id = utils_default.random({ length: 10 });\n switch (msg.type) {\n case diagObj.db.LINETYPE.LOOP_START:\n case diagObj.db.LINETYPE.ALT_START:\n case diagObj.db.LINETYPE.OPT_START:\n case diagObj.db.LINETYPE.PAR_START:\n case diagObj.db.LINETYPE.PAR_OVER_START:\n case diagObj.db.LINETYPE.CRITICAL_START:\n case diagObj.db.LINETYPE.BREAK_START:\n stack.push({\n id: msg.id,\n msg: msg.message,\n from: Number.MAX_SAFE_INTEGER,\n to: Number.MIN_SAFE_INTEGER,\n width: 0\n });\n break;\n case diagObj.db.LINETYPE.ALT_ELSE:\n case diagObj.db.LINETYPE.PAR_AND:\n case diagObj.db.LINETYPE.CRITICAL_OPTION:\n if (msg.message) {\n current = stack.pop();\n loops[current.id] = current;\n loops[msg.id] = current;\n stack.push(current);\n }\n break;\n case diagObj.db.LINETYPE.LOOP_END:\n case diagObj.db.LINETYPE.ALT_END:\n case diagObj.db.LINETYPE.OPT_END:\n case diagObj.db.LINETYPE.PAR_END:\n case diagObj.db.LINETYPE.CRITICAL_END:\n case diagObj.db.LINETYPE.BREAK_END:\n current = stack.pop();\n loops[current.id] = current;\n break;\n case diagObj.db.LINETYPE.ACTIVE_START:\n {\n const actorRect = actors.get(msg.from ? msg.from : msg.to.actor);\n const stackedSize = actorActivations(msg.from ? msg.from : msg.to.actor).length;\n const x = actorRect.x + actorRect.width / 2 + (stackedSize - 1) * conf.activationWidth / 2;\n const toAdd = {\n startx: x,\n stopx: x + conf.activationWidth,\n actor: msg.from,\n enabled: true\n };\n bounds.activations.push(toAdd);\n }\n break;\n case diagObj.db.LINETYPE.ACTIVE_END:\n {\n const lastActorActivationIdx = bounds.activations.map((a) => a.actor).lastIndexOf(msg.from);\n bounds.activations.splice(lastActorActivationIdx, 1).splice(0, 1);\n }\n break;\n }\n const isNote = msg.placement !== void 0;\n if (isNote) {\n noteModel = await buildNoteModel(msg, actors, diagObj);\n msg.noteModel = noteModel;\n stack.forEach((stk) => {\n current = stk;\n current.from = common_default.getMin(current.from, noteModel.startx);\n current.to = common_default.getMax(current.to, noteModel.startx + noteModel.width);\n current.width = common_default.getMax(current.width, Math.abs(current.from - current.to)) - conf.labelBoxWidth;\n });\n } else {\n msgModel = buildMessageModel(msg, actors, diagObj);\n msg.msgModel = msgModel;\n if (msgModel.startx && msgModel.stopx && stack.length > 0) {\n stack.forEach((stk) => {\n current = stk;\n if (msgModel.startx === msgModel.stopx) {\n const from = actors.get(msg.from);\n const to = actors.get(msg.to);\n current.from = common_default.getMin(\n from.x - msgModel.width / 2,\n from.x - from.width / 2,\n current.from\n );\n current.to = common_default.getMax(\n to.x + msgModel.width / 2,\n to.x + from.width / 2,\n current.to\n );\n current.width = common_default.getMax(current.width, Math.abs(current.to - current.from)) - conf.labelBoxWidth;\n } else {\n current.from = common_default.getMin(msgModel.startx, current.from);\n current.to = common_default.getMax(msgModel.stopx, current.to);\n current.width = common_default.getMax(current.width, msgModel.width) - conf.labelBoxWidth;\n }\n });\n }\n }\n }\n bounds.activations = [];\n log.debug(\"Loop type widths:\", loops);\n return loops;\n}, \"calculateLoopBounds\");\nvar sequenceRenderer_default = {\n bounds,\n drawActors,\n drawActorsPopup,\n setConf,\n draw\n};\n\n// src/diagrams/sequence/sequenceDiagram.ts\nvar diagram = {\n parser: sequenceDiagram_default,\n db: sequenceDb_default,\n renderer: sequenceRenderer_default,\n styles: styles_default,\n init: /* @__PURE__ */ __name(({ wrap }) => {\n sequenceDb_default.setWrap(wrap);\n }, \"init\")\n};\nexport {\n diagram\n};\n", "import {\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n clear,\n common_default,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n getDiagramTitle,\n log,\n parseGenericTypes,\n sanitizeText,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/class/parser/classDiagram.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 17], $V1 = [1, 18], $V2 = [1, 19], $V3 = [1, 39], $V4 = [1, 40], $V5 = [1, 25], $V6 = [1, 23], $V7 = [1, 24], $V8 = [1, 31], $V9 = [1, 32], $Va = [1, 33], $Vb = [1, 34], $Vc = [1, 35], $Vd = [1, 36], $Ve = [1, 26], $Vf = [1, 27], $Vg = [1, 28], $Vh = [1, 29], $Vi = [1, 43], $Vj = [1, 30], $Vk = [1, 42], $Vl = [1, 44], $Vm = [1, 41], $Vn = [1, 45], $Vo = [1, 9], $Vp = [1, 8, 9], $Vq = [1, 56], $Vr = [1, 57], $Vs = [1, 58], $Vt = [1, 59], $Vu = [1, 60], $Vv = [1, 61], $Vw = [1, 62], $Vx = [1, 8, 9, 39], $Vy = [1, 74], $Vz = [1, 8, 9, 12, 13, 21, 37, 39, 42, 59, 60, 61, 62, 63, 64, 65, 70, 72], $VA = [1, 8, 9, 12, 13, 19, 21, 37, 39, 42, 46, 59, 60, 61, 62, 63, 64, 65, 70, 72, 74, 80, 95, 97, 98], $VB = [13, 74, 80, 95, 97, 98], $VC = [13, 64, 65, 74, 80, 95, 97, 98], $VD = [13, 59, 60, 61, 62, 63, 74, 80, 95, 97, 98], $VE = [1, 93], $VF = [1, 110], $VG = [1, 108], $VH = [1, 102], $VI = [1, 103], $VJ = [1, 104], $VK = [1, 105], $VL = [1, 106], $VM = [1, 107], $VN = [1, 109], $VO = [1, 8, 9, 37, 39, 42], $VP = [1, 8, 9, 21], $VQ = [1, 8, 9, 78], $VR = [1, 8, 9, 21, 73, 74, 78, 80, 81, 82, 83, 84, 85];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"mermaidDoc\": 4, \"statements\": 5, \"graphConfig\": 6, \"CLASS_DIAGRAM\": 7, \"NEWLINE\": 8, \"EOF\": 9, \"statement\": 10, \"classLabel\": 11, \"SQS\": 12, \"STR\": 13, \"SQE\": 14, \"namespaceName\": 15, \"alphaNumToken\": 16, \"className\": 17, \"classLiteralName\": 18, \"GENERICTYPE\": 19, \"relationStatement\": 20, \"LABEL\": 21, \"namespaceStatement\": 22, \"classStatement\": 23, \"memberStatement\": 24, \"annotationStatement\": 25, \"clickStatement\": 26, \"styleStatement\": 27, \"cssClassStatement\": 28, \"noteStatement\": 29, \"direction\": 30, \"acc_title\": 31, \"acc_title_value\": 32, \"acc_descr\": 33, \"acc_descr_value\": 34, \"acc_descr_multiline_value\": 35, \"namespaceIdentifier\": 36, \"STRUCT_START\": 37, \"classStatements\": 38, \"STRUCT_STOP\": 39, \"NAMESPACE\": 40, \"classIdentifier\": 41, \"STYLE_SEPARATOR\": 42, \"members\": 43, \"CLASS\": 44, \"ANNOTATION_START\": 45, \"ANNOTATION_END\": 46, \"MEMBER\": 47, \"SEPARATOR\": 48, \"relation\": 49, \"NOTE_FOR\": 50, \"noteText\": 51, \"NOTE\": 52, \"direction_tb\": 53, \"direction_bt\": 54, \"direction_rl\": 55, \"direction_lr\": 56, \"relationType\": 57, \"lineType\": 58, \"AGGREGATION\": 59, \"EXTENSION\": 60, \"COMPOSITION\": 61, \"DEPENDENCY\": 62, \"LOLLIPOP\": 63, \"LINE\": 64, \"DOTTED_LINE\": 65, \"CALLBACK\": 66, \"LINK\": 67, \"LINK_TARGET\": 68, \"CLICK\": 69, \"CALLBACK_NAME\": 70, \"CALLBACK_ARGS\": 71, \"HREF\": 72, \"STYLE\": 73, \"ALPHA\": 74, \"stylesOpt\": 75, \"CSSCLASS\": 76, \"style\": 77, \"COMMA\": 78, \"styleComponent\": 79, \"NUM\": 80, \"COLON\": 81, \"UNIT\": 82, \"SPACE\": 83, \"BRKT\": 84, \"PCT\": 85, \"commentToken\": 86, \"textToken\": 87, \"graphCodeTokens\": 88, \"textNoTagsToken\": 89, \"TAGSTART\": 90, \"TAGEND\": 91, \"==\": 92, \"--\": 93, \"DEFAULT\": 94, \"MINUS\": 95, \"keywords\": 96, \"UNICODE_TEXT\": 97, \"BQUOTE_STR\": 98, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 7: \"CLASS_DIAGRAM\", 8: \"NEWLINE\", 9: \"EOF\", 12: \"SQS\", 13: \"STR\", 14: \"SQE\", 19: \"GENERICTYPE\", 21: \"LABEL\", 31: \"acc_title\", 32: \"acc_title_value\", 33: \"acc_descr\", 34: \"acc_descr_value\", 35: \"acc_descr_multiline_value\", 37: \"STRUCT_START\", 39: \"STRUCT_STOP\", 40: \"NAMESPACE\", 42: \"STYLE_SEPARATOR\", 44: \"CLASS\", 45: \"ANNOTATION_START\", 46: \"ANNOTATION_END\", 47: \"MEMBER\", 48: \"SEPARATOR\", 50: \"NOTE_FOR\", 52: \"NOTE\", 53: \"direction_tb\", 54: \"direction_bt\", 55: \"direction_rl\", 56: \"direction_lr\", 59: \"AGGREGATION\", 60: \"EXTENSION\", 61: \"COMPOSITION\", 62: \"DEPENDENCY\", 63: \"LOLLIPOP\", 64: \"LINE\", 65: \"DOTTED_LINE\", 66: \"CALLBACK\", 67: \"LINK\", 68: \"LINK_TARGET\", 69: \"CLICK\", 70: \"CALLBACK_NAME\", 71: \"CALLBACK_ARGS\", 72: \"HREF\", 73: \"STYLE\", 74: \"ALPHA\", 76: \"CSSCLASS\", 78: \"COMMA\", 80: \"NUM\", 81: \"COLON\", 82: \"UNIT\", 83: \"SPACE\", 84: \"BRKT\", 85: \"PCT\", 88: \"graphCodeTokens\", 90: \"TAGSTART\", 91: \"TAGEND\", 92: \"==\", 93: \"--\", 94: \"DEFAULT\", 95: \"MINUS\", 96: \"keywords\", 97: \"UNICODE_TEXT\", 98: \"BQUOTE_STR\" },\n productions_: [0, [3, 1], [3, 1], [4, 1], [6, 4], [5, 1], [5, 2], [5, 3], [11, 3], [15, 1], [15, 2], [17, 1], [17, 1], [17, 2], [17, 2], [17, 2], [10, 1], [10, 2], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [10, 1], [22, 4], [22, 5], [36, 2], [38, 1], [38, 2], [38, 3], [23, 1], [23, 3], [23, 4], [23, 6], [41, 2], [41, 3], [25, 4], [43, 1], [43, 2], [24, 1], [24, 2], [24, 1], [24, 1], [20, 3], [20, 4], [20, 4], [20, 5], [29, 3], [29, 2], [30, 1], [30, 1], [30, 1], [30, 1], [49, 3], [49, 2], [49, 2], [49, 1], [57, 1], [57, 1], [57, 1], [57, 1], [57, 1], [58, 1], [58, 1], [26, 3], [26, 4], [26, 3], [26, 4], [26, 4], [26, 5], [26, 3], [26, 4], [26, 4], [26, 5], [26, 4], [26, 5], [26, 5], [26, 6], [27, 3], [28, 3], [75, 1], [75, 3], [77, 1], [77, 2], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [79, 1], [86, 1], [86, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [87, 1], [89, 1], [89, 1], [89, 1], [89, 1], [16, 1], [16, 1], [16, 1], [16, 1], [18, 1], [51, 1]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 8:\n this.$ = $$[$0 - 1];\n break;\n case 9:\n case 11:\n case 12:\n this.$ = $$[$0];\n break;\n case 10:\n case 13:\n this.$ = $$[$0 - 1] + $$[$0];\n break;\n case 14:\n case 15:\n this.$ = $$[$0 - 1] + \"~\" + $$[$0] + \"~\";\n break;\n case 16:\n yy.addRelation($$[$0]);\n break;\n case 17:\n $$[$0 - 1].title = yy.cleanupLabel($$[$0]);\n yy.addRelation($$[$0 - 1]);\n break;\n case 27:\n this.$ = $$[$0].trim();\n yy.setAccTitle(this.$);\n break;\n case 28:\n case 29:\n this.$ = $$[$0].trim();\n yy.setAccDescription(this.$);\n break;\n case 30:\n yy.addClassesToNamespace($$[$0 - 3], $$[$0 - 1]);\n break;\n case 31:\n yy.addClassesToNamespace($$[$0 - 4], $$[$0 - 1]);\n break;\n case 32:\n this.$ = $$[$0];\n yy.addNamespace($$[$0]);\n break;\n case 33:\n this.$ = [$$[$0]];\n break;\n case 34:\n this.$ = [$$[$0 - 1]];\n break;\n case 35:\n $$[$0].unshift($$[$0 - 2]);\n this.$ = $$[$0];\n break;\n case 37:\n yy.setCssClass($$[$0 - 2], $$[$0]);\n break;\n case 38:\n yy.addMembers($$[$0 - 3], $$[$0 - 1]);\n break;\n case 39:\n yy.setCssClass($$[$0 - 5], $$[$0 - 3]);\n yy.addMembers($$[$0 - 5], $$[$0 - 1]);\n break;\n case 40:\n this.$ = $$[$0];\n yy.addClass($$[$0]);\n break;\n case 41:\n this.$ = $$[$0 - 1];\n yy.addClass($$[$0 - 1]);\n yy.setClassLabel($$[$0 - 1], $$[$0]);\n break;\n case 42:\n yy.addAnnotation($$[$0], $$[$0 - 2]);\n break;\n case 43:\n this.$ = [$$[$0]];\n break;\n case 44:\n $$[$0].push($$[$0 - 1]);\n this.$ = $$[$0];\n break;\n case 45:\n break;\n case 46:\n yy.addMember($$[$0 - 1], yy.cleanupLabel($$[$0]));\n break;\n case 47:\n break;\n case 48:\n break;\n case 49:\n this.$ = { \"id1\": $$[$0 - 2], \"id2\": $$[$0], relation: $$[$0 - 1], relationTitle1: \"none\", relationTitle2: \"none\" };\n break;\n case 50:\n this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 1], relationTitle1: $$[$0 - 2], relationTitle2: \"none\" };\n break;\n case 51:\n this.$ = { id1: $$[$0 - 3], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: \"none\", relationTitle2: $$[$0 - 1] };\n break;\n case 52:\n this.$ = { id1: $$[$0 - 4], id2: $$[$0], relation: $$[$0 - 2], relationTitle1: $$[$0 - 3], relationTitle2: $$[$0 - 1] };\n break;\n case 53:\n yy.addNote($$[$0], $$[$0 - 1]);\n break;\n case 54:\n yy.addNote($$[$0]);\n break;\n case 55:\n yy.setDirection(\"TB\");\n break;\n case 56:\n yy.setDirection(\"BT\");\n break;\n case 57:\n yy.setDirection(\"RL\");\n break;\n case 58:\n yy.setDirection(\"LR\");\n break;\n case 59:\n this.$ = { type1: $$[$0 - 2], type2: $$[$0], lineType: $$[$0 - 1] };\n break;\n case 60:\n this.$ = { type1: \"none\", type2: $$[$0], lineType: $$[$0 - 1] };\n break;\n case 61:\n this.$ = { type1: $$[$0 - 1], type2: \"none\", lineType: $$[$0] };\n break;\n case 62:\n this.$ = { type1: \"none\", type2: \"none\", lineType: $$[$0] };\n break;\n case 63:\n this.$ = yy.relationType.AGGREGATION;\n break;\n case 64:\n this.$ = yy.relationType.EXTENSION;\n break;\n case 65:\n this.$ = yy.relationType.COMPOSITION;\n break;\n case 66:\n this.$ = yy.relationType.DEPENDENCY;\n break;\n case 67:\n this.$ = yy.relationType.LOLLIPOP;\n break;\n case 68:\n this.$ = yy.lineType.LINE;\n break;\n case 69:\n this.$ = yy.lineType.DOTTED_LINE;\n break;\n case 70:\n case 76:\n this.$ = $$[$0 - 2];\n yy.setClickEvent($$[$0 - 1], $$[$0]);\n break;\n case 71:\n case 77:\n this.$ = $$[$0 - 3];\n yy.setClickEvent($$[$0 - 2], $$[$0 - 1]);\n yy.setTooltip($$[$0 - 2], $$[$0]);\n break;\n case 72:\n this.$ = $$[$0 - 2];\n yy.setLink($$[$0 - 1], $$[$0]);\n break;\n case 73:\n this.$ = $$[$0 - 3];\n yy.setLink($$[$0 - 2], $$[$0 - 1], $$[$0]);\n break;\n case 74:\n this.$ = $$[$0 - 3];\n yy.setLink($$[$0 - 2], $$[$0 - 1]);\n yy.setTooltip($$[$0 - 2], $$[$0]);\n break;\n case 75:\n this.$ = $$[$0 - 4];\n yy.setLink($$[$0 - 3], $$[$0 - 2], $$[$0]);\n yy.setTooltip($$[$0 - 3], $$[$0 - 1]);\n break;\n case 78:\n this.$ = $$[$0 - 3];\n yy.setClickEvent($$[$0 - 2], $$[$0 - 1], $$[$0]);\n break;\n case 79:\n this.$ = $$[$0 - 4];\n yy.setClickEvent($$[$0 - 3], $$[$0 - 2], $$[$0 - 1]);\n yy.setTooltip($$[$0 - 3], $$[$0]);\n break;\n case 80:\n this.$ = $$[$0 - 3];\n yy.setLink($$[$0 - 2], $$[$0]);\n break;\n case 81:\n this.$ = $$[$0 - 4];\n yy.setLink($$[$0 - 3], $$[$0 - 1], $$[$0]);\n break;\n case 82:\n this.$ = $$[$0 - 4];\n yy.setLink($$[$0 - 3], $$[$0 - 1]);\n yy.setTooltip($$[$0 - 3], $$[$0]);\n break;\n case 83:\n this.$ = $$[$0 - 5];\n yy.setLink($$[$0 - 4], $$[$0 - 2], $$[$0]);\n yy.setTooltip($$[$0 - 4], $$[$0 - 1]);\n break;\n case 84:\n this.$ = $$[$0 - 2];\n yy.setCssStyle($$[$0 - 1], $$[$0]);\n break;\n case 85:\n yy.setCssClass($$[$0 - 1], $$[$0]);\n break;\n case 86:\n this.$ = [$$[$0]];\n break;\n case 87:\n $$[$0 - 2].push($$[$0]);\n this.$ = $$[$0 - 2];\n break;\n case 89:\n this.$ = $$[$0 - 1] + $$[$0];\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: 2, 5: 3, 6: 4, 7: [1, 6], 10: 5, 16: 37, 17: 20, 18: 38, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 31: $V0, 33: $V1, 35: $V2, 36: 21, 40: $V3, 41: 22, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 1: [3] }, { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3] }, o($Vo, [2, 5], { 8: [1, 46] }), { 8: [1, 47] }, o($Vp, [2, 16], { 21: [1, 48] }), o($Vp, [2, 18]), o($Vp, [2, 19]), o($Vp, [2, 20]), o($Vp, [2, 21]), o($Vp, [2, 22]), o($Vp, [2, 23]), o($Vp, [2, 24]), o($Vp, [2, 25]), o($Vp, [2, 26]), { 32: [1, 49] }, { 34: [1, 50] }, o($Vp, [2, 29]), o($Vp, [2, 45], { 49: 51, 57: 54, 58: 55, 13: [1, 52], 21: [1, 53], 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv, 65: $Vw }), { 37: [1, 63] }, o($Vx, [2, 36], { 37: [1, 65], 42: [1, 64] }), o($Vp, [2, 47]), o($Vp, [2, 48]), { 16: 66, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 16: 37, 17: 67, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 16: 37, 17: 68, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 16: 37, 17: 69, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 74: [1, 70] }, { 13: [1, 71] }, { 16: 37, 17: 72, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 13: $Vy, 51: 73 }, o($Vp, [2, 55]), o($Vp, [2, 56]), o($Vp, [2, 57]), o($Vp, [2, 58]), o($Vz, [2, 11], { 16: 37, 18: 38, 17: 75, 19: [1, 76], 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }), o($Vz, [2, 12], { 19: [1, 77] }), { 15: 78, 16: 79, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 16: 37, 17: 80, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VA, [2, 112]), o($VA, [2, 113]), o($VA, [2, 114]), o($VA, [2, 115]), o([1, 8, 9, 12, 13, 19, 21, 37, 39, 42, 59, 60, 61, 62, 63, 64, 65, 70, 72], [2, 116]), o($Vo, [2, 6], { 10: 5, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 17: 20, 36: 21, 41: 22, 16: 37, 18: 38, 5: 81, 31: $V0, 33: $V1, 35: $V2, 40: $V3, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }), { 5: 82, 10: 5, 16: 37, 17: 20, 18: 38, 20: 7, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 27: 13, 28: 14, 29: 15, 30: 16, 31: $V0, 33: $V1, 35: $V2, 36: 21, 40: $V3, 41: 22, 44: $V4, 45: $V5, 47: $V6, 48: $V7, 50: $V8, 52: $V9, 53: $Va, 54: $Vb, 55: $Vc, 56: $Vd, 66: $Ve, 67: $Vf, 69: $Vg, 73: $Vh, 74: $Vi, 76: $Vj, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($Vp, [2, 17]), o($Vp, [2, 27]), o($Vp, [2, 28]), { 13: [1, 84], 16: 37, 17: 83, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 49: 85, 57: 54, 58: 55, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu, 64: $Vv, 65: $Vw }, o($Vp, [2, 46]), { 58: 86, 64: $Vv, 65: $Vw }, o($VB, [2, 62], { 57: 87, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu }), o($VC, [2, 63]), o($VC, [2, 64]), o($VC, [2, 65]), o($VC, [2, 66]), o($VC, [2, 67]), o($VD, [2, 68]), o($VD, [2, 69]), { 8: [1, 89], 23: 90, 38: 88, 41: 22, 44: $V4 }, { 16: 91, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, { 43: 92, 47: $VE }, { 46: [1, 94] }, { 13: [1, 95] }, { 13: [1, 96] }, { 70: [1, 97], 72: [1, 98] }, { 21: $VF, 73: $VG, 74: $VH, 75: 99, 77: 100, 79: 101, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }, { 74: [1, 111] }, { 13: $Vy, 51: 112 }, o($Vp, [2, 54]), o($Vp, [2, 117]), o($Vz, [2, 13]), o($Vz, [2, 14]), o($Vz, [2, 15]), { 37: [2, 32] }, { 15: 113, 16: 79, 37: [2, 9], 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm }, o($VO, [2, 40], { 11: 114, 12: [1, 115] }), o($Vo, [2, 7]), { 9: [1, 116] }, o($VP, [2, 49]), { 16: 37, 17: 117, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, { 13: [1, 119], 16: 37, 17: 118, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VB, [2, 61], { 57: 120, 59: $Vq, 60: $Vr, 61: $Vs, 62: $Vt, 63: $Vu }), o($VB, [2, 60]), { 39: [1, 121] }, { 23: 90, 38: 122, 41: 22, 44: $V4 }, { 8: [1, 123], 39: [2, 33] }, o($Vx, [2, 37], { 37: [1, 124] }), { 39: [1, 125] }, { 39: [2, 43], 43: 126, 47: $VE }, { 16: 37, 17: 127, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($Vp, [2, 70], { 13: [1, 128] }), o($Vp, [2, 72], { 13: [1, 130], 68: [1, 129] }), o($Vp, [2, 76], { 13: [1, 131], 71: [1, 132] }), { 13: [1, 133] }, o($Vp, [2, 84], { 78: [1, 134] }), o($VQ, [2, 86], { 79: 135, 21: $VF, 73: $VG, 74: $VH, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }), o($VR, [2, 88]), o($VR, [2, 90]), o($VR, [2, 91]), o($VR, [2, 92]), o($VR, [2, 93]), o($VR, [2, 94]), o($VR, [2, 95]), o($VR, [2, 96]), o($VR, [2, 97]), o($VR, [2, 98]), o($Vp, [2, 85]), o($Vp, [2, 53]), { 37: [2, 10] }, o($VO, [2, 41]), { 13: [1, 136] }, { 1: [2, 4] }, o($VP, [2, 51]), o($VP, [2, 50]), { 16: 37, 17: 137, 18: 38, 74: $Vi, 80: $Vk, 95: $Vl, 97: $Vm, 98: $Vn }, o($VB, [2, 59]), o($Vp, [2, 30]), { 39: [1, 138] }, { 23: 90, 38: 139, 39: [2, 34], 41: 22, 44: $V4 }, { 43: 140, 47: $VE }, o($Vx, [2, 38]), { 39: [2, 44] }, o($Vp, [2, 42]), o($Vp, [2, 71]), o($Vp, [2, 73]), o($Vp, [2, 74], { 68: [1, 141] }), o($Vp, [2, 77]), o($Vp, [2, 78], { 13: [1, 142] }), o($Vp, [2, 80], { 13: [1, 144], 68: [1, 143] }), { 21: $VF, 73: $VG, 74: $VH, 77: 145, 79: 101, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }, o($VR, [2, 89]), { 14: [1, 146] }, o($VP, [2, 52]), o($Vp, [2, 31]), { 39: [2, 35] }, { 39: [1, 147] }, o($Vp, [2, 75]), o($Vp, [2, 79]), o($Vp, [2, 81]), o($Vp, [2, 82], { 68: [1, 148] }), o($VQ, [2, 87], { 79: 135, 21: $VF, 73: $VG, 74: $VH, 80: $VI, 81: $VJ, 82: $VK, 83: $VL, 84: $VM, 85: $VN }), o($VO, [2, 8]), o($Vx, [2, 39]), o($Vp, [2, 83])],\n defaultActions: { 2: [2, 1], 3: [2, 2], 4: [2, 3], 78: [2, 32], 113: [2, 10], 116: [2, 4], 126: [2, 44], 139: [2, 35] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: {},\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n return 53;\n break;\n case 1:\n return 54;\n break;\n case 2:\n return 55;\n break;\n case 3:\n return 56;\n break;\n case 4:\n break;\n case 5:\n break;\n case 6:\n this.begin(\"acc_title\");\n return 31;\n break;\n case 7:\n this.popState();\n return \"acc_title_value\";\n break;\n case 8:\n this.begin(\"acc_descr\");\n return 33;\n break;\n case 9:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 10:\n this.begin(\"acc_descr_multiline\");\n break;\n case 11:\n this.popState();\n break;\n case 12:\n return \"acc_descr_multiline_value\";\n break;\n case 13:\n return 8;\n break;\n case 14:\n break;\n case 15:\n return 7;\n break;\n case 16:\n return 7;\n break;\n case 17:\n return \"EDGE_STATE\";\n break;\n case 18:\n this.begin(\"callback_name\");\n break;\n case 19:\n this.popState();\n break;\n case 20:\n this.popState();\n this.begin(\"callback_args\");\n break;\n case 21:\n return 70;\n break;\n case 22:\n this.popState();\n break;\n case 23:\n return 71;\n break;\n case 24:\n this.popState();\n break;\n case 25:\n return \"STR\";\n break;\n case 26:\n this.begin(\"string\");\n break;\n case 27:\n return 73;\n break;\n case 28:\n this.begin(\"namespace\");\n return 40;\n break;\n case 29:\n this.popState();\n return 8;\n break;\n case 30:\n break;\n case 31:\n this.begin(\"namespace-body\");\n return 37;\n break;\n case 32:\n this.popState();\n return 39;\n break;\n case 33:\n return \"EOF_IN_STRUCT\";\n break;\n case 34:\n return 8;\n break;\n case 35:\n break;\n case 36:\n return \"EDGE_STATE\";\n break;\n case 37:\n this.begin(\"class\");\n return 44;\n break;\n case 38:\n this.popState();\n return 8;\n break;\n case 39:\n break;\n case 40:\n this.popState();\n this.popState();\n return 39;\n break;\n case 41:\n this.begin(\"class-body\");\n return 37;\n break;\n case 42:\n this.popState();\n return 39;\n break;\n case 43:\n return \"EOF_IN_STRUCT\";\n break;\n case 44:\n return \"EDGE_STATE\";\n break;\n case 45:\n return \"OPEN_IN_STRUCT\";\n break;\n case 46:\n break;\n case 47:\n return \"MEMBER\";\n break;\n case 48:\n return 76;\n break;\n case 49:\n return 66;\n break;\n case 50:\n return 67;\n break;\n case 51:\n return 69;\n break;\n case 52:\n return 50;\n break;\n case 53:\n return 52;\n break;\n case 54:\n return 45;\n break;\n case 55:\n return 46;\n break;\n case 56:\n return 72;\n break;\n case 57:\n this.popState();\n break;\n case 58:\n return \"GENERICTYPE\";\n break;\n case 59:\n this.begin(\"generic\");\n break;\n case 60:\n this.popState();\n break;\n case 61:\n return \"BQUOTE_STR\";\n break;\n case 62:\n this.begin(\"bqstring\");\n break;\n case 63:\n return 68;\n break;\n case 64:\n return 68;\n break;\n case 65:\n return 68;\n break;\n case 66:\n return 68;\n break;\n case 67:\n return 60;\n break;\n case 68:\n return 60;\n break;\n case 69:\n return 62;\n break;\n case 70:\n return 62;\n break;\n case 71:\n return 61;\n break;\n case 72:\n return 59;\n break;\n case 73:\n return 63;\n break;\n case 74:\n return 64;\n break;\n case 75:\n return 65;\n break;\n case 76:\n return 21;\n break;\n case 77:\n return 42;\n break;\n case 78:\n return 95;\n break;\n case 79:\n return \"DOT\";\n break;\n case 80:\n return \"PLUS\";\n break;\n case 81:\n return 81;\n break;\n case 82:\n return 78;\n break;\n case 83:\n return 84;\n break;\n case 84:\n return 84;\n break;\n case 85:\n return 85;\n break;\n case 86:\n return \"EQUALS\";\n break;\n case 87:\n return \"EQUALS\";\n break;\n case 88:\n return 74;\n break;\n case 89:\n return 12;\n break;\n case 90:\n return 14;\n break;\n case 91:\n return \"PUNCTUATION\";\n break;\n case 92:\n return 80;\n break;\n case 93:\n return 97;\n break;\n case 94:\n return 83;\n break;\n case 95:\n return 83;\n break;\n case 96:\n return 9;\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:.*direction\\s+TB[^\\n]*)/, /^(?:.*direction\\s+BT[^\\n]*)/, /^(?:.*direction\\s+RL[^\\n]*)/, /^(?:.*direction\\s+LR[^\\n]*)/, /^(?:%%(?!\\{)*[^\\n]*(\\r?\\n?)+)/, /^(?:%%[^\\n]*(\\r?\\n)*)/, /^(?:accTitle\\s*:\\s*)/, /^(?:(?!\\n||)*[^\\n]*)/, /^(?:accDescr\\s*:\\s*)/, /^(?:(?!\\n||)*[^\\n]*)/, /^(?:accDescr\\s*\\{\\s*)/, /^(?:[\\}])/, /^(?:[^\\}]*)/, /^(?:\\s*(\\r?\\n)+)/, /^(?:\\s+)/, /^(?:classDiagram-v2\\b)/, /^(?:classDiagram\\b)/, /^(?:\\[\\*\\])/, /^(?:call[\\s]+)/, /^(?:\\([\\s]*\\))/, /^(?:\\()/, /^(?:[^(]*)/, /^(?:\\))/, /^(?:[^)]*)/, /^(?:[\"])/, /^(?:[^\"]*)/, /^(?:[\"])/, /^(?:style\\b)/, /^(?:namespace\\b)/, /^(?:\\s*(\\r?\\n)+)/, /^(?:\\s+)/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\\s*(\\r?\\n)+)/, /^(?:\\s+)/, /^(?:\\[\\*\\])/, /^(?:class\\b)/, /^(?:\\s*(\\r?\\n)+)/, /^(?:\\s+)/, /^(?:[}])/, /^(?:[{])/, /^(?:[}])/, /^(?:$)/, /^(?:\\[\\*\\])/, /^(?:[{])/, /^(?:[\\n])/, /^(?:[^{}\\n]*)/, /^(?:cssClass\\b)/, /^(?:callback\\b)/, /^(?:link\\b)/, /^(?:click\\b)/, /^(?:note for\\b)/, /^(?:note\\b)/, /^(?:<<)/, /^(?:>>)/, /^(?:href\\b)/, /^(?:[~])/, /^(?:[^~]*)/, /^(?:~)/, /^(?:[`])/, /^(?:[^`]+)/, /^(?:[`])/, /^(?:_self\\b)/, /^(?:_blank\\b)/, /^(?:_parent\\b)/, /^(?:_top\\b)/, /^(?:\\s*<\\|)/, /^(?:\\s*\\|>)/, /^(?:\\s*>)/, /^(?:\\s*<)/, /^(?:\\s*\\*)/, /^(?:\\s*o\\b)/, /^(?:\\s*\\(\\))/, /^(?:--)/, /^(?:\\.\\.)/, /^(?::{1}[^:\\n;]+)/, /^(?::{3})/, /^(?:-)/, /^(?:\\.)/, /^(?:\\+)/, /^(?::)/, /^(?:,)/, /^(?:#)/, /^(?:#)/, /^(?:%)/, /^(?:=)/, /^(?:=)/, /^(?:\\w+)/, /^(?:\\[)/, /^(?:\\])/, /^(?:[!\"#$%&'*+,-.`?\\\\/])/, /^(?:[0-9]+)/, /^(?:[\\u00AA\\u00B5\\u00BA\\u00C0-\\u00D6\\u00D8-\\u00F6]|[\\u00F8-\\u02C1\\u02C6-\\u02D1\\u02E0-\\u02E4\\u02EC\\u02EE\\u0370-\\u0374\\u0376\\u0377]|[\\u037A-\\u037D\\u0386\\u0388-\\u038A\\u038C\\u038E-\\u03A1\\u03A3-\\u03F5]|[\\u03F7-\\u0481\\u048A-\\u0527\\u0531-\\u0556\\u0559\\u0561-\\u0587\\u05D0-\\u05EA]|[\\u05F0-\\u05F2\\u0620-\\u064A\\u066E\\u066F\\u0671-\\u06D3\\u06D5\\u06E5\\u06E6\\u06EE]|[\\u06EF\\u06FA-\\u06FC\\u06FF\\u0710\\u0712-\\u072F\\u074D-\\u07A5\\u07B1\\u07CA-\\u07EA]|[\\u07F4\\u07F5\\u07FA\\u0800-\\u0815\\u081A\\u0824\\u0828\\u0840-\\u0858\\u08A0]|[\\u08A2-\\u08AC\\u0904-\\u0939\\u093D\\u0950\\u0958-\\u0961\\u0971-\\u0977]|[\\u0979-\\u097F\\u0985-\\u098C\\u098F\\u0990\\u0993-\\u09A8\\u09AA-\\u09B0\\u09B2]|[\\u09B6-\\u09B9\\u09BD\\u09CE\\u09DC\\u09DD\\u09DF-\\u09E1\\u09F0\\u09F1\\u0A05-\\u0A0A]|[\\u0A0F\\u0A10\\u0A13-\\u0A28\\u0A2A-\\u0A30\\u0A32\\u0A33\\u0A35\\u0A36\\u0A38\\u0A39]|[\\u0A59-\\u0A5C\\u0A5E\\u0A72-\\u0A74\\u0A85-\\u0A8D\\u0A8F-\\u0A91\\u0A93-\\u0AA8]|[\\u0AAA-\\u0AB0\\u0AB2\\u0AB3\\u0AB5-\\u0AB9\\u0ABD\\u0AD0\\u0AE0\\u0AE1\\u0B05-\\u0B0C]|[\\u0B0F\\u0B10\\u0B13-\\u0B28\\u0B2A-\\u0B30\\u0B32\\u0B33\\u0B35-\\u0B39\\u0B3D\\u0B5C]|[\\u0B5D\\u0B5F-\\u0B61\\u0B71\\u0B83\\u0B85-\\u0B8A\\u0B8E-\\u0B90\\u0B92-\\u0B95\\u0B99]|[\\u0B9A\\u0B9C\\u0B9E\\u0B9F\\u0BA3\\u0BA4\\u0BA8-\\u0BAA\\u0BAE-\\u0BB9\\u0BD0]|[\\u0C05-\\u0C0C\\u0C0E-\\u0C10\\u0C12-\\u0C28\\u0C2A-\\u0C33\\u0C35-\\u0C39\\u0C3D]|[\\u0C58\\u0C59\\u0C60\\u0C61\\u0C85-\\u0C8C\\u0C8E-\\u0C90\\u0C92-\\u0CA8\\u0CAA-\\u0CB3]|[\\u0CB5-\\u0CB9\\u0CBD\\u0CDE\\u0CE0\\u0CE1\\u0CF1\\u0CF2\\u0D05-\\u0D0C\\u0D0E-\\u0D10]|[\\u0D12-\\u0D3A\\u0D3D\\u0D4E\\u0D60\\u0D61\\u0D7A-\\u0D7F\\u0D85-\\u0D96\\u0D9A-\\u0DB1]|[\\u0DB3-\\u0DBB\\u0DBD\\u0DC0-\\u0DC6\\u0E01-\\u0E30\\u0E32\\u0E33\\u0E40-\\u0E46\\u0E81]|[\\u0E82\\u0E84\\u0E87\\u0E88\\u0E8A\\u0E8D\\u0E94-\\u0E97\\u0E99-\\u0E9F\\u0EA1-\\u0EA3]|[\\u0EA5\\u0EA7\\u0EAA\\u0EAB\\u0EAD-\\u0EB0\\u0EB2\\u0EB3\\u0EBD\\u0EC0-\\u0EC4\\u0EC6]|[\\u0EDC-\\u0EDF\\u0F00\\u0F40-\\u0F47\\u0F49-\\u0F6C\\u0F88-\\u0F8C\\u1000-\\u102A]|[\\u103F\\u1050-\\u1055\\u105A-\\u105D\\u1061\\u1065\\u1066\\u106E-\\u1070\\u1075-\\u1081]|[\\u108E\\u10A0-\\u10C5\\u10C7\\u10CD\\u10D0-\\u10FA\\u10FC-\\u1248\\u124A-\\u124D]|[\\u1250-\\u1256\\u1258\\u125A-\\u125D\\u1260-\\u1288\\u128A-\\u128D\\u1290-\\u12B0]|[\\u12B2-\\u12B5\\u12B8-\\u12BE\\u12C0\\u12C2-\\u12C5\\u12C8-\\u12D6\\u12D8-\\u1310]|[\\u1312-\\u1315\\u1318-\\u135A\\u1380-\\u138F\\u13A0-\\u13F4\\u1401-\\u166C]|[\\u166F-\\u167F\\u1681-\\u169A\\u16A0-\\u16EA\\u1700-\\u170C\\u170E-\\u1711]|[\\u1720-\\u1731\\u1740-\\u1751\\u1760-\\u176C\\u176E-\\u1770\\u1780-\\u17B3\\u17D7]|[\\u17DC\\u1820-\\u1877\\u1880-\\u18A8\\u18AA\\u18B0-\\u18F5\\u1900-\\u191C]|[\\u1950-\\u196D\\u1970-\\u1974\\u1980-\\u19AB\\u19C1-\\u19C7\\u1A00-\\u1A16]|[\\u1A20-\\u1A54\\u1AA7\\u1B05-\\u1B33\\u1B45-\\u1B4B\\u1B83-\\u1BA0\\u1BAE\\u1BAF]|[\\u1BBA-\\u1BE5\\u1C00-\\u1C23\\u1C4D-\\u1C4F\\u1C5A-\\u1C7D\\u1CE9-\\u1CEC]|[\\u1CEE-\\u1CF1\\u1CF5\\u1CF6\\u1D00-\\u1DBF\\u1E00-\\u1F15\\u1F18-\\u1F1D]|[\\u1F20-\\u1F45\\u1F48-\\u1F4D\\u1F50-\\u1F57\\u1F59\\u1F5B\\u1F5D\\u1F5F-\\u1F7D]|[\\u1F80-\\u1FB4\\u1FB6-\\u1FBC\\u1FBE\\u1FC2-\\u1FC4\\u1FC6-\\u1FCC\\u1FD0-\\u1FD3]|[\\u1FD6-\\u1FDB\\u1FE0-\\u1FEC\\u1FF2-\\u1FF4\\u1FF6-\\u1FFC\\u2071\\u207F]|[\\u2090-\\u209C\\u2102\\u2107\\u210A-\\u2113\\u2115\\u2119-\\u211D\\u2124\\u2126\\u2128]|[\\u212A-\\u212D\\u212F-\\u2139\\u213C-\\u213F\\u2145-\\u2149\\u214E\\u2183\\u2184]|[\\u2C00-\\u2C2E\\u2C30-\\u2C5E\\u2C60-\\u2CE4\\u2CEB-\\u2CEE\\u2CF2\\u2CF3]|[\\u2D00-\\u2D25\\u2D27\\u2D2D\\u2D30-\\u2D67\\u2D6F\\u2D80-\\u2D96\\u2DA0-\\u2DA6]|[\\u2DA8-\\u2DAE\\u2DB0-\\u2DB6\\u2DB8-\\u2DBE\\u2DC0-\\u2DC6\\u2DC8-\\u2DCE]|[\\u2DD0-\\u2DD6\\u2DD8-\\u2DDE\\u2E2F\\u3005\\u3006\\u3031-\\u3035\\u303B\\u303C]|[\\u3041-\\u3096\\u309D-\\u309F\\u30A1-\\u30FA\\u30FC-\\u30FF\\u3105-\\u312D]|[\\u3131-\\u318E\\u31A0-\\u31BA\\u31F0-\\u31FF\\u3400-\\u4DB5\\u4E00-\\u9FCC]|[\\uA000-\\uA48C\\uA4D0-\\uA4FD\\uA500-\\uA60C\\uA610-\\uA61F\\uA62A\\uA62B]|[\\uA640-\\uA66E\\uA67F-\\uA697\\uA6A0-\\uA6E5\\uA717-\\uA71F\\uA722-\\uA788]|[\\uA78B-\\uA78E\\uA790-\\uA793\\uA7A0-\\uA7AA\\uA7F8-\\uA801\\uA803-\\uA805]|[\\uA807-\\uA80A\\uA80C-\\uA822\\uA840-\\uA873\\uA882-\\uA8B3\\uA8F2-\\uA8F7\\uA8FB]|[\\uA90A-\\uA925\\uA930-\\uA946\\uA960-\\uA97C\\uA984-\\uA9B2\\uA9CF\\uAA00-\\uAA28]|[\\uAA40-\\uAA42\\uAA44-\\uAA4B\\uAA60-\\uAA76\\uAA7A\\uAA80-\\uAAAF\\uAAB1\\uAAB5]|[\\uAAB6\\uAAB9-\\uAABD\\uAAC0\\uAAC2\\uAADB-\\uAADD\\uAAE0-\\uAAEA\\uAAF2-\\uAAF4]|[\\uAB01-\\uAB06\\uAB09-\\uAB0E\\uAB11-\\uAB16\\uAB20-\\uAB26\\uAB28-\\uAB2E]|[\\uABC0-\\uABE2\\uAC00-\\uD7A3\\uD7B0-\\uD7C6\\uD7CB-\\uD7FB\\uF900-\\uFA6D]|[\\uFA70-\\uFAD9\\uFB00-\\uFB06\\uFB13-\\uFB17\\uFB1D\\uFB1F-\\uFB28\\uFB2A-\\uFB36]|[\\uFB38-\\uFB3C\\uFB3E\\uFB40\\uFB41\\uFB43\\uFB44\\uFB46-\\uFBB1\\uFBD3-\\uFD3D]|[\\uFD50-\\uFD8F\\uFD92-\\uFDC7\\uFDF0-\\uFDFB\\uFE70-\\uFE74\\uFE76-\\uFEFC]|[\\uFF21-\\uFF3A\\uFF41-\\uFF5A\\uFF66-\\uFFBE\\uFFC2-\\uFFC7\\uFFCA-\\uFFCF]|[\\uFFD2-\\uFFD7\\uFFDA-\\uFFDC])/, /^(?:\\s)/, /^(?:\\s)/, /^(?:$)/],\n conditions: { \"namespace-body\": { \"rules\": [26, 32, 33, 34, 35, 36, 37, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"namespace\": { \"rules\": [26, 28, 29, 30, 31, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"class-body\": { \"rules\": [26, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"class\": { \"rules\": [26, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"acc_descr_multiline\": { \"rules\": [11, 12, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"acc_descr\": { \"rules\": [9, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"acc_title\": { \"rules\": [7, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"callback_args\": { \"rules\": [22, 23, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"callback_name\": { \"rules\": [19, 20, 21, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"href\": { \"rules\": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"struct\": { \"rules\": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"generic\": { \"rules\": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"bqstring\": { \"rules\": [26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"string\": { \"rules\": [24, 25, 26, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 96], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 2, 3, 4, 5, 6, 8, 10, 13, 14, 15, 16, 17, 18, 26, 27, 28, 37, 48, 49, 50, 51, 52, 53, 54, 55, 56, 59, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar classDiagram_default = parser;\n\n// src/diagrams/class/classDb.ts\nimport { select } from \"d3\";\n\n// src/diagrams/class/classTypes.ts\nvar visibilityValues = [\"#\", \"+\", \"~\", \"-\", \"\"];\nvar ClassMember = class {\n static {\n __name(this, \"ClassMember\");\n }\n constructor(input, memberType) {\n this.memberType = memberType;\n this.visibility = \"\";\n this.classifier = \"\";\n const sanitizedInput = sanitizeText(input, getConfig());\n this.parseMember(sanitizedInput);\n }\n getDisplayDetails() {\n let displayText = this.visibility + parseGenericTypes(this.id);\n if (this.memberType === \"method\") {\n displayText += `(${parseGenericTypes(this.parameters.trim())})`;\n if (this.returnType) {\n displayText += \" : \" + parseGenericTypes(this.returnType);\n }\n }\n displayText = displayText.trim();\n const cssStyle = this.parseClassifier();\n return {\n displayText,\n cssStyle\n };\n }\n parseMember(input) {\n let potentialClassifier = \"\";\n if (this.memberType === \"method\") {\n const methodRegEx = /([#+~-])?(.+)\\((.*)\\)([\\s$*])?(.*)([$*])?/;\n const match = methodRegEx.exec(input);\n if (match) {\n const detectedVisibility = match[1] ? match[1].trim() : \"\";\n if (visibilityValues.includes(detectedVisibility)) {\n this.visibility = detectedVisibility;\n }\n this.id = match[2].trim();\n this.parameters = match[3] ? match[3].trim() : \"\";\n potentialClassifier = match[4] ? match[4].trim() : \"\";\n this.returnType = match[5] ? match[5].trim() : \"\";\n if (potentialClassifier === \"\") {\n const lastChar = this.returnType.substring(this.returnType.length - 1);\n if (/[$*]/.exec(lastChar)) {\n potentialClassifier = lastChar;\n this.returnType = this.returnType.substring(0, this.returnType.length - 1);\n }\n }\n }\n } else {\n const length = input.length;\n const firstChar = input.substring(0, 1);\n const lastChar = input.substring(length - 1);\n if (visibilityValues.includes(firstChar)) {\n this.visibility = firstChar;\n }\n if (/[$*]/.exec(lastChar)) {\n potentialClassifier = lastChar;\n }\n this.id = input.substring(\n this.visibility === \"\" ? 0 : 1,\n potentialClassifier === \"\" ? length : length - 1\n );\n }\n this.classifier = potentialClassifier;\n }\n parseClassifier() {\n switch (this.classifier) {\n case \"*\":\n return \"font-style:italic;\";\n case \"$\":\n return \"text-decoration:underline;\";\n default:\n return \"\";\n }\n }\n};\n\n// src/diagrams/class/classDb.ts\nvar MERMAID_DOM_ID_PREFIX = \"classId-\";\nvar relations = [];\nvar classes = /* @__PURE__ */ new Map();\nvar notes = [];\nvar classCounter = 0;\nvar namespaces = /* @__PURE__ */ new Map();\nvar namespaceCounter = 0;\nvar functions = [];\nvar sanitizeText2 = /* @__PURE__ */ __name((txt) => common_default.sanitizeText(txt, getConfig()), \"sanitizeText\");\nvar splitClassNameAndType = /* @__PURE__ */ __name(function(_id) {\n const id = common_default.sanitizeText(_id, getConfig());\n let genericType = \"\";\n let className = id;\n if (id.indexOf(\"~\") > 0) {\n const split = id.split(\"~\");\n className = sanitizeText2(split[0]);\n genericType = sanitizeText2(split[1]);\n }\n return { className, type: genericType };\n}, \"splitClassNameAndType\");\nvar setClassLabel = /* @__PURE__ */ __name(function(_id, label) {\n const id = common_default.sanitizeText(_id, getConfig());\n if (label) {\n label = sanitizeText2(label);\n }\n const { className } = splitClassNameAndType(id);\n classes.get(className).label = label;\n}, \"setClassLabel\");\nvar addClass = /* @__PURE__ */ __name(function(_id) {\n const id = common_default.sanitizeText(_id, getConfig());\n const { className, type } = splitClassNameAndType(id);\n if (classes.has(className)) {\n return;\n }\n const name = common_default.sanitizeText(className, getConfig());\n classes.set(name, {\n id: name,\n type,\n label: name,\n cssClasses: [],\n methods: [],\n members: [],\n annotations: [],\n styles: [],\n domId: MERMAID_DOM_ID_PREFIX + name + \"-\" + classCounter\n });\n classCounter++;\n}, \"addClass\");\nvar lookUpDomId = /* @__PURE__ */ __name(function(_id) {\n const id = common_default.sanitizeText(_id, getConfig());\n if (classes.has(id)) {\n return classes.get(id).domId;\n }\n throw new Error(\"Class not found: \" + id);\n}, \"lookUpDomId\");\nvar clear2 = /* @__PURE__ */ __name(function() {\n relations = [];\n classes = /* @__PURE__ */ new Map();\n notes = [];\n functions = [];\n functions.push(setupToolTips);\n namespaces = /* @__PURE__ */ new Map();\n namespaceCounter = 0;\n direction = \"TB\";\n clear();\n}, \"clear\");\nvar getClass = /* @__PURE__ */ __name(function(id) {\n return classes.get(id);\n}, \"getClass\");\nvar getClasses = /* @__PURE__ */ __name(function() {\n return classes;\n}, \"getClasses\");\nvar getRelations = /* @__PURE__ */ __name(function() {\n return relations;\n}, \"getRelations\");\nvar getNotes = /* @__PURE__ */ __name(function() {\n return notes;\n}, \"getNotes\");\nvar addRelation = /* @__PURE__ */ __name(function(relation) {\n log.debug(\"Adding relation: \" + JSON.stringify(relation));\n addClass(relation.id1);\n addClass(relation.id2);\n relation.id1 = splitClassNameAndType(relation.id1).className;\n relation.id2 = splitClassNameAndType(relation.id2).className;\n relation.relationTitle1 = common_default.sanitizeText(relation.relationTitle1.trim(), getConfig());\n relation.relationTitle2 = common_default.sanitizeText(relation.relationTitle2.trim(), getConfig());\n relations.push(relation);\n}, \"addRelation\");\nvar addAnnotation = /* @__PURE__ */ __name(function(className, annotation) {\n const validatedClassName = splitClassNameAndType(className).className;\n classes.get(validatedClassName).annotations.push(annotation);\n}, \"addAnnotation\");\nvar addMember = /* @__PURE__ */ __name(function(className, member) {\n addClass(className);\n const validatedClassName = splitClassNameAndType(className).className;\n const theClass = classes.get(validatedClassName);\n if (typeof member === \"string\") {\n const memberString = member.trim();\n if (memberString.startsWith(\"<<\") && memberString.endsWith(\">>\")) {\n theClass.annotations.push(sanitizeText2(memberString.substring(2, memberString.length - 2)));\n } else if (memberString.indexOf(\")\") > 0) {\n theClass.methods.push(new ClassMember(memberString, \"method\"));\n } else if (memberString) {\n theClass.members.push(new ClassMember(memberString, \"attribute\"));\n }\n }\n}, \"addMember\");\nvar addMembers = /* @__PURE__ */ __name(function(className, members) {\n if (Array.isArray(members)) {\n members.reverse();\n members.forEach((member) => addMember(className, member));\n }\n}, \"addMembers\");\nvar addNote = /* @__PURE__ */ __name(function(text, className) {\n const note = {\n id: `note${notes.length}`,\n class: className,\n text\n };\n notes.push(note);\n}, \"addNote\");\nvar cleanupLabel = /* @__PURE__ */ __name(function(label) {\n if (label.startsWith(\":\")) {\n label = label.substring(1);\n }\n return sanitizeText2(label.trim());\n}, \"cleanupLabel\");\nvar setCssClass = /* @__PURE__ */ __name(function(ids, className) {\n ids.split(\",\").forEach(function(_id) {\n let id = _id;\n if (/\\d/.exec(_id[0])) {\n id = MERMAID_DOM_ID_PREFIX + id;\n }\n const classNode = classes.get(id);\n if (classNode) {\n classNode.cssClasses.push(className);\n }\n });\n}, \"setCssClass\");\nvar setTooltip = /* @__PURE__ */ __name(function(ids, tooltip) {\n ids.split(\",\").forEach(function(id) {\n if (tooltip !== void 0) {\n classes.get(id).tooltip = sanitizeText2(tooltip);\n }\n });\n}, \"setTooltip\");\nvar getTooltip = /* @__PURE__ */ __name(function(id, namespace) {\n if (namespace && namespaces.has(namespace)) {\n return namespaces.get(namespace).classes.get(id).tooltip;\n }\n return classes.get(id).tooltip;\n}, \"getTooltip\");\nvar setLink = /* @__PURE__ */ __name(function(ids, linkStr, target) {\n const config = getConfig();\n ids.split(\",\").forEach(function(_id) {\n let id = _id;\n if (/\\d/.exec(_id[0])) {\n id = MERMAID_DOM_ID_PREFIX + id;\n }\n const theClass = classes.get(id);\n if (theClass) {\n theClass.link = utils_default.formatUrl(linkStr, config);\n if (config.securityLevel === \"sandbox\") {\n theClass.linkTarget = \"_top\";\n } else if (typeof target === \"string\") {\n theClass.linkTarget = sanitizeText2(target);\n } else {\n theClass.linkTarget = \"_blank\";\n }\n }\n });\n setCssClass(ids, \"clickable\");\n}, \"setLink\");\nvar setClickEvent = /* @__PURE__ */ __name(function(ids, functionName, functionArgs) {\n ids.split(\",\").forEach(function(id) {\n setClickFunc(id, functionName, functionArgs);\n classes.get(id).haveCallback = true;\n });\n setCssClass(ids, \"clickable\");\n}, \"setClickEvent\");\nvar setClickFunc = /* @__PURE__ */ __name(function(_domId, functionName, functionArgs) {\n const domId = common_default.sanitizeText(_domId, getConfig());\n const config = getConfig();\n if (config.securityLevel !== \"loose\") {\n return;\n }\n if (functionName === void 0) {\n return;\n }\n const id = domId;\n if (classes.has(id)) {\n const elemId = lookUpDomId(id);\n let argList = [];\n if (typeof functionArgs === \"string\") {\n argList = functionArgs.split(/,(?=(?:(?:[^\"]*\"){2})*[^\"]*$)/);\n for (let i = 0; i < argList.length; i++) {\n let item = argList[i].trim();\n if (item.startsWith('\"') && item.endsWith('\"')) {\n item = item.substr(1, item.length - 2);\n }\n argList[i] = item;\n }\n }\n if (argList.length === 0) {\n argList.push(elemId);\n }\n functions.push(function() {\n const elem = document.querySelector(`[id=\"${elemId}\"]`);\n if (elem !== null) {\n elem.addEventListener(\n \"click\",\n function() {\n utils_default.runFunc(functionName, ...argList);\n },\n false\n );\n }\n });\n }\n}, \"setClickFunc\");\nvar bindFunctions = /* @__PURE__ */ __name(function(element) {\n functions.forEach(function(fun) {\n fun(element);\n });\n}, \"bindFunctions\");\nvar lineType = {\n LINE: 0,\n DOTTED_LINE: 1\n};\nvar relationType = {\n AGGREGATION: 0,\n EXTENSION: 1,\n COMPOSITION: 2,\n DEPENDENCY: 3,\n LOLLIPOP: 4\n};\nvar setupToolTips = /* @__PURE__ */ __name(function(element) {\n let tooltipElem = select(\".mermaidTooltip\");\n if ((tooltipElem._groups || tooltipElem)[0][0] === null) {\n tooltipElem = select(\"body\").append(\"div\").attr(\"class\", \"mermaidTooltip\").style(\"opacity\", 0);\n }\n const svg = select(element).select(\"svg\");\n const nodes = svg.selectAll(\"g.node\");\n nodes.on(\"mouseover\", function() {\n const el = select(this);\n const title = el.attr(\"title\");\n if (title === null) {\n return;\n }\n const rect = this.getBoundingClientRect();\n tooltipElem.transition().duration(200).style(\"opacity\", \".9\");\n tooltipElem.text(el.attr(\"title\")).style(\"left\", window.scrollX + rect.left + (rect.right - rect.left) / 2 + \"px\").style(\"top\", window.scrollY + rect.top - 14 + document.body.scrollTop + \"px\");\n tooltipElem.html(tooltipElem.html().replace(/<br\\/>/g, \"
\"));\n el.classed(\"hover\", true);\n }).on(\"mouseout\", function() {\n tooltipElem.transition().duration(500).style(\"opacity\", 0);\n const el = select(this);\n el.classed(\"hover\", false);\n });\n}, \"setupToolTips\");\nfunctions.push(setupToolTips);\nvar direction = \"TB\";\nvar getDirection = /* @__PURE__ */ __name(() => direction, \"getDirection\");\nvar setDirection = /* @__PURE__ */ __name((dir) => {\n direction = dir;\n}, \"setDirection\");\nvar addNamespace = /* @__PURE__ */ __name(function(id) {\n if (namespaces.has(id)) {\n return;\n }\n namespaces.set(id, {\n id,\n classes: /* @__PURE__ */ new Map(),\n children: {},\n domId: MERMAID_DOM_ID_PREFIX + id + \"-\" + namespaceCounter\n });\n namespaceCounter++;\n}, \"addNamespace\");\nvar getNamespace = /* @__PURE__ */ __name(function(name) {\n return namespaces.get(name);\n}, \"getNamespace\");\nvar getNamespaces = /* @__PURE__ */ __name(function() {\n return namespaces;\n}, \"getNamespaces\");\nvar addClassesToNamespace = /* @__PURE__ */ __name(function(id, classNames) {\n if (!namespaces.has(id)) {\n return;\n }\n for (const name of classNames) {\n const { className } = splitClassNameAndType(name);\n classes.get(className).parent = id;\n namespaces.get(id).classes.set(className, classes.get(className));\n }\n}, \"addClassesToNamespace\");\nvar setCssStyle = /* @__PURE__ */ __name(function(id, styles) {\n const thisClass = classes.get(id);\n if (!styles || !thisClass) {\n return;\n }\n for (const s of styles) {\n if (s.includes(\",\")) {\n thisClass.styles.push(...s.split(\",\"));\n } else {\n thisClass.styles.push(s);\n }\n }\n}, \"setCssStyle\");\nvar classDb_default = {\n setAccTitle,\n getAccTitle,\n getAccDescription,\n setAccDescription,\n getConfig: /* @__PURE__ */ __name(() => getConfig().class, \"getConfig\"),\n addClass,\n bindFunctions,\n clear: clear2,\n getClass,\n getClasses,\n getNotes,\n addAnnotation,\n addNote,\n getRelations,\n addRelation,\n getDirection,\n setDirection,\n addMember,\n addMembers,\n cleanupLabel,\n lineType,\n relationType,\n setClickEvent,\n setCssClass,\n setLink,\n getTooltip,\n setTooltip,\n lookUpDomId,\n setDiagramTitle,\n getDiagramTitle,\n setClassLabel,\n addNamespace,\n addClassesToNamespace,\n getNamespace,\n getNamespaces,\n setCssStyle\n};\n\n// src/diagrams/class/styles.js\nvar getStyles = /* @__PURE__ */ __name((options) => `g.classGroup text {\n fill: ${options.nodeBorder || options.classText};\n stroke: none;\n font-family: ${options.fontFamily};\n font-size: 10px;\n\n .title {\n font-weight: bolder;\n }\n\n}\n\n.nodeLabel, .edgeLabel {\n color: ${options.classText};\n}\n.edgeLabel .label rect {\n fill: ${options.mainBkg};\n}\n.label text {\n fill: ${options.classText};\n}\n.edgeLabel .label span {\n background: ${options.mainBkg};\n}\n\n.classTitle {\n font-weight: bolder;\n}\n.node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${options.mainBkg};\n stroke: ${options.nodeBorder};\n stroke-width: 1px;\n }\n\n\n.divider {\n stroke: ${options.nodeBorder};\n stroke-width: 1;\n}\n\ng.clickable {\n cursor: pointer;\n}\n\ng.classGroup rect {\n fill: ${options.mainBkg};\n stroke: ${options.nodeBorder};\n}\n\ng.classGroup line {\n stroke: ${options.nodeBorder};\n stroke-width: 1;\n}\n\n.classLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${options.mainBkg};\n opacity: 0.5;\n}\n\n.classLabel .label {\n fill: ${options.nodeBorder};\n font-size: 10px;\n}\n\n.relation {\n stroke: ${options.lineColor};\n stroke-width: 1;\n fill: none;\n}\n\n.dashed-line{\n stroke-dasharray: 3;\n}\n\n.dotted-line{\n stroke-dasharray: 1 2;\n}\n\n#compositionStart, .composition {\n fill: ${options.lineColor} !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#compositionEnd, .composition {\n fill: ${options.lineColor} !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${options.lineColor} !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#dependencyStart, .dependency {\n fill: ${options.lineColor} !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionStart, .extension {\n fill: transparent !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#extensionEnd, .extension {\n fill: transparent !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationStart, .aggregation {\n fill: transparent !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#aggregationEnd, .aggregation {\n fill: transparent !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopStart, .lollipop {\n fill: ${options.mainBkg} !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n#lollipopEnd, .lollipop {\n fill: ${options.mainBkg} !important;\n stroke: ${options.lineColor} !important;\n stroke-width: 1;\n}\n\n.edgeTerminals {\n font-size: 11px;\n line-height: initial;\n}\n\n.classTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${options.textColor};\n}\n`, \"getStyles\");\nvar styles_default = getStyles;\n\nexport {\n classDiagram_default,\n classDb_default,\n styles_default\n};\n", "import {\n classDb_default,\n classDiagram_default,\n styles_default\n} from \"./chunk-BAVOGKFW.mjs\";\nimport {\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n configureSvgSize,\n getConfig2 as getConfig,\n log,\n parseGenericTypes\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/class/classRenderer.js\nimport { select } from \"d3\";\nimport { layout as dagreLayout } from \"dagre-d3-es/src/dagre/index.js\";\nimport * as graphlib from \"dagre-d3-es/src/graphlib/index.js\";\n\n// src/diagrams/class/svgDraw.js\nimport { line, curveBasis } from \"d3\";\nvar edgeCount = 0;\nvar drawEdge = /* @__PURE__ */ __name(function(elem, path, relation, conf, diagObj) {\n const getRelationType = /* @__PURE__ */ __name(function(type) {\n switch (type) {\n case diagObj.db.relationType.AGGREGATION:\n return \"aggregation\";\n case diagObj.db.relationType.EXTENSION:\n return \"extension\";\n case diagObj.db.relationType.COMPOSITION:\n return \"composition\";\n case diagObj.db.relationType.DEPENDENCY:\n return \"dependency\";\n case diagObj.db.relationType.LOLLIPOP:\n return \"lollipop\";\n }\n }, \"getRelationType\");\n path.points = path.points.filter((p) => !Number.isNaN(p.y));\n const lineData = path.points;\n const lineFunction = line().x(function(d) {\n return d.x;\n }).y(function(d) {\n return d.y;\n }).curve(curveBasis);\n const svgPath = elem.append(\"path\").attr(\"d\", lineFunction(lineData)).attr(\"id\", \"edge\" + edgeCount).attr(\"class\", \"relation\");\n let url = \"\";\n if (conf.arrowMarkerAbsolute) {\n url = window.location.protocol + \"//\" + window.location.host + window.location.pathname + window.location.search;\n url = url.replace(/\\(/g, \"\\\\(\");\n url = url.replace(/\\)/g, \"\\\\)\");\n }\n if (relation.relation.lineType == 1) {\n svgPath.attr(\"class\", \"relation dashed-line\");\n }\n if (relation.relation.lineType == 10) {\n svgPath.attr(\"class\", \"relation dotted-line\");\n }\n if (relation.relation.type1 !== \"none\") {\n svgPath.attr(\n \"marker-start\",\n \"url(\" + url + \"#\" + getRelationType(relation.relation.type1) + \"Start)\"\n );\n }\n if (relation.relation.type2 !== \"none\") {\n svgPath.attr(\n \"marker-end\",\n \"url(\" + url + \"#\" + getRelationType(relation.relation.type2) + \"End)\"\n );\n }\n let x, y;\n const l = path.points.length;\n let labelPosition = utils_default.calcLabelPosition(path.points);\n x = labelPosition.x;\n y = labelPosition.y;\n let p1_card_x, p1_card_y;\n let p2_card_x, p2_card_y;\n if (l % 2 !== 0 && l > 1) {\n let cardinality_1_point = utils_default.calcCardinalityPosition(\n relation.relation.type1 !== \"none\",\n path.points,\n path.points[0]\n );\n let cardinality_2_point = utils_default.calcCardinalityPosition(\n relation.relation.type2 !== \"none\",\n path.points,\n path.points[l - 1]\n );\n log.debug(\"cardinality_1_point \" + JSON.stringify(cardinality_1_point));\n log.debug(\"cardinality_2_point \" + JSON.stringify(cardinality_2_point));\n p1_card_x = cardinality_1_point.x;\n p1_card_y = cardinality_1_point.y;\n p2_card_x = cardinality_2_point.x;\n p2_card_y = cardinality_2_point.y;\n }\n if (relation.title !== void 0) {\n const g = elem.append(\"g\").attr(\"class\", \"classLabel\");\n const label = g.append(\"text\").attr(\"class\", \"label\").attr(\"x\", x).attr(\"y\", y).attr(\"fill\", \"red\").attr(\"text-anchor\", \"middle\").text(relation.title);\n window.label = label;\n const bounds = label.node().getBBox();\n g.insert(\"rect\", \":first-child\").attr(\"class\", \"box\").attr(\"x\", bounds.x - conf.padding / 2).attr(\"y\", bounds.y - conf.padding / 2).attr(\"width\", bounds.width + conf.padding).attr(\"height\", bounds.height + conf.padding);\n }\n log.info(\"Rendering relation \" + JSON.stringify(relation));\n if (relation.relationTitle1 !== void 0 && relation.relationTitle1 !== \"none\") {\n const g = elem.append(\"g\").attr(\"class\", \"cardinality\");\n g.append(\"text\").attr(\"class\", \"type1\").attr(\"x\", p1_card_x).attr(\"y\", p1_card_y).attr(\"fill\", \"black\").attr(\"font-size\", \"6\").text(relation.relationTitle1);\n }\n if (relation.relationTitle2 !== void 0 && relation.relationTitle2 !== \"none\") {\n const g = elem.append(\"g\").attr(\"class\", \"cardinality\");\n g.append(\"text\").attr(\"class\", \"type2\").attr(\"x\", p2_card_x).attr(\"y\", p2_card_y).attr(\"fill\", \"black\").attr(\"font-size\", \"6\").text(relation.relationTitle2);\n }\n edgeCount++;\n}, \"drawEdge\");\nvar drawClass = /* @__PURE__ */ __name(function(elem, classDef, conf, diagObj) {\n log.debug(\"Rendering class \", classDef, conf);\n const id = classDef.id;\n const classInfo = {\n id,\n label: classDef.id,\n width: 0,\n height: 0\n };\n const g = elem.append(\"g\").attr(\"id\", diagObj.db.lookUpDomId(id)).attr(\"class\", \"classGroup\");\n let title;\n if (classDef.link) {\n title = g.append(\"svg:a\").attr(\"xlink:href\", classDef.link).attr(\"target\", classDef.linkTarget).append(\"text\").attr(\"y\", conf.textHeight + conf.padding).attr(\"x\", 0);\n } else {\n title = g.append(\"text\").attr(\"y\", conf.textHeight + conf.padding).attr(\"x\", 0);\n }\n let isFirst = true;\n classDef.annotations.forEach(function(member) {\n const titleText2 = title.append(\"tspan\").text(\"\\xAB\" + member + \"\\xBB\");\n if (!isFirst) {\n titleText2.attr(\"dy\", conf.textHeight);\n }\n isFirst = false;\n });\n let classTitleString = getClassTitleString(classDef);\n const classTitle = title.append(\"tspan\").text(classTitleString).attr(\"class\", \"title\");\n if (!isFirst) {\n classTitle.attr(\"dy\", conf.textHeight);\n }\n const titleHeight = title.node().getBBox().height;\n let membersLine;\n let membersBox;\n let methodsLine;\n if (classDef.members.length > 0) {\n membersLine = g.append(\"line\").attr(\"x1\", 0).attr(\"y1\", conf.padding + titleHeight + conf.dividerMargin / 2).attr(\"y2\", conf.padding + titleHeight + conf.dividerMargin / 2);\n const members = g.append(\"text\").attr(\"x\", conf.padding).attr(\"y\", titleHeight + conf.dividerMargin + conf.textHeight).attr(\"fill\", \"white\").attr(\"class\", \"classText\");\n isFirst = true;\n classDef.members.forEach(function(member) {\n addTspan(members, member, isFirst, conf);\n isFirst = false;\n });\n membersBox = members.node().getBBox();\n }\n if (classDef.methods.length > 0) {\n methodsLine = g.append(\"line\").attr(\"x1\", 0).attr(\"y1\", conf.padding + titleHeight + conf.dividerMargin + membersBox.height).attr(\"y2\", conf.padding + titleHeight + conf.dividerMargin + membersBox.height);\n const methods = g.append(\"text\").attr(\"x\", conf.padding).attr(\"y\", titleHeight + 2 * conf.dividerMargin + membersBox.height + conf.textHeight).attr(\"fill\", \"white\").attr(\"class\", \"classText\");\n isFirst = true;\n classDef.methods.forEach(function(method) {\n addTspan(methods, method, isFirst, conf);\n isFirst = false;\n });\n }\n const classBox = g.node().getBBox();\n var cssClassStr = \" \";\n if (classDef.cssClasses.length > 0) {\n cssClassStr = cssClassStr + classDef.cssClasses.join(\" \");\n }\n const rect = g.insert(\"rect\", \":first-child\").attr(\"x\", 0).attr(\"y\", 0).attr(\"width\", classBox.width + 2 * conf.padding).attr(\"height\", classBox.height + conf.padding + 0.5 * conf.dividerMargin).attr(\"class\", cssClassStr);\n const rectWidth = rect.node().getBBox().width;\n title.node().childNodes.forEach(function(x) {\n x.setAttribute(\"x\", (rectWidth - x.getBBox().width) / 2);\n });\n if (classDef.tooltip) {\n title.insert(\"title\").text(classDef.tooltip);\n }\n if (membersLine) {\n membersLine.attr(\"x2\", rectWidth);\n }\n if (methodsLine) {\n methodsLine.attr(\"x2\", rectWidth);\n }\n classInfo.width = rectWidth;\n classInfo.height = classBox.height + conf.padding + 0.5 * conf.dividerMargin;\n return classInfo;\n}, \"drawClass\");\nvar getClassTitleString = /* @__PURE__ */ __name(function(classDef) {\n let classTitleString = classDef.id;\n if (classDef.type) {\n classTitleString += \"<\" + parseGenericTypes(classDef.type) + \">\";\n }\n return classTitleString;\n}, \"getClassTitleString\");\nvar drawNote = /* @__PURE__ */ __name(function(elem, note, conf, _diagObj) {\n log.debug(\"Rendering note \", note, conf);\n const id = note.id;\n const noteInfo = {\n id,\n text: note.text,\n width: 0,\n height: 0\n };\n const g = elem.append(\"g\").attr(\"id\", id).attr(\"class\", \"classGroup\");\n let text = g.append(\"text\").attr(\"y\", conf.textHeight + conf.padding).attr(\"x\", 0);\n const lines = JSON.parse(`\"${note.text}\"`).split(\"\\n\");\n lines.forEach(function(line2) {\n log.debug(`Adding line: ${line2}`);\n text.append(\"tspan\").text(line2).attr(\"class\", \"title\").attr(\"dy\", conf.textHeight);\n });\n const noteBox = g.node().getBBox();\n const rect = g.insert(\"rect\", \":first-child\").attr(\"x\", 0).attr(\"y\", 0).attr(\"width\", noteBox.width + 2 * conf.padding).attr(\n \"height\",\n noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin\n );\n const rectWidth = rect.node().getBBox().width;\n text.node().childNodes.forEach(function(x) {\n x.setAttribute(\"x\", (rectWidth - x.getBBox().width) / 2);\n });\n noteInfo.width = rectWidth;\n noteInfo.height = noteBox.height + lines.length * conf.textHeight + conf.padding + 0.5 * conf.dividerMargin;\n return noteInfo;\n}, \"drawNote\");\nvar addTspan = /* @__PURE__ */ __name(function(textEl, member, isFirst, conf) {\n const { displayText, cssStyle } = member.getDisplayDetails();\n const tSpan = textEl.append(\"tspan\").attr(\"x\", conf.padding).text(displayText);\n if (cssStyle !== \"\") {\n tSpan.attr(\"style\", member.cssStyle);\n }\n if (!isFirst) {\n tSpan.attr(\"dy\", conf.textHeight);\n }\n}, \"addTspan\");\nvar svgDraw_default = {\n getClassTitleString,\n drawClass,\n drawEdge,\n drawNote\n};\n\n// src/diagrams/class/classRenderer.js\nvar idCache = {};\nvar padding = 20;\nvar getGraphId = /* @__PURE__ */ __name(function(label) {\n const foundEntry = Object.entries(idCache).find((entry) => entry[1].label === label);\n if (foundEntry) {\n return foundEntry[0];\n }\n}, \"getGraphId\");\nvar insertMarkers = /* @__PURE__ */ __name(function(elem) {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"extensionStart\").attr(\"class\", \"extension\").attr(\"refX\", 0).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 1,7 L18,13 V 1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"extensionEnd\").attr(\"refX\", 19).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 1,1 V 13 L18,7 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"compositionStart\").attr(\"class\", \"extension\").attr(\"refX\", 0).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L1,7 L9,1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"compositionEnd\").attr(\"refX\", 19).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L1,7 L9,1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"aggregationStart\").attr(\"class\", \"extension\").attr(\"refX\", 0).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L1,7 L9,1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"aggregationEnd\").attr(\"refX\", 19).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L1,7 L9,1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"dependencyStart\").attr(\"class\", \"extension\").attr(\"refX\", 0).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 5,7 L9,13 L1,7 L9,1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"dependencyEnd\").attr(\"refX\", 19).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L14,7 L9,1 Z\");\n}, \"insertMarkers\");\nvar draw = /* @__PURE__ */ __name(function(text, id, _version, diagObj) {\n const conf = getConfig().class;\n idCache = {};\n log.info(\"Rendering diagram \" + text);\n const securityLevel = getConfig().securityLevel;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select(sandboxElement.nodes()[0].contentDocument.body) : select(\"body\");\n const diagram2 = root.select(`[id='${id}']`);\n insertMarkers(diagram2);\n const g = new graphlib.Graph({\n multigraph: true\n });\n g.setGraph({\n isMultiGraph: true\n });\n g.setDefaultEdgeLabel(function() {\n return {};\n });\n const classes = diagObj.db.getClasses();\n const keys = [...classes.keys()];\n for (const key of keys) {\n const classDef = classes.get(key);\n const node = svgDraw_default.drawClass(diagram2, classDef, conf, diagObj);\n idCache[node.id] = node;\n g.setNode(node.id, node);\n log.info(\"Org height: \" + node.height);\n }\n const relations = diagObj.db.getRelations();\n relations.forEach(function(relation) {\n log.info(\n // cspell:ignore tjoho\n \"tjoho\" + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation)\n );\n g.setEdge(\n getGraphId(relation.id1),\n getGraphId(relation.id2),\n {\n relation\n },\n relation.title || \"DEFAULT\"\n );\n });\n const notes = diagObj.db.getNotes();\n notes.forEach(function(note) {\n log.debug(`Adding note: ${JSON.stringify(note)}`);\n const node = svgDraw_default.drawNote(diagram2, note, conf, diagObj);\n idCache[node.id] = node;\n g.setNode(node.id, node);\n if (note.class && classes.has(note.class)) {\n g.setEdge(\n note.id,\n getGraphId(note.class),\n {\n relation: {\n id1: note.id,\n id2: note.class,\n relation: {\n type1: \"none\",\n type2: \"none\",\n lineType: 10\n }\n }\n },\n \"DEFAULT\"\n );\n }\n });\n dagreLayout(g);\n g.nodes().forEach(function(v) {\n if (v !== void 0 && g.node(v) !== void 0) {\n log.debug(\"Node \" + v + \": \" + JSON.stringify(g.node(v)));\n root.select(\"#\" + (diagObj.db.lookUpDomId(v) || v)).attr(\n \"transform\",\n \"translate(\" + (g.node(v).x - g.node(v).width / 2) + \",\" + (g.node(v).y - g.node(v).height / 2) + \" )\"\n );\n }\n });\n g.edges().forEach(function(e) {\n if (e !== void 0 && g.edge(e) !== void 0) {\n log.debug(\"Edge \" + e.v + \" -> \" + e.w + \": \" + JSON.stringify(g.edge(e)));\n svgDraw_default.drawEdge(diagram2, g.edge(e), g.edge(e).relation, conf, diagObj);\n }\n });\n const svgBounds = diagram2.node().getBBox();\n const width = svgBounds.width + padding * 2;\n const height = svgBounds.height + padding * 2;\n configureSvgSize(diagram2, height, width, conf.useMaxWidth);\n const vBox = `${svgBounds.x - padding} ${svgBounds.y - padding} ${width} ${height}`;\n log.debug(`viewBox ${vBox}`);\n diagram2.attr(\"viewBox\", vBox);\n}, \"draw\");\nvar classRenderer_default = {\n draw\n};\n\n// src/diagrams/class/classDiagram.ts\nvar diagram = {\n parser: classDiagram_default,\n db: classDb_default,\n renderer: classRenderer_default,\n styles: styles_default,\n init: /* @__PURE__ */ __name((cnf) => {\n if (!cnf.class) {\n cnf.class = {};\n }\n cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;\n classDb_default.clear();\n }, \"init\")\n};\nexport {\n diagram\n};\n", "import {\n createLabel_default\n} from \"./chunk-YWFND7JV.mjs\";\nimport {\n getLineFunctionsWithOffset,\n getSubGraphTitleMargins\n} from \"./chunk-23ATMZXV.mjs\";\nimport {\n createText\n} from \"./chunk-5N55DQE6.mjs\";\nimport {\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n evaluate,\n getConfig2 as getConfig,\n log\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/dagre-wrapper/markers.js\nvar insertMarkers = /* @__PURE__ */ __name((elem, markerArray, type, id) => {\n markerArray.forEach((markerName) => {\n markers[markerName](elem, type, id);\n });\n}, \"insertMarkers\");\nvar extension = /* @__PURE__ */ __name((elem, type, id) => {\n log.trace(\"Making markers for \", id);\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-extensionStart\").attr(\"class\", \"marker extension \" + type).attr(\"refX\", 18).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 1,7 L18,13 V 1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-extensionEnd\").attr(\"class\", \"marker extension \" + type).attr(\"refX\", 1).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 1,1 V 13 L18,7 Z\");\n}, \"extension\");\nvar composition = /* @__PURE__ */ __name((elem, type, id) => {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-compositionStart\").attr(\"class\", \"marker composition \" + type).attr(\"refX\", 18).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L1,7 L9,1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-compositionEnd\").attr(\"class\", \"marker composition \" + type).attr(\"refX\", 1).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L1,7 L9,1 Z\");\n}, \"composition\");\nvar aggregation = /* @__PURE__ */ __name((elem, type, id) => {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-aggregationStart\").attr(\"class\", \"marker aggregation \" + type).attr(\"refX\", 18).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L1,7 L9,1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-aggregationEnd\").attr(\"class\", \"marker aggregation \" + type).attr(\"refX\", 1).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L1,7 L9,1 Z\");\n}, \"aggregation\");\nvar dependency = /* @__PURE__ */ __name((elem, type, id) => {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-dependencyStart\").attr(\"class\", \"marker dependency \" + type).attr(\"refX\", 6).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 5,7 L9,13 L1,7 L9,1 Z\");\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-dependencyEnd\").attr(\"class\", \"marker dependency \" + type).attr(\"refX\", 13).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 18,7 L9,13 L14,7 L9,1 Z\");\n}, \"dependency\");\nvar lollipop = /* @__PURE__ */ __name((elem, type, id) => {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-lollipopStart\").attr(\"class\", \"marker lollipop \" + type).attr(\"refX\", 13).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"circle\").attr(\"stroke\", \"black\").attr(\"fill\", \"transparent\").attr(\"cx\", 7).attr(\"cy\", 7).attr(\"r\", 6);\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-lollipopEnd\").attr(\"class\", \"marker lollipop \" + type).attr(\"refX\", 1).attr(\"refY\", 7).attr(\"markerWidth\", 190).attr(\"markerHeight\", 240).attr(\"orient\", \"auto\").append(\"circle\").attr(\"stroke\", \"black\").attr(\"fill\", \"transparent\").attr(\"cx\", 7).attr(\"cy\", 7).attr(\"r\", 6);\n}, \"lollipop\");\nvar point = /* @__PURE__ */ __name((elem, type, id) => {\n elem.append(\"marker\").attr(\"id\", id + \"_\" + type + \"-pointEnd\").attr(\"class\", \"marker \" + type).attr(\"viewBox\", \"0 0 10 10\").attr(\"refX\", 6).attr(\"refY\", 5).attr(\"markerUnits\", \"userSpaceOnUse\").attr(\"markerWidth\", 12).attr(\"markerHeight\", 12).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 0 0 L 10 5 L 0 10 z\").attr(\"class\", \"arrowMarkerPath\").style(\"stroke-width\", 1).style(\"stroke-dasharray\", \"1,0\");\n elem.append(\"marker\").attr(\"id\", id + \"_\" + type + \"-pointStart\").attr(\"class\", \"marker \" + type).attr(\"viewBox\", \"0 0 10 10\").attr(\"refX\", 4.5).attr(\"refY\", 5).attr(\"markerUnits\", \"userSpaceOnUse\").attr(\"markerWidth\", 12).attr(\"markerHeight\", 12).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 0 5 L 10 10 L 10 0 z\").attr(\"class\", \"arrowMarkerPath\").style(\"stroke-width\", 1).style(\"stroke-dasharray\", \"1,0\");\n}, \"point\");\nvar circle = /* @__PURE__ */ __name((elem, type, id) => {\n elem.append(\"marker\").attr(\"id\", id + \"_\" + type + \"-circleEnd\").attr(\"class\", \"marker \" + type).attr(\"viewBox\", \"0 0 10 10\").attr(\"refX\", 11).attr(\"refY\", 5).attr(\"markerUnits\", \"userSpaceOnUse\").attr(\"markerWidth\", 11).attr(\"markerHeight\", 11).attr(\"orient\", \"auto\").append(\"circle\").attr(\"cx\", \"5\").attr(\"cy\", \"5\").attr(\"r\", \"5\").attr(\"class\", \"arrowMarkerPath\").style(\"stroke-width\", 1).style(\"stroke-dasharray\", \"1,0\");\n elem.append(\"marker\").attr(\"id\", id + \"_\" + type + \"-circleStart\").attr(\"class\", \"marker \" + type).attr(\"viewBox\", \"0 0 10 10\").attr(\"refX\", -1).attr(\"refY\", 5).attr(\"markerUnits\", \"userSpaceOnUse\").attr(\"markerWidth\", 11).attr(\"markerHeight\", 11).attr(\"orient\", \"auto\").append(\"circle\").attr(\"cx\", \"5\").attr(\"cy\", \"5\").attr(\"r\", \"5\").attr(\"class\", \"arrowMarkerPath\").style(\"stroke-width\", 1).style(\"stroke-dasharray\", \"1,0\");\n}, \"circle\");\nvar cross = /* @__PURE__ */ __name((elem, type, id) => {\n elem.append(\"marker\").attr(\"id\", id + \"_\" + type + \"-crossEnd\").attr(\"class\", \"marker cross \" + type).attr(\"viewBox\", \"0 0 11 11\").attr(\"refX\", 12).attr(\"refY\", 5.2).attr(\"markerUnits\", \"userSpaceOnUse\").attr(\"markerWidth\", 11).attr(\"markerHeight\", 11).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 1,1 l 9,9 M 10,1 l -9,9\").attr(\"class\", \"arrowMarkerPath\").style(\"stroke-width\", 2).style(\"stroke-dasharray\", \"1,0\");\n elem.append(\"marker\").attr(\"id\", id + \"_\" + type + \"-crossStart\").attr(\"class\", \"marker cross \" + type).attr(\"viewBox\", \"0 0 11 11\").attr(\"refX\", -1).attr(\"refY\", 5.2).attr(\"markerUnits\", \"userSpaceOnUse\").attr(\"markerWidth\", 11).attr(\"markerHeight\", 11).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 1,1 l 9,9 M 10,1 l -9,9\").attr(\"class\", \"arrowMarkerPath\").style(\"stroke-width\", 2).style(\"stroke-dasharray\", \"1,0\");\n}, \"cross\");\nvar barb = /* @__PURE__ */ __name((elem, type, id) => {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", id + \"_\" + type + \"-barbEnd\").attr(\"refX\", 19).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 14).attr(\"markerUnits\", \"strokeWidth\").attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 19,7 L9,13 L14,7 L9,1 Z\");\n}, \"barb\");\nvar markers = {\n extension,\n composition,\n aggregation,\n dependency,\n lollipop,\n point,\n circle,\n cross,\n barb\n};\nvar markers_default = insertMarkers;\n\n// src/dagre-wrapper/edges.js\nimport { line, curveBasis, select } from \"d3\";\n\n// src/dagre-wrapper/edgeMarker.ts\nvar addEdgeMarkers = /* @__PURE__ */ __name((svgPath, edge, url, id, diagramType) => {\n if (edge.arrowTypeStart) {\n addEdgeMarker(svgPath, \"start\", edge.arrowTypeStart, url, id, diagramType);\n }\n if (edge.arrowTypeEnd) {\n addEdgeMarker(svgPath, \"end\", edge.arrowTypeEnd, url, id, diagramType);\n }\n}, \"addEdgeMarkers\");\nvar arrowTypesMap = {\n arrow_cross: \"cross\",\n arrow_point: \"point\",\n arrow_barb: \"barb\",\n arrow_circle: \"circle\",\n aggregation: \"aggregation\",\n extension: \"extension\",\n composition: \"composition\",\n dependency: \"dependency\",\n lollipop: \"lollipop\"\n};\nvar addEdgeMarker = /* @__PURE__ */ __name((svgPath, position, arrowType, url, id, diagramType) => {\n const endMarkerType = arrowTypesMap[arrowType];\n if (!endMarkerType) {\n log.warn(`Unknown arrow type: ${arrowType}`);\n return;\n }\n const suffix = position === \"start\" ? \"Start\" : \"End\";\n svgPath.attr(`marker-${position}`, `url(${url}#${id}_${diagramType}-${endMarkerType}${suffix})`);\n}, \"addEdgeMarker\");\n\n// src/dagre-wrapper/edges.js\nvar edgeLabels = {};\nvar terminalLabels = {};\nvar clear = /* @__PURE__ */ __name(() => {\n edgeLabels = {};\n terminalLabels = {};\n}, \"clear\");\nvar insertEdgeLabel = /* @__PURE__ */ __name((elem, edge) => {\n const config = getConfig();\n const useHtmlLabels = evaluate(config.flowchart.htmlLabels);\n const labelElement = edge.labelType === \"markdown\" ? createText(\n elem,\n edge.label,\n {\n style: edge.labelStyle,\n useHtmlLabels,\n addSvgBackground: true\n },\n config\n ) : createLabel_default(edge.label, edge.labelStyle);\n const edgeLabel = elem.insert(\"g\").attr(\"class\", \"edgeLabel\");\n const label = edgeLabel.insert(\"g\").attr(\"class\", \"label\");\n label.node().appendChild(labelElement);\n let bbox = labelElement.getBBox();\n if (useHtmlLabels) {\n const div = labelElement.children[0];\n const dv = select(labelElement);\n bbox = div.getBoundingClientRect();\n dv.attr(\"width\", bbox.width);\n dv.attr(\"height\", bbox.height);\n }\n label.attr(\"transform\", \"translate(\" + -bbox.width / 2 + \", \" + -bbox.height / 2 + \")\");\n edgeLabels[edge.id] = edgeLabel;\n edge.width = bbox.width;\n edge.height = bbox.height;\n let fo;\n if (edge.startLabelLeft) {\n const startLabelElement = createLabel_default(edge.startLabelLeft, edge.labelStyle);\n const startEdgeLabelLeft = elem.insert(\"g\").attr(\"class\", \"edgeTerminals\");\n const inner = startEdgeLabelLeft.insert(\"g\").attr(\"class\", \"inner\");\n fo = inner.node().appendChild(startLabelElement);\n const slBox = startLabelElement.getBBox();\n inner.attr(\"transform\", \"translate(\" + -slBox.width / 2 + \", \" + -slBox.height / 2 + \")\");\n if (!terminalLabels[edge.id]) {\n terminalLabels[edge.id] = {};\n }\n terminalLabels[edge.id].startLeft = startEdgeLabelLeft;\n setTerminalWidth(fo, edge.startLabelLeft);\n }\n if (edge.startLabelRight) {\n const startLabelElement = createLabel_default(edge.startLabelRight, edge.labelStyle);\n const startEdgeLabelRight = elem.insert(\"g\").attr(\"class\", \"edgeTerminals\");\n const inner = startEdgeLabelRight.insert(\"g\").attr(\"class\", \"inner\");\n fo = startEdgeLabelRight.node().appendChild(startLabelElement);\n inner.node().appendChild(startLabelElement);\n const slBox = startLabelElement.getBBox();\n inner.attr(\"transform\", \"translate(\" + -slBox.width / 2 + \", \" + -slBox.height / 2 + \")\");\n if (!terminalLabels[edge.id]) {\n terminalLabels[edge.id] = {};\n }\n terminalLabels[edge.id].startRight = startEdgeLabelRight;\n setTerminalWidth(fo, edge.startLabelRight);\n }\n if (edge.endLabelLeft) {\n const endLabelElement = createLabel_default(edge.endLabelLeft, edge.labelStyle);\n const endEdgeLabelLeft = elem.insert(\"g\").attr(\"class\", \"edgeTerminals\");\n const inner = endEdgeLabelLeft.insert(\"g\").attr(\"class\", \"inner\");\n fo = inner.node().appendChild(endLabelElement);\n const slBox = endLabelElement.getBBox();\n inner.attr(\"transform\", \"translate(\" + -slBox.width / 2 + \", \" + -slBox.height / 2 + \")\");\n endEdgeLabelLeft.node().appendChild(endLabelElement);\n if (!terminalLabels[edge.id]) {\n terminalLabels[edge.id] = {};\n }\n terminalLabels[edge.id].endLeft = endEdgeLabelLeft;\n setTerminalWidth(fo, edge.endLabelLeft);\n }\n if (edge.endLabelRight) {\n const endLabelElement = createLabel_default(edge.endLabelRight, edge.labelStyle);\n const endEdgeLabelRight = elem.insert(\"g\").attr(\"class\", \"edgeTerminals\");\n const inner = endEdgeLabelRight.insert(\"g\").attr(\"class\", \"inner\");\n fo = inner.node().appendChild(endLabelElement);\n const slBox = endLabelElement.getBBox();\n inner.attr(\"transform\", \"translate(\" + -slBox.width / 2 + \", \" + -slBox.height / 2 + \")\");\n endEdgeLabelRight.node().appendChild(endLabelElement);\n if (!terminalLabels[edge.id]) {\n terminalLabels[edge.id] = {};\n }\n terminalLabels[edge.id].endRight = endEdgeLabelRight;\n setTerminalWidth(fo, edge.endLabelRight);\n }\n return labelElement;\n}, \"insertEdgeLabel\");\nfunction setTerminalWidth(fo, value) {\n if (getConfig().flowchart.htmlLabels && fo) {\n fo.style.width = value.length * 9 + \"px\";\n fo.style.height = \"12px\";\n }\n}\n__name(setTerminalWidth, \"setTerminalWidth\");\nvar positionEdgeLabel = /* @__PURE__ */ __name((edge, paths) => {\n log.debug(\"Moving label abc88 \", edge.id, edge.label, edgeLabels[edge.id], paths);\n let path = paths.updatedPath ? paths.updatedPath : paths.originalPath;\n const siteConfig = getConfig();\n const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig);\n if (edge.label) {\n const el = edgeLabels[edge.id];\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcLabelPosition(path);\n log.debug(\n \"Moving label \" + edge.label + \" from (\",\n x,\n \",\",\n y,\n \") to (\",\n pos.x,\n \",\",\n pos.y,\n \") abc88\"\n );\n if (paths.updatedPath) {\n x = pos.x;\n y = pos.y;\n }\n }\n el.attr(\"transform\", `translate(${x}, ${y + subGraphTitleTotalMargin / 2})`);\n }\n if (edge.startLabelLeft) {\n const el = terminalLabels[edge.id].startLeft;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeStart ? 10 : 0, \"start_left\", path);\n x = pos.x;\n y = pos.y;\n }\n el.attr(\"transform\", `translate(${x}, ${y})`);\n }\n if (edge.startLabelRight) {\n const el = terminalLabels[edge.id].startRight;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcTerminalLabelPosition(\n edge.arrowTypeStart ? 10 : 0,\n \"start_right\",\n path\n );\n x = pos.x;\n y = pos.y;\n }\n el.attr(\"transform\", `translate(${x}, ${y})`);\n }\n if (edge.endLabelLeft) {\n const el = terminalLabels[edge.id].endLeft;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, \"end_left\", path);\n x = pos.x;\n y = pos.y;\n }\n el.attr(\"transform\", `translate(${x}, ${y})`);\n }\n if (edge.endLabelRight) {\n const el = terminalLabels[edge.id].endRight;\n let x = edge.x;\n let y = edge.y;\n if (path) {\n const pos = utils_default.calcTerminalLabelPosition(edge.arrowTypeEnd ? 10 : 0, \"end_right\", path);\n x = pos.x;\n y = pos.y;\n }\n el.attr(\"transform\", `translate(${x}, ${y})`);\n }\n}, \"positionEdgeLabel\");\nvar outsideNode = /* @__PURE__ */ __name((node, point2) => {\n const x = node.x;\n const y = node.y;\n const dx = Math.abs(point2.x - x);\n const dy = Math.abs(point2.y - y);\n const w = node.width / 2;\n const h = node.height / 2;\n if (dx >= w || dy >= h) {\n return true;\n }\n return false;\n}, \"outsideNode\");\nvar intersection = /* @__PURE__ */ __name((node, outsidePoint, insidePoint) => {\n log.debug(`intersection calc abc89:\n outsidePoint: ${JSON.stringify(outsidePoint)}\n insidePoint : ${JSON.stringify(insidePoint)}\n node : x:${node.x} y:${node.y} w:${node.width} h:${node.height}`);\n const x = node.x;\n const y = node.y;\n const dx = Math.abs(x - insidePoint.x);\n const w = node.width / 2;\n let r = insidePoint.x < outsidePoint.x ? w - dx : w + dx;\n const h = node.height / 2;\n const Q = Math.abs(outsidePoint.y - insidePoint.y);\n const R = Math.abs(outsidePoint.x - insidePoint.x);\n if (Math.abs(y - outsidePoint.y) * w > Math.abs(x - outsidePoint.x) * h) {\n let q = insidePoint.y < outsidePoint.y ? outsidePoint.y - h - y : y - h - outsidePoint.y;\n r = R * q / Q;\n const res = {\n x: insidePoint.x < outsidePoint.x ? insidePoint.x + r : insidePoint.x - R + r,\n y: insidePoint.y < outsidePoint.y ? insidePoint.y + Q - q : insidePoint.y - Q + q\n };\n if (r === 0) {\n res.x = outsidePoint.x;\n res.y = outsidePoint.y;\n }\n if (R === 0) {\n res.x = outsidePoint.x;\n }\n if (Q === 0) {\n res.y = outsidePoint.y;\n }\n log.debug(`abc89 topp/bott calc, Q ${Q}, q ${q}, R ${R}, r ${r}`, res);\n return res;\n } else {\n if (insidePoint.x < outsidePoint.x) {\n r = outsidePoint.x - w - x;\n } else {\n r = x - w - outsidePoint.x;\n }\n let q = Q * r / R;\n let _x = insidePoint.x < outsidePoint.x ? insidePoint.x + R - r : insidePoint.x - R + r;\n let _y = insidePoint.y < outsidePoint.y ? insidePoint.y + q : insidePoint.y - q;\n log.debug(`sides calc abc89, Q ${Q}, q ${q}, R ${R}, r ${r}`, { _x, _y });\n if (r === 0) {\n _x = outsidePoint.x;\n _y = outsidePoint.y;\n }\n if (R === 0) {\n _x = outsidePoint.x;\n }\n if (Q === 0) {\n _y = outsidePoint.y;\n }\n return { x: _x, y: _y };\n }\n}, \"intersection\");\nvar cutPathAtIntersect = /* @__PURE__ */ __name((_points, boundaryNode) => {\n log.debug(\"abc88 cutPathAtIntersect\", _points, boundaryNode);\n let points = [];\n let lastPointOutside = _points[0];\n let isInside = false;\n _points.forEach((point2) => {\n if (!outsideNode(boundaryNode, point2) && !isInside) {\n const inter = intersection(boundaryNode, lastPointOutside, point2);\n let pointPresent = false;\n points.forEach((p) => {\n pointPresent = pointPresent || p.x === inter.x && p.y === inter.y;\n });\n if (!points.some((e) => e.x === inter.x && e.y === inter.y)) {\n points.push(inter);\n }\n isInside = true;\n } else {\n lastPointOutside = point2;\n if (!isInside) {\n points.push(point2);\n }\n }\n });\n return points;\n}, \"cutPathAtIntersect\");\nvar insertEdge = /* @__PURE__ */ __name(function(elem, e, edge, clusterDb, diagramType, graph, id) {\n let points = edge.points;\n log.debug(\"abc88 InsertEdge: edge=\", edge, \"e=\", e);\n let pointsHasChanged = false;\n const tail = graph.node(e.v);\n var head = graph.node(e.w);\n if (head?.intersect && tail?.intersect) {\n points = points.slice(1, edge.points.length - 1);\n points.unshift(tail.intersect(points[0]));\n points.push(head.intersect(points[points.length - 1]));\n }\n if (edge.toCluster) {\n log.debug(\"to cluster abc88\", clusterDb[edge.toCluster]);\n points = cutPathAtIntersect(edge.points, clusterDb[edge.toCluster].node);\n pointsHasChanged = true;\n }\n if (edge.fromCluster) {\n log.debug(\"from cluster abc88\", clusterDb[edge.fromCluster]);\n points = cutPathAtIntersect(points.reverse(), clusterDb[edge.fromCluster].node).reverse();\n pointsHasChanged = true;\n }\n const lineData = points.filter((p) => !Number.isNaN(p.y));\n let curve = curveBasis;\n if (edge.curve && (diagramType === \"graph\" || diagramType === \"flowchart\")) {\n curve = edge.curve;\n }\n const { x, y } = getLineFunctionsWithOffset(edge);\n const lineFunction = line().x(x).y(y).curve(curve);\n let strokeClasses;\n switch (edge.thickness) {\n case \"normal\":\n strokeClasses = \"edge-thickness-normal\";\n break;\n case \"thick\":\n strokeClasses = \"edge-thickness-thick\";\n break;\n case \"invisible\":\n strokeClasses = \"edge-thickness-thick\";\n break;\n default:\n strokeClasses = \"\";\n }\n switch (edge.pattern) {\n case \"solid\":\n strokeClasses += \" edge-pattern-solid\";\n break;\n case \"dotted\":\n strokeClasses += \" edge-pattern-dotted\";\n break;\n case \"dashed\":\n strokeClasses += \" edge-pattern-dashed\";\n break;\n }\n const svgPath = elem.append(\"path\").attr(\"d\", lineFunction(lineData)).attr(\"id\", edge.id).attr(\"class\", \" \" + strokeClasses + (edge.classes ? \" \" + edge.classes : \"\")).attr(\"style\", edge.style);\n let url = \"\";\n if (getConfig().flowchart.arrowMarkerAbsolute || getConfig().state.arrowMarkerAbsolute) {\n url = window.location.protocol + \"//\" + window.location.host + window.location.pathname + window.location.search;\n url = url.replace(/\\(/g, \"\\\\(\");\n url = url.replace(/\\)/g, \"\\\\)\");\n }\n addEdgeMarkers(svgPath, edge, url, id, diagramType);\n let paths = {};\n if (pointsHasChanged) {\n paths.updatedPath = points;\n }\n paths.originalPath = edge.points;\n return paths;\n}, \"insertEdge\");\n\nexport {\n markers_default,\n clear,\n insertEdgeLabel,\n positionEdgeLabel,\n insertEdge\n};\n", "import {\n clear as clear2,\n insertEdge,\n insertEdgeLabel,\n markers_default,\n positionEdgeLabel\n} from \"./chunk-UGV5ZQQN.mjs\";\nimport {\n classDb_default,\n classDiagram_default,\n styles_default\n} from \"./chunk-BAVOGKFW.mjs\";\nimport {\n clear,\n createLabel_default,\n insertNode,\n intersect_rect_default,\n positionNode,\n setNodeElem,\n updateNodeBounds\n} from \"./chunk-YWFND7JV.mjs\";\nimport {\n getSubGraphTitleMargins\n} from \"./chunk-23ATMZXV.mjs\";\nimport {\n createText\n} from \"./chunk-5N55DQE6.mjs\";\nimport {\n getEdgeId,\n getStylesFromArray,\n interpolateToCurve,\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n common_default,\n evaluate,\n getConfig2 as getConfig,\n log,\n setupGraphViewbox\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/class/classRenderer-v2.ts\nimport { select as select2, curveLinear } from \"d3\";\nimport * as graphlib2 from \"dagre-d3-es/src/graphlib/index.js\";\n\n// src/dagre-wrapper/index.js\nimport { layout as dagreLayout } from \"dagre-d3-es/src/dagre/index.js\";\nimport * as graphlibJson2 from \"dagre-d3-es/src/graphlib/json.js\";\n\n// src/dagre-wrapper/mermaid-graphlib.js\nimport * as graphlibJson from \"dagre-d3-es/src/graphlib/json.js\";\nimport * as graphlib from \"dagre-d3-es/src/graphlib/index.js\";\nvar clusterDb = {};\nvar descendants = {};\nvar parents = {};\nvar clear3 = /* @__PURE__ */ __name(() => {\n descendants = {};\n parents = {};\n clusterDb = {};\n}, \"clear\");\nvar isDescendant = /* @__PURE__ */ __name((id, ancestorId) => {\n log.trace(\"In isDescendant\", ancestorId, \" \", id, \" = \", descendants[ancestorId].includes(id));\n if (descendants[ancestorId].includes(id)) {\n return true;\n }\n return false;\n}, \"isDescendant\");\nvar edgeInCluster = /* @__PURE__ */ __name((edge, clusterId) => {\n log.info(\"Descendants of \", clusterId, \" is \", descendants[clusterId]);\n log.info(\"Edge is \", edge);\n if (edge.v === clusterId) {\n return false;\n }\n if (edge.w === clusterId) {\n return false;\n }\n if (!descendants[clusterId]) {\n log.debug(\"Tilt, \", clusterId, \",not in descendants\");\n return false;\n }\n return descendants[clusterId].includes(edge.v) || isDescendant(edge.v, clusterId) || isDescendant(edge.w, clusterId) || descendants[clusterId].includes(edge.w);\n}, \"edgeInCluster\");\nvar copy = /* @__PURE__ */ __name((clusterId, graph, newGraph, rootId) => {\n log.warn(\n \"Copying children of \",\n clusterId,\n \"root\",\n rootId,\n \"data\",\n graph.node(clusterId),\n rootId\n );\n const nodes = graph.children(clusterId) || [];\n if (clusterId !== rootId) {\n nodes.push(clusterId);\n }\n log.warn(\"Copying (nodes) clusterId\", clusterId, \"nodes\", nodes);\n nodes.forEach((node) => {\n if (graph.children(node).length > 0) {\n copy(node, graph, newGraph, rootId);\n } else {\n const data = graph.node(node);\n log.info(\"cp \", node, \" to \", rootId, \" with parent \", clusterId);\n newGraph.setNode(node, data);\n if (rootId !== graph.parent(node)) {\n log.warn(\"Setting parent\", node, graph.parent(node));\n newGraph.setParent(node, graph.parent(node));\n }\n if (clusterId !== rootId && node !== clusterId) {\n log.debug(\"Setting parent\", node, clusterId);\n newGraph.setParent(node, clusterId);\n } else {\n log.info(\"In copy \", clusterId, \"root\", rootId, \"data\", graph.node(clusterId), rootId);\n log.debug(\n \"Not Setting parent for node=\",\n node,\n \"cluster!==rootId\",\n clusterId !== rootId,\n \"node!==clusterId\",\n node !== clusterId\n );\n }\n const edges = graph.edges(node);\n log.debug(\"Copying Edges\", edges);\n edges.forEach((edge) => {\n log.info(\"Edge\", edge);\n const data2 = graph.edge(edge.v, edge.w, edge.name);\n log.info(\"Edge data\", data2, rootId);\n try {\n if (edgeInCluster(edge, rootId)) {\n log.info(\"Copying as \", edge.v, edge.w, data2, edge.name);\n newGraph.setEdge(edge.v, edge.w, data2, edge.name);\n log.info(\"newGraph edges \", newGraph.edges(), newGraph.edge(newGraph.edges()[0]));\n } else {\n log.info(\n \"Skipping copy of edge \",\n edge.v,\n \"-->\",\n edge.w,\n \" rootId: \",\n rootId,\n \" clusterId:\",\n clusterId\n );\n }\n } catch (e) {\n log.error(e);\n }\n });\n }\n log.debug(\"Removing node\", node);\n graph.removeNode(node);\n });\n}, \"copy\");\nvar extractDescendants = /* @__PURE__ */ __name((id, graph) => {\n const children = graph.children(id);\n let res = [...children];\n for (const child of children) {\n parents[child] = id;\n res = [...res, ...extractDescendants(child, graph)];\n }\n return res;\n}, \"extractDescendants\");\nvar findNonClusterChild = /* @__PURE__ */ __name((id, graph) => {\n log.trace(\"Searching\", id);\n const children = graph.children(id);\n log.trace(\"Searching children of id \", id, children);\n if (children.length < 1) {\n log.trace(\"This is a valid node\", id);\n return id;\n }\n for (const child of children) {\n const _id = findNonClusterChild(child, graph);\n if (_id) {\n log.trace(\"Found replacement for\", id, \" => \", _id);\n return _id;\n }\n }\n}, \"findNonClusterChild\");\nvar getAnchorId = /* @__PURE__ */ __name((id) => {\n if (!clusterDb[id]) {\n return id;\n }\n if (!clusterDb[id].externalConnections) {\n return id;\n }\n if (clusterDb[id]) {\n return clusterDb[id].id;\n }\n return id;\n}, \"getAnchorId\");\nvar adjustClustersAndEdges = /* @__PURE__ */ __name((graph, depth) => {\n if (!graph || depth > 10) {\n log.debug(\"Opting out, no graph \");\n return;\n } else {\n log.debug(\"Opting in, graph \");\n }\n graph.nodes().forEach(function(id) {\n const children = graph.children(id);\n if (children.length > 0) {\n log.warn(\n \"Cluster identified\",\n id,\n \" Replacement id in edges: \",\n findNonClusterChild(id, graph)\n );\n descendants[id] = extractDescendants(id, graph);\n clusterDb[id] = { id: findNonClusterChild(id, graph), clusterData: graph.node(id) };\n }\n });\n graph.nodes().forEach(function(id) {\n const children = graph.children(id);\n const edges = graph.edges();\n if (children.length > 0) {\n log.debug(\"Cluster identified\", id, descendants);\n edges.forEach((edge) => {\n if (edge.v !== id && edge.w !== id) {\n const d1 = isDescendant(edge.v, id);\n const d2 = isDescendant(edge.w, id);\n if (d1 ^ d2) {\n log.warn(\"Edge: \", edge, \" leaves cluster \", id);\n log.warn(\"Descendants of XXX \", id, \": \", descendants[id]);\n clusterDb[id].externalConnections = true;\n }\n }\n });\n } else {\n log.debug(\"Not a cluster \", id, descendants);\n }\n });\n for (let id of Object.keys(clusterDb)) {\n const nonClusterChild = clusterDb[id].id;\n const parent = graph.parent(nonClusterChild);\n if (parent !== id && clusterDb[parent] && !clusterDb[parent].externalConnections) {\n clusterDb[id].id = parent;\n }\n }\n graph.edges().forEach(function(e) {\n const edge = graph.edge(e);\n log.warn(\"Edge \" + e.v + \" -> \" + e.w + \": \" + JSON.stringify(e));\n log.warn(\"Edge \" + e.v + \" -> \" + e.w + \": \" + JSON.stringify(graph.edge(e)));\n let v = e.v;\n let w = e.w;\n log.warn(\n \"Fix XXX\",\n clusterDb,\n \"ids:\",\n e.v,\n e.w,\n \"Translating: \",\n clusterDb[e.v],\n \" --- \",\n clusterDb[e.w]\n );\n if (clusterDb[e.v] && clusterDb[e.w] && clusterDb[e.v] === clusterDb[e.w]) {\n log.warn(\"Fixing and trixing link to self - removing XXX\", e.v, e.w, e.name);\n log.warn(\"Fixing and trixing - removing XXX\", e.v, e.w, e.name);\n v = getAnchorId(e.v);\n w = getAnchorId(e.w);\n graph.removeEdge(e.v, e.w, e.name);\n const specialId = e.w + \"---\" + e.v;\n graph.setNode(specialId, {\n domId: specialId,\n id: specialId,\n labelStyle: \"\",\n labelText: edge.label,\n padding: 0,\n shape: \"labelRect\",\n style: \"\"\n });\n const edge1 = structuredClone(edge);\n const edge2 = structuredClone(edge);\n edge1.label = \"\";\n edge1.arrowTypeEnd = \"none\";\n edge2.label = \"\";\n edge1.fromCluster = e.v;\n edge2.toCluster = e.v;\n graph.setEdge(v, specialId, edge1, e.name + \"-cyclic-special\");\n graph.setEdge(specialId, w, edge2, e.name + \"-cyclic-special\");\n } else if (clusterDb[e.v] || clusterDb[e.w]) {\n log.warn(\"Fixing and trixing - removing XXX\", e.v, e.w, e.name);\n v = getAnchorId(e.v);\n w = getAnchorId(e.w);\n graph.removeEdge(e.v, e.w, e.name);\n if (v !== e.v) {\n const parent = graph.parent(v);\n clusterDb[parent].externalConnections = true;\n edge.fromCluster = e.v;\n }\n if (w !== e.w) {\n const parent = graph.parent(w);\n clusterDb[parent].externalConnections = true;\n edge.toCluster = e.w;\n }\n log.warn(\"Fix Replacing with XXX\", v, w, e.name);\n graph.setEdge(v, w, edge, e.name);\n }\n });\n log.warn(\"Adjusted Graph\", graphlibJson.write(graph));\n extractor(graph, 0);\n log.trace(clusterDb);\n}, \"adjustClustersAndEdges\");\nvar extractor = /* @__PURE__ */ __name((graph, depth) => {\n log.warn(\"extractor - \", depth, graphlibJson.write(graph), graph.children(\"D\"));\n if (depth > 10) {\n log.error(\"Bailing out\");\n return;\n }\n let nodes = graph.nodes();\n let hasChildren = false;\n for (const node of nodes) {\n const children = graph.children(node);\n hasChildren = hasChildren || children.length > 0;\n }\n if (!hasChildren) {\n log.debug(\"Done, no node has children\", graph.nodes());\n return;\n }\n log.debug(\"Nodes = \", nodes, depth);\n for (const node of nodes) {\n log.debug(\n \"Extracting node\",\n node,\n clusterDb,\n clusterDb[node] && !clusterDb[node].externalConnections,\n !graph.parent(node),\n graph.node(node),\n graph.children(\"D\"),\n \" Depth \",\n depth\n );\n if (!clusterDb[node]) {\n log.debug(\"Not a cluster\", node, depth);\n } else if (!clusterDb[node].externalConnections && // !graph.parent(node) &&\n graph.children(node) && graph.children(node).length > 0) {\n log.warn(\n \"Cluster without external connections, without a parent and with children\",\n node,\n depth\n );\n const graphSettings = graph.graph();\n let dir = graphSettings.rankdir === \"TB\" ? \"LR\" : \"TB\";\n if (clusterDb[node]?.clusterData?.dir) {\n dir = clusterDb[node].clusterData.dir;\n log.warn(\"Fixing dir\", clusterDb[node].clusterData.dir, dir);\n }\n const clusterGraph = new graphlib.Graph({\n multigraph: true,\n compound: true\n }).setGraph({\n rankdir: dir,\n // Todo: set proper spacing\n nodesep: 50,\n ranksep: 50,\n marginx: 8,\n marginy: 8\n }).setDefaultEdgeLabel(function() {\n return {};\n });\n log.warn(\"Old graph before copy\", graphlibJson.write(graph));\n copy(node, graph, clusterGraph, node);\n graph.setNode(node, {\n clusterNode: true,\n id: node,\n clusterData: clusterDb[node].clusterData,\n labelText: clusterDb[node].labelText,\n graph: clusterGraph\n });\n log.warn(\"New graph after copy node: (\", node, \")\", graphlibJson.write(clusterGraph));\n log.debug(\"Old graph after copy\", graphlibJson.write(graph));\n } else {\n log.warn(\n \"Cluster ** \",\n node,\n \" **not meeting the criteria !externalConnections:\",\n !clusterDb[node].externalConnections,\n \" no parent: \",\n !graph.parent(node),\n \" children \",\n graph.children(node) && graph.children(node).length > 0,\n graph.children(\"D\"),\n depth\n );\n log.debug(clusterDb);\n }\n }\n nodes = graph.nodes();\n log.warn(\"New list of nodes\", nodes);\n for (const node of nodes) {\n const data = graph.node(node);\n log.warn(\" Now next level\", node, data);\n if (data.clusterNode) {\n extractor(data.graph, depth + 1);\n }\n }\n}, \"extractor\");\nvar sorter = /* @__PURE__ */ __name((graph, nodes) => {\n if (nodes.length === 0) {\n return [];\n }\n let result = Object.assign(nodes);\n nodes.forEach((node) => {\n const children = graph.children(node);\n const sorted = sorter(graph, children);\n result = [...result, ...sorted];\n });\n return result;\n}, \"sorter\");\nvar sortNodesByHierarchy = /* @__PURE__ */ __name((graph) => sorter(graph, graph.children()), \"sortNodesByHierarchy\");\n\n// src/dagre-wrapper/clusters.js\nimport { select } from \"d3\";\nvar rect = /* @__PURE__ */ __name((parent, node) => {\n log.info(\"Creating subgraph rect for \", node.id, node);\n const siteConfig = getConfig();\n const shapeSvg = parent.insert(\"g\").attr(\"class\", \"cluster\" + (node.class ? \" \" + node.class : \"\")).attr(\"id\", node.id);\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const useHtmlLabels = evaluate(siteConfig.flowchart.htmlLabels);\n const label = shapeSvg.insert(\"g\").attr(\"class\", \"cluster-label\");\n const text = node.labelType === \"markdown\" ? createText(label, node.labelText, { style: node.labelStyle, useHtmlLabels }, siteConfig) : label.node().appendChild(createLabel_default(node.labelText, node.labelStyle, void 0, true));\n let bbox = text.getBBox();\n if (evaluate(siteConfig.flowchart.htmlLabels)) {\n const div = text.children[0];\n const dv = select(text);\n bbox = div.getBoundingClientRect();\n dv.attr(\"width\", bbox.width);\n dv.attr(\"height\", bbox.height);\n }\n const padding = 0 * node.padding;\n const halfPadding = padding / 2;\n const width = node.width <= bbox.width + padding ? bbox.width + padding : node.width;\n if (node.width <= bbox.width + padding) {\n node.diff = (bbox.width - node.width) / 2 - node.padding / 2;\n } else {\n node.diff = -node.padding / 2;\n }\n log.trace(\"Data \", node, JSON.stringify(node));\n rect2.attr(\"style\", node.style).attr(\"rx\", node.rx).attr(\"ry\", node.ry).attr(\"x\", node.x - width / 2).attr(\"y\", node.y - node.height / 2 - halfPadding).attr(\"width\", width).attr(\"height\", node.height + padding);\n const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);\n if (useHtmlLabels) {\n label.attr(\n \"transform\",\n // This puts the label on top of the box instead of inside it\n `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 + subGraphTitleTopMargin})`\n );\n } else {\n label.attr(\n \"transform\",\n // This puts the label on top of the box instead of inside it\n `translate(${node.x}, ${node.y - node.height / 2 + subGraphTitleTopMargin})`\n );\n }\n const rectBox = rect2.node().getBBox();\n node.width = rectBox.width;\n node.height = rectBox.height;\n node.intersect = function(point) {\n return intersect_rect_default(node, point);\n };\n return shapeSvg;\n}, \"rect\");\nvar noteGroup = /* @__PURE__ */ __name((parent, node) => {\n const shapeSvg = parent.insert(\"g\").attr(\"class\", \"note-cluster\").attr(\"id\", node.id);\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const padding = 0 * node.padding;\n const halfPadding = padding / 2;\n rect2.attr(\"rx\", node.rx).attr(\"ry\", node.ry).attr(\"x\", node.x - node.width / 2 - halfPadding).attr(\"y\", node.y - node.height / 2 - halfPadding).attr(\"width\", node.width + padding).attr(\"height\", node.height + padding).attr(\"fill\", \"none\");\n const rectBox = rect2.node().getBBox();\n node.width = rectBox.width;\n node.height = rectBox.height;\n node.intersect = function(point) {\n return intersect_rect_default(node, point);\n };\n return shapeSvg;\n}, \"noteGroup\");\nvar roundedWithTitle = /* @__PURE__ */ __name((parent, node) => {\n const siteConfig = getConfig();\n const shapeSvg = parent.insert(\"g\").attr(\"class\", node.classes).attr(\"id\", node.id);\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const label = shapeSvg.insert(\"g\").attr(\"class\", \"cluster-label\");\n const innerRect = shapeSvg.append(\"rect\");\n const text = label.node().appendChild(createLabel_default(node.labelText, node.labelStyle, void 0, true));\n let bbox = text.getBBox();\n if (evaluate(siteConfig.flowchart.htmlLabels)) {\n const div = text.children[0];\n const dv = select(text);\n bbox = div.getBoundingClientRect();\n dv.attr(\"width\", bbox.width);\n dv.attr(\"height\", bbox.height);\n }\n bbox = text.getBBox();\n const padding = 0 * node.padding;\n const halfPadding = padding / 2;\n const width = node.width <= bbox.width + node.padding ? bbox.width + node.padding : node.width;\n if (node.width <= bbox.width + node.padding) {\n node.diff = (bbox.width + node.padding * 0 - node.width) / 2;\n } else {\n node.diff = -node.padding / 2;\n }\n rect2.attr(\"class\", \"outer\").attr(\"x\", node.x - width / 2 - halfPadding).attr(\"y\", node.y - node.height / 2 - halfPadding).attr(\"width\", width + padding).attr(\"height\", node.height + padding);\n innerRect.attr(\"class\", \"inner\").attr(\"x\", node.x - width / 2 - halfPadding).attr(\"y\", node.y - node.height / 2 - halfPadding + bbox.height - 1).attr(\"width\", width + padding).attr(\"height\", node.height + padding - bbox.height - 3);\n const { subGraphTitleTopMargin } = getSubGraphTitleMargins(siteConfig);\n label.attr(\n \"transform\",\n `translate(${node.x - bbox.width / 2}, ${node.y - node.height / 2 - node.padding / 3 + (evaluate(siteConfig.flowchart.htmlLabels) ? 5 : 3) + subGraphTitleTopMargin})`\n );\n const rectBox = rect2.node().getBBox();\n node.height = rectBox.height;\n node.intersect = function(point) {\n return intersect_rect_default(node, point);\n };\n return shapeSvg;\n}, \"roundedWithTitle\");\nvar divider = /* @__PURE__ */ __name((parent, node) => {\n const shapeSvg = parent.insert(\"g\").attr(\"class\", node.classes).attr(\"id\", node.id);\n const rect2 = shapeSvg.insert(\"rect\", \":first-child\");\n const padding = 0 * node.padding;\n const halfPadding = padding / 2;\n rect2.attr(\"class\", \"divider\").attr(\"x\", node.x - node.width / 2 - halfPadding).attr(\"y\", node.y - node.height / 2).attr(\"width\", node.width + padding).attr(\"height\", node.height + padding);\n const rectBox = rect2.node().getBBox();\n node.width = rectBox.width;\n node.height = rectBox.height;\n node.diff = -node.padding / 2;\n node.intersect = function(point) {\n return intersect_rect_default(node, point);\n };\n return shapeSvg;\n}, \"divider\");\nvar shapes = { rect, roundedWithTitle, noteGroup, divider };\nvar clusterElems = {};\nvar insertCluster = /* @__PURE__ */ __name((elem, node) => {\n log.trace(\"Inserting cluster\");\n const shape = node.shape || \"rect\";\n clusterElems[node.id] = shapes[shape](elem, node);\n}, \"insertCluster\");\nvar clear4 = /* @__PURE__ */ __name(() => {\n clusterElems = {};\n}, \"clear\");\n\n// src/dagre-wrapper/index.js\nvar recursiveRender = /* @__PURE__ */ __name(async (_elem, graph, diagramType, id, parentCluster, siteConfig) => {\n log.info(\"Graph in recursive render: XXX\", graphlibJson2.write(graph), parentCluster);\n const dir = graph.graph().rankdir;\n log.trace(\"Dir in recursive render - dir:\", dir);\n const elem = _elem.insert(\"g\").attr(\"class\", \"root\");\n if (!graph.nodes()) {\n log.info(\"No nodes found for\", graph);\n } else {\n log.info(\"Recursive render XXX\", graph.nodes());\n }\n if (graph.edges().length > 0) {\n log.trace(\"Recursive edges\", graph.edge(graph.edges()[0]));\n }\n const clusters = elem.insert(\"g\").attr(\"class\", \"clusters\");\n const edgePaths = elem.insert(\"g\").attr(\"class\", \"edgePaths\");\n const edgeLabels = elem.insert(\"g\").attr(\"class\", \"edgeLabels\");\n const nodes = elem.insert(\"g\").attr(\"class\", \"nodes\");\n await Promise.all(\n graph.nodes().map(async function(v) {\n const node = graph.node(v);\n if (parentCluster !== void 0) {\n const data = JSON.parse(JSON.stringify(parentCluster.clusterData));\n log.info(\"Setting data for cluster XXX (\", v, \") \", data, parentCluster);\n graph.setNode(parentCluster.id, data);\n if (!graph.parent(v)) {\n log.trace(\"Setting parent\", v, parentCluster.id);\n graph.setParent(v, parentCluster.id, data);\n }\n }\n log.info(\"(Insert) Node XXX\" + v + \": \" + JSON.stringify(graph.node(v)));\n if (node?.clusterNode) {\n log.info(\"Cluster identified\", v, node.width, graph.node(v));\n const { ranksep, nodesep } = graph.graph();\n node.graph.setGraph({\n ...node.graph.graph(),\n ranksep,\n nodesep\n });\n const o = await recursiveRender(\n nodes,\n node.graph,\n diagramType,\n id,\n graph.node(v),\n siteConfig\n );\n const newEl = o.elem;\n updateNodeBounds(node, newEl);\n node.diff = o.diff || 0;\n log.info(\"Node bounds (abc123)\", v, node, node.width, node.x, node.y);\n setNodeElem(newEl, node);\n log.warn(\"Recursive render complete \", newEl, node);\n } else {\n if (graph.children(v).length > 0) {\n log.info(\"Cluster - the non recursive path XXX\", v, node.id, node, graph);\n log.info(findNonClusterChild(node.id, graph));\n clusterDb[node.id] = { id: findNonClusterChild(node.id, graph), node };\n } else {\n log.info(\"Node - the non recursive path\", v, node.id, node);\n await insertNode(nodes, graph.node(v), dir);\n }\n }\n })\n );\n graph.edges().forEach(async function(e) {\n const edge = graph.edge(e.v, e.w, e.name);\n log.info(\"Edge \" + e.v + \" -> \" + e.w + \": \" + JSON.stringify(e));\n log.info(\"Edge \" + e.v + \" -> \" + e.w + \": \", e, \" \", JSON.stringify(graph.edge(e)));\n log.info(\"Fix\", clusterDb, \"ids:\", e.v, e.w, \"Translating: \", clusterDb[e.v], clusterDb[e.w]);\n await insertEdgeLabel(edgeLabels, edge);\n });\n graph.edges().forEach(function(e) {\n log.info(\"Edge \" + e.v + \" -> \" + e.w + \": \" + JSON.stringify(e));\n });\n log.info(\"Graph before layout:\", JSON.stringify(graphlibJson2.write(graph)));\n log.info(\"#############################################\");\n log.info(\"### Layout ###\");\n log.info(\"#############################################\");\n log.info(graph);\n dagreLayout(graph);\n log.info(\"Graph after layout:\", JSON.stringify(graphlibJson2.write(graph)));\n let diff = 0;\n const { subGraphTitleTotalMargin } = getSubGraphTitleMargins(siteConfig);\n sortNodesByHierarchy(graph).forEach(function(v) {\n const node = graph.node(v);\n log.info(\"Position \" + v + \": \" + JSON.stringify(graph.node(v)));\n log.info(\n \"Position \" + v + \": (\" + node.x,\n \",\" + node.y,\n \") width: \",\n node.width,\n \" height: \",\n node.height\n );\n if (node?.clusterNode) {\n node.y += subGraphTitleTotalMargin;\n positionNode(node);\n } else {\n if (graph.children(v).length > 0) {\n node.height += subGraphTitleTotalMargin;\n insertCluster(clusters, node);\n clusterDb[node.id].node = node;\n } else {\n node.y += subGraphTitleTotalMargin / 2;\n positionNode(node);\n }\n }\n });\n graph.edges().forEach(function(e) {\n const edge = graph.edge(e);\n log.info(\"Edge \" + e.v + \" -> \" + e.w + \": \" + JSON.stringify(edge), edge);\n edge.points.forEach((point) => point.y += subGraphTitleTotalMargin / 2);\n const paths = insertEdge(edgePaths, e, edge, clusterDb, diagramType, graph, id);\n positionEdgeLabel(edge, paths);\n });\n graph.nodes().forEach(function(v) {\n const n = graph.node(v);\n log.info(v, n.type, n.diff);\n if (n.type === \"group\") {\n diff = n.diff;\n }\n });\n return { elem, diff };\n}, \"recursiveRender\");\nvar render = /* @__PURE__ */ __name(async (elem, graph, markers, diagramType, id) => {\n markers_default(elem, markers, diagramType, id);\n clear();\n clear2();\n clear4();\n clear3();\n log.warn(\"Graph at first:\", JSON.stringify(graphlibJson2.write(graph)));\n adjustClustersAndEdges(graph);\n log.warn(\"Graph after:\", JSON.stringify(graphlibJson2.write(graph)));\n const siteConfig = getConfig();\n await recursiveRender(elem, graph, diagramType, id, void 0, siteConfig);\n}, \"render\");\n\n// src/diagrams/class/classRenderer-v2.ts\nvar sanitizeText = /* @__PURE__ */ __name((txt) => common_default.sanitizeText(txt, getConfig()), \"sanitizeText\");\nvar conf = {\n dividerMargin: 10,\n padding: 5,\n textHeight: 10,\n curve: void 0\n};\nvar addNamespaces = /* @__PURE__ */ __name(function(namespaces, g, _id, diagObj) {\n log.info(\"keys:\", [...namespaces.keys()]);\n log.info(namespaces);\n namespaces.forEach(function(vertex) {\n const shape = \"rect\";\n const node = {\n shape,\n id: vertex.id,\n domId: vertex.domId,\n labelText: sanitizeText(vertex.id),\n labelStyle: \"\",\n style: \"fill: none; stroke: black\",\n // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release\n padding: getConfig().flowchart?.padding ?? getConfig().class?.padding\n };\n g.setNode(vertex.id, node);\n addClasses(vertex.classes, g, _id, diagObj, vertex.id);\n log.info(\"setNode\", node);\n });\n}, \"addNamespaces\");\nvar addClasses = /* @__PURE__ */ __name(function(classes, g, _id, diagObj, parent) {\n log.info(\"keys:\", [...classes.keys()]);\n log.info(classes);\n [...classes.values()].filter((vertex) => vertex.parent === parent).forEach(function(vertex) {\n const cssClassStr = vertex.cssClasses.join(\" \");\n const styles = getStylesFromArray(vertex.styles);\n const vertexText = vertex.label ?? vertex.id;\n const radius = 0;\n const shape = \"class_box\";\n const node = {\n labelStyle: styles.labelStyle,\n shape,\n labelText: sanitizeText(vertexText),\n classData: vertex,\n rx: radius,\n ry: radius,\n class: cssClassStr,\n style: styles.style,\n id: vertex.id,\n domId: vertex.domId,\n tooltip: diagObj.db.getTooltip(vertex.id, parent) || \"\",\n haveCallback: vertex.haveCallback,\n link: vertex.link,\n width: vertex.type === \"group\" ? 500 : void 0,\n type: vertex.type,\n // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release\n padding: getConfig().flowchart?.padding ?? getConfig().class?.padding\n };\n g.setNode(vertex.id, node);\n if (parent) {\n g.setParent(vertex.id, parent);\n }\n log.info(\"setNode\", node);\n });\n}, \"addClasses\");\nvar addNotes = /* @__PURE__ */ __name(function(notes, g, startEdgeId, classes) {\n log.info(notes);\n notes.forEach(function(note, i) {\n const vertex = note;\n const cssNoteStr = \"\";\n const styles = { labelStyle: \"\", style: \"\" };\n const vertexText = vertex.text;\n const radius = 0;\n const shape = \"note\";\n const node = {\n labelStyle: styles.labelStyle,\n shape,\n labelText: sanitizeText(vertexText),\n noteData: vertex,\n rx: radius,\n ry: radius,\n class: cssNoteStr,\n style: styles.style,\n id: vertex.id,\n domId: vertex.id,\n tooltip: \"\",\n type: \"note\",\n // TODO V10: Flowchart ? Keeping flowchart for backwards compatibility. Remove in next major release\n padding: getConfig().flowchart?.padding ?? getConfig().class?.padding\n };\n g.setNode(vertex.id, node);\n log.info(\"setNode\", node);\n if (!vertex.class || !classes.has(vertex.class)) {\n return;\n }\n const edgeId = startEdgeId + i;\n const edgeData = {\n id: `edgeNote${edgeId}`,\n //Set relationship style and line type\n classes: \"relation\",\n pattern: \"dotted\",\n // Set link type for rendering\n arrowhead: \"none\",\n //Set edge extra labels\n startLabelRight: \"\",\n endLabelLeft: \"\",\n //Set relation arrow types\n arrowTypeStart: \"none\",\n arrowTypeEnd: \"none\",\n style: \"fill:none\",\n labelStyle: \"\",\n curve: interpolateToCurve(conf.curve, curveLinear)\n };\n g.setEdge(vertex.id, vertex.class, edgeData, edgeId);\n });\n}, \"addNotes\");\nvar addRelations = /* @__PURE__ */ __name(function(relations, g) {\n const conf2 = getConfig().flowchart;\n let cnt = 0;\n relations.forEach(function(edge) {\n cnt++;\n const edgeData = {\n //Set relationship style and line type\n classes: \"relation\",\n pattern: edge.relation.lineType == 1 ? \"dashed\" : \"solid\",\n id: getEdgeId(edge.id1, edge.id2, {\n prefix: \"id\",\n counter: cnt\n }),\n // Set link type for rendering\n arrowhead: edge.type === \"arrow_open\" ? \"none\" : \"normal\",\n //Set edge extra labels\n startLabelRight: edge.relationTitle1 === \"none\" ? \"\" : edge.relationTitle1,\n endLabelLeft: edge.relationTitle2 === \"none\" ? \"\" : edge.relationTitle2,\n //Set relation arrow types\n arrowTypeStart: getArrowMarker(edge.relation.type1),\n arrowTypeEnd: getArrowMarker(edge.relation.type2),\n style: \"fill:none\",\n labelStyle: \"\",\n curve: interpolateToCurve(conf2?.curve, curveLinear)\n };\n log.info(edgeData, edge);\n if (edge.style !== void 0) {\n const styles = getStylesFromArray(edge.style);\n edgeData.style = styles.style;\n edgeData.labelStyle = styles.labelStyle;\n }\n edge.text = edge.title;\n if (edge.text === void 0) {\n if (edge.style !== void 0) {\n edgeData.arrowheadStyle = \"fill: #333\";\n }\n } else {\n edgeData.arrowheadStyle = \"fill: #333\";\n edgeData.labelpos = \"c\";\n if (getConfig().flowchart?.htmlLabels ?? getConfig().htmlLabels) {\n edgeData.labelType = \"html\";\n edgeData.label = '' + edge.text + \"\";\n } else {\n edgeData.labelType = \"text\";\n edgeData.label = edge.text.replace(common_default.lineBreakRegex, \"\\n\");\n if (edge.style === void 0) {\n edgeData.style = edgeData.style || \"stroke: #333; stroke-width: 1.5px;fill:none\";\n }\n edgeData.labelStyle = edgeData.labelStyle.replace(\"color:\", \"fill:\");\n }\n }\n g.setEdge(edge.id1, edge.id2, edgeData, cnt);\n });\n}, \"addRelations\");\nvar setConf = /* @__PURE__ */ __name(function(cnf) {\n conf = {\n ...conf,\n ...cnf\n };\n}, \"setConf\");\nvar draw = /* @__PURE__ */ __name(async function(text, id, _version, diagObj) {\n log.info(\"Drawing class - \", id);\n const conf2 = getConfig().flowchart ?? getConfig().class;\n const securityLevel = getConfig().securityLevel;\n log.info(\"config:\", conf2);\n const nodeSpacing = conf2?.nodeSpacing ?? 50;\n const rankSpacing = conf2?.rankSpacing ?? 50;\n const g = new graphlib2.Graph({\n multigraph: true,\n compound: true\n }).setGraph({\n rankdir: diagObj.db.getDirection(),\n nodesep: nodeSpacing,\n ranksep: rankSpacing,\n marginx: 8,\n marginy: 8\n }).setDefaultEdgeLabel(function() {\n return {};\n });\n const namespaces = diagObj.db.getNamespaces();\n const classes = diagObj.db.getClasses();\n const relations = diagObj.db.getRelations();\n const notes = diagObj.db.getNotes();\n log.info(relations);\n addNamespaces(namespaces, g, id, diagObj);\n addClasses(classes, g, id, diagObj);\n addRelations(relations, g);\n addNotes(notes, g, relations.length + 1, classes);\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select2(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select2(sandboxElement.nodes()[0].contentDocument.body) : select2(\"body\");\n const svg = root.select(`[id=\"${id}\"]`);\n const element = root.select(\"#\" + id + \" g\");\n await render(\n element,\n g,\n [\"aggregation\", \"extension\", \"composition\", \"dependency\", \"lollipop\"],\n \"classDiagram\",\n id\n );\n utils_default.insertTitle(svg, \"classTitleText\", conf2?.titleTopMargin ?? 5, diagObj.db.getDiagramTitle());\n setupGraphViewbox(g, svg, conf2?.diagramPadding, conf2?.useMaxWidth);\n if (!conf2?.htmlLabels) {\n const doc = securityLevel === \"sandbox\" ? sandboxElement.nodes()[0].contentDocument : document;\n const labels = doc.querySelectorAll('[id=\"' + id + '\"] .edgeLabel .label');\n for (const label of labels) {\n const dim = label.getBBox();\n const rect2 = doc.createElementNS(\"http://www.w3.org/2000/svg\", \"rect\");\n rect2.setAttribute(\"rx\", 0);\n rect2.setAttribute(\"ry\", 0);\n rect2.setAttribute(\"width\", dim.width);\n rect2.setAttribute(\"height\", dim.height);\n label.insertBefore(rect2, label.firstChild);\n }\n }\n}, \"draw\");\nfunction getArrowMarker(type) {\n let marker;\n switch (type) {\n case 0:\n marker = \"aggregation\";\n break;\n case 1:\n marker = \"extension\";\n break;\n case 2:\n marker = \"composition\";\n break;\n case 3:\n marker = \"dependency\";\n break;\n case 4:\n marker = \"lollipop\";\n break;\n default:\n marker = \"none\";\n }\n return marker;\n}\n__name(getArrowMarker, \"getArrowMarker\");\nvar classRenderer_v2_default = {\n setConf,\n draw\n};\n\n// src/diagrams/class/classDiagram-v2.ts\nvar diagram = {\n parser: classDiagram_default,\n db: classDb_default,\n renderer: classRenderer_v2_default,\n styles: styles_default,\n init: /* @__PURE__ */ __name((cnf) => {\n if (!cnf.class) {\n cnf.class = {};\n }\n cnf.class.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;\n classDb_default.clear();\n }, \"init\")\n};\nexport {\n diagram\n};\n", "import {\n getDiagramElement,\n setupViewPortForSVG\n} from \"./chunk-DUMQOTYW.mjs\";\nimport {\n render\n} from \"./chunk-WSMKYKZ5.mjs\";\nimport {\n generateId,\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n clear,\n common_default,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n getDiagramTitle,\n log,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/state/parser/stateDiagram.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 2], $V1 = [1, 3], $V2 = [1, 4], $V3 = [2, 4], $V4 = [1, 9], $V5 = [1, 11], $V6 = [1, 16], $V7 = [1, 17], $V8 = [1, 18], $V9 = [1, 19], $Va = [1, 32], $Vb = [1, 20], $Vc = [1, 21], $Vd = [1, 22], $Ve = [1, 23], $Vf = [1, 24], $Vg = [1, 26], $Vh = [1, 27], $Vi = [1, 28], $Vj = [1, 29], $Vk = [1, 30], $Vl = [1, 31], $Vm = [1, 34], $Vn = [1, 35], $Vo = [1, 36], $Vp = [1, 37], $Vq = [1, 33], $Vr = [1, 4, 5, 16, 17, 19, 21, 22, 24, 25, 26, 27, 28, 29, 33, 35, 37, 38, 42, 45, 48, 49, 50, 51, 54], $Vs = [1, 4, 5, 14, 15, 16, 17, 19, 21, 22, 24, 25, 26, 27, 28, 29, 33, 35, 37, 38, 42, 45, 48, 49, 50, 51, 54], $Vt = [4, 5, 16, 17, 19, 21, 22, 24, 25, 26, 27, 28, 29, 33, 35, 37, 38, 42, 45, 48, 49, 50, 51, 54];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"SPACE\": 4, \"NL\": 5, \"SD\": 6, \"document\": 7, \"line\": 8, \"statement\": 9, \"classDefStatement\": 10, \"styleStatement\": 11, \"cssClassStatement\": 12, \"idStatement\": 13, \"DESCR\": 14, \"-->\": 15, \"HIDE_EMPTY\": 16, \"scale\": 17, \"WIDTH\": 18, \"COMPOSIT_STATE\": 19, \"STRUCT_START\": 20, \"STRUCT_STOP\": 21, \"STATE_DESCR\": 22, \"AS\": 23, \"ID\": 24, \"FORK\": 25, \"JOIN\": 26, \"CHOICE\": 27, \"CONCURRENT\": 28, \"note\": 29, \"notePosition\": 30, \"NOTE_TEXT\": 31, \"direction\": 32, \"acc_title\": 33, \"acc_title_value\": 34, \"acc_descr\": 35, \"acc_descr_value\": 36, \"acc_descr_multiline_value\": 37, \"classDef\": 38, \"CLASSDEF_ID\": 39, \"CLASSDEF_STYLEOPTS\": 40, \"DEFAULT\": 41, \"style\": 42, \"STYLE_IDS\": 43, \"STYLEDEF_STYLEOPTS\": 44, \"class\": 45, \"CLASSENTITY_IDS\": 46, \"STYLECLASS\": 47, \"direction_tb\": 48, \"direction_bt\": 49, \"direction_rl\": 50, \"direction_lr\": 51, \"eol\": 52, \";\": 53, \"EDGE_STATE\": 54, \"STYLE_SEPARATOR\": 55, \"left_of\": 56, \"right_of\": 57, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 4: \"SPACE\", 5: \"NL\", 6: \"SD\", 14: \"DESCR\", 15: \"-->\", 16: \"HIDE_EMPTY\", 17: \"scale\", 18: \"WIDTH\", 19: \"COMPOSIT_STATE\", 20: \"STRUCT_START\", 21: \"STRUCT_STOP\", 22: \"STATE_DESCR\", 23: \"AS\", 24: \"ID\", 25: \"FORK\", 26: \"JOIN\", 27: \"CHOICE\", 28: \"CONCURRENT\", 29: \"note\", 31: \"NOTE_TEXT\", 33: \"acc_title\", 34: \"acc_title_value\", 35: \"acc_descr\", 36: \"acc_descr_value\", 37: \"acc_descr_multiline_value\", 38: \"classDef\", 39: \"CLASSDEF_ID\", 40: \"CLASSDEF_STYLEOPTS\", 41: \"DEFAULT\", 42: \"style\", 43: \"STYLE_IDS\", 44: \"STYLEDEF_STYLEOPTS\", 45: \"class\", 46: \"CLASSENTITY_IDS\", 47: \"STYLECLASS\", 48: \"direction_tb\", 49: \"direction_bt\", 50: \"direction_rl\", 51: \"direction_lr\", 53: \";\", 54: \"EDGE_STATE\", 55: \"STYLE_SEPARATOR\", 56: \"left_of\", 57: \"right_of\" },\n productions_: [0, [3, 2], [3, 2], [3, 2], [7, 0], [7, 2], [8, 2], [8, 1], [8, 1], [9, 1], [9, 1], [9, 1], [9, 1], [9, 2], [9, 3], [9, 4], [9, 1], [9, 2], [9, 1], [9, 4], [9, 3], [9, 6], [9, 1], [9, 1], [9, 1], [9, 1], [9, 4], [9, 4], [9, 1], [9, 2], [9, 2], [9, 1], [10, 3], [10, 3], [11, 3], [12, 3], [32, 1], [32, 1], [32, 1], [32, 1], [52, 1], [52, 1], [13, 1], [13, 1], [13, 3], [13, 3], [30, 1], [30, 1]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 3:\n yy.setRootDoc($$[$0]);\n return $$[$0];\n break;\n case 4:\n this.$ = [];\n break;\n case 5:\n if ($$[$0] != \"nl\") {\n $$[$0 - 1].push($$[$0]);\n this.$ = $$[$0 - 1];\n }\n break;\n case 6:\n case 7:\n this.$ = $$[$0];\n break;\n case 8:\n this.$ = \"nl\";\n break;\n case 12:\n this.$ = $$[$0];\n break;\n case 13:\n const stateStmt = $$[$0 - 1];\n stateStmt.description = yy.trimColon($$[$0]);\n this.$ = stateStmt;\n break;\n case 14:\n this.$ = { stmt: \"relation\", state1: $$[$0 - 2], state2: $$[$0] };\n break;\n case 15:\n const relDescription = yy.trimColon($$[$0]);\n this.$ = { stmt: \"relation\", state1: $$[$0 - 3], state2: $$[$0 - 1], description: relDescription };\n break;\n case 19:\n this.$ = { stmt: \"state\", id: $$[$0 - 3], type: \"default\", description: \"\", doc: $$[$0 - 1] };\n break;\n case 20:\n var id = $$[$0];\n var description = $$[$0 - 2].trim();\n if ($$[$0].match(\":\")) {\n var parts = $$[$0].split(\":\");\n id = parts[0];\n description = [description, parts[1]];\n }\n this.$ = { stmt: \"state\", id, type: \"default\", description };\n break;\n case 21:\n this.$ = { stmt: \"state\", id: $$[$0 - 3], type: \"default\", description: $$[$0 - 5], doc: $$[$0 - 1] };\n break;\n case 22:\n this.$ = { stmt: \"state\", id: $$[$0], type: \"fork\" };\n break;\n case 23:\n this.$ = { stmt: \"state\", id: $$[$0], type: \"join\" };\n break;\n case 24:\n this.$ = { stmt: \"state\", id: $$[$0], type: \"choice\" };\n break;\n case 25:\n this.$ = { stmt: \"state\", id: yy.getDividerId(), type: \"divider\" };\n break;\n case 26:\n this.$ = { stmt: \"state\", id: $$[$0 - 1].trim(), note: { position: $$[$0 - 2].trim(), text: $$[$0].trim() } };\n break;\n case 29:\n this.$ = $$[$0].trim();\n yy.setAccTitle(this.$);\n break;\n case 30:\n case 31:\n this.$ = $$[$0].trim();\n yy.setAccDescription(this.$);\n break;\n case 32:\n case 33:\n this.$ = { stmt: \"classDef\", id: $$[$0 - 1].trim(), classes: $$[$0].trim() };\n break;\n case 34:\n this.$ = { stmt: \"style\", id: $$[$0 - 1].trim(), styleClass: $$[$0].trim() };\n break;\n case 35:\n this.$ = { stmt: \"applyClass\", id: $$[$0 - 1].trim(), styleClass: $$[$0].trim() };\n break;\n case 36:\n yy.setDirection(\"TB\");\n this.$ = { stmt: \"dir\", value: \"TB\" };\n break;\n case 37:\n yy.setDirection(\"BT\");\n this.$ = { stmt: \"dir\", value: \"BT\" };\n break;\n case 38:\n yy.setDirection(\"RL\");\n this.$ = { stmt: \"dir\", value: \"RL\" };\n break;\n case 39:\n yy.setDirection(\"LR\");\n this.$ = { stmt: \"dir\", value: \"LR\" };\n break;\n case 42:\n case 43:\n this.$ = { stmt: \"state\", id: $$[$0].trim(), type: \"default\", description: \"\" };\n break;\n case 44:\n this.$ = { stmt: \"state\", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: \"default\", description: \"\" };\n break;\n case 45:\n this.$ = { stmt: \"state\", id: $$[$0 - 2].trim(), classes: [$$[$0].trim()], type: \"default\", description: \"\" };\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: $V0, 5: $V1, 6: $V2 }, { 1: [3] }, { 3: 5, 4: $V0, 5: $V1, 6: $V2 }, { 3: 6, 4: $V0, 5: $V1, 6: $V2 }, o([1, 4, 5, 16, 17, 19, 22, 24, 25, 26, 27, 28, 29, 33, 35, 37, 38, 42, 45, 48, 49, 50, 51, 54], $V3, { 7: 7 }), { 1: [2, 1] }, { 1: [2, 2] }, { 1: [2, 3], 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 13: 15, 16: $V6, 17: $V7, 19: $V8, 22: $V9, 24: $Va, 25: $Vb, 26: $Vc, 27: $Vd, 28: $Ve, 29: $Vf, 32: 25, 33: $Vg, 35: $Vh, 37: $Vi, 38: $Vj, 42: $Vk, 45: $Vl, 48: $Vm, 49: $Vn, 50: $Vo, 51: $Vp, 54: $Vq }, o($Vr, [2, 5]), { 9: 38, 10: 12, 11: 13, 12: 14, 13: 15, 16: $V6, 17: $V7, 19: $V8, 22: $V9, 24: $Va, 25: $Vb, 26: $Vc, 27: $Vd, 28: $Ve, 29: $Vf, 32: 25, 33: $Vg, 35: $Vh, 37: $Vi, 38: $Vj, 42: $Vk, 45: $Vl, 48: $Vm, 49: $Vn, 50: $Vo, 51: $Vp, 54: $Vq }, o($Vr, [2, 7]), o($Vr, [2, 8]), o($Vr, [2, 9]), o($Vr, [2, 10]), o($Vr, [2, 11]), o($Vr, [2, 12], { 14: [1, 39], 15: [1, 40] }), o($Vr, [2, 16]), { 18: [1, 41] }, o($Vr, [2, 18], { 20: [1, 42] }), { 23: [1, 43] }, o($Vr, [2, 22]), o($Vr, [2, 23]), o($Vr, [2, 24]), o($Vr, [2, 25]), { 30: 44, 31: [1, 45], 56: [1, 46], 57: [1, 47] }, o($Vr, [2, 28]), { 34: [1, 48] }, { 36: [1, 49] }, o($Vr, [2, 31]), { 39: [1, 50], 41: [1, 51] }, { 43: [1, 52] }, { 46: [1, 53] }, o($Vs, [2, 42], { 55: [1, 54] }), o($Vs, [2, 43], { 55: [1, 55] }), o($Vr, [2, 36]), o($Vr, [2, 37]), o($Vr, [2, 38]), o($Vr, [2, 39]), o($Vr, [2, 6]), o($Vr, [2, 13]), { 13: 56, 24: $Va, 54: $Vq }, o($Vr, [2, 17]), o($Vt, $V3, { 7: 57 }), { 24: [1, 58] }, { 24: [1, 59] }, { 23: [1, 60] }, { 24: [2, 46] }, { 24: [2, 47] }, o($Vr, [2, 29]), o($Vr, [2, 30]), { 40: [1, 61] }, { 40: [1, 62] }, { 44: [1, 63] }, { 47: [1, 64] }, { 24: [1, 65] }, { 24: [1, 66] }, o($Vr, [2, 14], { 14: [1, 67] }), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 13: 15, 16: $V6, 17: $V7, 19: $V8, 21: [1, 68], 22: $V9, 24: $Va, 25: $Vb, 26: $Vc, 27: $Vd, 28: $Ve, 29: $Vf, 32: 25, 33: $Vg, 35: $Vh, 37: $Vi, 38: $Vj, 42: $Vk, 45: $Vl, 48: $Vm, 49: $Vn, 50: $Vo, 51: $Vp, 54: $Vq }, o($Vr, [2, 20], { 20: [1, 69] }), { 31: [1, 70] }, { 24: [1, 71] }, o($Vr, [2, 32]), o($Vr, [2, 33]), o($Vr, [2, 34]), o($Vr, [2, 35]), o($Vs, [2, 44]), o($Vs, [2, 45]), o($Vr, [2, 15]), o($Vr, [2, 19]), o($Vt, $V3, { 7: 72 }), o($Vr, [2, 26]), o($Vr, [2, 27]), { 4: $V4, 5: $V5, 8: 8, 9: 10, 10: 12, 11: 13, 12: 14, 13: 15, 16: $V6, 17: $V7, 19: $V8, 21: [1, 73], 22: $V9, 24: $Va, 25: $Vb, 26: $Vc, 27: $Vd, 28: $Ve, 29: $Vf, 32: 25, 33: $Vg, 35: $Vh, 37: $Vi, 38: $Vj, 42: $Vk, 45: $Vl, 48: $Vm, 49: $Vn, 50: $Vo, 51: $Vp, 54: $Vq }, o($Vr, [2, 21])],\n defaultActions: { 5: [2, 1], 6: [2, 2], 46: [2, 46], 47: [2, 47] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n return 41;\n break;\n case 1:\n return 48;\n break;\n case 2:\n return 49;\n break;\n case 3:\n return 50;\n break;\n case 4:\n return 51;\n break;\n case 5:\n break;\n case 6:\n {\n }\n break;\n case 7:\n return 5;\n break;\n case 8:\n break;\n case 9:\n break;\n case 10:\n break;\n case 11:\n break;\n case 12:\n this.pushState(\"SCALE\");\n return 17;\n break;\n case 13:\n return 18;\n break;\n case 14:\n this.popState();\n break;\n case 15:\n this.begin(\"acc_title\");\n return 33;\n break;\n case 16:\n this.popState();\n return \"acc_title_value\";\n break;\n case 17:\n this.begin(\"acc_descr\");\n return 35;\n break;\n case 18:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 19:\n this.begin(\"acc_descr_multiline\");\n break;\n case 20:\n this.popState();\n break;\n case 21:\n return \"acc_descr_multiline_value\";\n break;\n case 22:\n this.pushState(\"CLASSDEF\");\n return 38;\n break;\n case 23:\n this.popState();\n this.pushState(\"CLASSDEFID\");\n return \"DEFAULT_CLASSDEF_ID\";\n break;\n case 24:\n this.popState();\n this.pushState(\"CLASSDEFID\");\n return 39;\n break;\n case 25:\n this.popState();\n return 40;\n break;\n case 26:\n this.pushState(\"CLASS\");\n return 45;\n break;\n case 27:\n this.popState();\n this.pushState(\"CLASS_STYLE\");\n return 46;\n break;\n case 28:\n this.popState();\n return 47;\n break;\n case 29:\n this.pushState(\"STYLE\");\n return 42;\n break;\n case 30:\n this.popState();\n this.pushState(\"STYLEDEF_STYLES\");\n return 43;\n break;\n case 31:\n this.popState();\n return 44;\n break;\n case 32:\n this.pushState(\"SCALE\");\n return 17;\n break;\n case 33:\n return 18;\n break;\n case 34:\n this.popState();\n break;\n case 35:\n this.pushState(\"STATE\");\n break;\n case 36:\n this.popState();\n yy_.yytext = yy_.yytext.slice(0, -8).trim();\n return 25;\n break;\n case 37:\n this.popState();\n yy_.yytext = yy_.yytext.slice(0, -8).trim();\n return 26;\n break;\n case 38:\n this.popState();\n yy_.yytext = yy_.yytext.slice(0, -10).trim();\n return 27;\n break;\n case 39:\n this.popState();\n yy_.yytext = yy_.yytext.slice(0, -8).trim();\n return 25;\n break;\n case 40:\n this.popState();\n yy_.yytext = yy_.yytext.slice(0, -8).trim();\n return 26;\n break;\n case 41:\n this.popState();\n yy_.yytext = yy_.yytext.slice(0, -10).trim();\n return 27;\n break;\n case 42:\n return 48;\n break;\n case 43:\n return 49;\n break;\n case 44:\n return 50;\n break;\n case 45:\n return 51;\n break;\n case 46:\n this.pushState(\"STATE_STRING\");\n break;\n case 47:\n this.pushState(\"STATE_ID\");\n return \"AS\";\n break;\n case 48:\n this.popState();\n return \"ID\";\n break;\n case 49:\n this.popState();\n break;\n case 50:\n return \"STATE_DESCR\";\n break;\n case 51:\n return 19;\n break;\n case 52:\n this.popState();\n break;\n case 53:\n this.popState();\n this.pushState(\"struct\");\n return 20;\n break;\n case 54:\n break;\n case 55:\n this.popState();\n return 21;\n break;\n case 56:\n break;\n case 57:\n this.begin(\"NOTE\");\n return 29;\n break;\n case 58:\n this.popState();\n this.pushState(\"NOTE_ID\");\n return 56;\n break;\n case 59:\n this.popState();\n this.pushState(\"NOTE_ID\");\n return 57;\n break;\n case 60:\n this.popState();\n this.pushState(\"FLOATING_NOTE\");\n break;\n case 61:\n this.popState();\n this.pushState(\"FLOATING_NOTE_ID\");\n return \"AS\";\n break;\n case 62:\n break;\n case 63:\n return \"NOTE_TEXT\";\n break;\n case 64:\n this.popState();\n return \"ID\";\n break;\n case 65:\n this.popState();\n this.pushState(\"NOTE_TEXT\");\n return 24;\n break;\n case 66:\n this.popState();\n yy_.yytext = yy_.yytext.substr(2).trim();\n return 31;\n break;\n case 67:\n this.popState();\n yy_.yytext = yy_.yytext.slice(0, -8).trim();\n return 31;\n break;\n case 68:\n return 6;\n break;\n case 69:\n return 6;\n break;\n case 70:\n return 16;\n break;\n case 71:\n return 54;\n break;\n case 72:\n return 24;\n break;\n case 73:\n yy_.yytext = yy_.yytext.trim();\n return 14;\n break;\n case 74:\n return 15;\n break;\n case 75:\n return 28;\n break;\n case 76:\n return 55;\n break;\n case 77:\n return 5;\n break;\n case 78:\n return \"INVALID\";\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:default\\b)/i, /^(?:.*direction\\s+TB[^\\n]*)/i, /^(?:.*direction\\s+BT[^\\n]*)/i, /^(?:.*direction\\s+RL[^\\n]*)/i, /^(?:.*direction\\s+LR[^\\n]*)/i, /^(?:%%(?!\\{)[^\\n]*)/i, /^(?:[^\\}]%%[^\\n]*)/i, /^(?:[\\n]+)/i, /^(?:[\\s]+)/i, /^(?:((?!\\n)\\s)+)/i, /^(?:#[^\\n]*)/i, /^(?:%[^\\n]*)/i, /^(?:scale\\s+)/i, /^(?:\\d+)/i, /^(?:\\s+width\\b)/i, /^(?:accTitle\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*\\{\\s*)/i, /^(?:[\\}])/i, /^(?:[^\\}]*)/i, /^(?:classDef\\s+)/i, /^(?:DEFAULT\\s+)/i, /^(?:\\w+\\s+)/i, /^(?:[^\\n]*)/i, /^(?:class\\s+)/i, /^(?:(\\w+)+((,\\s*\\w+)*))/i, /^(?:[^\\n]*)/i, /^(?:style\\s+)/i, /^(?:[\\w,]+\\s+)/i, /^(?:[^\\n]*)/i, /^(?:scale\\s+)/i, /^(?:\\d+)/i, /^(?:\\s+width\\b)/i, /^(?:state\\s+)/i, /^(?:.*<>)/i, /^(?:.*<>)/i, /^(?:.*<>)/i, /^(?:.*\\[\\[fork\\]\\])/i, /^(?:.*\\[\\[join\\]\\])/i, /^(?:.*\\[\\[choice\\]\\])/i, /^(?:.*direction\\s+TB[^\\n]*)/i, /^(?:.*direction\\s+BT[^\\n]*)/i, /^(?:.*direction\\s+RL[^\\n]*)/i, /^(?:.*direction\\s+LR[^\\n]*)/i, /^(?:[\"])/i, /^(?:\\s*as\\s+)/i, /^(?:[^\\n\\{]*)/i, /^(?:[\"])/i, /^(?:[^\"]*)/i, /^(?:[^\\n\\s\\{]+)/i, /^(?:\\n)/i, /^(?:\\{)/i, /^(?:%%(?!\\{)[^\\n]*)/i, /^(?:\\})/i, /^(?:[\\n])/i, /^(?:note\\s+)/i, /^(?:left of\\b)/i, /^(?:right of\\b)/i, /^(?:\")/i, /^(?:\\s*as\\s*)/i, /^(?:[\"])/i, /^(?:[^\"]*)/i, /^(?:[^\\n]*)/i, /^(?:\\s*[^:\\n\\s\\-]+)/i, /^(?:\\s*:[^:\\n;]+)/i, /^(?:[\\s\\S]*?end note\\b)/i, /^(?:stateDiagram\\s+)/i, /^(?:stateDiagram-v2\\s+)/i, /^(?:hide empty description\\b)/i, /^(?:\\[\\*\\])/i, /^(?:[^:\\n\\s\\-\\{]+)/i, /^(?:\\s*:[^:\\n;]+)/i, /^(?:-->)/i, /^(?:--)/i, /^(?::::)/i, /^(?:$)/i, /^(?:.)/i],\n conditions: { \"LINE\": { \"rules\": [9, 10], \"inclusive\": false }, \"struct\": { \"rules\": [9, 10, 22, 26, 29, 35, 42, 43, 44, 45, 54, 55, 56, 57, 71, 72, 73, 74, 75], \"inclusive\": false }, \"FLOATING_NOTE_ID\": { \"rules\": [64], \"inclusive\": false }, \"FLOATING_NOTE\": { \"rules\": [61, 62, 63], \"inclusive\": false }, \"NOTE_TEXT\": { \"rules\": [66, 67], \"inclusive\": false }, \"NOTE_ID\": { \"rules\": [65], \"inclusive\": false }, \"NOTE\": { \"rules\": [58, 59, 60], \"inclusive\": false }, \"STYLEDEF_STYLEOPTS\": { \"rules\": [], \"inclusive\": false }, \"STYLEDEF_STYLES\": { \"rules\": [31], \"inclusive\": false }, \"STYLE_IDS\": { \"rules\": [], \"inclusive\": false }, \"STYLE\": { \"rules\": [30], \"inclusive\": false }, \"CLASS_STYLE\": { \"rules\": [28], \"inclusive\": false }, \"CLASS\": { \"rules\": [27], \"inclusive\": false }, \"CLASSDEFID\": { \"rules\": [25], \"inclusive\": false }, \"CLASSDEF\": { \"rules\": [23, 24], \"inclusive\": false }, \"acc_descr_multiline\": { \"rules\": [20, 21], \"inclusive\": false }, \"acc_descr\": { \"rules\": [18], \"inclusive\": false }, \"acc_title\": { \"rules\": [16], \"inclusive\": false }, \"SCALE\": { \"rules\": [13, 14, 33, 34], \"inclusive\": false }, \"ALIAS\": { \"rules\": [], \"inclusive\": false }, \"STATE_ID\": { \"rules\": [48], \"inclusive\": false }, \"STATE_STRING\": { \"rules\": [49, 50], \"inclusive\": false }, \"FORK_STATE\": { \"rules\": [], \"inclusive\": false }, \"STATE\": { \"rules\": [9, 10, 36, 37, 38, 39, 40, 41, 46, 47, 51, 52, 53], \"inclusive\": false }, \"ID\": { \"rules\": [9, 10], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 15, 17, 19, 22, 26, 29, 32, 35, 53, 57, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar stateDiagram_default = parser;\n\n// src/diagrams/state/stateCommon.ts\nvar DEFAULT_DIAGRAM_DIRECTION = \"LR\";\nvar DEFAULT_NESTED_DOC_DIR = \"TB\";\nvar STMT_STATE = \"state\";\nvar STMT_RELATION = \"relation\";\nvar STMT_CLASSDEF = \"classDef\";\nvar STMT_STYLEDEF = \"style\";\nvar STMT_APPLYCLASS = \"applyClass\";\nvar DEFAULT_STATE_TYPE = \"default\";\nvar DIVIDER_TYPE = \"divider\";\nvar G_EDGE_STYLE = \"fill:none\";\nvar G_EDGE_ARROWHEADSTYLE = \"fill: #333\";\nvar G_EDGE_LABELPOS = \"c\";\nvar G_EDGE_LABELTYPE = \"text\";\nvar G_EDGE_THICKNESS = \"normal\";\nvar SHAPE_STATE = \"rect\";\nvar SHAPE_STATE_WITH_DESC = \"rectWithTitle\";\nvar SHAPE_START = \"stateStart\";\nvar SHAPE_END = \"stateEnd\";\nvar SHAPE_DIVIDER = \"divider\";\nvar SHAPE_GROUP = \"roundedWithTitle\";\nvar SHAPE_NOTE = \"note\";\nvar SHAPE_NOTEGROUP = \"noteGroup\";\nvar CSS_DIAGRAM = \"statediagram\";\nvar CSS_STATE = \"state\";\nvar CSS_DIAGRAM_STATE = `${CSS_DIAGRAM}-${CSS_STATE}`;\nvar CSS_EDGE = \"transition\";\nvar CSS_NOTE = \"note\";\nvar CSS_NOTE_EDGE = \"note-edge\";\nvar CSS_EDGE_NOTE_EDGE = `${CSS_EDGE} ${CSS_NOTE_EDGE}`;\nvar CSS_DIAGRAM_NOTE = `${CSS_DIAGRAM}-${CSS_NOTE}`;\nvar CSS_CLUSTER = \"cluster\";\nvar CSS_DIAGRAM_CLUSTER = `${CSS_DIAGRAM}-${CSS_CLUSTER}`;\nvar CSS_CLUSTER_ALT = \"cluster-alt\";\nvar CSS_DIAGRAM_CLUSTER_ALT = `${CSS_DIAGRAM}-${CSS_CLUSTER_ALT}`;\nvar PARENT = \"parent\";\nvar NOTE = \"note\";\nvar DOMID_STATE = \"state\";\nvar DOMID_TYPE_SPACER = \"----\";\nvar NOTE_ID = `${DOMID_TYPE_SPACER}${NOTE}`;\nvar PARENT_ID = `${DOMID_TYPE_SPACER}${PARENT}`;\n\n// src/diagrams/state/stateRenderer-v3-unified.ts\nvar getDir = /* @__PURE__ */ __name((parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => {\n if (!parsedItem.doc) {\n return defaultDir;\n }\n let dir = defaultDir;\n for (const parsedItemDoc of parsedItem.doc) {\n if (parsedItemDoc.stmt === \"dir\") {\n dir = parsedItemDoc.value;\n }\n }\n return dir;\n}, \"getDir\");\nvar getClasses = /* @__PURE__ */ __name(function(text, diagramObj) {\n diagramObj.db.extract(diagramObj.db.getRootDocV2());\n return diagramObj.db.getClasses();\n}, \"getClasses\");\nvar draw = /* @__PURE__ */ __name(async function(text, id, _version, diag) {\n log.info(\"REF0:\");\n log.info(\"Drawing state diagram (v2)\", id);\n const { securityLevel, state: conf, layout } = getConfig();\n diag.db.extract(diag.db.getRootDocV2());\n const data4Layout = diag.db.getData();\n const svg = getDiagramElement(id, securityLevel);\n data4Layout.type = diag.type;\n data4Layout.layoutAlgorithm = layout;\n data4Layout.nodeSpacing = conf?.nodeSpacing || 50;\n data4Layout.rankSpacing = conf?.rankSpacing || 50;\n data4Layout.markers = [\"barb\"];\n data4Layout.diagramId = id;\n await render(data4Layout, svg);\n const padding = 8;\n utils_default.insertTitle(\n svg,\n \"statediagramTitleText\",\n conf?.titleTopMargin ?? 25,\n diag.db.getDiagramTitle()\n );\n setupViewPortForSVG(svg, padding, CSS_DIAGRAM, conf?.useMaxWidth ?? true);\n}, \"draw\");\nvar stateRenderer_v3_unified_default = {\n getClasses,\n draw,\n getDir\n};\n\n// src/diagrams/state/dataFetcher.js\nvar nodeDb = /* @__PURE__ */ new Map();\nvar graphItemCount = 0;\nfunction stateDomId(itemId = \"\", counter = 0, type = \"\", typeSpacer = DOMID_TYPE_SPACER) {\n const typeStr = type !== null && type.length > 0 ? `${typeSpacer}${type}` : \"\";\n return `${DOMID_STATE}-${itemId}${typeStr}-${counter}`;\n}\n__name(stateDomId, \"stateDomId\");\nvar setupDoc = /* @__PURE__ */ __name((parentParsedItem, doc, diagramStates, nodes2, edges2, altFlag, look, classes2) => {\n log.trace(\"items\", doc);\n doc.forEach((item) => {\n switch (item.stmt) {\n case STMT_STATE:\n dataFetcher(parentParsedItem, item, diagramStates, nodes2, edges2, altFlag, look, classes2);\n break;\n case DEFAULT_STATE_TYPE:\n dataFetcher(parentParsedItem, item, diagramStates, nodes2, edges2, altFlag, look, classes2);\n break;\n case STMT_RELATION:\n {\n dataFetcher(\n parentParsedItem,\n item.state1,\n diagramStates,\n nodes2,\n edges2,\n altFlag,\n look,\n classes2\n );\n dataFetcher(\n parentParsedItem,\n item.state2,\n diagramStates,\n nodes2,\n edges2,\n altFlag,\n look,\n classes2\n );\n const edgeData = {\n id: \"edge\" + graphItemCount,\n start: item.state1.id,\n end: item.state2.id,\n arrowhead: \"normal\",\n arrowTypeEnd: \"arrow_barb\",\n style: G_EDGE_STYLE,\n labelStyle: \"\",\n label: common_default.sanitizeText(item.description, getConfig()),\n arrowheadStyle: G_EDGE_ARROWHEADSTYLE,\n labelpos: G_EDGE_LABELPOS,\n labelType: G_EDGE_LABELTYPE,\n thickness: G_EDGE_THICKNESS,\n classes: CSS_EDGE,\n look\n };\n edges2.push(edgeData);\n graphItemCount++;\n }\n break;\n }\n });\n}, \"setupDoc\");\nvar getDir2 = /* @__PURE__ */ __name((parsedItem, defaultDir = DEFAULT_NESTED_DOC_DIR) => {\n let dir = defaultDir;\n if (parsedItem.doc) {\n for (const parsedItemDoc of parsedItem.doc) {\n if (parsedItemDoc.stmt === \"dir\") {\n dir = parsedItemDoc.value;\n }\n }\n }\n return dir;\n}, \"getDir\");\nfunction insertOrUpdateNode(nodes2, nodeData, classes2) {\n if (!nodeData.id || nodeData.id === \"\" || nodeData.id === \"\") {\n return;\n }\n if (nodeData.cssClasses) {\n if (!Array.isArray(nodeData.cssCompiledStyles)) {\n nodeData.cssCompiledStyles = [];\n }\n nodeData.cssClasses.split(\" \").forEach((cssClass) => {\n if (classes2.get(cssClass)) {\n const classDef = classes2.get(cssClass);\n nodeData.cssCompiledStyles = [...nodeData.cssCompiledStyles, ...classDef.styles];\n }\n });\n }\n const existingNodeData = nodes2.find((node) => node.id === nodeData.id);\n if (existingNodeData) {\n Object.assign(existingNodeData, nodeData);\n } else {\n nodes2.push(nodeData);\n }\n}\n__name(insertOrUpdateNode, \"insertOrUpdateNode\");\nfunction getClassesFromDbInfo(dbInfoItem) {\n return dbInfoItem?.classes?.join(\" \") ?? \"\";\n}\n__name(getClassesFromDbInfo, \"getClassesFromDbInfo\");\nfunction getStylesFromDbInfo(dbInfoItem) {\n return dbInfoItem?.styles ?? [];\n}\n__name(getStylesFromDbInfo, \"getStylesFromDbInfo\");\nvar dataFetcher = /* @__PURE__ */ __name((parent, parsedItem, diagramStates, nodes2, edges2, altFlag, look, classes2) => {\n const itemId = parsedItem.id;\n const dbState = diagramStates.get(itemId);\n const classStr = getClassesFromDbInfo(dbState);\n const style = getStylesFromDbInfo(dbState);\n log.info(\"dataFetcher parsedItem\", parsedItem, dbState, style);\n if (itemId !== \"root\") {\n let shape = SHAPE_STATE;\n if (parsedItem.start === true) {\n shape = SHAPE_START;\n } else if (parsedItem.start === false) {\n shape = SHAPE_END;\n }\n if (parsedItem.type !== DEFAULT_STATE_TYPE) {\n shape = parsedItem.type;\n }\n if (!nodeDb.get(itemId)) {\n nodeDb.set(itemId, {\n id: itemId,\n shape,\n description: common_default.sanitizeText(itemId, getConfig()),\n cssClasses: `${classStr} ${CSS_DIAGRAM_STATE}`,\n cssStyles: style\n });\n }\n const newNode = nodeDb.get(itemId);\n if (parsedItem.description) {\n if (Array.isArray(newNode.description)) {\n newNode.shape = SHAPE_STATE_WITH_DESC;\n newNode.description.push(parsedItem.description);\n } else {\n if (newNode.description?.length > 0) {\n newNode.shape = SHAPE_STATE_WITH_DESC;\n if (newNode.description === itemId) {\n newNode.description = [parsedItem.description];\n } else {\n newNode.description = [newNode.description, parsedItem.description];\n }\n } else {\n newNode.shape = SHAPE_STATE;\n newNode.description = parsedItem.description;\n }\n }\n newNode.description = common_default.sanitizeTextOrArray(newNode.description, getConfig());\n }\n if (newNode.description?.length === 1 && newNode.shape === SHAPE_STATE_WITH_DESC) {\n if (newNode.type === \"group\") {\n newNode.shape = SHAPE_GROUP;\n } else {\n newNode.shape = SHAPE_STATE;\n }\n }\n if (!newNode.type && parsedItem.doc) {\n log.info(\"Setting cluster for XCX\", itemId, getDir2(parsedItem));\n newNode.type = \"group\";\n newNode.isGroup = true;\n newNode.dir = getDir2(parsedItem);\n newNode.shape = parsedItem.type === DIVIDER_TYPE ? SHAPE_DIVIDER : SHAPE_GROUP;\n newNode.cssClasses = `${newNode.cssClasses} ${CSS_DIAGRAM_CLUSTER} ${altFlag ? CSS_DIAGRAM_CLUSTER_ALT : \"\"}`;\n }\n const nodeData = {\n labelStyle: \"\",\n shape: newNode.shape,\n label: newNode.description,\n cssClasses: newNode.cssClasses,\n cssCompiledStyles: [],\n cssStyles: newNode.cssStyles,\n id: itemId,\n dir: newNode.dir,\n domId: stateDomId(itemId, graphItemCount),\n type: newNode.type,\n isGroup: newNode.type === \"group\",\n padding: 8,\n rx: 10,\n ry: 10,\n look\n };\n if (nodeData.shape === SHAPE_DIVIDER) {\n nodeData.label = \"\";\n }\n if (parent && parent.id !== \"root\") {\n log.trace(\"Setting node \", itemId, \" to be child of its parent \", parent.id);\n nodeData.parentId = parent.id;\n }\n nodeData.centerLabel = true;\n if (parsedItem.note) {\n const noteData = {\n labelStyle: \"\",\n shape: SHAPE_NOTE,\n label: parsedItem.note.text,\n cssClasses: CSS_DIAGRAM_NOTE,\n // useHtmlLabels: false,\n cssStyles: [],\n cssCompilesStyles: [],\n id: itemId + NOTE_ID + \"-\" + graphItemCount,\n domId: stateDomId(itemId, graphItemCount, NOTE),\n type: newNode.type,\n isGroup: newNode.type === \"group\",\n padding: getConfig().flowchart.padding,\n look,\n position: parsedItem.note.position\n };\n const parentNodeId = itemId + PARENT_ID;\n const groupData = {\n labelStyle: \"\",\n shape: SHAPE_NOTEGROUP,\n label: parsedItem.note.text,\n cssClasses: newNode.cssClasses,\n cssStyles: [],\n id: itemId + PARENT_ID,\n domId: stateDomId(itemId, graphItemCount, PARENT),\n type: \"group\",\n isGroup: true,\n padding: 16,\n //getConfig().flowchart.padding\n look,\n position: parsedItem.note.position\n };\n graphItemCount++;\n groupData.id = parentNodeId;\n noteData.parentId = parentNodeId;\n insertOrUpdateNode(nodes2, groupData, classes2);\n insertOrUpdateNode(nodes2, noteData, classes2);\n insertOrUpdateNode(nodes2, nodeData, classes2);\n let from = itemId;\n let to = noteData.id;\n if (parsedItem.note.position === \"left of\") {\n from = noteData.id;\n to = itemId;\n }\n edges2.push({\n id: from + \"-\" + to,\n start: from,\n end: to,\n arrowhead: \"none\",\n arrowTypeEnd: \"\",\n style: G_EDGE_STYLE,\n labelStyle: \"\",\n classes: CSS_EDGE_NOTE_EDGE,\n arrowheadStyle: G_EDGE_ARROWHEADSTYLE,\n labelpos: G_EDGE_LABELPOS,\n labelType: G_EDGE_LABELTYPE,\n thickness: G_EDGE_THICKNESS,\n look\n });\n } else {\n insertOrUpdateNode(nodes2, nodeData, classes2);\n }\n }\n if (parsedItem.doc) {\n log.trace(\"Adding nodes children \");\n setupDoc(parsedItem, parsedItem.doc, diagramStates, nodes2, edges2, !altFlag, look, classes2);\n }\n}, \"dataFetcher\");\nvar reset = /* @__PURE__ */ __name(() => {\n nodeDb.clear();\n graphItemCount = 0;\n}, \"reset\");\n\n// src/diagrams/state/stateDb.js\nvar START_NODE = \"[*]\";\nvar START_TYPE = \"start\";\nvar END_NODE = START_NODE;\nvar END_TYPE = \"end\";\nvar COLOR_KEYWORD = \"color\";\nvar FILL_KEYWORD = \"fill\";\nvar BG_FILL = \"bgFill\";\nvar STYLECLASS_SEP = \",\";\nfunction newClassesList() {\n return /* @__PURE__ */ new Map();\n}\n__name(newClassesList, \"newClassesList\");\nvar nodes = [];\nvar edges = [];\nvar direction = DEFAULT_DIAGRAM_DIRECTION;\nvar rootDoc = [];\nvar classes = newClassesList();\nvar newDoc = /* @__PURE__ */ __name(() => {\n return {\n /** @type {{ id1: string, id2: string, relationTitle: string }[]} */\n relations: [],\n states: /* @__PURE__ */ new Map(),\n documents: {}\n };\n}, \"newDoc\");\nvar documents = {\n root: newDoc()\n};\nvar currentDocument = documents.root;\nvar startEndCount = 0;\nvar dividerCnt = 0;\nvar lineType = {\n LINE: 0,\n DOTTED_LINE: 1\n};\nvar relationType = {\n AGGREGATION: 0,\n EXTENSION: 1,\n COMPOSITION: 2,\n DEPENDENCY: 3\n};\nvar clone = /* @__PURE__ */ __name((o) => JSON.parse(JSON.stringify(o)), \"clone\");\nvar setRootDoc = /* @__PURE__ */ __name((o) => {\n log.info(\"Setting root doc\", o);\n rootDoc = o;\n}, \"setRootDoc\");\nvar getRootDoc = /* @__PURE__ */ __name(() => rootDoc, \"getRootDoc\");\nvar docTranslator = /* @__PURE__ */ __name((parent, node, first) => {\n if (node.stmt === STMT_RELATION) {\n docTranslator(parent, node.state1, true);\n docTranslator(parent, node.state2, false);\n } else {\n if (node.stmt === STMT_STATE) {\n if (node.id === \"[*]\") {\n node.id = first ? parent.id + \"_start\" : parent.id + \"_end\";\n node.start = first;\n } else {\n node.id = node.id.trim();\n }\n }\n if (node.doc) {\n const doc = [];\n let currentDoc = [];\n let i;\n for (i = 0; i < node.doc.length; i++) {\n if (node.doc[i].type === DIVIDER_TYPE) {\n const newNode = clone(node.doc[i]);\n newNode.doc = clone(currentDoc);\n doc.push(newNode);\n currentDoc = [];\n } else {\n currentDoc.push(node.doc[i]);\n }\n }\n if (doc.length > 0 && currentDoc.length > 0) {\n const newNode = {\n stmt: STMT_STATE,\n id: generateId(),\n type: \"divider\",\n doc: clone(currentDoc)\n };\n doc.push(clone(newNode));\n node.doc = doc;\n }\n node.doc.forEach((docNode) => docTranslator(node, docNode, true));\n }\n }\n}, \"docTranslator\");\nvar getRootDocV2 = /* @__PURE__ */ __name(() => {\n docTranslator({ id: \"root\" }, { id: \"root\", doc: rootDoc }, true);\n return { id: \"root\", doc: rootDoc };\n}, \"getRootDocV2\");\nvar extract = /* @__PURE__ */ __name((_doc) => {\n let doc;\n if (_doc.doc) {\n doc = _doc.doc;\n } else {\n doc = _doc;\n }\n log.info(doc);\n clear2(true);\n log.info(\"Extract initial document:\", doc);\n doc.forEach((item) => {\n log.warn(\"Statement\", item.stmt);\n switch (item.stmt) {\n case STMT_STATE:\n addState(\n item.id.trim(),\n item.type,\n item.doc,\n item.description,\n item.note,\n item.classes,\n item.styles,\n item.textStyles\n );\n break;\n case STMT_RELATION:\n addRelation(item.state1, item.state2, item.description);\n break;\n case STMT_CLASSDEF:\n addStyleClass(item.id.trim(), item.classes);\n break;\n case STMT_STYLEDEF:\n {\n const ids = item.id.trim().split(\",\");\n const styles = item.styleClass.split(\",\");\n ids.forEach((id) => {\n let foundState = getState(id);\n if (foundState === void 0) {\n const trimmedId = id.trim();\n addState(trimmedId);\n foundState = getState(trimmedId);\n }\n foundState.styles = styles.map((s) => s.replace(/;/g, \"\")?.trim());\n });\n }\n break;\n case STMT_APPLYCLASS:\n setCssClass(item.id.trim(), item.styleClass);\n break;\n }\n });\n const diagramStates = getStates();\n const config = getConfig();\n const look = config.look;\n reset();\n dataFetcher(void 0, getRootDocV2(), diagramStates, nodes, edges, true, look, classes);\n nodes.forEach((node) => {\n if (Array.isArray(node.label)) {\n node.description = node.label.slice(1);\n if (node.isGroup && node.description.length > 0) {\n throw new Error(\n \"Group nodes can only have label. Remove the additional description for node [\" + node.id + \"]\"\n );\n }\n node.label = node.label[0];\n }\n });\n}, \"extract\");\nvar addState = /* @__PURE__ */ __name(function(id, type = DEFAULT_STATE_TYPE, doc = null, descr = null, note = null, classes2 = null, styles = null, textStyles = null) {\n const trimmedId = id?.trim();\n if (!currentDocument.states.has(trimmedId)) {\n log.info(\"Adding state \", trimmedId, descr);\n currentDocument.states.set(trimmedId, {\n id: trimmedId,\n descriptions: [],\n type,\n doc,\n note,\n classes: [],\n styles: [],\n textStyles: []\n });\n } else {\n if (!currentDocument.states.get(trimmedId).doc) {\n currentDocument.states.get(trimmedId).doc = doc;\n }\n if (!currentDocument.states.get(trimmedId).type) {\n currentDocument.states.get(trimmedId).type = type;\n }\n }\n if (descr) {\n log.info(\"Setting state description\", trimmedId, descr);\n if (typeof descr === \"string\") {\n addDescription(trimmedId, descr.trim());\n }\n if (typeof descr === \"object\") {\n descr.forEach((des) => addDescription(trimmedId, des.trim()));\n }\n }\n if (note) {\n const doc2 = currentDocument.states.get(trimmedId);\n doc2.note = note;\n doc2.note.text = common_default.sanitizeText(doc2.note.text, getConfig());\n }\n if (classes2) {\n log.info(\"Setting state classes\", trimmedId, classes2);\n const classesList = typeof classes2 === \"string\" ? [classes2] : classes2;\n classesList.forEach((cssClass) => setCssClass(trimmedId, cssClass.trim()));\n }\n if (styles) {\n log.info(\"Setting state styles\", trimmedId, styles);\n const stylesList = typeof styles === \"string\" ? [styles] : styles;\n stylesList.forEach((style) => setStyle(trimmedId, style.trim()));\n }\n if (textStyles) {\n log.info(\"Setting state styles\", trimmedId, styles);\n const textStylesList = typeof textStyles === \"string\" ? [textStyles] : textStyles;\n textStylesList.forEach((textStyle) => setTextStyle(trimmedId, textStyle.trim()));\n }\n}, \"addState\");\nvar clear2 = /* @__PURE__ */ __name(function(saveCommon) {\n nodes = [];\n edges = [];\n documents = {\n root: newDoc()\n };\n currentDocument = documents.root;\n startEndCount = 0;\n classes = newClassesList();\n if (!saveCommon) {\n clear();\n }\n}, \"clear\");\nvar getState = /* @__PURE__ */ __name(function(id) {\n return currentDocument.states.get(id);\n}, \"getState\");\nvar getStates = /* @__PURE__ */ __name(function() {\n return currentDocument.states;\n}, \"getStates\");\nvar logDocuments = /* @__PURE__ */ __name(function() {\n log.info(\"Documents = \", documents);\n}, \"logDocuments\");\nvar getRelations = /* @__PURE__ */ __name(function() {\n return currentDocument.relations;\n}, \"getRelations\");\nfunction startIdIfNeeded(id = \"\") {\n let fixedId = id;\n if (id === START_NODE) {\n startEndCount++;\n fixedId = `${START_TYPE}${startEndCount}`;\n }\n return fixedId;\n}\n__name(startIdIfNeeded, \"startIdIfNeeded\");\nfunction startTypeIfNeeded(id = \"\", type = DEFAULT_STATE_TYPE) {\n return id === START_NODE ? START_TYPE : type;\n}\n__name(startTypeIfNeeded, \"startTypeIfNeeded\");\nfunction endIdIfNeeded(id = \"\") {\n let fixedId = id;\n if (id === END_NODE) {\n startEndCount++;\n fixedId = `${END_TYPE}${startEndCount}`;\n }\n return fixedId;\n}\n__name(endIdIfNeeded, \"endIdIfNeeded\");\nfunction endTypeIfNeeded(id = \"\", type = DEFAULT_STATE_TYPE) {\n return id === END_NODE ? END_TYPE : type;\n}\n__name(endTypeIfNeeded, \"endTypeIfNeeded\");\nfunction addRelationObjs(item1, item2, relationTitle) {\n let id1 = startIdIfNeeded(item1.id.trim());\n let type1 = startTypeIfNeeded(item1.id.trim(), item1.type);\n let id2 = startIdIfNeeded(item2.id.trim());\n let type2 = startTypeIfNeeded(item2.id.trim(), item2.type);\n addState(\n id1,\n type1,\n item1.doc,\n item1.description,\n item1.note,\n item1.classes,\n item1.styles,\n item1.textStyles\n );\n addState(\n id2,\n type2,\n item2.doc,\n item2.description,\n item2.note,\n item2.classes,\n item2.styles,\n item2.textStyles\n );\n currentDocument.relations.push({\n id1,\n id2,\n relationTitle: common_default.sanitizeText(relationTitle, getConfig())\n });\n}\n__name(addRelationObjs, \"addRelationObjs\");\nvar addRelation = /* @__PURE__ */ __name(function(item1, item2, title) {\n if (typeof item1 === \"object\") {\n addRelationObjs(item1, item2, title);\n } else {\n const id1 = startIdIfNeeded(item1.trim());\n const type1 = startTypeIfNeeded(item1);\n const id2 = endIdIfNeeded(item2.trim());\n const type2 = endTypeIfNeeded(item2);\n addState(id1, type1);\n addState(id2, type2);\n currentDocument.relations.push({\n id1,\n id2,\n title: common_default.sanitizeText(title, getConfig())\n });\n }\n}, \"addRelation\");\nvar addDescription = /* @__PURE__ */ __name(function(id, descr) {\n const theState = currentDocument.states.get(id);\n const _descr = descr.startsWith(\":\") ? descr.replace(\":\", \"\").trim() : descr;\n theState.descriptions.push(common_default.sanitizeText(_descr, getConfig()));\n}, \"addDescription\");\nvar cleanupLabel = /* @__PURE__ */ __name(function(label) {\n if (label.substring(0, 1) === \":\") {\n return label.substr(2).trim();\n } else {\n return label.trim();\n }\n}, \"cleanupLabel\");\nvar getDividerId = /* @__PURE__ */ __name(() => {\n dividerCnt++;\n return \"divider-id-\" + dividerCnt;\n}, \"getDividerId\");\nvar addStyleClass = /* @__PURE__ */ __name(function(id, styleAttributes = \"\") {\n if (!classes.has(id)) {\n classes.set(id, { id, styles: [], textStyles: [] });\n }\n const foundClass = classes.get(id);\n if (styleAttributes !== void 0 && styleAttributes !== null) {\n styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => {\n const fixedAttrib = attrib.replace(/([^;]*);/, \"$1\").trim();\n if (RegExp(COLOR_KEYWORD).exec(attrib)) {\n const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL);\n const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD);\n foundClass.textStyles.push(newStyle2);\n }\n foundClass.styles.push(fixedAttrib);\n });\n }\n}, \"addStyleClass\");\nvar getClasses2 = /* @__PURE__ */ __name(function() {\n return classes;\n}, \"getClasses\");\nvar setCssClass = /* @__PURE__ */ __name(function(itemIds, cssClassName) {\n itemIds.split(\",\").forEach(function(id) {\n let foundState = getState(id);\n if (foundState === void 0) {\n const trimmedId = id.trim();\n addState(trimmedId);\n foundState = getState(trimmedId);\n }\n foundState.classes.push(cssClassName);\n });\n}, \"setCssClass\");\nvar setStyle = /* @__PURE__ */ __name(function(itemId, styleText) {\n const item = getState(itemId);\n if (item !== void 0) {\n item.styles.push(styleText);\n }\n}, \"setStyle\");\nvar setTextStyle = /* @__PURE__ */ __name(function(itemId, cssClassName) {\n const item = getState(itemId);\n if (item !== void 0) {\n item.textStyles.push(cssClassName);\n }\n}, \"setTextStyle\");\nvar getDirection = /* @__PURE__ */ __name(() => direction, \"getDirection\");\nvar setDirection = /* @__PURE__ */ __name((dir) => {\n direction = dir;\n}, \"setDirection\");\nvar trimColon = /* @__PURE__ */ __name((str) => str && str[0] === \":\" ? str.substr(1).trim() : str.trim(), \"trimColon\");\nvar getData = /* @__PURE__ */ __name(() => {\n const config = getConfig();\n return { nodes, edges, other: {}, config, direction: getDir(getRootDocV2()) };\n}, \"getData\");\nvar stateDb_default = {\n getConfig: /* @__PURE__ */ __name(() => getConfig().state, \"getConfig\"),\n getData,\n addState,\n clear: clear2,\n getState,\n getStates,\n getRelations,\n getClasses: getClasses2,\n getDirection,\n addRelation,\n getDividerId,\n setDirection,\n cleanupLabel,\n lineType,\n relationType,\n logDocuments,\n getRootDoc,\n setRootDoc,\n getRootDocV2,\n extract,\n trimColon,\n getAccTitle,\n setAccTitle,\n getAccDescription,\n setAccDescription,\n addStyleClass,\n setCssClass,\n addDescription,\n setDiagramTitle,\n getDiagramTitle\n};\n\n// src/diagrams/state/styles.js\nvar getStyles = /* @__PURE__ */ __name((options) => `\ndefs #statediagram-barbEnd {\n fill: ${options.transitionColor};\n stroke: ${options.transitionColor};\n }\ng.stateGroup text {\n fill: ${options.nodeBorder};\n stroke: none;\n font-size: 10px;\n}\ng.stateGroup text {\n fill: ${options.textColor};\n stroke: none;\n font-size: 10px;\n\n}\ng.stateGroup .state-title {\n font-weight: bolder;\n fill: ${options.stateLabelColor};\n}\n\ng.stateGroup rect {\n fill: ${options.mainBkg};\n stroke: ${options.nodeBorder};\n}\n\ng.stateGroup line {\n stroke: ${options.lineColor};\n stroke-width: 1;\n}\n\n.transition {\n stroke: ${options.transitionColor};\n stroke-width: 1;\n fill: none;\n}\n\n.stateGroup .composit {\n fill: ${options.background};\n border-bottom: 1px\n}\n\n.stateGroup .alt-composit {\n fill: #e0e0e0;\n border-bottom: 1px\n}\n\n.state-note {\n stroke: ${options.noteBorderColor};\n fill: ${options.noteBkgColor};\n\n text {\n fill: ${options.noteTextColor};\n stroke: none;\n font-size: 10px;\n }\n}\n\n.stateLabel .box {\n stroke: none;\n stroke-width: 0;\n fill: ${options.mainBkg};\n opacity: 0.5;\n}\n\n.edgeLabel .label rect {\n fill: ${options.labelBackgroundColor};\n opacity: 0.5;\n}\n.edgeLabel {\n background-color: ${options.edgeLabelBackground};\n p {\n background-color: ${options.edgeLabelBackground};\n }\n rect {\n opacity: 0.5;\n background-color: ${options.edgeLabelBackground};\n fill: ${options.edgeLabelBackground};\n }\n text-align: center;\n}\n.edgeLabel .label text {\n fill: ${options.transitionLabelColor || options.tertiaryTextColor};\n}\n.label div .edgeLabel {\n color: ${options.transitionLabelColor || options.tertiaryTextColor};\n}\n\n.stateLabel text {\n fill: ${options.stateLabelColor};\n font-size: 10px;\n font-weight: bold;\n}\n\n.node circle.state-start {\n fill: ${options.specialStateColor};\n stroke: ${options.specialStateColor};\n}\n\n.node .fork-join {\n fill: ${options.specialStateColor};\n stroke: ${options.specialStateColor};\n}\n\n.node circle.state-end {\n fill: ${options.innerEndBackground};\n stroke: ${options.background};\n stroke-width: 1.5\n}\n.end-state-inner {\n fill: ${options.compositeBackground || options.background};\n // stroke: ${options.background};\n stroke-width: 1.5\n}\n\n.node rect {\n fill: ${options.stateBkg || options.mainBkg};\n stroke: ${options.stateBorder || options.nodeBorder};\n stroke-width: 1px;\n}\n.node polygon {\n fill: ${options.mainBkg};\n stroke: ${options.stateBorder || options.nodeBorder};;\n stroke-width: 1px;\n}\n#statediagram-barbEnd {\n fill: ${options.lineColor};\n}\n\n.statediagram-cluster rect {\n fill: ${options.compositeTitleBackground};\n stroke: ${options.stateBorder || options.nodeBorder};\n stroke-width: 1px;\n}\n\n.cluster-label, .nodeLabel {\n color: ${options.stateLabelColor};\n // line-height: 1;\n}\n\n.statediagram-cluster rect.outer {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state .divider {\n stroke: ${options.stateBorder || options.nodeBorder};\n}\n\n.statediagram-state .title-state {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-cluster.statediagram-cluster .inner {\n fill: ${options.compositeBackground || options.background};\n}\n.statediagram-cluster.statediagram-cluster-alt .inner {\n fill: ${options.altBackground ? options.altBackground : \"#efefef\"};\n}\n\n.statediagram-cluster .inner {\n rx:0;\n ry:0;\n}\n\n.statediagram-state rect.basic {\n rx: 5px;\n ry: 5px;\n}\n.statediagram-state rect.divider {\n stroke-dasharray: 10,10;\n fill: ${options.altBackground ? options.altBackground : \"#efefef\"};\n}\n\n.note-edge {\n stroke-dasharray: 5;\n}\n\n.statediagram-note rect {\n fill: ${options.noteBkgColor};\n stroke: ${options.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n.statediagram-note rect {\n fill: ${options.noteBkgColor};\n stroke: ${options.noteBorderColor};\n stroke-width: 1px;\n rx: 0;\n ry: 0;\n}\n\n.statediagram-note text {\n fill: ${options.noteTextColor};\n}\n\n.statediagram-note .nodeLabel {\n color: ${options.noteTextColor};\n}\n.statediagram .edgeLabel {\n color: red; // ${options.noteTextColor};\n}\n\n#dependencyStart, #dependencyEnd {\n fill: ${options.lineColor};\n stroke: ${options.lineColor};\n stroke-width: 1;\n}\n\n.statediagramTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${options.textColor};\n}\n`, \"getStyles\");\nvar styles_default = getStyles;\n\nexport {\n stateDiagram_default,\n stateRenderer_v3_unified_default,\n stateDb_default,\n styles_default\n};\n", "import {\n stateDb_default,\n stateDiagram_default,\n styles_default\n} from \"./chunk-2JBRQKJ5.mjs\";\nimport \"./chunk-DUMQOTYW.mjs\";\nimport \"./chunk-YWFND7JV.mjs\";\nimport \"./chunk-WSMKYKZ5.mjs\";\nimport \"./chunk-VR7AIV22.mjs\";\nimport \"./chunk-23ATMZXV.mjs\";\nimport \"./chunk-5N55DQE6.mjs\";\nimport {\n utils_default\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n common_default,\n configureSvgSize,\n getConfig2 as getConfig,\n log\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/state/stateRenderer.js\nimport { select } from \"d3\";\nimport { layout as dagreLayout } from \"dagre-d3-es/src/dagre/index.js\";\nimport * as graphlib from \"dagre-d3-es/src/graphlib/index.js\";\n\n// src/diagrams/state/shapes.js\nimport { line, curveBasis } from \"d3\";\n\n// src/diagrams/state/id-cache.js\nvar idCache = {};\nvar set = /* @__PURE__ */ __name((key, val) => {\n idCache[key] = val;\n}, \"set\");\nvar get = /* @__PURE__ */ __name((k) => idCache[k], \"get\");\nvar keys = /* @__PURE__ */ __name(() => Object.keys(idCache), \"keys\");\nvar size = /* @__PURE__ */ __name(() => keys().length, \"size\");\nvar id_cache_default = {\n get,\n set,\n keys,\n size\n};\n\n// src/diagrams/state/shapes.js\nvar drawStartState = /* @__PURE__ */ __name((g) => g.append(\"circle\").attr(\"class\", \"start-state\").attr(\"r\", getConfig().state.sizeUnit).attr(\"cx\", getConfig().state.padding + getConfig().state.sizeUnit).attr(\"cy\", getConfig().state.padding + getConfig().state.sizeUnit), \"drawStartState\");\nvar drawDivider = /* @__PURE__ */ __name((g) => g.append(\"line\").style(\"stroke\", \"grey\").style(\"stroke-dasharray\", \"3\").attr(\"x1\", getConfig().state.textHeight).attr(\"class\", \"divider\").attr(\"x2\", getConfig().state.textHeight * 2).attr(\"y1\", 0).attr(\"y2\", 0), \"drawDivider\");\nvar drawSimpleState = /* @__PURE__ */ __name((g, stateDef) => {\n const state = g.append(\"text\").attr(\"x\", 2 * getConfig().state.padding).attr(\"y\", getConfig().state.textHeight + 2 * getConfig().state.padding).attr(\"font-size\", getConfig().state.fontSize).attr(\"class\", \"state-title\").text(stateDef.id);\n const classBox = state.node().getBBox();\n g.insert(\"rect\", \":first-child\").attr(\"x\", getConfig().state.padding).attr(\"y\", getConfig().state.padding).attr(\"width\", classBox.width + 2 * getConfig().state.padding).attr(\"height\", classBox.height + 2 * getConfig().state.padding).attr(\"rx\", getConfig().state.radius);\n return state;\n}, \"drawSimpleState\");\nvar drawDescrState = /* @__PURE__ */ __name((g, stateDef) => {\n const addTspan = /* @__PURE__ */ __name(function(textEl, txt, isFirst2) {\n const tSpan = textEl.append(\"tspan\").attr(\"x\", 2 * getConfig().state.padding).text(txt);\n if (!isFirst2) {\n tSpan.attr(\"dy\", getConfig().state.textHeight);\n }\n }, \"addTspan\");\n const title = g.append(\"text\").attr(\"x\", 2 * getConfig().state.padding).attr(\"y\", getConfig().state.textHeight + 1.3 * getConfig().state.padding).attr(\"font-size\", getConfig().state.fontSize).attr(\"class\", \"state-title\").text(stateDef.descriptions[0]);\n const titleBox = title.node().getBBox();\n const titleHeight = titleBox.height;\n const description = g.append(\"text\").attr(\"x\", getConfig().state.padding).attr(\n \"y\",\n titleHeight + getConfig().state.padding * 0.4 + getConfig().state.dividerMargin + getConfig().state.textHeight\n ).attr(\"class\", \"state-description\");\n let isFirst = true;\n let isSecond = true;\n stateDef.descriptions.forEach(function(descr) {\n if (!isFirst) {\n addTspan(description, descr, isSecond);\n isSecond = false;\n }\n isFirst = false;\n });\n const descrLine = g.append(\"line\").attr(\"x1\", getConfig().state.padding).attr(\"y1\", getConfig().state.padding + titleHeight + getConfig().state.dividerMargin / 2).attr(\"y2\", getConfig().state.padding + titleHeight + getConfig().state.dividerMargin / 2).attr(\"class\", \"descr-divider\");\n const descrBox = description.node().getBBox();\n const width = Math.max(descrBox.width, titleBox.width);\n descrLine.attr(\"x2\", width + 3 * getConfig().state.padding);\n g.insert(\"rect\", \":first-child\").attr(\"x\", getConfig().state.padding).attr(\"y\", getConfig().state.padding).attr(\"width\", width + 2 * getConfig().state.padding).attr(\"height\", descrBox.height + titleHeight + 2 * getConfig().state.padding).attr(\"rx\", getConfig().state.radius);\n return g;\n}, \"drawDescrState\");\nvar addTitleAndBox = /* @__PURE__ */ __name((g, stateDef, altBkg) => {\n const pad = getConfig().state.padding;\n const dblPad = 2 * getConfig().state.padding;\n const orgBox = g.node().getBBox();\n const orgWidth = orgBox.width;\n const orgX = orgBox.x;\n const title = g.append(\"text\").attr(\"x\", 0).attr(\"y\", getConfig().state.titleShift).attr(\"font-size\", getConfig().state.fontSize).attr(\"class\", \"state-title\").text(stateDef.id);\n const titleBox = title.node().getBBox();\n const titleWidth = titleBox.width + dblPad;\n let width = Math.max(titleWidth, orgWidth);\n if (width === orgWidth) {\n width = width + dblPad;\n }\n let startX;\n const graphBox = g.node().getBBox();\n if (stateDef.doc) {\n }\n startX = orgX - pad;\n if (titleWidth > orgWidth) {\n startX = (orgWidth - width) / 2 + pad;\n }\n if (Math.abs(orgX - graphBox.x) < pad && titleWidth > orgWidth) {\n startX = orgX - (titleWidth - orgWidth) / 2;\n }\n const lineY = 1 - getConfig().state.textHeight;\n g.insert(\"rect\", \":first-child\").attr(\"x\", startX).attr(\"y\", lineY).attr(\"class\", altBkg ? \"alt-composit\" : \"composit\").attr(\"width\", width).attr(\n \"height\",\n graphBox.height + getConfig().state.textHeight + getConfig().state.titleShift + 1\n ).attr(\"rx\", \"0\");\n title.attr(\"x\", startX + pad);\n if (titleWidth <= orgWidth) {\n title.attr(\"x\", orgX + (width - dblPad) / 2 - titleWidth / 2 + pad);\n }\n g.insert(\"rect\", \":first-child\").attr(\"x\", startX).attr(\n \"y\",\n getConfig().state.titleShift - getConfig().state.textHeight - getConfig().state.padding\n ).attr(\"width\", width).attr(\"height\", getConfig().state.textHeight * 3).attr(\"rx\", getConfig().state.radius);\n g.insert(\"rect\", \":first-child\").attr(\"x\", startX).attr(\n \"y\",\n getConfig().state.titleShift - getConfig().state.textHeight - getConfig().state.padding\n ).attr(\"width\", width).attr(\"height\", graphBox.height + 3 + 2 * getConfig().state.textHeight).attr(\"rx\", getConfig().state.radius);\n return g;\n}, \"addTitleAndBox\");\nvar drawEndState = /* @__PURE__ */ __name((g) => {\n g.append(\"circle\").attr(\"class\", \"end-state-outer\").attr(\"r\", getConfig().state.sizeUnit + getConfig().state.miniPadding).attr(\n \"cx\",\n getConfig().state.padding + getConfig().state.sizeUnit + getConfig().state.miniPadding\n ).attr(\n \"cy\",\n getConfig().state.padding + getConfig().state.sizeUnit + getConfig().state.miniPadding\n );\n return g.append(\"circle\").attr(\"class\", \"end-state-inner\").attr(\"r\", getConfig().state.sizeUnit).attr(\"cx\", getConfig().state.padding + getConfig().state.sizeUnit + 2).attr(\"cy\", getConfig().state.padding + getConfig().state.sizeUnit + 2);\n}, \"drawEndState\");\nvar drawForkJoinState = /* @__PURE__ */ __name((g, stateDef) => {\n let width = getConfig().state.forkWidth;\n let height = getConfig().state.forkHeight;\n if (stateDef.parentId) {\n let tmp = width;\n width = height;\n height = tmp;\n }\n return g.append(\"rect\").style(\"stroke\", \"black\").style(\"fill\", \"black\").attr(\"width\", width).attr(\"height\", height).attr(\"x\", getConfig().state.padding).attr(\"y\", getConfig().state.padding);\n}, \"drawForkJoinState\");\nvar _drawLongText = /* @__PURE__ */ __name((_text, x, y, g) => {\n let textHeight = 0;\n const textElem = g.append(\"text\");\n textElem.style(\"text-anchor\", \"start\");\n textElem.attr(\"class\", \"noteText\");\n let text = _text.replace(/\\r\\n/g, \"
\");\n text = text.replace(/\\n/g, \"
\");\n const lines = text.split(common_default.lineBreakRegex);\n let tHeight = 1.25 * getConfig().state.noteMargin;\n for (const line2 of lines) {\n const txt = line2.trim();\n if (txt.length > 0) {\n const span = textElem.append(\"tspan\");\n span.text(txt);\n if (tHeight === 0) {\n const textBounds = span.node().getBBox();\n tHeight += textBounds.height;\n }\n textHeight += tHeight;\n span.attr(\"x\", x + getConfig().state.noteMargin);\n span.attr(\"y\", y + textHeight + 1.25 * getConfig().state.noteMargin);\n }\n }\n return { textWidth: textElem.node().getBBox().width, textHeight };\n}, \"_drawLongText\");\nvar drawNote = /* @__PURE__ */ __name((text, g) => {\n g.attr(\"class\", \"state-note\");\n const note = g.append(\"rect\").attr(\"x\", 0).attr(\"y\", getConfig().state.padding);\n const rectElem = g.append(\"g\");\n const { textWidth, textHeight } = _drawLongText(text, 0, 0, rectElem);\n note.attr(\"height\", textHeight + 2 * getConfig().state.noteMargin);\n note.attr(\"width\", textWidth + getConfig().state.noteMargin * 2);\n return note;\n}, \"drawNote\");\nvar drawState = /* @__PURE__ */ __name(function(elem, stateDef) {\n const id = stateDef.id;\n const stateInfo = {\n id,\n label: stateDef.id,\n width: 0,\n height: 0\n };\n const g = elem.append(\"g\").attr(\"id\", id).attr(\"class\", \"stateGroup\");\n if (stateDef.type === \"start\") {\n drawStartState(g);\n }\n if (stateDef.type === \"end\") {\n drawEndState(g);\n }\n if (stateDef.type === \"fork\" || stateDef.type === \"join\") {\n drawForkJoinState(g, stateDef);\n }\n if (stateDef.type === \"note\") {\n drawNote(stateDef.note.text, g);\n }\n if (stateDef.type === \"divider\") {\n drawDivider(g);\n }\n if (stateDef.type === \"default\" && stateDef.descriptions.length === 0) {\n drawSimpleState(g, stateDef);\n }\n if (stateDef.type === \"default\" && stateDef.descriptions.length > 0) {\n drawDescrState(g, stateDef);\n }\n const stateBox = g.node().getBBox();\n stateInfo.width = stateBox.width + 2 * getConfig().state.padding;\n stateInfo.height = stateBox.height + 2 * getConfig().state.padding;\n id_cache_default.set(id, stateInfo);\n return stateInfo;\n}, \"drawState\");\nvar edgeCount = 0;\nvar drawEdge = /* @__PURE__ */ __name(function(elem, path, relation) {\n const getRelationType = /* @__PURE__ */ __name(function(type) {\n switch (type) {\n case stateDb_default.relationType.AGGREGATION:\n return \"aggregation\";\n case stateDb_default.relationType.EXTENSION:\n return \"extension\";\n case stateDb_default.relationType.COMPOSITION:\n return \"composition\";\n case stateDb_default.relationType.DEPENDENCY:\n return \"dependency\";\n }\n }, \"getRelationType\");\n path.points = path.points.filter((p) => !Number.isNaN(p.y));\n const lineData = path.points;\n const lineFunction = line().x(function(d) {\n return d.x;\n }).y(function(d) {\n return d.y;\n }).curve(curveBasis);\n const svgPath = elem.append(\"path\").attr(\"d\", lineFunction(lineData)).attr(\"id\", \"edge\" + edgeCount).attr(\"class\", \"transition\");\n let url = \"\";\n if (getConfig().state.arrowMarkerAbsolute) {\n url = window.location.protocol + \"//\" + window.location.host + window.location.pathname + window.location.search;\n url = url.replace(/\\(/g, \"\\\\(\");\n url = url.replace(/\\)/g, \"\\\\)\");\n }\n svgPath.attr(\n \"marker-end\",\n \"url(\" + url + \"#\" + getRelationType(stateDb_default.relationType.DEPENDENCY) + \"End)\"\n );\n if (relation.title !== void 0) {\n const label = elem.append(\"g\").attr(\"class\", \"stateLabel\");\n const { x, y } = utils_default.calcLabelPosition(path.points);\n const rows = common_default.getRows(relation.title);\n let titleHeight = 0;\n const titleRows = [];\n let maxWidth = 0;\n let minX = 0;\n for (let i = 0; i <= rows.length; i++) {\n const title = label.append(\"text\").attr(\"text-anchor\", \"middle\").text(rows[i]).attr(\"x\", x).attr(\"y\", y + titleHeight);\n const boundsTmp = title.node().getBBox();\n maxWidth = Math.max(maxWidth, boundsTmp.width);\n minX = Math.min(minX, boundsTmp.x);\n log.info(boundsTmp.x, x, y + titleHeight);\n if (titleHeight === 0) {\n const titleBox = title.node().getBBox();\n titleHeight = titleBox.height;\n log.info(\"Title height\", titleHeight, y);\n }\n titleRows.push(title);\n }\n let boxHeight = titleHeight * rows.length;\n if (rows.length > 1) {\n const heightAdj = (rows.length - 1) * titleHeight * 0.5;\n titleRows.forEach((title, i) => title.attr(\"y\", y + i * titleHeight - heightAdj));\n boxHeight = titleHeight * rows.length;\n }\n const bounds = label.node().getBBox();\n label.insert(\"rect\", \":first-child\").attr(\"class\", \"box\").attr(\"x\", x - maxWidth / 2 - getConfig().state.padding / 2).attr(\"y\", y - boxHeight / 2 - getConfig().state.padding / 2 - 3.5).attr(\"width\", maxWidth + getConfig().state.padding).attr(\"height\", boxHeight + getConfig().state.padding);\n log.info(bounds);\n }\n edgeCount++;\n}, \"drawEdge\");\n\n// src/diagrams/state/stateRenderer.js\nvar conf;\nvar transformationLog = {};\nvar setConf = /* @__PURE__ */ __name(function() {\n}, \"setConf\");\nvar insertMarkers = /* @__PURE__ */ __name(function(elem) {\n elem.append(\"defs\").append(\"marker\").attr(\"id\", \"dependencyEnd\").attr(\"refX\", 19).attr(\"refY\", 7).attr(\"markerWidth\", 20).attr(\"markerHeight\", 28).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 19,7 L9,13 L14,7 L9,1 Z\");\n}, \"insertMarkers\");\nvar draw = /* @__PURE__ */ __name(function(text, id, _version, diagObj) {\n conf = getConfig().state;\n const securityLevel = getConfig().securityLevel;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select(sandboxElement.nodes()[0].contentDocument.body) : select(\"body\");\n const doc = securityLevel === \"sandbox\" ? sandboxElement.nodes()[0].contentDocument : document;\n log.debug(\"Rendering diagram \" + text);\n const diagram2 = root.select(`[id='${id}']`);\n insertMarkers(diagram2);\n const rootDoc = diagObj.db.getRootDoc();\n renderDoc(rootDoc, diagram2, void 0, false, root, doc, diagObj);\n const padding = conf.padding;\n const bounds = diagram2.node().getBBox();\n const width = bounds.width + padding * 2;\n const height = bounds.height + padding * 2;\n const svgWidth = width * 1.75;\n configureSvgSize(diagram2, height, svgWidth, conf.useMaxWidth);\n diagram2.attr(\n \"viewBox\",\n `${bounds.x - conf.padding} ${bounds.y - conf.padding} ` + width + \" \" + height\n );\n}, \"draw\");\nvar getLabelWidth = /* @__PURE__ */ __name((text) => {\n return text ? text.length * conf.fontSizeFactor : 1;\n}, \"getLabelWidth\");\nvar renderDoc = /* @__PURE__ */ __name((doc, diagram2, parentId, altBkg, root, domDocument, diagObj) => {\n const graph = new graphlib.Graph({\n compound: true,\n multigraph: true\n });\n let i;\n let edgeFreeDoc = true;\n for (i = 0; i < doc.length; i++) {\n if (doc[i].stmt === \"relation\") {\n edgeFreeDoc = false;\n break;\n }\n }\n if (parentId) {\n graph.setGraph({\n rankdir: \"LR\",\n multigraph: true,\n compound: true,\n // acyclicer: 'greedy',\n ranker: \"tight-tree\",\n ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor,\n nodeSep: edgeFreeDoc ? 1 : 50,\n isMultiGraph: true\n // ranksep: 5,\n // nodesep: 1\n });\n } else {\n graph.setGraph({\n rankdir: \"TB\",\n multigraph: true,\n compound: true,\n // isCompound: true,\n // acyclicer: 'greedy',\n // ranker: 'longest-path'\n ranksep: edgeFreeDoc ? 1 : conf.edgeLengthFactor,\n nodeSep: edgeFreeDoc ? 1 : 50,\n ranker: \"tight-tree\",\n // ranker: 'network-simplex'\n isMultiGraph: true\n });\n }\n graph.setDefaultEdgeLabel(function() {\n return {};\n });\n diagObj.db.extract(doc);\n const states = diagObj.db.getStates();\n const relations = diagObj.db.getRelations();\n const keys2 = Object.keys(states);\n let first = true;\n for (const key of keys2) {\n const stateDef = states[key];\n if (parentId) {\n stateDef.parentId = parentId;\n }\n let node;\n if (stateDef.doc) {\n let sub = diagram2.append(\"g\").attr(\"id\", stateDef.id).attr(\"class\", \"stateGroup\");\n node = renderDoc(stateDef.doc, sub, stateDef.id, !altBkg, root, domDocument, diagObj);\n if (first) {\n sub = addTitleAndBox(sub, stateDef, altBkg);\n let boxBounds = sub.node().getBBox();\n node.width = boxBounds.width;\n node.height = boxBounds.height + conf.padding / 2;\n transformationLog[stateDef.id] = { y: conf.compositTitleSize };\n } else {\n let boxBounds = sub.node().getBBox();\n node.width = boxBounds.width;\n node.height = boxBounds.height;\n }\n } else {\n node = drawState(diagram2, stateDef, graph);\n }\n if (stateDef.note) {\n const noteDef = {\n descriptions: [],\n id: stateDef.id + \"-note\",\n note: stateDef.note,\n type: \"note\"\n };\n const note = drawState(diagram2, noteDef, graph);\n if (stateDef.note.position === \"left of\") {\n graph.setNode(node.id + \"-note\", note);\n graph.setNode(node.id, node);\n } else {\n graph.setNode(node.id, node);\n graph.setNode(node.id + \"-note\", note);\n }\n graph.setParent(node.id, node.id + \"-group\");\n graph.setParent(node.id + \"-note\", node.id + \"-group\");\n } else {\n graph.setNode(node.id, node);\n }\n }\n log.debug(\"Count=\", graph.nodeCount(), graph);\n let cnt = 0;\n relations.forEach(function(relation) {\n cnt++;\n log.debug(\"Setting edge\", relation);\n graph.setEdge(\n relation.id1,\n relation.id2,\n {\n relation,\n width: getLabelWidth(relation.title),\n height: conf.labelHeight * common_default.getRows(relation.title).length,\n labelpos: \"c\"\n },\n \"id\" + cnt\n );\n });\n dagreLayout(graph);\n log.debug(\"Graph after layout\", graph.nodes());\n const svgElem = diagram2.node();\n graph.nodes().forEach(function(v) {\n if (v !== void 0 && graph.node(v) !== void 0) {\n log.warn(\"Node \" + v + \": \" + JSON.stringify(graph.node(v)));\n root.select(\"#\" + svgElem.id + \" #\" + v).attr(\n \"transform\",\n \"translate(\" + (graph.node(v).x - graph.node(v).width / 2) + \",\" + (graph.node(v).y + (transformationLog[v] ? transformationLog[v].y : 0) - graph.node(v).height / 2) + \" )\"\n );\n root.select(\"#\" + svgElem.id + \" #\" + v).attr(\"data-x-shift\", graph.node(v).x - graph.node(v).width / 2);\n const dividers = domDocument.querySelectorAll(\"#\" + svgElem.id + \" #\" + v + \" .divider\");\n dividers.forEach((divider) => {\n const parent = divider.parentElement;\n let pWidth = 0;\n let pShift = 0;\n if (parent) {\n if (parent.parentElement) {\n pWidth = parent.parentElement.getBBox().width;\n }\n pShift = parseInt(parent.getAttribute(\"data-x-shift\"), 10);\n if (Number.isNaN(pShift)) {\n pShift = 0;\n }\n }\n divider.setAttribute(\"x1\", 0 - pShift + 8);\n divider.setAttribute(\"x2\", pWidth - pShift - 8);\n });\n } else {\n log.debug(\"No Node \" + v + \": \" + JSON.stringify(graph.node(v)));\n }\n });\n let stateBox = svgElem.getBBox();\n graph.edges().forEach(function(e) {\n if (e !== void 0 && graph.edge(e) !== void 0) {\n log.debug(\"Edge \" + e.v + \" -> \" + e.w + \": \" + JSON.stringify(graph.edge(e)));\n drawEdge(diagram2, graph.edge(e), graph.edge(e).relation);\n }\n });\n stateBox = svgElem.getBBox();\n const stateInfo = {\n id: parentId ? parentId : \"root\",\n label: parentId ? parentId : \"root\",\n width: 0,\n height: 0\n };\n stateInfo.width = stateBox.width + 2 * conf.padding;\n stateInfo.height = stateBox.height + 2 * conf.padding;\n log.debug(\"Doc rendered\", stateInfo, graph);\n return stateInfo;\n}, \"renderDoc\");\nvar stateRenderer_default = {\n setConf,\n draw\n};\n\n// src/diagrams/state/stateDiagram.ts\nvar diagram = {\n parser: stateDiagram_default,\n db: stateDb_default,\n renderer: stateRenderer_default,\n styles: styles_default,\n init: /* @__PURE__ */ __name((cnf) => {\n if (!cnf.state) {\n cnf.state = {};\n }\n cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;\n stateDb_default.clear();\n }, \"init\")\n};\nexport {\n diagram\n};\n", "import {\n stateDb_default,\n stateDiagram_default,\n stateRenderer_v3_unified_default,\n styles_default\n} from \"./chunk-2JBRQKJ5.mjs\";\nimport \"./chunk-DUMQOTYW.mjs\";\nimport \"./chunk-YWFND7JV.mjs\";\nimport \"./chunk-WSMKYKZ5.mjs\";\nimport \"./chunk-VR7AIV22.mjs\";\nimport \"./chunk-23ATMZXV.mjs\";\nimport \"./chunk-5N55DQE6.mjs\";\nimport \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/state/stateDiagram-v2.ts\nvar diagram = {\n parser: stateDiagram_default,\n db: stateDb_default,\n renderer: stateRenderer_v3_unified_default,\n styles: styles_default,\n init: /* @__PURE__ */ __name((cnf) => {\n if (!cnf.state) {\n cnf.state = {};\n }\n cnf.state.arrowMarkerAbsolute = cnf.arrowMarkerAbsolute;\n stateDb_default.clear();\n }, \"init\")\n};\nexport {\n diagram\n};\n", "import {\n drawBackgroundRect,\n drawRect,\n drawText,\n getNoteRect\n} from \"./chunk-XVOYOM2C.mjs\";\nimport {\n __name,\n clear,\n configureSvgSize,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n getDiagramTitle,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/user-journey/parser/journey.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [6, 8, 10, 11, 12, 14, 16, 17, 18], $V1 = [1, 9], $V2 = [1, 10], $V3 = [1, 11], $V4 = [1, 12], $V5 = [1, 13], $V6 = [1, 14];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"journey\": 4, \"document\": 5, \"EOF\": 6, \"line\": 7, \"SPACE\": 8, \"statement\": 9, \"NEWLINE\": 10, \"title\": 11, \"acc_title\": 12, \"acc_title_value\": 13, \"acc_descr\": 14, \"acc_descr_value\": 15, \"acc_descr_multiline_value\": 16, \"section\": 17, \"taskName\": 18, \"taskData\": 19, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 4: \"journey\", 6: \"EOF\", 8: \"SPACE\", 10: \"NEWLINE\", 11: \"title\", 12: \"acc_title\", 13: \"acc_title_value\", 14: \"acc_descr\", 15: \"acc_descr_value\", 16: \"acc_descr_multiline_value\", 17: \"section\", 18: \"taskName\", 19: \"taskData\" },\n productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 2]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 1:\n return $$[$0 - 1];\n break;\n case 2:\n this.$ = [];\n break;\n case 3:\n $$[$0 - 1].push($$[$0]);\n this.$ = $$[$0 - 1];\n break;\n case 4:\n case 5:\n this.$ = $$[$0];\n break;\n case 6:\n case 7:\n this.$ = [];\n break;\n case 8:\n yy.setDiagramTitle($$[$0].substr(6));\n this.$ = $$[$0].substr(6);\n break;\n case 9:\n this.$ = $$[$0].trim();\n yy.setAccTitle(this.$);\n break;\n case 10:\n case 11:\n this.$ = $$[$0].trim();\n yy.setAccDescription(this.$);\n break;\n case 12:\n yy.addSection($$[$0].substr(8));\n this.$ = $$[$0].substr(8);\n break;\n case 13:\n yy.addTask($$[$0 - 1], $$[$0]);\n this.$ = \"task\";\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: $V6 }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 15, 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: $V6 }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 8]), { 13: [1, 16] }, { 15: [1, 17] }, o($V0, [2, 11]), o($V0, [2, 12]), { 19: [1, 18] }, o($V0, [2, 4]), o($V0, [2, 9]), o($V0, [2, 10]), o($V0, [2, 13])],\n defaultActions: {},\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n break;\n case 1:\n break;\n case 2:\n return 10;\n break;\n case 3:\n break;\n case 4:\n break;\n case 5:\n return 4;\n break;\n case 6:\n return 11;\n break;\n case 7:\n this.begin(\"acc_title\");\n return 12;\n break;\n case 8:\n this.popState();\n return \"acc_title_value\";\n break;\n case 9:\n this.begin(\"acc_descr\");\n return 14;\n break;\n case 10:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 11:\n this.begin(\"acc_descr_multiline\");\n break;\n case 12:\n this.popState();\n break;\n case 13:\n return \"acc_descr_multiline_value\";\n break;\n case 14:\n return 17;\n break;\n case 15:\n return 18;\n break;\n case 16:\n return 19;\n break;\n case 17:\n return \":\";\n break;\n case 18:\n return 6;\n break;\n case 19:\n return \"INVALID\";\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:%(?!\\{)[^\\n]*)/i, /^(?:[^\\}]%%[^\\n]*)/i, /^(?:[\\n]+)/i, /^(?:\\s+)/i, /^(?:#[^\\n]*)/i, /^(?:journey\\b)/i, /^(?:title\\s[^#\\n;]+)/i, /^(?:accTitle\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*\\{\\s*)/i, /^(?:[\\}])/i, /^(?:[^\\}]*)/i, /^(?:section\\s[^#:\\n;]+)/i, /^(?:[^#:\\n;]+)/i, /^(?::[^#\\n;]+)/i, /^(?::)/i, /^(?:$)/i, /^(?:.)/i],\n conditions: { \"acc_descr_multiline\": { \"rules\": [12, 13], \"inclusive\": false }, \"acc_descr\": { \"rules\": [10], \"inclusive\": false }, \"acc_title\": { \"rules\": [8], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18, 19], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar journey_default = parser;\n\n// src/diagrams/user-journey/journeyDb.js\nvar currentSection = \"\";\nvar sections = [];\nvar tasks = [];\nvar rawTasks = [];\nvar clear2 = /* @__PURE__ */ __name(function() {\n sections.length = 0;\n tasks.length = 0;\n currentSection = \"\";\n rawTasks.length = 0;\n clear();\n}, \"clear\");\nvar addSection = /* @__PURE__ */ __name(function(txt) {\n currentSection = txt;\n sections.push(txt);\n}, \"addSection\");\nvar getSections = /* @__PURE__ */ __name(function() {\n return sections;\n}, \"getSections\");\nvar getTasks = /* @__PURE__ */ __name(function() {\n let allItemsProcessed = compileTasks();\n const maxDepth = 100;\n let iterationCount = 0;\n while (!allItemsProcessed && iterationCount < maxDepth) {\n allItemsProcessed = compileTasks();\n iterationCount++;\n }\n tasks.push(...rawTasks);\n return tasks;\n}, \"getTasks\");\nvar updateActors = /* @__PURE__ */ __name(function() {\n const tempActors = [];\n tasks.forEach((task) => {\n if (task.people) {\n tempActors.push(...task.people);\n }\n });\n const unique = new Set(tempActors);\n return [...unique].sort();\n}, \"updateActors\");\nvar addTask = /* @__PURE__ */ __name(function(descr, taskData) {\n const pieces = taskData.substr(1).split(\":\");\n let score = 0;\n let peeps = [];\n if (pieces.length === 1) {\n score = Number(pieces[0]);\n peeps = [];\n } else {\n score = Number(pieces[0]);\n peeps = pieces[1].split(\",\");\n }\n const peopleList = peeps.map((s) => s.trim());\n const rawTask = {\n section: currentSection,\n type: currentSection,\n people: peopleList,\n task: descr,\n score\n };\n rawTasks.push(rawTask);\n}, \"addTask\");\nvar addTaskOrg = /* @__PURE__ */ __name(function(descr) {\n const newTask = {\n section: currentSection,\n type: currentSection,\n description: descr,\n task: descr,\n classes: []\n };\n tasks.push(newTask);\n}, \"addTaskOrg\");\nvar compileTasks = /* @__PURE__ */ __name(function() {\n const compileTask = /* @__PURE__ */ __name(function(pos) {\n return rawTasks[pos].processed;\n }, \"compileTask\");\n let allProcessed = true;\n for (const [i, rawTask] of rawTasks.entries()) {\n compileTask(i);\n allProcessed = allProcessed && rawTask.processed;\n }\n return allProcessed;\n}, \"compileTasks\");\nvar getActors = /* @__PURE__ */ __name(function() {\n return updateActors();\n}, \"getActors\");\nvar journeyDb_default = {\n getConfig: /* @__PURE__ */ __name(() => getConfig().journey, \"getConfig\"),\n clear: clear2,\n setDiagramTitle,\n getDiagramTitle,\n setAccTitle,\n getAccTitle,\n setAccDescription,\n getAccDescription,\n addSection,\n getSections,\n getTasks,\n addTask,\n addTaskOrg,\n getActors\n};\n\n// src/diagrams/user-journey/styles.js\nvar getStyles = /* @__PURE__ */ __name((options) => `.label {\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n color: ${options.textColor};\n }\n .mouth {\n stroke: #666;\n }\n\n line {\n stroke: ${options.textColor}\n }\n\n .legend {\n fill: ${options.textColor};\n }\n\n .label text {\n fill: #333;\n }\n .label {\n color: ${options.textColor}\n }\n\n .face {\n ${options.faceColor ? `fill: ${options.faceColor}` : \"fill: #FFF8DC\"};\n stroke: #999;\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${options.mainBkg};\n stroke: ${options.nodeBorder};\n stroke-width: 1px;\n }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${options.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${options.lineColor};\n stroke-width: 1.5px;\n }\n\n .flowchart-link {\n stroke: ${options.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${options.edgeLabelBackground};\n rect {\n opacity: 0.5;\n }\n text-align: center;\n }\n\n .cluster rect {\n }\n\n .cluster text {\n fill: ${options.titleColor};\n }\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: 'trebuchet ms', verdana, arial, sans-serif;\n font-family: var(--mermaid-font-family);\n font-size: 12px;\n background: ${options.tertiaryColor};\n border: 1px solid ${options.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .task-type-0, .section-type-0 {\n ${options.fillType0 ? `fill: ${options.fillType0}` : \"\"};\n }\n .task-type-1, .section-type-1 {\n ${options.fillType0 ? `fill: ${options.fillType1}` : \"\"};\n }\n .task-type-2, .section-type-2 {\n ${options.fillType0 ? `fill: ${options.fillType2}` : \"\"};\n }\n .task-type-3, .section-type-3 {\n ${options.fillType0 ? `fill: ${options.fillType3}` : \"\"};\n }\n .task-type-4, .section-type-4 {\n ${options.fillType0 ? `fill: ${options.fillType4}` : \"\"};\n }\n .task-type-5, .section-type-5 {\n ${options.fillType0 ? `fill: ${options.fillType5}` : \"\"};\n }\n .task-type-6, .section-type-6 {\n ${options.fillType0 ? `fill: ${options.fillType6}` : \"\"};\n }\n .task-type-7, .section-type-7 {\n ${options.fillType0 ? `fill: ${options.fillType7}` : \"\"};\n }\n\n .actor-0 {\n ${options.actor0 ? `fill: ${options.actor0}` : \"\"};\n }\n .actor-1 {\n ${options.actor1 ? `fill: ${options.actor1}` : \"\"};\n }\n .actor-2 {\n ${options.actor2 ? `fill: ${options.actor2}` : \"\"};\n }\n .actor-3 {\n ${options.actor3 ? `fill: ${options.actor3}` : \"\"};\n }\n .actor-4 {\n ${options.actor4 ? `fill: ${options.actor4}` : \"\"};\n }\n .actor-5 {\n ${options.actor5 ? `fill: ${options.actor5}` : \"\"};\n }\n`, \"getStyles\");\nvar styles_default = getStyles;\n\n// src/diagrams/user-journey/journeyRenderer.ts\nimport { select } from \"d3\";\n\n// src/diagrams/user-journey/svgDraw.js\nimport { arc as d3arc } from \"d3\";\nvar drawRect2 = /* @__PURE__ */ __name(function(elem, rectData) {\n return drawRect(elem, rectData);\n}, \"drawRect\");\nvar drawFace = /* @__PURE__ */ __name(function(element, faceData) {\n const radius = 15;\n const circleElement = element.append(\"circle\").attr(\"cx\", faceData.cx).attr(\"cy\", faceData.cy).attr(\"class\", \"face\").attr(\"r\", radius).attr(\"stroke-width\", 2).attr(\"overflow\", \"visible\");\n const face = element.append(\"g\");\n face.append(\"circle\").attr(\"cx\", faceData.cx - radius / 3).attr(\"cy\", faceData.cy - radius / 3).attr(\"r\", 1.5).attr(\"stroke-width\", 2).attr(\"fill\", \"#666\").attr(\"stroke\", \"#666\");\n face.append(\"circle\").attr(\"cx\", faceData.cx + radius / 3).attr(\"cy\", faceData.cy - radius / 3).attr(\"r\", 1.5).attr(\"stroke-width\", 2).attr(\"fill\", \"#666\").attr(\"stroke\", \"#666\");\n function smile(face2) {\n const arc = d3arc().startAngle(Math.PI / 2).endAngle(3 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2);\n face2.append(\"path\").attr(\"class\", \"mouth\").attr(\"d\", arc).attr(\"transform\", \"translate(\" + faceData.cx + \",\" + (faceData.cy + 2) + \")\");\n }\n __name(smile, \"smile\");\n function sad(face2) {\n const arc = d3arc().startAngle(3 * Math.PI / 2).endAngle(5 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2);\n face2.append(\"path\").attr(\"class\", \"mouth\").attr(\"d\", arc).attr(\"transform\", \"translate(\" + faceData.cx + \",\" + (faceData.cy + 7) + \")\");\n }\n __name(sad, \"sad\");\n function ambivalent(face2) {\n face2.append(\"line\").attr(\"class\", \"mouth\").attr(\"stroke\", 2).attr(\"x1\", faceData.cx - 5).attr(\"y1\", faceData.cy + 7).attr(\"x2\", faceData.cx + 5).attr(\"y2\", faceData.cy + 7).attr(\"class\", \"mouth\").attr(\"stroke-width\", \"1px\").attr(\"stroke\", \"#666\");\n }\n __name(ambivalent, \"ambivalent\");\n if (faceData.score > 3) {\n smile(face);\n } else if (faceData.score < 3) {\n sad(face);\n } else {\n ambivalent(face);\n }\n return circleElement;\n}, \"drawFace\");\nvar drawCircle = /* @__PURE__ */ __name(function(element, circleData) {\n const circleElement = element.append(\"circle\");\n circleElement.attr(\"cx\", circleData.cx);\n circleElement.attr(\"cy\", circleData.cy);\n circleElement.attr(\"class\", \"actor-\" + circleData.pos);\n circleElement.attr(\"fill\", circleData.fill);\n circleElement.attr(\"stroke\", circleData.stroke);\n circleElement.attr(\"r\", circleData.r);\n if (circleElement.class !== void 0) {\n circleElement.attr(\"class\", circleElement.class);\n }\n if (circleData.title !== void 0) {\n circleElement.append(\"title\").text(circleData.title);\n }\n return circleElement;\n}, \"drawCircle\");\nvar drawText2 = /* @__PURE__ */ __name(function(elem, textData) {\n return drawText(elem, textData);\n}, \"drawText\");\nvar drawLabel = /* @__PURE__ */ __name(function(elem, txtObject) {\n function genPoints(x, y, width, height, cut) {\n return x + \",\" + y + \" \" + (x + width) + \",\" + y + \" \" + (x + width) + \",\" + (y + height - cut) + \" \" + (x + width - cut * 1.2) + \",\" + (y + height) + \" \" + x + \",\" + (y + height);\n }\n __name(genPoints, \"genPoints\");\n const polygon = elem.append(\"polygon\");\n polygon.attr(\"points\", genPoints(txtObject.x, txtObject.y, 50, 20, 7));\n polygon.attr(\"class\", \"labelBox\");\n txtObject.y = txtObject.y + txtObject.labelMargin;\n txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin;\n drawText2(elem, txtObject);\n}, \"drawLabel\");\nvar drawSection = /* @__PURE__ */ __name(function(elem, section, conf2) {\n const g = elem.append(\"g\");\n const rect = getNoteRect();\n rect.x = section.x;\n rect.y = section.y;\n rect.fill = section.fill;\n rect.width = conf2.width * section.taskCount + // width of the tasks\n conf2.diagramMarginX * (section.taskCount - 1);\n rect.height = conf2.height;\n rect.class = \"journey-section section-type-\" + section.num;\n rect.rx = 3;\n rect.ry = 3;\n drawRect2(g, rect);\n _drawTextCandidateFunc(conf2)(\n section.text,\n g,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n { class: \"journey-section section-type-\" + section.num },\n conf2,\n section.colour\n );\n}, \"drawSection\");\nvar taskCount = -1;\nvar drawTask = /* @__PURE__ */ __name(function(elem, task, conf2) {\n const center = task.x + conf2.width / 2;\n const g = elem.append(\"g\");\n taskCount++;\n const maxHeight = 300 + 5 * 30;\n g.append(\"line\").attr(\"id\", \"task\" + taskCount).attr(\"x1\", center).attr(\"y1\", task.y).attr(\"x2\", center).attr(\"y2\", maxHeight).attr(\"class\", \"task-line\").attr(\"stroke-width\", \"1px\").attr(\"stroke-dasharray\", \"4 2\").attr(\"stroke\", \"#666\");\n drawFace(g, {\n cx: center,\n cy: 300 + (5 - task.score) * 30,\n score: task.score\n });\n const rect = getNoteRect();\n rect.x = task.x;\n rect.y = task.y;\n rect.fill = task.fill;\n rect.width = conf2.width;\n rect.height = conf2.height;\n rect.class = \"task task-type-\" + task.num;\n rect.rx = 3;\n rect.ry = 3;\n drawRect2(g, rect);\n let xPos = task.x + 14;\n task.people.forEach((person) => {\n const colour = task.actors[person].color;\n const circle = {\n cx: xPos,\n cy: task.y,\n r: 7,\n fill: colour,\n stroke: \"#000\",\n title: person,\n pos: task.actors[person].position\n };\n drawCircle(g, circle);\n xPos += 10;\n });\n _drawTextCandidateFunc(conf2)(\n task.task,\n g,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n { class: \"task\" },\n conf2,\n task.colour\n );\n}, \"drawTask\");\nvar drawBackgroundRect2 = /* @__PURE__ */ __name(function(elem, bounds2) {\n drawBackgroundRect(elem, bounds2);\n}, \"drawBackgroundRect\");\nvar _drawTextCandidateFunc = /* @__PURE__ */ function() {\n function byText(content, g, x, y, width, height, textAttrs, colour) {\n const text = g.append(\"text\").attr(\"x\", x + width / 2).attr(\"y\", y + height / 2 + 5).style(\"font-color\", colour).style(\"text-anchor\", \"middle\").text(content);\n _setTextAttrs(text, textAttrs);\n }\n __name(byText, \"byText\");\n function byTspan(content, g, x, y, width, height, textAttrs, conf2, colour) {\n const { taskFontSize, taskFontFamily } = conf2;\n const lines = content.split(//gi);\n for (let i = 0; i < lines.length; i++) {\n const dy = i * taskFontSize - taskFontSize * (lines.length - 1) / 2;\n const text = g.append(\"text\").attr(\"x\", x + width / 2).attr(\"y\", y).attr(\"fill\", colour).style(\"text-anchor\", \"middle\").style(\"font-size\", taskFontSize).style(\"font-family\", taskFontFamily);\n text.append(\"tspan\").attr(\"x\", x + width / 2).attr(\"dy\", dy).text(lines[i]);\n text.attr(\"y\", y + height / 2).attr(\"dominant-baseline\", \"central\").attr(\"alignment-baseline\", \"central\");\n _setTextAttrs(text, textAttrs);\n }\n }\n __name(byTspan, \"byTspan\");\n function byFo(content, g, x, y, width, height, textAttrs, conf2) {\n const body = g.append(\"switch\");\n const f = body.append(\"foreignObject\").attr(\"x\", x).attr(\"y\", y).attr(\"width\", width).attr(\"height\", height).attr(\"position\", \"fixed\");\n const text = f.append(\"xhtml:div\").style(\"display\", \"table\").style(\"height\", \"100%\").style(\"width\", \"100%\");\n text.append(\"div\").attr(\"class\", \"label\").style(\"display\", \"table-cell\").style(\"text-align\", \"center\").style(\"vertical-align\", \"middle\").text(content);\n byTspan(content, body, x, y, width, height, textAttrs, conf2);\n _setTextAttrs(text, textAttrs);\n }\n __name(byFo, \"byFo\");\n function _setTextAttrs(toText, fromTextAttrsDict) {\n for (const key in fromTextAttrsDict) {\n if (key in fromTextAttrsDict) {\n toText.attr(key, fromTextAttrsDict[key]);\n }\n }\n }\n __name(_setTextAttrs, \"_setTextAttrs\");\n return function(conf2) {\n return conf2.textPlacement === \"fo\" ? byFo : conf2.textPlacement === \"old\" ? byText : byTspan;\n };\n}();\nvar initGraphics = /* @__PURE__ */ __name(function(graphics) {\n graphics.append(\"defs\").append(\"marker\").attr(\"id\", \"arrowhead\").attr(\"refX\", 5).attr(\"refY\", 2).attr(\"markerWidth\", 6).attr(\"markerHeight\", 4).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 0,0 V 4 L6,2 Z\");\n}, \"initGraphics\");\nvar svgDraw_default = {\n drawRect: drawRect2,\n drawCircle,\n drawSection,\n drawText: drawText2,\n drawLabel,\n drawTask,\n drawBackgroundRect: drawBackgroundRect2,\n initGraphics\n};\n\n// src/diagrams/user-journey/journeyRenderer.ts\nvar setConf = /* @__PURE__ */ __name(function(cnf) {\n const keys = Object.keys(cnf);\n keys.forEach(function(key) {\n conf[key] = cnf[key];\n });\n}, \"setConf\");\nvar actors = {};\nfunction drawActorLegend(diagram2) {\n const conf2 = getConfig().journey;\n let yPos = 60;\n Object.keys(actors).forEach((person) => {\n const colour = actors[person].color;\n const circleData = {\n cx: 20,\n cy: yPos,\n r: 7,\n fill: colour,\n stroke: \"#000\",\n pos: actors[person].position\n };\n svgDraw_default.drawCircle(diagram2, circleData);\n const labelData = {\n x: 40,\n y: yPos + 7,\n fill: \"#666\",\n text: person,\n textMargin: conf2.boxTextMargin | 5\n };\n svgDraw_default.drawText(diagram2, labelData);\n yPos += 20;\n });\n}\n__name(drawActorLegend, \"drawActorLegend\");\nvar conf = getConfig().journey;\nvar LEFT_MARGIN = conf.leftMargin;\nvar draw = /* @__PURE__ */ __name(function(text, id, version, diagObj) {\n const conf2 = getConfig().journey;\n const securityLevel = getConfig().securityLevel;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select(sandboxElement.nodes()[0].contentDocument.body) : select(\"body\");\n bounds.init();\n const diagram2 = root.select(\"#\" + id);\n svgDraw_default.initGraphics(diagram2);\n const tasks2 = diagObj.db.getTasks();\n const title = diagObj.db.getDiagramTitle();\n const actorNames = diagObj.db.getActors();\n for (const member in actors) {\n delete actors[member];\n }\n let actorPos = 0;\n actorNames.forEach((actorName) => {\n actors[actorName] = {\n color: conf2.actorColours[actorPos % conf2.actorColours.length],\n position: actorPos\n };\n actorPos++;\n });\n drawActorLegend(diagram2);\n bounds.insert(0, 0, LEFT_MARGIN, Object.keys(actors).length * 50);\n drawTasks(diagram2, tasks2, 0);\n const box = bounds.getBounds();\n if (title) {\n diagram2.append(\"text\").text(title).attr(\"x\", LEFT_MARGIN).attr(\"font-size\", \"4ex\").attr(\"font-weight\", \"bold\").attr(\"y\", 25);\n }\n const height = box.stopy - box.starty + 2 * conf2.diagramMarginY;\n const width = LEFT_MARGIN + box.stopx + 2 * conf2.diagramMarginX;\n configureSvgSize(diagram2, height, width, conf2.useMaxWidth);\n diagram2.append(\"line\").attr(\"x1\", LEFT_MARGIN).attr(\"y1\", conf2.height * 4).attr(\"x2\", width - LEFT_MARGIN - 4).attr(\"y2\", conf2.height * 4).attr(\"stroke-width\", 4).attr(\"stroke\", \"black\").attr(\"marker-end\", \"url(#arrowhead)\");\n const extraVertForTitle = title ? 70 : 0;\n diagram2.attr(\"viewBox\", `${box.startx} -25 ${width} ${height + extraVertForTitle}`);\n diagram2.attr(\"preserveAspectRatio\", \"xMinYMin meet\");\n diagram2.attr(\"height\", height + extraVertForTitle + 25);\n}, \"draw\");\nvar bounds = {\n data: {\n startx: void 0,\n stopx: void 0,\n starty: void 0,\n stopy: void 0\n },\n verticalPos: 0,\n sequenceItems: [],\n init: /* @__PURE__ */ __name(function() {\n this.sequenceItems = [];\n this.data = {\n startx: void 0,\n stopx: void 0,\n starty: void 0,\n stopy: void 0\n };\n this.verticalPos = 0;\n }, \"init\"),\n updateVal: /* @__PURE__ */ __name(function(obj, key, val, fun) {\n if (obj[key] === void 0) {\n obj[key] = val;\n } else {\n obj[key] = fun(val, obj[key]);\n }\n }, \"updateVal\"),\n updateBounds: /* @__PURE__ */ __name(function(startx, starty, stopx, stopy) {\n const conf2 = getConfig().journey;\n const _self = this;\n let cnt = 0;\n function updateFn(type) {\n return /* @__PURE__ */ __name(function updateItemBounds(item) {\n cnt++;\n const n = _self.sequenceItems.length - cnt + 1;\n _self.updateVal(item, \"starty\", starty - n * conf2.boxMargin, Math.min);\n _self.updateVal(item, \"stopy\", stopy + n * conf2.boxMargin, Math.max);\n _self.updateVal(bounds.data, \"startx\", startx - n * conf2.boxMargin, Math.min);\n _self.updateVal(bounds.data, \"stopx\", stopx + n * conf2.boxMargin, Math.max);\n if (!(type === \"activation\")) {\n _self.updateVal(item, \"startx\", startx - n * conf2.boxMargin, Math.min);\n _self.updateVal(item, \"stopx\", stopx + n * conf2.boxMargin, Math.max);\n _self.updateVal(bounds.data, \"starty\", starty - n * conf2.boxMargin, Math.min);\n _self.updateVal(bounds.data, \"stopy\", stopy + n * conf2.boxMargin, Math.max);\n }\n }, \"updateItemBounds\");\n }\n __name(updateFn, \"updateFn\");\n this.sequenceItems.forEach(updateFn());\n }, \"updateBounds\"),\n insert: /* @__PURE__ */ __name(function(startx, starty, stopx, stopy) {\n const _startx = Math.min(startx, stopx);\n const _stopx = Math.max(startx, stopx);\n const _starty = Math.min(starty, stopy);\n const _stopy = Math.max(starty, stopy);\n this.updateVal(bounds.data, \"startx\", _startx, Math.min);\n this.updateVal(bounds.data, \"starty\", _starty, Math.min);\n this.updateVal(bounds.data, \"stopx\", _stopx, Math.max);\n this.updateVal(bounds.data, \"stopy\", _stopy, Math.max);\n this.updateBounds(_startx, _starty, _stopx, _stopy);\n }, \"insert\"),\n bumpVerticalPos: /* @__PURE__ */ __name(function(bump) {\n this.verticalPos = this.verticalPos + bump;\n this.data.stopy = this.verticalPos;\n }, \"bumpVerticalPos\"),\n getVerticalPos: /* @__PURE__ */ __name(function() {\n return this.verticalPos;\n }, \"getVerticalPos\"),\n getBounds: /* @__PURE__ */ __name(function() {\n return this.data;\n }, \"getBounds\")\n};\nvar fills = conf.sectionFills;\nvar textColours = conf.sectionColours;\nvar drawTasks = /* @__PURE__ */ __name(function(diagram2, tasks2, verticalPos) {\n const conf2 = getConfig().journey;\n let lastSection = \"\";\n const sectionVHeight = conf2.height * 2 + conf2.diagramMarginY;\n const taskPos = verticalPos + sectionVHeight;\n let sectionNumber = 0;\n let fill = \"#CCC\";\n let colour = \"black\";\n let num = 0;\n for (const [i, task] of tasks2.entries()) {\n if (lastSection !== task.section) {\n fill = fills[sectionNumber % fills.length];\n num = sectionNumber % fills.length;\n colour = textColours[sectionNumber % textColours.length];\n let taskInSectionCount = 0;\n const currentSection2 = task.section;\n for (let taskIndex = i; taskIndex < tasks2.length; taskIndex++) {\n if (tasks2[taskIndex].section == currentSection2) {\n taskInSectionCount = taskInSectionCount + 1;\n } else {\n break;\n }\n }\n const section = {\n x: i * conf2.taskMargin + i * conf2.width + LEFT_MARGIN,\n y: 50,\n text: task.section,\n fill,\n num,\n colour,\n taskCount: taskInSectionCount\n };\n svgDraw_default.drawSection(diagram2, section, conf2);\n lastSection = task.section;\n sectionNumber++;\n }\n const taskActors = task.people.reduce((acc, actorName) => {\n if (actors[actorName]) {\n acc[actorName] = actors[actorName];\n }\n return acc;\n }, {});\n task.x = i * conf2.taskMargin + i * conf2.width + LEFT_MARGIN;\n task.y = taskPos;\n task.width = conf2.diagramMarginX;\n task.height = conf2.diagramMarginY;\n task.colour = colour;\n task.fill = fill;\n task.num = num;\n task.actors = taskActors;\n svgDraw_default.drawTask(diagram2, task, conf2);\n bounds.insert(task.x, task.y, task.x + task.width + conf2.taskMargin, 300 + 5 * 30);\n }\n}, \"drawTasks\");\nvar journeyRenderer_default = {\n setConf,\n draw\n};\n\n// src/diagrams/user-journey/journeyDiagram.ts\nvar diagram = {\n parser: journey_default,\n db: journeyDb_default,\n renderer: journeyRenderer_default,\n styles: styles_default,\n init: /* @__PURE__ */ __name((cnf) => {\n journeyRenderer_default.setConf(cnf.journey);\n journeyDb_default.clear();\n }, \"init\")\n};\nexport {\n diagram\n};\n", "import {\n __export,\n __name,\n clear,\n commonDb_exports,\n getConfig2 as getConfig,\n log,\n setupGraphViewbox\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/timeline/parser/timeline.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [6, 8, 10, 11, 12, 14, 16, 17, 20, 21], $V1 = [1, 9], $V2 = [1, 10], $V3 = [1, 11], $V4 = [1, 12], $V5 = [1, 13], $V6 = [1, 16], $V7 = [1, 17];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"timeline\": 4, \"document\": 5, \"EOF\": 6, \"line\": 7, \"SPACE\": 8, \"statement\": 9, \"NEWLINE\": 10, \"title\": 11, \"acc_title\": 12, \"acc_title_value\": 13, \"acc_descr\": 14, \"acc_descr_value\": 15, \"acc_descr_multiline_value\": 16, \"section\": 17, \"period_statement\": 18, \"event_statement\": 19, \"period\": 20, \"event\": 21, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 4: \"timeline\", 6: \"EOF\", 8: \"SPACE\", 10: \"NEWLINE\", 11: \"title\", 12: \"acc_title\", 13: \"acc_title_value\", 14: \"acc_descr\", 15: \"acc_descr_value\", 16: \"acc_descr_multiline_value\", 17: \"section\", 20: \"period\", 21: \"event\" },\n productions_: [0, [3, 3], [5, 0], [5, 2], [7, 2], [7, 1], [7, 1], [7, 1], [9, 1], [9, 2], [9, 2], [9, 1], [9, 1], [9, 1], [9, 1], [18, 1], [19, 1]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 1:\n return $$[$0 - 1];\n break;\n case 2:\n this.$ = [];\n break;\n case 3:\n $$[$0 - 1].push($$[$0]);\n this.$ = $$[$0 - 1];\n break;\n case 4:\n case 5:\n this.$ = $$[$0];\n break;\n case 6:\n case 7:\n this.$ = [];\n break;\n case 8:\n yy.getCommonDb().setDiagramTitle($$[$0].substr(6));\n this.$ = $$[$0].substr(6);\n break;\n case 9:\n this.$ = $$[$0].trim();\n yy.getCommonDb().setAccTitle(this.$);\n break;\n case 10:\n case 11:\n this.$ = $$[$0].trim();\n yy.getCommonDb().setAccDescription(this.$);\n break;\n case 12:\n yy.addSection($$[$0].substr(8));\n this.$ = $$[$0].substr(8);\n break;\n case 15:\n yy.addTask($$[$0], 0, \"\");\n this.$ = $$[$0];\n break;\n case 16:\n yy.addEvent($$[$0].substr(2));\n this.$ = $$[$0];\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, o($V0, [2, 2], { 5: 3 }), { 6: [1, 4], 7: 5, 8: [1, 6], 9: 7, 10: [1, 8], 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: 14, 19: 15, 20: $V6, 21: $V7 }, o($V0, [2, 7], { 1: [2, 1] }), o($V0, [2, 3]), { 9: 18, 11: $V1, 12: $V2, 14: $V3, 16: $V4, 17: $V5, 18: 14, 19: 15, 20: $V6, 21: $V7 }, o($V0, [2, 5]), o($V0, [2, 6]), o($V0, [2, 8]), { 13: [1, 19] }, { 15: [1, 20] }, o($V0, [2, 11]), o($V0, [2, 12]), o($V0, [2, 13]), o($V0, [2, 14]), o($V0, [2, 15]), o($V0, [2, 16]), o($V0, [2, 4]), o($V0, [2, 9]), o($V0, [2, 10])],\n defaultActions: {},\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n break;\n case 1:\n break;\n case 2:\n return 10;\n break;\n case 3:\n break;\n case 4:\n break;\n case 5:\n return 4;\n break;\n case 6:\n return 11;\n break;\n case 7:\n this.begin(\"acc_title\");\n return 12;\n break;\n case 8:\n this.popState();\n return \"acc_title_value\";\n break;\n case 9:\n this.begin(\"acc_descr\");\n return 14;\n break;\n case 10:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 11:\n this.begin(\"acc_descr_multiline\");\n break;\n case 12:\n this.popState();\n break;\n case 13:\n return \"acc_descr_multiline_value\";\n break;\n case 14:\n return 17;\n break;\n case 15:\n return 21;\n break;\n case 16:\n return 20;\n break;\n case 17:\n return 6;\n break;\n case 18:\n return \"INVALID\";\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:%(?!\\{)[^\\n]*)/i, /^(?:[^\\}]%%[^\\n]*)/i, /^(?:[\\n]+)/i, /^(?:\\s+)/i, /^(?:#[^\\n]*)/i, /^(?:timeline\\b)/i, /^(?:title\\s[^\\n]+)/i, /^(?:accTitle\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*:\\s*)/i, /^(?:(?!\\n||)*[^\\n]*)/i, /^(?:accDescr\\s*\\{\\s*)/i, /^(?:[\\}])/i, /^(?:[^\\}]*)/i, /^(?:section\\s[^:\\n]+)/i, /^(?::\\s[^:\\n]+)/i, /^(?:[^#:\\n]+)/i, /^(?:$)/i, /^(?:.)/i],\n conditions: { \"acc_descr_multiline\": { \"rules\": [12, 13], \"inclusive\": false }, \"acc_descr\": { \"rules\": [10], \"inclusive\": false }, \"acc_title\": { \"rules\": [8], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 2, 3, 4, 5, 6, 7, 9, 11, 14, 15, 16, 17, 18], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar timeline_default = parser;\n\n// src/diagrams/timeline/timelineDb.js\nvar timelineDb_exports = {};\n__export(timelineDb_exports, {\n addEvent: () => addEvent,\n addSection: () => addSection,\n addTask: () => addTask,\n addTaskOrg: () => addTaskOrg,\n clear: () => clear2,\n default: () => timelineDb_default,\n getCommonDb: () => getCommonDb,\n getSections: () => getSections,\n getTasks: () => getTasks\n});\nvar currentSection = \"\";\nvar currentTaskId = 0;\nvar sections = [];\nvar tasks = [];\nvar rawTasks = [];\nvar getCommonDb = /* @__PURE__ */ __name(() => commonDb_exports, \"getCommonDb\");\nvar clear2 = /* @__PURE__ */ __name(function() {\n sections.length = 0;\n tasks.length = 0;\n currentSection = \"\";\n rawTasks.length = 0;\n clear();\n}, \"clear\");\nvar addSection = /* @__PURE__ */ __name(function(txt) {\n currentSection = txt;\n sections.push(txt);\n}, \"addSection\");\nvar getSections = /* @__PURE__ */ __name(function() {\n return sections;\n}, \"getSections\");\nvar getTasks = /* @__PURE__ */ __name(function() {\n let allItemsProcessed = compileTasks();\n const maxDepth = 100;\n let iterationCount = 0;\n while (!allItemsProcessed && iterationCount < maxDepth) {\n allItemsProcessed = compileTasks();\n iterationCount++;\n }\n tasks.push(...rawTasks);\n return tasks;\n}, \"getTasks\");\nvar addTask = /* @__PURE__ */ __name(function(period, length, event) {\n const rawTask = {\n id: currentTaskId++,\n section: currentSection,\n type: currentSection,\n task: period,\n score: length ? length : 0,\n //if event is defined, then add it the events array\n events: event ? [event] : []\n };\n rawTasks.push(rawTask);\n}, \"addTask\");\nvar addEvent = /* @__PURE__ */ __name(function(event) {\n const currentTask = rawTasks.find((task) => task.id === currentTaskId - 1);\n currentTask.events.push(event);\n}, \"addEvent\");\nvar addTaskOrg = /* @__PURE__ */ __name(function(descr) {\n const newTask = {\n section: currentSection,\n type: currentSection,\n description: descr,\n task: descr,\n classes: []\n };\n tasks.push(newTask);\n}, \"addTaskOrg\");\nvar compileTasks = /* @__PURE__ */ __name(function() {\n const compileTask = /* @__PURE__ */ __name(function(pos) {\n return rawTasks[pos].processed;\n }, \"compileTask\");\n let allProcessed = true;\n for (const [i, rawTask] of rawTasks.entries()) {\n compileTask(i);\n allProcessed = allProcessed && rawTask.processed;\n }\n return allProcessed;\n}, \"compileTasks\");\nvar timelineDb_default = {\n clear: clear2,\n getCommonDb,\n addSection,\n getSections,\n getTasks,\n addTask,\n addTaskOrg,\n addEvent\n};\n\n// src/diagrams/timeline/timelineRenderer.ts\nimport { select as select2 } from \"d3\";\n\n// src/diagrams/timeline/svgDraw.js\nimport { arc as d3arc, select } from \"d3\";\nvar MAX_SECTIONS = 12;\nvar drawRect = /* @__PURE__ */ __name(function(elem, rectData) {\n const rectElem = elem.append(\"rect\");\n rectElem.attr(\"x\", rectData.x);\n rectElem.attr(\"y\", rectData.y);\n rectElem.attr(\"fill\", rectData.fill);\n rectElem.attr(\"stroke\", rectData.stroke);\n rectElem.attr(\"width\", rectData.width);\n rectElem.attr(\"height\", rectData.height);\n rectElem.attr(\"rx\", rectData.rx);\n rectElem.attr(\"ry\", rectData.ry);\n if (rectData.class !== void 0) {\n rectElem.attr(\"class\", rectData.class);\n }\n return rectElem;\n}, \"drawRect\");\nvar drawFace = /* @__PURE__ */ __name(function(element, faceData) {\n const radius = 15;\n const circleElement = element.append(\"circle\").attr(\"cx\", faceData.cx).attr(\"cy\", faceData.cy).attr(\"class\", \"face\").attr(\"r\", radius).attr(\"stroke-width\", 2).attr(\"overflow\", \"visible\");\n const face = element.append(\"g\");\n face.append(\"circle\").attr(\"cx\", faceData.cx - radius / 3).attr(\"cy\", faceData.cy - radius / 3).attr(\"r\", 1.5).attr(\"stroke-width\", 2).attr(\"fill\", \"#666\").attr(\"stroke\", \"#666\");\n face.append(\"circle\").attr(\"cx\", faceData.cx + radius / 3).attr(\"cy\", faceData.cy - radius / 3).attr(\"r\", 1.5).attr(\"stroke-width\", 2).attr(\"fill\", \"#666\").attr(\"stroke\", \"#666\");\n function smile(face2) {\n const arc = d3arc().startAngle(Math.PI / 2).endAngle(3 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2);\n face2.append(\"path\").attr(\"class\", \"mouth\").attr(\"d\", arc).attr(\"transform\", \"translate(\" + faceData.cx + \",\" + (faceData.cy + 2) + \")\");\n }\n __name(smile, \"smile\");\n function sad(face2) {\n const arc = d3arc().startAngle(3 * Math.PI / 2).endAngle(5 * (Math.PI / 2)).innerRadius(radius / 2).outerRadius(radius / 2.2);\n face2.append(\"path\").attr(\"class\", \"mouth\").attr(\"d\", arc).attr(\"transform\", \"translate(\" + faceData.cx + \",\" + (faceData.cy + 7) + \")\");\n }\n __name(sad, \"sad\");\n function ambivalent(face2) {\n face2.append(\"line\").attr(\"class\", \"mouth\").attr(\"stroke\", 2).attr(\"x1\", faceData.cx - 5).attr(\"y1\", faceData.cy + 7).attr(\"x2\", faceData.cx + 5).attr(\"y2\", faceData.cy + 7).attr(\"class\", \"mouth\").attr(\"stroke-width\", \"1px\").attr(\"stroke\", \"#666\");\n }\n __name(ambivalent, \"ambivalent\");\n if (faceData.score > 3) {\n smile(face);\n } else if (faceData.score < 3) {\n sad(face);\n } else {\n ambivalent(face);\n }\n return circleElement;\n}, \"drawFace\");\nvar drawCircle = /* @__PURE__ */ __name(function(element, circleData) {\n const circleElement = element.append(\"circle\");\n circleElement.attr(\"cx\", circleData.cx);\n circleElement.attr(\"cy\", circleData.cy);\n circleElement.attr(\"class\", \"actor-\" + circleData.pos);\n circleElement.attr(\"fill\", circleData.fill);\n circleElement.attr(\"stroke\", circleData.stroke);\n circleElement.attr(\"r\", circleData.r);\n if (circleElement.class !== void 0) {\n circleElement.attr(\"class\", circleElement.class);\n }\n if (circleData.title !== void 0) {\n circleElement.append(\"title\").text(circleData.title);\n }\n return circleElement;\n}, \"drawCircle\");\nvar drawText = /* @__PURE__ */ __name(function(elem, textData) {\n const nText = textData.text.replace(//gi, \" \");\n const textElem = elem.append(\"text\");\n textElem.attr(\"x\", textData.x);\n textElem.attr(\"y\", textData.y);\n textElem.attr(\"class\", \"legend\");\n textElem.style(\"text-anchor\", textData.anchor);\n if (textData.class !== void 0) {\n textElem.attr(\"class\", textData.class);\n }\n const span = textElem.append(\"tspan\");\n span.attr(\"x\", textData.x + textData.textMargin * 2);\n span.text(nText);\n return textElem;\n}, \"drawText\");\nvar drawLabel = /* @__PURE__ */ __name(function(elem, txtObject) {\n function genPoints(x, y, width, height, cut) {\n return x + \",\" + y + \" \" + (x + width) + \",\" + y + \" \" + (x + width) + \",\" + (y + height - cut) + \" \" + (x + width - cut * 1.2) + \",\" + (y + height) + \" \" + x + \",\" + (y + height);\n }\n __name(genPoints, \"genPoints\");\n const polygon = elem.append(\"polygon\");\n polygon.attr(\"points\", genPoints(txtObject.x, txtObject.y, 50, 20, 7));\n polygon.attr(\"class\", \"labelBox\");\n txtObject.y = txtObject.y + txtObject.labelMargin;\n txtObject.x = txtObject.x + 0.5 * txtObject.labelMargin;\n drawText(elem, txtObject);\n}, \"drawLabel\");\nvar drawSection = /* @__PURE__ */ __name(function(elem, section, conf) {\n const g = elem.append(\"g\");\n const rect = getNoteRect();\n rect.x = section.x;\n rect.y = section.y;\n rect.fill = section.fill;\n rect.width = conf.width;\n rect.height = conf.height;\n rect.class = \"journey-section section-type-\" + section.num;\n rect.rx = 3;\n rect.ry = 3;\n drawRect(g, rect);\n _drawTextCandidateFunc(conf)(\n section.text,\n g,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n { class: \"journey-section section-type-\" + section.num },\n conf,\n section.colour\n );\n}, \"drawSection\");\nvar taskCount = -1;\nvar drawTask = /* @__PURE__ */ __name(function(elem, task, conf) {\n const center = task.x + conf.width / 2;\n const g = elem.append(\"g\");\n taskCount++;\n const maxHeight = 300 + 5 * 30;\n g.append(\"line\").attr(\"id\", \"task\" + taskCount).attr(\"x1\", center).attr(\"y1\", task.y).attr(\"x2\", center).attr(\"y2\", maxHeight).attr(\"class\", \"task-line\").attr(\"stroke-width\", \"1px\").attr(\"stroke-dasharray\", \"4 2\").attr(\"stroke\", \"#666\");\n drawFace(g, {\n cx: center,\n cy: 300 + (5 - task.score) * 30,\n score: task.score\n });\n const rect = getNoteRect();\n rect.x = task.x;\n rect.y = task.y;\n rect.fill = task.fill;\n rect.width = conf.width;\n rect.height = conf.height;\n rect.class = \"task task-type-\" + task.num;\n rect.rx = 3;\n rect.ry = 3;\n drawRect(g, rect);\n _drawTextCandidateFunc(conf)(\n task.task,\n g,\n rect.x,\n rect.y,\n rect.width,\n rect.height,\n { class: \"task\" },\n conf,\n task.colour\n );\n}, \"drawTask\");\nvar drawBackgroundRect = /* @__PURE__ */ __name(function(elem, bounds) {\n const rectElem = drawRect(elem, {\n x: bounds.startx,\n y: bounds.starty,\n width: bounds.stopx - bounds.startx,\n height: bounds.stopy - bounds.starty,\n fill: bounds.fill,\n class: \"rect\"\n });\n rectElem.lower();\n}, \"drawBackgroundRect\");\nvar getTextObj = /* @__PURE__ */ __name(function() {\n return {\n x: 0,\n y: 0,\n fill: void 0,\n \"text-anchor\": \"start\",\n width: 100,\n height: 100,\n textMargin: 0,\n rx: 0,\n ry: 0\n };\n}, \"getTextObj\");\nvar getNoteRect = /* @__PURE__ */ __name(function() {\n return {\n x: 0,\n y: 0,\n width: 100,\n anchor: \"start\",\n height: 100,\n rx: 0,\n ry: 0\n };\n}, \"getNoteRect\");\nvar _drawTextCandidateFunc = /* @__PURE__ */ function() {\n function byText(content, g, x, y, width, height, textAttrs, colour) {\n const text = g.append(\"text\").attr(\"x\", x + width / 2).attr(\"y\", y + height / 2 + 5).style(\"font-color\", colour).style(\"text-anchor\", \"middle\").text(content);\n _setTextAttrs(text, textAttrs);\n }\n __name(byText, \"byText\");\n function byTspan(content, g, x, y, width, height, textAttrs, conf, colour) {\n const { taskFontSize, taskFontFamily } = conf;\n const lines = content.split(//gi);\n for (let i = 0; i < lines.length; i++) {\n const dy = i * taskFontSize - taskFontSize * (lines.length - 1) / 2;\n const text = g.append(\"text\").attr(\"x\", x + width / 2).attr(\"y\", y).attr(\"fill\", colour).style(\"text-anchor\", \"middle\").style(\"font-size\", taskFontSize).style(\"font-family\", taskFontFamily);\n text.append(\"tspan\").attr(\"x\", x + width / 2).attr(\"dy\", dy).text(lines[i]);\n text.attr(\"y\", y + height / 2).attr(\"dominant-baseline\", \"central\").attr(\"alignment-baseline\", \"central\");\n _setTextAttrs(text, textAttrs);\n }\n }\n __name(byTspan, \"byTspan\");\n function byFo(content, g, x, y, width, height, textAttrs, conf) {\n const body = g.append(\"switch\");\n const f = body.append(\"foreignObject\").attr(\"x\", x).attr(\"y\", y).attr(\"width\", width).attr(\"height\", height).attr(\"position\", \"fixed\");\n const text = f.append(\"xhtml:div\").style(\"display\", \"table\").style(\"height\", \"100%\").style(\"width\", \"100%\");\n text.append(\"div\").attr(\"class\", \"label\").style(\"display\", \"table-cell\").style(\"text-align\", \"center\").style(\"vertical-align\", \"middle\").text(content);\n byTspan(content, body, x, y, width, height, textAttrs, conf);\n _setTextAttrs(text, textAttrs);\n }\n __name(byFo, \"byFo\");\n function _setTextAttrs(toText, fromTextAttrsDict) {\n for (const key in fromTextAttrsDict) {\n if (key in fromTextAttrsDict) {\n toText.attr(key, fromTextAttrsDict[key]);\n }\n }\n }\n __name(_setTextAttrs, \"_setTextAttrs\");\n return function(conf) {\n return conf.textPlacement === \"fo\" ? byFo : conf.textPlacement === \"old\" ? byText : byTspan;\n };\n}();\nvar initGraphics = /* @__PURE__ */ __name(function(graphics) {\n graphics.append(\"defs\").append(\"marker\").attr(\"id\", \"arrowhead\").attr(\"refX\", 5).attr(\"refY\", 2).attr(\"markerWidth\", 6).attr(\"markerHeight\", 4).attr(\"orient\", \"auto\").append(\"path\").attr(\"d\", \"M 0,0 V 4 L6,2 Z\");\n}, \"initGraphics\");\nfunction wrap(text, width) {\n text.each(function() {\n var text2 = select(this), words = text2.text().split(/(\\s+|
)/).reverse(), word, line = [], lineHeight = 1.1, y = text2.attr(\"y\"), dy = parseFloat(text2.attr(\"dy\")), tspan = text2.text(null).append(\"tspan\").attr(\"x\", 0).attr(\"y\", y).attr(\"dy\", dy + \"em\");\n for (let j = 0; j < words.length; j++) {\n word = words[words.length - 1 - j];\n line.push(word);\n tspan.text(line.join(\" \").trim());\n if (tspan.node().getComputedTextLength() > width || word === \"
\") {\n line.pop();\n tspan.text(line.join(\" \").trim());\n if (word === \"
\") {\n line = [\"\"];\n } else {\n line = [word];\n }\n tspan = text2.append(\"tspan\").attr(\"x\", 0).attr(\"y\", y).attr(\"dy\", lineHeight + \"em\").text(word);\n }\n }\n });\n}\n__name(wrap, \"wrap\");\nvar drawNode = /* @__PURE__ */ __name(function(elem, node, fullSection, conf) {\n const section = fullSection % MAX_SECTIONS - 1;\n const nodeElem = elem.append(\"g\");\n node.section = section;\n nodeElem.attr(\n \"class\",\n (node.class ? node.class + \" \" : \"\") + \"timeline-node \" + (\"section-\" + section)\n );\n const bkgElem = nodeElem.append(\"g\");\n const textElem = nodeElem.append(\"g\");\n const txt = textElem.append(\"text\").text(node.descr).attr(\"dy\", \"1em\").attr(\"alignment-baseline\", \"middle\").attr(\"dominant-baseline\", \"middle\").attr(\"text-anchor\", \"middle\").call(wrap, node.width);\n const bbox = txt.node().getBBox();\n const fontSize = conf.fontSize?.replace ? conf.fontSize.replace(\"px\", \"\") : conf.fontSize;\n node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;\n node.height = Math.max(node.height, node.maxHeight);\n node.width = node.width + 2 * node.padding;\n textElem.attr(\"transform\", \"translate(\" + node.width / 2 + \", \" + node.padding / 2 + \")\");\n defaultBkg(bkgElem, node, section, conf);\n return node;\n}, \"drawNode\");\nvar getVirtualNodeHeight = /* @__PURE__ */ __name(function(elem, node, conf) {\n const textElem = elem.append(\"g\");\n const txt = textElem.append(\"text\").text(node.descr).attr(\"dy\", \"1em\").attr(\"alignment-baseline\", \"middle\").attr(\"dominant-baseline\", \"middle\").attr(\"text-anchor\", \"middle\").call(wrap, node.width);\n const bbox = txt.node().getBBox();\n const fontSize = conf.fontSize?.replace ? conf.fontSize.replace(\"px\", \"\") : conf.fontSize;\n textElem.remove();\n return bbox.height + fontSize * 1.1 * 0.5 + node.padding;\n}, \"getVirtualNodeHeight\");\nvar defaultBkg = /* @__PURE__ */ __name(function(elem, node, section) {\n const rd = 5;\n elem.append(\"path\").attr(\"id\", \"node-\" + node.id).attr(\"class\", \"node-bkg node-\" + node.type).attr(\n \"d\",\n `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd} q5,0 5,5 v${node.height - rd} H0 Z`\n );\n elem.append(\"line\").attr(\"class\", \"node-line-\" + section).attr(\"x1\", 0).attr(\"y1\", node.height).attr(\"x2\", node.width).attr(\"y2\", node.height);\n}, \"defaultBkg\");\nvar svgDraw_default = {\n drawRect,\n drawCircle,\n drawSection,\n drawText,\n drawLabel,\n drawTask,\n drawBackgroundRect,\n getTextObj,\n getNoteRect,\n initGraphics,\n drawNode,\n getVirtualNodeHeight\n};\n\n// src/diagrams/timeline/timelineRenderer.ts\nvar draw = /* @__PURE__ */ __name(function(text, id, version, diagObj) {\n const conf = getConfig();\n const LEFT_MARGIN = conf.leftMargin ?? 50;\n log.debug(\"timeline\", diagObj.db);\n const securityLevel = conf.securityLevel;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = select2(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? select2(sandboxElement.nodes()[0].contentDocument.body) : select2(\"body\");\n const svg = root.select(\"#\" + id);\n svg.append(\"g\");\n const tasks2 = diagObj.db.getTasks();\n const title = diagObj.db.getCommonDb().getDiagramTitle();\n log.debug(\"task\", tasks2);\n svgDraw_default.initGraphics(svg);\n const sections2 = diagObj.db.getSections();\n log.debug(\"sections\", sections2);\n let maxSectionHeight = 0;\n let maxTaskHeight = 0;\n let depthY = 0;\n let sectionBeginY = 0;\n let masterX = 50 + LEFT_MARGIN;\n let masterY = 50;\n sectionBeginY = 50;\n let sectionNumber = 0;\n let hasSections = true;\n sections2.forEach(function(section) {\n const sectionNode = {\n number: sectionNumber,\n descr: section,\n section: sectionNumber,\n width: 150,\n padding: 20,\n maxHeight: maxSectionHeight\n };\n const sectionHeight = svgDraw_default.getVirtualNodeHeight(svg, sectionNode, conf);\n log.debug(\"sectionHeight before draw\", sectionHeight);\n maxSectionHeight = Math.max(maxSectionHeight, sectionHeight + 20);\n });\n let maxEventCount = 0;\n let maxEventLineLength = 0;\n log.debug(\"tasks.length\", tasks2.length);\n for (const [i, task] of tasks2.entries()) {\n const taskNode = {\n number: i,\n descr: task,\n section: task.section,\n width: 150,\n padding: 20,\n maxHeight: maxTaskHeight\n };\n const taskHeight = svgDraw_default.getVirtualNodeHeight(svg, taskNode, conf);\n log.debug(\"taskHeight before draw\", taskHeight);\n maxTaskHeight = Math.max(maxTaskHeight, taskHeight + 20);\n maxEventCount = Math.max(maxEventCount, task.events.length);\n let maxEventLineLengthTemp = 0;\n for (const event of task.events) {\n const eventNode = {\n descr: event,\n section: task.section,\n number: task.section,\n width: 150,\n padding: 20,\n maxHeight: 50\n };\n maxEventLineLengthTemp += svgDraw_default.getVirtualNodeHeight(svg, eventNode, conf);\n }\n maxEventLineLength = Math.max(maxEventLineLength, maxEventLineLengthTemp);\n }\n log.debug(\"maxSectionHeight before draw\", maxSectionHeight);\n log.debug(\"maxTaskHeight before draw\", maxTaskHeight);\n if (sections2 && sections2.length > 0) {\n sections2.forEach((section) => {\n const tasksForSection = tasks2.filter((task) => task.section === section);\n const sectionNode = {\n number: sectionNumber,\n descr: section,\n section: sectionNumber,\n width: 200 * Math.max(tasksForSection.length, 1) - 50,\n padding: 20,\n maxHeight: maxSectionHeight\n };\n log.debug(\"sectionNode\", sectionNode);\n const sectionNodeWrapper = svg.append(\"g\");\n const node = svgDraw_default.drawNode(sectionNodeWrapper, sectionNode, sectionNumber, conf);\n log.debug(\"sectionNode output\", node);\n sectionNodeWrapper.attr(\"transform\", `translate(${masterX}, ${sectionBeginY})`);\n masterY += maxSectionHeight + 50;\n if (tasksForSection.length > 0) {\n drawTasks(\n svg,\n tasksForSection,\n sectionNumber,\n masterX,\n masterY,\n maxTaskHeight,\n conf,\n maxEventCount,\n maxEventLineLength,\n maxSectionHeight,\n false\n );\n }\n masterX += 200 * Math.max(tasksForSection.length, 1);\n masterY = sectionBeginY;\n sectionNumber++;\n });\n } else {\n hasSections = false;\n drawTasks(\n svg,\n tasks2,\n sectionNumber,\n masterX,\n masterY,\n maxTaskHeight,\n conf,\n maxEventCount,\n maxEventLineLength,\n maxSectionHeight,\n true\n );\n }\n const box = svg.node().getBBox();\n log.debug(\"bounds\", box);\n if (title) {\n svg.append(\"text\").text(title).attr(\"x\", box.width / 2 - LEFT_MARGIN).attr(\"font-size\", \"4ex\").attr(\"font-weight\", \"bold\").attr(\"y\", 20);\n }\n depthY = hasSections ? maxSectionHeight + maxTaskHeight + 150 : maxTaskHeight + 100;\n const lineWrapper = svg.append(\"g\").attr(\"class\", \"lineWrapper\");\n lineWrapper.append(\"line\").attr(\"x1\", LEFT_MARGIN).attr(\"y1\", depthY).attr(\"x2\", box.width + 3 * LEFT_MARGIN).attr(\"y2\", depthY).attr(\"stroke-width\", 4).attr(\"stroke\", \"black\").attr(\"marker-end\", \"url(#arrowhead)\");\n setupGraphViewbox(\n void 0,\n svg,\n conf.timeline?.padding ?? 50,\n conf.timeline?.useMaxWidth ?? false\n );\n}, \"draw\");\nvar drawTasks = /* @__PURE__ */ __name(function(diagram2, tasks2, sectionColor, masterX, masterY, maxTaskHeight, conf, maxEventCount, maxEventLineLength, maxSectionHeight, isWithoutSections) {\n for (const task of tasks2) {\n const taskNode = {\n descr: task.task,\n section: sectionColor,\n number: sectionColor,\n width: 150,\n padding: 20,\n maxHeight: maxTaskHeight\n };\n log.debug(\"taskNode\", taskNode);\n const taskWrapper = diagram2.append(\"g\").attr(\"class\", \"taskWrapper\");\n const node = svgDraw_default.drawNode(taskWrapper, taskNode, sectionColor, conf);\n const taskHeight = node.height;\n log.debug(\"taskHeight after draw\", taskHeight);\n taskWrapper.attr(\"transform\", `translate(${masterX}, ${masterY})`);\n maxTaskHeight = Math.max(maxTaskHeight, taskHeight);\n if (task.events) {\n const lineWrapper = diagram2.append(\"g\").attr(\"class\", \"lineWrapper\");\n let lineLength = maxTaskHeight;\n masterY += 100;\n lineLength = lineLength + drawEvents(diagram2, task.events, sectionColor, masterX, masterY, conf);\n masterY -= 100;\n lineWrapper.append(\"line\").attr(\"x1\", masterX + 190 / 2).attr(\"y1\", masterY + maxTaskHeight).attr(\"x2\", masterX + 190 / 2).attr(\n \"y2\",\n masterY + maxTaskHeight + (isWithoutSections ? maxTaskHeight : maxSectionHeight) + maxEventLineLength + 120\n ).attr(\"stroke-width\", 2).attr(\"stroke\", \"black\").attr(\"marker-end\", \"url(#arrowhead)\").attr(\"stroke-dasharray\", \"5,5\");\n }\n masterX = masterX + 200;\n if (isWithoutSections && !conf.timeline?.disableMulticolor) {\n sectionColor++;\n }\n }\n masterY = masterY - 10;\n}, \"drawTasks\");\nvar drawEvents = /* @__PURE__ */ __name(function(diagram2, events, sectionColor, masterX, masterY, conf) {\n let maxEventHeight = 0;\n const eventBeginY = masterY;\n masterY = masterY + 100;\n for (const event of events) {\n const eventNode = {\n descr: event,\n section: sectionColor,\n number: sectionColor,\n width: 150,\n padding: 20,\n maxHeight: 50\n };\n log.debug(\"eventNode\", eventNode);\n const eventWrapper = diagram2.append(\"g\").attr(\"class\", \"eventWrapper\");\n const node = svgDraw_default.drawNode(eventWrapper, eventNode, sectionColor, conf);\n const eventHeight = node.height;\n maxEventHeight = maxEventHeight + eventHeight;\n eventWrapper.attr(\"transform\", `translate(${masterX}, ${masterY})`);\n masterY = masterY + 10 + eventHeight;\n }\n masterY = eventBeginY;\n return maxEventHeight;\n}, \"drawEvents\");\nvar timelineRenderer_default = {\n setConf: /* @__PURE__ */ __name(() => {\n }, \"setConf\"),\n draw\n};\n\n// src/diagrams/timeline/styles.js\nimport { darken, lighten, isDark } from \"khroma\";\nvar genSections = /* @__PURE__ */ __name((options) => {\n let sections2 = \"\";\n for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {\n options[\"lineColor\" + i] = options[\"lineColor\" + i] || options[\"cScaleInv\" + i];\n if (isDark(options[\"lineColor\" + i])) {\n options[\"lineColor\" + i] = lighten(options[\"lineColor\" + i], 20);\n } else {\n options[\"lineColor\" + i] = darken(options[\"lineColor\" + i], 20);\n }\n }\n for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {\n const sw = \"\" + (17 - 3 * i);\n sections2 += `\n .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} path {\n fill: ${options[\"cScale\" + i]};\n }\n .section-${i - 1} text {\n fill: ${options[\"cScaleLabel\" + i]};\n }\n .node-icon-${i - 1} {\n font-size: 40px;\n color: ${options[\"cScaleLabel\" + i]};\n }\n .section-edge-${i - 1}{\n stroke: ${options[\"cScale\" + i]};\n }\n .edge-depth-${i - 1}{\n stroke-width: ${sw};\n }\n .section-${i - 1} line {\n stroke: ${options[\"cScaleInv\" + i]} ;\n stroke-width: 3;\n }\n\n .lineWrapper line{\n stroke: ${options[\"cScaleLabel\" + i]} ;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `;\n }\n return sections2;\n}, \"genSections\");\nvar getStyles = /* @__PURE__ */ __name((options) => `\n .edge {\n stroke-width: 3;\n }\n ${genSections(options)}\n .section-root rect, .section-root path, .section-root circle {\n fill: ${options.git0};\n }\n .section-root text {\n fill: ${options.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .eventWrapper {\n filter: brightness(120%);\n }\n`, \"getStyles\");\nvar styles_default = getStyles;\n\n// src/diagrams/timeline/timeline-definition.ts\nvar diagram = {\n db: timelineDb_exports,\n renderer: timelineRenderer_default,\n parser: timeline_default,\n styles: styles_default\n};\nexport {\n diagram\n};\n", "/**\n * Copyright (c) 2016-2024, The Cytoscape Consortium.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of\n * this software and associated documentation files (the \u201CSoftware\u201D), to deal in\n * the Software without restriction, including without limitation the rights to\n * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\n * of the Software, and to permit persons to whom the Software is furnished to do\n * so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \u201CAS IS\u201D, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nfunction _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n}\nfunction _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}\nfunction _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\nfunction _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}\nfunction _defineProperty$1(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n return obj;\n}\nfunction _slicedToArray(arr, i) {\n return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest();\n}\nfunction _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}\nfunction _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n var _s, _e;\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n return _arr;\n}\nfunction _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return _arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);\n}\nfunction _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];\n return arr2;\n}\nfunction _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}\nfunction _createForOfIteratorHelper(o, allowArrayLike) {\n var it = typeof Symbol !== \"undefined\" && o[Symbol.iterator] || o[\"@@iterator\"];\n if (!it) {\n if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === \"number\") {\n if (it) o = it;\n var i = 0;\n var F = function () {};\n return {\n s: F,\n n: function () {\n if (i >= o.length) return {\n done: true\n };\n return {\n done: false,\n value: o[i++]\n };\n },\n e: function (e) {\n throw e;\n },\n f: F\n };\n }\n throw new TypeError(\"Invalid attempt to iterate non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n }\n var normalCompletion = true,\n didErr = false,\n err;\n return {\n s: function () {\n it = it.call(o);\n },\n n: function () {\n var step = it.next();\n normalCompletion = step.done;\n return step;\n },\n e: function (e) {\n didErr = true;\n err = e;\n },\n f: function () {\n try {\n if (!normalCompletion && it.return != null) it.return();\n } finally {\n if (didErr) throw err;\n }\n }\n };\n}\n\nvar _window = typeof window === 'undefined' ? null : window; // eslint-disable-line no-undef\n\nvar navigator = _window ? _window.navigator : null;\n_window ? _window.document : null;\nvar typeofstr = _typeof('');\nvar typeofobj = _typeof({});\nvar typeoffn = _typeof(function () {});\nvar typeofhtmlele = typeof HTMLElement === \"undefined\" ? \"undefined\" : _typeof(HTMLElement);\nvar instanceStr = function instanceStr(obj) {\n return obj && obj.instanceString && fn$6(obj.instanceString) ? obj.instanceString() : null;\n};\n\nvar string = function string(obj) {\n return obj != null && _typeof(obj) == typeofstr;\n};\nvar fn$6 = function fn(obj) {\n return obj != null && _typeof(obj) === typeoffn;\n};\nvar array = function array(obj) {\n return !elementOrCollection(obj) && (Array.isArray ? Array.isArray(obj) : obj != null && obj instanceof Array);\n};\nvar plainObject = function plainObject(obj) {\n return obj != null && _typeof(obj) === typeofobj && !array(obj) && obj.constructor === Object;\n};\nvar object = function object(obj) {\n return obj != null && _typeof(obj) === typeofobj;\n};\nvar number$1 = function number(obj) {\n return obj != null && _typeof(obj) === _typeof(1) && !isNaN(obj);\n};\nvar integer = function integer(obj) {\n return number$1(obj) && Math.floor(obj) === obj;\n};\nvar htmlElement = function htmlElement(obj) {\n if ('undefined' === typeofhtmlele) {\n return undefined;\n } else {\n return null != obj && obj instanceof HTMLElement;\n }\n};\nvar elementOrCollection = function elementOrCollection(obj) {\n return element(obj) || collection(obj);\n};\nvar element = function element(obj) {\n return instanceStr(obj) === 'collection' && obj._private.single;\n};\nvar collection = function collection(obj) {\n return instanceStr(obj) === 'collection' && !obj._private.single;\n};\nvar core = function core(obj) {\n return instanceStr(obj) === 'core';\n};\nvar stylesheet = function stylesheet(obj) {\n return instanceStr(obj) === 'stylesheet';\n};\nvar event = function event(obj) {\n return instanceStr(obj) === 'event';\n};\nvar emptyString = function emptyString(obj) {\n if (obj === undefined || obj === null) {\n // null is empty\n return true;\n } else if (obj === '' || obj.match(/^\\s+$/)) {\n return true; // empty string is empty\n }\n\n return false; // otherwise, we don't know what we've got\n};\nvar domElement = function domElement(obj) {\n if (typeof HTMLElement === 'undefined') {\n return false; // we're not in a browser so it doesn't matter\n } else {\n return obj instanceof HTMLElement;\n }\n};\nvar boundingBox = function boundingBox(obj) {\n return plainObject(obj) && number$1(obj.x1) && number$1(obj.x2) && number$1(obj.y1) && number$1(obj.y2);\n};\nvar promise = function promise(obj) {\n return object(obj) && fn$6(obj.then);\n};\nvar ms = function ms() {\n return navigator && navigator.userAgent.match(/msie|trident|edge/i);\n}; // probably a better way to detect this...\n\nvar memoize$1 = function memoize(fn, keyFn) {\n if (!keyFn) {\n keyFn = function keyFn() {\n if (arguments.length === 1) {\n return arguments[0];\n } else if (arguments.length === 0) {\n return 'undefined';\n }\n var args = [];\n for (var i = 0; i < arguments.length; i++) {\n args.push(arguments[i]);\n }\n return args.join('$');\n };\n }\n var memoizedFn = function memoizedFn() {\n var self = this;\n var args = arguments;\n var ret;\n var k = keyFn.apply(self, args);\n var cache = memoizedFn.cache;\n if (!(ret = cache[k])) {\n ret = cache[k] = fn.apply(self, args);\n }\n return ret;\n };\n memoizedFn.cache = {};\n return memoizedFn;\n};\n\nvar camel2dash = memoize$1(function (str) {\n return str.replace(/([A-Z])/g, function (v) {\n return '-' + v.toLowerCase();\n });\n});\nvar dash2camel = memoize$1(function (str) {\n return str.replace(/(-\\w)/g, function (v) {\n return v[1].toUpperCase();\n });\n});\nvar prependCamel = memoize$1(function (prefix, str) {\n return prefix + str[0].toUpperCase() + str.substring(1);\n}, function (prefix, str) {\n return prefix + '$' + str;\n});\nvar capitalize = function capitalize(str) {\n if (emptyString(str)) {\n return str;\n }\n return str.charAt(0).toUpperCase() + str.substring(1);\n};\n\nvar number = '(?:[-+]?(?:(?:\\\\d+|\\\\d*\\\\.\\\\d+)(?:[Ee][+-]?\\\\d+)?))';\nvar rgba = 'rgb[a]?\\\\((' + number + '[%]?)\\\\s*,\\\\s*(' + number + '[%]?)\\\\s*,\\\\s*(' + number + '[%]?)(?:\\\\s*,\\\\s*(' + number + '))?\\\\)';\nvar rgbaNoBackRefs = 'rgb[a]?\\\\((?:' + number + '[%]?)\\\\s*,\\\\s*(?:' + number + '[%]?)\\\\s*,\\\\s*(?:' + number + '[%]?)(?:\\\\s*,\\\\s*(?:' + number + '))?\\\\)';\nvar hsla = 'hsl[a]?\\\\((' + number + ')\\\\s*,\\\\s*(' + number + '[%])\\\\s*,\\\\s*(' + number + '[%])(?:\\\\s*,\\\\s*(' + number + '))?\\\\)';\nvar hslaNoBackRefs = 'hsl[a]?\\\\((?:' + number + ')\\\\s*,\\\\s*(?:' + number + '[%])\\\\s*,\\\\s*(?:' + number + '[%])(?:\\\\s*,\\\\s*(?:' + number + '))?\\\\)';\nvar hex3 = '\\\\#[0-9a-fA-F]{3}';\nvar hex6 = '\\\\#[0-9a-fA-F]{6}';\n\nvar ascending = function ascending(a, b) {\n if (a < b) {\n return -1;\n } else if (a > b) {\n return 1;\n } else {\n return 0;\n }\n};\nvar descending = function descending(a, b) {\n return -1 * ascending(a, b);\n};\n\nvar extend = Object.assign != null ? Object.assign.bind(Object) : function (tgt) {\n var args = arguments;\n for (var i = 1; i < args.length; i++) {\n var obj = args[i];\n if (obj == null) {\n continue;\n }\n var keys = Object.keys(obj);\n for (var j = 0; j < keys.length; j++) {\n var k = keys[j];\n tgt[k] = obj[k];\n }\n }\n return tgt;\n};\n\n// get [r, g, b] from #abc or #aabbcc\nvar hex2tuple = function hex2tuple(hex) {\n if (!(hex.length === 4 || hex.length === 7) || hex[0] !== '#') {\n return;\n }\n var shortHex = hex.length === 4;\n var r, g, b;\n var base = 16;\n if (shortHex) {\n r = parseInt(hex[1] + hex[1], base);\n g = parseInt(hex[2] + hex[2], base);\n b = parseInt(hex[3] + hex[3], base);\n } else {\n r = parseInt(hex[1] + hex[2], base);\n g = parseInt(hex[3] + hex[4], base);\n b = parseInt(hex[5] + hex[6], base);\n }\n return [r, g, b];\n};\n\n// get [r, g, b, a] from hsl(0, 0, 0) or hsla(0, 0, 0, 0)\nvar hsl2tuple = function hsl2tuple(hsl) {\n var ret;\n var h, s, l, a, r, g, b;\n function hue2rgb(p, q, t) {\n if (t < 0) t += 1;\n if (t > 1) t -= 1;\n if (t < 1 / 6) return p + (q - p) * 6 * t;\n if (t < 1 / 2) return q;\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;\n return p;\n }\n var m = new RegExp('^' + hsla + '$').exec(hsl);\n if (m) {\n // get hue\n h = parseInt(m[1]);\n if (h < 0) {\n h = (360 - -1 * h % 360) % 360;\n } else if (h > 360) {\n h = h % 360;\n }\n h /= 360; // normalise on [0, 1]\n\n s = parseFloat(m[2]);\n if (s < 0 || s > 100) {\n return;\n } // saturation is [0, 100]\n s = s / 100; // normalise on [0, 1]\n\n l = parseFloat(m[3]);\n if (l < 0 || l > 100) {\n return;\n } // lightness is [0, 100]\n l = l / 100; // normalise on [0, 1]\n\n a = m[4];\n if (a !== undefined) {\n a = parseFloat(a);\n if (a < 0 || a > 1) {\n return;\n } // alpha is [0, 1]\n }\n\n // now, convert to rgb\n // code from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript\n if (s === 0) {\n r = g = b = Math.round(l * 255); // achromatic\n } else {\n var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n var p = 2 * l - q;\n r = Math.round(255 * hue2rgb(p, q, h + 1 / 3));\n g = Math.round(255 * hue2rgb(p, q, h));\n b = Math.round(255 * hue2rgb(p, q, h - 1 / 3));\n }\n ret = [r, g, b, a];\n }\n return ret;\n};\n\n// get [r, g, b, a] from rgb(0, 0, 0) or rgba(0, 0, 0, 0)\nvar rgb2tuple = function rgb2tuple(rgb) {\n var ret;\n var m = new RegExp('^' + rgba + '$').exec(rgb);\n if (m) {\n ret = [];\n var isPct = [];\n for (var i = 1; i <= 3; i++) {\n var channel = m[i];\n if (channel[channel.length - 1] === '%') {\n isPct[i] = true;\n }\n channel = parseFloat(channel);\n if (isPct[i]) {\n channel = channel / 100 * 255; // normalise to [0, 255]\n }\n\n if (channel < 0 || channel > 255) {\n return;\n } // invalid channel value\n\n ret.push(Math.floor(channel));\n }\n var atLeastOneIsPct = isPct[1] || isPct[2] || isPct[3];\n var allArePct = isPct[1] && isPct[2] && isPct[3];\n if (atLeastOneIsPct && !allArePct) {\n return;\n } // must all be percent values if one is\n\n var alpha = m[4];\n if (alpha !== undefined) {\n alpha = parseFloat(alpha);\n if (alpha < 0 || alpha > 1) {\n return;\n } // invalid alpha value\n\n ret.push(alpha);\n }\n }\n return ret;\n};\nvar colorname2tuple = function colorname2tuple(color) {\n return colors[color.toLowerCase()];\n};\nvar color2tuple = function color2tuple(color) {\n return (array(color) ? color : null) || colorname2tuple(color) || hex2tuple(color) || rgb2tuple(color) || hsl2tuple(color);\n};\nvar colors = {\n // special colour names\n transparent: [0, 0, 0, 0],\n // NB alpha === 0\n\n // regular colours\n aliceblue: [240, 248, 255],\n antiquewhite: [250, 235, 215],\n aqua: [0, 255, 255],\n aquamarine: [127, 255, 212],\n azure: [240, 255, 255],\n beige: [245, 245, 220],\n bisque: [255, 228, 196],\n black: [0, 0, 0],\n blanchedalmond: [255, 235, 205],\n blue: [0, 0, 255],\n blueviolet: [138, 43, 226],\n brown: [165, 42, 42],\n burlywood: [222, 184, 135],\n cadetblue: [95, 158, 160],\n chartreuse: [127, 255, 0],\n chocolate: [210, 105, 30],\n coral: [255, 127, 80],\n cornflowerblue: [100, 149, 237],\n cornsilk: [255, 248, 220],\n crimson: [220, 20, 60],\n cyan: [0, 255, 255],\n darkblue: [0, 0, 139],\n darkcyan: [0, 139, 139],\n darkgoldenrod: [184, 134, 11],\n darkgray: [169, 169, 169],\n darkgreen: [0, 100, 0],\n darkgrey: [169, 169, 169],\n darkkhaki: [189, 183, 107],\n darkmagenta: [139, 0, 139],\n darkolivegreen: [85, 107, 47],\n darkorange: [255, 140, 0],\n darkorchid: [153, 50, 204],\n darkred: [139, 0, 0],\n darksalmon: [233, 150, 122],\n darkseagreen: [143, 188, 143],\n darkslateblue: [72, 61, 139],\n darkslategray: [47, 79, 79],\n darkslategrey: [47, 79, 79],\n darkturquoise: [0, 206, 209],\n darkviolet: [148, 0, 211],\n deeppink: [255, 20, 147],\n deepskyblue: [0, 191, 255],\n dimgray: [105, 105, 105],\n dimgrey: [105, 105, 105],\n dodgerblue: [30, 144, 255],\n firebrick: [178, 34, 34],\n floralwhite: [255, 250, 240],\n forestgreen: [34, 139, 34],\n fuchsia: [255, 0, 255],\n gainsboro: [220, 220, 220],\n ghostwhite: [248, 248, 255],\n gold: [255, 215, 0],\n goldenrod: [218, 165, 32],\n gray: [128, 128, 128],\n grey: [128, 128, 128],\n green: [0, 128, 0],\n greenyellow: [173, 255, 47],\n honeydew: [240, 255, 240],\n hotpink: [255, 105, 180],\n indianred: [205, 92, 92],\n indigo: [75, 0, 130],\n ivory: [255, 255, 240],\n khaki: [240, 230, 140],\n lavender: [230, 230, 250],\n lavenderblush: [255, 240, 245],\n lawngreen: [124, 252, 0],\n lemonchiffon: [255, 250, 205],\n lightblue: [173, 216, 230],\n lightcoral: [240, 128, 128],\n lightcyan: [224, 255, 255],\n lightgoldenrodyellow: [250, 250, 210],\n lightgray: [211, 211, 211],\n lightgreen: [144, 238, 144],\n lightgrey: [211, 211, 211],\n lightpink: [255, 182, 193],\n lightsalmon: [255, 160, 122],\n lightseagreen: [32, 178, 170],\n lightskyblue: [135, 206, 250],\n lightslategray: [119, 136, 153],\n lightslategrey: [119, 136, 153],\n lightsteelblue: [176, 196, 222],\n lightyellow: [255, 255, 224],\n lime: [0, 255, 0],\n limegreen: [50, 205, 50],\n linen: [250, 240, 230],\n magenta: [255, 0, 255],\n maroon: [128, 0, 0],\n mediumaquamarine: [102, 205, 170],\n mediumblue: [0, 0, 205],\n mediumorchid: [186, 85, 211],\n mediumpurple: [147, 112, 219],\n mediumseagreen: [60, 179, 113],\n mediumslateblue: [123, 104, 238],\n mediumspringgreen: [0, 250, 154],\n mediumturquoise: [72, 209, 204],\n mediumvioletred: [199, 21, 133],\n midnightblue: [25, 25, 112],\n mintcream: [245, 255, 250],\n mistyrose: [255, 228, 225],\n moccasin: [255, 228, 181],\n navajowhite: [255, 222, 173],\n navy: [0, 0, 128],\n oldlace: [253, 245, 230],\n olive: [128, 128, 0],\n olivedrab: [107, 142, 35],\n orange: [255, 165, 0],\n orangered: [255, 69, 0],\n orchid: [218, 112, 214],\n palegoldenrod: [238, 232, 170],\n palegreen: [152, 251, 152],\n paleturquoise: [175, 238, 238],\n palevioletred: [219, 112, 147],\n papayawhip: [255, 239, 213],\n peachpuff: [255, 218, 185],\n peru: [205, 133, 63],\n pink: [255, 192, 203],\n plum: [221, 160, 221],\n powderblue: [176, 224, 230],\n purple: [128, 0, 128],\n red: [255, 0, 0],\n rosybrown: [188, 143, 143],\n royalblue: [65, 105, 225],\n saddlebrown: [139, 69, 19],\n salmon: [250, 128, 114],\n sandybrown: [244, 164, 96],\n seagreen: [46, 139, 87],\n seashell: [255, 245, 238],\n sienna: [160, 82, 45],\n silver: [192, 192, 192],\n skyblue: [135, 206, 235],\n slateblue: [106, 90, 205],\n slategray: [112, 128, 144],\n slategrey: [112, 128, 144],\n snow: [255, 250, 250],\n springgreen: [0, 255, 127],\n steelblue: [70, 130, 180],\n tan: [210, 180, 140],\n teal: [0, 128, 128],\n thistle: [216, 191, 216],\n tomato: [255, 99, 71],\n turquoise: [64, 224, 208],\n violet: [238, 130, 238],\n wheat: [245, 222, 179],\n white: [255, 255, 255],\n whitesmoke: [245, 245, 245],\n yellow: [255, 255, 0],\n yellowgreen: [154, 205, 50]\n};\n\n// sets the value in a map (map may not be built)\nvar setMap = function setMap(options) {\n var obj = options.map;\n var keys = options.keys;\n var l = keys.length;\n for (var i = 0; i < l; i++) {\n var key = keys[i];\n if (plainObject(key)) {\n throw Error('Tried to set map with object key');\n }\n if (i < keys.length - 1) {\n // extend the map if necessary\n if (obj[key] == null) {\n obj[key] = {};\n }\n obj = obj[key];\n } else {\n // set the value\n obj[key] = options.value;\n }\n }\n};\n\n// gets the value in a map even if it's not built in places\nvar getMap = function getMap(options) {\n var obj = options.map;\n var keys = options.keys;\n var l = keys.length;\n for (var i = 0; i < l; i++) {\n var key = keys[i];\n if (plainObject(key)) {\n throw Error('Tried to get map with object key');\n }\n obj = obj[key];\n if (obj == null) {\n return obj;\n }\n }\n return obj;\n};\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return value != null && (type == 'object' || type == 'function');\n}\n\nvar isObject_1 = isObject;\n\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;\n\nvar _freeGlobal = freeGlobal;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = _freeGlobal || freeSelf || Function('return this')();\n\nvar _root = root;\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return _root.Date.now();\n};\n\nvar now_1 = now;\n\n/** Used to match a single whitespace character. */\nvar reWhitespace = /\\s/;\n\n/**\n * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace\n * character of `string`.\n *\n * @private\n * @param {string} string The string to inspect.\n * @returns {number} Returns the index of the last non-whitespace character.\n */\nfunction trimmedEndIndex(string) {\n var index = string.length;\n\n while (index-- && reWhitespace.test(string.charAt(index))) {}\n return index;\n}\n\nvar _trimmedEndIndex = trimmedEndIndex;\n\n/** Used to match leading whitespace. */\nvar reTrimStart = /^\\s+/;\n\n/**\n * The base implementation of `_.trim`.\n *\n * @private\n * @param {string} string The string to trim.\n * @returns {string} Returns the trimmed string.\n */\nfunction baseTrim(string) {\n return string\n ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')\n : string;\n}\n\nvar _baseTrim = baseTrim;\n\n/** Built-in value references. */\nvar Symbol$1 = _root.Symbol;\n\nvar _Symbol = Symbol$1;\n\n/** Used for built-in method references. */\nvar objectProto$5 = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty$4 = objectProto$5.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString$1 = objectProto$5.toString;\n\n/** Built-in value references. */\nvar symToStringTag$1 = _Symbol ? _Symbol.toStringTag : undefined;\n\n/**\n * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the raw `toStringTag`.\n */\nfunction getRawTag(value) {\n var isOwn = hasOwnProperty$4.call(value, symToStringTag$1),\n tag = value[symToStringTag$1];\n\n try {\n value[symToStringTag$1] = undefined;\n var unmasked = true;\n } catch (e) {}\n\n var result = nativeObjectToString$1.call(value);\n if (unmasked) {\n if (isOwn) {\n value[symToStringTag$1] = tag;\n } else {\n delete value[symToStringTag$1];\n }\n }\n return result;\n}\n\nvar _getRawTag = getRawTag;\n\n/** Used for built-in method references. */\nvar objectProto$4 = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar nativeObjectToString = objectProto$4.toString;\n\n/**\n * Converts `value` to a string using `Object.prototype.toString`.\n *\n * @private\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n */\nfunction objectToString(value) {\n return nativeObjectToString.call(value);\n}\n\nvar _objectToString = objectToString;\n\n/** `Object#toString` result references. */\nvar nullTag = '[object Null]',\n undefinedTag = '[object Undefined]';\n\n/** Built-in value references. */\nvar symToStringTag = _Symbol ? _Symbol.toStringTag : undefined;\n\n/**\n * The base implementation of `getTag` without fallbacks for buggy environments.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n if (value == null) {\n return value === undefined ? undefinedTag : nullTag;\n }\n return (symToStringTag && symToStringTag in Object(value))\n ? _getRawTag(value)\n : _objectToString(value);\n}\n\nvar _baseGetTag = baseGetTag;\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return value != null && typeof value == 'object';\n}\n\nvar isObjectLike_1 = isObjectLike;\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike_1(value) && _baseGetTag(value) == symbolTag);\n}\n\nvar isSymbol_1 = isSymbol;\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol_1(value)) {\n return NAN;\n }\n if (isObject_1(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject_1(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = _baseTrim(value);\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nvar toNumber_1 = toNumber;\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT$1 = 'Expected a function';\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT$1);\n }\n wait = toNumber_1(wait) || 0;\n if (isObject_1(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber_1(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n timeWaiting = wait - timeSinceLastCall;\n\n return maxing\n ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now_1();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now_1());\n }\n\n function debounced() {\n var time = now_1(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\nvar debounce_1 = debounce;\n\nvar performance = _window ? _window.performance : null;\nvar pnow = performance && performance.now ? function () {\n return performance.now();\n} : function () {\n return Date.now();\n};\nvar raf = function () {\n if (_window) {\n if (_window.requestAnimationFrame) {\n return function (fn) {\n _window.requestAnimationFrame(fn);\n };\n } else if (_window.mozRequestAnimationFrame) {\n return function (fn) {\n _window.mozRequestAnimationFrame(fn);\n };\n } else if (_window.webkitRequestAnimationFrame) {\n return function (fn) {\n _window.webkitRequestAnimationFrame(fn);\n };\n } else if (_window.msRequestAnimationFrame) {\n return function (fn) {\n _window.msRequestAnimationFrame(fn);\n };\n }\n }\n return function (fn) {\n if (fn) {\n setTimeout(function () {\n fn(pnow());\n }, 1000 / 60);\n }\n };\n}();\nvar requestAnimationFrame = function requestAnimationFrame(fn) {\n return raf(fn);\n};\nvar performanceNow = pnow;\n\nvar DEFAULT_HASH_SEED = 9261;\nvar K = 65599; // 37 also works pretty well\nvar DEFAULT_HASH_SEED_ALT = 5381;\nvar hashIterableInts = function hashIterableInts(iterator) {\n var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED;\n // sdbm/string-hash\n var hash = seed;\n var entry;\n for (;;) {\n entry = iterator.next();\n if (entry.done) {\n break;\n }\n hash = hash * K + entry.value | 0;\n }\n return hash;\n};\nvar hashInt = function hashInt(num) {\n var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED;\n // sdbm/string-hash\n return seed * K + num | 0;\n};\nvar hashIntAlt = function hashIntAlt(num) {\n var seed = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_HASH_SEED_ALT;\n // djb2/string-hash\n return (seed << 5) + seed + num | 0;\n};\nvar combineHashes = function combineHashes(hash1, hash2) {\n return hash1 * 0x200000 + hash2;\n};\nvar combineHashesArray = function combineHashesArray(hashes) {\n return hashes[0] * 0x200000 + hashes[1];\n};\nvar hashArrays = function hashArrays(hashes1, hashes2) {\n return [hashInt(hashes1[0], hashes2[0]), hashIntAlt(hashes1[1], hashes2[1])];\n};\nvar hashIntsArray = function hashIntsArray(ints, seed) {\n var entry = {\n value: 0,\n done: false\n };\n var i = 0;\n var length = ints.length;\n var iterator = {\n next: function next() {\n if (i < length) {\n entry.value = ints[i++];\n } else {\n entry.done = true;\n }\n return entry;\n }\n };\n return hashIterableInts(iterator, seed);\n};\nvar hashString = function hashString(str, seed) {\n var entry = {\n value: 0,\n done: false\n };\n var i = 0;\n var length = str.length;\n var iterator = {\n next: function next() {\n if (i < length) {\n entry.value = str.charCodeAt(i++);\n } else {\n entry.done = true;\n }\n return entry;\n }\n };\n return hashIterableInts(iterator, seed);\n};\nvar hashStrings = function hashStrings() {\n return hashStringsArray(arguments);\n};\nvar hashStringsArray = function hashStringsArray(strs) {\n var hash;\n for (var i = 0; i < strs.length; i++) {\n var str = strs[i];\n if (i === 0) {\n hash = hashString(str);\n } else {\n hash = hashString(str, hash);\n }\n }\n return hash;\n};\n\n/*global console */\nvar warningsEnabled = true;\nvar warnSupported = console.warn != null; // eslint-disable-line no-console\nvar traceSupported = console.trace != null; // eslint-disable-line no-console\n\nvar MAX_INT$1 = Number.MAX_SAFE_INTEGER || 9007199254740991;\nvar trueify = function trueify() {\n return true;\n};\nvar falsify = function falsify() {\n return false;\n};\nvar zeroify = function zeroify() {\n return 0;\n};\nvar noop$1 = function noop() {};\nvar error = function error(msg) {\n throw new Error(msg);\n};\nvar warnings = function warnings(enabled) {\n if (enabled !== undefined) {\n warningsEnabled = !!enabled;\n } else {\n return warningsEnabled;\n }\n};\nvar warn = function warn(msg) {\n /* eslint-disable no-console */\n if (!warnings()) {\n return;\n }\n if (warnSupported) {\n console.warn(msg);\n } else {\n console.log(msg);\n if (traceSupported) {\n console.trace();\n }\n }\n}; /* eslint-enable */\n\nvar clone = function clone(obj) {\n return extend({}, obj);\n};\n\n// gets a shallow copy of the argument\nvar copy = function copy(obj) {\n if (obj == null) {\n return obj;\n }\n if (array(obj)) {\n return obj.slice();\n } else if (plainObject(obj)) {\n return clone(obj);\n } else {\n return obj;\n }\n};\nvar copyArray$1 = function copyArray(arr) {\n return arr.slice();\n};\nvar uuid = function uuid(a, b /* placeholders */) {\n for (\n // loop :)\n b = a = '';\n // b - result , a - numeric letiable\n a++ < 36;\n //\n b += a * 51 & 52 // if \"a\" is not 9 or 14 or 19 or 24\n ?\n // return a random number or 4\n (a ^ 15 // if \"a\" is not 15\n ?\n // generate a random number from 0 to 15\n 8 ^ Math.random() * (a ^ 20 ? 16 : 4) // unless \"a\" is 20, in which case a random number from 8 to 11\n : 4 // otherwise 4\n ).toString(16) : '-' // in other cases (if \"a\" is 9,14,19,24) insert \"-\"\n ) {\n }\n return b;\n};\nvar _staticEmptyObject = {};\nvar staticEmptyObject = function staticEmptyObject() {\n return _staticEmptyObject;\n};\nvar defaults$g = function defaults(_defaults) {\n var keys = Object.keys(_defaults);\n return function (opts) {\n var filledOpts = {};\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n var optVal = opts == null ? undefined : opts[key];\n filledOpts[key] = optVal === undefined ? _defaults[key] : optVal;\n }\n return filledOpts;\n };\n};\nvar removeFromArray = function removeFromArray(arr, ele, oneCopy) {\n for (var i = arr.length - 1; i >= 0; i--) {\n if (arr[i] === ele) {\n arr.splice(i, 1);\n if (oneCopy) {\n break;\n }\n }\n }\n};\nvar clearArray = function clearArray(arr) {\n arr.splice(0, arr.length);\n};\nvar push = function push(arr, otherArr) {\n for (var i = 0; i < otherArr.length; i++) {\n var el = otherArr[i];\n arr.push(el);\n }\n};\nvar getPrefixedProperty = function getPrefixedProperty(obj, propName, prefix) {\n if (prefix) {\n propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth\n }\n\n return obj[propName];\n};\nvar setPrefixedProperty = function setPrefixedProperty(obj, propName, prefix, value) {\n if (prefix) {\n propName = prependCamel(prefix, propName); // e.g. (labelWidth, source) => sourceLabelWidth\n }\n\n obj[propName] = value;\n};\n\n/* global Map */\nvar ObjectMap = /*#__PURE__*/function () {\n function ObjectMap() {\n _classCallCheck(this, ObjectMap);\n this._obj = {};\n }\n _createClass(ObjectMap, [{\n key: \"set\",\n value: function set(key, val) {\n this._obj[key] = val;\n return this;\n }\n }, {\n key: \"delete\",\n value: function _delete(key) {\n this._obj[key] = undefined;\n return this;\n }\n }, {\n key: \"clear\",\n value: function clear() {\n this._obj = {};\n }\n }, {\n key: \"has\",\n value: function has(key) {\n return this._obj[key] !== undefined;\n }\n }, {\n key: \"get\",\n value: function get(key) {\n return this._obj[key];\n }\n }]);\n return ObjectMap;\n}();\nvar Map$2 = typeof Map !== 'undefined' ? Map : ObjectMap;\n\n/* global Set */\n\nvar undef = \"undefined\" ;\nvar ObjectSet = /*#__PURE__*/function () {\n function ObjectSet(arrayOrObjectSet) {\n _classCallCheck(this, ObjectSet);\n this._obj = Object.create(null);\n this.size = 0;\n if (arrayOrObjectSet != null) {\n var arr;\n if (arrayOrObjectSet.instanceString != null && arrayOrObjectSet.instanceString() === this.instanceString()) {\n arr = arrayOrObjectSet.toArray();\n } else {\n arr = arrayOrObjectSet;\n }\n for (var i = 0; i < arr.length; i++) {\n this.add(arr[i]);\n }\n }\n }\n _createClass(ObjectSet, [{\n key: \"instanceString\",\n value: function instanceString() {\n return 'set';\n }\n }, {\n key: \"add\",\n value: function add(val) {\n var o = this._obj;\n if (o[val] !== 1) {\n o[val] = 1;\n this.size++;\n }\n }\n }, {\n key: \"delete\",\n value: function _delete(val) {\n var o = this._obj;\n if (o[val] === 1) {\n o[val] = 0;\n this.size--;\n }\n }\n }, {\n key: \"clear\",\n value: function clear() {\n this._obj = Object.create(null);\n }\n }, {\n key: \"has\",\n value: function has(val) {\n return this._obj[val] === 1;\n }\n }, {\n key: \"toArray\",\n value: function toArray() {\n var _this = this;\n return Object.keys(this._obj).filter(function (key) {\n return _this.has(key);\n });\n }\n }, {\n key: \"forEach\",\n value: function forEach(callback, thisArg) {\n return this.toArray().forEach(callback, thisArg);\n }\n }]);\n return ObjectSet;\n}();\nvar Set$1 = (typeof Set === \"undefined\" ? \"undefined\" : _typeof(Set)) !== undef ? Set : ObjectSet;\n\n// represents a node or an edge\nvar Element = function Element(cy, params) {\n var restore = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n if (cy === undefined || params === undefined || !core(cy)) {\n error('An element must have a core reference and parameters set');\n return;\n }\n var group = params.group;\n\n // try to automatically infer the group if unspecified\n if (group == null) {\n if (params.data && params.data.source != null && params.data.target != null) {\n group = 'edges';\n } else {\n group = 'nodes';\n }\n }\n\n // validate group\n if (group !== 'nodes' && group !== 'edges') {\n error('An element must be of type `nodes` or `edges`; you specified `' + group + '`');\n return;\n }\n\n // make the element array-like, just like a collection\n this.length = 1;\n this[0] = this;\n\n // NOTE: when something is added here, add also to ele.json()\n var _p = this._private = {\n cy: cy,\n single: true,\n // indicates this is an element\n data: params.data || {},\n // data object\n position: params.position || {\n x: 0,\n y: 0\n },\n // (x, y) position pair\n autoWidth: undefined,\n // width and height of nodes calculated by the renderer when set to special 'auto' value\n autoHeight: undefined,\n autoPadding: undefined,\n compoundBoundsClean: false,\n // whether the compound dimensions need to be recalculated the next time dimensions are read\n listeners: [],\n // array of bound listeners\n group: group,\n // string; 'nodes' or 'edges'\n style: {},\n // properties as set by the style\n rstyle: {},\n // properties for style sent from the renderer to the core\n styleCxts: [],\n // applied style contexts from the styler\n styleKeys: {},\n // per-group keys of style property values\n removed: true,\n // whether it's inside the vis; true if removed (set true here since we call restore)\n selected: params.selected ? true : false,\n // whether it's selected\n selectable: params.selectable === undefined ? true : params.selectable ? true : false,\n // whether it's selectable\n locked: params.locked ? true : false,\n // whether the element is locked (cannot be moved)\n grabbed: false,\n // whether the element is grabbed by the mouse; renderer sets this privately\n grabbable: params.grabbable === undefined ? true : params.grabbable ? true : false,\n // whether the element can be grabbed\n pannable: params.pannable === undefined ? group === 'edges' ? true : false : params.pannable ? true : false,\n // whether the element has passthrough panning enabled\n active: false,\n // whether the element is active from user interaction\n classes: new Set$1(),\n // map ( className => true )\n animation: {\n // object for currently-running animations\n current: [],\n queue: []\n },\n rscratch: {},\n // object in which the renderer can store information\n scratch: params.scratch || {},\n // scratch objects\n edges: [],\n // array of connected edges\n children: [],\n // array of children\n parent: params.parent && params.parent.isNode() ? params.parent : null,\n // parent ref\n traversalCache: {},\n // cache of output of traversal functions\n backgrounding: false,\n // whether background images are loading\n bbCache: null,\n // cache of the current bounding box\n bbCacheShift: {\n x: 0,\n y: 0\n },\n // shift applied to cached bb to be applied on next get\n bodyBounds: null,\n // bounds cache of element body, w/o overlay\n overlayBounds: null,\n // bounds cache of element body, including overlay\n labelBounds: {\n // bounds cache of labels\n all: null,\n source: null,\n target: null,\n main: null\n },\n arrowBounds: {\n // bounds cache of edge arrows\n source: null,\n target: null,\n 'mid-source': null,\n 'mid-target': null\n }\n };\n if (_p.position.x == null) {\n _p.position.x = 0;\n }\n if (_p.position.y == null) {\n _p.position.y = 0;\n }\n\n // renderedPosition overrides if specified\n if (params.renderedPosition) {\n var rpos = params.renderedPosition;\n var pan = cy.pan();\n var zoom = cy.zoom();\n _p.position = {\n x: (rpos.x - pan.x) / zoom,\n y: (rpos.y - pan.y) / zoom\n };\n }\n var classes = [];\n if (array(params.classes)) {\n classes = params.classes;\n } else if (string(params.classes)) {\n classes = params.classes.split(/\\s+/);\n }\n for (var i = 0, l = classes.length; i < l; i++) {\n var cls = classes[i];\n if (!cls || cls === '') {\n continue;\n }\n _p.classes.add(cls);\n }\n this.createEmitter();\n var bypass = params.style || params.css;\n if (bypass) {\n warn('Setting a `style` bypass at element creation should be done only when absolutely necessary. Try to use the stylesheet instead.');\n this.style(bypass);\n }\n if (restore === undefined || restore) {\n this.restore();\n }\n};\n\nvar defineSearch = function defineSearch(params) {\n params = {\n bfs: params.bfs || !params.dfs,\n dfs: params.dfs || !params.bfs\n };\n\n // from pseudocode on wikipedia\n return function searchFn(roots, fn, directed) {\n var options;\n if (plainObject(roots) && !elementOrCollection(roots)) {\n options = roots;\n roots = options.roots || options.root;\n fn = options.visit;\n directed = options.directed;\n }\n directed = arguments.length === 2 && !fn$6(fn) ? fn : directed;\n fn = fn$6(fn) ? fn : function () {};\n var cy = this._private.cy;\n var v = roots = string(roots) ? this.filter(roots) : roots;\n var Q = [];\n var connectedNodes = [];\n var connectedBy = {};\n var id2depth = {};\n var V = {};\n var j = 0;\n var found;\n var _this$byGroup = this.byGroup(),\n nodes = _this$byGroup.nodes,\n edges = _this$byGroup.edges;\n\n // enqueue v\n for (var i = 0; i < v.length; i++) {\n var vi = v[i];\n var viId = vi.id();\n if (vi.isNode()) {\n Q.unshift(vi);\n if (params.bfs) {\n V[viId] = true;\n connectedNodes.push(vi);\n }\n id2depth[viId] = 0;\n }\n }\n var _loop = function _loop() {\n var v = params.bfs ? Q.shift() : Q.pop();\n var vId = v.id();\n if (params.dfs) {\n if (V[vId]) {\n return \"continue\";\n }\n V[vId] = true;\n connectedNodes.push(v);\n }\n var depth = id2depth[vId];\n var prevEdge = connectedBy[vId];\n var src = prevEdge != null ? prevEdge.source() : null;\n var tgt = prevEdge != null ? prevEdge.target() : null;\n var prevNode = prevEdge == null ? undefined : v.same(src) ? tgt[0] : src[0];\n var ret = void 0;\n ret = fn(v, prevEdge, prevNode, j++, depth);\n if (ret === true) {\n found = v;\n return \"break\";\n }\n if (ret === false) {\n return \"break\";\n }\n var vwEdges = v.connectedEdges().filter(function (e) {\n return (!directed || e.source().same(v)) && edges.has(e);\n });\n for (var _i2 = 0; _i2 < vwEdges.length; _i2++) {\n var e = vwEdges[_i2];\n var w = e.connectedNodes().filter(function (n) {\n return !n.same(v) && nodes.has(n);\n });\n var wId = w.id();\n if (w.length !== 0 && !V[wId]) {\n w = w[0];\n Q.push(w);\n if (params.bfs) {\n V[wId] = true;\n connectedNodes.push(w);\n }\n connectedBy[wId] = e;\n id2depth[wId] = id2depth[vId] + 1;\n }\n }\n };\n while (Q.length !== 0) {\n var _ret = _loop();\n if (_ret === \"continue\") continue;\n if (_ret === \"break\") break;\n }\n var connectedEles = cy.collection();\n for (var _i = 0; _i < connectedNodes.length; _i++) {\n var node = connectedNodes[_i];\n var edge = connectedBy[node.id()];\n if (edge != null) {\n connectedEles.push(edge);\n }\n connectedEles.push(node);\n }\n return {\n path: cy.collection(connectedEles),\n found: cy.collection(found)\n };\n };\n};\n\n// search, spanning trees, etc\nvar elesfn$v = {\n breadthFirstSearch: defineSearch({\n bfs: true\n }),\n depthFirstSearch: defineSearch({\n dfs: true\n })\n};\n\n// nice, short mathematical alias\nelesfn$v.bfs = elesfn$v.breadthFirstSearch;\nelesfn$v.dfs = elesfn$v.depthFirstSearch;\n\nvar heap$1 = createCommonjsModule(function (module, exports) {\n// Generated by CoffeeScript 1.8.0\n(function() {\n var Heap, defaultCmp, floor, heapify, heappop, heappush, heappushpop, heapreplace, insort, min, nlargest, nsmallest, updateItem, _siftdown, _siftup;\n\n floor = Math.floor, min = Math.min;\n\n\n /*\n Default comparison function to be used\n */\n\n defaultCmp = function(x, y) {\n if (x < y) {\n return -1;\n }\n if (x > y) {\n return 1;\n }\n return 0;\n };\n\n\n /*\n Insert item x in list a, and keep it sorted assuming a is sorted.\n \n If x is already in a, insert it to the right of the rightmost x.\n \n Optional args lo (default 0) and hi (default a.length) bound the slice\n of a to be searched.\n */\n\n insort = function(a, x, lo, hi, cmp) {\n var mid;\n if (lo == null) {\n lo = 0;\n }\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (lo < 0) {\n throw new Error('lo must be non-negative');\n }\n if (hi == null) {\n hi = a.length;\n }\n while (lo < hi) {\n mid = floor((lo + hi) / 2);\n if (cmp(x, a[mid]) < 0) {\n hi = mid;\n } else {\n lo = mid + 1;\n }\n }\n return ([].splice.apply(a, [lo, lo - lo].concat(x)), x);\n };\n\n\n /*\n Push item onto heap, maintaining the heap invariant.\n */\n\n heappush = function(array, item, cmp) {\n if (cmp == null) {\n cmp = defaultCmp;\n }\n array.push(item);\n return _siftdown(array, 0, array.length - 1, cmp);\n };\n\n\n /*\n Pop the smallest item off the heap, maintaining the heap invariant.\n */\n\n heappop = function(array, cmp) {\n var lastelt, returnitem;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n lastelt = array.pop();\n if (array.length) {\n returnitem = array[0];\n array[0] = lastelt;\n _siftup(array, 0, cmp);\n } else {\n returnitem = lastelt;\n }\n return returnitem;\n };\n\n\n /*\n Pop and return the current smallest value, and add the new item.\n \n This is more efficient than heappop() followed by heappush(), and can be\n more appropriate when using a fixed size heap. Note that the value\n returned may be larger than item! That constrains reasonable use of\n this routine unless written as part of a conditional replacement:\n if item > array[0]\n item = heapreplace(array, item)\n */\n\n heapreplace = function(array, item, cmp) {\n var returnitem;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n returnitem = array[0];\n array[0] = item;\n _siftup(array, 0, cmp);\n return returnitem;\n };\n\n\n /*\n Fast version of a heappush followed by a heappop.\n */\n\n heappushpop = function(array, item, cmp) {\n var _ref;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (array.length && cmp(array[0], item) < 0) {\n _ref = [array[0], item], item = _ref[0], array[0] = _ref[1];\n _siftup(array, 0, cmp);\n }\n return item;\n };\n\n\n /*\n Transform list into a heap, in-place, in O(array.length) time.\n */\n\n heapify = function(array, cmp) {\n var i, _i, _len, _ref1, _results, _results1;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n _ref1 = (function() {\n _results1 = [];\n for (var _j = 0, _ref = floor(array.length / 2); 0 <= _ref ? _j < _ref : _j > _ref; 0 <= _ref ? _j++ : _j--){ _results1.push(_j); }\n return _results1;\n }).apply(this).reverse();\n _results = [];\n for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n i = _ref1[_i];\n _results.push(_siftup(array, i, cmp));\n }\n return _results;\n };\n\n\n /*\n Update the position of the given item in the heap.\n This function should be called every time the item is being modified.\n */\n\n updateItem = function(array, item, cmp) {\n var pos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n pos = array.indexOf(item);\n if (pos === -1) {\n return;\n }\n _siftdown(array, 0, pos, cmp);\n return _siftup(array, pos, cmp);\n };\n\n\n /*\n Find the n largest elements in a dataset.\n */\n\n nlargest = function(array, n, cmp) {\n var elem, result, _i, _len, _ref;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n result = array.slice(0, n);\n if (!result.length) {\n return result;\n }\n heapify(result, cmp);\n _ref = array.slice(n);\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n elem = _ref[_i];\n heappushpop(result, elem, cmp);\n }\n return result.sort(cmp).reverse();\n };\n\n\n /*\n Find the n smallest elements in a dataset.\n */\n\n nsmallest = function(array, n, cmp) {\n var elem, los, result, _i, _j, _len, _ref, _ref1, _results;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n if (n * 10 <= array.length) {\n result = array.slice(0, n).sort(cmp);\n if (!result.length) {\n return result;\n }\n los = result[result.length - 1];\n _ref = array.slice(n);\n for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n elem = _ref[_i];\n if (cmp(elem, los) < 0) {\n insort(result, elem, 0, null, cmp);\n result.pop();\n los = result[result.length - 1];\n }\n }\n return result;\n }\n heapify(array, cmp);\n _results = [];\n for (_j = 0, _ref1 = min(n, array.length); 0 <= _ref1 ? _j < _ref1 : _j > _ref1; 0 <= _ref1 ? ++_j : --_j) {\n _results.push(heappop(array, cmp));\n }\n return _results;\n };\n\n _siftdown = function(array, startpos, pos, cmp) {\n var newitem, parent, parentpos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n newitem = array[pos];\n while (pos > startpos) {\n parentpos = (pos - 1) >> 1;\n parent = array[parentpos];\n if (cmp(newitem, parent) < 0) {\n array[pos] = parent;\n pos = parentpos;\n continue;\n }\n break;\n }\n return array[pos] = newitem;\n };\n\n _siftup = function(array, pos, cmp) {\n var childpos, endpos, newitem, rightpos, startpos;\n if (cmp == null) {\n cmp = defaultCmp;\n }\n endpos = array.length;\n startpos = pos;\n newitem = array[pos];\n childpos = 2 * pos + 1;\n while (childpos < endpos) {\n rightpos = childpos + 1;\n if (rightpos < endpos && !(cmp(array[childpos], array[rightpos]) < 0)) {\n childpos = rightpos;\n }\n array[pos] = array[childpos];\n pos = childpos;\n childpos = 2 * pos + 1;\n }\n array[pos] = newitem;\n return _siftdown(array, startpos, pos, cmp);\n };\n\n Heap = (function() {\n Heap.push = heappush;\n\n Heap.pop = heappop;\n\n Heap.replace = heapreplace;\n\n Heap.pushpop = heappushpop;\n\n Heap.heapify = heapify;\n\n Heap.updateItem = updateItem;\n\n Heap.nlargest = nlargest;\n\n Heap.nsmallest = nsmallest;\n\n function Heap(cmp) {\n this.cmp = cmp != null ? cmp : defaultCmp;\n this.nodes = [];\n }\n\n Heap.prototype.push = function(x) {\n return heappush(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.pop = function() {\n return heappop(this.nodes, this.cmp);\n };\n\n Heap.prototype.peek = function() {\n return this.nodes[0];\n };\n\n Heap.prototype.contains = function(x) {\n return this.nodes.indexOf(x) !== -1;\n };\n\n Heap.prototype.replace = function(x) {\n return heapreplace(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.pushpop = function(x) {\n return heappushpop(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.heapify = function() {\n return heapify(this.nodes, this.cmp);\n };\n\n Heap.prototype.updateItem = function(x) {\n return updateItem(this.nodes, x, this.cmp);\n };\n\n Heap.prototype.clear = function() {\n return this.nodes = [];\n };\n\n Heap.prototype.empty = function() {\n return this.nodes.length === 0;\n };\n\n Heap.prototype.size = function() {\n return this.nodes.length;\n };\n\n Heap.prototype.clone = function() {\n var heap;\n heap = new Heap();\n heap.nodes = this.nodes.slice(0);\n return heap;\n };\n\n Heap.prototype.toArray = function() {\n return this.nodes.slice(0);\n };\n\n Heap.prototype.insert = Heap.prototype.push;\n\n Heap.prototype.top = Heap.prototype.peek;\n\n Heap.prototype.front = Heap.prototype.peek;\n\n Heap.prototype.has = Heap.prototype.contains;\n\n Heap.prototype.copy = Heap.prototype.clone;\n\n return Heap;\n\n })();\n\n (function(root, factory) {\n {\n return module.exports = factory();\n }\n })(this, function() {\n return Heap;\n });\n\n}).call(commonjsGlobal);\n});\n\nvar heap = heap$1;\n\nvar dijkstraDefaults = defaults$g({\n root: null,\n weight: function weight(edge) {\n return 1;\n },\n directed: false\n});\nvar elesfn$u = {\n dijkstra: function dijkstra(options) {\n if (!plainObject(options)) {\n var args = arguments;\n options = {\n root: args[0],\n weight: args[1],\n directed: args[2]\n };\n }\n var _dijkstraDefaults = dijkstraDefaults(options),\n root = _dijkstraDefaults.root,\n weight = _dijkstraDefaults.weight,\n directed = _dijkstraDefaults.directed;\n var eles = this;\n var weightFn = weight;\n var source = string(root) ? this.filter(root)[0] : root[0];\n var dist = {};\n var prev = {};\n var knownDist = {};\n var _this$byGroup = this.byGroup(),\n nodes = _this$byGroup.nodes,\n edges = _this$byGroup.edges;\n edges.unmergeBy(function (ele) {\n return ele.isLoop();\n });\n var getDist = function getDist(node) {\n return dist[node.id()];\n };\n var setDist = function setDist(node, d) {\n dist[node.id()] = d;\n Q.updateItem(node);\n };\n var Q = new heap(function (a, b) {\n return getDist(a) - getDist(b);\n });\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n dist[node.id()] = node.same(source) ? 0 : Infinity;\n Q.push(node);\n }\n var distBetween = function distBetween(u, v) {\n var uvs = (directed ? u.edgesTo(v) : u.edgesWith(v)).intersect(edges);\n var smallestDistance = Infinity;\n var smallestEdge;\n for (var _i = 0; _i < uvs.length; _i++) {\n var edge = uvs[_i];\n var _weight = weightFn(edge);\n if (_weight < smallestDistance || !smallestEdge) {\n smallestDistance = _weight;\n smallestEdge = edge;\n }\n }\n return {\n edge: smallestEdge,\n dist: smallestDistance\n };\n };\n while (Q.size() > 0) {\n var u = Q.pop();\n var smalletsDist = getDist(u);\n var uid = u.id();\n knownDist[uid] = smalletsDist;\n if (smalletsDist === Infinity) {\n continue;\n }\n var neighbors = u.neighborhood().intersect(nodes);\n for (var _i2 = 0; _i2 < neighbors.length; _i2++) {\n var v = neighbors[_i2];\n var vid = v.id();\n var vDist = distBetween(u, v);\n var alt = smalletsDist + vDist.dist;\n if (alt < getDist(v)) {\n setDist(v, alt);\n prev[vid] = {\n node: u,\n edge: vDist.edge\n };\n }\n } // for\n } // while\n\n return {\n distanceTo: function distanceTo(node) {\n var target = string(node) ? nodes.filter(node)[0] : node[0];\n return knownDist[target.id()];\n },\n pathTo: function pathTo(node) {\n var target = string(node) ? nodes.filter(node)[0] : node[0];\n var S = [];\n var u = target;\n var uid = u.id();\n if (target.length > 0) {\n S.unshift(target);\n while (prev[uid]) {\n var p = prev[uid];\n S.unshift(p.edge);\n S.unshift(p.node);\n u = p.node;\n uid = u.id();\n }\n }\n return eles.spawn(S);\n }\n };\n }\n};\n\nvar elesfn$t = {\n // kruskal's algorithm (finds min spanning tree, assuming undirected graph)\n // implemented from pseudocode from wikipedia\n kruskal: function kruskal(weightFn) {\n weightFn = weightFn || function (edge) {\n return 1;\n };\n var _this$byGroup = this.byGroup(),\n nodes = _this$byGroup.nodes,\n edges = _this$byGroup.edges;\n var numNodes = nodes.length;\n var forest = new Array(numNodes);\n var A = nodes; // assumes byGroup() creates new collections that can be safely mutated\n\n var findSetIndex = function findSetIndex(ele) {\n for (var i = 0; i < forest.length; i++) {\n var eles = forest[i];\n if (eles.has(ele)) {\n return i;\n }\n }\n };\n\n // start with one forest per node\n for (var i = 0; i < numNodes; i++) {\n forest[i] = this.spawn(nodes[i]);\n }\n var S = edges.sort(function (a, b) {\n return weightFn(a) - weightFn(b);\n });\n for (var _i = 0; _i < S.length; _i++) {\n var edge = S[_i];\n var u = edge.source()[0];\n var v = edge.target()[0];\n var setUIndex = findSetIndex(u);\n var setVIndex = findSetIndex(v);\n var setU = forest[setUIndex];\n var setV = forest[setVIndex];\n if (setUIndex !== setVIndex) {\n A.merge(edge);\n\n // combine forests for u and v\n setU.merge(setV);\n forest.splice(setVIndex, 1);\n }\n }\n return A;\n }\n};\n\nvar aStarDefaults = defaults$g({\n root: null,\n goal: null,\n weight: function weight(edge) {\n return 1;\n },\n heuristic: function heuristic(edge) {\n return 0;\n },\n directed: false\n});\nvar elesfn$s = {\n // Implemented from pseudocode from wikipedia\n aStar: function aStar(options) {\n var cy = this.cy();\n var _aStarDefaults = aStarDefaults(options),\n root = _aStarDefaults.root,\n goal = _aStarDefaults.goal,\n heuristic = _aStarDefaults.heuristic,\n directed = _aStarDefaults.directed,\n weight = _aStarDefaults.weight;\n root = cy.collection(root)[0];\n goal = cy.collection(goal)[0];\n var sid = root.id();\n var tid = goal.id();\n var gScore = {};\n var fScore = {};\n var closedSetIds = {};\n var openSet = new heap(function (a, b) {\n return fScore[a.id()] - fScore[b.id()];\n });\n var openSetIds = new Set$1();\n var cameFrom = {};\n var cameFromEdge = {};\n var addToOpenSet = function addToOpenSet(ele, id) {\n openSet.push(ele);\n openSetIds.add(id);\n };\n var cMin, cMinId;\n var popFromOpenSet = function popFromOpenSet() {\n cMin = openSet.pop();\n cMinId = cMin.id();\n openSetIds[\"delete\"](cMinId);\n };\n var isInOpenSet = function isInOpenSet(id) {\n return openSetIds.has(id);\n };\n addToOpenSet(root, sid);\n gScore[sid] = 0;\n fScore[sid] = heuristic(root);\n\n // Counter\n var steps = 0;\n\n // Main loop\n while (openSet.size() > 0) {\n popFromOpenSet();\n steps++;\n\n // If we've found our goal, then we are done\n if (cMinId === tid) {\n var path = [];\n var pathNode = goal;\n var pathNodeId = tid;\n var pathEdge = cameFromEdge[pathNodeId];\n for (;;) {\n path.unshift(pathNode);\n if (pathEdge != null) {\n path.unshift(pathEdge);\n }\n pathNode = cameFrom[pathNodeId];\n if (pathNode == null) {\n break;\n }\n pathNodeId = pathNode.id();\n pathEdge = cameFromEdge[pathNodeId];\n }\n return {\n found: true,\n distance: gScore[cMinId],\n path: this.spawn(path),\n steps: steps\n };\n }\n\n // Add cMin to processed nodes\n closedSetIds[cMinId] = true;\n\n // Update scores for neighbors of cMin\n // Take into account if graph is directed or not\n var vwEdges = cMin._private.edges;\n for (var i = 0; i < vwEdges.length; i++) {\n var e = vwEdges[i];\n\n // edge must be in set of calling eles\n if (!this.hasElementWithId(e.id())) {\n continue;\n }\n\n // cMin must be the source of edge if directed\n if (directed && e.data('source') !== cMinId) {\n continue;\n }\n var wSrc = e.source();\n var wTgt = e.target();\n var w = wSrc.id() !== cMinId ? wSrc : wTgt;\n var wid = w.id();\n\n // node must be in set of calling eles\n if (!this.hasElementWithId(wid)) {\n continue;\n }\n\n // if node is in closedSet, ignore it\n if (closedSetIds[wid]) {\n continue;\n }\n\n // New tentative score for node w\n var tempScore = gScore[cMinId] + weight(e);\n\n // Update gScore for node w if:\n // w not present in openSet\n // OR\n // tentative gScore is less than previous value\n\n // w not in openSet\n if (!isInOpenSet(wid)) {\n gScore[wid] = tempScore;\n fScore[wid] = tempScore + heuristic(w);\n addToOpenSet(w, wid);\n cameFrom[wid] = cMin;\n cameFromEdge[wid] = e;\n continue;\n }\n\n // w already in openSet, but with greater gScore\n if (tempScore < gScore[wid]) {\n gScore[wid] = tempScore;\n fScore[wid] = tempScore + heuristic(w);\n cameFrom[wid] = cMin;\n cameFromEdge[wid] = e;\n }\n } // End of neighbors update\n } // End of main loop\n\n // If we've reached here, then we've not reached our goal\n return {\n found: false,\n distance: undefined,\n path: undefined,\n steps: steps\n };\n }\n}; // elesfn\n\nvar floydWarshallDefaults = defaults$g({\n weight: function weight(edge) {\n return 1;\n },\n directed: false\n});\nvar elesfn$r = {\n // Implemented from pseudocode from wikipedia\n floydWarshall: function floydWarshall(options) {\n var cy = this.cy();\n var _floydWarshallDefault = floydWarshallDefaults(options),\n weight = _floydWarshallDefault.weight,\n directed = _floydWarshallDefault.directed;\n var weightFn = weight;\n var _this$byGroup = this.byGroup(),\n nodes = _this$byGroup.nodes,\n edges = _this$byGroup.edges;\n var N = nodes.length;\n var Nsq = N * N;\n var indexOf = function indexOf(node) {\n return nodes.indexOf(node);\n };\n var atIndex = function atIndex(i) {\n return nodes[i];\n };\n\n // Initialize distance matrix\n var dist = new Array(Nsq);\n for (var n = 0; n < Nsq; n++) {\n var j = n % N;\n var i = (n - j) / N;\n if (i === j) {\n dist[n] = 0;\n } else {\n dist[n] = Infinity;\n }\n }\n\n // Initialize matrix used for path reconstruction\n // Initialize distance matrix\n var next = new Array(Nsq);\n var edgeNext = new Array(Nsq);\n\n // Process edges\n for (var _i = 0; _i < edges.length; _i++) {\n var edge = edges[_i];\n var src = edge.source()[0];\n var tgt = edge.target()[0];\n if (src === tgt) {\n continue;\n } // exclude loops\n\n var s = indexOf(src);\n var t = indexOf(tgt);\n var st = s * N + t; // source to target index\n var _weight = weightFn(edge);\n\n // Check if already process another edge between same 2 nodes\n if (dist[st] > _weight) {\n dist[st] = _weight;\n next[st] = t;\n edgeNext[st] = edge;\n }\n\n // If undirected graph, process 'reversed' edge\n if (!directed) {\n var ts = t * N + s; // target to source index\n\n if (!directed && dist[ts] > _weight) {\n dist[ts] = _weight;\n next[ts] = s;\n edgeNext[ts] = edge;\n }\n }\n }\n\n // Main loop\n for (var k = 0; k < N; k++) {\n for (var _i2 = 0; _i2 < N; _i2++) {\n var ik = _i2 * N + k;\n for (var _j = 0; _j < N; _j++) {\n var ij = _i2 * N + _j;\n var kj = k * N + _j;\n if (dist[ik] + dist[kj] < dist[ij]) {\n dist[ij] = dist[ik] + dist[kj];\n next[ij] = next[ik];\n }\n }\n }\n }\n var getArgEle = function getArgEle(ele) {\n return (string(ele) ? cy.filter(ele) : ele)[0];\n };\n var indexOfArgEle = function indexOfArgEle(ele) {\n return indexOf(getArgEle(ele));\n };\n var res = {\n distance: function distance(from, to) {\n var i = indexOfArgEle(from);\n var j = indexOfArgEle(to);\n return dist[i * N + j];\n },\n path: function path(from, to) {\n var i = indexOfArgEle(from);\n var j = indexOfArgEle(to);\n var fromNode = atIndex(i);\n if (i === j) {\n return fromNode.collection();\n }\n if (next[i * N + j] == null) {\n return cy.collection();\n }\n var path = cy.collection();\n var prev = i;\n var edge;\n path.merge(fromNode);\n while (i !== j) {\n prev = i;\n i = next[i * N + j];\n edge = edgeNext[prev * N + i];\n path.merge(edge);\n path.merge(atIndex(i));\n }\n return path;\n }\n };\n return res;\n } // floydWarshall\n}; // elesfn\n\nvar bellmanFordDefaults = defaults$g({\n weight: function weight(edge) {\n return 1;\n },\n directed: false,\n root: null\n});\nvar elesfn$q = {\n // Implemented from pseudocode from wikipedia\n bellmanFord: function bellmanFord(options) {\n var _this = this;\n var _bellmanFordDefaults = bellmanFordDefaults(options),\n weight = _bellmanFordDefaults.weight,\n directed = _bellmanFordDefaults.directed,\n root = _bellmanFordDefaults.root;\n var weightFn = weight;\n var eles = this;\n var cy = this.cy();\n var _this$byGroup = this.byGroup(),\n edges = _this$byGroup.edges,\n nodes = _this$byGroup.nodes;\n var numNodes = nodes.length;\n var infoMap = new Map$2();\n var hasNegativeWeightCycle = false;\n var negativeWeightCycles = [];\n root = cy.collection(root)[0]; // in case selector passed\n\n edges.unmergeBy(function (edge) {\n return edge.isLoop();\n });\n var numEdges = edges.length;\n var getInfo = function getInfo(node) {\n var obj = infoMap.get(node.id());\n if (!obj) {\n obj = {};\n infoMap.set(node.id(), obj);\n }\n return obj;\n };\n var getNodeFromTo = function getNodeFromTo(to) {\n return (string(to) ? cy.$(to) : to)[0];\n };\n var distanceTo = function distanceTo(to) {\n return getInfo(getNodeFromTo(to)).dist;\n };\n var pathTo = function pathTo(to) {\n var thisStart = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : root;\n var end = getNodeFromTo(to);\n var path = [];\n var node = end;\n for (;;) {\n if (node == null) {\n return _this.spawn();\n }\n var _getInfo = getInfo(node),\n edge = _getInfo.edge,\n pred = _getInfo.pred;\n path.unshift(node[0]);\n if (node.same(thisStart) && path.length > 0) {\n break;\n }\n if (edge != null) {\n path.unshift(edge);\n }\n node = pred;\n }\n return eles.spawn(path);\n };\n\n // Initializations { dist, pred, edge }\n for (var i = 0; i < numNodes; i++) {\n var node = nodes[i];\n var info = getInfo(node);\n if (node.same(root)) {\n info.dist = 0;\n } else {\n info.dist = Infinity;\n }\n info.pred = null;\n info.edge = null;\n }\n\n // Edges relaxation\n var replacedEdge = false;\n var checkForEdgeReplacement = function checkForEdgeReplacement(node1, node2, edge, info1, info2, weight) {\n var dist = info1.dist + weight;\n if (dist < info2.dist && !edge.same(info1.edge)) {\n info2.dist = dist;\n info2.pred = node1;\n info2.edge = edge;\n replacedEdge = true;\n }\n };\n for (var _i = 1; _i < numNodes; _i++) {\n replacedEdge = false;\n for (var e = 0; e < numEdges; e++) {\n var edge = edges[e];\n var src = edge.source();\n var tgt = edge.target();\n var _weight = weightFn(edge);\n var srcInfo = getInfo(src);\n var tgtInfo = getInfo(tgt);\n checkForEdgeReplacement(src, tgt, edge, srcInfo, tgtInfo, _weight);\n\n // If undirected graph, we need to take into account the 'reverse' edge\n if (!directed) {\n checkForEdgeReplacement(tgt, src, edge, tgtInfo, srcInfo, _weight);\n }\n }\n if (!replacedEdge) {\n break;\n }\n }\n if (replacedEdge) {\n // Check for negative weight cycles\n var negativeWeightCycleIds = [];\n for (var _e = 0; _e < numEdges; _e++) {\n var _edge = edges[_e];\n var _src = _edge.source();\n var _tgt = _edge.target();\n var _weight2 = weightFn(_edge);\n var srcDist = getInfo(_src).dist;\n var tgtDist = getInfo(_tgt).dist;\n if (srcDist + _weight2 < tgtDist || !directed && tgtDist + _weight2 < srcDist) {\n if (!hasNegativeWeightCycle) {\n warn('Graph contains a negative weight cycle for Bellman-Ford');\n hasNegativeWeightCycle = true;\n }\n if (options.findNegativeWeightCycles !== false) {\n var negativeNodes = [];\n if (srcDist + _weight2 < tgtDist) {\n negativeNodes.push(_src);\n }\n if (!directed && tgtDist + _weight2 < srcDist) {\n negativeNodes.push(_tgt);\n }\n var numNegativeNodes = negativeNodes.length;\n for (var n = 0; n < numNegativeNodes; n++) {\n var start = negativeNodes[n];\n var cycle = [start];\n cycle.push(getInfo(start).edge);\n var _node = getInfo(start).pred;\n while (cycle.indexOf(_node) === -1) {\n cycle.push(_node);\n cycle.push(getInfo(_node).edge);\n _node = getInfo(_node).pred;\n }\n cycle = cycle.slice(cycle.indexOf(_node));\n var smallestId = cycle[0].id();\n var smallestIndex = 0;\n for (var c = 2; c < cycle.length; c += 2) {\n if (cycle[c].id() < smallestId) {\n smallestId = cycle[c].id();\n smallestIndex = c;\n }\n }\n cycle = cycle.slice(smallestIndex).concat(cycle.slice(0, smallestIndex));\n cycle.push(cycle[0]);\n var cycleId = cycle.map(function (el) {\n return el.id();\n }).join(\",\");\n if (negativeWeightCycleIds.indexOf(cycleId) === -1) {\n negativeWeightCycles.push(eles.spawn(cycle));\n negativeWeightCycleIds.push(cycleId);\n }\n }\n } else {\n break;\n }\n }\n }\n }\n return {\n distanceTo: distanceTo,\n pathTo: pathTo,\n hasNegativeWeightCycle: hasNegativeWeightCycle,\n negativeWeightCycles: negativeWeightCycles\n };\n } // bellmanFord\n}; // elesfn\n\nvar sqrt2 = Math.sqrt(2);\n\n// Function which colapses 2 (meta) nodes into one\n// Updates the remaining edge lists\n// Receives as a paramater the edge which causes the collapse\nvar collapse = function collapse(edgeIndex, nodeMap, remainingEdges) {\n if (remainingEdges.length === 0) {\n error(\"Karger-Stein must be run on a connected (sub)graph\");\n }\n var edgeInfo = remainingEdges[edgeIndex];\n var sourceIn = edgeInfo[1];\n var targetIn = edgeInfo[2];\n var partition1 = nodeMap[sourceIn];\n var partition2 = nodeMap[targetIn];\n var newEdges = remainingEdges; // re-use array\n\n // Delete all edges between partition1 and partition2\n for (var i = newEdges.length - 1; i >= 0; i--) {\n var edge = newEdges[i];\n var src = edge[1];\n var tgt = edge[2];\n if (nodeMap[src] === partition1 && nodeMap[tgt] === partition2 || nodeMap[src] === partition2 && nodeMap[tgt] === partition1) {\n newEdges.splice(i, 1);\n }\n }\n\n // All edges pointing to partition2 should now point to partition1\n for (var _i = 0; _i < newEdges.length; _i++) {\n var _edge = newEdges[_i];\n if (_edge[1] === partition2) {\n // Check source\n newEdges[_i] = _edge.slice(); // copy\n newEdges[_i][1] = partition1;\n } else if (_edge[2] === partition2) {\n // Check target\n newEdges[_i] = _edge.slice(); // copy\n newEdges[_i][2] = partition1;\n }\n }\n\n // Move all nodes from partition2 to partition1\n for (var _i2 = 0; _i2 < nodeMap.length; _i2++) {\n if (nodeMap[_i2] === partition2) {\n nodeMap[_i2] = partition1;\n }\n }\n return newEdges;\n};\n\n// Contracts a graph until we reach a certain number of meta nodes\nvar contractUntil = function contractUntil(metaNodeMap, remainingEdges, size, sizeLimit) {\n while (size > sizeLimit) {\n // Choose an edge randomly\n var edgeIndex = Math.floor(Math.random() * remainingEdges.length);\n\n // Collapse graph based on edge\n remainingEdges = collapse(edgeIndex, metaNodeMap, remainingEdges);\n size--;\n }\n return remainingEdges;\n};\nvar elesfn$p = {\n // Computes the minimum cut of an undirected graph\n // Returns the correct answer with high probability\n kargerStein: function kargerStein() {\n var _this = this;\n var _this$byGroup = this.byGroup(),\n nodes = _this$byGroup.nodes,\n edges = _this$byGroup.edges;\n edges.unmergeBy(function (edge) {\n return edge.isLoop();\n });\n var numNodes = nodes.length;\n var numEdges = edges.length;\n var numIter = Math.ceil(Math.pow(Math.log(numNodes) / Math.LN2, 2));\n var stopSize = Math.floor(numNodes / sqrt2);\n if (numNodes < 2) {\n error('At least 2 nodes are required for Karger-Stein algorithm');\n return undefined;\n }\n\n // Now store edge destination as indexes\n // Format for each edge (edge index, source node index, target node index)\n var edgeIndexes = [];\n for (var i = 0; i < numEdges; i++) {\n var e = edges[i];\n edgeIndexes.push([i, nodes.indexOf(e.source()), nodes.indexOf(e.target())]);\n }\n\n // We will store the best cut found here\n var minCutSize = Infinity;\n var minCutEdgeIndexes = [];\n var minCutNodeMap = new Array(numNodes);\n\n // Initial meta node partition\n var metaNodeMap = new Array(numNodes);\n var metaNodeMap2 = new Array(numNodes);\n var copyNodesMap = function copyNodesMap(from, to) {\n for (var _i3 = 0; _i3 < numNodes; _i3++) {\n to[_i3] = from[_i3];\n }\n };\n\n // Main loop\n for (var iter = 0; iter <= numIter; iter++) {\n // Reset meta node partition\n for (var _i4 = 0; _i4 < numNodes; _i4++) {\n metaNodeMap[_i4] = _i4;\n }\n\n // Contract until stop point (stopSize nodes)\n var edgesState = contractUntil(metaNodeMap, edgeIndexes.slice(), numNodes, stopSize);\n var edgesState2 = edgesState.slice(); // copy\n\n // Create a copy of the colapsed nodes state\n copyNodesMap(metaNodeMap, metaNodeMap2);\n\n // Run 2 iterations starting in the stop state\n var res1 = contractUntil(metaNodeMap, edgesState, stopSize, 2);\n var res2 = contractUntil(metaNodeMap2, edgesState2, stopSize, 2);\n\n // Is any of the 2 results the best cut so far?\n if (res1.length <= res2.length && res1.length < minCutSize) {\n minCutSize = res1.length;\n minCutEdgeIndexes = res1;\n copyNodesMap(metaNodeMap, minCutNodeMap);\n } else if (res2.length <= res1.length && res2.length < minCutSize) {\n minCutSize = res2.length;\n minCutEdgeIndexes = res2;\n copyNodesMap(metaNodeMap2, minCutNodeMap);\n }\n } // end of main loop\n\n // Construct result\n var cut = this.spawn(minCutEdgeIndexes.map(function (e) {\n return edges[e[0]];\n }));\n var partition1 = this.spawn();\n var partition2 = this.spawn();\n\n // traverse metaNodeMap for best cut\n var witnessNodePartition = minCutNodeMap[0];\n for (var _i5 = 0; _i5 < minCutNodeMap.length; _i5++) {\n var partitionId = minCutNodeMap[_i5];\n var node = nodes[_i5];\n if (partitionId === witnessNodePartition) {\n partition1.merge(node);\n } else {\n partition2.merge(node);\n }\n }\n\n // construct components corresponding to each disjoint subset of nodes\n var constructComponent = function constructComponent(subset) {\n var component = _this.spawn();\n subset.forEach(function (node) {\n component.merge(node);\n node.connectedEdges().forEach(function (edge) {\n // ensure edge is within calling collection and edge is not in cut\n if (_this.contains(edge) && !cut.contains(edge)) {\n component.merge(edge);\n }\n });\n });\n return component;\n };\n var components = [constructComponent(partition1), constructComponent(partition2)];\n var ret = {\n cut: cut,\n components: components,\n // n.b. partitions are included to be compatible with the old api spec\n // (could be removed in a future major version)\n partition1: partition1,\n partition2: partition2\n };\n return ret;\n }\n}; // elesfn\n\nvar copyPosition = function copyPosition(p) {\n return {\n x: p.x,\n y: p.y\n };\n};\nvar modelToRenderedPosition = function modelToRenderedPosition(p, zoom, pan) {\n return {\n x: p.x * zoom + pan.x,\n y: p.y * zoom + pan.y\n };\n};\nvar renderedToModelPosition = function renderedToModelPosition(p, zoom, pan) {\n return {\n x: (p.x - pan.x) / zoom,\n y: (p.y - pan.y) / zoom\n };\n};\nvar array2point = function array2point(arr) {\n return {\n x: arr[0],\n y: arr[1]\n };\n};\nvar min = function min(arr) {\n var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;\n var min = Infinity;\n for (var i = begin; i < end; i++) {\n var val = arr[i];\n if (isFinite(val)) {\n min = Math.min(val, min);\n }\n }\n return min;\n};\nvar max = function max(arr) {\n var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;\n var max = -Infinity;\n for (var i = begin; i < end; i++) {\n var val = arr[i];\n if (isFinite(val)) {\n max = Math.max(val, max);\n }\n }\n return max;\n};\nvar mean = function mean(arr) {\n var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;\n var total = 0;\n var n = 0;\n for (var i = begin; i < end; i++) {\n var val = arr[i];\n if (isFinite(val)) {\n total += val;\n n++;\n }\n }\n return total / n;\n};\nvar median = function median(arr) {\n var begin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n var end = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : arr.length;\n var copy = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n var sort = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n var includeHoles = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;\n if (copy) {\n arr = arr.slice(begin, end);\n } else {\n if (end < arr.length) {\n arr.splice(end, arr.length - end);\n }\n if (begin > 0) {\n arr.splice(0, begin);\n }\n }\n\n // all non finite (e.g. Infinity, NaN) elements must be -Infinity so they go to the start\n var off = 0; // offset from non-finite values\n for (var i = arr.length - 1; i >= 0; i--) {\n var v = arr[i];\n if (includeHoles) {\n if (!isFinite(v)) {\n arr[i] = -Infinity;\n off++;\n }\n } else {\n // just remove it if we don't want to consider holes\n arr.splice(i, 1);\n }\n }\n if (sort) {\n arr.sort(function (a, b) {\n return a - b;\n }); // requires copy = true if you don't want to change the orig\n }\n\n var len = arr.length;\n var mid = Math.floor(len / 2);\n if (len % 2 !== 0) {\n return arr[mid + 1 + off];\n } else {\n return (arr[mid - 1 + off] + arr[mid + off]) / 2;\n }\n};\nvar deg2rad = function deg2rad(deg) {\n return Math.PI * deg / 180;\n};\nvar getAngleFromDisp = function getAngleFromDisp(dispX, dispY) {\n return Math.atan2(dispY, dispX) - Math.PI / 2;\n};\nvar log2 = Math.log2 || function (n) {\n return Math.log(n) / Math.log(2);\n};\nvar signum = function signum(x) {\n if (x > 0) {\n return 1;\n } else if (x < 0) {\n return -1;\n } else {\n return 0;\n }\n};\nvar dist = function dist(p1, p2) {\n return Math.sqrt(sqdist(p1, p2));\n};\nvar sqdist = function sqdist(p1, p2) {\n var dx = p2.x - p1.x;\n var dy = p2.y - p1.y;\n return dx * dx + dy * dy;\n};\nvar inPlaceSumNormalize = function inPlaceSumNormalize(v) {\n var length = v.length;\n\n // First, get sum of all elements\n var total = 0;\n for (var i = 0; i < length; i++) {\n total += v[i];\n }\n\n // Now, divide each by the sum of all elements\n for (var _i = 0; _i < length; _i++) {\n v[_i] = v[_i] / total;\n }\n return v;\n};\n\n// from http://en.wikipedia.org/wiki/B\u00E9zier_curve#Quadratic_curves\nvar qbezierAt = function qbezierAt(p0, p1, p2, t) {\n return (1 - t) * (1 - t) * p0 + 2 * (1 - t) * t * p1 + t * t * p2;\n};\nvar qbezierPtAt = function qbezierPtAt(p0, p1, p2, t) {\n return {\n x: qbezierAt(p0.x, p1.x, p2.x, t),\n y: qbezierAt(p0.y, p1.y, p2.y, t)\n };\n};\nvar lineAt = function lineAt(p0, p1, t, d) {\n var vec = {\n x: p1.x - p0.x,\n y: p1.y - p0.y\n };\n var vecDist = dist(p0, p1);\n var normVec = {\n x: vec.x / vecDist,\n y: vec.y / vecDist\n };\n t = t == null ? 0 : t;\n d = d != null ? d : t * vecDist;\n return {\n x: p0.x + normVec.x * d,\n y: p0.y + normVec.y * d\n };\n};\nvar bound = function bound(min, val, max) {\n return Math.max(min, Math.min(max, val));\n};\n\n// makes a full bb (x1, y1, x2, y2, w, h) from implicit params\nvar makeBoundingBox = function makeBoundingBox(bb) {\n if (bb == null) {\n return {\n x1: Infinity,\n y1: Infinity,\n x2: -Infinity,\n y2: -Infinity,\n w: 0,\n h: 0\n };\n } else if (bb.x1 != null && bb.y1 != null) {\n if (bb.x2 != null && bb.y2 != null && bb.x2 >= bb.x1 && bb.y2 >= bb.y1) {\n return {\n x1: bb.x1,\n y1: bb.y1,\n x2: bb.x2,\n y2: bb.y2,\n w: bb.x2 - bb.x1,\n h: bb.y2 - bb.y1\n };\n } else if (bb.w != null && bb.h != null && bb.w >= 0 && bb.h >= 0) {\n return {\n x1: bb.x1,\n y1: bb.y1,\n x2: bb.x1 + bb.w,\n y2: bb.y1 + bb.h,\n w: bb.w,\n h: bb.h\n };\n }\n }\n};\nvar copyBoundingBox = function copyBoundingBox(bb) {\n return {\n x1: bb.x1,\n x2: bb.x2,\n w: bb.w,\n y1: bb.y1,\n y2: bb.y2,\n h: bb.h\n };\n};\nvar clearBoundingBox = function clearBoundingBox(bb) {\n bb.x1 = Infinity;\n bb.y1 = Infinity;\n bb.x2 = -Infinity;\n bb.y2 = -Infinity;\n bb.w = 0;\n bb.h = 0;\n};\nvar shiftBoundingBox = function shiftBoundingBox(bb, dx, dy) {\n return {\n x1: bb.x1 + dx,\n x2: bb.x2 + dx,\n y1: bb.y1 + dy,\n y2: bb.y2 + dy,\n w: bb.w,\n h: bb.h\n };\n};\nvar updateBoundingBox = function updateBoundingBox(bb1, bb2) {\n // update bb1 with bb2 bounds\n\n bb1.x1 = Math.min(bb1.x1, bb2.x1);\n bb1.x2 = Math.max(bb1.x2, bb2.x2);\n bb1.w = bb1.x2 - bb1.x1;\n bb1.y1 = Math.min(bb1.y1, bb2.y1);\n bb1.y2 = Math.max(bb1.y2, bb2.y2);\n bb1.h = bb1.y2 - bb1.y1;\n};\nvar expandBoundingBoxByPoint = function expandBoundingBoxByPoint(bb, x, y) {\n bb.x1 = Math.min(bb.x1, x);\n bb.x2 = Math.max(bb.x2, x);\n bb.w = bb.x2 - bb.x1;\n bb.y1 = Math.min(bb.y1, y);\n bb.y2 = Math.max(bb.y2, y);\n bb.h = bb.y2 - bb.y1;\n};\nvar expandBoundingBox = function expandBoundingBox(bb) {\n var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;\n bb.x1 -= padding;\n bb.x2 += padding;\n bb.y1 -= padding;\n bb.y2 += padding;\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n return bb;\n};\nvar expandBoundingBoxSides = function expandBoundingBoxSides(bb) {\n var padding = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [0];\n var top, right, bottom, left;\n if (padding.length === 1) {\n top = right = bottom = left = padding[0];\n } else if (padding.length === 2) {\n top = bottom = padding[0];\n left = right = padding[1];\n } else if (padding.length === 4) {\n var _padding = _slicedToArray(padding, 4);\n top = _padding[0];\n right = _padding[1];\n bottom = _padding[2];\n left = _padding[3];\n }\n bb.x1 -= left;\n bb.x2 += right;\n bb.y1 -= top;\n bb.y2 += bottom;\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n return bb;\n};\n\n// assign the values of bb2 into bb1\nvar assignBoundingBox = function assignBoundingBox(bb1, bb2) {\n bb1.x1 = bb2.x1;\n bb1.y1 = bb2.y1;\n bb1.x2 = bb2.x2;\n bb1.y2 = bb2.y2;\n bb1.w = bb1.x2 - bb1.x1;\n bb1.h = bb1.y2 - bb1.y1;\n};\nvar boundingBoxesIntersect = function boundingBoxesIntersect(bb1, bb2) {\n // case: one bb to right of other\n if (bb1.x1 > bb2.x2) {\n return false;\n }\n if (bb2.x1 > bb1.x2) {\n return false;\n }\n\n // case: one bb to left of other\n if (bb1.x2 < bb2.x1) {\n return false;\n }\n if (bb2.x2 < bb1.x1) {\n return false;\n }\n\n // case: one bb above other\n if (bb1.y2 < bb2.y1) {\n return false;\n }\n if (bb2.y2 < bb1.y1) {\n return false;\n }\n\n // case: one bb below other\n if (bb1.y1 > bb2.y2) {\n return false;\n }\n if (bb2.y1 > bb1.y2) {\n return false;\n }\n\n // otherwise, must have some overlap\n return true;\n};\nvar inBoundingBox = function inBoundingBox(bb, x, y) {\n return bb.x1 <= x && x <= bb.x2 && bb.y1 <= y && y <= bb.y2;\n};\nvar pointInBoundingBox = function pointInBoundingBox(bb, pt) {\n return inBoundingBox(bb, pt.x, pt.y);\n};\nvar boundingBoxInBoundingBox = function boundingBoxInBoundingBox(bb1, bb2) {\n return inBoundingBox(bb1, bb2.x1, bb2.y1) && inBoundingBox(bb1, bb2.x2, bb2.y2);\n};\nvar roundRectangleIntersectLine = function roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding) {\n var radius = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : 'auto';\n var cornerRadius = radius === 'auto' ? getRoundRectangleRadius(width, height) : radius;\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n cornerRadius = Math.min(cornerRadius, halfWidth, halfHeight);\n var doWidth = cornerRadius !== halfWidth,\n doHeight = cornerRadius !== halfHeight;\n\n // Check intersections with straight line segments\n var straightLineIntersections;\n\n // Top segment, left to right\n if (doWidth) {\n var topStartX = nodeX - halfWidth + cornerRadius - padding;\n var topStartY = nodeY - halfHeight - padding;\n var topEndX = nodeX + halfWidth - cornerRadius + padding;\n var topEndY = topStartY;\n straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false);\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Right segment, top to bottom\n if (doHeight) {\n var rightStartX = nodeX + halfWidth + padding;\n var rightStartY = nodeY - halfHeight + cornerRadius - padding;\n var rightEndX = rightStartX;\n var rightEndY = nodeY + halfHeight - cornerRadius + padding;\n straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, rightStartX, rightStartY, rightEndX, rightEndY, false);\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Bottom segment, left to right\n if (doWidth) {\n var bottomStartX = nodeX - halfWidth + cornerRadius - padding;\n var bottomStartY = nodeY + halfHeight + padding;\n var bottomEndX = nodeX + halfWidth - cornerRadius + padding;\n var bottomEndY = bottomStartY;\n straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, bottomStartX, bottomStartY, bottomEndX, bottomEndY, false);\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Left segment, top to bottom\n if (doHeight) {\n var leftStartX = nodeX - halfWidth - padding;\n var leftStartY = nodeY - halfHeight + cornerRadius - padding;\n var leftEndX = leftStartX;\n var leftEndY = nodeY + halfHeight - cornerRadius + padding;\n straightLineIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, leftStartX, leftStartY, leftEndX, leftEndY, false);\n if (straightLineIntersections.length > 0) {\n return straightLineIntersections;\n }\n }\n\n // Check intersections with arc segments\n var arcIntersections;\n\n // Top Left\n {\n var topLeftCenterX = nodeX - halfWidth + cornerRadius;\n var topLeftCenterY = nodeY - halfHeight + cornerRadius;\n arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topLeftCenterX, topLeftCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0 && arcIntersections[0] <= topLeftCenterX && arcIntersections[1] <= topLeftCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Top Right\n {\n var topRightCenterX = nodeX + halfWidth - cornerRadius;\n var topRightCenterY = nodeY - halfHeight + cornerRadius;\n arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, topRightCenterX, topRightCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0 && arcIntersections[0] >= topRightCenterX && arcIntersections[1] <= topRightCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Bottom Right\n {\n var bottomRightCenterX = nodeX + halfWidth - cornerRadius;\n var bottomRightCenterY = nodeY + halfHeight - cornerRadius;\n arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomRightCenterX, bottomRightCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0 && arcIntersections[0] >= bottomRightCenterX && arcIntersections[1] >= bottomRightCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n\n // Bottom Left\n {\n var bottomLeftCenterX = nodeX - halfWidth + cornerRadius;\n var bottomLeftCenterY = nodeY + halfHeight - cornerRadius;\n arcIntersections = intersectLineCircle(x, y, nodeX, nodeY, bottomLeftCenterX, bottomLeftCenterY, cornerRadius + padding);\n\n // Ensure the intersection is on the desired quarter of the circle\n if (arcIntersections.length > 0 && arcIntersections[0] <= bottomLeftCenterX && arcIntersections[1] >= bottomLeftCenterY) {\n return [arcIntersections[0], arcIntersections[1]];\n }\n }\n return []; // if nothing\n};\n\nvar inLineVicinity = function inLineVicinity(x, y, lx1, ly1, lx2, ly2, tolerance) {\n var t = tolerance;\n var x1 = Math.min(lx1, lx2);\n var x2 = Math.max(lx1, lx2);\n var y1 = Math.min(ly1, ly2);\n var y2 = Math.max(ly1, ly2);\n return x1 - t <= x && x <= x2 + t && y1 - t <= y && y <= y2 + t;\n};\nvar inBezierVicinity = function inBezierVicinity(x, y, x1, y1, x2, y2, x3, y3, tolerance) {\n var bb = {\n x1: Math.min(x1, x3, x2) - tolerance,\n x2: Math.max(x1, x3, x2) + tolerance,\n y1: Math.min(y1, y3, y2) - tolerance,\n y2: Math.max(y1, y3, y2) + tolerance\n };\n\n // if outside the rough bounding box for the bezier, then it can't be a hit\n if (x < bb.x1 || x > bb.x2 || y < bb.y1 || y > bb.y2) {\n // console.log('bezier out of rough bb')\n return false;\n } else {\n // console.log('do more expensive check');\n return true;\n }\n};\nvar solveQuadratic = function solveQuadratic(a, b, c, val) {\n c -= val;\n var r = b * b - 4 * a * c;\n if (r < 0) {\n return [];\n }\n var sqrtR = Math.sqrt(r);\n var denom = 2 * a;\n var root1 = (-b + sqrtR) / denom;\n var root2 = (-b - sqrtR) / denom;\n return [root1, root2];\n};\nvar solveCubic = function solveCubic(a, b, c, d, result) {\n // Solves a cubic function, returns root in form [r1, i1, r2, i2, r3, i3], where\n // r is the real component, i is the imaginary component\n\n // An implementation of the Cardano method from the year 1545\n // http://en.wikipedia.org/wiki/Cubic_function#The_nature_of_the_roots\n\n var epsilon = 0.00001;\n\n // avoid division by zero while keeping the overall expression close in value\n if (a === 0) {\n a = epsilon;\n }\n b /= a;\n c /= a;\n d /= a;\n var discriminant, q, r, dum1, s, t, term1, r13;\n q = (3.0 * c - b * b) / 9.0;\n r = -(27.0 * d) + b * (9.0 * c - 2.0 * (b * b));\n r /= 54.0;\n discriminant = q * q * q + r * r;\n result[1] = 0;\n term1 = b / 3.0;\n if (discriminant > 0) {\n s = r + Math.sqrt(discriminant);\n s = s < 0 ? -Math.pow(-s, 1.0 / 3.0) : Math.pow(s, 1.0 / 3.0);\n t = r - Math.sqrt(discriminant);\n t = t < 0 ? -Math.pow(-t, 1.0 / 3.0) : Math.pow(t, 1.0 / 3.0);\n result[0] = -term1 + s + t;\n term1 += (s + t) / 2.0;\n result[4] = result[2] = -term1;\n term1 = Math.sqrt(3.0) * (-t + s) / 2;\n result[3] = term1;\n result[5] = -term1;\n return;\n }\n result[5] = result[3] = 0;\n if (discriminant === 0) {\n r13 = r < 0 ? -Math.pow(-r, 1.0 / 3.0) : Math.pow(r, 1.0 / 3.0);\n result[0] = -term1 + 2.0 * r13;\n result[4] = result[2] = -(r13 + term1);\n return;\n }\n q = -q;\n dum1 = q * q * q;\n dum1 = Math.acos(r / Math.sqrt(dum1));\n r13 = 2.0 * Math.sqrt(q);\n result[0] = -term1 + r13 * Math.cos(dum1 / 3.0);\n result[2] = -term1 + r13 * Math.cos((dum1 + 2.0 * Math.PI) / 3.0);\n result[4] = -term1 + r13 * Math.cos((dum1 + 4.0 * Math.PI) / 3.0);\n return;\n};\nvar sqdistToQuadraticBezier = function sqdistToQuadraticBezier(x, y, x1, y1, x2, y2, x3, y3) {\n // Find minimum distance by using the minimum of the distance\n // function between the given point and the curve\n\n // This gives the coefficients of the resulting cubic equation\n // whose roots tell us where a possible minimum is\n // (Coefficients are divided by 4)\n\n var a = 1.0 * x1 * x1 - 4 * x1 * x2 + 2 * x1 * x3 + 4 * x2 * x2 - 4 * x2 * x3 + x3 * x3 + y1 * y1 - 4 * y1 * y2 + 2 * y1 * y3 + 4 * y2 * y2 - 4 * y2 * y3 + y3 * y3;\n var b = 1.0 * 9 * x1 * x2 - 3 * x1 * x1 - 3 * x1 * x3 - 6 * x2 * x2 + 3 * x2 * x3 + 9 * y1 * y2 - 3 * y1 * y1 - 3 * y1 * y3 - 6 * y2 * y2 + 3 * y2 * y3;\n var c = 1.0 * 3 * x1 * x1 - 6 * x1 * x2 + x1 * x3 - x1 * x + 2 * x2 * x2 + 2 * x2 * x - x3 * x + 3 * y1 * y1 - 6 * y1 * y2 + y1 * y3 - y1 * y + 2 * y2 * y2 + 2 * y2 * y - y3 * y;\n var d = 1.0 * x1 * x2 - x1 * x1 + x1 * x - x2 * x + y1 * y2 - y1 * y1 + y1 * y - y2 * y;\n\n // debug(\"coefficients: \" + a / a + \", \" + b / a + \", \" + c / a + \", \" + d / a);\n\n var roots = [];\n\n // Use the cubic solving algorithm\n solveCubic(a, b, c, d, roots);\n var zeroThreshold = 0.0000001;\n var params = [];\n for (var index = 0; index < 6; index += 2) {\n if (Math.abs(roots[index + 1]) < zeroThreshold && roots[index] >= 0 && roots[index] <= 1.0) {\n params.push(roots[index]);\n }\n }\n params.push(1.0);\n params.push(0.0);\n var minDistanceSquared = -1;\n var curX, curY, distSquared;\n for (var i = 0; i < params.length; i++) {\n curX = Math.pow(1.0 - params[i], 2.0) * x1 + 2.0 * (1 - params[i]) * params[i] * x2 + params[i] * params[i] * x3;\n curY = Math.pow(1 - params[i], 2.0) * y1 + 2 * (1.0 - params[i]) * params[i] * y2 + params[i] * params[i] * y3;\n distSquared = Math.pow(curX - x, 2) + Math.pow(curY - y, 2);\n // debug('distance for param ' + params[i] + \": \" + Math.sqrt(distSquared));\n if (minDistanceSquared >= 0) {\n if (distSquared < minDistanceSquared) {\n minDistanceSquared = distSquared;\n }\n } else {\n minDistanceSquared = distSquared;\n }\n }\n return minDistanceSquared;\n};\nvar sqdistToFiniteLine = function sqdistToFiniteLine(x, y, x1, y1, x2, y2) {\n var offset = [x - x1, y - y1];\n var line = [x2 - x1, y2 - y1];\n var lineSq = line[0] * line[0] + line[1] * line[1];\n var hypSq = offset[0] * offset[0] + offset[1] * offset[1];\n var dotProduct = offset[0] * line[0] + offset[1] * line[1];\n var adjSq = dotProduct * dotProduct / lineSq;\n if (dotProduct < 0) {\n return hypSq;\n }\n if (adjSq > lineSq) {\n return (x - x2) * (x - x2) + (y - y2) * (y - y2);\n }\n return hypSq - adjSq;\n};\nvar pointInsidePolygonPoints = function pointInsidePolygonPoints(x, y, points) {\n var x1, y1, x2, y2;\n var y3;\n\n // Intersect with vertical line through (x, y)\n var up = 0;\n // let down = 0;\n for (var i = 0; i < points.length / 2; i++) {\n x1 = points[i * 2];\n y1 = points[i * 2 + 1];\n if (i + 1 < points.length / 2) {\n x2 = points[(i + 1) * 2];\n y2 = points[(i + 1) * 2 + 1];\n } else {\n x2 = points[(i + 1 - points.length / 2) * 2];\n y2 = points[(i + 1 - points.length / 2) * 2 + 1];\n }\n if (x1 == x && x2 == x) ; else if (x1 >= x && x >= x2 || x1 <= x && x <= x2) {\n y3 = (x - x1) / (x2 - x1) * (y2 - y1) + y1;\n if (y3 > y) {\n up++;\n }\n\n // if( y3 < y ){\n // down++;\n // }\n } else {\n continue;\n }\n }\n if (up % 2 === 0) {\n return false;\n } else {\n return true;\n }\n};\nvar pointInsidePolygon = function pointInsidePolygon(x, y, basePoints, centerX, centerY, width, height, direction, padding) {\n var transformedPoints = new Array(basePoints.length);\n\n // Gives negative angle\n var angle;\n if (direction[0] != null) {\n angle = Math.atan(direction[1] / direction[0]);\n if (direction[0] < 0) {\n angle = angle + Math.PI / 2;\n } else {\n angle = -angle - Math.PI / 2;\n }\n } else {\n angle = direction;\n }\n var cos = Math.cos(-angle);\n var sin = Math.sin(-angle);\n\n // console.log(\"base: \" + basePoints);\n for (var i = 0; i < transformedPoints.length / 2; i++) {\n transformedPoints[i * 2] = width / 2 * (basePoints[i * 2] * cos - basePoints[i * 2 + 1] * sin);\n transformedPoints[i * 2 + 1] = height / 2 * (basePoints[i * 2 + 1] * cos + basePoints[i * 2] * sin);\n transformedPoints[i * 2] += centerX;\n transformedPoints[i * 2 + 1] += centerY;\n }\n var points;\n if (padding > 0) {\n var expandedLineSet = expandPolygon(transformedPoints, -padding);\n points = joinLines(expandedLineSet);\n } else {\n points = transformedPoints;\n }\n return pointInsidePolygonPoints(x, y, points);\n};\nvar pointInsideRoundPolygon = function pointInsideRoundPolygon(x, y, basePoints, centerX, centerY, width, height, corners) {\n var cutPolygonPoints = new Array(basePoints.length * 2);\n for (var i = 0; i < corners.length; i++) {\n var corner = corners[i];\n cutPolygonPoints[i * 4 + 0] = corner.startX;\n cutPolygonPoints[i * 4 + 1] = corner.startY;\n cutPolygonPoints[i * 4 + 2] = corner.stopX;\n cutPolygonPoints[i * 4 + 3] = corner.stopY;\n var squaredDistance = Math.pow(corner.cx - x, 2) + Math.pow(corner.cy - y, 2);\n if (squaredDistance <= Math.pow(corner.radius, 2)) {\n return true;\n }\n }\n return pointInsidePolygonPoints(x, y, cutPolygonPoints);\n};\nvar joinLines = function joinLines(lineSet) {\n var vertices = new Array(lineSet.length / 2);\n var currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY;\n var nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY;\n for (var i = 0; i < lineSet.length / 4; i++) {\n currentLineStartX = lineSet[i * 4];\n currentLineStartY = lineSet[i * 4 + 1];\n currentLineEndX = lineSet[i * 4 + 2];\n currentLineEndY = lineSet[i * 4 + 3];\n if (i < lineSet.length / 4 - 1) {\n nextLineStartX = lineSet[(i + 1) * 4];\n nextLineStartY = lineSet[(i + 1) * 4 + 1];\n nextLineEndX = lineSet[(i + 1) * 4 + 2];\n nextLineEndY = lineSet[(i + 1) * 4 + 3];\n } else {\n nextLineStartX = lineSet[0];\n nextLineStartY = lineSet[1];\n nextLineEndX = lineSet[2];\n nextLineEndY = lineSet[3];\n }\n var intersection = finiteLinesIntersect(currentLineStartX, currentLineStartY, currentLineEndX, currentLineEndY, nextLineStartX, nextLineStartY, nextLineEndX, nextLineEndY, true);\n vertices[i * 2] = intersection[0];\n vertices[i * 2 + 1] = intersection[1];\n }\n return vertices;\n};\nvar expandPolygon = function expandPolygon(points, pad) {\n var expandedLineSet = new Array(points.length * 2);\n var currentPointX, currentPointY, nextPointX, nextPointY;\n for (var i = 0; i < points.length / 2; i++) {\n currentPointX = points[i * 2];\n currentPointY = points[i * 2 + 1];\n if (i < points.length / 2 - 1) {\n nextPointX = points[(i + 1) * 2];\n nextPointY = points[(i + 1) * 2 + 1];\n } else {\n nextPointX = points[0];\n nextPointY = points[1];\n }\n\n // Current line: [currentPointX, currentPointY] to [nextPointX, nextPointY]\n\n // Assume CCW polygon winding\n\n var offsetX = nextPointY - currentPointY;\n var offsetY = -(nextPointX - currentPointX);\n\n // Normalize\n var offsetLength = Math.sqrt(offsetX * offsetX + offsetY * offsetY);\n var normalizedOffsetX = offsetX / offsetLength;\n var normalizedOffsetY = offsetY / offsetLength;\n expandedLineSet[i * 4] = currentPointX + normalizedOffsetX * pad;\n expandedLineSet[i * 4 + 1] = currentPointY + normalizedOffsetY * pad;\n expandedLineSet[i * 4 + 2] = nextPointX + normalizedOffsetX * pad;\n expandedLineSet[i * 4 + 3] = nextPointY + normalizedOffsetY * pad;\n }\n return expandedLineSet;\n};\nvar intersectLineEllipse = function intersectLineEllipse(x, y, centerX, centerY, ellipseWradius, ellipseHradius) {\n var dispX = centerX - x;\n var dispY = centerY - y;\n dispX /= ellipseWradius;\n dispY /= ellipseHradius;\n var len = Math.sqrt(dispX * dispX + dispY * dispY);\n var newLength = len - 1;\n if (newLength < 0) {\n return [];\n }\n var lenProportion = newLength / len;\n return [(centerX - x) * lenProportion + x, (centerY - y) * lenProportion + y];\n};\nvar checkInEllipse = function checkInEllipse(x, y, width, height, centerX, centerY, padding) {\n x -= centerX;\n y -= centerY;\n x /= width / 2 + padding;\n y /= height / 2 + padding;\n return x * x + y * y <= 1;\n};\n\n// Returns intersections of increasing distance from line's start point\nvar intersectLineCircle = function intersectLineCircle(x1, y1, x2, y2, centerX, centerY, radius) {\n // Calculate d, direction vector of line\n var d = [x2 - x1, y2 - y1]; // Direction vector of line\n var f = [x1 - centerX, y1 - centerY];\n var a = d[0] * d[0] + d[1] * d[1];\n var b = 2 * (f[0] * d[0] + f[1] * d[1]);\n var c = f[0] * f[0] + f[1] * f[1] - radius * radius;\n var discriminant = b * b - 4 * a * c;\n if (discriminant < 0) {\n return [];\n }\n var t1 = (-b + Math.sqrt(discriminant)) / (2 * a);\n var t2 = (-b - Math.sqrt(discriminant)) / (2 * a);\n var tMin = Math.min(t1, t2);\n var tMax = Math.max(t1, t2);\n var inRangeParams = [];\n if (tMin >= 0 && tMin <= 1) {\n inRangeParams.push(tMin);\n }\n if (tMax >= 0 && tMax <= 1) {\n inRangeParams.push(tMax);\n }\n if (inRangeParams.length === 0) {\n return [];\n }\n var nearIntersectionX = inRangeParams[0] * d[0] + x1;\n var nearIntersectionY = inRangeParams[0] * d[1] + y1;\n if (inRangeParams.length > 1) {\n if (inRangeParams[0] == inRangeParams[1]) {\n return [nearIntersectionX, nearIntersectionY];\n } else {\n var farIntersectionX = inRangeParams[1] * d[0] + x1;\n var farIntersectionY = inRangeParams[1] * d[1] + y1;\n return [nearIntersectionX, nearIntersectionY, farIntersectionX, farIntersectionY];\n }\n } else {\n return [nearIntersectionX, nearIntersectionY];\n }\n};\nvar midOfThree = function midOfThree(a, b, c) {\n if (b <= a && a <= c || c <= a && a <= b) {\n return a;\n } else if (a <= b && b <= c || c <= b && b <= a) {\n return b;\n } else {\n return c;\n }\n};\n\n// (x1,y1)=>(x2,y2) intersect with (x3,y3)=>(x4,y4)\nvar finiteLinesIntersect = function finiteLinesIntersect(x1, y1, x2, y2, x3, y3, x4, y4, infiniteLines) {\n var dx13 = x1 - x3;\n var dx21 = x2 - x1;\n var dx43 = x4 - x3;\n var dy13 = y1 - y3;\n var dy21 = y2 - y1;\n var dy43 = y4 - y3;\n var ua_t = dx43 * dy13 - dy43 * dx13;\n var ub_t = dx21 * dy13 - dy21 * dx13;\n var u_b = dy43 * dx21 - dx43 * dy21;\n if (u_b !== 0) {\n var ua = ua_t / u_b;\n var ub = ub_t / u_b;\n var flptThreshold = 0.001;\n var _min = 0 - flptThreshold;\n var _max = 1 + flptThreshold;\n if (_min <= ua && ua <= _max && _min <= ub && ub <= _max) {\n return [x1 + ua * dx21, y1 + ua * dy21];\n } else {\n if (!infiniteLines) {\n return [];\n } else {\n return [x1 + ua * dx21, y1 + ua * dy21];\n }\n }\n } else {\n if (ua_t === 0 || ub_t === 0) {\n // Parallel, coincident lines. Check if overlap\n\n // Check endpoint of second line\n if (midOfThree(x1, x2, x4) === x4) {\n return [x4, y4];\n }\n\n // Check start point of second line\n if (midOfThree(x1, x2, x3) === x3) {\n return [x3, y3];\n }\n\n // Endpoint of first line\n if (midOfThree(x3, x4, x2) === x2) {\n return [x2, y2];\n }\n return [];\n } else {\n // Parallel, non-coincident\n return [];\n }\n }\n};\n\n// math.polygonIntersectLine( x, y, basePoints, centerX, centerY, width, height, padding )\n// intersect a node polygon (pts transformed)\n//\n// math.polygonIntersectLine( x, y, basePoints, centerX, centerY )\n// intersect the points (no transform)\nvar polygonIntersectLine = function polygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding) {\n var intersections = [];\n var intersection;\n var transformedPoints = new Array(basePoints.length);\n var doTransform = true;\n if (width == null) {\n doTransform = false;\n }\n var points;\n if (doTransform) {\n for (var i = 0; i < transformedPoints.length / 2; i++) {\n transformedPoints[i * 2] = basePoints[i * 2] * width + centerX;\n transformedPoints[i * 2 + 1] = basePoints[i * 2 + 1] * height + centerY;\n }\n if (padding > 0) {\n var expandedLineSet = expandPolygon(transformedPoints, -padding);\n points = joinLines(expandedLineSet);\n } else {\n points = transformedPoints;\n }\n } else {\n points = basePoints;\n }\n var currentX, currentY, nextX, nextY;\n for (var _i2 = 0; _i2 < points.length / 2; _i2++) {\n currentX = points[_i2 * 2];\n currentY = points[_i2 * 2 + 1];\n if (_i2 < points.length / 2 - 1) {\n nextX = points[(_i2 + 1) * 2];\n nextY = points[(_i2 + 1) * 2 + 1];\n } else {\n nextX = points[0];\n nextY = points[1];\n }\n intersection = finiteLinesIntersect(x, y, centerX, centerY, currentX, currentY, nextX, nextY);\n if (intersection.length !== 0) {\n intersections.push(intersection[0], intersection[1]);\n }\n }\n return intersections;\n};\nvar roundPolygonIntersectLine = function roundPolygonIntersectLine(x, y, basePoints, centerX, centerY, width, height, padding, corners) {\n var intersections = [];\n var intersection;\n var lines = new Array(basePoints.length * 2);\n corners.forEach(function (corner, i) {\n if (i === 0) {\n lines[lines.length - 2] = corner.startX;\n lines[lines.length - 1] = corner.startY;\n } else {\n lines[i * 4 - 2] = corner.startX;\n lines[i * 4 - 1] = corner.startY;\n }\n lines[i * 4] = corner.stopX;\n lines[i * 4 + 1] = corner.stopY;\n intersection = intersectLineCircle(x, y, centerX, centerY, corner.cx, corner.cy, corner.radius);\n if (intersection.length !== 0) {\n intersections.push(intersection[0], intersection[1]);\n }\n });\n for (var i = 0; i < lines.length / 4; i++) {\n intersection = finiteLinesIntersect(x, y, centerX, centerY, lines[i * 4], lines[i * 4 + 1], lines[i * 4 + 2], lines[i * 4 + 3], false);\n if (intersection.length !== 0) {\n intersections.push(intersection[0], intersection[1]);\n }\n }\n if (intersections.length > 2) {\n var lowestIntersection = [intersections[0], intersections[1]];\n var lowestSquaredDistance = Math.pow(lowestIntersection[0] - x, 2) + Math.pow(lowestIntersection[1] - y, 2);\n for (var _i3 = 1; _i3 < intersections.length / 2; _i3++) {\n var squaredDistance = Math.pow(intersections[_i3 * 2] - x, 2) + Math.pow(intersections[_i3 * 2 + 1] - y, 2);\n if (squaredDistance <= lowestSquaredDistance) {\n lowestIntersection[0] = intersections[_i3 * 2];\n lowestIntersection[1] = intersections[_i3 * 2 + 1];\n lowestSquaredDistance = squaredDistance;\n }\n }\n return lowestIntersection;\n }\n return intersections;\n};\nvar shortenIntersection = function shortenIntersection(intersection, offset, amount) {\n var disp = [intersection[0] - offset[0], intersection[1] - offset[1]];\n var length = Math.sqrt(disp[0] * disp[0] + disp[1] * disp[1]);\n var lenRatio = (length - amount) / length;\n if (lenRatio < 0) {\n lenRatio = 0.00001;\n }\n return [offset[0] + lenRatio * disp[0], offset[1] + lenRatio * disp[1]];\n};\nvar generateUnitNgonPointsFitToSquare = function generateUnitNgonPointsFitToSquare(sides, rotationRadians) {\n var points = generateUnitNgonPoints(sides, rotationRadians);\n points = fitPolygonToSquare(points);\n return points;\n};\nvar fitPolygonToSquare = function fitPolygonToSquare(points) {\n var x, y;\n var sides = points.length / 2;\n var minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n for (var i = 0; i < sides; i++) {\n x = points[2 * i];\n y = points[2 * i + 1];\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n }\n\n // stretch factors\n var sx = 2 / (maxX - minX);\n var sy = 2 / (maxY - minY);\n for (var _i4 = 0; _i4 < sides; _i4++) {\n x = points[2 * _i4] = points[2 * _i4] * sx;\n y = points[2 * _i4 + 1] = points[2 * _i4 + 1] * sy;\n minX = Math.min(minX, x);\n maxX = Math.max(maxX, x);\n minY = Math.min(minY, y);\n maxY = Math.max(maxY, y);\n }\n if (minY < -1) {\n for (var _i5 = 0; _i5 < sides; _i5++) {\n y = points[2 * _i5 + 1] = points[2 * _i5 + 1] + (-1 - minY);\n }\n }\n return points;\n};\nvar generateUnitNgonPoints = function generateUnitNgonPoints(sides, rotationRadians) {\n var increment = 1.0 / sides * 2 * Math.PI;\n var startAngle = sides % 2 === 0 ? Math.PI / 2.0 + increment / 2.0 : Math.PI / 2.0;\n startAngle += rotationRadians;\n var points = new Array(sides * 2);\n var currentAngle;\n for (var i = 0; i < sides; i++) {\n currentAngle = i * increment + startAngle;\n points[2 * i] = Math.cos(currentAngle); // x\n points[2 * i + 1] = Math.sin(-currentAngle); // y\n }\n\n return points;\n};\n\n// Set the default radius, unless half of width or height is smaller than default\nvar getRoundRectangleRadius = function getRoundRectangleRadius(width, height) {\n return Math.min(width / 4, height / 4, 8);\n};\n\n// Set the default radius\nvar getRoundPolygonRadius = function getRoundPolygonRadius(width, height) {\n return Math.min(width / 10, height / 10, 8);\n};\nvar getCutRectangleCornerLength = function getCutRectangleCornerLength() {\n return 8;\n};\nvar bezierPtsToQuadCoeff = function bezierPtsToQuadCoeff(p0, p1, p2) {\n return [p0 - 2 * p1 + p2, 2 * (p1 - p0), p0];\n};\n\n// get curve width, height, and control point position offsets as a percentage of node height / width\nvar getBarrelCurveConstants = function getBarrelCurveConstants(width, height) {\n return {\n heightOffset: Math.min(15, 0.05 * height),\n widthOffset: Math.min(100, 0.25 * width),\n ctrlPtOffsetPct: 0.05\n };\n};\n\nvar pageRankDefaults = defaults$g({\n dampingFactor: 0.8,\n precision: 0.000001,\n iterations: 200,\n weight: function weight(edge) {\n return 1;\n }\n});\nvar elesfn$o = {\n pageRank: function pageRank(options) {\n var _pageRankDefaults = pageRankDefaults(options),\n dampingFactor = _pageRankDefaults.dampingFactor,\n precision = _pageRankDefaults.precision,\n iterations = _pageRankDefaults.iterations,\n weight = _pageRankDefaults.weight;\n var cy = this._private.cy;\n var _this$byGroup = this.byGroup(),\n nodes = _this$byGroup.nodes,\n edges = _this$byGroup.edges;\n var numNodes = nodes.length;\n var numNodesSqd = numNodes * numNodes;\n var numEdges = edges.length;\n\n // Construct transposed adjacency matrix\n // First lets have a zeroed matrix of the right size\n // We'll also keep track of the sum of each column\n var matrix = new Array(numNodesSqd);\n var columnSum = new Array(numNodes);\n var additionalProb = (1 - dampingFactor) / numNodes;\n\n // Create null matrix\n for (var i = 0; i < numNodes; i++) {\n for (var j = 0; j < numNodes; j++) {\n var n = i * numNodes + j;\n matrix[n] = 0;\n }\n columnSum[i] = 0;\n }\n\n // Now, process edges\n for (var _i = 0; _i < numEdges; _i++) {\n var edge = edges[_i];\n var srcId = edge.data('source');\n var tgtId = edge.data('target');\n\n // Don't include loops in the matrix\n if (srcId === tgtId) {\n continue;\n }\n var s = nodes.indexOfId(srcId);\n var t = nodes.indexOfId(tgtId);\n var w = weight(edge);\n var _n = t * numNodes + s;\n\n // Update matrix\n matrix[_n] += w;\n\n // Update column sum\n columnSum[s] += w;\n }\n\n // Add additional probability based on damping factor\n // Also, take into account columns that have sum = 0\n var p = 1.0 / numNodes + additionalProb; // Shorthand\n\n // Traverse matrix, column by column\n for (var _j = 0; _j < numNodes; _j++) {\n if (columnSum[_j] === 0) {\n // No 'links' out from node jth, assume equal probability for each possible node\n for (var _i2 = 0; _i2 < numNodes; _i2++) {\n var _n2 = _i2 * numNodes + _j;\n matrix[_n2] = p;\n }\n } else {\n // Node jth has outgoing link, compute normalized probabilities\n for (var _i3 = 0; _i3 < numNodes; _i3++) {\n var _n3 = _i3 * numNodes + _j;\n matrix[_n3] = matrix[_n3] / columnSum[_j] + additionalProb;\n }\n }\n }\n\n // Compute dominant eigenvector using power method\n var eigenvector = new Array(numNodes);\n var temp = new Array(numNodes);\n var previous;\n\n // Start with a vector of all 1's\n // Also, initialize a null vector which will be used as shorthand\n for (var _i4 = 0; _i4 < numNodes; _i4++) {\n eigenvector[_i4] = 1;\n }\n for (var iter = 0; iter < iterations; iter++) {\n // Temp array with all 0's\n for (var _i5 = 0; _i5 < numNodes; _i5++) {\n temp[_i5] = 0;\n }\n\n // Multiply matrix with previous result\n for (var _i6 = 0; _i6 < numNodes; _i6++) {\n for (var _j2 = 0; _j2 < numNodes; _j2++) {\n var _n4 = _i6 * numNodes + _j2;\n temp[_i6] += matrix[_n4] * eigenvector[_j2];\n }\n }\n inPlaceSumNormalize(temp);\n previous = eigenvector;\n eigenvector = temp;\n temp = previous;\n var diff = 0;\n // Compute difference (squared module) of both vectors\n for (var _i7 = 0; _i7 < numNodes; _i7++) {\n var delta = previous[_i7] - eigenvector[_i7];\n diff += delta * delta;\n }\n\n // If difference is less than the desired threshold, stop iterating\n if (diff < precision) {\n break;\n }\n }\n\n // Construct result\n var res = {\n rank: function rank(node) {\n node = cy.collection(node)[0];\n return eigenvector[nodes.indexOf(node)];\n }\n };\n return res;\n } // pageRank\n}; // elesfn\n\nvar defaults$f = defaults$g({\n root: null,\n weight: function weight(edge) {\n return 1;\n },\n directed: false,\n alpha: 0\n});\nvar elesfn$n = {\n degreeCentralityNormalized: function degreeCentralityNormalized(options) {\n options = defaults$f(options);\n var cy = this.cy();\n var nodes = this.nodes();\n var numNodes = nodes.length;\n if (!options.directed) {\n var degrees = {};\n var maxDegree = 0;\n for (var i = 0; i < numNodes; i++) {\n var node = nodes[i];\n\n // add current node to the current options object and call degreeCentrality\n options.root = node;\n var currDegree = this.degreeCentrality(options);\n if (maxDegree < currDegree.degree) {\n maxDegree = currDegree.degree;\n }\n degrees[node.id()] = currDegree.degree;\n }\n return {\n degree: function degree(node) {\n if (maxDegree === 0) {\n return 0;\n }\n if (string(node)) {\n // from is a selector string\n node = cy.filter(node);\n }\n return degrees[node.id()] / maxDegree;\n }\n };\n } else {\n var indegrees = {};\n var outdegrees = {};\n var maxIndegree = 0;\n var maxOutdegree = 0;\n for (var _i = 0; _i < numNodes; _i++) {\n var _node = nodes[_i];\n var id = _node.id();\n\n // add current node to the current options object and call degreeCentrality\n options.root = _node;\n var _currDegree = this.degreeCentrality(options);\n if (maxIndegree < _currDegree.indegree) maxIndegree = _currDegree.indegree;\n if (maxOutdegree < _currDegree.outdegree) maxOutdegree = _currDegree.outdegree;\n indegrees[id] = _currDegree.indegree;\n outdegrees[id] = _currDegree.outdegree;\n }\n return {\n indegree: function indegree(node) {\n if (maxIndegree == 0) {\n return 0;\n }\n if (string(node)) {\n // from is a selector string\n node = cy.filter(node);\n }\n return indegrees[node.id()] / maxIndegree;\n },\n outdegree: function outdegree(node) {\n if (maxOutdegree === 0) {\n return 0;\n }\n if (string(node)) {\n // from is a selector string\n node = cy.filter(node);\n }\n return outdegrees[node.id()] / maxOutdegree;\n }\n };\n }\n },\n // degreeCentralityNormalized\n\n // Implemented from the algorithm in Opsahl's paper\n // \"Node centrality in weighted networks: Generalizing degree and shortest paths\"\n // check the heading 2 \"Degree\"\n degreeCentrality: function degreeCentrality(options) {\n options = defaults$f(options);\n var cy = this.cy();\n var callingEles = this;\n var _options = options,\n root = _options.root,\n weight = _options.weight,\n directed = _options.directed,\n alpha = _options.alpha;\n root = cy.collection(root)[0];\n if (!directed) {\n var connEdges = root.connectedEdges().intersection(callingEles);\n var k = connEdges.length;\n var s = 0;\n\n // Now, sum edge weights\n for (var i = 0; i < connEdges.length; i++) {\n s += weight(connEdges[i]);\n }\n return {\n degree: Math.pow(k, 1 - alpha) * Math.pow(s, alpha)\n };\n } else {\n var edges = root.connectedEdges();\n var incoming = edges.filter(function (edge) {\n return edge.target().same(root) && callingEles.has(edge);\n });\n var outgoing = edges.filter(function (edge) {\n return edge.source().same(root) && callingEles.has(edge);\n });\n var k_in = incoming.length;\n var k_out = outgoing.length;\n var s_in = 0;\n var s_out = 0;\n\n // Now, sum incoming edge weights\n for (var _i2 = 0; _i2 < incoming.length; _i2++) {\n s_in += weight(incoming[_i2]);\n }\n\n // Now, sum outgoing edge weights\n for (var _i3 = 0; _i3 < outgoing.length; _i3++) {\n s_out += weight(outgoing[_i3]);\n }\n return {\n indegree: Math.pow(k_in, 1 - alpha) * Math.pow(s_in, alpha),\n outdegree: Math.pow(k_out, 1 - alpha) * Math.pow(s_out, alpha)\n };\n }\n } // degreeCentrality\n}; // elesfn\n\n// nice, short mathematical alias\nelesfn$n.dc = elesfn$n.degreeCentrality;\nelesfn$n.dcn = elesfn$n.degreeCentralityNormalised = elesfn$n.degreeCentralityNormalized;\n\nvar defaults$e = defaults$g({\n harmonic: true,\n weight: function weight() {\n return 1;\n },\n directed: false,\n root: null\n});\nvar elesfn$m = {\n closenessCentralityNormalized: function closenessCentralityNormalized(options) {\n var _defaults = defaults$e(options),\n harmonic = _defaults.harmonic,\n weight = _defaults.weight,\n directed = _defaults.directed;\n var cy = this.cy();\n var closenesses = {};\n var maxCloseness = 0;\n var nodes = this.nodes();\n var fw = this.floydWarshall({\n weight: weight,\n directed: directed\n });\n\n // Compute closeness for every node and find the maximum closeness\n for (var i = 0; i < nodes.length; i++) {\n var currCloseness = 0;\n var node_i = nodes[i];\n for (var j = 0; j < nodes.length; j++) {\n if (i !== j) {\n var d = fw.distance(node_i, nodes[j]);\n if (harmonic) {\n currCloseness += 1 / d;\n } else {\n currCloseness += d;\n }\n }\n }\n if (!harmonic) {\n currCloseness = 1 / currCloseness;\n }\n if (maxCloseness < currCloseness) {\n maxCloseness = currCloseness;\n }\n closenesses[node_i.id()] = currCloseness;\n }\n return {\n closeness: function closeness(node) {\n if (maxCloseness == 0) {\n return 0;\n }\n if (string(node)) {\n // from is a selector string\n node = cy.filter(node)[0].id();\n } else {\n // from is a node\n node = node.id();\n }\n return closenesses[node] / maxCloseness;\n }\n };\n },\n // Implemented from pseudocode from wikipedia\n closenessCentrality: function closenessCentrality(options) {\n var _defaults2 = defaults$e(options),\n root = _defaults2.root,\n weight = _defaults2.weight,\n directed = _defaults2.directed,\n harmonic = _defaults2.harmonic;\n root = this.filter(root)[0];\n\n // we need distance from this node to every other node\n var dijkstra = this.dijkstra({\n root: root,\n weight: weight,\n directed: directed\n });\n var totalDistance = 0;\n var nodes = this.nodes();\n for (var i = 0; i < nodes.length; i++) {\n var n = nodes[i];\n if (!n.same(root)) {\n var d = dijkstra.distanceTo(n);\n if (harmonic) {\n totalDistance += 1 / d;\n } else {\n totalDistance += d;\n }\n }\n }\n return harmonic ? totalDistance : 1 / totalDistance;\n } // closenessCentrality\n}; // elesfn\n\n// nice, short mathematical alias\nelesfn$m.cc = elesfn$m.closenessCentrality;\nelesfn$m.ccn = elesfn$m.closenessCentralityNormalised = elesfn$m.closenessCentralityNormalized;\n\nvar defaults$d = defaults$g({\n weight: null,\n directed: false\n});\nvar elesfn$l = {\n // Implemented from the algorithm in the paper \"On Variants of Shortest-Path Betweenness Centrality and their Generic Computation\" by Ulrik Brandes\n betweennessCentrality: function betweennessCentrality(options) {\n var _defaults = defaults$d(options),\n directed = _defaults.directed,\n weight = _defaults.weight;\n var weighted = weight != null;\n var cy = this.cy();\n\n // starting\n var V = this.nodes();\n var A = {};\n var _C = {};\n var max = 0;\n var C = {\n set: function set(key, val) {\n _C[key] = val;\n if (val > max) {\n max = val;\n }\n },\n get: function get(key) {\n return _C[key];\n }\n };\n\n // A contains the neighborhoods of every node\n for (var i = 0; i < V.length; i++) {\n var v = V[i];\n var vid = v.id();\n if (directed) {\n A[vid] = v.outgoers().nodes(); // get outgoers of every node\n } else {\n A[vid] = v.openNeighborhood().nodes(); // get neighbors of every node\n }\n\n C.set(vid, 0);\n }\n var _loop = function _loop(s) {\n var sid = V[s].id();\n var S = []; // stack\n var P = {};\n var g = {};\n var d = {};\n var Q = new heap(function (a, b) {\n return d[a] - d[b];\n }); // queue\n\n // init dictionaries\n for (var _i = 0; _i < V.length; _i++) {\n var _vid = V[_i].id();\n P[_vid] = [];\n g[_vid] = 0;\n d[_vid] = Infinity;\n }\n g[sid] = 1; // sigma\n d[sid] = 0; // distance to s\n\n Q.push(sid);\n while (!Q.empty()) {\n var _v = Q.pop();\n S.push(_v);\n if (weighted) {\n for (var j = 0; j < A[_v].length; j++) {\n var w = A[_v][j];\n var vEle = cy.getElementById(_v);\n var edge = void 0;\n if (vEle.edgesTo(w).length > 0) {\n edge = vEle.edgesTo(w)[0];\n } else {\n edge = w.edgesTo(vEle)[0];\n }\n var edgeWeight = weight(edge);\n w = w.id();\n if (d[w] > d[_v] + edgeWeight) {\n d[w] = d[_v] + edgeWeight;\n if (Q.nodes.indexOf(w) < 0) {\n //if w is not in Q\n Q.push(w);\n } else {\n // update position if w is in Q\n Q.updateItem(w);\n }\n g[w] = 0;\n P[w] = [];\n }\n if (d[w] == d[_v] + edgeWeight) {\n g[w] = g[w] + g[_v];\n P[w].push(_v);\n }\n }\n } else {\n for (var _j = 0; _j < A[_v].length; _j++) {\n var _w = A[_v][_j].id();\n if (d[_w] == Infinity) {\n Q.push(_w);\n d[_w] = d[_v] + 1;\n }\n if (d[_w] == d[_v] + 1) {\n g[_w] = g[_w] + g[_v];\n P[_w].push(_v);\n }\n }\n }\n }\n var e = {};\n for (var _i2 = 0; _i2 < V.length; _i2++) {\n e[V[_i2].id()] = 0;\n }\n while (S.length > 0) {\n var _w2 = S.pop();\n for (var _j2 = 0; _j2 < P[_w2].length; _j2++) {\n var _v2 = P[_w2][_j2];\n e[_v2] = e[_v2] + g[_v2] / g[_w2] * (1 + e[_w2]);\n }\n if (_w2 != V[s].id()) {\n C.set(_w2, C.get(_w2) + e[_w2]);\n }\n }\n };\n for (var s = 0; s < V.length; s++) {\n _loop(s);\n }\n var ret = {\n betweenness: function betweenness(node) {\n var id = cy.collection(node).id();\n return C.get(id);\n },\n betweennessNormalized: function betweennessNormalized(node) {\n if (max == 0) {\n return 0;\n }\n var id = cy.collection(node).id();\n return C.get(id) / max;\n }\n };\n\n // alias\n ret.betweennessNormalised = ret.betweennessNormalized;\n return ret;\n } // betweennessCentrality\n}; // elesfn\n\n// nice, short mathematical alias\nelesfn$l.bc = elesfn$l.betweennessCentrality;\n\n// Implemented by Zoe Xi @zoexi for GSOC 2016\n\n/* eslint-disable no-unused-vars */\nvar defaults$c = defaults$g({\n expandFactor: 2,\n // affects time of computation and cluster granularity to some extent: M * M\n inflateFactor: 2,\n // affects cluster granularity (the greater the value, the more clusters): M(i,j) / E(j)\n multFactor: 1,\n // optional self loops for each node. Use a neutral value to improve cluster computations.\n maxIterations: 20,\n // maximum number of iterations of the MCL algorithm in a single run\n attributes: [\n // attributes/features used to group nodes, ie. similarity values between nodes\n function (edge) {\n return 1;\n }]\n});\n/* eslint-enable */\n\nvar setOptions$3 = function setOptions(options) {\n return defaults$c(options);\n};\n/* eslint-enable */\n\nvar getSimilarity$1 = function getSimilarity(edge, attributes) {\n var total = 0;\n for (var i = 0; i < attributes.length; i++) {\n total += attributes[i](edge);\n }\n return total;\n};\nvar addLoops = function addLoops(M, n, val) {\n for (var i = 0; i < n; i++) {\n M[i * n + i] = val;\n }\n};\nvar normalize = function normalize(M, n) {\n var sum;\n for (var col = 0; col < n; col++) {\n sum = 0;\n for (var row = 0; row < n; row++) {\n sum += M[row * n + col];\n }\n for (var _row = 0; _row < n; _row++) {\n M[_row * n + col] = M[_row * n + col] / sum;\n }\n }\n};\n\n// TODO: blocked matrix multiplication?\nvar mmult = function mmult(A, B, n) {\n var C = new Array(n * n);\n for (var i = 0; i < n; i++) {\n for (var j = 0; j < n; j++) {\n C[i * n + j] = 0;\n }\n for (var k = 0; k < n; k++) {\n for (var _j = 0; _j < n; _j++) {\n C[i * n + _j] += A[i * n + k] * B[k * n + _j];\n }\n }\n }\n return C;\n};\nvar expand = function expand(M, n, expandFactor /** power **/) {\n var _M = M.slice(0);\n for (var p = 1; p < expandFactor; p++) {\n M = mmult(M, _M, n);\n }\n return M;\n};\nvar inflate = function inflate(M, n, inflateFactor /** r **/) {\n var _M = new Array(n * n);\n\n // M(i,j) ^ inflatePower\n for (var i = 0; i < n * n; i++) {\n _M[i] = Math.pow(M[i], inflateFactor);\n }\n normalize(_M, n);\n return _M;\n};\nvar hasConverged = function hasConverged(M, _M, n2, roundFactor) {\n // Check that both matrices have the same elements (i,j)\n for (var i = 0; i < n2; i++) {\n var v1 = Math.round(M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor); // truncate to 'roundFactor' decimal places\n var v2 = Math.round(_M[i] * Math.pow(10, roundFactor)) / Math.pow(10, roundFactor);\n if (v1 !== v2) {\n return false;\n }\n }\n return true;\n};\nvar assign$2 = function assign(M, n, nodes, cy) {\n var clusters = [];\n for (var i = 0; i < n; i++) {\n var cluster = [];\n for (var j = 0; j < n; j++) {\n // Row-wise attractors and elements that they attract belong in same cluster\n if (Math.round(M[i * n + j] * 1000) / 1000 > 0) {\n cluster.push(nodes[j]);\n }\n }\n if (cluster.length !== 0) {\n clusters.push(cy.collection(cluster));\n }\n }\n return clusters;\n};\nvar isDuplicate = function isDuplicate(c1, c2) {\n for (var i = 0; i < c1.length; i++) {\n if (!c2[i] || c1[i].id() !== c2[i].id()) {\n return false;\n }\n }\n return true;\n};\nvar removeDuplicates = function removeDuplicates(clusters) {\n for (var i = 0; i < clusters.length; i++) {\n for (var j = 0; j < clusters.length; j++) {\n if (i != j && isDuplicate(clusters[i], clusters[j])) {\n clusters.splice(j, 1);\n }\n }\n }\n return clusters;\n};\nvar markovClustering = function markovClustering(options) {\n var nodes = this.nodes();\n var edges = this.edges();\n var cy = this.cy();\n\n // Set parameters of algorithm:\n var opts = setOptions$3(options);\n\n // Map each node to its position in node array\n var id2position = {};\n for (var i = 0; i < nodes.length; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Generate stochastic matrix M from input graph G (should be symmetric/undirected)\n var n = nodes.length,\n n2 = n * n;\n var M = new Array(n2),\n _M;\n for (var _i = 0; _i < n2; _i++) {\n M[_i] = 0;\n }\n for (var e = 0; e < edges.length; e++) {\n var edge = edges[e];\n var _i2 = id2position[edge.source().id()];\n var j = id2position[edge.target().id()];\n var sim = getSimilarity$1(edge, opts.attributes);\n M[_i2 * n + j] += sim; // G should be symmetric and undirected\n M[j * n + _i2] += sim;\n }\n\n // Begin Markov cluster algorithm\n\n // Step 1: Add self loops to each node, ie. add multFactor to matrix diagonal\n addLoops(M, n, opts.multFactor);\n\n // Step 2: M = normalize( M );\n normalize(M, n);\n var isStillMoving = true;\n var iterations = 0;\n while (isStillMoving && iterations < opts.maxIterations) {\n isStillMoving = false;\n\n // Step 3:\n _M = expand(M, n, opts.expandFactor);\n\n // Step 4:\n M = inflate(_M, n, opts.inflateFactor);\n\n // Step 5: check to see if ~steady state has been reached\n if (!hasConverged(M, _M, n2, 4)) {\n isStillMoving = true;\n }\n iterations++;\n }\n\n // Build clusters from matrix\n var clusters = assign$2(M, n, nodes, cy);\n\n // Remove duplicate clusters due to symmetry of graph and M matrix\n clusters = removeDuplicates(clusters);\n return clusters;\n};\nvar markovClustering$1 = {\n markovClustering: markovClustering,\n mcl: markovClustering\n};\n\n// Common distance metrics for clustering algorithms\nvar identity = function identity(x) {\n return x;\n};\nvar absDiff = function absDiff(p, q) {\n return Math.abs(q - p);\n};\nvar addAbsDiff = function addAbsDiff(total, p, q) {\n return total + absDiff(p, q);\n};\nvar addSquaredDiff = function addSquaredDiff(total, p, q) {\n return total + Math.pow(q - p, 2);\n};\nvar sqrt = function sqrt(x) {\n return Math.sqrt(x);\n};\nvar maxAbsDiff = function maxAbsDiff(currentMax, p, q) {\n return Math.max(currentMax, absDiff(p, q));\n};\nvar getDistance = function getDistance(length, getP, getQ, init, visit) {\n var post = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : identity;\n var ret = init;\n var p, q;\n for (var dim = 0; dim < length; dim++) {\n p = getP(dim);\n q = getQ(dim);\n ret = visit(ret, p, q);\n }\n return post(ret);\n};\nvar distances = {\n euclidean: function euclidean(length, getP, getQ) {\n if (length >= 2) {\n return getDistance(length, getP, getQ, 0, addSquaredDiff, sqrt);\n } else {\n // for single attr case, more efficient to avoid sqrt\n return getDistance(length, getP, getQ, 0, addAbsDiff);\n }\n },\n squaredEuclidean: function squaredEuclidean(length, getP, getQ) {\n return getDistance(length, getP, getQ, 0, addSquaredDiff);\n },\n manhattan: function manhattan(length, getP, getQ) {\n return getDistance(length, getP, getQ, 0, addAbsDiff);\n },\n max: function max(length, getP, getQ) {\n return getDistance(length, getP, getQ, -Infinity, maxAbsDiff);\n }\n};\n\n// in case the user accidentally doesn't use camel case\ndistances['squared-euclidean'] = distances['squaredEuclidean'];\ndistances['squaredeuclidean'] = distances['squaredEuclidean'];\nfunction clusteringDistance (method, length, getP, getQ, nodeP, nodeQ) {\n var impl;\n if (fn$6(method)) {\n impl = method;\n } else {\n impl = distances[method] || distances.euclidean;\n }\n if (length === 0 && fn$6(method)) {\n return impl(nodeP, nodeQ);\n } else {\n return impl(length, getP, getQ, nodeP, nodeQ);\n }\n}\n\nvar defaults$b = defaults$g({\n k: 2,\n m: 2,\n sensitivityThreshold: 0.0001,\n distance: 'euclidean',\n maxIterations: 10,\n attributes: [],\n testMode: false,\n testCentroids: null\n});\nvar setOptions$2 = function setOptions(options) {\n return defaults$b(options);\n};\n\nvar getDist = function getDist(type, node, centroid, attributes, mode) {\n var noNodeP = mode !== 'kMedoids';\n var getP = noNodeP ? function (i) {\n return centroid[i];\n } : function (i) {\n return attributes[i](centroid);\n };\n var getQ = function getQ(i) {\n return attributes[i](node);\n };\n var nodeP = centroid;\n var nodeQ = node;\n return clusteringDistance(type, attributes.length, getP, getQ, nodeP, nodeQ);\n};\nvar randomCentroids = function randomCentroids(nodes, k, attributes) {\n var ndim = attributes.length;\n var min = new Array(ndim);\n var max = new Array(ndim);\n var centroids = new Array(k);\n var centroid = null;\n\n // Find min, max values for each attribute dimension\n for (var i = 0; i < ndim; i++) {\n min[i] = nodes.min(attributes[i]).value;\n max[i] = nodes.max(attributes[i]).value;\n }\n\n // Build k centroids, each represented as an n-dim feature vector\n for (var c = 0; c < k; c++) {\n centroid = [];\n for (var _i = 0; _i < ndim; _i++) {\n centroid[_i] = Math.random() * (max[_i] - min[_i]) + min[_i]; // random initial value\n }\n\n centroids[c] = centroid;\n }\n return centroids;\n};\nvar classify = function classify(node, centroids, distance, attributes, type) {\n var min = Infinity;\n var index = 0;\n for (var i = 0; i < centroids.length; i++) {\n var dist = getDist(distance, node, centroids[i], attributes, type);\n if (dist < min) {\n min = dist;\n index = i;\n }\n }\n return index;\n};\nvar buildCluster = function buildCluster(centroid, nodes, assignment) {\n var cluster = [];\n var node = null;\n for (var n = 0; n < nodes.length; n++) {\n node = nodes[n];\n if (assignment[node.id()] === centroid) {\n //console.log(\"Node \" + node.id() + \" is associated with medoid #: \" + m);\n cluster.push(node);\n }\n }\n return cluster;\n};\nvar haveValuesConverged = function haveValuesConverged(v1, v2, sensitivityThreshold) {\n return Math.abs(v2 - v1) <= sensitivityThreshold;\n};\nvar haveMatricesConverged = function haveMatricesConverged(v1, v2, sensitivityThreshold) {\n for (var i = 0; i < v1.length; i++) {\n for (var j = 0; j < v1[i].length; j++) {\n var diff = Math.abs(v1[i][j] - v2[i][j]);\n if (diff > sensitivityThreshold) {\n return false;\n }\n }\n }\n return true;\n};\nvar seenBefore = function seenBefore(node, medoids, n) {\n for (var i = 0; i < n; i++) {\n if (node === medoids[i]) return true;\n }\n return false;\n};\nvar randomMedoids = function randomMedoids(nodes, k) {\n var medoids = new Array(k);\n\n // For small data sets, the probability of medoid conflict is greater,\n // so we need to check to see if we've already seen or chose this node before.\n if (nodes.length < 50) {\n // Randomly select k medoids from the n nodes\n for (var i = 0; i < k; i++) {\n var node = nodes[Math.floor(Math.random() * nodes.length)];\n\n // If we've already chosen this node to be a medoid, don't choose it again (for small data sets).\n // Instead choose a different random node.\n while (seenBefore(node, medoids, i)) {\n node = nodes[Math.floor(Math.random() * nodes.length)];\n }\n medoids[i] = node;\n }\n } else {\n // Relatively large data set, so pretty safe to not check and just select random nodes\n for (var _i2 = 0; _i2 < k; _i2++) {\n medoids[_i2] = nodes[Math.floor(Math.random() * nodes.length)];\n }\n }\n return medoids;\n};\nvar findCost = function findCost(potentialNewMedoid, cluster, attributes) {\n var cost = 0;\n for (var n = 0; n < cluster.length; n++) {\n cost += getDist('manhattan', cluster[n], potentialNewMedoid, attributes, 'kMedoids');\n }\n return cost;\n};\nvar kMeans = function kMeans(options) {\n var cy = this.cy();\n var nodes = this.nodes();\n var node = null;\n\n // Set parameters of algorithm: # of clusters, distance metric, etc.\n var opts = setOptions$2(options);\n\n // Begin k-means algorithm\n var clusters = new Array(opts.k);\n var assignment = {};\n var centroids;\n\n // Step 1: Initialize centroid positions\n if (opts.testMode) {\n if (typeof opts.testCentroids === 'number') {\n // TODO: implement a seeded random number generator.\n opts.testCentroids;\n centroids = randomCentroids(nodes, opts.k, opts.attributes);\n } else if (_typeof(opts.testCentroids) === 'object') {\n centroids = opts.testCentroids;\n } else {\n centroids = randomCentroids(nodes, opts.k, opts.attributes);\n }\n } else {\n centroids = randomCentroids(nodes, opts.k, opts.attributes);\n }\n var isStillMoving = true;\n var iterations = 0;\n while (isStillMoving && iterations < opts.maxIterations) {\n // Step 2: Assign nodes to the nearest centroid\n for (var n = 0; n < nodes.length; n++) {\n node = nodes[n];\n // Determine which cluster this node belongs to: node id => cluster #\n assignment[node.id()] = classify(node, centroids, opts.distance, opts.attributes, 'kMeans');\n }\n\n // Step 3: For each of the k clusters, update its centroid\n isStillMoving = false;\n for (var c = 0; c < opts.k; c++) {\n // Get all nodes that belong to this cluster\n var cluster = buildCluster(c, nodes, assignment);\n if (cluster.length === 0) {\n // If cluster is empty, break out early & move to next cluster\n continue;\n }\n\n // Update centroids by calculating avg of all nodes within the cluster.\n var ndim = opts.attributes.length;\n var centroid = centroids[c]; // [ dim_1, dim_2, dim_3, ... , dim_n ]\n var newCentroid = new Array(ndim);\n var sum = new Array(ndim);\n for (var d = 0; d < ndim; d++) {\n sum[d] = 0.0;\n for (var i = 0; i < cluster.length; i++) {\n node = cluster[i];\n sum[d] += opts.attributes[d](node);\n }\n newCentroid[d] = sum[d] / cluster.length;\n\n // Check to see if algorithm has converged, i.e. when centroids no longer change\n if (!haveValuesConverged(newCentroid[d], centroid[d], opts.sensitivityThreshold)) {\n isStillMoving = true;\n }\n }\n centroids[c] = newCentroid;\n clusters[c] = cy.collection(cluster);\n }\n iterations++;\n }\n return clusters;\n};\nvar kMedoids = function kMedoids(options) {\n var cy = this.cy();\n var nodes = this.nodes();\n var node = null;\n var opts = setOptions$2(options);\n\n // Begin k-medoids algorithm\n var clusters = new Array(opts.k);\n var medoids;\n var assignment = {};\n var curCost;\n var minCosts = new Array(opts.k); // minimum cost configuration for each cluster\n\n // Step 1: Initialize k medoids\n if (opts.testMode) {\n if (typeof opts.testCentroids === 'number') ; else if (_typeof(opts.testCentroids) === 'object') {\n medoids = opts.testCentroids;\n } else {\n medoids = randomMedoids(nodes, opts.k);\n }\n } else {\n medoids = randomMedoids(nodes, opts.k);\n }\n var isStillMoving = true;\n var iterations = 0;\n while (isStillMoving && iterations < opts.maxIterations) {\n // Step 2: Assign nodes to the nearest medoid\n for (var n = 0; n < nodes.length; n++) {\n node = nodes[n];\n // Determine which cluster this node belongs to: node id => cluster #\n assignment[node.id()] = classify(node, medoids, opts.distance, opts.attributes, 'kMedoids');\n }\n isStillMoving = false;\n // Step 3: For each medoid m, and for each node associated with mediod m,\n // select the node with the lowest configuration cost as new medoid.\n for (var m = 0; m < medoids.length; m++) {\n // Get all nodes that belong to this medoid\n var cluster = buildCluster(m, nodes, assignment);\n if (cluster.length === 0) {\n // If cluster is empty, break out early & move to next cluster\n continue;\n }\n minCosts[m] = findCost(medoids[m], cluster, opts.attributes); // original cost\n\n // Select different medoid if its configuration has the lowest cost\n for (var _n = 0; _n < cluster.length; _n++) {\n curCost = findCost(cluster[_n], cluster, opts.attributes);\n if (curCost < minCosts[m]) {\n minCosts[m] = curCost;\n medoids[m] = cluster[_n];\n isStillMoving = true;\n }\n }\n clusters[m] = cy.collection(cluster);\n }\n iterations++;\n }\n return clusters;\n};\nvar updateCentroids = function updateCentroids(centroids, nodes, U, weight, opts) {\n var numerator, denominator;\n for (var n = 0; n < nodes.length; n++) {\n for (var c = 0; c < centroids.length; c++) {\n weight[n][c] = Math.pow(U[n][c], opts.m);\n }\n }\n for (var _c = 0; _c < centroids.length; _c++) {\n for (var dim = 0; dim < opts.attributes.length; dim++) {\n numerator = 0;\n denominator = 0;\n for (var _n2 = 0; _n2 < nodes.length; _n2++) {\n numerator += weight[_n2][_c] * opts.attributes[dim](nodes[_n2]);\n denominator += weight[_n2][_c];\n }\n centroids[_c][dim] = numerator / denominator;\n }\n }\n};\nvar updateMembership = function updateMembership(U, _U, centroids, nodes, opts) {\n // Save previous step\n for (var i = 0; i < U.length; i++) {\n _U[i] = U[i].slice();\n }\n var sum, numerator, denominator;\n var pow = 2 / (opts.m - 1);\n for (var c = 0; c < centroids.length; c++) {\n for (var n = 0; n < nodes.length; n++) {\n sum = 0;\n for (var k = 0; k < centroids.length; k++) {\n // against all other centroids\n numerator = getDist(opts.distance, nodes[n], centroids[c], opts.attributes, 'cmeans');\n denominator = getDist(opts.distance, nodes[n], centroids[k], opts.attributes, 'cmeans');\n sum += Math.pow(numerator / denominator, pow);\n }\n U[n][c] = 1 / sum;\n }\n }\n};\nvar assign$1 = function assign(nodes, U, opts, cy) {\n var clusters = new Array(opts.k);\n for (var c = 0; c < clusters.length; c++) {\n clusters[c] = [];\n }\n var max;\n var index;\n for (var n = 0; n < U.length; n++) {\n // for each node (U is N x C matrix)\n max = -Infinity;\n index = -1;\n // Determine which cluster the node is most likely to belong in\n for (var _c2 = 0; _c2 < U[0].length; _c2++) {\n if (U[n][_c2] > max) {\n max = U[n][_c2];\n index = _c2;\n }\n }\n clusters[index].push(nodes[n]);\n }\n\n // Turn every array into a collection of nodes\n for (var _c3 = 0; _c3 < clusters.length; _c3++) {\n clusters[_c3] = cy.collection(clusters[_c3]);\n }\n return clusters;\n};\nvar fuzzyCMeans = function fuzzyCMeans(options) {\n var cy = this.cy();\n var nodes = this.nodes();\n var opts = setOptions$2(options);\n\n // Begin fuzzy c-means algorithm\n var clusters;\n var centroids;\n var U;\n var _U;\n var weight;\n\n // Step 1: Initialize letiables.\n _U = new Array(nodes.length);\n for (var i = 0; i < nodes.length; i++) {\n // N x C matrix\n _U[i] = new Array(opts.k);\n }\n U = new Array(nodes.length);\n for (var _i3 = 0; _i3 < nodes.length; _i3++) {\n // N x C matrix\n U[_i3] = new Array(opts.k);\n }\n for (var _i4 = 0; _i4 < nodes.length; _i4++) {\n var total = 0;\n for (var j = 0; j < opts.k; j++) {\n U[_i4][j] = Math.random();\n total += U[_i4][j];\n }\n for (var _j = 0; _j < opts.k; _j++) {\n U[_i4][_j] = U[_i4][_j] / total;\n }\n }\n centroids = new Array(opts.k);\n for (var _i5 = 0; _i5 < opts.k; _i5++) {\n centroids[_i5] = new Array(opts.attributes.length);\n }\n weight = new Array(nodes.length);\n for (var _i6 = 0; _i6 < nodes.length; _i6++) {\n // N x C matrix\n weight[_i6] = new Array(opts.k);\n }\n // end init FCM\n\n var isStillMoving = true;\n var iterations = 0;\n while (isStillMoving && iterations < opts.maxIterations) {\n isStillMoving = false;\n\n // Step 2: Calculate the centroids for each step.\n updateCentroids(centroids, nodes, U, weight, opts);\n\n // Step 3: Update the partition matrix U.\n updateMembership(U, _U, centroids, nodes, opts);\n\n // Step 4: Check for convergence.\n if (!haveMatricesConverged(U, _U, opts.sensitivityThreshold)) {\n isStillMoving = true;\n }\n iterations++;\n }\n\n // Assign nodes to clusters with highest probability.\n clusters = assign$1(nodes, U, opts, cy);\n return {\n clusters: clusters,\n degreeOfMembership: U\n };\n};\nvar kClustering = {\n kMeans: kMeans,\n kMedoids: kMedoids,\n fuzzyCMeans: fuzzyCMeans,\n fcm: fuzzyCMeans\n};\n\n// Implemented by Zoe Xi @zoexi for GSOC 2016\nvar defaults$a = defaults$g({\n distance: 'euclidean',\n // distance metric to compare nodes\n linkage: 'min',\n // linkage criterion : how to determine the distance between clusters of nodes\n mode: 'threshold',\n // mode:'threshold' => clusters must be threshold distance apart\n threshold: Infinity,\n // the distance threshold\n // mode:'dendrogram' => the nodes are organised as leaves in a tree (siblings are close), merging makes clusters\n addDendrogram: false,\n // whether to add the dendrogram to the graph for viz\n dendrogramDepth: 0,\n // depth at which dendrogram branches are merged into the returned clusters\n attributes: [] // array of attr functions\n});\n\nvar linkageAliases = {\n 'single': 'min',\n 'complete': 'max'\n};\nvar setOptions$1 = function setOptions(options) {\n var opts = defaults$a(options);\n var preferredAlias = linkageAliases[opts.linkage];\n if (preferredAlias != null) {\n opts.linkage = preferredAlias;\n }\n return opts;\n};\nvar mergeClosest = function mergeClosest(clusters, index, dists, mins, opts) {\n // Find two closest clusters from cached mins\n var minKey = 0;\n var min = Infinity;\n var dist;\n var attrs = opts.attributes;\n var getDist = function getDist(n1, n2) {\n return clusteringDistance(opts.distance, attrs.length, function (i) {\n return attrs[i](n1);\n }, function (i) {\n return attrs[i](n2);\n }, n1, n2);\n };\n for (var i = 0; i < clusters.length; i++) {\n var key = clusters[i].key;\n var _dist = dists[key][mins[key]];\n if (_dist < min) {\n minKey = key;\n min = _dist;\n }\n }\n if (opts.mode === 'threshold' && min >= opts.threshold || opts.mode === 'dendrogram' && clusters.length === 1) {\n return false;\n }\n var c1 = index[minKey];\n var c2 = index[mins[minKey]];\n var merged;\n\n // Merge two closest clusters\n if (opts.mode === 'dendrogram') {\n merged = {\n left: c1,\n right: c2,\n key: c1.key\n };\n } else {\n merged = {\n value: c1.value.concat(c2.value),\n key: c1.key\n };\n }\n clusters[c1.index] = merged;\n clusters.splice(c2.index, 1);\n index[c1.key] = merged;\n\n // Update distances with new merged cluster\n for (var _i = 0; _i < clusters.length; _i++) {\n var cur = clusters[_i];\n if (c1.key === cur.key) {\n dist = Infinity;\n } else if (opts.linkage === 'min') {\n dist = dists[c1.key][cur.key];\n if (dists[c1.key][cur.key] > dists[c2.key][cur.key]) {\n dist = dists[c2.key][cur.key];\n }\n } else if (opts.linkage === 'max') {\n dist = dists[c1.key][cur.key];\n if (dists[c1.key][cur.key] < dists[c2.key][cur.key]) {\n dist = dists[c2.key][cur.key];\n }\n } else if (opts.linkage === 'mean') {\n dist = (dists[c1.key][cur.key] * c1.size + dists[c2.key][cur.key] * c2.size) / (c1.size + c2.size);\n } else {\n if (opts.mode === 'dendrogram') dist = getDist(cur.value, c1.value);else dist = getDist(cur.value[0], c1.value[0]);\n }\n dists[c1.key][cur.key] = dists[cur.key][c1.key] = dist; // distance matrix is symmetric\n }\n\n // Update cached mins\n for (var _i2 = 0; _i2 < clusters.length; _i2++) {\n var key1 = clusters[_i2].key;\n if (mins[key1] === c1.key || mins[key1] === c2.key) {\n var _min = key1;\n for (var j = 0; j < clusters.length; j++) {\n var key2 = clusters[j].key;\n if (dists[key1][key2] < dists[key1][_min]) {\n _min = key2;\n }\n }\n mins[key1] = _min;\n }\n clusters[_i2].index = _i2;\n }\n\n // Clean up meta data used for clustering\n c1.key = c2.key = c1.index = c2.index = null;\n return true;\n};\nvar getAllChildren = function getAllChildren(root, arr, cy) {\n if (!root) return;\n if (root.value) {\n arr.push(root.value);\n } else {\n if (root.left) getAllChildren(root.left, arr);\n if (root.right) getAllChildren(root.right, arr);\n }\n};\nvar buildDendrogram = function buildDendrogram(root, cy) {\n if (!root) return '';\n if (root.left && root.right) {\n var leftStr = buildDendrogram(root.left, cy);\n var rightStr = buildDendrogram(root.right, cy);\n var node = cy.add({\n group: 'nodes',\n data: {\n id: leftStr + ',' + rightStr\n }\n });\n cy.add({\n group: 'edges',\n data: {\n source: leftStr,\n target: node.id()\n }\n });\n cy.add({\n group: 'edges',\n data: {\n source: rightStr,\n target: node.id()\n }\n });\n return node.id();\n } else if (root.value) {\n return root.value.id();\n }\n};\nvar buildClustersFromTree = function buildClustersFromTree(root, k, cy) {\n if (!root) return [];\n var left = [],\n right = [],\n leaves = [];\n if (k === 0) {\n // don't cut tree, simply return all nodes as 1 single cluster\n if (root.left) getAllChildren(root.left, left);\n if (root.right) getAllChildren(root.right, right);\n leaves = left.concat(right);\n return [cy.collection(leaves)];\n } else if (k === 1) {\n // cut at root\n\n if (root.value) {\n // leaf node\n return [cy.collection(root.value)];\n } else {\n if (root.left) getAllChildren(root.left, left);\n if (root.right) getAllChildren(root.right, right);\n return [cy.collection(left), cy.collection(right)];\n }\n } else {\n if (root.value) {\n return [cy.collection(root.value)];\n } else {\n if (root.left) left = buildClustersFromTree(root.left, k - 1, cy);\n if (root.right) right = buildClustersFromTree(root.right, k - 1, cy);\n return left.concat(right);\n }\n }\n};\n\nvar hierarchicalClustering = function hierarchicalClustering(options) {\n var cy = this.cy();\n var nodes = this.nodes();\n\n // Set parameters of algorithm: linkage type, distance metric, etc.\n var opts = setOptions$1(options);\n var attrs = opts.attributes;\n var getDist = function getDist(n1, n2) {\n return clusteringDistance(opts.distance, attrs.length, function (i) {\n return attrs[i](n1);\n }, function (i) {\n return attrs[i](n2);\n }, n1, n2);\n };\n\n // Begin hierarchical algorithm\n var clusters = [];\n var dists = []; // distances between each pair of clusters\n var mins = []; // closest cluster for each cluster\n var index = []; // hash of all clusters by key\n\n // In agglomerative (bottom-up) clustering, each node starts as its own cluster\n for (var n = 0; n < nodes.length; n++) {\n var cluster = {\n value: opts.mode === 'dendrogram' ? nodes[n] : [nodes[n]],\n key: n,\n index: n\n };\n clusters[n] = cluster;\n index[n] = cluster;\n dists[n] = [];\n mins[n] = 0;\n }\n\n // Calculate the distance between each pair of clusters\n for (var i = 0; i < clusters.length; i++) {\n for (var j = 0; j <= i; j++) {\n var dist = void 0;\n if (opts.mode === 'dendrogram') {\n // modes store cluster values differently\n dist = i === j ? Infinity : getDist(clusters[i].value, clusters[j].value);\n } else {\n dist = i === j ? Infinity : getDist(clusters[i].value[0], clusters[j].value[0]);\n }\n dists[i][j] = dist;\n dists[j][i] = dist;\n if (dist < dists[i][mins[i]]) {\n mins[i] = j; // Cache mins: closest cluster to cluster i is cluster j\n }\n }\n }\n\n // Find the closest pair of clusters and merge them into a single cluster.\n // Update distances between new cluster and each of the old clusters, and loop until threshold reached.\n var merged = mergeClosest(clusters, index, dists, mins, opts);\n while (merged) {\n merged = mergeClosest(clusters, index, dists, mins, opts);\n }\n var retClusters;\n\n // Dendrogram mode builds the hierarchy and adds intermediary nodes + edges\n // in addition to returning the clusters.\n if (opts.mode === 'dendrogram') {\n retClusters = buildClustersFromTree(clusters[0], opts.dendrogramDepth, cy);\n if (opts.addDendrogram) buildDendrogram(clusters[0], cy);\n } else {\n // Regular mode simply returns the clusters\n\n retClusters = new Array(clusters.length);\n clusters.forEach(function (cluster, i) {\n // Clean up meta data used for clustering\n cluster.key = cluster.index = null;\n retClusters[i] = cy.collection(cluster.value);\n });\n }\n return retClusters;\n};\nvar hierarchicalClustering$1 = {\n hierarchicalClustering: hierarchicalClustering,\n hca: hierarchicalClustering\n};\n\n// Implemented by Zoe Xi @zoexi for GSOC 2016\nvar defaults$9 = defaults$g({\n distance: 'euclidean',\n // distance metric to compare attributes between two nodes\n preference: 'median',\n // suitability of a data point to serve as an exemplar\n damping: 0.8,\n // damping factor between [0.5, 1)\n maxIterations: 1000,\n // max number of iterations to run\n minIterations: 100,\n // min number of iterations to run in order for clustering to stop\n attributes: [// functions to quantify the similarity between any two points\n // e.g. node => node.data('weight')\n ]\n});\nvar setOptions = function setOptions(options) {\n var dmp = options.damping;\n var pref = options.preference;\n if (!(0.5 <= dmp && dmp < 1)) {\n error(\"Damping must range on [0.5, 1). Got: \".concat(dmp));\n }\n var validPrefs = ['median', 'mean', 'min', 'max'];\n if (!(validPrefs.some(function (v) {\n return v === pref;\n }) || number$1(pref))) {\n error(\"Preference must be one of [\".concat(validPrefs.map(function (p) {\n return \"'\".concat(p, \"'\");\n }).join(', '), \"] or a number. Got: \").concat(pref));\n }\n return defaults$9(options);\n};\n\nvar getSimilarity = function getSimilarity(type, n1, n2, attributes) {\n var attr = function attr(n, i) {\n return attributes[i](n);\n };\n\n // nb negative because similarity should have an inverse relationship to distance\n return -clusteringDistance(type, attributes.length, function (i) {\n return attr(n1, i);\n }, function (i) {\n return attr(n2, i);\n }, n1, n2);\n};\nvar getPreference = function getPreference(S, preference) {\n // larger preference = greater # of clusters\n var p = null;\n if (preference === 'median') {\n p = median(S);\n } else if (preference === 'mean') {\n p = mean(S);\n } else if (preference === 'min') {\n p = min(S);\n } else if (preference === 'max') {\n p = max(S);\n } else {\n // Custom preference number, as set by user\n p = preference;\n }\n return p;\n};\nvar findExemplars = function findExemplars(n, R, A) {\n var indices = [];\n for (var i = 0; i < n; i++) {\n if (R[i * n + i] + A[i * n + i] > 0) {\n indices.push(i);\n }\n }\n return indices;\n};\nvar assignClusters = function assignClusters(n, S, exemplars) {\n var clusters = [];\n for (var i = 0; i < n; i++) {\n var index = -1;\n var max = -Infinity;\n for (var ei = 0; ei < exemplars.length; ei++) {\n var e = exemplars[ei];\n if (S[i * n + e] > max) {\n index = e;\n max = S[i * n + e];\n }\n }\n if (index > 0) {\n clusters.push(index);\n }\n }\n for (var _ei = 0; _ei < exemplars.length; _ei++) {\n clusters[exemplars[_ei]] = exemplars[_ei];\n }\n return clusters;\n};\nvar assign = function assign(n, S, exemplars) {\n var clusters = assignClusters(n, S, exemplars);\n for (var ei = 0; ei < exemplars.length; ei++) {\n var ii = [];\n for (var c = 0; c < clusters.length; c++) {\n if (clusters[c] === exemplars[ei]) {\n ii.push(c);\n }\n }\n var maxI = -1;\n var maxSum = -Infinity;\n for (var i = 0; i < ii.length; i++) {\n var sum = 0;\n for (var j = 0; j < ii.length; j++) {\n sum += S[ii[j] * n + ii[i]];\n }\n if (sum > maxSum) {\n maxI = i;\n maxSum = sum;\n }\n }\n exemplars[ei] = ii[maxI];\n }\n clusters = assignClusters(n, S, exemplars);\n return clusters;\n};\nvar affinityPropagation = function affinityPropagation(options) {\n var cy = this.cy();\n var nodes = this.nodes();\n var opts = setOptions(options);\n\n // Map each node to its position in node array\n var id2position = {};\n for (var i = 0; i < nodes.length; i++) {\n id2position[nodes[i].id()] = i;\n }\n\n // Begin affinity propagation algorithm\n\n var n; // number of data points\n var n2; // size of matrices\n var S; // similarity matrix (1D array)\n var p; // preference/suitability of a data point to serve as an exemplar\n var R; // responsibility matrix (1D array)\n var A; // availability matrix (1D array)\n\n n = nodes.length;\n n2 = n * n;\n\n // Initialize and build S similarity matrix\n S = new Array(n2);\n for (var _i = 0; _i < n2; _i++) {\n S[_i] = -Infinity; // for cases where two data points shouldn't be linked together\n }\n\n for (var _i2 = 0; _i2 < n; _i2++) {\n for (var j = 0; j < n; j++) {\n if (_i2 !== j) {\n S[_i2 * n + j] = getSimilarity(opts.distance, nodes[_i2], nodes[j], opts.attributes);\n }\n }\n }\n\n // Place preferences on the diagonal of S\n p = getPreference(S, opts.preference);\n for (var _i3 = 0; _i3 < n; _i3++) {\n S[_i3 * n + _i3] = p;\n }\n\n // Initialize R responsibility matrix\n R = new Array(n2);\n for (var _i4 = 0; _i4 < n2; _i4++) {\n R[_i4] = 0.0;\n }\n\n // Initialize A availability matrix\n A = new Array(n2);\n for (var _i5 = 0; _i5 < n2; _i5++) {\n A[_i5] = 0.0;\n }\n var old = new Array(n);\n var Rp = new Array(n);\n var se = new Array(n);\n for (var _i6 = 0; _i6 < n; _i6++) {\n old[_i6] = 0.0;\n Rp[_i6] = 0.0;\n se[_i6] = 0;\n }\n var e = new Array(n * opts.minIterations);\n for (var _i7 = 0; _i7 < e.length; _i7++) {\n e[_i7] = 0;\n }\n var iter;\n for (iter = 0; iter < opts.maxIterations; iter++) {\n // main algorithmic loop\n\n // Update R responsibility matrix\n for (var _i8 = 0; _i8 < n; _i8++) {\n var max = -Infinity,\n max2 = -Infinity,\n maxI = -1,\n AS = 0.0;\n for (var _j = 0; _j < n; _j++) {\n old[_j] = R[_i8 * n + _j];\n AS = A[_i8 * n + _j] + S[_i8 * n + _j];\n if (AS >= max) {\n max2 = max;\n max = AS;\n maxI = _j;\n } else if (AS > max2) {\n max2 = AS;\n }\n }\n for (var _j2 = 0; _j2 < n; _j2++) {\n R[_i8 * n + _j2] = (1 - opts.damping) * (S[_i8 * n + _j2] - max) + opts.damping * old[_j2];\n }\n R[_i8 * n + maxI] = (1 - opts.damping) * (S[_i8 * n + maxI] - max2) + opts.damping * old[maxI];\n }\n\n // Update A availability matrix\n for (var _i9 = 0; _i9 < n; _i9++) {\n var sum = 0;\n for (var _j3 = 0; _j3 < n; _j3++) {\n old[_j3] = A[_j3 * n + _i9];\n Rp[_j3] = Math.max(0, R[_j3 * n + _i9]);\n sum += Rp[_j3];\n }\n sum -= Rp[_i9];\n Rp[_i9] = R[_i9 * n + _i9];\n sum += Rp[_i9];\n for (var _j4 = 0; _j4 < n; _j4++) {\n A[_j4 * n + _i9] = (1 - opts.damping) * Math.min(0, sum - Rp[_j4]) + opts.damping * old[_j4];\n }\n A[_i9 * n + _i9] = (1 - opts.damping) * (sum - Rp[_i9]) + opts.damping * old[_i9];\n }\n\n // Check for convergence\n var K = 0;\n for (var _i10 = 0; _i10 < n; _i10++) {\n var E = A[_i10 * n + _i10] + R[_i10 * n + _i10] > 0 ? 1 : 0;\n e[iter % opts.minIterations * n + _i10] = E;\n K += E;\n }\n if (K > 0 && (iter >= opts.minIterations - 1 || iter == opts.maxIterations - 1)) {\n var _sum = 0;\n for (var _i11 = 0; _i11 < n; _i11++) {\n se[_i11] = 0;\n for (var _j5 = 0; _j5 < opts.minIterations; _j5++) {\n se[_i11] += e[_j5 * n + _i11];\n }\n if (se[_i11] === 0 || se[_i11] === opts.minIterations) {\n _sum++;\n }\n }\n if (_sum === n) {\n // then we have convergence\n break;\n }\n }\n }\n\n // Identify exemplars (cluster centers)\n var exemplarsIndices = findExemplars(n, R, A);\n\n // Assign nodes to clusters\n var clusterIndices = assign(n, S, exemplarsIndices);\n var clusters = {};\n for (var c = 0; c < exemplarsIndices.length; c++) {\n clusters[exemplarsIndices[c]] = [];\n }\n for (var _i12 = 0; _i12 < nodes.length; _i12++) {\n var pos = id2position[nodes[_i12].id()];\n var clusterIndex = clusterIndices[pos];\n if (clusterIndex != null) {\n // the node may have not been assigned a cluster if no valid attributes were specified\n clusters[clusterIndex].push(nodes[_i12]);\n }\n }\n var retClusters = new Array(exemplarsIndices.length);\n for (var _c = 0; _c < exemplarsIndices.length; _c++) {\n retClusters[_c] = cy.collection(clusters[exemplarsIndices[_c]]);\n }\n return retClusters;\n};\nvar affinityPropagation$1 = {\n affinityPropagation: affinityPropagation,\n ap: affinityPropagation\n};\n\nvar hierholzerDefaults = defaults$g({\n root: undefined,\n directed: false\n});\nvar elesfn$k = {\n hierholzer: function hierholzer(options) {\n if (!plainObject(options)) {\n var args = arguments;\n options = {\n root: args[0],\n directed: args[1]\n };\n }\n var _hierholzerDefaults = hierholzerDefaults(options),\n root = _hierholzerDefaults.root,\n directed = _hierholzerDefaults.directed;\n var eles = this;\n var dflag = false;\n var oddIn;\n var oddOut;\n var startVertex;\n if (root) startVertex = string(root) ? this.filter(root)[0].id() : root[0].id();\n var nodes = {};\n var edges = {};\n if (directed) {\n eles.forEach(function (ele) {\n var id = ele.id();\n if (ele.isNode()) {\n var ind = ele.indegree(true);\n var outd = ele.outdegree(true);\n var d1 = ind - outd;\n var d2 = outd - ind;\n if (d1 == 1) {\n if (oddIn) dflag = true;else oddIn = id;\n } else if (d2 == 1) {\n if (oddOut) dflag = true;else oddOut = id;\n } else if (d2 > 1 || d1 > 1) {\n dflag = true;\n }\n nodes[id] = [];\n ele.outgoers().forEach(function (e) {\n if (e.isEdge()) nodes[id].push(e.id());\n });\n } else {\n edges[id] = [undefined, ele.target().id()];\n }\n });\n } else {\n eles.forEach(function (ele) {\n var id = ele.id();\n if (ele.isNode()) {\n var d = ele.degree(true);\n if (d % 2) {\n if (!oddIn) oddIn = id;else if (!oddOut) oddOut = id;else dflag = true;\n }\n nodes[id] = [];\n ele.connectedEdges().forEach(function (e) {\n return nodes[id].push(e.id());\n });\n } else {\n edges[id] = [ele.source().id(), ele.target().id()];\n }\n });\n }\n var result = {\n found: false,\n trail: undefined\n };\n if (dflag) return result;else if (oddOut && oddIn) {\n if (directed) {\n if (startVertex && oddOut != startVertex) {\n return result;\n }\n startVertex = oddOut;\n } else {\n if (startVertex && oddOut != startVertex && oddIn != startVertex) {\n return result;\n } else if (!startVertex) {\n startVertex = oddOut;\n }\n }\n } else {\n if (!startVertex) startVertex = eles[0].id();\n }\n var walk = function walk(v) {\n var currentNode = v;\n var subtour = [v];\n var adj, adjTail, adjHead;\n while (nodes[currentNode].length) {\n adj = nodes[currentNode].shift();\n adjTail = edges[adj][0];\n adjHead = edges[adj][1];\n if (currentNode != adjHead) {\n nodes[adjHead] = nodes[adjHead].filter(function (e) {\n return e != adj;\n });\n currentNode = adjHead;\n } else if (!directed && currentNode != adjTail) {\n nodes[adjTail] = nodes[adjTail].filter(function (e) {\n return e != adj;\n });\n currentNode = adjTail;\n }\n subtour.unshift(adj);\n subtour.unshift(currentNode);\n }\n return subtour;\n };\n var trail = [];\n var subtour = [];\n subtour = walk(startVertex);\n while (subtour.length != 1) {\n if (nodes[subtour[0]].length == 0) {\n trail.unshift(eles.getElementById(subtour.shift()));\n trail.unshift(eles.getElementById(subtour.shift()));\n } else {\n subtour = walk(subtour.shift()).concat(subtour);\n }\n }\n trail.unshift(eles.getElementById(subtour.shift())); // final node\n\n for (var d in nodes) {\n if (nodes[d].length) {\n return result;\n }\n }\n result.found = true;\n result.trail = this.spawn(trail, true);\n return result;\n }\n};\n\nvar hopcroftTarjanBiconnected = function hopcroftTarjanBiconnected() {\n var eles = this;\n var nodes = {};\n var id = 0;\n var edgeCount = 0;\n var components = [];\n var stack = [];\n var visitedEdges = {};\n var buildComponent = function buildComponent(x, y) {\n var i = stack.length - 1;\n var cutset = [];\n var component = eles.spawn();\n while (stack[i].x != x || stack[i].y != y) {\n cutset.push(stack.pop().edge);\n i--;\n }\n cutset.push(stack.pop().edge);\n cutset.forEach(function (edge) {\n var connectedNodes = edge.connectedNodes().intersection(eles);\n component.merge(edge);\n connectedNodes.forEach(function (node) {\n var nodeId = node.id();\n var connectedEdges = node.connectedEdges().intersection(eles);\n component.merge(node);\n if (!nodes[nodeId].cutVertex) {\n component.merge(connectedEdges);\n } else {\n component.merge(connectedEdges.filter(function (edge) {\n return edge.isLoop();\n }));\n }\n });\n });\n components.push(component);\n };\n var biconnectedSearch = function biconnectedSearch(root, currentNode, parent) {\n if (root === parent) edgeCount += 1;\n nodes[currentNode] = {\n id: id,\n low: id++,\n cutVertex: false\n };\n var edges = eles.getElementById(currentNode).connectedEdges().intersection(eles);\n if (edges.size() === 0) {\n components.push(eles.spawn(eles.getElementById(currentNode)));\n } else {\n var sourceId, targetId, otherNodeId, edgeId;\n edges.forEach(function (edge) {\n sourceId = edge.source().id();\n targetId = edge.target().id();\n otherNodeId = sourceId === currentNode ? targetId : sourceId;\n if (otherNodeId !== parent) {\n edgeId = edge.id();\n if (!visitedEdges[edgeId]) {\n visitedEdges[edgeId] = true;\n stack.push({\n x: currentNode,\n y: otherNodeId,\n edge: edge\n });\n }\n if (!(otherNodeId in nodes)) {\n biconnectedSearch(root, otherNodeId, currentNode);\n nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].low);\n if (nodes[currentNode].id <= nodes[otherNodeId].low) {\n nodes[currentNode].cutVertex = true;\n buildComponent(currentNode, otherNodeId);\n }\n } else {\n nodes[currentNode].low = Math.min(nodes[currentNode].low, nodes[otherNodeId].id);\n }\n }\n });\n }\n };\n eles.forEach(function (ele) {\n if (ele.isNode()) {\n var nodeId = ele.id();\n if (!(nodeId in nodes)) {\n edgeCount = 0;\n biconnectedSearch(nodeId, nodeId);\n nodes[nodeId].cutVertex = edgeCount > 1;\n }\n }\n });\n var cutVertices = Object.keys(nodes).filter(function (id) {\n return nodes[id].cutVertex;\n }).map(function (id) {\n return eles.getElementById(id);\n });\n return {\n cut: eles.spawn(cutVertices),\n components: components\n };\n};\nvar hopcroftTarjanBiconnected$1 = {\n hopcroftTarjanBiconnected: hopcroftTarjanBiconnected,\n htbc: hopcroftTarjanBiconnected,\n htb: hopcroftTarjanBiconnected,\n hopcroftTarjanBiconnectedComponents: hopcroftTarjanBiconnected\n};\n\nvar tarjanStronglyConnected = function tarjanStronglyConnected() {\n var eles = this;\n var nodes = {};\n var index = 0;\n var components = [];\n var stack = [];\n var cut = eles.spawn(eles);\n var stronglyConnectedSearch = function stronglyConnectedSearch(sourceNodeId) {\n stack.push(sourceNodeId);\n nodes[sourceNodeId] = {\n index: index,\n low: index++,\n explored: false\n };\n var connectedEdges = eles.getElementById(sourceNodeId).connectedEdges().intersection(eles);\n connectedEdges.forEach(function (edge) {\n var targetNodeId = edge.target().id();\n if (targetNodeId !== sourceNodeId) {\n if (!(targetNodeId in nodes)) {\n stronglyConnectedSearch(targetNodeId);\n }\n if (!nodes[targetNodeId].explored) {\n nodes[sourceNodeId].low = Math.min(nodes[sourceNodeId].low, nodes[targetNodeId].low);\n }\n }\n });\n if (nodes[sourceNodeId].index === nodes[sourceNodeId].low) {\n var componentNodes = eles.spawn();\n for (;;) {\n var nodeId = stack.pop();\n componentNodes.merge(eles.getElementById(nodeId));\n nodes[nodeId].low = nodes[sourceNodeId].index;\n nodes[nodeId].explored = true;\n if (nodeId === sourceNodeId) {\n break;\n }\n }\n var componentEdges = componentNodes.edgesWith(componentNodes);\n var component = componentNodes.merge(componentEdges);\n components.push(component);\n cut = cut.difference(component);\n }\n };\n eles.forEach(function (ele) {\n if (ele.isNode()) {\n var nodeId = ele.id();\n if (!(nodeId in nodes)) {\n stronglyConnectedSearch(nodeId);\n }\n }\n });\n return {\n cut: cut,\n components: components\n };\n};\nvar tarjanStronglyConnected$1 = {\n tarjanStronglyConnected: tarjanStronglyConnected,\n tsc: tarjanStronglyConnected,\n tscc: tarjanStronglyConnected,\n tarjanStronglyConnectedComponents: tarjanStronglyConnected\n};\n\nvar elesfn$j = {};\n[elesfn$v, elesfn$u, elesfn$t, elesfn$s, elesfn$r, elesfn$q, elesfn$p, elesfn$o, elesfn$n, elesfn$m, elesfn$l, markovClustering$1, kClustering, hierarchicalClustering$1, affinityPropagation$1, elesfn$k, hopcroftTarjanBiconnected$1, tarjanStronglyConnected$1].forEach(function (props) {\n extend(elesfn$j, props);\n});\n\n/*!\nEmbeddable Minimum Strictly-Compliant Promises/A+ 1.1.1 Thenable\nCopyright (c) 2013-2014 Ralf S. Engelschall (http://engelschall.com)\nLicensed under The MIT License (http://opensource.org/licenses/MIT)\n*/\n\n/* promise states [Promises/A+ 2.1] */\nvar STATE_PENDING = 0; /* [Promises/A+ 2.1.1] */\nvar STATE_FULFILLED = 1; /* [Promises/A+ 2.1.2] */\nvar STATE_REJECTED = 2; /* [Promises/A+ 2.1.3] */\n\n/* promise object constructor */\nvar api = function api(executor) {\n /* optionally support non-constructor/plain-function call */\n if (!(this instanceof api)) return new api(executor);\n\n /* initialize object */\n this.id = 'Thenable/1.0.7';\n this.state = STATE_PENDING; /* initial state */\n this.fulfillValue = undefined; /* initial value */ /* [Promises/A+ 1.3, 2.1.2.2] */\n this.rejectReason = undefined; /* initial reason */ /* [Promises/A+ 1.5, 2.1.3.2] */\n this.onFulfilled = []; /* initial handlers */\n this.onRejected = []; /* initial handlers */\n\n /* provide optional information-hiding proxy */\n this.proxy = {\n then: this.then.bind(this)\n };\n\n /* support optional executor function */\n if (typeof executor === 'function') executor.call(this, this.fulfill.bind(this), this.reject.bind(this));\n};\n\n/* promise API methods */\napi.prototype = {\n /* promise resolving methods */\n fulfill: function fulfill(value) {\n return deliver(this, STATE_FULFILLED, 'fulfillValue', value);\n },\n reject: function reject(value) {\n return deliver(this, STATE_REJECTED, 'rejectReason', value);\n },\n /* \"The then Method\" [Promises/A+ 1.1, 1.2, 2.2] */\n then: function then(onFulfilled, onRejected) {\n var curr = this;\n var next = new api(); /* [Promises/A+ 2.2.7] */\n curr.onFulfilled.push(resolver(onFulfilled, next, 'fulfill')); /* [Promises/A+ 2.2.2/2.2.6] */\n curr.onRejected.push(resolver(onRejected, next, 'reject')); /* [Promises/A+ 2.2.3/2.2.6] */\n execute(curr);\n return next.proxy; /* [Promises/A+ 2.2.7, 3.3] */\n }\n};\n\n/* deliver an action */\nvar deliver = function deliver(curr, state, name, value) {\n if (curr.state === STATE_PENDING) {\n curr.state = state; /* [Promises/A+ 2.1.2.1, 2.1.3.1] */\n curr[name] = value; /* [Promises/A+ 2.1.2.2, 2.1.3.2] */\n execute(curr);\n }\n return curr;\n};\n\n/* execute all handlers */\nvar execute = function execute(curr) {\n if (curr.state === STATE_FULFILLED) execute_handlers(curr, 'onFulfilled', curr.fulfillValue);else if (curr.state === STATE_REJECTED) execute_handlers(curr, 'onRejected', curr.rejectReason);\n};\n\n/* execute particular set of handlers */\nvar execute_handlers = function execute_handlers(curr, name, value) {\n /* global setImmediate: true */\n /* global setTimeout: true */\n\n /* short-circuit processing */\n if (curr[name].length === 0) return;\n\n /* iterate over all handlers, exactly once */\n var handlers = curr[name];\n curr[name] = []; /* [Promises/A+ 2.2.2.3, 2.2.3.3] */\n var func = function func() {\n for (var i = 0; i < handlers.length; i++) {\n handlers[i](value);\n } /* [Promises/A+ 2.2.5] */\n };\n\n /* execute procedure asynchronously */ /* [Promises/A+ 2.2.4, 3.1] */\n if (typeof setImmediate === 'function') setImmediate(func);else setTimeout(func, 0);\n};\n\n/* generate a resolver function */\nvar resolver = function resolver(cb, next, method) {\n return function (value) {\n if (typeof cb !== 'function') /* [Promises/A+ 2.2.1, 2.2.7.3, 2.2.7.4] */\n next[method].call(next, value); /* [Promises/A+ 2.2.7.3, 2.2.7.4] */else {\n var result;\n try {\n result = cb(value);\n } /* [Promises/A+ 2.2.2.1, 2.2.3.1, 2.2.5, 3.2] */ catch (e) {\n next.reject(e); /* [Promises/A+ 2.2.7.2] */\n return;\n }\n resolve(next, result); /* [Promises/A+ 2.2.7.1] */\n }\n };\n};\n\n/* \"Promise Resolution Procedure\" */ /* [Promises/A+ 2.3] */\nvar resolve = function resolve(promise, x) {\n /* sanity check arguments */ /* [Promises/A+ 2.3.1] */\n if (promise === x || promise.proxy === x) {\n promise.reject(new TypeError('cannot resolve promise with itself'));\n return;\n }\n\n /* surgically check for a \"then\" method\n (mainly to just call the \"getter\" of \"then\" only once) */\n var then;\n if (_typeof(x) === 'object' && x !== null || typeof x === 'function') {\n try {\n then = x.then;\n } /* [Promises/A+ 2.3.3.1, 3.5] */ catch (e) {\n promise.reject(e); /* [Promises/A+ 2.3.3.2] */\n return;\n }\n }\n\n /* handle own Thenables [Promises/A+ 2.3.2]\n and similar \"thenables\" [Promises/A+ 2.3.3] */\n if (typeof then === 'function') {\n var resolved = false;\n try {\n /* call retrieved \"then\" method */ /* [Promises/A+ 2.3.3.3] */\n then.call(x, /* resolvePromise */ /* [Promises/A+ 2.3.3.3.1] */\n function (y) {\n if (resolved) return;\n resolved = true; /* [Promises/A+ 2.3.3.3.3] */\n if (y === x) /* [Promises/A+ 3.6] */\n promise.reject(new TypeError('circular thenable chain'));else resolve(promise, y);\n }, /* rejectPromise */ /* [Promises/A+ 2.3.3.3.2] */\n function (r) {\n if (resolved) return;\n resolved = true; /* [Promises/A+ 2.3.3.3.3] */\n promise.reject(r);\n });\n } catch (e) {\n if (!resolved) /* [Promises/A+ 2.3.3.3.3] */\n promise.reject(e); /* [Promises/A+ 2.3.3.3.4] */\n }\n\n return;\n }\n\n /* handle other values */\n promise.fulfill(x); /* [Promises/A+ 2.3.4, 2.3.3.4] */\n};\n\n// so we always have Promise.all()\napi.all = function (ps) {\n return new api(function (resolveAll, rejectAll) {\n var vals = new Array(ps.length);\n var doneCount = 0;\n var fulfill = function fulfill(i, val) {\n vals[i] = val;\n doneCount++;\n if (doneCount === ps.length) {\n resolveAll(vals);\n }\n };\n for (var i = 0; i < ps.length; i++) {\n (function (i) {\n var p = ps[i];\n var isPromise = p != null && p.then != null;\n if (isPromise) {\n p.then(function (val) {\n fulfill(i, val);\n }, function (err) {\n rejectAll(err);\n });\n } else {\n var val = p;\n fulfill(i, val);\n }\n })(i);\n }\n });\n};\napi.resolve = function (val) {\n return new api(function (resolve, reject) {\n resolve(val);\n });\n};\napi.reject = function (val) {\n return new api(function (resolve, reject) {\n reject(val);\n });\n};\nvar Promise$1 = typeof Promise !== 'undefined' ? Promise : api; // eslint-disable-line no-undef\n\nvar Animation = function Animation(target, opts, opts2) {\n var isCore = core(target);\n var isEle = !isCore;\n var _p = this._private = extend({\n duration: 1000\n }, opts, opts2);\n _p.target = target;\n _p.style = _p.style || _p.css;\n _p.started = false;\n _p.playing = false;\n _p.hooked = false;\n _p.applying = false;\n _p.progress = 0;\n _p.completes = [];\n _p.frames = [];\n if (_p.complete && fn$6(_p.complete)) {\n _p.completes.push(_p.complete);\n }\n if (isEle) {\n var pos = target.position();\n _p.startPosition = _p.startPosition || {\n x: pos.x,\n y: pos.y\n };\n _p.startStyle = _p.startStyle || target.cy().style().getAnimationStartStyle(target, _p.style);\n }\n if (isCore) {\n var pan = target.pan();\n _p.startPan = {\n x: pan.x,\n y: pan.y\n };\n _p.startZoom = target.zoom();\n }\n\n // for future timeline/animations impl\n this.length = 1;\n this[0] = this;\n};\nvar anifn = Animation.prototype;\nextend(anifn, {\n instanceString: function instanceString() {\n return 'animation';\n },\n hook: function hook() {\n var _p = this._private;\n if (!_p.hooked) {\n // add to target's animation queue\n var q;\n var tAni = _p.target._private.animation;\n if (_p.queue) {\n q = tAni.queue;\n } else {\n q = tAni.current;\n }\n q.push(this);\n\n // add to the animation loop pool\n if (elementOrCollection(_p.target)) {\n _p.target.cy().addToAnimationPool(_p.target);\n }\n _p.hooked = true;\n }\n return this;\n },\n play: function play() {\n var _p = this._private;\n\n // autorewind\n if (_p.progress === 1) {\n _p.progress = 0;\n }\n _p.playing = true;\n _p.started = false; // needs to be started by animation loop\n _p.stopped = false;\n this.hook();\n\n // the animation loop will start the animation...\n\n return this;\n },\n playing: function playing() {\n return this._private.playing;\n },\n apply: function apply() {\n var _p = this._private;\n _p.applying = true;\n _p.started = false; // needs to be started by animation loop\n _p.stopped = false;\n this.hook();\n\n // the animation loop will apply the animation at this progress\n\n return this;\n },\n applying: function applying() {\n return this._private.applying;\n },\n pause: function pause() {\n var _p = this._private;\n _p.playing = false;\n _p.started = false;\n return this;\n },\n stop: function stop() {\n var _p = this._private;\n _p.playing = false;\n _p.started = false;\n _p.stopped = true; // to be removed from animation queues\n\n return this;\n },\n rewind: function rewind() {\n return this.progress(0);\n },\n fastforward: function fastforward() {\n return this.progress(1);\n },\n time: function time(t) {\n var _p = this._private;\n if (t === undefined) {\n return _p.progress * _p.duration;\n } else {\n return this.progress(t / _p.duration);\n }\n },\n progress: function progress(p) {\n var _p = this._private;\n var wasPlaying = _p.playing;\n if (p === undefined) {\n return _p.progress;\n } else {\n if (wasPlaying) {\n this.pause();\n }\n _p.progress = p;\n _p.started = false;\n if (wasPlaying) {\n this.play();\n }\n }\n return this;\n },\n completed: function completed() {\n return this._private.progress === 1;\n },\n reverse: function reverse() {\n var _p = this._private;\n var wasPlaying = _p.playing;\n if (wasPlaying) {\n this.pause();\n }\n _p.progress = 1 - _p.progress;\n _p.started = false;\n var swap = function swap(a, b) {\n var _pa = _p[a];\n if (_pa == null) {\n return;\n }\n _p[a] = _p[b];\n _p[b] = _pa;\n };\n swap('zoom', 'startZoom');\n swap('pan', 'startPan');\n swap('position', 'startPosition');\n\n // swap styles\n if (_p.style) {\n for (var i = 0; i < _p.style.length; i++) {\n var prop = _p.style[i];\n var name = prop.name;\n var startStyleProp = _p.startStyle[name];\n _p.startStyle[name] = prop;\n _p.style[i] = startStyleProp;\n }\n }\n if (wasPlaying) {\n this.play();\n }\n return this;\n },\n promise: function promise(type) {\n var _p = this._private;\n var arr;\n switch (type) {\n case 'frame':\n arr = _p.frames;\n break;\n default:\n case 'complete':\n case 'completed':\n arr = _p.completes;\n }\n return new Promise$1(function (resolve, reject) {\n arr.push(function () {\n resolve();\n });\n });\n }\n});\nanifn.complete = anifn.completed;\nanifn.run = anifn.play;\nanifn.running = anifn.playing;\n\nvar define$3 = {\n animated: function animated() {\n return function animatedImpl() {\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n if (!cy.styleEnabled()) {\n return false;\n }\n var ele = all[0];\n if (ele) {\n return ele._private.animation.current.length > 0;\n }\n };\n },\n // animated\n\n clearQueue: function clearQueue() {\n return function clearQueueImpl() {\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n if (!cy.styleEnabled()) {\n return this;\n }\n for (var i = 0; i < all.length; i++) {\n var ele = all[i];\n ele._private.animation.queue = [];\n }\n return this;\n };\n },\n // clearQueue\n\n delay: function delay() {\n return function delayImpl(time, complete) {\n var cy = this._private.cy || this;\n if (!cy.styleEnabled()) {\n return this;\n }\n return this.animate({\n delay: time,\n duration: time,\n complete: complete\n });\n };\n },\n // delay\n\n delayAnimation: function delayAnimation() {\n return function delayAnimationImpl(time, complete) {\n var cy = this._private.cy || this;\n if (!cy.styleEnabled()) {\n return this;\n }\n return this.animation({\n delay: time,\n duration: time,\n complete: complete\n });\n };\n },\n // delay\n\n animation: function animation() {\n return function animationImpl(properties, params) {\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n var isCore = !selfIsArrayLike;\n var isEles = !isCore;\n if (!cy.styleEnabled()) {\n return this;\n }\n var style = cy.style();\n properties = extend({}, properties, params);\n var propertiesEmpty = Object.keys(properties).length === 0;\n if (propertiesEmpty) {\n return new Animation(all[0], properties); // nothing to animate\n }\n\n if (properties.duration === undefined) {\n properties.duration = 400;\n }\n switch (properties.duration) {\n case 'slow':\n properties.duration = 600;\n break;\n case 'fast':\n properties.duration = 200;\n break;\n }\n if (isEles) {\n properties.style = style.getPropsList(properties.style || properties.css);\n properties.css = undefined;\n }\n if (isEles && properties.renderedPosition != null) {\n var rpos = properties.renderedPosition;\n var pan = cy.pan();\n var zoom = cy.zoom();\n properties.position = renderedToModelPosition(rpos, zoom, pan);\n }\n\n // override pan w/ panBy if set\n if (isCore && properties.panBy != null) {\n var panBy = properties.panBy;\n var cyPan = cy.pan();\n properties.pan = {\n x: cyPan.x + panBy.x,\n y: cyPan.y + panBy.y\n };\n }\n\n // override pan w/ center if set\n var center = properties.center || properties.centre;\n if (isCore && center != null) {\n var centerPan = cy.getCenterPan(center.eles, properties.zoom);\n if (centerPan != null) {\n properties.pan = centerPan;\n }\n }\n\n // override pan & zoom w/ fit if set\n if (isCore && properties.fit != null) {\n var fit = properties.fit;\n var fitVp = cy.getFitViewport(fit.eles || fit.boundingBox, fit.padding);\n if (fitVp != null) {\n properties.pan = fitVp.pan;\n properties.zoom = fitVp.zoom;\n }\n }\n\n // override zoom (& potentially pan) w/ zoom obj if set\n if (isCore && plainObject(properties.zoom)) {\n var vp = cy.getZoomedViewport(properties.zoom);\n if (vp != null) {\n if (vp.zoomed) {\n properties.zoom = vp.zoom;\n }\n if (vp.panned) {\n properties.pan = vp.pan;\n }\n } else {\n properties.zoom = null; // an inavalid zoom (e.g. no delta) gets automatically destroyed\n }\n }\n\n return new Animation(all[0], properties);\n };\n },\n // animate\n\n animate: function animate() {\n return function animateImpl(properties, params) {\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n if (!cy.styleEnabled()) {\n return this;\n }\n if (params) {\n properties = extend({}, properties, params);\n }\n\n // manually hook and run the animation\n for (var i = 0; i < all.length; i++) {\n var ele = all[i];\n var queue = ele.animated() && (properties.queue === undefined || properties.queue);\n var ani = ele.animation(properties, queue ? {\n queue: true\n } : undefined);\n ani.play();\n }\n return this; // chaining\n };\n },\n\n // animate\n\n stop: function stop() {\n return function stopImpl(clearQueue, jumpToEnd) {\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var cy = this._private.cy || this;\n if (!cy.styleEnabled()) {\n return this;\n }\n for (var i = 0; i < all.length; i++) {\n var ele = all[i];\n var _p = ele._private;\n var anis = _p.animation.current;\n for (var j = 0; j < anis.length; j++) {\n var ani = anis[j];\n var ani_p = ani._private;\n if (jumpToEnd) {\n // next iteration of the animation loop, the animation\n // will go straight to the end and be removed\n ani_p.duration = 0;\n }\n }\n\n // clear the queue of future animations\n if (clearQueue) {\n _p.animation.queue = [];\n }\n if (!jumpToEnd) {\n _p.animation.current = [];\n }\n }\n\n // we have to notify (the animation loop doesn't do it for us on `stop`)\n cy.notify('draw');\n return this;\n };\n } // stop\n}; // define\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\nvar isArray_1 = isArray;\n\n/** Used to match property names within property paths. */\nvar reIsDeepProp = /\\.|\\[(?:[^[\\]]*|([\"'])(?:(?!\\1)[^\\\\]|\\\\.)*?\\1)\\]/,\n reIsPlainProp = /^\\w*$/;\n\n/**\n * Checks if `value` is a property name and not a property path.\n *\n * @private\n * @param {*} value The value to check.\n * @param {Object} [object] The object to query keys on.\n * @returns {boolean} Returns `true` if `value` is a property name, else `false`.\n */\nfunction isKey(value, object) {\n if (isArray_1(value)) {\n return false;\n }\n var type = typeof value;\n if (type == 'number' || type == 'symbol' || type == 'boolean' ||\n value == null || isSymbol_1(value)) {\n return true;\n }\n return reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||\n (object != null && value in Object(object));\n}\n\nvar _isKey = isKey;\n\n/** `Object#toString` result references. */\nvar asyncTag = '[object AsyncFunction]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n proxyTag = '[object Proxy]';\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n if (!isObject_1(value)) {\n return false;\n }\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 9 which returns 'object' for typed arrays and other constructors.\n var tag = _baseGetTag(value);\n return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;\n}\n\nvar isFunction_1 = isFunction;\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = _root['__core-js_shared__'];\n\nvar _coreJsData = coreJsData;\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(_coreJsData && _coreJsData.keys && _coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\nvar _isMasked = isMasked;\n\n/** Used for built-in method references. */\nvar funcProto$1 = Function.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString$1 = funcProto$1.toString;\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to convert.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString$1.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\nvar _toSource = toSource;\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used for built-in method references. */\nvar funcProto = Function.prototype,\n objectProto$3 = Object.prototype;\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty$3 = objectProto$3.hasOwnProperty;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty$3).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject_1(value) || _isMasked(value)) {\n return false;\n }\n var pattern = isFunction_1(value) ? reIsNative : reIsHostCtor;\n return pattern.test(_toSource(value));\n}\n\nvar _baseIsNative = baseIsNative;\n\n/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue$1(object, key) {\n return object == null ? undefined : object[key];\n}\n\nvar _getValue = getValue$1;\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = _getValue(object, key);\n return _baseIsNative(value) ? value : undefined;\n}\n\nvar _getNative = getNative;\n\n/* Built-in method references that are verified to be native. */\nvar nativeCreate = _getNative(Object, 'create');\n\nvar _nativeCreate = nativeCreate;\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = _nativeCreate ? _nativeCreate(null) : {};\n this.size = 0;\n}\n\nvar _hashClear = hashClear;\n\n/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n var result = this.has(key) && delete this.__data__[key];\n this.size -= result ? 1 : 0;\n return result;\n}\n\nvar _hashDelete = hashDelete;\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED$1 = '__lodash_hash_undefined__';\n\n/** Used for built-in method references. */\nvar objectProto$2 = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty$2 = objectProto$2.hasOwnProperty;\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (_nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED$1 ? undefined : result;\n }\n return hasOwnProperty$2.call(data, key) ? data[key] : undefined;\n}\n\nvar _hashGet = hashGet;\n\n/** Used for built-in method references. */\nvar objectProto$1 = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty$1 = objectProto$1.hasOwnProperty;\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return _nativeCreate ? (data[key] !== undefined) : hasOwnProperty$1.call(data, key);\n}\n\nvar _hashHas = hashHas;\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n this.size += this.has(key) ? 0 : 1;\n data[key] = (_nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\nvar _hashSet = hashSet;\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = _hashClear;\nHash.prototype['delete'] = _hashDelete;\nHash.prototype.get = _hashGet;\nHash.prototype.has = _hashHas;\nHash.prototype.set = _hashSet;\n\nvar _Hash = Hash;\n\n/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n this.size = 0;\n}\n\nvar _listCacheClear = listCacheClear;\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\nvar eq_1 = eq;\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq_1(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\nvar _assocIndexOf = assocIndexOf;\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype;\n\n/** Built-in value references. */\nvar splice = arrayProto.splice;\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = _assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n --this.size;\n return true;\n}\n\nvar _listCacheDelete = listCacheDelete;\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = _assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\nvar _listCacheGet = listCacheGet;\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return _assocIndexOf(this.__data__, key) > -1;\n}\n\nvar _listCacheHas = listCacheHas;\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = _assocIndexOf(data, key);\n\n if (index < 0) {\n ++this.size;\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\nvar _listCacheSet = listCacheSet;\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = _listCacheClear;\nListCache.prototype['delete'] = _listCacheDelete;\nListCache.prototype.get = _listCacheGet;\nListCache.prototype.has = _listCacheHas;\nListCache.prototype.set = _listCacheSet;\n\nvar _ListCache = ListCache;\n\n/* Built-in method references that are verified to be native. */\nvar Map$1 = _getNative(_root, 'Map');\n\nvar _Map = Map$1;\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.size = 0;\n this.__data__ = {\n 'hash': new _Hash,\n 'map': new (_Map || _ListCache),\n 'string': new _Hash\n };\n}\n\nvar _mapCacheClear = mapCacheClear;\n\n/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\nvar _isKeyable = isKeyable;\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return _isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\nvar _getMapData = getMapData;\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n var result = _getMapData(this, key)['delete'](key);\n this.size -= result ? 1 : 0;\n return result;\n}\n\nvar _mapCacheDelete = mapCacheDelete;\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return _getMapData(this, key).get(key);\n}\n\nvar _mapCacheGet = mapCacheGet;\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return _getMapData(this, key).has(key);\n}\n\nvar _mapCacheHas = mapCacheHas;\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n var data = _getMapData(this, key),\n size = data.size;\n\n data.set(key, value);\n this.size += data.size == size ? 0 : 1;\n return this;\n}\n\nvar _mapCacheSet = mapCacheSet;\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries == null ? 0 : entries.length;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = _mapCacheClear;\nMapCache.prototype['delete'] = _mapCacheDelete;\nMapCache.prototype.get = _mapCacheGet;\nMapCache.prototype.has = _mapCacheHas;\nMapCache.prototype.set = _mapCacheSet;\n\nvar _MapCache = MapCache;\n\n/** Error message constants. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a function that memoizes the result of `func`. If `resolver` is\n * provided, it determines the cache key for storing the result based on the\n * arguments provided to the memoized function. By default, the first argument\n * provided to the memoized function is used as the map cache key. The `func`\n * is invoked with the `this` binding of the memoized function.\n *\n * **Note:** The cache is exposed as the `cache` property on the memoized\n * function. Its creation may be customized by replacing the `_.memoize.Cache`\n * constructor with one whose instances implement the\n * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)\n * method interface of `clear`, `delete`, `get`, `has`, and `set`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to have its output memoized.\n * @param {Function} [resolver] The function to resolve the cache key.\n * @returns {Function} Returns the new memoized function.\n * @example\n *\n * var object = { 'a': 1, 'b': 2 };\n * var other = { 'c': 3, 'd': 4 };\n *\n * var values = _.memoize(_.values);\n * values(object);\n * // => [1, 2]\n *\n * values(other);\n * // => [3, 4]\n *\n * object.a = 2;\n * values(object);\n * // => [1, 2]\n *\n * // Modify the result cache.\n * values.cache.set(object, ['a', 'b']);\n * values(object);\n * // => ['a', 'b']\n *\n * // Replace `_.memoize.Cache`.\n * _.memoize.Cache = WeakMap;\n */\nfunction memoize(func, resolver) {\n if (typeof func != 'function' || (resolver != null && typeof resolver != 'function')) {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n var memoized = function() {\n var args = arguments,\n key = resolver ? resolver.apply(this, args) : args[0],\n cache = memoized.cache;\n\n if (cache.has(key)) {\n return cache.get(key);\n }\n var result = func.apply(this, args);\n memoized.cache = cache.set(key, result) || cache;\n return result;\n };\n memoized.cache = new (memoize.Cache || _MapCache);\n return memoized;\n}\n\n// Expose `MapCache`.\nmemoize.Cache = _MapCache;\n\nvar memoize_1 = memoize;\n\n/** Used as the maximum memoize cache size. */\nvar MAX_MEMOIZE_SIZE = 500;\n\n/**\n * A specialized version of `_.memoize` which clears the memoized function's\n * cache when it exceeds `MAX_MEMOIZE_SIZE`.\n *\n * @private\n * @param {Function} func The function to have its output memoized.\n * @returns {Function} Returns the new memoized function.\n */\nfunction memoizeCapped(func) {\n var result = memoize_1(func, function(key) {\n if (cache.size === MAX_MEMOIZE_SIZE) {\n cache.clear();\n }\n return key;\n });\n\n var cache = result.cache;\n return result;\n}\n\nvar _memoizeCapped = memoizeCapped;\n\n/** Used to match property names within property paths. */\nvar rePropName = /[^.[\\]]+|\\[(?:(-?\\d+(?:\\.\\d+)?)|([\"'])((?:(?!\\2)[^\\\\]|\\\\.)*?)\\2)\\]|(?=(?:\\.|\\[\\])(?:\\.|\\[\\]|$))/g;\n\n/** Used to match backslashes in property paths. */\nvar reEscapeChar = /\\\\(\\\\)?/g;\n\n/**\n * Converts `string` to a property path array.\n *\n * @private\n * @param {string} string The string to convert.\n * @returns {Array} Returns the property path array.\n */\nvar stringToPath = _memoizeCapped(function(string) {\n var result = [];\n if (string.charCodeAt(0) === 46 /* . */) {\n result.push('');\n }\n string.replace(rePropName, function(match, number, quote, subString) {\n result.push(quote ? subString.replace(reEscapeChar, '$1') : (number || match));\n });\n return result;\n});\n\nvar _stringToPath = stringToPath;\n\n/**\n * A specialized version of `_.map` for arrays without support for iteratee\n * shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the new mapped array.\n */\nfunction arrayMap(array, iteratee) {\n var index = -1,\n length = array == null ? 0 : array.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iteratee(array[index], index, array);\n }\n return result;\n}\n\nvar _arrayMap = arrayMap;\n\n/** Used as references for various `Number` constants. */\nvar INFINITY$1 = 1 / 0;\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = _Symbol ? _Symbol.prototype : undefined,\n symbolToString = symbolProto ? symbolProto.toString : undefined;\n\n/**\n * The base implementation of `_.toString` which doesn't convert nullish\n * values to empty strings.\n *\n * @private\n * @param {*} value The value to process.\n * @returns {string} Returns the string.\n */\nfunction baseToString(value) {\n // Exit early for strings to avoid a performance hit in some environments.\n if (typeof value == 'string') {\n return value;\n }\n if (isArray_1(value)) {\n // Recursively convert values (susceptible to call stack limits).\n return _arrayMap(value, baseToString) + '';\n }\n if (isSymbol_1(value)) {\n return symbolToString ? symbolToString.call(value) : '';\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY$1) ? '-0' : result;\n}\n\nvar _baseToString = baseToString;\n\n/**\n * Converts `value` to a string. An empty string is returned for `null`\n * and `undefined` values. The sign of `-0` is preserved.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {string} Returns the converted string.\n * @example\n *\n * _.toString(null);\n * // => ''\n *\n * _.toString(-0);\n * // => '-0'\n *\n * _.toString([1, 2, 3]);\n * // => '1,2,3'\n */\nfunction toString$1(value) {\n return value == null ? '' : _baseToString(value);\n}\n\nvar toString_1 = toString$1;\n\n/**\n * Casts `value` to a path array if it's not one.\n *\n * @private\n * @param {*} value The value to inspect.\n * @param {Object} [object] The object to query keys on.\n * @returns {Array} Returns the cast property path array.\n */\nfunction castPath(value, object) {\n if (isArray_1(value)) {\n return value;\n }\n return _isKey(value, object) ? [value] : _stringToPath(toString_1(value));\n}\n\nvar _castPath = castPath;\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0;\n\n/**\n * Converts `value` to a string key if it's not a string or symbol.\n *\n * @private\n * @param {*} value The value to inspect.\n * @returns {string|symbol} Returns the key.\n */\nfunction toKey(value) {\n if (typeof value == 'string' || isSymbol_1(value)) {\n return value;\n }\n var result = (value + '');\n return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;\n}\n\nvar _toKey = toKey;\n\n/**\n * The base implementation of `_.get` without support for default values.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @returns {*} Returns the resolved value.\n */\nfunction baseGet(object, path) {\n path = _castPath(path, object);\n\n var index = 0,\n length = path.length;\n\n while (object != null && index < length) {\n object = object[_toKey(path[index++])];\n }\n return (index && index == length) ? object : undefined;\n}\n\nvar _baseGet = baseGet;\n\n/**\n * Gets the value at `path` of `object`. If the resolved value is\n * `undefined`, the `defaultValue` is returned in its place.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to query.\n * @param {Array|string} path The path of the property to get.\n * @param {*} [defaultValue] The value returned for `undefined` resolved values.\n * @returns {*} Returns the resolved value.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.get(object, 'a[0].b.c');\n * // => 3\n *\n * _.get(object, ['a', '0', 'b', 'c']);\n * // => 3\n *\n * _.get(object, 'a.b.c', 'default');\n * // => 'default'\n */\nfunction get(object, path, defaultValue) {\n var result = object == null ? undefined : _baseGet(object, path);\n return result === undefined ? defaultValue : result;\n}\n\nvar get_1 = get;\n\nvar defineProperty = (function() {\n try {\n var func = _getNative(Object, 'defineProperty');\n func({}, '', {});\n return func;\n } catch (e) {}\n}());\n\nvar _defineProperty = defineProperty;\n\n/**\n * The base implementation of `assignValue` and `assignMergeValue` without\n * value checks.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction baseAssignValue(object, key, value) {\n if (key == '__proto__' && _defineProperty) {\n _defineProperty(object, key, {\n 'configurable': true,\n 'enumerable': true,\n 'value': value,\n 'writable': true\n });\n } else {\n object[key] = value;\n }\n}\n\nvar _baseAssignValue = baseAssignValue;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq_1(objValue, value)) ||\n (value === undefined && !(key in object))) {\n _baseAssignValue(object, key, value);\n }\n}\n\nvar _assignValue = assignValue;\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n var type = typeof value;\n length = length == null ? MAX_SAFE_INTEGER : length;\n\n return !!length &&\n (type == 'number' ||\n (type != 'symbol' && reIsUint.test(value))) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\nvar _isIndex = isIndex;\n\n/**\n * The base implementation of `_.set`.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @param {Function} [customizer] The function to customize path creation.\n * @returns {Object} Returns `object`.\n */\nfunction baseSet(object, path, value, customizer) {\n if (!isObject_1(object)) {\n return object;\n }\n path = _castPath(path, object);\n\n var index = -1,\n length = path.length,\n lastIndex = length - 1,\n nested = object;\n\n while (nested != null && ++index < length) {\n var key = _toKey(path[index]),\n newValue = value;\n\n if (key === '__proto__' || key === 'constructor' || key === 'prototype') {\n return object;\n }\n\n if (index != lastIndex) {\n var objValue = nested[key];\n newValue = customizer ? customizer(objValue, key, nested) : undefined;\n if (newValue === undefined) {\n newValue = isObject_1(objValue)\n ? objValue\n : (_isIndex(path[index + 1]) ? [] : {});\n }\n }\n _assignValue(nested, key, newValue);\n nested = nested[key];\n }\n return object;\n}\n\nvar _baseSet = baseSet;\n\n/**\n * Sets the value at `path` of `object`. If a portion of `path` doesn't exist,\n * it's created. Arrays are created for missing index properties while objects\n * are created for all other missing properties. Use `_.setWith` to customize\n * `path` creation.\n *\n * **Note:** This method mutates `object`.\n *\n * @static\n * @memberOf _\n * @since 3.7.0\n * @category Object\n * @param {Object} object The object to modify.\n * @param {Array|string} path The path of the property to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns `object`.\n * @example\n *\n * var object = { 'a': [{ 'b': { 'c': 3 } }] };\n *\n * _.set(object, 'a[0].b.c', 4);\n * console.log(object.a[0].b.c);\n * // => 4\n *\n * _.set(object, ['x', '0', 'y', 'z'], 5);\n * console.log(object.x[0].y.z);\n * // => 5\n */\nfunction set(object, path, value) {\n return object == null ? object : _baseSet(object, path, value);\n}\n\nvar set_1 = set;\n\n/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\nvar _copyArray = copyArray;\n\n/**\n * Converts `value` to a property path array.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Util\n * @param {*} value The value to convert.\n * @returns {Array} Returns the new property path array.\n * @example\n *\n * _.toPath('a.b.c');\n * // => ['a', 'b', 'c']\n *\n * _.toPath('a[0].b.c');\n * // => ['a', '0', 'b', 'c']\n */\nfunction toPath(value) {\n if (isArray_1(value)) {\n return _arrayMap(value, _toKey);\n }\n return isSymbol_1(value) ? [value] : _copyArray(_stringToPath(toString_1(value)));\n}\n\nvar toPath_1 = toPath;\n\nvar define$2 = {\n // access data field\n data: function data(params) {\n var defaults = {\n field: 'data',\n bindingEvent: 'data',\n allowBinding: false,\n allowSetting: false,\n allowGetting: false,\n settingEvent: 'data',\n settingTriggersEvent: false,\n triggerFnName: 'trigger',\n immutableKeys: {},\n // key => true if immutable\n updateStyle: false,\n beforeGet: function beforeGet(self) {},\n beforeSet: function beforeSet(self, obj) {},\n onSet: function onSet(self) {},\n canSet: function canSet(self) {\n return true;\n }\n };\n params = extend({}, defaults, params);\n return function dataImpl(name, value) {\n var p = params;\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n var single = selfIsArrayLike ? self[0] : self;\n\n // .data('foo', ...)\n if (string(name)) {\n // set or get property\n var isPathLike = name.indexOf('.') !== -1; // there might be a normal field with a dot \n var path = isPathLike && toPath_1(name);\n\n // .data('foo')\n if (p.allowGetting && value === undefined) {\n // get\n\n var ret;\n if (single) {\n p.beforeGet(single);\n\n // check if it's path and a field with the same name doesn't exist\n if (path && single._private[p.field][name] === undefined) {\n ret = get_1(single._private[p.field], path);\n } else {\n ret = single._private[p.field][name];\n }\n }\n return ret;\n\n // .data('foo', 'bar')\n } else if (p.allowSetting && value !== undefined) {\n // set\n var valid = !p.immutableKeys[name];\n if (valid) {\n var change = _defineProperty$1({}, name, value);\n p.beforeSet(self, change);\n for (var i = 0, l = all.length; i < l; i++) {\n var ele = all[i];\n if (p.canSet(ele)) {\n if (path && single._private[p.field][name] === undefined) {\n set_1(ele._private[p.field], path, value);\n } else {\n ele._private[p.field][name] = value;\n }\n }\n }\n\n // update mappers if asked\n if (p.updateStyle) {\n self.updateStyle();\n }\n\n // call onSet callback\n p.onSet(self);\n if (p.settingTriggersEvent) {\n self[p.triggerFnName](p.settingEvent);\n }\n }\n }\n\n // .data({ 'foo': 'bar' })\n } else if (p.allowSetting && plainObject(name)) {\n // extend\n var obj = name;\n var k, v;\n var keys = Object.keys(obj);\n p.beforeSet(self, obj);\n for (var _i = 0; _i < keys.length; _i++) {\n k = keys[_i];\n v = obj[k];\n var _valid = !p.immutableKeys[k];\n if (_valid) {\n for (var j = 0; j < all.length; j++) {\n var _ele = all[j];\n if (p.canSet(_ele)) {\n _ele._private[p.field][k] = v;\n }\n }\n }\n }\n\n // update mappers if asked\n if (p.updateStyle) {\n self.updateStyle();\n }\n\n // call onSet callback\n p.onSet(self);\n if (p.settingTriggersEvent) {\n self[p.triggerFnName](p.settingEvent);\n }\n\n // .data(function(){ ... })\n } else if (p.allowBinding && fn$6(name)) {\n // bind to event\n var fn = name;\n self.on(p.bindingEvent, fn);\n\n // .data()\n } else if (p.allowGetting && name === undefined) {\n // get whole object\n var _ret;\n if (single) {\n p.beforeGet(single);\n _ret = single._private[p.field];\n }\n return _ret;\n }\n return self; // maintain chainability\n }; // function\n },\n\n // data\n\n // remove data field\n removeData: function removeData(params) {\n var defaults = {\n field: 'data',\n event: 'data',\n triggerFnName: 'trigger',\n triggerEvent: false,\n immutableKeys: {} // key => true if immutable\n };\n\n params = extend({}, defaults, params);\n return function removeDataImpl(names) {\n var p = params;\n var self = this;\n var selfIsArrayLike = self.length !== undefined;\n var all = selfIsArrayLike ? self : [self]; // put in array if not array-like\n\n // .removeData('foo bar')\n if (string(names)) {\n // then get the list of keys, and delete them\n var keys = names.split(/\\s+/);\n var l = keys.length;\n for (var i = 0; i < l; i++) {\n // delete each non-empty key\n var key = keys[i];\n if (emptyString(key)) {\n continue;\n }\n var valid = !p.immutableKeys[key]; // not valid if immutable\n if (valid) {\n for (var i_a = 0, l_a = all.length; i_a < l_a; i_a++) {\n all[i_a]._private[p.field][key] = undefined;\n }\n }\n }\n if (p.triggerEvent) {\n self[p.triggerFnName](p.event);\n }\n\n // .removeData()\n } else if (names === undefined) {\n // then delete all keys\n\n for (var _i_a = 0, _l_a = all.length; _i_a < _l_a; _i_a++) {\n var _privateFields = all[_i_a]._private[p.field];\n var _keys = Object.keys(_privateFields);\n for (var _i2 = 0; _i2 < _keys.length; _i2++) {\n var _key = _keys[_i2];\n var validKeyToDelete = !p.immutableKeys[_key];\n if (validKeyToDelete) {\n _privateFields[_key] = undefined;\n }\n }\n }\n if (p.triggerEvent) {\n self[p.triggerFnName](p.event);\n }\n }\n return self; // maintain chaining\n }; // function\n } // removeData\n}; // define\n\nvar define$1 = {\n eventAliasesOn: function eventAliasesOn(proto) {\n var p = proto;\n p.addListener = p.listen = p.bind = p.on;\n p.unlisten = p.unbind = p.off = p.removeListener;\n p.trigger = p.emit;\n\n // this is just a wrapper alias of .on()\n p.pon = p.promiseOn = function (events, selector) {\n var self = this;\n var args = Array.prototype.slice.call(arguments, 0);\n return new Promise$1(function (resolve, reject) {\n var callback = function callback(e) {\n self.off.apply(self, offArgs);\n resolve(e);\n };\n var onArgs = args.concat([callback]);\n var offArgs = onArgs.concat([]);\n self.on.apply(self, onArgs);\n });\n };\n }\n}; // define\n\n// use this module to cherry pick functions into your prototype\nvar define = {};\n[define$3, define$2, define$1].forEach(function (m) {\n extend(define, m);\n});\n\nvar elesfn$i = {\n animate: define.animate(),\n animation: define.animation(),\n animated: define.animated(),\n clearQueue: define.clearQueue(),\n delay: define.delay(),\n delayAnimation: define.delayAnimation(),\n stop: define.stop()\n};\n\nvar elesfn$h = {\n classes: function classes(_classes) {\n var self = this;\n if (_classes === undefined) {\n var ret = [];\n self[0]._private.classes.forEach(function (cls) {\n return ret.push(cls);\n });\n return ret;\n } else if (!array(_classes)) {\n // extract classes from string\n _classes = (_classes || '').match(/\\S+/g) || [];\n }\n var changed = [];\n var classesSet = new Set$1(_classes);\n\n // check and update each ele\n for (var j = 0; j < self.length; j++) {\n var ele = self[j];\n var _p = ele._private;\n var eleClasses = _p.classes;\n var changedEle = false;\n\n // check if ele has all of the passed classes\n for (var i = 0; i < _classes.length; i++) {\n var cls = _classes[i];\n var eleHasClass = eleClasses.has(cls);\n if (!eleHasClass) {\n changedEle = true;\n break;\n }\n }\n\n // check if ele has classes outside of those passed\n if (!changedEle) {\n changedEle = eleClasses.size !== _classes.length;\n }\n if (changedEle) {\n _p.classes = classesSet;\n changed.push(ele);\n }\n }\n\n // trigger update style on those eles that had class changes\n if (changed.length > 0) {\n this.spawn(changed).updateStyle().emit('class');\n }\n return self;\n },\n addClass: function addClass(classes) {\n return this.toggleClass(classes, true);\n },\n hasClass: function hasClass(className) {\n var ele = this[0];\n return ele != null && ele._private.classes.has(className);\n },\n toggleClass: function toggleClass(classes, toggle) {\n if (!array(classes)) {\n // extract classes from string\n classes = classes.match(/\\S+/g) || [];\n }\n var self = this;\n var toggleUndefd = toggle === undefined;\n var changed = []; // eles who had classes changed\n\n for (var i = 0, il = self.length; i < il; i++) {\n var ele = self[i];\n var eleClasses = ele._private.classes;\n var changedEle = false;\n for (var j = 0; j < classes.length; j++) {\n var cls = classes[j];\n var hasClass = eleClasses.has(cls);\n var changedNow = false;\n if (toggle || toggleUndefd && !hasClass) {\n eleClasses.add(cls);\n changedNow = true;\n } else if (!toggle || toggleUndefd && hasClass) {\n eleClasses[\"delete\"](cls);\n changedNow = true;\n }\n if (!changedEle && changedNow) {\n changed.push(ele);\n changedEle = true;\n }\n } // for j classes\n } // for i eles\n\n // trigger update style on those eles that had class changes\n if (changed.length > 0) {\n this.spawn(changed).updateStyle().emit('class');\n }\n return self;\n },\n removeClass: function removeClass(classes) {\n return this.toggleClass(classes, false);\n },\n flashClass: function flashClass(classes, duration) {\n var self = this;\n if (duration == null) {\n duration = 250;\n } else if (duration === 0) {\n return self; // nothing to do really\n }\n\n self.addClass(classes);\n setTimeout(function () {\n self.removeClass(classes);\n }, duration);\n return self;\n }\n};\nelesfn$h.className = elesfn$h.classNames = elesfn$h.classes;\n\n// tokens in the query language\nvar tokens = {\n metaChar: '[\\\\!\\\\\"\\\\#\\\\$\\\\%\\\\&\\\\\\'\\\\(\\\\)\\\\*\\\\+\\\\,\\\\.\\\\/\\\\:\\\\;\\\\<\\\\=\\\\>\\\\?\\\\@\\\\[\\\\]\\\\^\\\\`\\\\{\\\\|\\\\}\\\\~]',\n // chars we need to escape in let names, etc\n comparatorOp: '=|\\\\!=|>|>=|<|<=|\\\\$=|\\\\^=|\\\\*=',\n // binary comparison op (used in data selectors)\n boolOp: '\\\\?|\\\\!|\\\\^',\n // boolean (unary) operators (used in data selectors)\n string: '\"(?:\\\\\\\\\"|[^\"])*\"' + '|' + \"'(?:\\\\\\\\'|[^'])*'\",\n // string literals (used in data selectors) -- doublequotes | singlequotes\n number: number,\n // number literal (used in data selectors) --- e.g. 0.1234, 1234, 12e123\n meta: 'degree|indegree|outdegree',\n // allowed metadata fields (i.e. allowed functions to use from Collection)\n separator: '\\\\s*,\\\\s*',\n // queries are separated by commas, e.g. edge[foo = 'bar'], node.someClass\n descendant: '\\\\s+',\n child: '\\\\s+>\\\\s+',\n subject: '\\\\$',\n group: 'node|edge|\\\\*',\n directedEdge: '\\\\s+->\\\\s+',\n undirectedEdge: '\\\\s+<->\\\\s+'\n};\ntokens.variable = '(?:[\\\\w-.]|(?:\\\\\\\\' + tokens.metaChar + '))+'; // a variable name can have letters, numbers, dashes, and periods\ntokens.className = '(?:[\\\\w-]|(?:\\\\\\\\' + tokens.metaChar + '))+'; // a class name has the same rules as a variable except it can't have a '.' in the name\ntokens.value = tokens.string + '|' + tokens.number; // a value literal, either a string or number\ntokens.id = tokens.variable; // an element id (follows variable conventions)\n\n(function () {\n var ops, op, i;\n\n // add @ variants to comparatorOp\n ops = tokens.comparatorOp.split('|');\n for (i = 0; i < ops.length; i++) {\n op = ops[i];\n tokens.comparatorOp += '|@' + op;\n }\n\n // add ! variants to comparatorOp\n ops = tokens.comparatorOp.split('|');\n for (i = 0; i < ops.length; i++) {\n op = ops[i];\n if (op.indexOf('!') >= 0) {\n continue;\n } // skip ops that explicitly contain !\n if (op === '=') {\n continue;\n } // skip = b/c != is explicitly defined\n\n tokens.comparatorOp += '|\\\\!' + op;\n }\n})();\n\n/**\n * Make a new query object\n *\n * @prop type {Type} The type enum (int) of the query\n * @prop checks List of checks to make against an ele to test for a match\n */\nvar newQuery = function newQuery() {\n return {\n checks: []\n };\n};\n\n/**\n * A check type enum-like object. Uses integer values for fast match() lookup.\n * The ordering does not matter as long as the ints are unique.\n */\nvar Type = {\n /** E.g. node */\n GROUP: 0,\n /** A collection of elements */\n COLLECTION: 1,\n /** A filter(ele) function */\n FILTER: 2,\n /** E.g. [foo > 1] */\n DATA_COMPARE: 3,\n /** E.g. [foo] */\n DATA_EXIST: 4,\n /** E.g. [?foo] */\n DATA_BOOL: 5,\n /** E.g. [[degree > 2]] */\n META_COMPARE: 6,\n /** E.g. :selected */\n STATE: 7,\n /** E.g. #foo */\n ID: 8,\n /** E.g. .foo */\n CLASS: 9,\n /** E.g. #foo <-> #bar */\n UNDIRECTED_EDGE: 10,\n /** E.g. #foo -> #bar */\n DIRECTED_EDGE: 11,\n /** E.g. $#foo -> #bar */\n NODE_SOURCE: 12,\n /** E.g. #foo -> $#bar */\n NODE_TARGET: 13,\n /** E.g. $#foo <-> #bar */\n NODE_NEIGHBOR: 14,\n /** E.g. #foo > #bar */\n CHILD: 15,\n /** E.g. #foo #bar */\n DESCENDANT: 16,\n /** E.g. $#foo > #bar */\n PARENT: 17,\n /** E.g. $#foo #bar */\n ANCESTOR: 18,\n /** E.g. #foo > $bar > #baz */\n COMPOUND_SPLIT: 19,\n /** Always matches, useful placeholder for subject in `COMPOUND_SPLIT` */\n TRUE: 20\n};\n\nvar stateSelectors = [{\n selector: ':selected',\n matches: function matches(ele) {\n return ele.selected();\n }\n}, {\n selector: ':unselected',\n matches: function matches(ele) {\n return !ele.selected();\n }\n}, {\n selector: ':selectable',\n matches: function matches(ele) {\n return ele.selectable();\n }\n}, {\n selector: ':unselectable',\n matches: function matches(ele) {\n return !ele.selectable();\n }\n}, {\n selector: ':locked',\n matches: function matches(ele) {\n return ele.locked();\n }\n}, {\n selector: ':unlocked',\n matches: function matches(ele) {\n return !ele.locked();\n }\n}, {\n selector: ':visible',\n matches: function matches(ele) {\n return ele.visible();\n }\n}, {\n selector: ':hidden',\n matches: function matches(ele) {\n return !ele.visible();\n }\n}, {\n selector: ':transparent',\n matches: function matches(ele) {\n return ele.transparent();\n }\n}, {\n selector: ':grabbed',\n matches: function matches(ele) {\n return ele.grabbed();\n }\n}, {\n selector: ':free',\n matches: function matches(ele) {\n return !ele.grabbed();\n }\n}, {\n selector: ':removed',\n matches: function matches(ele) {\n return ele.removed();\n }\n}, {\n selector: ':inside',\n matches: function matches(ele) {\n return !ele.removed();\n }\n}, {\n selector: ':grabbable',\n matches: function matches(ele) {\n return ele.grabbable();\n }\n}, {\n selector: ':ungrabbable',\n matches: function matches(ele) {\n return !ele.grabbable();\n }\n}, {\n selector: ':animated',\n matches: function matches(ele) {\n return ele.animated();\n }\n}, {\n selector: ':unanimated',\n matches: function matches(ele) {\n return !ele.animated();\n }\n}, {\n selector: ':parent',\n matches: function matches(ele) {\n return ele.isParent();\n }\n}, {\n selector: ':childless',\n matches: function matches(ele) {\n return ele.isChildless();\n }\n}, {\n selector: ':child',\n matches: function matches(ele) {\n return ele.isChild();\n }\n}, {\n selector: ':orphan',\n matches: function matches(ele) {\n return ele.isOrphan();\n }\n}, {\n selector: ':nonorphan',\n matches: function matches(ele) {\n return ele.isChild();\n }\n}, {\n selector: ':compound',\n matches: function matches(ele) {\n if (ele.isNode()) {\n return ele.isParent();\n } else {\n return ele.source().isParent() || ele.target().isParent();\n }\n }\n}, {\n selector: ':loop',\n matches: function matches(ele) {\n return ele.isLoop();\n }\n}, {\n selector: ':simple',\n matches: function matches(ele) {\n return ele.isSimple();\n }\n}, {\n selector: ':active',\n matches: function matches(ele) {\n return ele.active();\n }\n}, {\n selector: ':inactive',\n matches: function matches(ele) {\n return !ele.active();\n }\n}, {\n selector: ':backgrounding',\n matches: function matches(ele) {\n return ele.backgrounding();\n }\n}, {\n selector: ':nonbackgrounding',\n matches: function matches(ele) {\n return !ele.backgrounding();\n }\n}].sort(function (a, b) {\n // n.b. selectors that are starting substrings of others must have the longer ones first\n return descending(a.selector, b.selector);\n});\nvar lookup = function () {\n var selToFn = {};\n var s;\n for (var i = 0; i < stateSelectors.length; i++) {\n s = stateSelectors[i];\n selToFn[s.selector] = s.matches;\n }\n return selToFn;\n}();\nvar stateSelectorMatches = function stateSelectorMatches(sel, ele) {\n return lookup[sel](ele);\n};\nvar stateSelectorRegex = '(' + stateSelectors.map(function (s) {\n return s.selector;\n}).join('|') + ')';\n\n// when a token like a variable has escaped meta characters, we need to clean the backslashes out\n// so that values get compared properly in Selector.filter()\nvar cleanMetaChars = function cleanMetaChars(str) {\n return str.replace(new RegExp('\\\\\\\\(' + tokens.metaChar + ')', 'g'), function (match, $1) {\n return $1;\n });\n};\nvar replaceLastQuery = function replaceLastQuery(selector, examiningQuery, replacementQuery) {\n selector[selector.length - 1] = replacementQuery;\n};\n\n// NOTE: add new expression syntax here to have it recognised by the parser;\n// - a query contains all adjacent (i.e. no separator in between) expressions;\n// - the current query is stored in selector[i]\n// - you need to check the query objects in match() for it actually filter properly, but that's pretty straight forward\nvar exprs = [{\n name: 'group',\n // just used for identifying when debugging\n query: true,\n regex: '(' + tokens.group + ')',\n populate: function populate(selector, query, _ref) {\n var _ref2 = _slicedToArray(_ref, 1),\n group = _ref2[0];\n query.checks.push({\n type: Type.GROUP,\n value: group === '*' ? group : group + 's'\n });\n }\n}, {\n name: 'state',\n query: true,\n regex: stateSelectorRegex,\n populate: function populate(selector, query, _ref3) {\n var _ref4 = _slicedToArray(_ref3, 1),\n state = _ref4[0];\n query.checks.push({\n type: Type.STATE,\n value: state\n });\n }\n}, {\n name: 'id',\n query: true,\n regex: '\\\\#(' + tokens.id + ')',\n populate: function populate(selector, query, _ref5) {\n var _ref6 = _slicedToArray(_ref5, 1),\n id = _ref6[0];\n query.checks.push({\n type: Type.ID,\n value: cleanMetaChars(id)\n });\n }\n}, {\n name: 'className',\n query: true,\n regex: '\\\\.(' + tokens.className + ')',\n populate: function populate(selector, query, _ref7) {\n var _ref8 = _slicedToArray(_ref7, 1),\n className = _ref8[0];\n query.checks.push({\n type: Type.CLASS,\n value: cleanMetaChars(className)\n });\n }\n}, {\n name: 'dataExists',\n query: true,\n regex: '\\\\[\\\\s*(' + tokens.variable + ')\\\\s*\\\\]',\n populate: function populate(selector, query, _ref9) {\n var _ref10 = _slicedToArray(_ref9, 1),\n variable = _ref10[0];\n query.checks.push({\n type: Type.DATA_EXIST,\n field: cleanMetaChars(variable)\n });\n }\n}, {\n name: 'dataCompare',\n query: true,\n regex: '\\\\[\\\\s*(' + tokens.variable + ')\\\\s*(' + tokens.comparatorOp + ')\\\\s*(' + tokens.value + ')\\\\s*\\\\]',\n populate: function populate(selector, query, _ref11) {\n var _ref12 = _slicedToArray(_ref11, 3),\n variable = _ref12[0],\n comparatorOp = _ref12[1],\n value = _ref12[2];\n var valueIsString = new RegExp('^' + tokens.string + '$').exec(value) != null;\n if (valueIsString) {\n value = value.substring(1, value.length - 1);\n } else {\n value = parseFloat(value);\n }\n query.checks.push({\n type: Type.DATA_COMPARE,\n field: cleanMetaChars(variable),\n operator: comparatorOp,\n value: value\n });\n }\n}, {\n name: 'dataBool',\n query: true,\n regex: '\\\\[\\\\s*(' + tokens.boolOp + ')\\\\s*(' + tokens.variable + ')\\\\s*\\\\]',\n populate: function populate(selector, query, _ref13) {\n var _ref14 = _slicedToArray(_ref13, 2),\n boolOp = _ref14[0],\n variable = _ref14[1];\n query.checks.push({\n type: Type.DATA_BOOL,\n field: cleanMetaChars(variable),\n operator: boolOp\n });\n }\n}, {\n name: 'metaCompare',\n query: true,\n regex: '\\\\[\\\\[\\\\s*(' + tokens.meta + ')\\\\s*(' + tokens.comparatorOp + ')\\\\s*(' + tokens.number + ')\\\\s*\\\\]\\\\]',\n populate: function populate(selector, query, _ref15) {\n var _ref16 = _slicedToArray(_ref15, 3),\n meta = _ref16[0],\n comparatorOp = _ref16[1],\n number = _ref16[2];\n query.checks.push({\n type: Type.META_COMPARE,\n field: cleanMetaChars(meta),\n operator: comparatorOp,\n value: parseFloat(number)\n });\n }\n}, {\n name: 'nextQuery',\n separator: true,\n regex: tokens.separator,\n populate: function populate(selector, query) {\n var currentSubject = selector.currentSubject;\n var edgeCount = selector.edgeCount;\n var compoundCount = selector.compoundCount;\n var lastQ = selector[selector.length - 1];\n if (currentSubject != null) {\n lastQ.subject = currentSubject;\n selector.currentSubject = null;\n }\n lastQ.edgeCount = edgeCount;\n lastQ.compoundCount = compoundCount;\n selector.edgeCount = 0;\n selector.compoundCount = 0;\n\n // go on to next query\n var nextQuery = selector[selector.length++] = newQuery();\n return nextQuery; // this is the new query to be filled by the following exprs\n }\n}, {\n name: 'directedEdge',\n separator: true,\n regex: tokens.directedEdge,\n populate: function populate(selector, query) {\n if (selector.currentSubject == null) {\n // undirected edge\n var edgeQuery = newQuery();\n var source = query;\n var target = newQuery();\n edgeQuery.checks.push({\n type: Type.DIRECTED_EDGE,\n source: source,\n target: target\n });\n\n // the query in the selector should be the edge rather than the source\n replaceLastQuery(selector, query, edgeQuery);\n selector.edgeCount++;\n\n // we're now populating the target query with expressions that follow\n return target;\n } else {\n // source/target\n var srcTgtQ = newQuery();\n var _source = query;\n var _target = newQuery();\n srcTgtQ.checks.push({\n type: Type.NODE_SOURCE,\n source: _source,\n target: _target\n });\n\n // the query in the selector should be the neighbourhood rather than the node\n replaceLastQuery(selector, query, srcTgtQ);\n selector.edgeCount++;\n return _target; // now populating the target with the following expressions\n }\n }\n}, {\n name: 'undirectedEdge',\n separator: true,\n regex: tokens.undirectedEdge,\n populate: function populate(selector, query) {\n if (selector.currentSubject == null) {\n // undirected edge\n var edgeQuery = newQuery();\n var source = query;\n var target = newQuery();\n edgeQuery.checks.push({\n type: Type.UNDIRECTED_EDGE,\n nodes: [source, target]\n });\n\n // the query in the selector should be the edge rather than the source\n replaceLastQuery(selector, query, edgeQuery);\n selector.edgeCount++;\n\n // we're now populating the target query with expressions that follow\n return target;\n } else {\n // neighbourhood\n var nhoodQ = newQuery();\n var node = query;\n var neighbor = newQuery();\n nhoodQ.checks.push({\n type: Type.NODE_NEIGHBOR,\n node: node,\n neighbor: neighbor\n });\n\n // the query in the selector should be the neighbourhood rather than the node\n replaceLastQuery(selector, query, nhoodQ);\n return neighbor; // now populating the neighbor with following expressions\n }\n }\n}, {\n name: 'child',\n separator: true,\n regex: tokens.child,\n populate: function populate(selector, query) {\n if (selector.currentSubject == null) {\n // default: child query\n var parentChildQuery = newQuery();\n var child = newQuery();\n var parent = selector[selector.length - 1];\n parentChildQuery.checks.push({\n type: Type.CHILD,\n parent: parent,\n child: child\n });\n\n // the query in the selector should be the '>' itself\n replaceLastQuery(selector, query, parentChildQuery);\n selector.compoundCount++;\n\n // we're now populating the child query with expressions that follow\n return child;\n } else if (selector.currentSubject === query) {\n // compound split query\n var compound = newQuery();\n var left = selector[selector.length - 1];\n var right = newQuery();\n var subject = newQuery();\n var _child = newQuery();\n var _parent = newQuery();\n\n // set up the root compound q\n compound.checks.push({\n type: Type.COMPOUND_SPLIT,\n left: left,\n right: right,\n subject: subject\n });\n\n // populate the subject and replace the q at the old spot (within left) with TRUE\n subject.checks = query.checks; // take the checks from the left\n query.checks = [{\n type: Type.TRUE\n }]; // checks under left refs the subject implicitly\n\n // set up the right q\n _parent.checks.push({\n type: Type.TRUE\n }); // parent implicitly refs the subject\n right.checks.push({\n type: Type.PARENT,\n // type is swapped on right side queries\n parent: _parent,\n child: _child // empty for now\n });\n\n replaceLastQuery(selector, left, compound);\n\n // update the ref since we moved things around for `query`\n selector.currentSubject = subject;\n selector.compoundCount++;\n return _child; // now populating the right side's child\n } else {\n // parent query\n // info for parent query\n var _parent2 = newQuery();\n var _child2 = newQuery();\n var pcQChecks = [{\n type: Type.PARENT,\n parent: _parent2,\n child: _child2\n }];\n\n // the parent-child query takes the place of the query previously being populated\n _parent2.checks = query.checks; // the previous query contains the checks for the parent\n query.checks = pcQChecks; // pc query takes over\n\n selector.compoundCount++;\n return _child2; // we're now populating the child\n }\n }\n}, {\n name: 'descendant',\n separator: true,\n regex: tokens.descendant,\n populate: function populate(selector, query) {\n if (selector.currentSubject == null) {\n // default: descendant query\n var ancChQuery = newQuery();\n var descendant = newQuery();\n var ancestor = selector[selector.length - 1];\n ancChQuery.checks.push({\n type: Type.DESCENDANT,\n ancestor: ancestor,\n descendant: descendant\n });\n\n // the query in the selector should be the '>' itself\n replaceLastQuery(selector, query, ancChQuery);\n selector.compoundCount++;\n\n // we're now populating the descendant query with expressions that follow\n return descendant;\n } else if (selector.currentSubject === query) {\n // compound split query\n var compound = newQuery();\n var left = selector[selector.length - 1];\n var right = newQuery();\n var subject = newQuery();\n var _descendant = newQuery();\n var _ancestor = newQuery();\n\n // set up the root compound q\n compound.checks.push({\n type: Type.COMPOUND_SPLIT,\n left: left,\n right: right,\n subject: subject\n });\n\n // populate the subject and replace the q at the old spot (within left) with TRUE\n subject.checks = query.checks; // take the checks from the left\n query.checks = [{\n type: Type.TRUE\n }]; // checks under left refs the subject implicitly\n\n // set up the right q\n _ancestor.checks.push({\n type: Type.TRUE\n }); // ancestor implicitly refs the subject\n right.checks.push({\n type: Type.ANCESTOR,\n // type is swapped on right side queries\n ancestor: _ancestor,\n descendant: _descendant // empty for now\n });\n\n replaceLastQuery(selector, left, compound);\n\n // update the ref since we moved things around for `query`\n selector.currentSubject = subject;\n selector.compoundCount++;\n return _descendant; // now populating the right side's descendant\n } else {\n // ancestor query\n // info for parent query\n var _ancestor2 = newQuery();\n var _descendant2 = newQuery();\n var adQChecks = [{\n type: Type.ANCESTOR,\n ancestor: _ancestor2,\n descendant: _descendant2\n }];\n\n // the parent-child query takes the place of the query previously being populated\n _ancestor2.checks = query.checks; // the previous query contains the checks for the parent\n query.checks = adQChecks; // pc query takes over\n\n selector.compoundCount++;\n return _descendant2; // we're now populating the child\n }\n }\n}, {\n name: 'subject',\n modifier: true,\n regex: tokens.subject,\n populate: function populate(selector, query) {\n if (selector.currentSubject != null && selector.currentSubject !== query) {\n warn('Redefinition of subject in selector `' + selector.toString() + '`');\n return false;\n }\n selector.currentSubject = query;\n var topQ = selector[selector.length - 1];\n var topChk = topQ.checks[0];\n var topType = topChk == null ? null : topChk.type;\n if (topType === Type.DIRECTED_EDGE) {\n // directed edge with subject on the target\n\n // change to target node check\n topChk.type = Type.NODE_TARGET;\n } else if (topType === Type.UNDIRECTED_EDGE) {\n // undirected edge with subject on the second node\n\n // change to neighbor check\n topChk.type = Type.NODE_NEIGHBOR;\n topChk.node = topChk.nodes[1]; // second node is subject\n topChk.neighbor = topChk.nodes[0];\n\n // clean up unused fields for new type\n topChk.nodes = null;\n }\n }\n}];\nexprs.forEach(function (e) {\n return e.regexObj = new RegExp('^' + e.regex);\n});\n\n/**\n * Of all the expressions, find the first match in the remaining text.\n * @param {string} remaining The remaining text to parse\n * @returns The matched expression and the newly remaining text `{ expr, match, name, remaining }`\n */\nvar consumeExpr = function consumeExpr(remaining) {\n var expr;\n var match;\n var name;\n for (var j = 0; j < exprs.length; j++) {\n var e = exprs[j];\n var n = e.name;\n var m = remaining.match(e.regexObj);\n if (m != null) {\n match = m;\n expr = e;\n name = n;\n var consumed = m[0];\n remaining = remaining.substring(consumed.length);\n break; // we've consumed one expr, so we can return now\n }\n }\n\n return {\n expr: expr,\n match: match,\n name: name,\n remaining: remaining\n };\n};\n\n/**\n * Consume all the leading whitespace\n * @param {string} remaining The text to consume\n * @returns The text with the leading whitespace removed\n */\nvar consumeWhitespace = function consumeWhitespace(remaining) {\n var match = remaining.match(/^\\s+/);\n if (match) {\n var consumed = match[0];\n remaining = remaining.substring(consumed.length);\n }\n return remaining;\n};\n\n/**\n * Parse the string and store the parsed representation in the Selector.\n * @param {string} selector The selector string\n * @returns `true` if the selector was successfully parsed, `false` otherwise\n */\nvar parse = function parse(selector) {\n var self = this;\n var remaining = self.inputText = selector;\n var currentQuery = self[0] = newQuery();\n self.length = 1;\n remaining = consumeWhitespace(remaining); // get rid of leading whitespace\n\n for (;;) {\n var exprInfo = consumeExpr(remaining);\n if (exprInfo.expr == null) {\n warn('The selector `' + selector + '`is invalid');\n return false;\n } else {\n var args = exprInfo.match.slice(1);\n\n // let the token populate the selector object in currentQuery\n var ret = exprInfo.expr.populate(self, currentQuery, args);\n if (ret === false) {\n return false; // exit if population failed\n } else if (ret != null) {\n currentQuery = ret; // change the current query to be filled if the expr specifies\n }\n }\n\n remaining = exprInfo.remaining;\n\n // we're done when there's nothing left to parse\n if (remaining.match(/^\\s*$/)) {\n break;\n }\n }\n var lastQ = self[self.length - 1];\n if (self.currentSubject != null) {\n lastQ.subject = self.currentSubject;\n }\n lastQ.edgeCount = self.edgeCount;\n lastQ.compoundCount = self.compoundCount;\n for (var i = 0; i < self.length; i++) {\n var q = self[i];\n\n // in future, this could potentially be allowed if there were operator precedence and detection of invalid combinations\n if (q.compoundCount > 0 && q.edgeCount > 0) {\n warn('The selector `' + selector + '` is invalid because it uses both a compound selector and an edge selector');\n return false;\n }\n if (q.edgeCount > 1) {\n warn('The selector `' + selector + '` is invalid because it uses multiple edge selectors');\n return false;\n } else if (q.edgeCount === 1) {\n warn('The selector `' + selector + '` is deprecated. Edge selectors do not take effect on changes to source and target nodes after an edge is added, for performance reasons. Use a class or data selector on edges instead, updating the class or data of an edge when your app detects a change in source or target nodes.');\n }\n }\n return true; // success\n};\n\n/**\n * Get the selector represented as a string. This value uses default formatting,\n * so things like spacing may differ from the input text passed to the constructor.\n * @returns {string} The selector string\n */\nvar toString = function toString() {\n if (this.toStringCache != null) {\n return this.toStringCache;\n }\n var clean = function clean(obj) {\n if (obj == null) {\n return '';\n } else {\n return obj;\n }\n };\n var cleanVal = function cleanVal(val) {\n if (string(val)) {\n return '\"' + val + '\"';\n } else {\n return clean(val);\n }\n };\n var space = function space(val) {\n return ' ' + val + ' ';\n };\n var checkToString = function checkToString(check, subject) {\n var type = check.type,\n value = check.value;\n switch (type) {\n case Type.GROUP:\n {\n var group = clean(value);\n return group.substring(0, group.length - 1);\n }\n case Type.DATA_COMPARE:\n {\n var field = check.field,\n operator = check.operator;\n return '[' + field + space(clean(operator)) + cleanVal(value) + ']';\n }\n case Type.DATA_BOOL:\n {\n var _operator = check.operator,\n _field = check.field;\n return '[' + clean(_operator) + _field + ']';\n }\n case Type.DATA_EXIST:\n {\n var _field2 = check.field;\n return '[' + _field2 + ']';\n }\n case Type.META_COMPARE:\n {\n var _operator2 = check.operator,\n _field3 = check.field;\n return '[[' + _field3 + space(clean(_operator2)) + cleanVal(value) + ']]';\n }\n case Type.STATE:\n {\n return value;\n }\n case Type.ID:\n {\n return '#' + value;\n }\n case Type.CLASS:\n {\n return '.' + value;\n }\n case Type.PARENT:\n case Type.CHILD:\n {\n return queryToString(check.parent, subject) + space('>') + queryToString(check.child, subject);\n }\n case Type.ANCESTOR:\n case Type.DESCENDANT:\n {\n return queryToString(check.ancestor, subject) + ' ' + queryToString(check.descendant, subject);\n }\n case Type.COMPOUND_SPLIT:\n {\n var lhs = queryToString(check.left, subject);\n var sub = queryToString(check.subject, subject);\n var rhs = queryToString(check.right, subject);\n return lhs + (lhs.length > 0 ? ' ' : '') + sub + rhs;\n }\n case Type.TRUE:\n {\n return '';\n }\n }\n };\n var queryToString = function queryToString(query, subject) {\n return query.checks.reduce(function (str, chk, i) {\n return str + (subject === query && i === 0 ? '$' : '') + checkToString(chk, subject);\n }, '');\n };\n var str = '';\n for (var i = 0; i < this.length; i++) {\n var query = this[i];\n str += queryToString(query, query.subject);\n if (this.length > 1 && i < this.length - 1) {\n str += ', ';\n }\n }\n this.toStringCache = str;\n return str;\n};\nvar parse$1 = {\n parse: parse,\n toString: toString\n};\n\nvar valCmp = function valCmp(fieldVal, operator, value) {\n var matches;\n var isFieldStr = string(fieldVal);\n var isFieldNum = number$1(fieldVal);\n var isValStr = string(value);\n var fieldStr, valStr;\n var caseInsensitive = false;\n var notExpr = false;\n var isIneqCmp = false;\n if (operator.indexOf('!') >= 0) {\n operator = operator.replace('!', '');\n notExpr = true;\n }\n if (operator.indexOf('@') >= 0) {\n operator = operator.replace('@', '');\n caseInsensitive = true;\n }\n if (isFieldStr || isValStr || caseInsensitive) {\n fieldStr = !isFieldStr && !isFieldNum ? '' : '' + fieldVal;\n valStr = '' + value;\n }\n\n // if we're doing a case insensitive comparison, then we're using a STRING comparison\n // even if we're comparing numbers\n if (caseInsensitive) {\n fieldVal = fieldStr = fieldStr.toLowerCase();\n value = valStr = valStr.toLowerCase();\n }\n switch (operator) {\n case '*=':\n matches = fieldStr.indexOf(valStr) >= 0;\n break;\n case '$=':\n matches = fieldStr.indexOf(valStr, fieldStr.length - valStr.length) >= 0;\n break;\n case '^=':\n matches = fieldStr.indexOf(valStr) === 0;\n break;\n case '=':\n matches = fieldVal === value;\n break;\n case '>':\n isIneqCmp = true;\n matches = fieldVal > value;\n break;\n case '>=':\n isIneqCmp = true;\n matches = fieldVal >= value;\n break;\n case '<':\n isIneqCmp = true;\n matches = fieldVal < value;\n break;\n case '<=':\n isIneqCmp = true;\n matches = fieldVal <= value;\n break;\n default:\n matches = false;\n break;\n }\n\n // apply the not op, but null vals for inequalities should always stay non-matching\n if (notExpr && (fieldVal != null || !isIneqCmp)) {\n matches = !matches;\n }\n return matches;\n};\nvar boolCmp = function boolCmp(fieldVal, operator) {\n switch (operator) {\n case '?':\n return fieldVal ? true : false;\n case '!':\n return fieldVal ? false : true;\n case '^':\n return fieldVal === undefined;\n }\n};\nvar existCmp = function existCmp(fieldVal) {\n return fieldVal !== undefined;\n};\nvar data$1 = function data(ele, field) {\n return ele.data(field);\n};\nvar meta = function meta(ele, field) {\n return ele[field]();\n};\n\n/** A lookup of `match(check, ele)` functions by `Type` int */\nvar match = [];\n\n/**\n * Returns whether the query matches for the element\n * @param query The `{ type, value, ... }` query object\n * @param ele The element to compare against\n*/\nvar matches$1 = function matches(query, ele) {\n return query.checks.every(function (chk) {\n return match[chk.type](chk, ele);\n });\n};\nmatch[Type.GROUP] = function (check, ele) {\n var group = check.value;\n return group === '*' || group === ele.group();\n};\nmatch[Type.STATE] = function (check, ele) {\n var stateSelector = check.value;\n return stateSelectorMatches(stateSelector, ele);\n};\nmatch[Type.ID] = function (check, ele) {\n var id = check.value;\n return ele.id() === id;\n};\nmatch[Type.CLASS] = function (check, ele) {\n var cls = check.value;\n return ele.hasClass(cls);\n};\nmatch[Type.META_COMPARE] = function (check, ele) {\n var field = check.field,\n operator = check.operator,\n value = check.value;\n return valCmp(meta(ele, field), operator, value);\n};\nmatch[Type.DATA_COMPARE] = function (check, ele) {\n var field = check.field,\n operator = check.operator,\n value = check.value;\n return valCmp(data$1(ele, field), operator, value);\n};\nmatch[Type.DATA_BOOL] = function (check, ele) {\n var field = check.field,\n operator = check.operator;\n return boolCmp(data$1(ele, field), operator);\n};\nmatch[Type.DATA_EXIST] = function (check, ele) {\n var field = check.field;\n check.operator;\n return existCmp(data$1(ele, field));\n};\nmatch[Type.UNDIRECTED_EDGE] = function (check, ele) {\n var qA = check.nodes[0];\n var qB = check.nodes[1];\n var src = ele.source();\n var tgt = ele.target();\n return matches$1(qA, src) && matches$1(qB, tgt) || matches$1(qB, src) && matches$1(qA, tgt);\n};\nmatch[Type.NODE_NEIGHBOR] = function (check, ele) {\n return matches$1(check.node, ele) && ele.neighborhood().some(function (n) {\n return n.isNode() && matches$1(check.neighbor, n);\n });\n};\nmatch[Type.DIRECTED_EDGE] = function (check, ele) {\n return matches$1(check.source, ele.source()) && matches$1(check.target, ele.target());\n};\nmatch[Type.NODE_SOURCE] = function (check, ele) {\n return matches$1(check.source, ele) && ele.outgoers().some(function (n) {\n return n.isNode() && matches$1(check.target, n);\n });\n};\nmatch[Type.NODE_TARGET] = function (check, ele) {\n return matches$1(check.target, ele) && ele.incomers().some(function (n) {\n return n.isNode() && matches$1(check.source, n);\n });\n};\nmatch[Type.CHILD] = function (check, ele) {\n return matches$1(check.child, ele) && matches$1(check.parent, ele.parent());\n};\nmatch[Type.PARENT] = function (check, ele) {\n return matches$1(check.parent, ele) && ele.children().some(function (c) {\n return matches$1(check.child, c);\n });\n};\nmatch[Type.DESCENDANT] = function (check, ele) {\n return matches$1(check.descendant, ele) && ele.ancestors().some(function (a) {\n return matches$1(check.ancestor, a);\n });\n};\nmatch[Type.ANCESTOR] = function (check, ele) {\n return matches$1(check.ancestor, ele) && ele.descendants().some(function (d) {\n return matches$1(check.descendant, d);\n });\n};\nmatch[Type.COMPOUND_SPLIT] = function (check, ele) {\n return matches$1(check.subject, ele) && matches$1(check.left, ele) && matches$1(check.right, ele);\n};\nmatch[Type.TRUE] = function () {\n return true;\n};\nmatch[Type.COLLECTION] = function (check, ele) {\n var collection = check.value;\n return collection.has(ele);\n};\nmatch[Type.FILTER] = function (check, ele) {\n var filter = check.value;\n return filter(ele);\n};\n\n// filter an existing collection\nvar filter = function filter(collection) {\n var self = this;\n\n // for 1 id #foo queries, just get the element\n if (self.length === 1 && self[0].checks.length === 1 && self[0].checks[0].type === Type.ID) {\n return collection.getElementById(self[0].checks[0].value).collection();\n }\n var selectorFunction = function selectorFunction(element) {\n for (var j = 0; j < self.length; j++) {\n var query = self[j];\n if (matches$1(query, element)) {\n return true;\n }\n }\n return false;\n };\n if (self.text() == null) {\n selectorFunction = function selectorFunction() {\n return true;\n };\n }\n return collection.filter(selectorFunction);\n}; // filter\n\n// does selector match a single element?\nvar matches = function matches(ele) {\n var self = this;\n for (var j = 0; j < self.length; j++) {\n var query = self[j];\n if (matches$1(query, ele)) {\n return true;\n }\n }\n return false;\n}; // matches\n\nvar matching = {\n matches: matches,\n filter: filter\n};\n\nvar Selector = function Selector(selector) {\n this.inputText = selector;\n this.currentSubject = null;\n this.compoundCount = 0;\n this.edgeCount = 0;\n this.length = 0;\n if (selector == null || string(selector) && selector.match(/^\\s*$/)) ; else if (elementOrCollection(selector)) {\n this.addQuery({\n checks: [{\n type: Type.COLLECTION,\n value: selector.collection()\n }]\n });\n } else if (fn$6(selector)) {\n this.addQuery({\n checks: [{\n type: Type.FILTER,\n value: selector\n }]\n });\n } else if (string(selector)) {\n if (!this.parse(selector)) {\n this.invalid = true;\n }\n } else {\n error('A selector must be created from a string; found ');\n }\n};\nvar selfn = Selector.prototype;\n[parse$1, matching].forEach(function (p) {\n return extend(selfn, p);\n});\nselfn.text = function () {\n return this.inputText;\n};\nselfn.size = function () {\n return this.length;\n};\nselfn.eq = function (i) {\n return this[i];\n};\nselfn.sameText = function (otherSel) {\n return !this.invalid && !otherSel.invalid && this.text() === otherSel.text();\n};\nselfn.addQuery = function (q) {\n this[this.length++] = q;\n};\nselfn.selector = selfn.toString;\n\nvar elesfn$g = {\n allAre: function allAre(selector) {\n var selObj = new Selector(selector);\n return this.every(function (ele) {\n return selObj.matches(ele);\n });\n },\n is: function is(selector) {\n var selObj = new Selector(selector);\n return this.some(function (ele) {\n return selObj.matches(ele);\n });\n },\n some: function some(fn, thisArg) {\n for (var i = 0; i < this.length; i++) {\n var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]);\n if (ret) {\n return true;\n }\n }\n return false;\n },\n every: function every(fn, thisArg) {\n for (var i = 0; i < this.length; i++) {\n var ret = !thisArg ? fn(this[i], i, this) : fn.apply(thisArg, [this[i], i, this]);\n if (!ret) {\n return false;\n }\n }\n return true;\n },\n same: function same(collection) {\n // cheap collection ref check\n if (this === collection) {\n return true;\n }\n collection = this.cy().collection(collection);\n var thisLength = this.length;\n var collectionLength = collection.length;\n\n // cheap length check\n if (thisLength !== collectionLength) {\n return false;\n }\n\n // cheap element ref check\n if (thisLength === 1) {\n return this[0] === collection[0];\n }\n return this.every(function (ele) {\n return collection.hasElementWithId(ele.id());\n });\n },\n anySame: function anySame(collection) {\n collection = this.cy().collection(collection);\n return this.some(function (ele) {\n return collection.hasElementWithId(ele.id());\n });\n },\n allAreNeighbors: function allAreNeighbors(collection) {\n collection = this.cy().collection(collection);\n var nhood = this.neighborhood();\n return collection.every(function (ele) {\n return nhood.hasElementWithId(ele.id());\n });\n },\n contains: function contains(collection) {\n collection = this.cy().collection(collection);\n var self = this;\n return collection.every(function (ele) {\n return self.hasElementWithId(ele.id());\n });\n }\n};\nelesfn$g.allAreNeighbours = elesfn$g.allAreNeighbors;\nelesfn$g.has = elesfn$g.contains;\nelesfn$g.equal = elesfn$g.equals = elesfn$g.same;\n\nvar cache = function cache(fn, name) {\n return function traversalCache(arg1, arg2, arg3, arg4) {\n var selectorOrEles = arg1;\n var eles = this;\n var key;\n if (selectorOrEles == null) {\n key = '';\n } else if (elementOrCollection(selectorOrEles) && selectorOrEles.length === 1) {\n key = selectorOrEles.id();\n }\n if (eles.length === 1 && key) {\n var _p = eles[0]._private;\n var tch = _p.traversalCache = _p.traversalCache || {};\n var ch = tch[name] = tch[name] || [];\n var hash = hashString(key);\n var cacheHit = ch[hash];\n if (cacheHit) {\n return cacheHit;\n } else {\n return ch[hash] = fn.call(eles, arg1, arg2, arg3, arg4);\n }\n } else {\n return fn.call(eles, arg1, arg2, arg3, arg4);\n }\n };\n};\n\nvar elesfn$f = {\n parent: function parent(selector) {\n var parents = [];\n\n // optimisation for single ele call\n if (this.length === 1) {\n var parent = this[0]._private.parent;\n if (parent) {\n return parent;\n }\n }\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var _parent = ele._private.parent;\n if (_parent) {\n parents.push(_parent);\n }\n }\n return this.spawn(parents, true).filter(selector);\n },\n parents: function parents(selector) {\n var parents = [];\n var eles = this.parent();\n while (eles.nonempty()) {\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n parents.push(ele);\n }\n eles = eles.parent();\n }\n return this.spawn(parents, true).filter(selector);\n },\n commonAncestors: function commonAncestors(selector) {\n var ancestors;\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var parents = ele.parents();\n ancestors = ancestors || parents;\n ancestors = ancestors.intersect(parents); // current list must be common with current ele parents set\n }\n\n return ancestors.filter(selector);\n },\n orphans: function orphans(selector) {\n return this.stdFilter(function (ele) {\n return ele.isOrphan();\n }).filter(selector);\n },\n nonorphans: function nonorphans(selector) {\n return this.stdFilter(function (ele) {\n return ele.isChild();\n }).filter(selector);\n },\n children: cache(function (selector) {\n var children = [];\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var eleChildren = ele._private.children;\n for (var j = 0; j < eleChildren.length; j++) {\n children.push(eleChildren[j]);\n }\n }\n return this.spawn(children, true).filter(selector);\n }, 'children'),\n siblings: function siblings(selector) {\n return this.parent().children().not(this).filter(selector);\n },\n isParent: function isParent() {\n var ele = this[0];\n if (ele) {\n return ele.isNode() && ele._private.children.length !== 0;\n }\n },\n isChildless: function isChildless() {\n var ele = this[0];\n if (ele) {\n return ele.isNode() && ele._private.children.length === 0;\n }\n },\n isChild: function isChild() {\n var ele = this[0];\n if (ele) {\n return ele.isNode() && ele._private.parent != null;\n }\n },\n isOrphan: function isOrphan() {\n var ele = this[0];\n if (ele) {\n return ele.isNode() && ele._private.parent == null;\n }\n },\n descendants: function descendants(selector) {\n var elements = [];\n function add(eles) {\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n elements.push(ele);\n if (ele.children().nonempty()) {\n add(ele.children());\n }\n }\n }\n add(this.children());\n return this.spawn(elements, true).filter(selector);\n }\n};\nfunction forEachCompound(eles, fn, includeSelf, recursiveStep) {\n var q = [];\n var did = new Set$1();\n var cy = eles.cy();\n var hasCompounds = cy.hasCompoundNodes();\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n if (includeSelf) {\n q.push(ele);\n } else if (hasCompounds) {\n recursiveStep(q, did, ele);\n }\n }\n while (q.length > 0) {\n var _ele = q.shift();\n fn(_ele);\n did.add(_ele.id());\n if (hasCompounds) {\n recursiveStep(q, did, _ele);\n }\n }\n return eles;\n}\nfunction addChildren(q, did, ele) {\n if (ele.isParent()) {\n var children = ele._private.children;\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n if (!did.has(child.id())) {\n q.push(child);\n }\n }\n }\n}\n\n// very efficient version of eles.add( eles.descendants() ).forEach()\n// for internal use\nelesfn$f.forEachDown = function (fn) {\n var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n return forEachCompound(this, fn, includeSelf, addChildren);\n};\nfunction addParent(q, did, ele) {\n if (ele.isChild()) {\n var parent = ele._private.parent;\n if (!did.has(parent.id())) {\n q.push(parent);\n }\n }\n}\nelesfn$f.forEachUp = function (fn) {\n var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n return forEachCompound(this, fn, includeSelf, addParent);\n};\nfunction addParentAndChildren(q, did, ele) {\n addParent(q, did, ele);\n addChildren(q, did, ele);\n}\nelesfn$f.forEachUpAndDown = function (fn) {\n var includeSelf = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n return forEachCompound(this, fn, includeSelf, addParentAndChildren);\n};\n\n// aliases\nelesfn$f.ancestors = elesfn$f.parents;\n\nvar fn$5, elesfn$e;\nfn$5 = elesfn$e = {\n data: define.data({\n field: 'data',\n bindingEvent: 'data',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'data',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true,\n immutableKeys: {\n 'id': true,\n 'source': true,\n 'target': true,\n 'parent': true\n },\n updateStyle: true\n }),\n removeData: define.removeData({\n field: 'data',\n event: 'data',\n triggerFnName: 'trigger',\n triggerEvent: true,\n immutableKeys: {\n 'id': true,\n 'source': true,\n 'target': true,\n 'parent': true\n },\n updateStyle: true\n }),\n scratch: define.data({\n field: 'scratch',\n bindingEvent: 'scratch',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'scratch',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true,\n updateStyle: true\n }),\n removeScratch: define.removeData({\n field: 'scratch',\n event: 'scratch',\n triggerFnName: 'trigger',\n triggerEvent: true,\n updateStyle: true\n }),\n rscratch: define.data({\n field: 'rscratch',\n allowBinding: false,\n allowSetting: true,\n settingTriggersEvent: false,\n allowGetting: true\n }),\n removeRscratch: define.removeData({\n field: 'rscratch',\n triggerEvent: false\n }),\n id: function id() {\n var ele = this[0];\n if (ele) {\n return ele._private.data.id;\n }\n }\n};\n\n// aliases\nfn$5.attr = fn$5.data;\nfn$5.removeAttr = fn$5.removeData;\nvar data = elesfn$e;\n\nvar elesfn$d = {};\nfunction defineDegreeFunction(callback) {\n return function (includeLoops) {\n var self = this;\n if (includeLoops === undefined) {\n includeLoops = true;\n }\n if (self.length === 0) {\n return;\n }\n if (self.isNode() && !self.removed()) {\n var degree = 0;\n var node = self[0];\n var connectedEdges = node._private.edges;\n for (var i = 0; i < connectedEdges.length; i++) {\n var edge = connectedEdges[i];\n if (!includeLoops && edge.isLoop()) {\n continue;\n }\n degree += callback(node, edge);\n }\n return degree;\n } else {\n return;\n }\n };\n}\nextend(elesfn$d, {\n degree: defineDegreeFunction(function (node, edge) {\n if (edge.source().same(edge.target())) {\n return 2;\n } else {\n return 1;\n }\n }),\n indegree: defineDegreeFunction(function (node, edge) {\n if (edge.target().same(node)) {\n return 1;\n } else {\n return 0;\n }\n }),\n outdegree: defineDegreeFunction(function (node, edge) {\n if (edge.source().same(node)) {\n return 1;\n } else {\n return 0;\n }\n })\n});\nfunction defineDegreeBoundsFunction(degreeFn, callback) {\n return function (includeLoops) {\n var ret;\n var nodes = this.nodes();\n for (var i = 0; i < nodes.length; i++) {\n var ele = nodes[i];\n var degree = ele[degreeFn](includeLoops);\n if (degree !== undefined && (ret === undefined || callback(degree, ret))) {\n ret = degree;\n }\n }\n return ret;\n };\n}\nextend(elesfn$d, {\n minDegree: defineDegreeBoundsFunction('degree', function (degree, min) {\n return degree < min;\n }),\n maxDegree: defineDegreeBoundsFunction('degree', function (degree, max) {\n return degree > max;\n }),\n minIndegree: defineDegreeBoundsFunction('indegree', function (degree, min) {\n return degree < min;\n }),\n maxIndegree: defineDegreeBoundsFunction('indegree', function (degree, max) {\n return degree > max;\n }),\n minOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, min) {\n return degree < min;\n }),\n maxOutdegree: defineDegreeBoundsFunction('outdegree', function (degree, max) {\n return degree > max;\n })\n});\nextend(elesfn$d, {\n totalDegree: function totalDegree(includeLoops) {\n var total = 0;\n var nodes = this.nodes();\n for (var i = 0; i < nodes.length; i++) {\n total += nodes[i].degree(includeLoops);\n }\n return total;\n }\n});\n\nvar fn$4, elesfn$c;\nvar beforePositionSet = function beforePositionSet(eles, newPos, silent) {\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n if (!ele.locked()) {\n var oldPos = ele._private.position;\n var delta = {\n x: newPos.x != null ? newPos.x - oldPos.x : 0,\n y: newPos.y != null ? newPos.y - oldPos.y : 0\n };\n if (ele.isParent() && !(delta.x === 0 && delta.y === 0)) {\n ele.children().shift(delta, silent);\n }\n ele.dirtyBoundingBoxCache();\n }\n }\n};\nvar positionDef = {\n field: 'position',\n bindingEvent: 'position',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'position',\n settingTriggersEvent: true,\n triggerFnName: 'emitAndNotify',\n allowGetting: true,\n validKeys: ['x', 'y'],\n beforeGet: function beforeGet(ele) {\n ele.updateCompoundBounds();\n },\n beforeSet: function beforeSet(eles, newPos) {\n beforePositionSet(eles, newPos, false);\n },\n onSet: function onSet(eles) {\n eles.dirtyCompoundBoundsCache();\n },\n canSet: function canSet(ele) {\n return !ele.locked();\n }\n};\nfn$4 = elesfn$c = {\n position: define.data(positionDef),\n // position but no notification to renderer\n silentPosition: define.data(extend({}, positionDef, {\n allowBinding: false,\n allowSetting: true,\n settingTriggersEvent: false,\n allowGetting: false,\n beforeSet: function beforeSet(eles, newPos) {\n beforePositionSet(eles, newPos, true);\n },\n onSet: function onSet(eles) {\n eles.dirtyCompoundBoundsCache();\n }\n })),\n positions: function positions(pos, silent) {\n if (plainObject(pos)) {\n if (silent) {\n this.silentPosition(pos);\n } else {\n this.position(pos);\n }\n } else if (fn$6(pos)) {\n var _fn = pos;\n var cy = this.cy();\n cy.startBatch();\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var _pos = void 0;\n if (_pos = _fn(ele, i)) {\n if (silent) {\n ele.silentPosition(_pos);\n } else {\n ele.position(_pos);\n }\n }\n }\n cy.endBatch();\n }\n return this; // chaining\n },\n\n silentPositions: function silentPositions(pos) {\n return this.positions(pos, true);\n },\n shift: function shift(dim, val, silent) {\n var delta;\n if (plainObject(dim)) {\n delta = {\n x: number$1(dim.x) ? dim.x : 0,\n y: number$1(dim.y) ? dim.y : 0\n };\n silent = val;\n } else if (string(dim) && number$1(val)) {\n delta = {\n x: 0,\n y: 0\n };\n delta[dim] = val;\n }\n if (delta != null) {\n var cy = this.cy();\n cy.startBatch();\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n\n // exclude any node that is a descendant of the calling collection\n if (cy.hasCompoundNodes() && ele.isChild() && ele.ancestors().anySame(this)) {\n continue;\n }\n var pos = ele.position();\n var newPos = {\n x: pos.x + delta.x,\n y: pos.y + delta.y\n };\n if (silent) {\n ele.silentPosition(newPos);\n } else {\n ele.position(newPos);\n }\n }\n cy.endBatch();\n }\n return this;\n },\n silentShift: function silentShift(dim, val) {\n if (plainObject(dim)) {\n this.shift(dim, true);\n } else if (string(dim) && number$1(val)) {\n this.shift(dim, val, true);\n }\n return this;\n },\n // get/set the rendered (i.e. on screen) positon of the element\n renderedPosition: function renderedPosition(dim, val) {\n var ele = this[0];\n var cy = this.cy();\n var zoom = cy.zoom();\n var pan = cy.pan();\n var rpos = plainObject(dim) ? dim : undefined;\n var setting = rpos !== undefined || val !== undefined && string(dim);\n if (ele && ele.isNode()) {\n // must have an element and must be a node to return position\n if (setting) {\n for (var i = 0; i < this.length; i++) {\n var _ele = this[i];\n if (val !== undefined) {\n // set one dimension\n _ele.position(dim, (val - pan[dim]) / zoom);\n } else if (rpos !== undefined) {\n // set whole position\n _ele.position(renderedToModelPosition(rpos, zoom, pan));\n }\n }\n } else {\n // getting\n var pos = ele.position();\n rpos = modelToRenderedPosition(pos, zoom, pan);\n if (dim === undefined) {\n // then return the whole rendered position\n return rpos;\n } else {\n // then return the specified dimension\n return rpos[dim];\n }\n }\n } else if (!setting) {\n return undefined; // for empty collection case\n }\n\n return this; // chaining\n },\n\n // get/set the position relative to the parent\n relativePosition: function relativePosition(dim, val) {\n var ele = this[0];\n var cy = this.cy();\n var ppos = plainObject(dim) ? dim : undefined;\n var setting = ppos !== undefined || val !== undefined && string(dim);\n var hasCompoundNodes = cy.hasCompoundNodes();\n if (ele && ele.isNode()) {\n // must have an element and must be a node to return position\n if (setting) {\n for (var i = 0; i < this.length; i++) {\n var _ele2 = this[i];\n var parent = hasCompoundNodes ? _ele2.parent() : null;\n var hasParent = parent && parent.length > 0;\n var relativeToParent = hasParent;\n if (hasParent) {\n parent = parent[0];\n }\n var origin = relativeToParent ? parent.position() : {\n x: 0,\n y: 0\n };\n if (val !== undefined) {\n // set one dimension\n _ele2.position(dim, val + origin[dim]);\n } else if (ppos !== undefined) {\n // set whole position\n _ele2.position({\n x: ppos.x + origin.x,\n y: ppos.y + origin.y\n });\n }\n }\n } else {\n // getting\n var pos = ele.position();\n var _parent = hasCompoundNodes ? ele.parent() : null;\n var _hasParent = _parent && _parent.length > 0;\n var _relativeToParent = _hasParent;\n if (_hasParent) {\n _parent = _parent[0];\n }\n var _origin = _relativeToParent ? _parent.position() : {\n x: 0,\n y: 0\n };\n ppos = {\n x: pos.x - _origin.x,\n y: pos.y - _origin.y\n };\n if (dim === undefined) {\n // then return the whole rendered position\n return ppos;\n } else {\n // then return the specified dimension\n return ppos[dim];\n }\n }\n } else if (!setting) {\n return undefined; // for empty collection case\n }\n\n return this; // chaining\n }\n};\n\n// aliases\nfn$4.modelPosition = fn$4.point = fn$4.position;\nfn$4.modelPositions = fn$4.points = fn$4.positions;\nfn$4.renderedPoint = fn$4.renderedPosition;\nfn$4.relativePoint = fn$4.relativePosition;\nvar position = elesfn$c;\n\nvar fn$3, elesfn$b;\nfn$3 = elesfn$b = {};\nelesfn$b.renderedBoundingBox = function (options) {\n var bb = this.boundingBox(options);\n var cy = this.cy();\n var zoom = cy.zoom();\n var pan = cy.pan();\n var x1 = bb.x1 * zoom + pan.x;\n var x2 = bb.x2 * zoom + pan.x;\n var y1 = bb.y1 * zoom + pan.y;\n var y2 = bb.y2 * zoom + pan.y;\n return {\n x1: x1,\n x2: x2,\n y1: y1,\n y2: y2,\n w: x2 - x1,\n h: y2 - y1\n };\n};\nelesfn$b.dirtyCompoundBoundsCache = function () {\n var silent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n var cy = this.cy();\n if (!cy.styleEnabled() || !cy.hasCompoundNodes()) {\n return this;\n }\n this.forEachUp(function (ele) {\n if (ele.isParent()) {\n var _p = ele._private;\n _p.compoundBoundsClean = false;\n _p.bbCache = null;\n if (!silent) {\n ele.emitAndNotify('bounds');\n }\n }\n });\n return this;\n};\nelesfn$b.updateCompoundBounds = function () {\n var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n var cy = this.cy();\n\n // not possible to do on non-compound graphs or with the style disabled\n if (!cy.styleEnabled() || !cy.hasCompoundNodes()) {\n return this;\n }\n\n // save cycles when batching -- but bounds will be stale (or not exist yet)\n if (!force && cy.batching()) {\n return this;\n }\n function update(parent) {\n if (!parent.isParent()) {\n return;\n }\n var _p = parent._private;\n var children = parent.children();\n var includeLabels = parent.pstyle('compound-sizing-wrt-labels').value === 'include';\n var min = {\n width: {\n val: parent.pstyle('min-width').pfValue,\n left: parent.pstyle('min-width-bias-left'),\n right: parent.pstyle('min-width-bias-right')\n },\n height: {\n val: parent.pstyle('min-height').pfValue,\n top: parent.pstyle('min-height-bias-top'),\n bottom: parent.pstyle('min-height-bias-bottom')\n }\n };\n var bb = children.boundingBox({\n includeLabels: includeLabels,\n includeOverlays: false,\n // updating the compound bounds happens outside of the regular\n // cache cycle (i.e. before fired events)\n useCache: false\n });\n var pos = _p.position;\n\n // if children take up zero area then keep position and fall back on stylesheet w/h\n if (bb.w === 0 || bb.h === 0) {\n bb = {\n w: parent.pstyle('width').pfValue,\n h: parent.pstyle('height').pfValue\n };\n bb.x1 = pos.x - bb.w / 2;\n bb.x2 = pos.x + bb.w / 2;\n bb.y1 = pos.y - bb.h / 2;\n bb.y2 = pos.y + bb.h / 2;\n }\n function computeBiasValues(propDiff, propBias, propBiasComplement) {\n var biasDiff = 0;\n var biasComplementDiff = 0;\n var biasTotal = propBias + propBiasComplement;\n if (propDiff > 0 && biasTotal > 0) {\n biasDiff = propBias / biasTotal * propDiff;\n biasComplementDiff = propBiasComplement / biasTotal * propDiff;\n }\n return {\n biasDiff: biasDiff,\n biasComplementDiff: biasComplementDiff\n };\n }\n function computePaddingValues(width, height, paddingObject, relativeTo) {\n // Assuming percentage is number from 0 to 1\n if (paddingObject.units === '%') {\n switch (relativeTo) {\n case 'width':\n return width > 0 ? paddingObject.pfValue * width : 0;\n case 'height':\n return height > 0 ? paddingObject.pfValue * height : 0;\n case 'average':\n return width > 0 && height > 0 ? paddingObject.pfValue * (width + height) / 2 : 0;\n case 'min':\n return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * height : paddingObject.pfValue * width : 0;\n case 'max':\n return width > 0 && height > 0 ? width > height ? paddingObject.pfValue * width : paddingObject.pfValue * height : 0;\n default:\n return 0;\n }\n } else if (paddingObject.units === 'px') {\n return paddingObject.pfValue;\n } else {\n return 0;\n }\n }\n var leftVal = min.width.left.value;\n if (min.width.left.units === 'px' && min.width.val > 0) {\n leftVal = leftVal * 100 / min.width.val;\n }\n var rightVal = min.width.right.value;\n if (min.width.right.units === 'px' && min.width.val > 0) {\n rightVal = rightVal * 100 / min.width.val;\n }\n var topVal = min.height.top.value;\n if (min.height.top.units === 'px' && min.height.val > 0) {\n topVal = topVal * 100 / min.height.val;\n }\n var bottomVal = min.height.bottom.value;\n if (min.height.bottom.units === 'px' && min.height.val > 0) {\n bottomVal = bottomVal * 100 / min.height.val;\n }\n var widthBiasDiffs = computeBiasValues(min.width.val - bb.w, leftVal, rightVal);\n var diffLeft = widthBiasDiffs.biasDiff;\n var diffRight = widthBiasDiffs.biasComplementDiff;\n var heightBiasDiffs = computeBiasValues(min.height.val - bb.h, topVal, bottomVal);\n var diffTop = heightBiasDiffs.biasDiff;\n var diffBottom = heightBiasDiffs.biasComplementDiff;\n _p.autoPadding = computePaddingValues(bb.w, bb.h, parent.pstyle('padding'), parent.pstyle('padding-relative-to').value);\n _p.autoWidth = Math.max(bb.w, min.width.val);\n pos.x = (-diffLeft + bb.x1 + bb.x2 + diffRight) / 2;\n _p.autoHeight = Math.max(bb.h, min.height.val);\n pos.y = (-diffTop + bb.y1 + bb.y2 + diffBottom) / 2;\n }\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var _p = ele._private;\n if (!_p.compoundBoundsClean || force) {\n update(ele);\n if (!cy.batching()) {\n _p.compoundBoundsClean = true;\n }\n }\n }\n return this;\n};\nvar noninf = function noninf(x) {\n if (x === Infinity || x === -Infinity) {\n return 0;\n }\n return x;\n};\nvar updateBounds = function updateBounds(b, x1, y1, x2, y2) {\n // don't update with zero area boxes\n if (x2 - x1 === 0 || y2 - y1 === 0) {\n return;\n }\n\n // don't update with null dim\n if (x1 == null || y1 == null || x2 == null || y2 == null) {\n return;\n }\n b.x1 = x1 < b.x1 ? x1 : b.x1;\n b.x2 = x2 > b.x2 ? x2 : b.x2;\n b.y1 = y1 < b.y1 ? y1 : b.y1;\n b.y2 = y2 > b.y2 ? y2 : b.y2;\n b.w = b.x2 - b.x1;\n b.h = b.y2 - b.y1;\n};\nvar updateBoundsFromBox = function updateBoundsFromBox(b, b2) {\n if (b2 == null) {\n return b;\n }\n return updateBounds(b, b2.x1, b2.y1, b2.x2, b2.y2);\n};\nvar prefixedProperty = function prefixedProperty(obj, field, prefix) {\n return getPrefixedProperty(obj, field, prefix);\n};\nvar updateBoundsFromArrow = function updateBoundsFromArrow(bounds, ele, prefix) {\n if (ele.cy().headless()) {\n return;\n }\n var _p = ele._private;\n var rstyle = _p.rstyle;\n var halfArW = rstyle.arrowWidth / 2;\n var arrowType = ele.pstyle(prefix + '-arrow-shape').value;\n var x;\n var y;\n if (arrowType !== 'none') {\n if (prefix === 'source') {\n x = rstyle.srcX;\n y = rstyle.srcY;\n } else if (prefix === 'target') {\n x = rstyle.tgtX;\n y = rstyle.tgtY;\n } else {\n x = rstyle.midX;\n y = rstyle.midY;\n }\n\n // always store the individual arrow bounds\n var bbs = _p.arrowBounds = _p.arrowBounds || {};\n var bb = bbs[prefix] = bbs[prefix] || {};\n bb.x1 = x - halfArW;\n bb.y1 = y - halfArW;\n bb.x2 = x + halfArW;\n bb.y2 = y + halfArW;\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n expandBoundingBox(bb, 1);\n updateBounds(bounds, bb.x1, bb.y1, bb.x2, bb.y2);\n }\n};\nvar updateBoundsFromLabel = function updateBoundsFromLabel(bounds, ele, prefix) {\n if (ele.cy().headless()) {\n return;\n }\n var prefixDash;\n if (prefix) {\n prefixDash = prefix + '-';\n } else {\n prefixDash = '';\n }\n var _p = ele._private;\n var rstyle = _p.rstyle;\n var label = ele.pstyle(prefixDash + 'label').strValue;\n if (label) {\n var halign = ele.pstyle('text-halign');\n var valign = ele.pstyle('text-valign');\n var labelWidth = prefixedProperty(rstyle, 'labelWidth', prefix);\n var labelHeight = prefixedProperty(rstyle, 'labelHeight', prefix);\n var labelX = prefixedProperty(rstyle, 'labelX', prefix);\n var labelY = prefixedProperty(rstyle, 'labelY', prefix);\n var marginX = ele.pstyle(prefixDash + 'text-margin-x').pfValue;\n var marginY = ele.pstyle(prefixDash + 'text-margin-y').pfValue;\n var isEdge = ele.isEdge();\n var rotation = ele.pstyle(prefixDash + 'text-rotation');\n var outlineWidth = ele.pstyle('text-outline-width').pfValue;\n var borderWidth = ele.pstyle('text-border-width').pfValue;\n var halfBorderWidth = borderWidth / 2;\n var padding = ele.pstyle('text-background-padding').pfValue;\n var marginOfError = 2; // expand to work around browser dimension inaccuracies\n\n var lh = labelHeight;\n var lw = labelWidth;\n var lw_2 = lw / 2;\n var lh_2 = lh / 2;\n var lx1, lx2, ly1, ly2;\n if (isEdge) {\n lx1 = labelX - lw_2;\n lx2 = labelX + lw_2;\n ly1 = labelY - lh_2;\n ly2 = labelY + lh_2;\n } else {\n switch (halign.value) {\n case 'left':\n lx1 = labelX - lw;\n lx2 = labelX;\n break;\n case 'center':\n lx1 = labelX - lw_2;\n lx2 = labelX + lw_2;\n break;\n case 'right':\n lx1 = labelX;\n lx2 = labelX + lw;\n break;\n }\n switch (valign.value) {\n case 'top':\n ly1 = labelY - lh;\n ly2 = labelY;\n break;\n case 'center':\n ly1 = labelY - lh_2;\n ly2 = labelY + lh_2;\n break;\n case 'bottom':\n ly1 = labelY;\n ly2 = labelY + lh;\n break;\n }\n }\n\n // shift by margin and expand by outline and border\n lx1 += marginX - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError;\n lx2 += marginX + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError;\n ly1 += marginY - Math.max(outlineWidth, halfBorderWidth) - padding - marginOfError;\n ly2 += marginY + Math.max(outlineWidth, halfBorderWidth) + padding + marginOfError;\n\n // always store the unrotated label bounds separately\n var bbPrefix = prefix || 'main';\n var bbs = _p.labelBounds;\n var bb = bbs[bbPrefix] = bbs[bbPrefix] || {};\n bb.x1 = lx1;\n bb.y1 = ly1;\n bb.x2 = lx2;\n bb.y2 = ly2;\n bb.w = lx2 - lx1;\n bb.h = ly2 - ly1;\n var isAutorotate = isEdge && rotation.strValue === 'autorotate';\n var isPfValue = rotation.pfValue != null && rotation.pfValue !== 0;\n if (isAutorotate || isPfValue) {\n var theta = isAutorotate ? prefixedProperty(_p.rstyle, 'labelAngle', prefix) : rotation.pfValue;\n var cos = Math.cos(theta);\n var sin = Math.sin(theta);\n\n // rotation point (default value for center-center)\n var xo = (lx1 + lx2) / 2;\n var yo = (ly1 + ly2) / 2;\n if (!isEdge) {\n switch (halign.value) {\n case 'left':\n xo = lx2;\n break;\n case 'right':\n xo = lx1;\n break;\n }\n switch (valign.value) {\n case 'top':\n yo = ly2;\n break;\n case 'bottom':\n yo = ly1;\n break;\n }\n }\n var rotate = function rotate(x, y) {\n x = x - xo;\n y = y - yo;\n return {\n x: x * cos - y * sin + xo,\n y: x * sin + y * cos + yo\n };\n };\n var px1y1 = rotate(lx1, ly1);\n var px1y2 = rotate(lx1, ly2);\n var px2y1 = rotate(lx2, ly1);\n var px2y2 = rotate(lx2, ly2);\n lx1 = Math.min(px1y1.x, px1y2.x, px2y1.x, px2y2.x);\n lx2 = Math.max(px1y1.x, px1y2.x, px2y1.x, px2y2.x);\n ly1 = Math.min(px1y1.y, px1y2.y, px2y1.y, px2y2.y);\n ly2 = Math.max(px1y1.y, px1y2.y, px2y1.y, px2y2.y);\n }\n var bbPrefixRot = bbPrefix + 'Rot';\n var bbRot = bbs[bbPrefixRot] = bbs[bbPrefixRot] || {};\n bbRot.x1 = lx1;\n bbRot.y1 = ly1;\n bbRot.x2 = lx2;\n bbRot.y2 = ly2;\n bbRot.w = lx2 - lx1;\n bbRot.h = ly2 - ly1;\n updateBounds(bounds, lx1, ly1, lx2, ly2);\n updateBounds(_p.labelBounds.all, lx1, ly1, lx2, ly2);\n }\n return bounds;\n};\nvar updateBoundsFromOutline = function updateBoundsFromOutline(bounds, ele) {\n if (ele.cy().headless()) {\n return;\n }\n var outlineOpacity = ele.pstyle('outline-opacity').value;\n var outlineWidth = ele.pstyle('outline-width').value;\n if (outlineOpacity > 0 && outlineWidth > 0) {\n var outlineOffset = ele.pstyle('outline-offset').value;\n var nodeShape = ele.pstyle('shape').value;\n var outlineSize = outlineWidth + outlineOffset;\n var scaleX = (bounds.w + outlineSize * 2) / bounds.w;\n var scaleY = (bounds.h + outlineSize * 2) / bounds.h;\n var xOffset = 0;\n var yOffset = 0;\n if ([\"diamond\", \"pentagon\", \"round-triangle\"].includes(nodeShape)) {\n scaleX = (bounds.w + outlineSize * 2.4) / bounds.w;\n yOffset = -outlineSize / 3.6;\n } else if ([\"concave-hexagon\", \"rhomboid\", \"right-rhomboid\"].includes(nodeShape)) {\n scaleX = (bounds.w + outlineSize * 2.4) / bounds.w;\n } else if (nodeShape === \"star\") {\n scaleX = (bounds.w + outlineSize * 2.8) / bounds.w;\n scaleY = (bounds.h + outlineSize * 2.6) / bounds.h;\n yOffset = -outlineSize / 3.8;\n } else if (nodeShape === \"triangle\") {\n scaleX = (bounds.w + outlineSize * 2.8) / bounds.w;\n scaleY = (bounds.h + outlineSize * 2.4) / bounds.h;\n yOffset = -outlineSize / 1.4;\n } else if (nodeShape === \"vee\") {\n scaleX = (bounds.w + outlineSize * 4.4) / bounds.w;\n scaleY = (bounds.h + outlineSize * 3.8) / bounds.h;\n yOffset = -outlineSize * .5;\n }\n var hDelta = bounds.h * scaleY - bounds.h;\n var wDelta = bounds.w * scaleX - bounds.w;\n expandBoundingBoxSides(bounds, [Math.ceil(hDelta / 2), Math.ceil(wDelta / 2)]);\n if (xOffset != 0 || yOffset !== 0) {\n var oBounds = shiftBoundingBox(bounds, xOffset, yOffset);\n updateBoundingBox(bounds, oBounds);\n }\n }\n};\n\n// get the bounding box of the elements (in raw model position)\nvar boundingBoxImpl = function boundingBoxImpl(ele, options) {\n var cy = ele._private.cy;\n var styleEnabled = cy.styleEnabled();\n var headless = cy.headless();\n var bounds = makeBoundingBox();\n var _p = ele._private;\n var isNode = ele.isNode();\n var isEdge = ele.isEdge();\n var ex1, ex2, ey1, ey2; // extrema of body / lines\n var x, y; // node pos\n var rstyle = _p.rstyle;\n var manualExpansion = isNode && styleEnabled ? ele.pstyle('bounds-expansion').pfValue : [0];\n\n // must use `display` prop only, as reading `compound.width()` causes recursion\n // (other factors like width values will be considered later in this function anyway)\n var isDisplayed = function isDisplayed(ele) {\n return ele.pstyle('display').value !== 'none';\n };\n var displayed = !styleEnabled || isDisplayed(ele)\n\n // must take into account connected nodes b/c of implicit edge hiding on display:none node\n && (!isEdge || isDisplayed(ele.source()) && isDisplayed(ele.target()));\n if (displayed) {\n // displayed suffices, since we will find zero area eles anyway\n var overlayOpacity = 0;\n var overlayPadding = 0;\n if (styleEnabled && options.includeOverlays) {\n overlayOpacity = ele.pstyle('overlay-opacity').value;\n if (overlayOpacity !== 0) {\n overlayPadding = ele.pstyle('overlay-padding').value;\n }\n }\n var underlayOpacity = 0;\n var underlayPadding = 0;\n if (styleEnabled && options.includeUnderlays) {\n underlayOpacity = ele.pstyle('underlay-opacity').value;\n if (underlayOpacity !== 0) {\n underlayPadding = ele.pstyle('underlay-padding').value;\n }\n }\n var padding = Math.max(overlayPadding, underlayPadding);\n var w = 0;\n var wHalf = 0;\n if (styleEnabled) {\n w = ele.pstyle('width').pfValue;\n wHalf = w / 2;\n }\n if (isNode && options.includeNodes) {\n var pos = ele.position();\n x = pos.x;\n y = pos.y;\n var _w = ele.outerWidth();\n var halfW = _w / 2;\n var h = ele.outerHeight();\n var halfH = h / 2;\n\n // handle node dimensions\n /////////////////////////\n\n ex1 = x - halfW;\n ex2 = x + halfW;\n ey1 = y - halfH;\n ey2 = y + halfH;\n updateBounds(bounds, ex1, ey1, ex2, ey2);\n if (styleEnabled && options.includeOutlines) {\n updateBoundsFromOutline(bounds, ele);\n }\n } else if (isEdge && options.includeEdges) {\n if (styleEnabled && !headless) {\n var curveStyle = ele.pstyle('curve-style').strValue;\n\n // handle edge dimensions (rough box estimate)\n //////////////////////////////////////////////\n\n ex1 = Math.min(rstyle.srcX, rstyle.midX, rstyle.tgtX);\n ex2 = Math.max(rstyle.srcX, rstyle.midX, rstyle.tgtX);\n ey1 = Math.min(rstyle.srcY, rstyle.midY, rstyle.tgtY);\n ey2 = Math.max(rstyle.srcY, rstyle.midY, rstyle.tgtY);\n\n // take into account edge width\n ex1 -= wHalf;\n ex2 += wHalf;\n ey1 -= wHalf;\n ey2 += wHalf;\n updateBounds(bounds, ex1, ey1, ex2, ey2);\n\n // precise edges\n ////////////////\n\n if (curveStyle === 'haystack') {\n var hpts = rstyle.haystackPts;\n if (hpts && hpts.length === 2) {\n ex1 = hpts[0].x;\n ey1 = hpts[0].y;\n ex2 = hpts[1].x;\n ey2 = hpts[1].y;\n if (ex1 > ex2) {\n var temp = ex1;\n ex1 = ex2;\n ex2 = temp;\n }\n if (ey1 > ey2) {\n var _temp = ey1;\n ey1 = ey2;\n ey2 = _temp;\n }\n updateBounds(bounds, ex1 - wHalf, ey1 - wHalf, ex2 + wHalf, ey2 + wHalf);\n }\n } else if (curveStyle === 'bezier' || curveStyle === 'unbundled-bezier' || curveStyle.endsWith('segments') || curveStyle.endsWith('taxi')) {\n var pts;\n switch (curveStyle) {\n case 'bezier':\n case 'unbundled-bezier':\n pts = rstyle.bezierPts;\n break;\n case 'segments':\n case 'taxi':\n case 'round-segments':\n case 'round-taxi':\n pts = rstyle.linePts;\n break;\n }\n if (pts != null) {\n for (var j = 0; j < pts.length; j++) {\n var pt = pts[j];\n ex1 = pt.x - wHalf;\n ex2 = pt.x + wHalf;\n ey1 = pt.y - wHalf;\n ey2 = pt.y + wHalf;\n updateBounds(bounds, ex1, ey1, ex2, ey2);\n }\n }\n } // bezier-like or segment-like edge\n } else {\n // headless or style disabled\n\n // fallback on source and target positions\n //////////////////////////////////////////\n\n var n1 = ele.source();\n var n1pos = n1.position();\n var n2 = ele.target();\n var n2pos = n2.position();\n ex1 = n1pos.x;\n ex2 = n2pos.x;\n ey1 = n1pos.y;\n ey2 = n2pos.y;\n if (ex1 > ex2) {\n var _temp2 = ex1;\n ex1 = ex2;\n ex2 = _temp2;\n }\n if (ey1 > ey2) {\n var _temp3 = ey1;\n ey1 = ey2;\n ey2 = _temp3;\n }\n\n // take into account edge width\n ex1 -= wHalf;\n ex2 += wHalf;\n ey1 -= wHalf;\n ey2 += wHalf;\n updateBounds(bounds, ex1, ey1, ex2, ey2);\n } // headless or style disabled\n } // edges\n\n // handle edge arrow size\n /////////////////////////\n\n if (styleEnabled && options.includeEdges && isEdge) {\n updateBoundsFromArrow(bounds, ele, 'mid-source');\n updateBoundsFromArrow(bounds, ele, 'mid-target');\n updateBoundsFromArrow(bounds, ele, 'source');\n updateBoundsFromArrow(bounds, ele, 'target');\n }\n\n // ghost\n ////////\n\n if (styleEnabled) {\n var ghost = ele.pstyle('ghost').value === 'yes';\n if (ghost) {\n var gx = ele.pstyle('ghost-offset-x').pfValue;\n var gy = ele.pstyle('ghost-offset-y').pfValue;\n updateBounds(bounds, bounds.x1 + gx, bounds.y1 + gy, bounds.x2 + gx, bounds.y2 + gy);\n }\n }\n\n // always store the body bounds separately from the labels\n var bbBody = _p.bodyBounds = _p.bodyBounds || {};\n assignBoundingBox(bbBody, bounds);\n expandBoundingBoxSides(bbBody, manualExpansion);\n expandBoundingBox(bbBody, 1); // expand to work around browser dimension inaccuracies\n\n // overlay\n //////////\n\n if (styleEnabled) {\n ex1 = bounds.x1;\n ex2 = bounds.x2;\n ey1 = bounds.y1;\n ey2 = bounds.y2;\n updateBounds(bounds, ex1 - padding, ey1 - padding, ex2 + padding, ey2 + padding);\n }\n\n // always store the body bounds separately from the labels\n var bbOverlay = _p.overlayBounds = _p.overlayBounds || {};\n assignBoundingBox(bbOverlay, bounds);\n expandBoundingBoxSides(bbOverlay, manualExpansion);\n expandBoundingBox(bbOverlay, 1); // expand to work around browser dimension inaccuracies\n\n // handle label dimensions\n //////////////////////////\n\n var bbLabels = _p.labelBounds = _p.labelBounds || {};\n if (bbLabels.all != null) {\n clearBoundingBox(bbLabels.all);\n } else {\n bbLabels.all = makeBoundingBox();\n }\n if (styleEnabled && options.includeLabels) {\n if (options.includeMainLabels) {\n updateBoundsFromLabel(bounds, ele, null);\n }\n if (isEdge) {\n if (options.includeSourceLabels) {\n updateBoundsFromLabel(bounds, ele, 'source');\n }\n if (options.includeTargetLabels) {\n updateBoundsFromLabel(bounds, ele, 'target');\n }\n }\n } // style enabled for labels\n } // if displayed\n\n bounds.x1 = noninf(bounds.x1);\n bounds.y1 = noninf(bounds.y1);\n bounds.x2 = noninf(bounds.x2);\n bounds.y2 = noninf(bounds.y2);\n bounds.w = noninf(bounds.x2 - bounds.x1);\n bounds.h = noninf(bounds.y2 - bounds.y1);\n if (bounds.w > 0 && bounds.h > 0 && displayed) {\n expandBoundingBoxSides(bounds, manualExpansion);\n\n // expand bounds by 1 because antialiasing can increase the visual/effective size by 1 on all sides\n expandBoundingBox(bounds, 1);\n }\n return bounds;\n};\nvar getKey = function getKey(opts) {\n var i = 0;\n var tf = function tf(val) {\n return (val ? 1 : 0) << i++;\n };\n var key = 0;\n key += tf(opts.incudeNodes);\n key += tf(opts.includeEdges);\n key += tf(opts.includeLabels);\n key += tf(opts.includeMainLabels);\n key += tf(opts.includeSourceLabels);\n key += tf(opts.includeTargetLabels);\n key += tf(opts.includeOverlays);\n key += tf(opts.includeOutlines);\n return key;\n};\nvar getBoundingBoxPosKey = function getBoundingBoxPosKey(ele) {\n if (ele.isEdge()) {\n var p1 = ele.source().position();\n var p2 = ele.target().position();\n var r = function r(x) {\n return Math.round(x);\n };\n return hashIntsArray([r(p1.x), r(p1.y), r(p2.x), r(p2.y)]);\n } else {\n return 0;\n }\n};\nvar cachedBoundingBoxImpl = function cachedBoundingBoxImpl(ele, opts) {\n var _p = ele._private;\n var bb;\n var isEdge = ele.isEdge();\n var key = opts == null ? defBbOptsKey : getKey(opts);\n var usingDefOpts = key === defBbOptsKey;\n var currPosKey = getBoundingBoxPosKey(ele);\n var isPosKeySame = _p.bbCachePosKey === currPosKey;\n var useCache = opts.useCache && isPosKeySame;\n var isDirty = function isDirty(ele) {\n return ele._private.bbCache == null || ele._private.styleDirty;\n };\n var needRecalc = !useCache || isDirty(ele) || isEdge && isDirty(ele.source()) || isDirty(ele.target());\n if (needRecalc) {\n if (!isPosKeySame) {\n ele.recalculateRenderedStyle(useCache);\n }\n bb = boundingBoxImpl(ele, defBbOpts);\n _p.bbCache = bb;\n _p.bbCachePosKey = currPosKey;\n } else {\n bb = _p.bbCache;\n }\n\n // not using def opts => need to build up bb from combination of sub bbs\n if (!usingDefOpts) {\n var isNode = ele.isNode();\n bb = makeBoundingBox();\n if (opts.includeNodes && isNode || opts.includeEdges && !isNode) {\n if (opts.includeOverlays) {\n updateBoundsFromBox(bb, _p.overlayBounds);\n } else {\n updateBoundsFromBox(bb, _p.bodyBounds);\n }\n }\n if (opts.includeLabels) {\n if (opts.includeMainLabels && (!isEdge || opts.includeSourceLabels && opts.includeTargetLabels)) {\n updateBoundsFromBox(bb, _p.labelBounds.all);\n } else {\n if (opts.includeMainLabels) {\n updateBoundsFromBox(bb, _p.labelBounds.mainRot);\n }\n if (opts.includeSourceLabels) {\n updateBoundsFromBox(bb, _p.labelBounds.sourceRot);\n }\n if (opts.includeTargetLabels) {\n updateBoundsFromBox(bb, _p.labelBounds.targetRot);\n }\n }\n }\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n }\n return bb;\n};\nvar defBbOpts = {\n includeNodes: true,\n includeEdges: true,\n includeLabels: true,\n includeMainLabels: true,\n includeSourceLabels: true,\n includeTargetLabels: true,\n includeOverlays: true,\n includeUnderlays: true,\n includeOutlines: true,\n useCache: true\n};\nvar defBbOptsKey = getKey(defBbOpts);\nvar filledBbOpts = defaults$g(defBbOpts);\nelesfn$b.boundingBox = function (options) {\n var bounds;\n\n // the main usecase is ele.boundingBox() for a single element with no/def options\n // specified s.t. the cache is used, so check for this case to make it faster by\n // avoiding the overhead of the rest of the function\n if (this.length === 1 && this[0]._private.bbCache != null && !this[0]._private.styleDirty && (options === undefined || options.useCache === undefined || options.useCache === true)) {\n if (options === undefined) {\n options = defBbOpts;\n } else {\n options = filledBbOpts(options);\n }\n bounds = cachedBoundingBoxImpl(this[0], options);\n } else {\n bounds = makeBoundingBox();\n options = options || defBbOpts;\n var opts = filledBbOpts(options);\n var eles = this;\n var cy = eles.cy();\n var styleEnabled = cy.styleEnabled();\n if (styleEnabled) {\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var _p = ele._private;\n var currPosKey = getBoundingBoxPosKey(ele);\n var isPosKeySame = _p.bbCachePosKey === currPosKey;\n var useCache = opts.useCache && isPosKeySame && !_p.styleDirty;\n ele.recalculateRenderedStyle(useCache);\n }\n }\n this.updateCompoundBounds(!options.useCache);\n for (var _i = 0; _i < eles.length; _i++) {\n var _ele = eles[_i];\n updateBoundsFromBox(bounds, cachedBoundingBoxImpl(_ele, opts));\n }\n }\n bounds.x1 = noninf(bounds.x1);\n bounds.y1 = noninf(bounds.y1);\n bounds.x2 = noninf(bounds.x2);\n bounds.y2 = noninf(bounds.y2);\n bounds.w = noninf(bounds.x2 - bounds.x1);\n bounds.h = noninf(bounds.y2 - bounds.y1);\n return bounds;\n};\nelesfn$b.dirtyBoundingBoxCache = function () {\n for (var i = 0; i < this.length; i++) {\n var _p = this[i]._private;\n _p.bbCache = null;\n _p.bbCachePosKey = null;\n _p.bodyBounds = null;\n _p.overlayBounds = null;\n _p.labelBounds.all = null;\n _p.labelBounds.source = null;\n _p.labelBounds.target = null;\n _p.labelBounds.main = null;\n _p.labelBounds.sourceRot = null;\n _p.labelBounds.targetRot = null;\n _p.labelBounds.mainRot = null;\n _p.arrowBounds.source = null;\n _p.arrowBounds.target = null;\n _p.arrowBounds['mid-source'] = null;\n _p.arrowBounds['mid-target'] = null;\n }\n this.emitAndNotify('bounds');\n return this;\n};\n\n// private helper to get bounding box for custom node positions\n// - good for perf in certain cases but currently requires dirtying the rendered style\n// - would be better to not modify the nodes but the nodes are read directly everywhere in the renderer...\n// - try to use for only things like discrete layouts where the node position would change anyway\nelesfn$b.boundingBoxAt = function (fn) {\n var nodes = this.nodes();\n var cy = this.cy();\n var hasCompoundNodes = cy.hasCompoundNodes();\n var parents = cy.collection();\n if (hasCompoundNodes) {\n parents = nodes.filter(function (node) {\n return node.isParent();\n });\n nodes = nodes.not(parents);\n }\n if (plainObject(fn)) {\n var obj = fn;\n fn = function fn() {\n return obj;\n };\n }\n var storeOldPos = function storeOldPos(node, i) {\n return node._private.bbAtOldPos = fn(node, i);\n };\n var getOldPos = function getOldPos(node) {\n return node._private.bbAtOldPos;\n };\n cy.startBatch();\n nodes.forEach(storeOldPos).silentPositions(fn);\n if (hasCompoundNodes) {\n parents.dirtyCompoundBoundsCache();\n parents.dirtyBoundingBoxCache();\n parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle\n }\n\n var bb = copyBoundingBox(this.boundingBox({\n useCache: false\n }));\n nodes.silentPositions(getOldPos);\n if (hasCompoundNodes) {\n parents.dirtyCompoundBoundsCache();\n parents.dirtyBoundingBoxCache();\n parents.updateCompoundBounds(true); // force update b/c we're inside a batch cycle\n }\n\n cy.endBatch();\n return bb;\n};\nfn$3.boundingbox = fn$3.bb = fn$3.boundingBox;\nfn$3.renderedBoundingbox = fn$3.renderedBoundingBox;\nvar bounds = elesfn$b;\n\nvar fn$2, elesfn$a;\nfn$2 = elesfn$a = {};\nvar defineDimFns = function defineDimFns(opts) {\n opts.uppercaseName = capitalize(opts.name);\n opts.autoName = 'auto' + opts.uppercaseName;\n opts.labelName = 'label' + opts.uppercaseName;\n opts.outerName = 'outer' + opts.uppercaseName;\n opts.uppercaseOuterName = capitalize(opts.outerName);\n fn$2[opts.name] = function dimImpl() {\n var ele = this[0];\n var _p = ele._private;\n var cy = _p.cy;\n var styleEnabled = cy._private.styleEnabled;\n if (ele) {\n if (styleEnabled) {\n if (ele.isParent()) {\n ele.updateCompoundBounds();\n return _p[opts.autoName] || 0;\n }\n var d = ele.pstyle(opts.name);\n switch (d.strValue) {\n case 'label':\n ele.recalculateRenderedStyle();\n return _p.rstyle[opts.labelName] || 0;\n default:\n return d.pfValue;\n }\n } else {\n return 1;\n }\n }\n };\n fn$2['outer' + opts.uppercaseName] = function outerDimImpl() {\n var ele = this[0];\n var _p = ele._private;\n var cy = _p.cy;\n var styleEnabled = cy._private.styleEnabled;\n if (ele) {\n if (styleEnabled) {\n var dim = ele[opts.name]();\n var border = ele.pstyle('border-width').pfValue; // n.b. 1/2 each side\n var padding = 2 * ele.padding();\n return dim + border + padding;\n } else {\n return 1;\n }\n }\n };\n fn$2['rendered' + opts.uppercaseName] = function renderedDimImpl() {\n var ele = this[0];\n if (ele) {\n var d = ele[opts.name]();\n return d * this.cy().zoom();\n }\n };\n fn$2['rendered' + opts.uppercaseOuterName] = function renderedOuterDimImpl() {\n var ele = this[0];\n if (ele) {\n var od = ele[opts.outerName]();\n return od * this.cy().zoom();\n }\n };\n};\ndefineDimFns({\n name: 'width'\n});\ndefineDimFns({\n name: 'height'\n});\nelesfn$a.padding = function () {\n var ele = this[0];\n var _p = ele._private;\n if (ele.isParent()) {\n ele.updateCompoundBounds();\n if (_p.autoPadding !== undefined) {\n return _p.autoPadding;\n } else {\n return ele.pstyle('padding').pfValue;\n }\n } else {\n return ele.pstyle('padding').pfValue;\n }\n};\nelesfn$a.paddedHeight = function () {\n var ele = this[0];\n return ele.height() + 2 * ele.padding();\n};\nelesfn$a.paddedWidth = function () {\n var ele = this[0];\n return ele.width() + 2 * ele.padding();\n};\nvar widthHeight = elesfn$a;\n\nvar ifEdge = function ifEdge(ele, getValue) {\n if (ele.isEdge()) {\n return getValue(ele);\n }\n};\nvar ifEdgeRenderedPosition = function ifEdgeRenderedPosition(ele, getPoint) {\n if (ele.isEdge()) {\n var cy = ele.cy();\n return modelToRenderedPosition(getPoint(ele), cy.zoom(), cy.pan());\n }\n};\nvar ifEdgeRenderedPositions = function ifEdgeRenderedPositions(ele, getPoints) {\n if (ele.isEdge()) {\n var cy = ele.cy();\n var pan = cy.pan();\n var zoom = cy.zoom();\n return getPoints(ele).map(function (p) {\n return modelToRenderedPosition(p, zoom, pan);\n });\n }\n};\nvar controlPoints = function controlPoints(ele) {\n return ele.renderer().getControlPoints(ele);\n};\nvar segmentPoints = function segmentPoints(ele) {\n return ele.renderer().getSegmentPoints(ele);\n};\nvar sourceEndpoint = function sourceEndpoint(ele) {\n return ele.renderer().getSourceEndpoint(ele);\n};\nvar targetEndpoint = function targetEndpoint(ele) {\n return ele.renderer().getTargetEndpoint(ele);\n};\nvar midpoint = function midpoint(ele) {\n return ele.renderer().getEdgeMidpoint(ele);\n};\nvar pts = {\n controlPoints: {\n get: controlPoints,\n mult: true\n },\n segmentPoints: {\n get: segmentPoints,\n mult: true\n },\n sourceEndpoint: {\n get: sourceEndpoint\n },\n targetEndpoint: {\n get: targetEndpoint\n },\n midpoint: {\n get: midpoint\n }\n};\nvar renderedName = function renderedName(name) {\n return 'rendered' + name[0].toUpperCase() + name.substr(1);\n};\nvar edgePoints = Object.keys(pts).reduce(function (obj, name) {\n var spec = pts[name];\n var rName = renderedName(name);\n obj[name] = function () {\n return ifEdge(this, spec.get);\n };\n if (spec.mult) {\n obj[rName] = function () {\n return ifEdgeRenderedPositions(this, spec.get);\n };\n } else {\n obj[rName] = function () {\n return ifEdgeRenderedPosition(this, spec.get);\n };\n }\n return obj;\n}, {});\n\nvar dimensions = extend({}, position, bounds, widthHeight, edgePoints);\n\n/*!\nEvent object based on jQuery events, MIT license\n\nhttps://jquery.org/license/\nhttps://tldrlegal.com/license/mit-license\nhttps://github.com/jquery/jquery/blob/master/src/event.js\n*/\n\nvar Event = function Event(src, props) {\n this.recycle(src, props);\n};\nfunction returnFalse() {\n return false;\n}\nfunction returnTrue() {\n return true;\n}\n\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\nEvent.prototype = {\n instanceString: function instanceString() {\n return 'event';\n },\n recycle: function recycle(src, props) {\n this.isImmediatePropagationStopped = this.isPropagationStopped = this.isDefaultPrevented = returnFalse;\n if (src != null && src.preventDefault) {\n // Browser Event object\n this.type = src.type;\n\n // Events bubbling up the document may have been marked as prevented\n // by a handler lower down the tree; reflect the correct value.\n this.isDefaultPrevented = src.defaultPrevented ? returnTrue : returnFalse;\n } else if (src != null && src.type) {\n // Plain object containing all event details\n props = src;\n } else {\n // Event string\n this.type = src;\n }\n\n // Put explicitly provided properties onto the event object\n if (props != null) {\n // more efficient to manually copy fields we use\n this.originalEvent = props.originalEvent;\n this.type = props.type != null ? props.type : this.type;\n this.cy = props.cy;\n this.target = props.target;\n this.position = props.position;\n this.renderedPosition = props.renderedPosition;\n this.namespace = props.namespace;\n this.layout = props.layout;\n }\n if (this.cy != null && this.position != null && this.renderedPosition == null) {\n // create a rendered position based on the passed position\n var pos = this.position;\n var zoom = this.cy.zoom();\n var pan = this.cy.pan();\n this.renderedPosition = {\n x: pos.x * zoom + pan.x,\n y: pos.y * zoom + pan.y\n };\n }\n\n // Create a timestamp if incoming event doesn't have one\n this.timeStamp = src && src.timeStamp || Date.now();\n },\n preventDefault: function preventDefault() {\n this.isDefaultPrevented = returnTrue;\n var e = this.originalEvent;\n if (!e) {\n return;\n }\n\n // if preventDefault exists run it on the original event\n if (e.preventDefault) {\n e.preventDefault();\n }\n },\n stopPropagation: function stopPropagation() {\n this.isPropagationStopped = returnTrue;\n var e = this.originalEvent;\n if (!e) {\n return;\n }\n\n // if stopPropagation exists run it on the original event\n if (e.stopPropagation) {\n e.stopPropagation();\n }\n },\n stopImmediatePropagation: function stopImmediatePropagation() {\n this.isImmediatePropagationStopped = returnTrue;\n this.stopPropagation();\n },\n isDefaultPrevented: returnFalse,\n isPropagationStopped: returnFalse,\n isImmediatePropagationStopped: returnFalse\n};\n\nvar eventRegex = /^([^.]+)(\\.(?:[^.]+))?$/; // regex for matching event strings (e.g. \"click.namespace\")\nvar universalNamespace = '.*'; // matches as if no namespace specified and prevents users from unbinding accidentally\n\nvar defaults$8 = {\n qualifierCompare: function qualifierCompare(q1, q2) {\n return q1 === q2;\n },\n eventMatches: function eventMatches( /*context, listener, eventObj*/\n ) {\n return true;\n },\n addEventFields: function addEventFields( /*context, evt*/\n ) {},\n callbackContext: function callbackContext(context /*, listener, eventObj*/) {\n return context;\n },\n beforeEmit: function beforeEmit( /* context, listener, eventObj */\n ) {},\n afterEmit: function afterEmit( /* context, listener, eventObj */\n ) {},\n bubble: function bubble( /*context*/\n ) {\n return false;\n },\n parent: function parent( /*context*/\n ) {\n return null;\n },\n context: null\n};\nvar defaultsKeys = Object.keys(defaults$8);\nvar emptyOpts = {};\nfunction Emitter() {\n var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : emptyOpts;\n var context = arguments.length > 1 ? arguments[1] : undefined;\n // micro-optimisation vs Object.assign() -- reduces Element instantiation time\n for (var i = 0; i < defaultsKeys.length; i++) {\n var key = defaultsKeys[i];\n this[key] = opts[key] || defaults$8[key];\n }\n this.context = context || this.context;\n this.listeners = [];\n this.emitting = 0;\n}\nvar p = Emitter.prototype;\nvar forEachEvent = function forEachEvent(self, handler, events, qualifier, callback, conf, confOverrides) {\n if (fn$6(qualifier)) {\n callback = qualifier;\n qualifier = null;\n }\n if (confOverrides) {\n if (conf == null) {\n conf = confOverrides;\n } else {\n conf = extend({}, conf, confOverrides);\n }\n }\n var eventList = array(events) ? events : events.split(/\\s+/);\n for (var i = 0; i < eventList.length; i++) {\n var evt = eventList[i];\n if (emptyString(evt)) {\n continue;\n }\n var match = evt.match(eventRegex); // type[.namespace]\n\n if (match) {\n var type = match[1];\n var namespace = match[2] ? match[2] : null;\n var ret = handler(self, evt, type, namespace, qualifier, callback, conf);\n if (ret === false) {\n break;\n } // allow exiting early\n }\n }\n};\n\nvar makeEventObj = function makeEventObj(self, obj) {\n self.addEventFields(self.context, obj);\n return new Event(obj.type, obj);\n};\nvar forEachEventObj = function forEachEventObj(self, handler, events) {\n if (event(events)) {\n handler(self, events);\n return;\n } else if (plainObject(events)) {\n handler(self, makeEventObj(self, events));\n return;\n }\n var eventList = array(events) ? events : events.split(/\\s+/);\n for (var i = 0; i < eventList.length; i++) {\n var evt = eventList[i];\n if (emptyString(evt)) {\n continue;\n }\n var match = evt.match(eventRegex); // type[.namespace]\n\n if (match) {\n var type = match[1];\n var namespace = match[2] ? match[2] : null;\n var eventObj = makeEventObj(self, {\n type: type,\n namespace: namespace,\n target: self.context\n });\n handler(self, eventObj);\n }\n }\n};\np.on = p.addListener = function (events, qualifier, callback, conf, confOverrides) {\n forEachEvent(this, function (self, event, type, namespace, qualifier, callback, conf) {\n if (fn$6(callback)) {\n self.listeners.push({\n event: event,\n // full event string\n callback: callback,\n // callback to run\n type: type,\n // the event type (e.g. 'click')\n namespace: namespace,\n // the event namespace (e.g. \".foo\")\n qualifier: qualifier,\n // a restriction on whether to match this emitter\n conf: conf // additional configuration\n });\n }\n }, events, qualifier, callback, conf, confOverrides);\n return this;\n};\np.one = function (events, qualifier, callback, conf) {\n return this.on(events, qualifier, callback, conf, {\n one: true\n });\n};\np.removeListener = p.off = function (events, qualifier, callback, conf) {\n var _this = this;\n if (this.emitting !== 0) {\n this.listeners = copyArray$1(this.listeners);\n }\n var listeners = this.listeners;\n var _loop = function _loop(i) {\n var listener = listeners[i];\n forEachEvent(_this, function (self, event, type, namespace, qualifier, callback /*, conf*/) {\n if ((listener.type === type || events === '*') && (!namespace && listener.namespace !== '.*' || listener.namespace === namespace) && (!qualifier || self.qualifierCompare(listener.qualifier, qualifier)) && (!callback || listener.callback === callback)) {\n listeners.splice(i, 1);\n return false;\n }\n }, events, qualifier, callback, conf);\n };\n for (var i = listeners.length - 1; i >= 0; i--) {\n _loop(i);\n }\n return this;\n};\np.removeAllListeners = function () {\n return this.removeListener('*');\n};\np.emit = p.trigger = function (events, extraParams, manualCallback) {\n var listeners = this.listeners;\n var numListenersBeforeEmit = listeners.length;\n this.emitting++;\n if (!array(extraParams)) {\n extraParams = [extraParams];\n }\n forEachEventObj(this, function (self, eventObj) {\n if (manualCallback != null) {\n listeners = [{\n event: eventObj.event,\n type: eventObj.type,\n namespace: eventObj.namespace,\n callback: manualCallback\n }];\n numListenersBeforeEmit = listeners.length;\n }\n var _loop2 = function _loop2(i) {\n var listener = listeners[i];\n if (listener.type === eventObj.type && (!listener.namespace || listener.namespace === eventObj.namespace || listener.namespace === universalNamespace) && self.eventMatches(self.context, listener, eventObj)) {\n var args = [eventObj];\n if (extraParams != null) {\n push(args, extraParams);\n }\n self.beforeEmit(self.context, listener, eventObj);\n if (listener.conf && listener.conf.one) {\n self.listeners = self.listeners.filter(function (l) {\n return l !== listener;\n });\n }\n var context = self.callbackContext(self.context, listener, eventObj);\n var ret = listener.callback.apply(context, args);\n self.afterEmit(self.context, listener, eventObj);\n if (ret === false) {\n eventObj.stopPropagation();\n eventObj.preventDefault();\n }\n } // if listener matches\n };\n for (var i = 0; i < numListenersBeforeEmit; i++) {\n _loop2(i);\n } // for listener\n\n if (self.bubble(self.context) && !eventObj.isPropagationStopped()) {\n self.parent(self.context).emit(eventObj, extraParams);\n }\n }, events);\n this.emitting--;\n return this;\n};\n\nvar emitterOptions$1 = {\n qualifierCompare: function qualifierCompare(selector1, selector2) {\n if (selector1 == null || selector2 == null) {\n return selector1 == null && selector2 == null;\n } else {\n return selector1.sameText(selector2);\n }\n },\n eventMatches: function eventMatches(ele, listener, eventObj) {\n var selector = listener.qualifier;\n if (selector != null) {\n return ele !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target);\n }\n return true;\n },\n addEventFields: function addEventFields(ele, evt) {\n evt.cy = ele.cy();\n evt.target = ele;\n },\n callbackContext: function callbackContext(ele, listener, eventObj) {\n return listener.qualifier != null ? eventObj.target : ele;\n },\n beforeEmit: function beforeEmit(context, listener /*, eventObj*/) {\n if (listener.conf && listener.conf.once) {\n listener.conf.onceCollection.removeListener(listener.event, listener.qualifier, listener.callback);\n }\n },\n bubble: function bubble() {\n return true;\n },\n parent: function parent(ele) {\n return ele.isChild() ? ele.parent() : ele.cy();\n }\n};\nvar argSelector$1 = function argSelector(arg) {\n if (string(arg)) {\n return new Selector(arg);\n } else {\n return arg;\n }\n};\nvar elesfn$9 = {\n createEmitter: function createEmitter() {\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var _p = ele._private;\n if (!_p.emitter) {\n _p.emitter = new Emitter(emitterOptions$1, ele);\n }\n }\n return this;\n },\n emitter: function emitter() {\n return this._private.emitter;\n },\n on: function on(events, selector, callback) {\n var argSel = argSelector$1(selector);\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n ele.emitter().on(events, argSel, callback);\n }\n return this;\n },\n removeListener: function removeListener(events, selector, callback) {\n var argSel = argSelector$1(selector);\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n ele.emitter().removeListener(events, argSel, callback);\n }\n return this;\n },\n removeAllListeners: function removeAllListeners() {\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n ele.emitter().removeAllListeners();\n }\n return this;\n },\n one: function one(events, selector, callback) {\n var argSel = argSelector$1(selector);\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n ele.emitter().one(events, argSel, callback);\n }\n return this;\n },\n once: function once(events, selector, callback) {\n var argSel = argSelector$1(selector);\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n ele.emitter().on(events, argSel, callback, {\n once: true,\n onceCollection: this\n });\n }\n },\n emit: function emit(events, extraParams) {\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n ele.emitter().emit(events, extraParams);\n }\n return this;\n },\n emitAndNotify: function emitAndNotify(event, extraParams) {\n // for internal use only\n if (this.length === 0) {\n return;\n } // empty collections don't need to notify anything\n\n // notify renderer\n this.cy().notify(event, this);\n this.emit(event, extraParams);\n return this;\n }\n};\ndefine.eventAliasesOn(elesfn$9);\n\nvar elesfn$8 = {\n nodes: function nodes(selector) {\n return this.filter(function (ele) {\n return ele.isNode();\n }).filter(selector);\n },\n edges: function edges(selector) {\n return this.filter(function (ele) {\n return ele.isEdge();\n }).filter(selector);\n },\n // internal helper to get nodes and edges as separate collections with single iteration over elements\n byGroup: function byGroup() {\n var nodes = this.spawn();\n var edges = this.spawn();\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n if (ele.isNode()) {\n nodes.push(ele);\n } else {\n edges.push(ele);\n }\n }\n return {\n nodes: nodes,\n edges: edges\n };\n },\n filter: function filter(_filter, thisArg) {\n if (_filter === undefined) {\n // check this first b/c it's the most common/performant case\n return this;\n } else if (string(_filter) || elementOrCollection(_filter)) {\n return new Selector(_filter).filter(this);\n } else if (fn$6(_filter)) {\n var filterEles = this.spawn();\n var eles = this;\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var include = thisArg ? _filter.apply(thisArg, [ele, i, eles]) : _filter(ele, i, eles);\n if (include) {\n filterEles.push(ele);\n }\n }\n return filterEles;\n }\n return this.spawn(); // if not handled by above, give 'em an empty collection\n },\n\n not: function not(toRemove) {\n if (!toRemove) {\n return this;\n } else {\n if (string(toRemove)) {\n toRemove = this.filter(toRemove);\n }\n var elements = this.spawn();\n for (var i = 0; i < this.length; i++) {\n var element = this[i];\n var remove = toRemove.has(element);\n if (!remove) {\n elements.push(element);\n }\n }\n return elements;\n }\n },\n absoluteComplement: function absoluteComplement() {\n var cy = this.cy();\n return cy.mutableElements().not(this);\n },\n intersect: function intersect(other) {\n // if a selector is specified, then filter by it instead\n if (string(other)) {\n var selector = other;\n return this.filter(selector);\n }\n var elements = this.spawn();\n var col1 = this;\n var col2 = other;\n var col1Smaller = this.length < other.length;\n var colS = col1Smaller ? col1 : col2;\n var colL = col1Smaller ? col2 : col1;\n for (var i = 0; i < colS.length; i++) {\n var ele = colS[i];\n if (colL.has(ele)) {\n elements.push(ele);\n }\n }\n return elements;\n },\n xor: function xor(other) {\n var cy = this._private.cy;\n if (string(other)) {\n other = cy.$(other);\n }\n var elements = this.spawn();\n var col1 = this;\n var col2 = other;\n var add = function add(col, other) {\n for (var i = 0; i < col.length; i++) {\n var ele = col[i];\n var id = ele._private.data.id;\n var inOther = other.hasElementWithId(id);\n if (!inOther) {\n elements.push(ele);\n }\n }\n };\n add(col1, col2);\n add(col2, col1);\n return elements;\n },\n diff: function diff(other) {\n var cy = this._private.cy;\n if (string(other)) {\n other = cy.$(other);\n }\n var left = this.spawn();\n var right = this.spawn();\n var both = this.spawn();\n var col1 = this;\n var col2 = other;\n var add = function add(col, other, retEles) {\n for (var i = 0; i < col.length; i++) {\n var ele = col[i];\n var id = ele._private.data.id;\n var inOther = other.hasElementWithId(id);\n if (inOther) {\n both.merge(ele);\n } else {\n retEles.push(ele);\n }\n }\n };\n add(col1, col2, left);\n add(col2, col1, right);\n return {\n left: left,\n right: right,\n both: both\n };\n },\n add: function add(toAdd) {\n var cy = this._private.cy;\n if (!toAdd) {\n return this;\n }\n if (string(toAdd)) {\n var selector = toAdd;\n toAdd = cy.mutableElements().filter(selector);\n }\n var elements = this.spawnSelf();\n for (var i = 0; i < toAdd.length; i++) {\n var ele = toAdd[i];\n var add = !this.has(ele);\n if (add) {\n elements.push(ele);\n }\n }\n return elements;\n },\n // in place merge on calling collection\n merge: function merge(toAdd) {\n var _p = this._private;\n var cy = _p.cy;\n if (!toAdd) {\n return this;\n }\n if (toAdd && string(toAdd)) {\n var selector = toAdd;\n toAdd = cy.mutableElements().filter(selector);\n }\n var map = _p.map;\n for (var i = 0; i < toAdd.length; i++) {\n var toAddEle = toAdd[i];\n var id = toAddEle._private.data.id;\n var add = !map.has(id);\n if (add) {\n var index = this.length++;\n this[index] = toAddEle;\n map.set(id, {\n ele: toAddEle,\n index: index\n });\n }\n }\n return this; // chaining\n },\n\n unmergeAt: function unmergeAt(i) {\n var ele = this[i];\n var id = ele.id();\n var _p = this._private;\n var map = _p.map;\n\n // remove ele\n this[i] = undefined;\n map[\"delete\"](id);\n var unmergedLastEle = i === this.length - 1;\n\n // replace empty spot with last ele in collection\n if (this.length > 1 && !unmergedLastEle) {\n var lastEleI = this.length - 1;\n var lastEle = this[lastEleI];\n var lastEleId = lastEle._private.data.id;\n this[lastEleI] = undefined;\n this[i] = lastEle;\n map.set(lastEleId, {\n ele: lastEle,\n index: i\n });\n }\n\n // the collection is now 1 ele smaller\n this.length--;\n return this;\n },\n // remove single ele in place in calling collection\n unmergeOne: function unmergeOne(ele) {\n ele = ele[0];\n var _p = this._private;\n var id = ele._private.data.id;\n var map = _p.map;\n var entry = map.get(id);\n if (!entry) {\n return this; // no need to remove\n }\n\n var i = entry.index;\n this.unmergeAt(i);\n return this;\n },\n // remove eles in place on calling collection\n unmerge: function unmerge(toRemove) {\n var cy = this._private.cy;\n if (!toRemove) {\n return this;\n }\n if (toRemove && string(toRemove)) {\n var selector = toRemove;\n toRemove = cy.mutableElements().filter(selector);\n }\n for (var i = 0; i < toRemove.length; i++) {\n this.unmergeOne(toRemove[i]);\n }\n return this; // chaining\n },\n\n unmergeBy: function unmergeBy(toRmFn) {\n for (var i = this.length - 1; i >= 0; i--) {\n var ele = this[i];\n if (toRmFn(ele)) {\n this.unmergeAt(i);\n }\n }\n return this;\n },\n map: function map(mapFn, thisArg) {\n var arr = [];\n var eles = this;\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var ret = thisArg ? mapFn.apply(thisArg, [ele, i, eles]) : mapFn(ele, i, eles);\n arr.push(ret);\n }\n return arr;\n },\n reduce: function reduce(fn, initialValue) {\n var val = initialValue;\n var eles = this;\n for (var i = 0; i < eles.length; i++) {\n val = fn(val, eles[i], i, eles);\n }\n return val;\n },\n max: function max(valFn, thisArg) {\n var max = -Infinity;\n var maxEle;\n var eles = this;\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles);\n if (val > max) {\n max = val;\n maxEle = ele;\n }\n }\n return {\n value: max,\n ele: maxEle\n };\n },\n min: function min(valFn, thisArg) {\n var min = Infinity;\n var minEle;\n var eles = this;\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var val = thisArg ? valFn.apply(thisArg, [ele, i, eles]) : valFn(ele, i, eles);\n if (val < min) {\n min = val;\n minEle = ele;\n }\n }\n return {\n value: min,\n ele: minEle\n };\n }\n};\n\n// aliases\nvar fn$1 = elesfn$8;\nfn$1['u'] = fn$1['|'] = fn$1['+'] = fn$1.union = fn$1.or = fn$1.add;\nfn$1['\\\\'] = fn$1['!'] = fn$1['-'] = fn$1.difference = fn$1.relativeComplement = fn$1.subtract = fn$1.not;\nfn$1['n'] = fn$1['&'] = fn$1['.'] = fn$1.and = fn$1.intersection = fn$1.intersect;\nfn$1['^'] = fn$1['(+)'] = fn$1['(-)'] = fn$1.symmetricDifference = fn$1.symdiff = fn$1.xor;\nfn$1.fnFilter = fn$1.filterFn = fn$1.stdFilter = fn$1.filter;\nfn$1.complement = fn$1.abscomp = fn$1.absoluteComplement;\n\nvar elesfn$7 = {\n isNode: function isNode() {\n return this.group() === 'nodes';\n },\n isEdge: function isEdge() {\n return this.group() === 'edges';\n },\n isLoop: function isLoop() {\n return this.isEdge() && this.source()[0] === this.target()[0];\n },\n isSimple: function isSimple() {\n return this.isEdge() && this.source()[0] !== this.target()[0];\n },\n group: function group() {\n var ele = this[0];\n if (ele) {\n return ele._private.group;\n }\n }\n};\n\n/**\n * Elements are drawn in a specific order based on compound depth (low to high), the element type (nodes above edges),\n * and z-index (low to high). These styles affect how this applies:\n *\n * z-compound-depth: May be `bottom | orphan | auto | top`. The first drawn is `bottom`, then `orphan` which is the\n * same depth as the root of the compound graph, followed by the default value `auto` which draws in order from\n * root to leaves of the compound graph. The last drawn is `top`.\n * z-index-compare: May be `auto | manual`. The default value is `auto` which always draws edges under nodes.\n * `manual` ignores this convention and draws based on the `z-index` value setting.\n * z-index: An integer value that affects the relative draw order of elements. In general, an element with a higher\n * `z-index` will be drawn on top of an element with a lower `z-index`.\n */\nvar zIndexSort = function zIndexSort(a, b) {\n var cy = a.cy();\n var hasCompoundNodes = cy.hasCompoundNodes();\n function getDepth(ele) {\n var style = ele.pstyle('z-compound-depth');\n if (style.value === 'auto') {\n return hasCompoundNodes ? ele.zDepth() : 0;\n } else if (style.value === 'bottom') {\n return -1;\n } else if (style.value === 'top') {\n return MAX_INT$1;\n }\n // 'orphan'\n return 0;\n }\n var depthDiff = getDepth(a) - getDepth(b);\n if (depthDiff !== 0) {\n return depthDiff;\n }\n function getEleDepth(ele) {\n var style = ele.pstyle('z-index-compare');\n if (style.value === 'auto') {\n return ele.isNode() ? 1 : 0;\n }\n // 'manual'\n return 0;\n }\n var eleDiff = getEleDepth(a) - getEleDepth(b);\n if (eleDiff !== 0) {\n return eleDiff;\n }\n var zDiff = a.pstyle('z-index').value - b.pstyle('z-index').value;\n if (zDiff !== 0) {\n return zDiff;\n }\n // compare indices in the core (order added to graph w/ last on top)\n return a.poolIndex() - b.poolIndex();\n};\n\nvar elesfn$6 = {\n forEach: function forEach(fn, thisArg) {\n if (fn$6(fn)) {\n var N = this.length;\n for (var i = 0; i < N; i++) {\n var ele = this[i];\n var ret = thisArg ? fn.apply(thisArg, [ele, i, this]) : fn(ele, i, this);\n if (ret === false) {\n break;\n } // exit each early on return false\n }\n }\n\n return this;\n },\n toArray: function toArray() {\n var array = [];\n for (var i = 0; i < this.length; i++) {\n array.push(this[i]);\n }\n return array;\n },\n slice: function slice(start, end) {\n var array = [];\n var thisSize = this.length;\n if (end == null) {\n end = thisSize;\n }\n if (start == null) {\n start = 0;\n }\n if (start < 0) {\n start = thisSize + start;\n }\n if (end < 0) {\n end = thisSize + end;\n }\n for (var i = start; i >= 0 && i < end && i < thisSize; i++) {\n array.push(this[i]);\n }\n return this.spawn(array);\n },\n size: function size() {\n return this.length;\n },\n eq: function eq(i) {\n return this[i] || this.spawn();\n },\n first: function first() {\n return this[0] || this.spawn();\n },\n last: function last() {\n return this[this.length - 1] || this.spawn();\n },\n empty: function empty() {\n return this.length === 0;\n },\n nonempty: function nonempty() {\n return !this.empty();\n },\n sort: function sort(sortFn) {\n if (!fn$6(sortFn)) {\n return this;\n }\n var sorted = this.toArray().sort(sortFn);\n return this.spawn(sorted);\n },\n sortByZIndex: function sortByZIndex() {\n return this.sort(zIndexSort);\n },\n zDepth: function zDepth() {\n var ele = this[0];\n if (!ele) {\n return undefined;\n }\n\n // let cy = ele.cy();\n var _p = ele._private;\n var group = _p.group;\n if (group === 'nodes') {\n var depth = _p.data.parent ? ele.parents().size() : 0;\n if (!ele.isParent()) {\n return MAX_INT$1 - 1; // childless nodes always on top\n }\n\n return depth;\n } else {\n var src = _p.source;\n var tgt = _p.target;\n var srcDepth = src.zDepth();\n var tgtDepth = tgt.zDepth();\n return Math.max(srcDepth, tgtDepth, 0); // depth of deepest parent\n }\n }\n};\n\nelesfn$6.each = elesfn$6.forEach;\nvar defineSymbolIterator = function defineSymbolIterator() {\n var typeofUndef = \"undefined\" ;\n var isIteratorSupported = (typeof Symbol === \"undefined\" ? \"undefined\" : _typeof(Symbol)) != typeofUndef && _typeof(Symbol.iterator) != typeofUndef; // eslint-disable-line no-undef\n\n if (isIteratorSupported) {\n elesfn$6[Symbol.iterator] = function () {\n var _this = this;\n // eslint-disable-line no-undef\n var entry = {\n value: undefined,\n done: false\n };\n var i = 0;\n var length = this.length;\n return _defineProperty$1({\n next: function next() {\n if (i < length) {\n entry.value = _this[i++];\n } else {\n entry.value = undefined;\n entry.done = true;\n }\n return entry;\n }\n }, Symbol.iterator, function () {\n // eslint-disable-line no-undef\n return this;\n });\n };\n }\n};\ndefineSymbolIterator();\n\nvar getLayoutDimensionOptions = defaults$g({\n nodeDimensionsIncludeLabels: false\n});\nvar elesfn$5 = {\n // Calculates and returns node dimensions { x, y } based on options given\n layoutDimensions: function layoutDimensions(options) {\n options = getLayoutDimensionOptions(options);\n var dims;\n if (!this.takesUpSpace()) {\n dims = {\n w: 0,\n h: 0\n };\n } else if (options.nodeDimensionsIncludeLabels) {\n var bbDim = this.boundingBox();\n dims = {\n w: bbDim.w,\n h: bbDim.h\n };\n } else {\n dims = {\n w: this.outerWidth(),\n h: this.outerHeight()\n };\n }\n\n // sanitise the dimensions for external layouts (avoid division by zero)\n if (dims.w === 0 || dims.h === 0) {\n dims.w = dims.h = 1;\n }\n return dims;\n },\n // using standard layout options, apply position function (w/ or w/o animation)\n layoutPositions: function layoutPositions(layout, options, fn) {\n var nodes = this.nodes().filter(function (n) {\n return !n.isParent();\n });\n var cy = this.cy();\n var layoutEles = options.eles; // nodes & edges\n var getMemoizeKey = function getMemoizeKey(node) {\n return node.id();\n };\n var fnMem = memoize$1(fn, getMemoizeKey); // memoized version of position function\n\n layout.emit({\n type: 'layoutstart',\n layout: layout\n });\n layout.animations = [];\n var calculateSpacing = function calculateSpacing(spacing, nodesBb, pos) {\n var center = {\n x: nodesBb.x1 + nodesBb.w / 2,\n y: nodesBb.y1 + nodesBb.h / 2\n };\n var spacingVector = {\n // scale from center of bounding box (not necessarily 0,0)\n x: (pos.x - center.x) * spacing,\n y: (pos.y - center.y) * spacing\n };\n return {\n x: center.x + spacingVector.x,\n y: center.y + spacingVector.y\n };\n };\n var useSpacingFactor = options.spacingFactor && options.spacingFactor !== 1;\n var spacingBb = function spacingBb() {\n if (!useSpacingFactor) {\n return null;\n }\n var bb = makeBoundingBox();\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n var pos = fnMem(node, i);\n expandBoundingBoxByPoint(bb, pos.x, pos.y);\n }\n return bb;\n };\n var bb = spacingBb();\n var getFinalPos = memoize$1(function (node, i) {\n var newPos = fnMem(node, i);\n if (useSpacingFactor) {\n var spacing = Math.abs(options.spacingFactor);\n newPos = calculateSpacing(spacing, bb, newPos);\n }\n if (options.transform != null) {\n newPos = options.transform(node, newPos);\n }\n return newPos;\n }, getMemoizeKey);\n if (options.animate) {\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n var newPos = getFinalPos(node, i);\n var animateNode = options.animateFilter == null || options.animateFilter(node, i);\n if (animateNode) {\n var ani = node.animation({\n position: newPos,\n duration: options.animationDuration,\n easing: options.animationEasing\n });\n layout.animations.push(ani);\n } else {\n node.position(newPos);\n }\n }\n if (options.fit) {\n var fitAni = cy.animation({\n fit: {\n boundingBox: layoutEles.boundingBoxAt(getFinalPos),\n padding: options.padding\n },\n duration: options.animationDuration,\n easing: options.animationEasing\n });\n layout.animations.push(fitAni);\n } else if (options.zoom !== undefined && options.pan !== undefined) {\n var zoomPanAni = cy.animation({\n zoom: options.zoom,\n pan: options.pan,\n duration: options.animationDuration,\n easing: options.animationEasing\n });\n layout.animations.push(zoomPanAni);\n }\n layout.animations.forEach(function (ani) {\n return ani.play();\n });\n layout.one('layoutready', options.ready);\n layout.emit({\n type: 'layoutready',\n layout: layout\n });\n Promise$1.all(layout.animations.map(function (ani) {\n return ani.promise();\n })).then(function () {\n layout.one('layoutstop', options.stop);\n layout.emit({\n type: 'layoutstop',\n layout: layout\n });\n });\n } else {\n nodes.positions(getFinalPos);\n if (options.fit) {\n cy.fit(options.eles, options.padding);\n }\n if (options.zoom != null) {\n cy.zoom(options.zoom);\n }\n if (options.pan) {\n cy.pan(options.pan);\n }\n layout.one('layoutready', options.ready);\n layout.emit({\n type: 'layoutready',\n layout: layout\n });\n layout.one('layoutstop', options.stop);\n layout.emit({\n type: 'layoutstop',\n layout: layout\n });\n }\n return this; // chaining\n },\n\n layout: function layout(options) {\n var cy = this.cy();\n return cy.makeLayout(extend({}, options, {\n eles: this\n }));\n }\n};\n\n// aliases:\nelesfn$5.createLayout = elesfn$5.makeLayout = elesfn$5.layout;\n\nfunction styleCache(key, fn, ele) {\n var _p = ele._private;\n var cache = _p.styleCache = _p.styleCache || [];\n var val;\n if ((val = cache[key]) != null) {\n return val;\n } else {\n val = cache[key] = fn(ele);\n return val;\n }\n}\nfunction cacheStyleFunction(key, fn) {\n key = hashString(key);\n return function cachedStyleFunction(ele) {\n return styleCache(key, fn, ele);\n };\n}\nfunction cachePrototypeStyleFunction(key, fn) {\n key = hashString(key);\n var selfFn = function selfFn(ele) {\n return fn.call(ele);\n };\n return function cachedPrototypeStyleFunction() {\n var ele = this[0];\n if (ele) {\n return styleCache(key, selfFn, ele);\n }\n };\n}\nvar elesfn$4 = {\n recalculateRenderedStyle: function recalculateRenderedStyle(useCache) {\n var cy = this.cy();\n var renderer = cy.renderer();\n var styleEnabled = cy.styleEnabled();\n if (renderer && styleEnabled) {\n renderer.recalculateRenderedStyle(this, useCache);\n }\n return this;\n },\n dirtyStyleCache: function dirtyStyleCache() {\n var cy = this.cy();\n var dirty = function dirty(ele) {\n return ele._private.styleCache = null;\n };\n if (cy.hasCompoundNodes()) {\n var eles;\n eles = this.spawnSelf().merge(this.descendants()).merge(this.parents());\n eles.merge(eles.connectedEdges());\n eles.forEach(dirty);\n } else {\n this.forEach(function (ele) {\n dirty(ele);\n ele.connectedEdges().forEach(dirty);\n });\n }\n return this;\n },\n // fully updates (recalculates) the style for the elements\n updateStyle: function updateStyle(notifyRenderer) {\n var cy = this._private.cy;\n if (!cy.styleEnabled()) {\n return this;\n }\n if (cy.batching()) {\n var bEles = cy._private.batchStyleEles;\n bEles.merge(this);\n return this; // chaining and exit early when batching\n }\n\n var hasCompounds = cy.hasCompoundNodes();\n var updatedEles = this;\n notifyRenderer = notifyRenderer || notifyRenderer === undefined ? true : false;\n if (hasCompounds) {\n // then add everything up and down for compound selector checks\n updatedEles = this.spawnSelf().merge(this.descendants()).merge(this.parents());\n }\n\n // let changedEles = style.apply( updatedEles );\n var changedEles = updatedEles;\n if (notifyRenderer) {\n changedEles.emitAndNotify('style'); // let renderer know we changed style\n } else {\n changedEles.emit('style'); // just fire the event\n }\n\n updatedEles.forEach(function (ele) {\n return ele._private.styleDirty = true;\n });\n return this; // chaining\n },\n\n // private: clears dirty flag and recalculates style\n cleanStyle: function cleanStyle() {\n var cy = this.cy();\n if (!cy.styleEnabled()) {\n return;\n }\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n if (ele._private.styleDirty) {\n // n.b. this flag should be set before apply() to avoid potential infinite recursion\n ele._private.styleDirty = false;\n cy.style().apply(ele);\n }\n }\n },\n // get the internal parsed style object for the specified property\n parsedStyle: function parsedStyle(property) {\n var includeNonDefault = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var ele = this[0];\n var cy = ele.cy();\n if (!cy.styleEnabled()) {\n return;\n }\n if (ele) {\n this.cleanStyle();\n var overriddenStyle = ele._private.style[property];\n if (overriddenStyle != null) {\n return overriddenStyle;\n } else if (includeNonDefault) {\n return cy.style().getDefaultProperty(property);\n } else {\n return null;\n }\n }\n },\n numericStyle: function numericStyle(property) {\n var ele = this[0];\n if (!ele.cy().styleEnabled()) {\n return;\n }\n if (ele) {\n var pstyle = ele.pstyle(property);\n return pstyle.pfValue !== undefined ? pstyle.pfValue : pstyle.value;\n }\n },\n numericStyleUnits: function numericStyleUnits(property) {\n var ele = this[0];\n if (!ele.cy().styleEnabled()) {\n return;\n }\n if (ele) {\n return ele.pstyle(property).units;\n }\n },\n // get the specified css property as a rendered value (i.e. on-screen value)\n // or get the whole rendered style if no property specified (NB doesn't allow setting)\n renderedStyle: function renderedStyle(property) {\n var cy = this.cy();\n if (!cy.styleEnabled()) {\n return this;\n }\n var ele = this[0];\n if (ele) {\n return cy.style().getRenderedStyle(ele, property);\n }\n },\n // read the calculated css style of the element or override the style (via a bypass)\n style: function style(name, value) {\n var cy = this.cy();\n if (!cy.styleEnabled()) {\n return this;\n }\n var updateTransitions = false;\n var style = cy.style();\n if (plainObject(name)) {\n // then extend the bypass\n var props = name;\n style.applyBypass(this, props, updateTransitions);\n this.emitAndNotify('style'); // let the renderer know we've updated style\n } else if (string(name)) {\n if (value === undefined) {\n // then get the property from the style\n var ele = this[0];\n if (ele) {\n return style.getStylePropertyValue(ele, name);\n } else {\n // empty collection => can't get any value\n return;\n }\n } else {\n // then set the bypass with the property value\n style.applyBypass(this, name, value, updateTransitions);\n this.emitAndNotify('style'); // let the renderer know we've updated style\n }\n } else if (name === undefined) {\n var _ele = this[0];\n if (_ele) {\n return style.getRawStyle(_ele);\n } else {\n // empty collection => can't get any value\n return;\n }\n }\n return this; // chaining\n },\n\n removeStyle: function removeStyle(names) {\n var cy = this.cy();\n if (!cy.styleEnabled()) {\n return this;\n }\n var updateTransitions = false;\n var style = cy.style();\n var eles = this;\n if (names === undefined) {\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n style.removeAllBypasses(ele, updateTransitions);\n }\n } else {\n names = names.split(/\\s+/);\n for (var _i = 0; _i < eles.length; _i++) {\n var _ele2 = eles[_i];\n style.removeBypasses(_ele2, names, updateTransitions);\n }\n }\n this.emitAndNotify('style'); // let the renderer know we've updated style\n\n return this; // chaining\n },\n\n show: function show() {\n this.css('display', 'element');\n return this; // chaining\n },\n\n hide: function hide() {\n this.css('display', 'none');\n return this; // chaining\n },\n\n effectiveOpacity: function effectiveOpacity() {\n var cy = this.cy();\n if (!cy.styleEnabled()) {\n return 1;\n }\n var hasCompoundNodes = cy.hasCompoundNodes();\n var ele = this[0];\n if (ele) {\n var _p = ele._private;\n var parentOpacity = ele.pstyle('opacity').value;\n if (!hasCompoundNodes) {\n return parentOpacity;\n }\n var parents = !_p.data.parent ? null : ele.parents();\n if (parents) {\n for (var i = 0; i < parents.length; i++) {\n var parent = parents[i];\n var opacity = parent.pstyle('opacity').value;\n parentOpacity = opacity * parentOpacity;\n }\n }\n return parentOpacity;\n }\n },\n transparent: function transparent() {\n var cy = this.cy();\n if (!cy.styleEnabled()) {\n return false;\n }\n var ele = this[0];\n var hasCompoundNodes = ele.cy().hasCompoundNodes();\n if (ele) {\n if (!hasCompoundNodes) {\n return ele.pstyle('opacity').value === 0;\n } else {\n return ele.effectiveOpacity() === 0;\n }\n }\n },\n backgrounding: function backgrounding() {\n var cy = this.cy();\n if (!cy.styleEnabled()) {\n return false;\n }\n var ele = this[0];\n return ele._private.backgrounding ? true : false;\n }\n};\nfunction checkCompound(ele, parentOk) {\n var _p = ele._private;\n var parents = _p.data.parent ? ele.parents() : null;\n if (parents) {\n for (var i = 0; i < parents.length; i++) {\n var parent = parents[i];\n if (!parentOk(parent)) {\n return false;\n }\n }\n }\n return true;\n}\nfunction defineDerivedStateFunction(specs) {\n var ok = specs.ok;\n var edgeOkViaNode = specs.edgeOkViaNode || specs.ok;\n var parentOk = specs.parentOk || specs.ok;\n return function () {\n var cy = this.cy();\n if (!cy.styleEnabled()) {\n return true;\n }\n var ele = this[0];\n var hasCompoundNodes = cy.hasCompoundNodes();\n if (ele) {\n var _p = ele._private;\n if (!ok(ele)) {\n return false;\n }\n if (ele.isNode()) {\n return !hasCompoundNodes || checkCompound(ele, parentOk);\n } else {\n var src = _p.source;\n var tgt = _p.target;\n return edgeOkViaNode(src) && (!hasCompoundNodes || checkCompound(src, edgeOkViaNode)) && (src === tgt || edgeOkViaNode(tgt) && (!hasCompoundNodes || checkCompound(tgt, edgeOkViaNode)));\n }\n }\n };\n}\nvar eleTakesUpSpace = cacheStyleFunction('eleTakesUpSpace', function (ele) {\n return ele.pstyle('display').value === 'element' && ele.width() !== 0 && (ele.isNode() ? ele.height() !== 0 : true);\n});\nelesfn$4.takesUpSpace = cachePrototypeStyleFunction('takesUpSpace', defineDerivedStateFunction({\n ok: eleTakesUpSpace\n}));\nvar eleInteractive = cacheStyleFunction('eleInteractive', function (ele) {\n return ele.pstyle('events').value === 'yes' && ele.pstyle('visibility').value === 'visible' && eleTakesUpSpace(ele);\n});\nvar parentInteractive = cacheStyleFunction('parentInteractive', function (parent) {\n return parent.pstyle('visibility').value === 'visible' && eleTakesUpSpace(parent);\n});\nelesfn$4.interactive = cachePrototypeStyleFunction('interactive', defineDerivedStateFunction({\n ok: eleInteractive,\n parentOk: parentInteractive,\n edgeOkViaNode: eleTakesUpSpace\n}));\nelesfn$4.noninteractive = function () {\n var ele = this[0];\n if (ele) {\n return !ele.interactive();\n }\n};\nvar eleVisible = cacheStyleFunction('eleVisible', function (ele) {\n return ele.pstyle('visibility').value === 'visible' && ele.pstyle('opacity').pfValue !== 0 && eleTakesUpSpace(ele);\n});\nvar edgeVisibleViaNode = eleTakesUpSpace;\nelesfn$4.visible = cachePrototypeStyleFunction('visible', defineDerivedStateFunction({\n ok: eleVisible,\n edgeOkViaNode: edgeVisibleViaNode\n}));\nelesfn$4.hidden = function () {\n var ele = this[0];\n if (ele) {\n return !ele.visible();\n }\n};\nelesfn$4.isBundledBezier = cachePrototypeStyleFunction('isBundledBezier', function () {\n if (!this.cy().styleEnabled()) {\n return false;\n }\n return !this.removed() && this.pstyle('curve-style').value === 'bezier' && this.takesUpSpace();\n});\nelesfn$4.bypass = elesfn$4.css = elesfn$4.style;\nelesfn$4.renderedCss = elesfn$4.renderedStyle;\nelesfn$4.removeBypass = elesfn$4.removeCss = elesfn$4.removeStyle;\nelesfn$4.pstyle = elesfn$4.parsedStyle;\n\nvar elesfn$3 = {};\nfunction defineSwitchFunction(params) {\n return function () {\n var args = arguments;\n var changedEles = [];\n\n // e.g. cy.nodes().select( data, handler )\n if (args.length === 2) {\n var data = args[0];\n var handler = args[1];\n this.on(params.event, data, handler);\n }\n\n // e.g. cy.nodes().select( handler )\n else if (args.length === 1 && fn$6(args[0])) {\n var _handler = args[0];\n this.on(params.event, _handler);\n }\n\n // e.g. cy.nodes().select()\n // e.g. (private) cy.nodes().select(['tapselect'])\n else if (args.length === 0 || args.length === 1 && array(args[0])) {\n var addlEvents = args.length === 1 ? args[0] : null;\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var able = !params.ableField || ele._private[params.ableField];\n var changed = ele._private[params.field] != params.value;\n if (params.overrideAble) {\n var overrideAble = params.overrideAble(ele);\n if (overrideAble !== undefined) {\n able = overrideAble;\n if (!overrideAble) {\n return this;\n } // to save cycles assume not able for all on override\n }\n }\n\n if (able) {\n ele._private[params.field] = params.value;\n if (changed) {\n changedEles.push(ele);\n }\n }\n }\n var changedColl = this.spawn(changedEles);\n changedColl.updateStyle(); // change of state => possible change of style\n changedColl.emit(params.event);\n if (addlEvents) {\n changedColl.emit(addlEvents);\n }\n }\n return this;\n };\n}\nfunction defineSwitchSet(params) {\n elesfn$3[params.field] = function () {\n var ele = this[0];\n if (ele) {\n if (params.overrideField) {\n var val = params.overrideField(ele);\n if (val !== undefined) {\n return val;\n }\n }\n return ele._private[params.field];\n }\n };\n elesfn$3[params.on] = defineSwitchFunction({\n event: params.on,\n field: params.field,\n ableField: params.ableField,\n overrideAble: params.overrideAble,\n value: true\n });\n elesfn$3[params.off] = defineSwitchFunction({\n event: params.off,\n field: params.field,\n ableField: params.ableField,\n overrideAble: params.overrideAble,\n value: false\n });\n}\ndefineSwitchSet({\n field: 'locked',\n overrideField: function overrideField(ele) {\n return ele.cy().autolock() ? true : undefined;\n },\n on: 'lock',\n off: 'unlock'\n});\ndefineSwitchSet({\n field: 'grabbable',\n overrideField: function overrideField(ele) {\n return ele.cy().autoungrabify() || ele.pannable() ? false : undefined;\n },\n on: 'grabify',\n off: 'ungrabify'\n});\ndefineSwitchSet({\n field: 'selected',\n ableField: 'selectable',\n overrideAble: function overrideAble(ele) {\n return ele.cy().autounselectify() ? false : undefined;\n },\n on: 'select',\n off: 'unselect'\n});\ndefineSwitchSet({\n field: 'selectable',\n overrideField: function overrideField(ele) {\n return ele.cy().autounselectify() ? false : undefined;\n },\n on: 'selectify',\n off: 'unselectify'\n});\nelesfn$3.deselect = elesfn$3.unselect;\nelesfn$3.grabbed = function () {\n var ele = this[0];\n if (ele) {\n return ele._private.grabbed;\n }\n};\ndefineSwitchSet({\n field: 'active',\n on: 'activate',\n off: 'unactivate'\n});\ndefineSwitchSet({\n field: 'pannable',\n on: 'panify',\n off: 'unpanify'\n});\nelesfn$3.inactive = function () {\n var ele = this[0];\n if (ele) {\n return !ele._private.active;\n }\n};\n\nvar elesfn$2 = {};\n\n// DAG functions\n////////////////\n\nvar defineDagExtremity = function defineDagExtremity(params) {\n return function dagExtremityImpl(selector) {\n var eles = this;\n var ret = [];\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n if (!ele.isNode()) {\n continue;\n }\n var disqualified = false;\n var edges = ele.connectedEdges();\n for (var j = 0; j < edges.length; j++) {\n var edge = edges[j];\n var src = edge.source();\n var tgt = edge.target();\n if (params.noIncomingEdges && tgt === ele && src !== ele || params.noOutgoingEdges && src === ele && tgt !== ele) {\n disqualified = true;\n break;\n }\n }\n if (!disqualified) {\n ret.push(ele);\n }\n }\n return this.spawn(ret, true).filter(selector);\n };\n};\nvar defineDagOneHop = function defineDagOneHop(params) {\n return function (selector) {\n var eles = this;\n var oEles = [];\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n if (!ele.isNode()) {\n continue;\n }\n var edges = ele.connectedEdges();\n for (var j = 0; j < edges.length; j++) {\n var edge = edges[j];\n var src = edge.source();\n var tgt = edge.target();\n if (params.outgoing && src === ele) {\n oEles.push(edge);\n oEles.push(tgt);\n } else if (params.incoming && tgt === ele) {\n oEles.push(edge);\n oEles.push(src);\n }\n }\n }\n return this.spawn(oEles, true).filter(selector);\n };\n};\nvar defineDagAllHops = function defineDagAllHops(params) {\n return function (selector) {\n var eles = this;\n var sEles = [];\n var sElesIds = {};\n for (;;) {\n var next = params.outgoing ? eles.outgoers() : eles.incomers();\n if (next.length === 0) {\n break;\n } // done if none left\n\n var newNext = false;\n for (var i = 0; i < next.length; i++) {\n var n = next[i];\n var nid = n.id();\n if (!sElesIds[nid]) {\n sElesIds[nid] = true;\n sEles.push(n);\n newNext = true;\n }\n }\n if (!newNext) {\n break;\n } // done if touched all outgoers already\n\n eles = next;\n }\n return this.spawn(sEles, true).filter(selector);\n };\n};\nelesfn$2.clearTraversalCache = function () {\n for (var i = 0; i < this.length; i++) {\n this[i]._private.traversalCache = null;\n }\n};\nextend(elesfn$2, {\n // get the root nodes in the DAG\n roots: defineDagExtremity({\n noIncomingEdges: true\n }),\n // get the leaf nodes in the DAG\n leaves: defineDagExtremity({\n noOutgoingEdges: true\n }),\n // normally called children in graph theory\n // these nodes =edges=> outgoing nodes\n outgoers: cache(defineDagOneHop({\n outgoing: true\n }), 'outgoers'),\n // aka DAG descendants\n successors: defineDagAllHops({\n outgoing: true\n }),\n // normally called parents in graph theory\n // these nodes <=edges= incoming nodes\n incomers: cache(defineDagOneHop({\n incoming: true\n }), 'incomers'),\n // aka DAG ancestors\n predecessors: defineDagAllHops({\n incoming: true\n })\n});\n\n// Neighbourhood functions\n//////////////////////////\n\nextend(elesfn$2, {\n neighborhood: cache(function (selector) {\n var elements = [];\n var nodes = this.nodes();\n for (var i = 0; i < nodes.length; i++) {\n // for all nodes\n var node = nodes[i];\n var connectedEdges = node.connectedEdges();\n\n // for each connected edge, add the edge and the other node\n for (var j = 0; j < connectedEdges.length; j++) {\n var edge = connectedEdges[j];\n var src = edge.source();\n var tgt = edge.target();\n var otherNode = node === src ? tgt : src;\n\n // need check in case of loop\n if (otherNode.length > 0) {\n elements.push(otherNode[0]); // add node 1 hop away\n }\n\n // add connected edge\n elements.push(edge[0]);\n }\n }\n return this.spawn(elements, true).filter(selector);\n }, 'neighborhood'),\n closedNeighborhood: function closedNeighborhood(selector) {\n return this.neighborhood().add(this).filter(selector);\n },\n openNeighborhood: function openNeighborhood(selector) {\n return this.neighborhood(selector);\n }\n});\n\n// aliases\nelesfn$2.neighbourhood = elesfn$2.neighborhood;\nelesfn$2.closedNeighbourhood = elesfn$2.closedNeighborhood;\nelesfn$2.openNeighbourhood = elesfn$2.openNeighborhood;\n\n// Edge functions\n/////////////////\n\nextend(elesfn$2, {\n source: cache(function sourceImpl(selector) {\n var ele = this[0];\n var src;\n if (ele) {\n src = ele._private.source || ele.cy().collection();\n }\n return src && selector ? src.filter(selector) : src;\n }, 'source'),\n target: cache(function targetImpl(selector) {\n var ele = this[0];\n var tgt;\n if (ele) {\n tgt = ele._private.target || ele.cy().collection();\n }\n return tgt && selector ? tgt.filter(selector) : tgt;\n }, 'target'),\n sources: defineSourceFunction({\n attr: 'source'\n }),\n targets: defineSourceFunction({\n attr: 'target'\n })\n});\nfunction defineSourceFunction(params) {\n return function sourceImpl(selector) {\n var sources = [];\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var src = ele._private[params.attr];\n if (src) {\n sources.push(src);\n }\n }\n return this.spawn(sources, true).filter(selector);\n };\n}\nextend(elesfn$2, {\n edgesWith: cache(defineEdgesWithFunction(), 'edgesWith'),\n edgesTo: cache(defineEdgesWithFunction({\n thisIsSrc: true\n }), 'edgesTo')\n});\nfunction defineEdgesWithFunction(params) {\n return function edgesWithImpl(otherNodes) {\n var elements = [];\n var cy = this._private.cy;\n var p = params || {};\n\n // get elements if a selector is specified\n if (string(otherNodes)) {\n otherNodes = cy.$(otherNodes);\n }\n for (var h = 0; h < otherNodes.length; h++) {\n var edges = otherNodes[h]._private.edges;\n for (var i = 0; i < edges.length; i++) {\n var edge = edges[i];\n var edgeData = edge._private.data;\n var thisToOther = this.hasElementWithId(edgeData.source) && otherNodes.hasElementWithId(edgeData.target);\n var otherToThis = otherNodes.hasElementWithId(edgeData.source) && this.hasElementWithId(edgeData.target);\n var edgeConnectsThisAndOther = thisToOther || otherToThis;\n if (!edgeConnectsThisAndOther) {\n continue;\n }\n if (p.thisIsSrc || p.thisIsTgt) {\n if (p.thisIsSrc && !thisToOther) {\n continue;\n }\n if (p.thisIsTgt && !otherToThis) {\n continue;\n }\n }\n elements.push(edge);\n }\n }\n return this.spawn(elements, true);\n };\n}\nextend(elesfn$2, {\n connectedEdges: cache(function (selector) {\n var retEles = [];\n var eles = this;\n for (var i = 0; i < eles.length; i++) {\n var node = eles[i];\n if (!node.isNode()) {\n continue;\n }\n var edges = node._private.edges;\n for (var j = 0; j < edges.length; j++) {\n var edge = edges[j];\n retEles.push(edge);\n }\n }\n return this.spawn(retEles, true).filter(selector);\n }, 'connectedEdges'),\n connectedNodes: cache(function (selector) {\n var retEles = [];\n var eles = this;\n for (var i = 0; i < eles.length; i++) {\n var edge = eles[i];\n if (!edge.isEdge()) {\n continue;\n }\n retEles.push(edge.source()[0]);\n retEles.push(edge.target()[0]);\n }\n return this.spawn(retEles, true).filter(selector);\n }, 'connectedNodes'),\n parallelEdges: cache(defineParallelEdgesFunction(), 'parallelEdges'),\n codirectedEdges: cache(defineParallelEdgesFunction({\n codirected: true\n }), 'codirectedEdges')\n});\nfunction defineParallelEdgesFunction(params) {\n var defaults = {\n codirected: false\n };\n params = extend({}, defaults, params);\n return function parallelEdgesImpl(selector) {\n // micro-optimised for renderer\n var elements = [];\n var edges = this.edges();\n var p = params;\n\n // look at all the edges in the collection\n for (var i = 0; i < edges.length; i++) {\n var edge1 = edges[i];\n var edge1_p = edge1._private;\n var src1 = edge1_p.source;\n var srcid1 = src1._private.data.id;\n var tgtid1 = edge1_p.data.target;\n var srcEdges1 = src1._private.edges;\n\n // look at edges connected to the src node of this edge\n for (var j = 0; j < srcEdges1.length; j++) {\n var edge2 = srcEdges1[j];\n var edge2data = edge2._private.data;\n var tgtid2 = edge2data.target;\n var srcid2 = edge2data.source;\n var codirected = tgtid2 === tgtid1 && srcid2 === srcid1;\n var oppdirected = srcid1 === tgtid2 && tgtid1 === srcid2;\n if (p.codirected && codirected || !p.codirected && (codirected || oppdirected)) {\n elements.push(edge2);\n }\n }\n }\n return this.spawn(elements, true).filter(selector);\n };\n}\n\n// Misc functions\n/////////////////\n\nextend(elesfn$2, {\n components: function components(root) {\n var self = this;\n var cy = self.cy();\n var visited = cy.collection();\n var unvisited = root == null ? self.nodes() : root.nodes();\n var components = [];\n if (root != null && unvisited.empty()) {\n // root may contain only edges\n unvisited = root.sources(); // doesn't matter which node to use (undirected), so just use the source sides\n }\n\n var visitInComponent = function visitInComponent(node, component) {\n visited.merge(node);\n unvisited.unmerge(node);\n component.merge(node);\n };\n if (unvisited.empty()) {\n return self.spawn();\n }\n var _loop = function _loop() {\n // each iteration yields a component\n var cmpt = cy.collection();\n components.push(cmpt);\n var root = unvisited[0];\n visitInComponent(root, cmpt);\n self.bfs({\n directed: false,\n roots: root,\n visit: function visit(v) {\n return visitInComponent(v, cmpt);\n }\n });\n cmpt.forEach(function (node) {\n node.connectedEdges().forEach(function (e) {\n // connectedEdges() usually cached\n if (self.has(e) && cmpt.has(e.source()) && cmpt.has(e.target())) {\n // has() is cheap\n cmpt.merge(e); // forEach() only considers nodes -- sets N at call time\n }\n });\n });\n };\n do {\n _loop();\n } while (unvisited.length > 0);\n return components;\n },\n component: function component() {\n var ele = this[0];\n return ele.cy().mutableElements().components(ele)[0];\n }\n});\nelesfn$2.componentsOf = elesfn$2.components;\n\n// represents a set of nodes, edges, or both together\nvar Collection = function Collection(cy, elements) {\n var unique = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;\n var removed = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n if (cy === undefined) {\n error('A collection must have a reference to the core');\n return;\n }\n var map = new Map$2();\n var createdElements = false;\n if (!elements) {\n elements = [];\n } else if (elements.length > 0 && plainObject(elements[0]) && !element(elements[0])) {\n createdElements = true;\n\n // make elements from json and restore all at once later\n var eles = [];\n var elesIds = new Set$1();\n for (var i = 0, l = elements.length; i < l; i++) {\n var json = elements[i];\n if (json.data == null) {\n json.data = {};\n }\n var _data = json.data;\n\n // make sure newly created elements have valid ids\n if (_data.id == null) {\n _data.id = uuid();\n } else if (cy.hasElementWithId(_data.id) || elesIds.has(_data.id)) {\n continue; // can't create element if prior id already exists\n }\n\n var ele = new Element(cy, json, false);\n eles.push(ele);\n elesIds.add(_data.id);\n }\n elements = eles;\n }\n this.length = 0;\n for (var _i = 0, _l = elements.length; _i < _l; _i++) {\n var element$1 = elements[_i][0]; // [0] in case elements is an array of collections, rather than array of elements\n if (element$1 == null) {\n continue;\n }\n var id = element$1._private.data.id;\n if (!unique || !map.has(id)) {\n if (unique) {\n map.set(id, {\n index: this.length,\n ele: element$1\n });\n }\n this[this.length] = element$1;\n this.length++;\n }\n }\n this._private = {\n eles: this,\n cy: cy,\n get map() {\n if (this.lazyMap == null) {\n this.rebuildMap();\n }\n return this.lazyMap;\n },\n set map(m) {\n this.lazyMap = m;\n },\n rebuildMap: function rebuildMap() {\n var m = this.lazyMap = new Map$2();\n var eles = this.eles;\n for (var _i2 = 0; _i2 < eles.length; _i2++) {\n var _ele = eles[_i2];\n m.set(_ele.id(), {\n index: _i2,\n ele: _ele\n });\n }\n }\n };\n if (unique) {\n this._private.map = map;\n }\n\n // restore the elements if we created them from json\n if (createdElements && !removed) {\n this.restore();\n }\n};\n\n// Functions\n////////////////////////////////////////////////////////////////////////////////////////////////////\n\n// keep the prototypes in sync (an element has the same functions as a collection)\n// and use elefn and elesfn as shorthands to the prototypes\nvar elesfn$1 = Element.prototype = Collection.prototype = Object.create(Array.prototype);\nelesfn$1.instanceString = function () {\n return 'collection';\n};\nelesfn$1.spawn = function (eles, unique) {\n return new Collection(this.cy(), eles, unique);\n};\nelesfn$1.spawnSelf = function () {\n return this.spawn(this);\n};\nelesfn$1.cy = function () {\n return this._private.cy;\n};\nelesfn$1.renderer = function () {\n return this._private.cy.renderer();\n};\nelesfn$1.element = function () {\n return this[0];\n};\nelesfn$1.collection = function () {\n if (collection(this)) {\n return this;\n } else {\n // an element\n return new Collection(this._private.cy, [this]);\n }\n};\nelesfn$1.unique = function () {\n return new Collection(this._private.cy, this, true);\n};\nelesfn$1.hasElementWithId = function (id) {\n id = '' + id; // id must be string\n\n return this._private.map.has(id);\n};\nelesfn$1.getElementById = function (id) {\n id = '' + id; // id must be string\n\n var cy = this._private.cy;\n var entry = this._private.map.get(id);\n return entry ? entry.ele : new Collection(cy); // get ele or empty collection\n};\n\nelesfn$1.$id = elesfn$1.getElementById;\nelesfn$1.poolIndex = function () {\n var cy = this._private.cy;\n var eles = cy._private.elements;\n var id = this[0]._private.data.id;\n return eles._private.map.get(id).index;\n};\nelesfn$1.indexOf = function (ele) {\n var id = ele[0]._private.data.id;\n return this._private.map.get(id).index;\n};\nelesfn$1.indexOfId = function (id) {\n id = '' + id; // id must be string\n\n return this._private.map.get(id).index;\n};\nelesfn$1.json = function (obj) {\n var ele = this.element();\n var cy = this.cy();\n if (ele == null && obj) {\n return this;\n } // can't set to no eles\n\n if (ele == null) {\n return undefined;\n } // can't get from no eles\n\n var p = ele._private;\n if (plainObject(obj)) {\n // set\n\n cy.startBatch();\n if (obj.data) {\n ele.data(obj.data);\n var _data2 = p.data;\n if (ele.isEdge()) {\n // source and target are immutable via data()\n var move = false;\n var spec = {};\n var src = obj.data.source;\n var tgt = obj.data.target;\n if (src != null && src != _data2.source) {\n spec.source = '' + src; // id must be string\n move = true;\n }\n if (tgt != null && tgt != _data2.target) {\n spec.target = '' + tgt; // id must be string\n move = true;\n }\n if (move) {\n ele = ele.move(spec);\n }\n } else {\n // parent is immutable via data()\n var newParentValSpecd = ('parent' in obj.data);\n var parent = obj.data.parent;\n if (newParentValSpecd && (parent != null || _data2.parent != null) && parent != _data2.parent) {\n if (parent === undefined) {\n // can't set undefined imperatively, so use null\n parent = null;\n }\n if (parent != null) {\n parent = '' + parent; // id must be string\n }\n\n ele = ele.move({\n parent: parent\n });\n }\n }\n }\n if (obj.position) {\n ele.position(obj.position);\n }\n\n // ignore group -- immutable\n\n var checkSwitch = function checkSwitch(k, trueFnName, falseFnName) {\n var obj_k = obj[k];\n if (obj_k != null && obj_k !== p[k]) {\n if (obj_k) {\n ele[trueFnName]();\n } else {\n ele[falseFnName]();\n }\n }\n };\n checkSwitch('removed', 'remove', 'restore');\n checkSwitch('selected', 'select', 'unselect');\n checkSwitch('selectable', 'selectify', 'unselectify');\n checkSwitch('locked', 'lock', 'unlock');\n checkSwitch('grabbable', 'grabify', 'ungrabify');\n checkSwitch('pannable', 'panify', 'unpanify');\n if (obj.classes != null) {\n ele.classes(obj.classes);\n }\n cy.endBatch();\n return this;\n } else if (obj === undefined) {\n // get\n\n var json = {\n data: copy(p.data),\n position: copy(p.position),\n group: p.group,\n removed: p.removed,\n selected: p.selected,\n selectable: p.selectable,\n locked: p.locked,\n grabbable: p.grabbable,\n pannable: p.pannable,\n classes: null\n };\n json.classes = '';\n var i = 0;\n p.classes.forEach(function (cls) {\n return json.classes += i++ === 0 ? cls : ' ' + cls;\n });\n return json;\n }\n};\nelesfn$1.jsons = function () {\n var jsons = [];\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var json = ele.json();\n jsons.push(json);\n }\n return jsons;\n};\nelesfn$1.clone = function () {\n var cy = this.cy();\n var elesArr = [];\n for (var i = 0; i < this.length; i++) {\n var ele = this[i];\n var json = ele.json();\n var clone = new Element(cy, json, false); // NB no restore\n\n elesArr.push(clone);\n }\n return new Collection(cy, elesArr);\n};\nelesfn$1.copy = elesfn$1.clone;\nelesfn$1.restore = function () {\n var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n var addToPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var self = this;\n var cy = self.cy();\n var cy_p = cy._private;\n\n // create arrays of nodes and edges, since we need to\n // restore the nodes first\n var nodes = [];\n var edges = [];\n var elements;\n for (var _i3 = 0, l = self.length; _i3 < l; _i3++) {\n var ele = self[_i3];\n if (addToPool && !ele.removed()) {\n // don't need to handle this ele\n continue;\n }\n\n // keep nodes first in the array and edges after\n if (ele.isNode()) {\n // put to front of array if node\n nodes.push(ele);\n } else {\n // put to end of array if edge\n edges.push(ele);\n }\n }\n elements = nodes.concat(edges);\n var i;\n var removeFromElements = function removeFromElements() {\n elements.splice(i, 1);\n i--;\n };\n\n // now, restore each element\n for (i = 0; i < elements.length; i++) {\n var _ele2 = elements[i];\n var _private = _ele2._private;\n var _data3 = _private.data;\n\n // the traversal cache should start fresh when ele is added\n _ele2.clearTraversalCache();\n\n // set id and validate\n if (!addToPool && !_private.removed) ; else if (_data3.id === undefined) {\n _data3.id = uuid();\n } else if (number$1(_data3.id)) {\n _data3.id = '' + _data3.id; // now it's a string\n } else if (emptyString(_data3.id) || !string(_data3.id)) {\n error('Can not create element with invalid string ID `' + _data3.id + '`');\n\n // can't create element if it has empty string as id or non-string id\n removeFromElements();\n continue;\n } else if (cy.hasElementWithId(_data3.id)) {\n error('Can not create second element with ID `' + _data3.id + '`');\n\n // can't create element if one already has that id\n removeFromElements();\n continue;\n }\n var id = _data3.id; // id is finalised, now let's keep a ref\n\n if (_ele2.isNode()) {\n // extra checks for nodes\n var pos = _private.position;\n\n // make sure the nodes have a defined position\n\n if (pos.x == null) {\n pos.x = 0;\n }\n if (pos.y == null) {\n pos.y = 0;\n }\n }\n if (_ele2.isEdge()) {\n // extra checks for edges\n\n var edge = _ele2;\n var fields = ['source', 'target'];\n var fieldsLength = fields.length;\n var badSourceOrTarget = false;\n for (var j = 0; j < fieldsLength; j++) {\n var field = fields[j];\n var val = _data3[field];\n if (number$1(val)) {\n val = _data3[field] = '' + _data3[field]; // now string\n }\n\n if (val == null || val === '') {\n // can't create if source or target is not defined properly\n error('Can not create edge `' + id + '` with unspecified ' + field);\n badSourceOrTarget = true;\n } else if (!cy.hasElementWithId(val)) {\n // can't create edge if one of its nodes doesn't exist\n error('Can not create edge `' + id + '` with nonexistant ' + field + ' `' + val + '`');\n badSourceOrTarget = true;\n }\n }\n if (badSourceOrTarget) {\n removeFromElements();\n continue;\n } // can't create this\n\n var src = cy.getElementById(_data3.source);\n var tgt = cy.getElementById(_data3.target);\n\n // only one edge in node if loop\n if (src.same(tgt)) {\n src._private.edges.push(edge);\n } else {\n src._private.edges.push(edge);\n tgt._private.edges.push(edge);\n }\n edge._private.source = src;\n edge._private.target = tgt;\n } // if is edge\n\n // create mock ids / indexes maps for element so it can be used like collections\n _private.map = new Map$2();\n _private.map.set(id, {\n ele: _ele2,\n index: 0\n });\n _private.removed = false;\n if (addToPool) {\n cy.addToPool(_ele2);\n }\n } // for each element\n\n // do compound node sanity checks\n for (var _i4 = 0; _i4 < nodes.length; _i4++) {\n // each node\n var node = nodes[_i4];\n var _data4 = node._private.data;\n if (number$1(_data4.parent)) {\n // then automake string\n _data4.parent = '' + _data4.parent;\n }\n var parentId = _data4.parent;\n var specifiedParent = parentId != null;\n if (specifiedParent || node._private.parent) {\n var parent = node._private.parent ? cy.collection().merge(node._private.parent) : cy.getElementById(parentId);\n if (parent.empty()) {\n // non-existant parent; just remove it\n _data4.parent = undefined;\n } else if (parent[0].removed()) {\n warn('Node added with missing parent, reference to parent removed');\n _data4.parent = undefined;\n node._private.parent = null;\n } else {\n var selfAsParent = false;\n var ancestor = parent;\n while (!ancestor.empty()) {\n if (node.same(ancestor)) {\n // mark self as parent and remove from data\n selfAsParent = true;\n _data4.parent = undefined; // remove parent reference\n\n // exit or we loop forever\n break;\n }\n ancestor = ancestor.parent();\n }\n if (!selfAsParent) {\n // connect with children\n parent[0]._private.children.push(node);\n node._private.parent = parent[0];\n\n // let the core know we have a compound graph\n cy_p.hasCompoundNodes = true;\n }\n } // else\n } // if specified parent\n } // for each node\n\n if (elements.length > 0) {\n var restored = elements.length === self.length ? self : new Collection(cy, elements);\n for (var _i5 = 0; _i5 < restored.length; _i5++) {\n var _ele3 = restored[_i5];\n if (_ele3.isNode()) {\n continue;\n }\n\n // adding an edge invalidates the traversal caches for the parallel edges\n _ele3.parallelEdges().clearTraversalCache();\n\n // adding an edge invalidates the traversal cache for the connected nodes\n _ele3.source().clearTraversalCache();\n _ele3.target().clearTraversalCache();\n }\n var toUpdateStyle;\n if (cy_p.hasCompoundNodes) {\n toUpdateStyle = cy.collection().merge(restored).merge(restored.connectedNodes()).merge(restored.parent());\n } else {\n toUpdateStyle = restored;\n }\n toUpdateStyle.dirtyCompoundBoundsCache().dirtyBoundingBoxCache().updateStyle(notifyRenderer);\n if (notifyRenderer) {\n restored.emitAndNotify('add');\n } else if (addToPool) {\n restored.emit('add');\n }\n }\n return self; // chainability\n};\n\nelesfn$1.removed = function () {\n var ele = this[0];\n return ele && ele._private.removed;\n};\nelesfn$1.inside = function () {\n var ele = this[0];\n return ele && !ele._private.removed;\n};\nelesfn$1.remove = function () {\n var notifyRenderer = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n var removeFromPool = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var self = this;\n var elesToRemove = [];\n var elesToRemoveIds = {};\n var cy = self._private.cy;\n\n // add connected edges\n function addConnectedEdges(node) {\n var edges = node._private.edges;\n for (var i = 0; i < edges.length; i++) {\n add(edges[i]);\n }\n }\n\n // add descendant nodes\n function addChildren(node) {\n var children = node._private.children;\n for (var i = 0; i < children.length; i++) {\n add(children[i]);\n }\n }\n function add(ele) {\n var alreadyAdded = elesToRemoveIds[ele.id()];\n if (removeFromPool && ele.removed() || alreadyAdded) {\n return;\n } else {\n elesToRemoveIds[ele.id()] = true;\n }\n if (ele.isNode()) {\n elesToRemove.push(ele); // nodes are removed last\n\n addConnectedEdges(ele);\n addChildren(ele);\n } else {\n elesToRemove.unshift(ele); // edges are removed first\n }\n }\n\n // make the list of elements to remove\n // (may be removing more than specified due to connected edges etc)\n\n for (var i = 0, l = self.length; i < l; i++) {\n var ele = self[i];\n add(ele);\n }\n function removeEdgeRef(node, edge) {\n var connectedEdges = node._private.edges;\n removeFromArray(connectedEdges, edge);\n\n // removing an edges invalidates the traversal cache for its nodes\n node.clearTraversalCache();\n }\n function removeParallelRef(pllEdge) {\n // removing an edge invalidates the traversal caches for the parallel edges\n pllEdge.clearTraversalCache();\n }\n var alteredParents = [];\n alteredParents.ids = {};\n function removeChildRef(parent, ele) {\n ele = ele[0];\n parent = parent[0];\n var children = parent._private.children;\n var pid = parent.id();\n removeFromArray(children, ele); // remove parent => child ref\n\n ele._private.parent = null; // remove child => parent ref\n\n if (!alteredParents.ids[pid]) {\n alteredParents.ids[pid] = true;\n alteredParents.push(parent);\n }\n }\n self.dirtyCompoundBoundsCache();\n if (removeFromPool) {\n cy.removeFromPool(elesToRemove); // remove from core pool\n }\n\n for (var _i6 = 0; _i6 < elesToRemove.length; _i6++) {\n var _ele4 = elesToRemove[_i6];\n if (_ele4.isEdge()) {\n // remove references to this edge in its connected nodes\n var src = _ele4.source()[0];\n var tgt = _ele4.target()[0];\n removeEdgeRef(src, _ele4);\n removeEdgeRef(tgt, _ele4);\n var pllEdges = _ele4.parallelEdges();\n for (var j = 0; j < pllEdges.length; j++) {\n var pllEdge = pllEdges[j];\n removeParallelRef(pllEdge);\n if (pllEdge.isBundledBezier()) {\n pllEdge.dirtyBoundingBoxCache();\n }\n }\n } else {\n // remove reference to parent\n var parent = _ele4.parent();\n if (parent.length !== 0) {\n removeChildRef(parent, _ele4);\n }\n }\n if (removeFromPool) {\n // mark as removed\n _ele4._private.removed = true;\n }\n }\n\n // check to see if we have a compound graph or not\n var elesStillInside = cy._private.elements;\n cy._private.hasCompoundNodes = false;\n for (var _i7 = 0; _i7 < elesStillInside.length; _i7++) {\n var _ele5 = elesStillInside[_i7];\n if (_ele5.isParent()) {\n cy._private.hasCompoundNodes = true;\n break;\n }\n }\n var removedElements = new Collection(this.cy(), elesToRemove);\n if (removedElements.size() > 0) {\n // must manually notify since trigger won't do this automatically once removed\n\n if (notifyRenderer) {\n removedElements.emitAndNotify('remove');\n } else if (removeFromPool) {\n removedElements.emit('remove');\n }\n }\n\n // the parents who were modified by the removal need their style updated\n for (var _i8 = 0; _i8 < alteredParents.length; _i8++) {\n var _ele6 = alteredParents[_i8];\n if (!removeFromPool || !_ele6.removed()) {\n _ele6.updateStyle();\n }\n }\n return removedElements;\n};\nelesfn$1.move = function (struct) {\n var cy = this._private.cy;\n var eles = this;\n\n // just clean up refs, caches, etc. in the same way as when removing and then restoring\n // (our calls to remove/restore do not remove from the graph or make events)\n var notifyRenderer = false;\n var modifyPool = false;\n var toString = function toString(id) {\n return id == null ? id : '' + id;\n }; // id must be string\n\n if (struct.source !== undefined || struct.target !== undefined) {\n var srcId = toString(struct.source);\n var tgtId = toString(struct.target);\n var srcExists = srcId != null && cy.hasElementWithId(srcId);\n var tgtExists = tgtId != null && cy.hasElementWithId(tgtId);\n if (srcExists || tgtExists) {\n cy.batch(function () {\n // avoid duplicate style updates\n eles.remove(notifyRenderer, modifyPool); // clean up refs etc.\n eles.emitAndNotify('moveout');\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var _data5 = ele._private.data;\n if (ele.isEdge()) {\n if (srcExists) {\n _data5.source = srcId;\n }\n if (tgtExists) {\n _data5.target = tgtId;\n }\n }\n }\n eles.restore(notifyRenderer, modifyPool); // make new refs, style, etc.\n });\n\n eles.emitAndNotify('move');\n }\n } else if (struct.parent !== undefined) {\n // move node to new parent\n var parentId = toString(struct.parent);\n var parentExists = parentId === null || cy.hasElementWithId(parentId);\n if (parentExists) {\n var pidToAssign = parentId === null ? undefined : parentId;\n cy.batch(function () {\n // avoid duplicate style updates\n var updated = eles.remove(notifyRenderer, modifyPool); // clean up refs etc.\n updated.emitAndNotify('moveout');\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var _data6 = ele._private.data;\n if (ele.isNode()) {\n _data6.parent = pidToAssign;\n }\n }\n updated.restore(notifyRenderer, modifyPool); // make new refs, style, etc.\n });\n\n eles.emitAndNotify('move');\n }\n }\n return this;\n};\n[elesfn$j, elesfn$i, elesfn$h, elesfn$g, elesfn$f, data, elesfn$d, dimensions, elesfn$9, elesfn$8, elesfn$7, elesfn$6, elesfn$5, elesfn$4, elesfn$3, elesfn$2].forEach(function (props) {\n extend(elesfn$1, props);\n});\n\nvar corefn$9 = {\n add: function add(opts) {\n var elements;\n var cy = this;\n\n // add the elements\n if (elementOrCollection(opts)) {\n var eles = opts;\n if (eles._private.cy === cy) {\n // same instance => just restore\n elements = eles.restore();\n } else {\n // otherwise, copy from json\n var jsons = [];\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n jsons.push(ele.json());\n }\n elements = new Collection(cy, jsons);\n }\n }\n\n // specify an array of options\n else if (array(opts)) {\n var _jsons = opts;\n elements = new Collection(cy, _jsons);\n }\n\n // specify via opts.nodes and opts.edges\n else if (plainObject(opts) && (array(opts.nodes) || array(opts.edges))) {\n var elesByGroup = opts;\n var _jsons2 = [];\n var grs = ['nodes', 'edges'];\n for (var _i = 0, il = grs.length; _i < il; _i++) {\n var group = grs[_i];\n var elesArray = elesByGroup[group];\n if (array(elesArray)) {\n for (var j = 0, jl = elesArray.length; j < jl; j++) {\n var json = extend({\n group: group\n }, elesArray[j]);\n _jsons2.push(json);\n }\n }\n }\n elements = new Collection(cy, _jsons2);\n }\n\n // specify options for one element\n else {\n var _json = opts;\n elements = new Element(cy, _json).collection();\n }\n return elements;\n },\n remove: function remove(collection) {\n if (elementOrCollection(collection)) ; else if (string(collection)) {\n var selector = collection;\n collection = this.$(selector);\n }\n return collection.remove();\n }\n};\n\n/* global Float32Array */\n\n/*! Bezier curve function generator. Copyright Gaetan Renaudeau. MIT License: http://en.wikipedia.org/wiki/MIT_License */\nfunction generateCubicBezier(mX1, mY1, mX2, mY2) {\n var NEWTON_ITERATIONS = 4,\n NEWTON_MIN_SLOPE = 0.001,\n SUBDIVISION_PRECISION = 0.0000001,\n SUBDIVISION_MAX_ITERATIONS = 10,\n kSplineTableSize = 11,\n kSampleStepSize = 1.0 / (kSplineTableSize - 1.0),\n float32ArraySupported = typeof Float32Array !== 'undefined';\n\n /* Must contain four arguments. */\n if (arguments.length !== 4) {\n return false;\n }\n\n /* Arguments must be numbers. */\n for (var i = 0; i < 4; ++i) {\n if (typeof arguments[i] !== \"number\" || isNaN(arguments[i]) || !isFinite(arguments[i])) {\n return false;\n }\n }\n\n /* X values must be in the [0, 1] range. */\n mX1 = Math.min(mX1, 1);\n mX2 = Math.min(mX2, 1);\n mX1 = Math.max(mX1, 0);\n mX2 = Math.max(mX2, 0);\n var mSampleValues = float32ArraySupported ? new Float32Array(kSplineTableSize) : new Array(kSplineTableSize);\n function A(aA1, aA2) {\n return 1.0 - 3.0 * aA2 + 3.0 * aA1;\n }\n function B(aA1, aA2) {\n return 3.0 * aA2 - 6.0 * aA1;\n }\n function C(aA1) {\n return 3.0 * aA1;\n }\n function calcBezier(aT, aA1, aA2) {\n return ((A(aA1, aA2) * aT + B(aA1, aA2)) * aT + C(aA1)) * aT;\n }\n function getSlope(aT, aA1, aA2) {\n return 3.0 * A(aA1, aA2) * aT * aT + 2.0 * B(aA1, aA2) * aT + C(aA1);\n }\n function newtonRaphsonIterate(aX, aGuessT) {\n for (var _i = 0; _i < NEWTON_ITERATIONS; ++_i) {\n var currentSlope = getSlope(aGuessT, mX1, mX2);\n if (currentSlope === 0.0) {\n return aGuessT;\n }\n var currentX = calcBezier(aGuessT, mX1, mX2) - aX;\n aGuessT -= currentX / currentSlope;\n }\n return aGuessT;\n }\n function calcSampleValues() {\n for (var _i2 = 0; _i2 < kSplineTableSize; ++_i2) {\n mSampleValues[_i2] = calcBezier(_i2 * kSampleStepSize, mX1, mX2);\n }\n }\n function binarySubdivide(aX, aA, aB) {\n var currentX,\n currentT,\n i = 0;\n do {\n currentT = aA + (aB - aA) / 2.0;\n currentX = calcBezier(currentT, mX1, mX2) - aX;\n if (currentX > 0.0) {\n aB = currentT;\n } else {\n aA = currentT;\n }\n } while (Math.abs(currentX) > SUBDIVISION_PRECISION && ++i < SUBDIVISION_MAX_ITERATIONS);\n return currentT;\n }\n function getTForX(aX) {\n var intervalStart = 0.0,\n currentSample = 1,\n lastSample = kSplineTableSize - 1;\n for (; currentSample !== lastSample && mSampleValues[currentSample] <= aX; ++currentSample) {\n intervalStart += kSampleStepSize;\n }\n --currentSample;\n var dist = (aX - mSampleValues[currentSample]) / (mSampleValues[currentSample + 1] - mSampleValues[currentSample]),\n guessForT = intervalStart + dist * kSampleStepSize,\n initialSlope = getSlope(guessForT, mX1, mX2);\n if (initialSlope >= NEWTON_MIN_SLOPE) {\n return newtonRaphsonIterate(aX, guessForT);\n } else if (initialSlope === 0.0) {\n return guessForT;\n } else {\n return binarySubdivide(aX, intervalStart, intervalStart + kSampleStepSize);\n }\n }\n var _precomputed = false;\n function precompute() {\n _precomputed = true;\n if (mX1 !== mY1 || mX2 !== mY2) {\n calcSampleValues();\n }\n }\n var f = function f(aX) {\n if (!_precomputed) {\n precompute();\n }\n if (mX1 === mY1 && mX2 === mY2) {\n return aX;\n }\n if (aX === 0) {\n return 0;\n }\n if (aX === 1) {\n return 1;\n }\n return calcBezier(getTForX(aX), mY1, mY2);\n };\n f.getControlPoints = function () {\n return [{\n x: mX1,\n y: mY1\n }, {\n x: mX2,\n y: mY2\n }];\n };\n var str = \"generateBezier(\" + [mX1, mY1, mX2, mY2] + \")\";\n f.toString = function () {\n return str;\n };\n return f;\n}\n\n/*! Runge-Kutta spring physics function generator. Adapted from Framer.js, copyright Koen Bok. MIT License: http://en.wikipedia.org/wiki/MIT_License */\n/* Given a tension, friction, and duration, a simulation at 60FPS will first run without a defined duration in order to calculate the full path. A second pass\n then adjusts the time delta -- using the relation between actual time and duration -- to calculate the path for the duration-constrained animation. */\nvar generateSpringRK4 = function () {\n function springAccelerationForState(state) {\n return -state.tension * state.x - state.friction * state.v;\n }\n function springEvaluateStateWithDerivative(initialState, dt, derivative) {\n var state = {\n x: initialState.x + derivative.dx * dt,\n v: initialState.v + derivative.dv * dt,\n tension: initialState.tension,\n friction: initialState.friction\n };\n return {\n dx: state.v,\n dv: springAccelerationForState(state)\n };\n }\n function springIntegrateState(state, dt) {\n var a = {\n dx: state.v,\n dv: springAccelerationForState(state)\n },\n b = springEvaluateStateWithDerivative(state, dt * 0.5, a),\n c = springEvaluateStateWithDerivative(state, dt * 0.5, b),\n d = springEvaluateStateWithDerivative(state, dt, c),\n dxdt = 1.0 / 6.0 * (a.dx + 2.0 * (b.dx + c.dx) + d.dx),\n dvdt = 1.0 / 6.0 * (a.dv + 2.0 * (b.dv + c.dv) + d.dv);\n state.x = state.x + dxdt * dt;\n state.v = state.v + dvdt * dt;\n return state;\n }\n return function springRK4Factory(tension, friction, duration) {\n var initState = {\n x: -1,\n v: 0,\n tension: null,\n friction: null\n },\n path = [0],\n time_lapsed = 0,\n tolerance = 1 / 10000,\n DT = 16 / 1000,\n have_duration,\n dt,\n last_state;\n tension = parseFloat(tension) || 500;\n friction = parseFloat(friction) || 20;\n duration = duration || null;\n initState.tension = tension;\n initState.friction = friction;\n have_duration = duration !== null;\n\n /* Calculate the actual time it takes for this animation to complete with the provided conditions. */\n if (have_duration) {\n /* Run the simulation without a duration. */\n time_lapsed = springRK4Factory(tension, friction);\n /* Compute the adjusted time delta. */\n dt = time_lapsed / duration * DT;\n } else {\n dt = DT;\n }\n for (;;) {\n /* Next/step function .*/\n last_state = springIntegrateState(last_state || initState, dt);\n /* Store the position. */\n path.push(1 + last_state.x);\n time_lapsed += 16;\n /* If the change threshold is reached, break. */\n if (!(Math.abs(last_state.x) > tolerance && Math.abs(last_state.v) > tolerance)) {\n break;\n }\n }\n\n /* If duration is not defined, return the actual time required for completing this animation. Otherwise, return a closure that holds the\n computed path and returns a snapshot of the position according to a given percentComplete. */\n return !have_duration ? time_lapsed : function (percentComplete) {\n return path[percentComplete * (path.length - 1) | 0];\n };\n };\n}();\n\nvar cubicBezier = function cubicBezier(t1, p1, t2, p2) {\n var bezier = generateCubicBezier(t1, p1, t2, p2);\n return function (start, end, percent) {\n return start + (end - start) * bezier(percent);\n };\n};\nvar easings = {\n 'linear': function linear(start, end, percent) {\n return start + (end - start) * percent;\n },\n // default easings\n 'ease': cubicBezier(0.25, 0.1, 0.25, 1),\n 'ease-in': cubicBezier(0.42, 0, 1, 1),\n 'ease-out': cubicBezier(0, 0, 0.58, 1),\n 'ease-in-out': cubicBezier(0.42, 0, 0.58, 1),\n // sine\n 'ease-in-sine': cubicBezier(0.47, 0, 0.745, 0.715),\n 'ease-out-sine': cubicBezier(0.39, 0.575, 0.565, 1),\n 'ease-in-out-sine': cubicBezier(0.445, 0.05, 0.55, 0.95),\n // quad\n 'ease-in-quad': cubicBezier(0.55, 0.085, 0.68, 0.53),\n 'ease-out-quad': cubicBezier(0.25, 0.46, 0.45, 0.94),\n 'ease-in-out-quad': cubicBezier(0.455, 0.03, 0.515, 0.955),\n // cubic\n 'ease-in-cubic': cubicBezier(0.55, 0.055, 0.675, 0.19),\n 'ease-out-cubic': cubicBezier(0.215, 0.61, 0.355, 1),\n 'ease-in-out-cubic': cubicBezier(0.645, 0.045, 0.355, 1),\n // quart\n 'ease-in-quart': cubicBezier(0.895, 0.03, 0.685, 0.22),\n 'ease-out-quart': cubicBezier(0.165, 0.84, 0.44, 1),\n 'ease-in-out-quart': cubicBezier(0.77, 0, 0.175, 1),\n // quint\n 'ease-in-quint': cubicBezier(0.755, 0.05, 0.855, 0.06),\n 'ease-out-quint': cubicBezier(0.23, 1, 0.32, 1),\n 'ease-in-out-quint': cubicBezier(0.86, 0, 0.07, 1),\n // expo\n 'ease-in-expo': cubicBezier(0.95, 0.05, 0.795, 0.035),\n 'ease-out-expo': cubicBezier(0.19, 1, 0.22, 1),\n 'ease-in-out-expo': cubicBezier(1, 0, 0, 1),\n // circ\n 'ease-in-circ': cubicBezier(0.6, 0.04, 0.98, 0.335),\n 'ease-out-circ': cubicBezier(0.075, 0.82, 0.165, 1),\n 'ease-in-out-circ': cubicBezier(0.785, 0.135, 0.15, 0.86),\n // user param easings...\n\n 'spring': function spring(tension, friction, duration) {\n if (duration === 0) {\n // can't get a spring w/ duration 0\n return easings.linear; // duration 0 => jump to end so impl doesn't matter\n }\n\n var spring = generateSpringRK4(tension, friction, duration);\n return function (start, end, percent) {\n return start + (end - start) * spring(percent);\n };\n },\n 'cubic-bezier': cubicBezier\n};\n\nfunction getEasedValue(type, start, end, percent, easingFn) {\n if (percent === 1) {\n return end;\n }\n if (start === end) {\n return end;\n }\n var val = easingFn(start, end, percent);\n if (type == null) {\n return val;\n }\n if (type.roundValue || type.color) {\n val = Math.round(val);\n }\n if (type.min !== undefined) {\n val = Math.max(val, type.min);\n }\n if (type.max !== undefined) {\n val = Math.min(val, type.max);\n }\n return val;\n}\nfunction getValue(prop, spec) {\n if (prop.pfValue != null || prop.value != null) {\n if (prop.pfValue != null && (spec == null || spec.type.units !== '%')) {\n return prop.pfValue;\n } else {\n return prop.value;\n }\n } else {\n return prop;\n }\n}\nfunction ease(startProp, endProp, percent, easingFn, propSpec) {\n var type = propSpec != null ? propSpec.type : null;\n if (percent < 0) {\n percent = 0;\n } else if (percent > 1) {\n percent = 1;\n }\n var start = getValue(startProp, propSpec);\n var end = getValue(endProp, propSpec);\n if (number$1(start) && number$1(end)) {\n return getEasedValue(type, start, end, percent, easingFn);\n } else if (array(start) && array(end)) {\n var easedArr = [];\n for (var i = 0; i < end.length; i++) {\n var si = start[i];\n var ei = end[i];\n if (si != null && ei != null) {\n var val = getEasedValue(type, si, ei, percent, easingFn);\n easedArr.push(val);\n } else {\n easedArr.push(ei);\n }\n }\n return easedArr;\n }\n return undefined;\n}\n\nfunction step$1(self, ani, now, isCore) {\n var isEles = !isCore;\n var _p = self._private;\n var ani_p = ani._private;\n var pEasing = ani_p.easing;\n var startTime = ani_p.startTime;\n var cy = isCore ? self : self.cy();\n var style = cy.style();\n if (!ani_p.easingImpl) {\n if (pEasing == null) {\n // use default\n ani_p.easingImpl = easings['linear'];\n } else {\n // then define w/ name\n var easingVals;\n if (string(pEasing)) {\n var easingProp = style.parse('transition-timing-function', pEasing);\n easingVals = easingProp.value;\n } else {\n // then assume preparsed array\n easingVals = pEasing;\n }\n var name, args;\n if (string(easingVals)) {\n name = easingVals;\n args = [];\n } else {\n name = easingVals[1];\n args = easingVals.slice(2).map(function (n) {\n return +n;\n });\n }\n if (args.length > 0) {\n // create with args\n if (name === 'spring') {\n args.push(ani_p.duration); // need duration to generate spring\n }\n\n ani_p.easingImpl = easings[name].apply(null, args);\n } else {\n // static impl by name\n ani_p.easingImpl = easings[name];\n }\n }\n }\n var easing = ani_p.easingImpl;\n var percent;\n if (ani_p.duration === 0) {\n percent = 1;\n } else {\n percent = (now - startTime) / ani_p.duration;\n }\n if (ani_p.applying) {\n percent = ani_p.progress;\n }\n if (percent < 0) {\n percent = 0;\n } else if (percent > 1) {\n percent = 1;\n }\n if (ani_p.delay == null) {\n // then update\n\n var startPos = ani_p.startPosition;\n var endPos = ani_p.position;\n if (endPos && isEles && !self.locked()) {\n var newPos = {};\n if (valid(startPos.x, endPos.x)) {\n newPos.x = ease(startPos.x, endPos.x, percent, easing);\n }\n if (valid(startPos.y, endPos.y)) {\n newPos.y = ease(startPos.y, endPos.y, percent, easing);\n }\n self.position(newPos);\n }\n var startPan = ani_p.startPan;\n var endPan = ani_p.pan;\n var pan = _p.pan;\n var animatingPan = endPan != null && isCore;\n if (animatingPan) {\n if (valid(startPan.x, endPan.x)) {\n pan.x = ease(startPan.x, endPan.x, percent, easing);\n }\n if (valid(startPan.y, endPan.y)) {\n pan.y = ease(startPan.y, endPan.y, percent, easing);\n }\n self.emit('pan');\n }\n var startZoom = ani_p.startZoom;\n var endZoom = ani_p.zoom;\n var animatingZoom = endZoom != null && isCore;\n if (animatingZoom) {\n if (valid(startZoom, endZoom)) {\n _p.zoom = bound(_p.minZoom, ease(startZoom, endZoom, percent, easing), _p.maxZoom);\n }\n self.emit('zoom');\n }\n if (animatingPan || animatingZoom) {\n self.emit('viewport');\n }\n var props = ani_p.style;\n if (props && props.length > 0 && isEles) {\n for (var i = 0; i < props.length; i++) {\n var prop = props[i];\n var _name = prop.name;\n var end = prop;\n var start = ani_p.startStyle[_name];\n var propSpec = style.properties[start.name];\n var easedVal = ease(start, end, percent, easing, propSpec);\n style.overrideBypass(self, _name, easedVal);\n } // for props\n\n self.emit('style');\n } // if\n }\n\n ani_p.progress = percent;\n return percent;\n}\nfunction valid(start, end) {\n if (start == null || end == null) {\n return false;\n }\n if (number$1(start) && number$1(end)) {\n return true;\n } else if (start && end) {\n return true;\n }\n return false;\n}\n\nfunction startAnimation(self, ani, now, isCore) {\n var ani_p = ani._private;\n ani_p.started = true;\n ani_p.startTime = now - ani_p.progress * ani_p.duration;\n}\n\nfunction stepAll(now, cy) {\n var eles = cy._private.aniEles;\n var doneEles = [];\n function stepOne(ele, isCore) {\n var _p = ele._private;\n var current = _p.animation.current;\n var queue = _p.animation.queue;\n var ranAnis = false;\n\n // if nothing currently animating, get something from the queue\n if (current.length === 0) {\n var next = queue.shift();\n if (next) {\n current.push(next);\n }\n }\n var callbacks = function callbacks(_callbacks) {\n for (var j = _callbacks.length - 1; j >= 0; j--) {\n var cb = _callbacks[j];\n cb();\n }\n _callbacks.splice(0, _callbacks.length);\n };\n\n // step and remove if done\n for (var i = current.length - 1; i >= 0; i--) {\n var ani = current[i];\n var ani_p = ani._private;\n if (ani_p.stopped) {\n current.splice(i, 1);\n ani_p.hooked = false;\n ani_p.playing = false;\n ani_p.started = false;\n callbacks(ani_p.frames);\n continue;\n }\n if (!ani_p.playing && !ani_p.applying) {\n continue;\n }\n\n // an apply() while playing shouldn't do anything\n if (ani_p.playing && ani_p.applying) {\n ani_p.applying = false;\n }\n if (!ani_p.started) {\n startAnimation(ele, ani, now);\n }\n step$1(ele, ani, now, isCore);\n if (ani_p.applying) {\n ani_p.applying = false;\n }\n callbacks(ani_p.frames);\n if (ani_p.step != null) {\n ani_p.step(now);\n }\n if (ani.completed()) {\n current.splice(i, 1);\n ani_p.hooked = false;\n ani_p.playing = false;\n ani_p.started = false;\n callbacks(ani_p.completes);\n }\n ranAnis = true;\n }\n if (!isCore && current.length === 0 && queue.length === 0) {\n doneEles.push(ele);\n }\n return ranAnis;\n } // stepElement\n\n // handle all eles\n var ranEleAni = false;\n for (var e = 0; e < eles.length; e++) {\n var ele = eles[e];\n var handledThisEle = stepOne(ele);\n ranEleAni = ranEleAni || handledThisEle;\n } // each element\n\n var ranCoreAni = stepOne(cy, true);\n\n // notify renderer\n if (ranEleAni || ranCoreAni) {\n if (eles.length > 0) {\n cy.notify('draw', eles);\n } else {\n cy.notify('draw');\n }\n }\n\n // remove elements from list of currently animating if its queues are empty\n eles.unmerge(doneEles);\n cy.emit('step');\n} // stepAll\n\nvar corefn$8 = {\n // pull in animation functions\n animate: define.animate(),\n animation: define.animation(),\n animated: define.animated(),\n clearQueue: define.clearQueue(),\n delay: define.delay(),\n delayAnimation: define.delayAnimation(),\n stop: define.stop(),\n addToAnimationPool: function addToAnimationPool(eles) {\n var cy = this;\n if (!cy.styleEnabled()) {\n return;\n } // save cycles when no style used\n\n cy._private.aniEles.merge(eles);\n },\n stopAnimationLoop: function stopAnimationLoop() {\n this._private.animationsRunning = false;\n },\n startAnimationLoop: function startAnimationLoop() {\n var cy = this;\n cy._private.animationsRunning = true;\n if (!cy.styleEnabled()) {\n return;\n } // save cycles when no style used\n\n // NB the animation loop will exec in headless environments if style enabled\n // and explicit cy.destroy() is necessary to stop the loop\n\n function headlessStep() {\n if (!cy._private.animationsRunning) {\n return;\n }\n requestAnimationFrame(function animationStep(now) {\n stepAll(now, cy);\n headlessStep();\n });\n }\n var renderer = cy.renderer();\n if (renderer && renderer.beforeRender) {\n // let the renderer schedule animations\n renderer.beforeRender(function rendererAnimationStep(willDraw, now) {\n stepAll(now, cy);\n }, renderer.beforeRenderPriorities.animations);\n } else {\n // manage the animation loop ourselves\n headlessStep(); // first call\n }\n }\n};\n\nvar emitterOptions = {\n qualifierCompare: function qualifierCompare(selector1, selector2) {\n if (selector1 == null || selector2 == null) {\n return selector1 == null && selector2 == null;\n } else {\n return selector1.sameText(selector2);\n }\n },\n eventMatches: function eventMatches(cy, listener, eventObj) {\n var selector = listener.qualifier;\n if (selector != null) {\n return cy !== eventObj.target && element(eventObj.target) && selector.matches(eventObj.target);\n }\n return true;\n },\n addEventFields: function addEventFields(cy, evt) {\n evt.cy = cy;\n evt.target = cy;\n },\n callbackContext: function callbackContext(cy, listener, eventObj) {\n return listener.qualifier != null ? eventObj.target : cy;\n }\n};\nvar argSelector = function argSelector(arg) {\n if (string(arg)) {\n return new Selector(arg);\n } else {\n return arg;\n }\n};\nvar elesfn = {\n createEmitter: function createEmitter() {\n var _p = this._private;\n if (!_p.emitter) {\n _p.emitter = new Emitter(emitterOptions, this);\n }\n return this;\n },\n emitter: function emitter() {\n return this._private.emitter;\n },\n on: function on(events, selector, callback) {\n this.emitter().on(events, argSelector(selector), callback);\n return this;\n },\n removeListener: function removeListener(events, selector, callback) {\n this.emitter().removeListener(events, argSelector(selector), callback);\n return this;\n },\n removeAllListeners: function removeAllListeners() {\n this.emitter().removeAllListeners();\n return this;\n },\n one: function one(events, selector, callback) {\n this.emitter().one(events, argSelector(selector), callback);\n return this;\n },\n once: function once(events, selector, callback) {\n this.emitter().one(events, argSelector(selector), callback);\n return this;\n },\n emit: function emit(events, extraParams) {\n this.emitter().emit(events, extraParams);\n return this;\n },\n emitAndNotify: function emitAndNotify(event, eles) {\n this.emit(event);\n this.notify(event, eles);\n return this;\n }\n};\ndefine.eventAliasesOn(elesfn);\n\nvar corefn$7 = {\n png: function png(options) {\n var renderer = this._private.renderer;\n options = options || {};\n return renderer.png(options);\n },\n jpg: function jpg(options) {\n var renderer = this._private.renderer;\n options = options || {};\n options.bg = options.bg || '#fff';\n return renderer.jpg(options);\n }\n};\ncorefn$7.jpeg = corefn$7.jpg;\n\nvar corefn$6 = {\n layout: function layout(options) {\n var cy = this;\n if (options == null) {\n error('Layout options must be specified to make a layout');\n return;\n }\n if (options.name == null) {\n error('A `name` must be specified to make a layout');\n return;\n }\n var name = options.name;\n var Layout = cy.extension('layout', name);\n if (Layout == null) {\n error('No such layout `' + name + '` found. Did you forget to import it and `cytoscape.use()` it?');\n return;\n }\n var eles;\n if (string(options.eles)) {\n eles = cy.$(options.eles);\n } else {\n eles = options.eles != null ? options.eles : cy.$();\n }\n var layout = new Layout(extend({}, options, {\n cy: cy,\n eles: eles\n }));\n return layout;\n }\n};\ncorefn$6.createLayout = corefn$6.makeLayout = corefn$6.layout;\n\nvar corefn$5 = {\n notify: function notify(eventName, eventEles) {\n var _p = this._private;\n if (this.batching()) {\n _p.batchNotifications = _p.batchNotifications || {};\n var eles = _p.batchNotifications[eventName] = _p.batchNotifications[eventName] || this.collection();\n if (eventEles != null) {\n eles.merge(eventEles);\n }\n return; // notifications are disabled during batching\n }\n\n if (!_p.notificationsEnabled) {\n return;\n } // exit on disabled\n\n var renderer = this.renderer();\n\n // exit if destroy() called on core or renderer in between frames #1499 #1528\n if (this.destroyed() || !renderer) {\n return;\n }\n renderer.notify(eventName, eventEles);\n },\n notifications: function notifications(bool) {\n var p = this._private;\n if (bool === undefined) {\n return p.notificationsEnabled;\n } else {\n p.notificationsEnabled = bool ? true : false;\n }\n return this;\n },\n noNotifications: function noNotifications(callback) {\n this.notifications(false);\n callback();\n this.notifications(true);\n },\n batching: function batching() {\n return this._private.batchCount > 0;\n },\n startBatch: function startBatch() {\n var _p = this._private;\n if (_p.batchCount == null) {\n _p.batchCount = 0;\n }\n if (_p.batchCount === 0) {\n _p.batchStyleEles = this.collection();\n _p.batchNotifications = {};\n }\n _p.batchCount++;\n return this;\n },\n endBatch: function endBatch() {\n var _p = this._private;\n if (_p.batchCount === 0) {\n return this;\n }\n _p.batchCount--;\n if (_p.batchCount === 0) {\n // update style for dirty eles\n _p.batchStyleEles.updateStyle();\n var renderer = this.renderer();\n\n // notify the renderer of queued eles and event types\n Object.keys(_p.batchNotifications).forEach(function (eventName) {\n var eles = _p.batchNotifications[eventName];\n if (eles.empty()) {\n renderer.notify(eventName);\n } else {\n renderer.notify(eventName, eles);\n }\n });\n }\n return this;\n },\n batch: function batch(callback) {\n this.startBatch();\n callback();\n this.endBatch();\n return this;\n },\n // for backwards compatibility\n batchData: function batchData(map) {\n var cy = this;\n return this.batch(function () {\n var ids = Object.keys(map);\n for (var i = 0; i < ids.length; i++) {\n var id = ids[i];\n var data = map[id];\n var ele = cy.getElementById(id);\n ele.data(data);\n }\n });\n }\n};\n\nvar rendererDefaults = defaults$g({\n hideEdgesOnViewport: false,\n textureOnViewport: false,\n motionBlur: false,\n motionBlurOpacity: 0.05,\n pixelRatio: undefined,\n desktopTapThreshold: 4,\n touchTapThreshold: 8,\n wheelSensitivity: 1,\n debug: false,\n showFps: false\n});\nvar corefn$4 = {\n renderTo: function renderTo(context, zoom, pan, pxRatio) {\n var r = this._private.renderer;\n r.renderTo(context, zoom, pan, pxRatio);\n return this;\n },\n renderer: function renderer() {\n return this._private.renderer;\n },\n forceRender: function forceRender() {\n this.notify('draw');\n return this;\n },\n resize: function resize() {\n this.invalidateSize();\n this.emitAndNotify('resize');\n return this;\n },\n initRenderer: function initRenderer(options) {\n var cy = this;\n var RendererProto = cy.extension('renderer', options.name);\n if (RendererProto == null) {\n error(\"Can not initialise: No such renderer `\".concat(options.name, \"` found. Did you forget to import it and `cytoscape.use()` it?\"));\n return;\n }\n if (options.wheelSensitivity !== undefined) {\n warn(\"You have set a custom wheel sensitivity. This will make your app zoom unnaturally when using mainstream mice. You should change this value from the default only if you can guarantee that all your users will use the same hardware and OS configuration as your current machine.\");\n }\n var rOpts = rendererDefaults(options);\n rOpts.cy = cy;\n cy._private.renderer = new RendererProto(rOpts);\n this.notify('init');\n },\n destroyRenderer: function destroyRenderer() {\n var cy = this;\n cy.notify('destroy'); // destroy the renderer\n\n var domEle = cy.container();\n if (domEle) {\n domEle._cyreg = null;\n while (domEle.childNodes.length > 0) {\n domEle.removeChild(domEle.childNodes[0]);\n }\n }\n cy._private.renderer = null; // to be extra safe, remove the ref\n cy.mutableElements().forEach(function (ele) {\n var _p = ele._private;\n _p.rscratch = {};\n _p.rstyle = {};\n _p.animation.current = [];\n _p.animation.queue = [];\n });\n },\n onRender: function onRender(fn) {\n return this.on('render', fn);\n },\n offRender: function offRender(fn) {\n return this.off('render', fn);\n }\n};\ncorefn$4.invalidateDimensions = corefn$4.resize;\n\nvar corefn$3 = {\n // get a collection\n // - empty collection on no args\n // - collection of elements in the graph on selector arg\n // - guarantee a returned collection when elements or collection specified\n collection: function collection(eles, opts) {\n if (string(eles)) {\n return this.$(eles);\n } else if (elementOrCollection(eles)) {\n return eles.collection();\n } else if (array(eles)) {\n if (!opts) {\n opts = {};\n }\n return new Collection(this, eles, opts.unique, opts.removed);\n }\n return new Collection(this);\n },\n nodes: function nodes(selector) {\n var nodes = this.$(function (ele) {\n return ele.isNode();\n });\n if (selector) {\n return nodes.filter(selector);\n }\n return nodes;\n },\n edges: function edges(selector) {\n var edges = this.$(function (ele) {\n return ele.isEdge();\n });\n if (selector) {\n return edges.filter(selector);\n }\n return edges;\n },\n // search the graph like jQuery\n $: function $(selector) {\n var eles = this._private.elements;\n if (selector) {\n return eles.filter(selector);\n } else {\n return eles.spawnSelf();\n }\n },\n mutableElements: function mutableElements() {\n return this._private.elements;\n }\n};\n\n// aliases\ncorefn$3.elements = corefn$3.filter = corefn$3.$;\n\nvar styfn$8 = {};\n\n// keys for style blocks, e.g. ttfftt\nvar TRUE = 't';\nvar FALSE = 'f';\n\n// (potentially expensive calculation)\n// apply the style to the element based on\n// - its bypass\n// - what selectors match it\nstyfn$8.apply = function (eles) {\n var self = this;\n var _p = self._private;\n var cy = _p.cy;\n var updatedEles = cy.collection();\n for (var ie = 0; ie < eles.length; ie++) {\n var ele = eles[ie];\n var cxtMeta = self.getContextMeta(ele);\n if (cxtMeta.empty) {\n continue;\n }\n var cxtStyle = self.getContextStyle(cxtMeta);\n var app = self.applyContextStyle(cxtMeta, cxtStyle, ele);\n if (ele._private.appliedInitStyle) {\n self.updateTransitions(ele, app.diffProps);\n } else {\n ele._private.appliedInitStyle = true;\n }\n var hintsDiff = self.updateStyleHints(ele);\n if (hintsDiff) {\n updatedEles.push(ele);\n }\n } // for elements\n\n return updatedEles;\n};\nstyfn$8.getPropertiesDiff = function (oldCxtKey, newCxtKey) {\n var self = this;\n var cache = self._private.propDiffs = self._private.propDiffs || {};\n var dualCxtKey = oldCxtKey + '-' + newCxtKey;\n var cachedVal = cache[dualCxtKey];\n if (cachedVal) {\n return cachedVal;\n }\n var diffProps = [];\n var addedProp = {};\n for (var i = 0; i < self.length; i++) {\n var cxt = self[i];\n var oldHasCxt = oldCxtKey[i] === TRUE;\n var newHasCxt = newCxtKey[i] === TRUE;\n var cxtHasDiffed = oldHasCxt !== newHasCxt;\n var cxtHasMappedProps = cxt.mappedProperties.length > 0;\n if (cxtHasDiffed || newHasCxt && cxtHasMappedProps) {\n var props = void 0;\n if (cxtHasDiffed && cxtHasMappedProps) {\n props = cxt.properties; // suffices b/c mappedProperties is a subset of properties\n } else if (cxtHasDiffed) {\n props = cxt.properties; // need to check them all\n } else if (cxtHasMappedProps) {\n props = cxt.mappedProperties; // only need to check mapped\n }\n\n for (var j = 0; j < props.length; j++) {\n var prop = props[j];\n var name = prop.name;\n\n // if a later context overrides this property, then the fact that this context has switched/diffed doesn't matter\n // (semi expensive check since it makes this function O(n^2) on context length, but worth it since overall result\n // is cached)\n var laterCxtOverrides = false;\n for (var k = i + 1; k < self.length; k++) {\n var laterCxt = self[k];\n var hasLaterCxt = newCxtKey[k] === TRUE;\n if (!hasLaterCxt) {\n continue;\n } // can't override unless the context is active\n\n laterCxtOverrides = laterCxt.properties[prop.name] != null;\n if (laterCxtOverrides) {\n break;\n } // exit early as long as one later context overrides\n }\n\n if (!addedProp[name] && !laterCxtOverrides) {\n addedProp[name] = true;\n diffProps.push(name);\n }\n } // for props\n } // if\n } // for contexts\n\n cache[dualCxtKey] = diffProps;\n return diffProps;\n};\nstyfn$8.getContextMeta = function (ele) {\n var self = this;\n var cxtKey = '';\n var diffProps;\n var prevKey = ele._private.styleCxtKey || '';\n\n // get the cxt key\n for (var i = 0; i < self.length; i++) {\n var context = self[i];\n var contextSelectorMatches = context.selector && context.selector.matches(ele); // NB: context.selector may be null for 'core'\n\n if (contextSelectorMatches) {\n cxtKey += TRUE;\n } else {\n cxtKey += FALSE;\n }\n } // for context\n\n diffProps = self.getPropertiesDiff(prevKey, cxtKey);\n ele._private.styleCxtKey = cxtKey;\n return {\n key: cxtKey,\n diffPropNames: diffProps,\n empty: diffProps.length === 0\n };\n};\n\n// gets a computed ele style object based on matched contexts\nstyfn$8.getContextStyle = function (cxtMeta) {\n var cxtKey = cxtMeta.key;\n var self = this;\n var cxtStyles = this._private.contextStyles = this._private.contextStyles || {};\n\n // if already computed style, returned cached copy\n if (cxtStyles[cxtKey]) {\n return cxtStyles[cxtKey];\n }\n var style = {\n _private: {\n key: cxtKey\n }\n };\n for (var i = 0; i < self.length; i++) {\n var cxt = self[i];\n var hasCxt = cxtKey[i] === TRUE;\n if (!hasCxt) {\n continue;\n }\n for (var j = 0; j < cxt.properties.length; j++) {\n var prop = cxt.properties[j];\n style[prop.name] = prop;\n }\n }\n cxtStyles[cxtKey] = style;\n return style;\n};\nstyfn$8.applyContextStyle = function (cxtMeta, cxtStyle, ele) {\n var self = this;\n var diffProps = cxtMeta.diffPropNames;\n var retDiffProps = {};\n var types = self.types;\n for (var i = 0; i < diffProps.length; i++) {\n var diffPropName = diffProps[i];\n var cxtProp = cxtStyle[diffPropName];\n var eleProp = ele.pstyle(diffPropName);\n if (!cxtProp) {\n // no context prop means delete\n if (!eleProp) {\n continue; // no existing prop means nothing needs to be removed\n // nb affects initial application on mapped values like control-point-distances\n } else if (eleProp.bypass) {\n cxtProp = {\n name: diffPropName,\n deleteBypassed: true\n };\n } else {\n cxtProp = {\n name: diffPropName,\n \"delete\": true\n };\n }\n }\n\n // save cycles when the context prop doesn't need to be applied\n if (eleProp === cxtProp) {\n continue;\n }\n\n // save cycles when a mapped context prop doesn't need to be applied\n if (cxtProp.mapped === types.fn // context prop is function mapper\n && eleProp != null // some props can be null even by default (e.g. a prop that overrides another one)\n && eleProp.mapping != null // ele prop is a concrete value from from a mapper\n && eleProp.mapping.value === cxtProp.value // the current prop on the ele is a flat prop value for the function mapper\n ) {\n // NB don't write to cxtProp, as it's shared among eles (stored in stylesheet)\n var mapping = eleProp.mapping; // can write to mapping, as it's a per-ele copy\n var fnValue = mapping.fnValue = cxtProp.value(ele); // temporarily cache the value in case of a miss\n\n if (fnValue === mapping.prevFnValue) {\n continue;\n }\n }\n var retDiffProp = retDiffProps[diffPropName] = {\n prev: eleProp\n };\n self.applyParsedProperty(ele, cxtProp);\n retDiffProp.next = ele.pstyle(diffPropName);\n if (retDiffProp.next && retDiffProp.next.bypass) {\n retDiffProp.next = retDiffProp.next.bypassed;\n }\n }\n return {\n diffProps: retDiffProps\n };\n};\nstyfn$8.updateStyleHints = function (ele) {\n var _p = ele._private;\n var self = this;\n var propNames = self.propertyGroupNames;\n var propGrKeys = self.propertyGroupKeys;\n var propHash = function propHash(ele, propNames, seedKey) {\n return self.getPropertiesHash(ele, propNames, seedKey);\n };\n var oldStyleKey = _p.styleKey;\n if (ele.removed()) {\n return false;\n }\n var isNode = _p.group === 'nodes';\n\n // get the style key hashes per prop group\n // but lazily -- only use non-default prop values to reduce the number of hashes\n //\n\n var overriddenStyles = ele._private.style;\n propNames = Object.keys(overriddenStyles);\n for (var i = 0; i < propGrKeys.length; i++) {\n var grKey = propGrKeys[i];\n _p.styleKeys[grKey] = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT];\n }\n var updateGrKey1 = function updateGrKey1(val, grKey) {\n return _p.styleKeys[grKey][0] = hashInt(val, _p.styleKeys[grKey][0]);\n };\n var updateGrKey2 = function updateGrKey2(val, grKey) {\n return _p.styleKeys[grKey][1] = hashIntAlt(val, _p.styleKeys[grKey][1]);\n };\n var updateGrKey = function updateGrKey(val, grKey) {\n updateGrKey1(val, grKey);\n updateGrKey2(val, grKey);\n };\n var updateGrKeyWStr = function updateGrKeyWStr(strVal, grKey) {\n for (var j = 0; j < strVal.length; j++) {\n var ch = strVal.charCodeAt(j);\n updateGrKey1(ch, grKey);\n updateGrKey2(ch, grKey);\n }\n };\n\n // - hashing works on 32 bit ints b/c we use bitwise ops\n // - small numbers get cut off (e.g. 0.123 is seen as 0 by the hashing function)\n // - raise up small numbers so more significant digits are seen by hashing\n // - make small numbers larger than a normal value to avoid collisions\n // - works in practice and it's relatively cheap\n var N = 2000000000;\n var cleanNum = function cleanNum(val) {\n return -128 < val && val < 128 && Math.floor(val) !== val ? N - (val * 1024 | 0) : val;\n };\n for (var _i = 0; _i < propNames.length; _i++) {\n var name = propNames[_i];\n var parsedProp = overriddenStyles[name];\n if (parsedProp == null) {\n continue;\n }\n var propInfo = this.properties[name];\n var type = propInfo.type;\n var _grKey = propInfo.groupKey;\n var normalizedNumberVal = void 0;\n if (propInfo.hashOverride != null) {\n normalizedNumberVal = propInfo.hashOverride(ele, parsedProp);\n } else if (parsedProp.pfValue != null) {\n normalizedNumberVal = parsedProp.pfValue;\n }\n\n // might not be a number if it allows enums\n var numberVal = propInfo.enums == null ? parsedProp.value : null;\n var haveNormNum = normalizedNumberVal != null;\n var haveUnitedNum = numberVal != null;\n var haveNum = haveNormNum || haveUnitedNum;\n var units = parsedProp.units;\n\n // numbers are cheaper to hash than strings\n // 1 hash op vs n hash ops (for length n string)\n if (type.number && haveNum && !type.multiple) {\n var v = haveNormNum ? normalizedNumberVal : numberVal;\n updateGrKey(cleanNum(v), _grKey);\n if (!haveNormNum && units != null) {\n updateGrKeyWStr(units, _grKey);\n }\n } else {\n updateGrKeyWStr(parsedProp.strValue, _grKey);\n }\n }\n\n // overall style key\n //\n\n var hash = [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT];\n for (var _i2 = 0; _i2 < propGrKeys.length; _i2++) {\n var _grKey2 = propGrKeys[_i2];\n var grHash = _p.styleKeys[_grKey2];\n hash[0] = hashInt(grHash[0], hash[0]);\n hash[1] = hashIntAlt(grHash[1], hash[1]);\n }\n _p.styleKey = combineHashes(hash[0], hash[1]);\n\n // label dims\n //\n\n var sk = _p.styleKeys;\n _p.labelDimsKey = combineHashesArray(sk.labelDimensions);\n var labelKeys = propHash(ele, ['label'], sk.labelDimensions);\n _p.labelKey = combineHashesArray(labelKeys);\n _p.labelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, labelKeys));\n if (!isNode) {\n var sourceLabelKeys = propHash(ele, ['source-label'], sk.labelDimensions);\n _p.sourceLabelKey = combineHashesArray(sourceLabelKeys);\n _p.sourceLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, sourceLabelKeys));\n var targetLabelKeys = propHash(ele, ['target-label'], sk.labelDimensions);\n _p.targetLabelKey = combineHashesArray(targetLabelKeys);\n _p.targetLabelStyleKey = combineHashesArray(hashArrays(sk.commonLabel, targetLabelKeys));\n }\n\n // node\n //\n\n if (isNode) {\n var _p$styleKeys = _p.styleKeys,\n nodeBody = _p$styleKeys.nodeBody,\n nodeBorder = _p$styleKeys.nodeBorder,\n nodeOutline = _p$styleKeys.nodeOutline,\n backgroundImage = _p$styleKeys.backgroundImage,\n compound = _p$styleKeys.compound,\n pie = _p$styleKeys.pie;\n var nodeKeys = [nodeBody, nodeBorder, nodeOutline, backgroundImage, compound, pie].filter(function (k) {\n return k != null;\n }).reduce(hashArrays, [DEFAULT_HASH_SEED, DEFAULT_HASH_SEED_ALT]);\n _p.nodeKey = combineHashesArray(nodeKeys);\n _p.hasPie = pie != null && pie[0] !== DEFAULT_HASH_SEED && pie[1] !== DEFAULT_HASH_SEED_ALT;\n }\n return oldStyleKey !== _p.styleKey;\n};\nstyfn$8.clearStyleHints = function (ele) {\n var _p = ele._private;\n _p.styleCxtKey = '';\n _p.styleKeys = {};\n _p.styleKey = null;\n _p.labelKey = null;\n _p.labelStyleKey = null;\n _p.sourceLabelKey = null;\n _p.sourceLabelStyleKey = null;\n _p.targetLabelKey = null;\n _p.targetLabelStyleKey = null;\n _p.nodeKey = null;\n _p.hasPie = null;\n};\n\n// apply a property to the style (for internal use)\n// returns whether application was successful\n//\n// now, this function flattens the property, and here's how:\n//\n// for parsedProp:{ bypass: true, deleteBypass: true }\n// no property is generated, instead the bypass property in the\n// element's style is replaced by what's pointed to by the `bypassed`\n// field in the bypass property (i.e. restoring the property the\n// bypass was overriding)\n//\n// for parsedProp:{ mapped: truthy }\n// the generated flattenedProp:{ mapping: prop }\n//\n// for parsedProp:{ bypass: true }\n// the generated flattenedProp:{ bypassed: parsedProp }\nstyfn$8.applyParsedProperty = function (ele, parsedProp) {\n var self = this;\n var prop = parsedProp;\n var style = ele._private.style;\n var flatProp;\n var types = self.types;\n var type = self.properties[prop.name].type;\n var propIsBypass = prop.bypass;\n var origProp = style[prop.name];\n var origPropIsBypass = origProp && origProp.bypass;\n var _p = ele._private;\n var flatPropMapping = 'mapping';\n var getVal = function getVal(p) {\n if (p == null) {\n return null;\n } else if (p.pfValue != null) {\n return p.pfValue;\n } else {\n return p.value;\n }\n };\n var checkTriggers = function checkTriggers() {\n var fromVal = getVal(origProp);\n var toVal = getVal(prop);\n self.checkTriggers(ele, prop.name, fromVal, toVal);\n };\n\n // edge sanity checks to prevent the client from making serious mistakes\n if (parsedProp.name === 'curve-style' && ele.isEdge() && (\n // loops must be bundled beziers\n parsedProp.value !== 'bezier' && ele.isLoop() ||\n // edges connected to compound nodes can not be haystacks\n parsedProp.value === 'haystack' && (ele.source().isParent() || ele.target().isParent()))) {\n prop = parsedProp = this.parse(parsedProp.name, 'bezier', propIsBypass);\n }\n if (prop[\"delete\"]) {\n // delete the property and use the default value on falsey value\n style[prop.name] = undefined;\n checkTriggers();\n return true;\n }\n if (prop.deleteBypassed) {\n // delete the property that the\n if (!origProp) {\n checkTriggers();\n return true; // can't delete if no prop\n } else if (origProp.bypass) {\n // delete bypassed\n origProp.bypassed = undefined;\n checkTriggers();\n return true;\n } else {\n return false; // we're unsuccessful deleting the bypassed\n }\n }\n\n // check if we need to delete the current bypass\n if (prop.deleteBypass) {\n // then this property is just here to indicate we need to delete\n if (!origProp) {\n checkTriggers();\n return true; // property is already not defined\n } else if (origProp.bypass) {\n // then replace the bypass property with the original\n // because the bypassed property was already applied (and therefore parsed), we can just replace it (no reapplying necessary)\n style[prop.name] = origProp.bypassed;\n checkTriggers();\n return true;\n } else {\n return false; // we're unsuccessful deleting the bypass\n }\n }\n\n var printMappingErr = function printMappingErr() {\n warn('Do not assign mappings to elements without corresponding data (i.e. ele `' + ele.id() + '` has no mapping for property `' + prop.name + '` with data field `' + prop.field + '`); try a `[' + prop.field + ']` selector to limit scope to elements with `' + prop.field + '` defined');\n };\n\n // put the property in the style objects\n switch (prop.mapped) {\n // flatten the property if mapped\n case types.mapData:\n {\n // flatten the field (e.g. data.foo.bar)\n var fields = prop.field.split('.');\n var fieldVal = _p.data;\n for (var i = 0; i < fields.length && fieldVal; i++) {\n var field = fields[i];\n fieldVal = fieldVal[field];\n }\n if (fieldVal == null) {\n printMappingErr();\n return false;\n }\n var percent;\n if (!number$1(fieldVal)) {\n // then don't apply and fall back on the existing style\n warn('Do not use continuous mappers without specifying numeric data (i.e. `' + prop.field + ': ' + fieldVal + '` for `' + ele.id() + '` is non-numeric)');\n return false;\n } else {\n var fieldWidth = prop.fieldMax - prop.fieldMin;\n if (fieldWidth === 0) {\n // safety check -- not strictly necessary as no props of zero range should be passed here\n percent = 0;\n } else {\n percent = (fieldVal - prop.fieldMin) / fieldWidth;\n }\n }\n\n // make sure to bound percent value\n if (percent < 0) {\n percent = 0;\n } else if (percent > 1) {\n percent = 1;\n }\n if (type.color) {\n var r1 = prop.valueMin[0];\n var r2 = prop.valueMax[0];\n var g1 = prop.valueMin[1];\n var g2 = prop.valueMax[1];\n var b1 = prop.valueMin[2];\n var b2 = prop.valueMax[2];\n var a1 = prop.valueMin[3] == null ? 1 : prop.valueMin[3];\n var a2 = prop.valueMax[3] == null ? 1 : prop.valueMax[3];\n var clr = [Math.round(r1 + (r2 - r1) * percent), Math.round(g1 + (g2 - g1) * percent), Math.round(b1 + (b2 - b1) * percent), Math.round(a1 + (a2 - a1) * percent)];\n flatProp = {\n // colours are simple, so just create the flat property instead of expensive string parsing\n bypass: prop.bypass,\n // we're a bypass if the mapping property is a bypass\n name: prop.name,\n value: clr,\n strValue: 'rgb(' + clr[0] + ', ' + clr[1] + ', ' + clr[2] + ')'\n };\n } else if (type.number) {\n var calcValue = prop.valueMin + (prop.valueMax - prop.valueMin) * percent;\n flatProp = this.parse(prop.name, calcValue, prop.bypass, flatPropMapping);\n } else {\n return false; // can only map to colours and numbers\n }\n\n if (!flatProp) {\n // if we can't flatten the property, then don't apply the property and fall back on the existing style\n printMappingErr();\n return false;\n }\n flatProp.mapping = prop; // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n }\n\n // direct mapping\n case types.data:\n {\n // flatten the field (e.g. data.foo.bar)\n var _fields = prop.field.split('.');\n var _fieldVal = _p.data;\n for (var _i3 = 0; _i3 < _fields.length && _fieldVal; _i3++) {\n var _field = _fields[_i3];\n _fieldVal = _fieldVal[_field];\n }\n if (_fieldVal != null) {\n flatProp = this.parse(prop.name, _fieldVal, prop.bypass, flatPropMapping);\n }\n if (!flatProp) {\n // if we can't flatten the property, then don't apply and fall back on the existing style\n printMappingErr();\n return false;\n }\n flatProp.mapping = prop; // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n }\n case types.fn:\n {\n var fn = prop.value;\n var fnRetVal = prop.fnValue != null ? prop.fnValue : fn(ele); // check for cached value before calling function\n\n prop.prevFnValue = fnRetVal;\n if (fnRetVal == null) {\n warn('Custom function mappers may not return null (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is null)');\n return false;\n }\n flatProp = this.parse(prop.name, fnRetVal, prop.bypass, flatPropMapping);\n if (!flatProp) {\n warn('Custom function mappers may not return invalid values for the property type (i.e. `' + prop.name + '` for ele `' + ele.id() + '` is invalid)');\n return false;\n }\n flatProp.mapping = copy(prop); // keep a reference to the mapping\n prop = flatProp; // the flattened (mapped) property is the one we want\n\n break;\n }\n case undefined:\n break;\n // just set the property\n\n default:\n return false;\n // not a valid mapping\n }\n\n // if the property is a bypass property, then link the resultant property to the original one\n if (propIsBypass) {\n if (origPropIsBypass) {\n // then this bypass overrides the existing one\n prop.bypassed = origProp.bypassed; // steal bypassed prop from old bypass\n } else {\n // then link the orig prop to the new bypass\n prop.bypassed = origProp;\n }\n style[prop.name] = prop; // and set\n } else {\n // prop is not bypass\n if (origPropIsBypass) {\n // then keep the orig prop (since it's a bypass) and link to the new prop\n origProp.bypassed = prop;\n } else {\n // then just replace the old prop with the new one\n style[prop.name] = prop;\n }\n }\n checkTriggers();\n return true;\n};\nstyfn$8.cleanElements = function (eles, keepBypasses) {\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n this.clearStyleHints(ele);\n ele.dirtyCompoundBoundsCache();\n ele.dirtyBoundingBoxCache();\n if (!keepBypasses) {\n ele._private.style = {};\n } else {\n var style = ele._private.style;\n var propNames = Object.keys(style);\n for (var j = 0; j < propNames.length; j++) {\n var propName = propNames[j];\n var eleProp = style[propName];\n if (eleProp != null) {\n if (eleProp.bypass) {\n eleProp.bypassed = null;\n } else {\n style[propName] = null;\n }\n }\n }\n }\n }\n};\n\n// updates the visual style for all elements (useful for manual style modification after init)\nstyfn$8.update = function () {\n var cy = this._private.cy;\n var eles = cy.mutableElements();\n eles.updateStyle();\n};\n\n// diffProps : { name => { prev, next } }\nstyfn$8.updateTransitions = function (ele, diffProps) {\n var self = this;\n var _p = ele._private;\n var props = ele.pstyle('transition-property').value;\n var duration = ele.pstyle('transition-duration').pfValue;\n var delay = ele.pstyle('transition-delay').pfValue;\n if (props.length > 0 && duration > 0) {\n var style = {};\n\n // build up the style to animate towards\n var anyPrev = false;\n for (var i = 0; i < props.length; i++) {\n var prop = props[i];\n var styProp = ele.pstyle(prop);\n var diffProp = diffProps[prop];\n if (!diffProp) {\n continue;\n }\n var prevProp = diffProp.prev;\n var fromProp = prevProp;\n var toProp = diffProp.next != null ? diffProp.next : styProp;\n var diff = false;\n var initVal = void 0;\n var initDt = 0.000001; // delta time % value for initVal (allows animating out of init zero opacity)\n\n if (!fromProp) {\n continue;\n }\n\n // consider px values\n if (number$1(fromProp.pfValue) && number$1(toProp.pfValue)) {\n diff = toProp.pfValue - fromProp.pfValue; // nonzero is truthy\n initVal = fromProp.pfValue + initDt * diff;\n\n // consider numerical values\n } else if (number$1(fromProp.value) && number$1(toProp.value)) {\n diff = toProp.value - fromProp.value; // nonzero is truthy\n initVal = fromProp.value + initDt * diff;\n\n // consider colour values\n } else if (array(fromProp.value) && array(toProp.value)) {\n diff = fromProp.value[0] !== toProp.value[0] || fromProp.value[1] !== toProp.value[1] || fromProp.value[2] !== toProp.value[2];\n initVal = fromProp.strValue;\n }\n\n // the previous value is good for an animation only if it's different\n if (diff) {\n style[prop] = toProp.strValue; // to val\n this.applyBypass(ele, prop, initVal); // from val\n anyPrev = true;\n }\n } // end if props allow ani\n\n // can't transition if there's nothing previous to transition from\n if (!anyPrev) {\n return;\n }\n _p.transitioning = true;\n new Promise$1(function (resolve) {\n if (delay > 0) {\n ele.delayAnimation(delay).play().promise().then(resolve);\n } else {\n resolve();\n }\n }).then(function () {\n return ele.animation({\n style: style,\n duration: duration,\n easing: ele.pstyle('transition-timing-function').value,\n queue: false\n }).play().promise();\n }).then(function () {\n // if( !isBypass ){\n self.removeBypasses(ele, props);\n ele.emitAndNotify('style');\n // }\n\n _p.transitioning = false;\n });\n } else if (_p.transitioning) {\n this.removeBypasses(ele, props);\n ele.emitAndNotify('style');\n _p.transitioning = false;\n }\n};\nstyfn$8.checkTrigger = function (ele, name, fromValue, toValue, getTrigger, onTrigger) {\n var prop = this.properties[name];\n var triggerCheck = getTrigger(prop);\n if (triggerCheck != null && triggerCheck(fromValue, toValue)) {\n onTrigger(prop);\n }\n};\nstyfn$8.checkZOrderTrigger = function (ele, name, fromValue, toValue) {\n var _this = this;\n this.checkTrigger(ele, name, fromValue, toValue, function (prop) {\n return prop.triggersZOrder;\n }, function () {\n _this._private.cy.notify('zorder', ele);\n });\n};\nstyfn$8.checkBoundsTrigger = function (ele, name, fromValue, toValue) {\n this.checkTrigger(ele, name, fromValue, toValue, function (prop) {\n return prop.triggersBounds;\n }, function (prop) {\n ele.dirtyCompoundBoundsCache();\n ele.dirtyBoundingBoxCache();\n\n // if the prop change makes the bb of pll bezier edges invalid,\n // then dirty the pll edge bb cache as well\n if (\n // only for beziers -- so performance of other edges isn't affected\n prop.triggersBoundsOfParallelBeziers && name === 'curve-style' && (fromValue === 'bezier' || toValue === 'bezier')) {\n ele.parallelEdges().forEach(function (pllEdge) {\n if (pllEdge.isBundledBezier()) {\n pllEdge.dirtyBoundingBoxCache();\n }\n });\n }\n if (prop.triggersBoundsOfConnectedEdges && name === 'display' && (fromValue === 'none' || toValue === 'none')) {\n ele.connectedEdges().forEach(function (edge) {\n edge.dirtyBoundingBoxCache();\n });\n }\n });\n};\nstyfn$8.checkTriggers = function (ele, name, fromValue, toValue) {\n ele.dirtyStyleCache();\n this.checkZOrderTrigger(ele, name, fromValue, toValue);\n this.checkBoundsTrigger(ele, name, fromValue, toValue);\n};\n\nvar styfn$7 = {};\n\n// bypasses are applied to an existing style on an element, and just tacked on temporarily\n// returns true iff application was successful for at least 1 specified property\nstyfn$7.applyBypass = function (eles, name, value, updateTransitions) {\n var self = this;\n var props = [];\n var isBypass = true;\n\n // put all the properties (can specify one or many) in an array after parsing them\n if (name === '*' || name === '**') {\n // apply to all property names\n\n if (value !== undefined) {\n for (var i = 0; i < self.properties.length; i++) {\n var prop = self.properties[i];\n var _name = prop.name;\n var parsedProp = this.parse(_name, value, true);\n if (parsedProp) {\n props.push(parsedProp);\n }\n }\n }\n } else if (string(name)) {\n // then parse the single property\n var _parsedProp = this.parse(name, value, true);\n if (_parsedProp) {\n props.push(_parsedProp);\n }\n } else if (plainObject(name)) {\n // then parse each property\n var specifiedProps = name;\n updateTransitions = value;\n var names = Object.keys(specifiedProps);\n for (var _i = 0; _i < names.length; _i++) {\n var _name2 = names[_i];\n var _value = specifiedProps[_name2];\n if (_value === undefined) {\n // try camel case name too\n _value = specifiedProps[dash2camel(_name2)];\n }\n if (_value !== undefined) {\n var _parsedProp2 = this.parse(_name2, _value, true);\n if (_parsedProp2) {\n props.push(_parsedProp2);\n }\n }\n }\n } else {\n // can't do anything without well defined properties\n return false;\n }\n\n // we've failed if there are no valid properties\n if (props.length === 0) {\n return false;\n }\n\n // now, apply the bypass properties on the elements\n var ret = false; // return true if at least one succesful bypass applied\n for (var _i2 = 0; _i2 < eles.length; _i2++) {\n // for each ele\n var ele = eles[_i2];\n var diffProps = {};\n var diffProp = void 0;\n for (var j = 0; j < props.length; j++) {\n // for each prop\n var _prop = props[j];\n if (updateTransitions) {\n var prevProp = ele.pstyle(_prop.name);\n diffProp = diffProps[_prop.name] = {\n prev: prevProp\n };\n }\n ret = this.applyParsedProperty(ele, copy(_prop)) || ret;\n if (updateTransitions) {\n diffProp.next = ele.pstyle(_prop.name);\n }\n } // for props\n\n if (ret) {\n this.updateStyleHints(ele);\n }\n if (updateTransitions) {\n this.updateTransitions(ele, diffProps, isBypass);\n }\n } // for eles\n\n return ret;\n};\n\n// only useful in specific cases like animation\nstyfn$7.overrideBypass = function (eles, name, value) {\n name = camel2dash(name);\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var prop = ele._private.style[name];\n var type = this.properties[name].type;\n var isColor = type.color;\n var isMulti = type.mutiple;\n var oldValue = !prop ? null : prop.pfValue != null ? prop.pfValue : prop.value;\n if (!prop || !prop.bypass) {\n // need a bypass if one doesn't exist\n this.applyBypass(ele, name, value);\n } else {\n prop.value = value;\n if (prop.pfValue != null) {\n prop.pfValue = value;\n }\n if (isColor) {\n prop.strValue = 'rgb(' + value.join(',') + ')';\n } else if (isMulti) {\n prop.strValue = value.join(' ');\n } else {\n prop.strValue = '' + value;\n }\n this.updateStyleHints(ele);\n }\n this.checkTriggers(ele, name, oldValue, value);\n }\n};\nstyfn$7.removeAllBypasses = function (eles, updateTransitions) {\n return this.removeBypasses(eles, this.propertyNames, updateTransitions);\n};\nstyfn$7.removeBypasses = function (eles, props, updateTransitions) {\n var isBypass = true;\n for (var j = 0; j < eles.length; j++) {\n var ele = eles[j];\n var diffProps = {};\n for (var i = 0; i < props.length; i++) {\n var name = props[i];\n var prop = this.properties[name];\n var prevProp = ele.pstyle(prop.name);\n if (!prevProp || !prevProp.bypass) {\n // if a bypass doesn't exist for the prop, nothing needs to be removed\n continue;\n }\n var value = ''; // empty => remove bypass\n var parsedProp = this.parse(name, value, true);\n var diffProp = diffProps[prop.name] = {\n prev: prevProp\n };\n this.applyParsedProperty(ele, parsedProp);\n diffProp.next = ele.pstyle(prop.name);\n } // for props\n\n this.updateStyleHints(ele);\n if (updateTransitions) {\n this.updateTransitions(ele, diffProps, isBypass);\n }\n } // for eles\n};\n\nvar styfn$6 = {};\n\n// gets what an em size corresponds to in pixels relative to a dom element\nstyfn$6.getEmSizeInPixels = function () {\n var px = this.containerCss('font-size');\n if (px != null) {\n return parseFloat(px);\n } else {\n return 1; // for headless\n }\n};\n\n// gets css property from the core container\nstyfn$6.containerCss = function (propName) {\n var cy = this._private.cy;\n var domElement = cy.container();\n var containerWindow = cy.window();\n if (containerWindow && domElement && containerWindow.getComputedStyle) {\n return containerWindow.getComputedStyle(domElement).getPropertyValue(propName);\n }\n};\n\nvar styfn$5 = {};\n\n// gets the rendered style for an element\nstyfn$5.getRenderedStyle = function (ele, prop) {\n if (prop) {\n return this.getStylePropertyValue(ele, prop, true);\n } else {\n return this.getRawStyle(ele, true);\n }\n};\n\n// gets the raw style for an element\nstyfn$5.getRawStyle = function (ele, isRenderedVal) {\n var self = this;\n ele = ele[0]; // insure it's an element\n\n if (ele) {\n var rstyle = {};\n for (var i = 0; i < self.properties.length; i++) {\n var prop = self.properties[i];\n var val = self.getStylePropertyValue(ele, prop.name, isRenderedVal);\n if (val != null) {\n rstyle[prop.name] = val;\n rstyle[dash2camel(prop.name)] = val;\n }\n }\n return rstyle;\n }\n};\nstyfn$5.getIndexedStyle = function (ele, property, subproperty, index) {\n var pstyle = ele.pstyle(property)[subproperty][index];\n return pstyle != null ? pstyle : ele.cy().style().getDefaultProperty(property)[subproperty][0];\n};\nstyfn$5.getStylePropertyValue = function (ele, propName, isRenderedVal) {\n var self = this;\n ele = ele[0]; // insure it's an element\n\n if (ele) {\n var prop = self.properties[propName];\n if (prop.alias) {\n prop = prop.pointsTo;\n }\n var type = prop.type;\n var styleProp = ele.pstyle(prop.name);\n if (styleProp) {\n var value = styleProp.value,\n units = styleProp.units,\n strValue = styleProp.strValue;\n if (isRenderedVal && type.number && value != null && number$1(value)) {\n var zoom = ele.cy().zoom();\n var getRenderedValue = function getRenderedValue(val) {\n return val * zoom;\n };\n var getValueStringWithUnits = function getValueStringWithUnits(val, units) {\n return getRenderedValue(val) + units;\n };\n var isArrayValue = array(value);\n var haveUnits = isArrayValue ? units.every(function (u) {\n return u != null;\n }) : units != null;\n if (haveUnits) {\n if (isArrayValue) {\n return value.map(function (v, i) {\n return getValueStringWithUnits(v, units[i]);\n }).join(' ');\n } else {\n return getValueStringWithUnits(value, units);\n }\n } else {\n if (isArrayValue) {\n return value.map(function (v) {\n return string(v) ? v : '' + getRenderedValue(v);\n }).join(' ');\n } else {\n return '' + getRenderedValue(value);\n }\n }\n } else if (strValue != null) {\n return strValue;\n }\n }\n return null;\n }\n};\nstyfn$5.getAnimationStartStyle = function (ele, aniProps) {\n var rstyle = {};\n for (var i = 0; i < aniProps.length; i++) {\n var aniProp = aniProps[i];\n var name = aniProp.name;\n var styleProp = ele.pstyle(name);\n if (styleProp !== undefined) {\n // then make a prop of it\n if (plainObject(styleProp)) {\n styleProp = this.parse(name, styleProp.strValue);\n } else {\n styleProp = this.parse(name, styleProp);\n }\n }\n if (styleProp) {\n rstyle[name] = styleProp;\n }\n }\n return rstyle;\n};\nstyfn$5.getPropsList = function (propsObj) {\n var self = this;\n var rstyle = [];\n var style = propsObj;\n var props = self.properties;\n if (style) {\n var names = Object.keys(style);\n for (var i = 0; i < names.length; i++) {\n var name = names[i];\n var val = style[name];\n var prop = props[name] || props[camel2dash(name)];\n var styleProp = this.parse(prop.name, val);\n if (styleProp) {\n rstyle.push(styleProp);\n }\n }\n }\n return rstyle;\n};\nstyfn$5.getNonDefaultPropertiesHash = function (ele, propNames, seed) {\n var hash = seed.slice();\n var name, val, strVal, chVal;\n var i, j;\n for (i = 0; i < propNames.length; i++) {\n name = propNames[i];\n val = ele.pstyle(name, false);\n if (val == null) {\n continue;\n } else if (val.pfValue != null) {\n hash[0] = hashInt(chVal, hash[0]);\n hash[1] = hashIntAlt(chVal, hash[1]);\n } else {\n strVal = val.strValue;\n for (j = 0; j < strVal.length; j++) {\n chVal = strVal.charCodeAt(j);\n hash[0] = hashInt(chVal, hash[0]);\n hash[1] = hashIntAlt(chVal, hash[1]);\n }\n }\n }\n return hash;\n};\nstyfn$5.getPropertiesHash = styfn$5.getNonDefaultPropertiesHash;\n\nvar styfn$4 = {};\nstyfn$4.appendFromJson = function (json) {\n var style = this;\n for (var i = 0; i < json.length; i++) {\n var context = json[i];\n var selector = context.selector;\n var props = context.style || context.css;\n var names = Object.keys(props);\n style.selector(selector); // apply selector\n\n for (var j = 0; j < names.length; j++) {\n var name = names[j];\n var value = props[name];\n style.css(name, value); // apply property\n }\n }\n\n return style;\n};\n\n// accessible cy.style() function\nstyfn$4.fromJson = function (json) {\n var style = this;\n style.resetToDefault();\n style.appendFromJson(json);\n return style;\n};\n\n// get json from cy.style() api\nstyfn$4.json = function () {\n var json = [];\n for (var i = this.defaultLength; i < this.length; i++) {\n var cxt = this[i];\n var selector = cxt.selector;\n var props = cxt.properties;\n var css = {};\n for (var j = 0; j < props.length; j++) {\n var prop = props[j];\n css[prop.name] = prop.strValue;\n }\n json.push({\n selector: !selector ? 'core' : selector.toString(),\n style: css\n });\n }\n return json;\n};\n\nvar styfn$3 = {};\nstyfn$3.appendFromString = function (string) {\n var self = this;\n var style = this;\n var remaining = '' + string;\n var selAndBlockStr;\n var blockRem;\n var propAndValStr;\n\n // remove comments from the style string\n remaining = remaining.replace(/[/][*](\\s|.)+?[*][/]/g, '');\n function removeSelAndBlockFromRemaining() {\n // remove the parsed selector and block from the remaining text to parse\n if (remaining.length > selAndBlockStr.length) {\n remaining = remaining.substr(selAndBlockStr.length);\n } else {\n remaining = '';\n }\n }\n function removePropAndValFromRem() {\n // remove the parsed property and value from the remaining block text to parse\n if (blockRem.length > propAndValStr.length) {\n blockRem = blockRem.substr(propAndValStr.length);\n } else {\n blockRem = '';\n }\n }\n for (;;) {\n var nothingLeftToParse = remaining.match(/^\\s*$/);\n if (nothingLeftToParse) {\n break;\n }\n var selAndBlock = remaining.match(/^\\s*((?:.|\\s)+?)\\s*\\{((?:.|\\s)+?)\\}/);\n if (!selAndBlock) {\n warn('Halting stylesheet parsing: String stylesheet contains more to parse but no selector and block found in: ' + remaining);\n break;\n }\n selAndBlockStr = selAndBlock[0];\n\n // parse the selector\n var selectorStr = selAndBlock[1];\n if (selectorStr !== 'core') {\n var selector = new Selector(selectorStr);\n if (selector.invalid) {\n warn('Skipping parsing of block: Invalid selector found in string stylesheet: ' + selectorStr);\n\n // skip this selector and block\n removeSelAndBlockFromRemaining();\n continue;\n }\n }\n\n // parse the block of properties and values\n var blockStr = selAndBlock[2];\n var invalidBlock = false;\n blockRem = blockStr;\n var props = [];\n for (;;) {\n var _nothingLeftToParse = blockRem.match(/^\\s*$/);\n if (_nothingLeftToParse) {\n break;\n }\n var propAndVal = blockRem.match(/^\\s*(.+?)\\s*:\\s*(.+?)(?:\\s*;|\\s*$)/);\n if (!propAndVal) {\n warn('Skipping parsing of block: Invalid formatting of style property and value definitions found in:' + blockStr);\n invalidBlock = true;\n break;\n }\n propAndValStr = propAndVal[0];\n var propStr = propAndVal[1];\n var valStr = propAndVal[2];\n var prop = self.properties[propStr];\n if (!prop) {\n warn('Skipping property: Invalid property name in: ' + propAndValStr);\n\n // skip this property in the block\n removePropAndValFromRem();\n continue;\n }\n var parsedProp = style.parse(propStr, valStr);\n if (!parsedProp) {\n warn('Skipping property: Invalid property definition in: ' + propAndValStr);\n\n // skip this property in the block\n removePropAndValFromRem();\n continue;\n }\n props.push({\n name: propStr,\n val: valStr\n });\n removePropAndValFromRem();\n }\n if (invalidBlock) {\n removeSelAndBlockFromRemaining();\n break;\n }\n\n // put the parsed block in the style\n style.selector(selectorStr);\n for (var i = 0; i < props.length; i++) {\n var _prop = props[i];\n style.css(_prop.name, _prop.val);\n }\n removeSelAndBlockFromRemaining();\n }\n return style;\n};\nstyfn$3.fromString = function (string) {\n var style = this;\n style.resetToDefault();\n style.appendFromString(string);\n return style;\n};\n\nvar styfn$2 = {};\n(function () {\n var number$1 = number;\n var rgba = rgbaNoBackRefs;\n var hsla = hslaNoBackRefs;\n var hex3$1 = hex3;\n var hex6$1 = hex6;\n var data = function data(prefix) {\n return '^' + prefix + '\\\\s*\\\\(\\\\s*([\\\\w\\\\.]+)\\\\s*\\\\)$';\n };\n var mapData = function mapData(prefix) {\n var mapArg = number$1 + '|\\\\w+|' + rgba + '|' + hsla + '|' + hex3$1 + '|' + hex6$1;\n return '^' + prefix + '\\\\s*\\\\(([\\\\w\\\\.]+)\\\\s*\\\\,\\\\s*(' + number$1 + ')\\\\s*\\\\,\\\\s*(' + number$1 + ')\\\\s*,\\\\s*(' + mapArg + ')\\\\s*\\\\,\\\\s*(' + mapArg + ')\\\\)$';\n };\n var urlRegexes = ['^url\\\\s*\\\\(\\\\s*[\\'\"]?(.+?)[\\'\"]?\\\\s*\\\\)$', '^(none)$', '^(.+)$'];\n\n // each visual style property has a type and needs to be validated according to it\n styfn$2.types = {\n time: {\n number: true,\n min: 0,\n units: 's|ms',\n implicitUnits: 'ms'\n },\n percent: {\n number: true,\n min: 0,\n max: 100,\n units: '%',\n implicitUnits: '%'\n },\n percentages: {\n number: true,\n min: 0,\n max: 100,\n units: '%',\n implicitUnits: '%',\n multiple: true\n },\n zeroOneNumber: {\n number: true,\n min: 0,\n max: 1,\n unitless: true\n },\n zeroOneNumbers: {\n number: true,\n min: 0,\n max: 1,\n unitless: true,\n multiple: true\n },\n nOneOneNumber: {\n number: true,\n min: -1,\n max: 1,\n unitless: true\n },\n nonNegativeInt: {\n number: true,\n min: 0,\n integer: true,\n unitless: true\n },\n nonNegativeNumber: {\n number: true,\n min: 0,\n unitless: true\n },\n position: {\n enums: ['parent', 'origin']\n },\n nodeSize: {\n number: true,\n min: 0,\n enums: ['label']\n },\n number: {\n number: true,\n unitless: true\n },\n numbers: {\n number: true,\n unitless: true,\n multiple: true\n },\n positiveNumber: {\n number: true,\n unitless: true,\n min: 0,\n strictMin: true\n },\n size: {\n number: true,\n min: 0\n },\n bidirectionalSize: {\n number: true\n },\n // allows negative\n bidirectionalSizeMaybePercent: {\n number: true,\n allowPercent: true\n },\n // allows negative\n bidirectionalSizes: {\n number: true,\n multiple: true\n },\n // allows negative\n sizeMaybePercent: {\n number: true,\n min: 0,\n allowPercent: true\n },\n axisDirection: {\n enums: ['horizontal', 'leftward', 'rightward', 'vertical', 'upward', 'downward', 'auto']\n },\n paddingRelativeTo: {\n enums: ['width', 'height', 'average', 'min', 'max']\n },\n bgWH: {\n number: true,\n min: 0,\n allowPercent: true,\n enums: ['auto'],\n multiple: true\n },\n bgPos: {\n number: true,\n allowPercent: true,\n multiple: true\n },\n bgRelativeTo: {\n enums: ['inner', 'include-padding'],\n multiple: true\n },\n bgRepeat: {\n enums: ['repeat', 'repeat-x', 'repeat-y', 'no-repeat'],\n multiple: true\n },\n bgFit: {\n enums: ['none', 'contain', 'cover'],\n multiple: true\n },\n bgCrossOrigin: {\n enums: ['anonymous', 'use-credentials', 'null'],\n multiple: true\n },\n bgClip: {\n enums: ['none', 'node'],\n multiple: true\n },\n bgContainment: {\n enums: ['inside', 'over'],\n multiple: true\n },\n color: {\n color: true\n },\n colors: {\n color: true,\n multiple: true\n },\n fill: {\n enums: ['solid', 'linear-gradient', 'radial-gradient']\n },\n bool: {\n enums: ['yes', 'no']\n },\n bools: {\n enums: ['yes', 'no'],\n multiple: true\n },\n lineStyle: {\n enums: ['solid', 'dotted', 'dashed']\n },\n lineCap: {\n enums: ['butt', 'round', 'square']\n },\n linePosition: {\n enums: ['center', 'inside', 'outside']\n },\n lineJoin: {\n enums: ['round', 'bevel', 'miter']\n },\n borderStyle: {\n enums: ['solid', 'dotted', 'dashed', 'double']\n },\n curveStyle: {\n enums: ['bezier', 'unbundled-bezier', 'haystack', 'segments', 'straight', 'straight-triangle', 'taxi', 'round-segments', 'round-taxi']\n },\n radiusType: {\n enums: ['arc-radius', 'influence-radius'],\n multiple: true\n },\n fontFamily: {\n regex: '^([\\\\w- \\\\\"]+(?:\\\\s*,\\\\s*[\\\\w- \\\\\"]+)*)$'\n },\n fontStyle: {\n enums: ['italic', 'normal', 'oblique']\n },\n fontWeight: {\n enums: ['normal', 'bold', 'bolder', 'lighter', '100', '200', '300', '400', '500', '600', '800', '900', 100, 200, 300, 400, 500, 600, 700, 800, 900]\n },\n textDecoration: {\n enums: ['none', 'underline', 'overline', 'line-through']\n },\n textTransform: {\n enums: ['none', 'uppercase', 'lowercase']\n },\n textWrap: {\n enums: ['none', 'wrap', 'ellipsis']\n },\n textOverflowWrap: {\n enums: ['whitespace', 'anywhere']\n },\n textBackgroundShape: {\n enums: ['rectangle', 'roundrectangle', 'round-rectangle']\n },\n nodeShape: {\n enums: ['rectangle', 'roundrectangle', 'round-rectangle', 'cutrectangle', 'cut-rectangle', 'bottomroundrectangle', 'bottom-round-rectangle', 'barrel', 'ellipse', 'triangle', 'round-triangle', 'square', 'pentagon', 'round-pentagon', 'hexagon', 'round-hexagon', 'concavehexagon', 'concave-hexagon', 'heptagon', 'round-heptagon', 'octagon', 'round-octagon', 'tag', 'round-tag', 'star', 'diamond', 'round-diamond', 'vee', 'rhomboid', 'right-rhomboid', 'polygon']\n },\n overlayShape: {\n enums: ['roundrectangle', 'round-rectangle', 'ellipse']\n },\n cornerRadius: {\n number: true,\n min: 0,\n units: 'px|em',\n implicitUnits: 'px',\n enums: ['auto']\n },\n compoundIncludeLabels: {\n enums: ['include', 'exclude']\n },\n arrowShape: {\n enums: ['tee', 'triangle', 'triangle-tee', 'circle-triangle', 'triangle-cross', 'triangle-backcurve', 'vee', 'square', 'circle', 'diamond', 'chevron', 'none']\n },\n arrowFill: {\n enums: ['filled', 'hollow']\n },\n arrowWidth: {\n number: true,\n units: '%|px|em',\n implicitUnits: 'px',\n enums: ['match-line']\n },\n display: {\n enums: ['element', 'none']\n },\n visibility: {\n enums: ['hidden', 'visible']\n },\n zCompoundDepth: {\n enums: ['bottom', 'orphan', 'auto', 'top']\n },\n zIndexCompare: {\n enums: ['auto', 'manual']\n },\n valign: {\n enums: ['top', 'center', 'bottom']\n },\n halign: {\n enums: ['left', 'center', 'right']\n },\n justification: {\n enums: ['left', 'center', 'right', 'auto']\n },\n text: {\n string: true\n },\n data: {\n mapping: true,\n regex: data('data')\n },\n layoutData: {\n mapping: true,\n regex: data('layoutData')\n },\n scratch: {\n mapping: true,\n regex: data('scratch')\n },\n mapData: {\n mapping: true,\n regex: mapData('mapData')\n },\n mapLayoutData: {\n mapping: true,\n regex: mapData('mapLayoutData')\n },\n mapScratch: {\n mapping: true,\n regex: mapData('mapScratch')\n },\n fn: {\n mapping: true,\n fn: true\n },\n url: {\n regexes: urlRegexes,\n singleRegexMatchValue: true\n },\n urls: {\n regexes: urlRegexes,\n singleRegexMatchValue: true,\n multiple: true\n },\n propList: {\n propList: true\n },\n angle: {\n number: true,\n units: 'deg|rad',\n implicitUnits: 'rad'\n },\n textRotation: {\n number: true,\n units: 'deg|rad',\n implicitUnits: 'rad',\n enums: ['none', 'autorotate']\n },\n polygonPointList: {\n number: true,\n multiple: true,\n evenMultiple: true,\n min: -1,\n max: 1,\n unitless: true\n },\n edgeDistances: {\n enums: ['intersection', 'node-position', 'endpoints']\n },\n edgeEndpoint: {\n number: true,\n multiple: true,\n units: '%|px|em|deg|rad',\n implicitUnits: 'px',\n enums: ['inside-to-node', 'outside-to-node', 'outside-to-node-or-label', 'outside-to-line', 'outside-to-line-or-label'],\n singleEnum: true,\n validate: function validate(valArr, unitsArr) {\n switch (valArr.length) {\n case 2:\n // can be % or px only\n return unitsArr[0] !== 'deg' && unitsArr[0] !== 'rad' && unitsArr[1] !== 'deg' && unitsArr[1] !== 'rad';\n case 1:\n // can be enum, deg, or rad only\n return string(valArr[0]) || unitsArr[0] === 'deg' || unitsArr[0] === 'rad';\n default:\n return false;\n }\n }\n },\n easing: {\n regexes: ['^(spring)\\\\s*\\\\(\\\\s*(' + number$1 + ')\\\\s*,\\\\s*(' + number$1 + ')\\\\s*\\\\)$', '^(cubic-bezier)\\\\s*\\\\(\\\\s*(' + number$1 + ')\\\\s*,\\\\s*(' + number$1 + ')\\\\s*,\\\\s*(' + number$1 + ')\\\\s*,\\\\s*(' + number$1 + ')\\\\s*\\\\)$'],\n enums: ['linear', 'ease', 'ease-in', 'ease-out', 'ease-in-out', 'ease-in-sine', 'ease-out-sine', 'ease-in-out-sine', 'ease-in-quad', 'ease-out-quad', 'ease-in-out-quad', 'ease-in-cubic', 'ease-out-cubic', 'ease-in-out-cubic', 'ease-in-quart', 'ease-out-quart', 'ease-in-out-quart', 'ease-in-quint', 'ease-out-quint', 'ease-in-out-quint', 'ease-in-expo', 'ease-out-expo', 'ease-in-out-expo', 'ease-in-circ', 'ease-out-circ', 'ease-in-out-circ']\n },\n gradientDirection: {\n enums: ['to-bottom', 'to-top', 'to-left', 'to-right', 'to-bottom-right', 'to-bottom-left', 'to-top-right', 'to-top-left', 'to-right-bottom', 'to-left-bottom', 'to-right-top', 'to-left-top' // different order\n ]\n },\n\n boundsExpansion: {\n number: true,\n multiple: true,\n min: 0,\n validate: function validate(valArr) {\n var length = valArr.length;\n return length === 1 || length === 2 || length === 4;\n }\n }\n };\n var diff = {\n zeroNonZero: function zeroNonZero(val1, val2) {\n if ((val1 == null || val2 == null) && val1 !== val2) {\n return true; // null cases could represent any value\n }\n if (val1 == 0 && val2 != 0) {\n return true;\n } else if (val1 != 0 && val2 == 0) {\n return true;\n } else {\n return false;\n }\n },\n any: function any(val1, val2) {\n return val1 != val2;\n },\n emptyNonEmpty: function emptyNonEmpty(str1, str2) {\n var empty1 = emptyString(str1);\n var empty2 = emptyString(str2);\n return empty1 && !empty2 || !empty1 && empty2;\n }\n };\n\n // define visual style properties\n //\n // - n.b. adding a new group of props may require updates to updateStyleHints()\n // - adding new props to an existing group gets handled automatically\n\n var t = styfn$2.types;\n var mainLabel = [{\n name: 'label',\n type: t.text,\n triggersBounds: diff.any,\n triggersZOrder: diff.emptyNonEmpty\n }, {\n name: 'text-rotation',\n type: t.textRotation,\n triggersBounds: diff.any\n }, {\n name: 'text-margin-x',\n type: t.bidirectionalSize,\n triggersBounds: diff.any\n }, {\n name: 'text-margin-y',\n type: t.bidirectionalSize,\n triggersBounds: diff.any\n }];\n var sourceLabel = [{\n name: 'source-label',\n type: t.text,\n triggersBounds: diff.any\n }, {\n name: 'source-text-rotation',\n type: t.textRotation,\n triggersBounds: diff.any\n }, {\n name: 'source-text-margin-x',\n type: t.bidirectionalSize,\n triggersBounds: diff.any\n }, {\n name: 'source-text-margin-y',\n type: t.bidirectionalSize,\n triggersBounds: diff.any\n }, {\n name: 'source-text-offset',\n type: t.size,\n triggersBounds: diff.any\n }];\n var targetLabel = [{\n name: 'target-label',\n type: t.text,\n triggersBounds: diff.any\n }, {\n name: 'target-text-rotation',\n type: t.textRotation,\n triggersBounds: diff.any\n }, {\n name: 'target-text-margin-x',\n type: t.bidirectionalSize,\n triggersBounds: diff.any\n }, {\n name: 'target-text-margin-y',\n type: t.bidirectionalSize,\n triggersBounds: diff.any\n }, {\n name: 'target-text-offset',\n type: t.size,\n triggersBounds: diff.any\n }];\n var labelDimensions = [{\n name: 'font-family',\n type: t.fontFamily,\n triggersBounds: diff.any\n }, {\n name: 'font-style',\n type: t.fontStyle,\n triggersBounds: diff.any\n }, {\n name: 'font-weight',\n type: t.fontWeight,\n triggersBounds: diff.any\n }, {\n name: 'font-size',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'text-transform',\n type: t.textTransform,\n triggersBounds: diff.any\n }, {\n name: 'text-wrap',\n type: t.textWrap,\n triggersBounds: diff.any\n }, {\n name: 'text-overflow-wrap',\n type: t.textOverflowWrap,\n triggersBounds: diff.any\n }, {\n name: 'text-max-width',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'text-outline-width',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'line-height',\n type: t.positiveNumber,\n triggersBounds: diff.any\n }];\n var commonLabel = [{\n name: 'text-valign',\n type: t.valign,\n triggersBounds: diff.any\n }, {\n name: 'text-halign',\n type: t.halign,\n triggersBounds: diff.any\n }, {\n name: 'color',\n type: t.color\n }, {\n name: 'text-outline-color',\n type: t.color\n }, {\n name: 'text-outline-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'text-background-color',\n type: t.color\n }, {\n name: 'text-background-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'text-background-padding',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'text-border-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'text-border-color',\n type: t.color\n }, {\n name: 'text-border-width',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'text-border-style',\n type: t.borderStyle,\n triggersBounds: diff.any\n }, {\n name: 'text-background-shape',\n type: t.textBackgroundShape,\n triggersBounds: diff.any\n }, {\n name: 'text-justification',\n type: t.justification\n }];\n var behavior = [{\n name: 'events',\n type: t.bool,\n triggersZOrder: diff.any\n }, {\n name: 'text-events',\n type: t.bool,\n triggersZOrder: diff.any\n }];\n var visibility = [{\n name: 'display',\n type: t.display,\n triggersZOrder: diff.any,\n triggersBounds: diff.any,\n triggersBoundsOfConnectedEdges: true\n }, {\n name: 'visibility',\n type: t.visibility,\n triggersZOrder: diff.any\n }, {\n name: 'opacity',\n type: t.zeroOneNumber,\n triggersZOrder: diff.zeroNonZero\n }, {\n name: 'text-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'min-zoomed-font-size',\n type: t.size\n }, {\n name: 'z-compound-depth',\n type: t.zCompoundDepth,\n triggersZOrder: diff.any\n }, {\n name: 'z-index-compare',\n type: t.zIndexCompare,\n triggersZOrder: diff.any\n }, {\n name: 'z-index',\n type: t.number,\n triggersZOrder: diff.any\n }];\n var overlay = [{\n name: 'overlay-padding',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'overlay-color',\n type: t.color\n }, {\n name: 'overlay-opacity',\n type: t.zeroOneNumber,\n triggersBounds: diff.zeroNonZero\n }, {\n name: 'overlay-shape',\n type: t.overlayShape,\n triggersBounds: diff.any\n }, {\n name: 'overlay-corner-radius',\n type: t.cornerRadius\n }];\n var underlay = [{\n name: 'underlay-padding',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'underlay-color',\n type: t.color\n }, {\n name: 'underlay-opacity',\n type: t.zeroOneNumber,\n triggersBounds: diff.zeroNonZero\n }, {\n name: 'underlay-shape',\n type: t.overlayShape,\n triggersBounds: diff.any\n }, {\n name: 'underlay-corner-radius',\n type: t.cornerRadius\n }];\n var transition = [{\n name: 'transition-property',\n type: t.propList\n }, {\n name: 'transition-duration',\n type: t.time\n }, {\n name: 'transition-delay',\n type: t.time\n }, {\n name: 'transition-timing-function',\n type: t.easing\n }];\n var nodeSizeHashOverride = function nodeSizeHashOverride(ele, parsedProp) {\n if (parsedProp.value === 'label') {\n return -ele.poolIndex(); // no hash key hits is using label size (hitrate for perf probably low anyway)\n } else {\n return parsedProp.pfValue;\n }\n };\n var nodeBody = [{\n name: 'height',\n type: t.nodeSize,\n triggersBounds: diff.any,\n hashOverride: nodeSizeHashOverride\n }, {\n name: 'width',\n type: t.nodeSize,\n triggersBounds: diff.any,\n hashOverride: nodeSizeHashOverride\n }, {\n name: 'shape',\n type: t.nodeShape,\n triggersBounds: diff.any\n }, {\n name: 'shape-polygon-points',\n type: t.polygonPointList,\n triggersBounds: diff.any\n }, {\n name: 'corner-radius',\n type: t.cornerRadius\n }, {\n name: 'background-color',\n type: t.color\n }, {\n name: 'background-fill',\n type: t.fill\n }, {\n name: 'background-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'background-blacken',\n type: t.nOneOneNumber\n }, {\n name: 'background-gradient-stop-colors',\n type: t.colors\n }, {\n name: 'background-gradient-stop-positions',\n type: t.percentages\n }, {\n name: 'background-gradient-direction',\n type: t.gradientDirection\n }, {\n name: 'padding',\n type: t.sizeMaybePercent,\n triggersBounds: diff.any\n }, {\n name: 'padding-relative-to',\n type: t.paddingRelativeTo,\n triggersBounds: diff.any\n }, {\n name: 'bounds-expansion',\n type: t.boundsExpansion,\n triggersBounds: diff.any\n }];\n var nodeBorder = [{\n name: 'border-color',\n type: t.color\n }, {\n name: 'border-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'border-width',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'border-style',\n type: t.borderStyle\n }, {\n name: 'border-cap',\n type: t.lineCap\n }, {\n name: 'border-join',\n type: t.lineJoin\n }, {\n name: 'border-dash-pattern',\n type: t.numbers\n }, {\n name: 'border-dash-offset',\n type: t.number\n }, {\n name: 'border-position',\n type: t.linePosition\n }];\n var nodeOutline = [{\n name: 'outline-color',\n type: t.color\n }, {\n name: 'outline-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'outline-width',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'outline-style',\n type: t.borderStyle\n }, {\n name: 'outline-offset',\n type: t.size,\n triggersBounds: diff.any\n }];\n var backgroundImage = [{\n name: 'background-image',\n type: t.urls\n }, {\n name: 'background-image-crossorigin',\n type: t.bgCrossOrigin\n }, {\n name: 'background-image-opacity',\n type: t.zeroOneNumbers\n }, {\n name: 'background-image-containment',\n type: t.bgContainment\n }, {\n name: 'background-image-smoothing',\n type: t.bools\n }, {\n name: 'background-position-x',\n type: t.bgPos\n }, {\n name: 'background-position-y',\n type: t.bgPos\n }, {\n name: 'background-width-relative-to',\n type: t.bgRelativeTo\n }, {\n name: 'background-height-relative-to',\n type: t.bgRelativeTo\n }, {\n name: 'background-repeat',\n type: t.bgRepeat\n }, {\n name: 'background-fit',\n type: t.bgFit\n }, {\n name: 'background-clip',\n type: t.bgClip\n }, {\n name: 'background-width',\n type: t.bgWH\n }, {\n name: 'background-height',\n type: t.bgWH\n }, {\n name: 'background-offset-x',\n type: t.bgPos\n }, {\n name: 'background-offset-y',\n type: t.bgPos\n }];\n var compound = [{\n name: 'position',\n type: t.position,\n triggersBounds: diff.any\n }, {\n name: 'compound-sizing-wrt-labels',\n type: t.compoundIncludeLabels,\n triggersBounds: diff.any\n }, {\n name: 'min-width',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'min-width-bias-left',\n type: t.sizeMaybePercent,\n triggersBounds: diff.any\n }, {\n name: 'min-width-bias-right',\n type: t.sizeMaybePercent,\n triggersBounds: diff.any\n }, {\n name: 'min-height',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'min-height-bias-top',\n type: t.sizeMaybePercent,\n triggersBounds: diff.any\n }, {\n name: 'min-height-bias-bottom',\n type: t.sizeMaybePercent,\n triggersBounds: diff.any\n }];\n var edgeLine = [{\n name: 'line-style',\n type: t.lineStyle\n }, {\n name: 'line-color',\n type: t.color\n }, {\n name: 'line-fill',\n type: t.fill\n }, {\n name: 'line-cap',\n type: t.lineCap\n }, {\n name: 'line-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'line-dash-pattern',\n type: t.numbers\n }, {\n name: 'line-dash-offset',\n type: t.number\n }, {\n name: 'line-outline-width',\n type: t.size\n }, {\n name: 'line-outline-color',\n type: t.color\n }, {\n name: 'line-gradient-stop-colors',\n type: t.colors\n }, {\n name: 'line-gradient-stop-positions',\n type: t.percentages\n }, {\n name: 'curve-style',\n type: t.curveStyle,\n triggersBounds: diff.any,\n triggersBoundsOfParallelBeziers: true\n }, {\n name: 'haystack-radius',\n type: t.zeroOneNumber,\n triggersBounds: diff.any\n }, {\n name: 'source-endpoint',\n type: t.edgeEndpoint,\n triggersBounds: diff.any\n }, {\n name: 'target-endpoint',\n type: t.edgeEndpoint,\n triggersBounds: diff.any\n }, {\n name: 'control-point-step-size',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'control-point-distances',\n type: t.bidirectionalSizes,\n triggersBounds: diff.any\n }, {\n name: 'control-point-weights',\n type: t.numbers,\n triggersBounds: diff.any\n }, {\n name: 'segment-distances',\n type: t.bidirectionalSizes,\n triggersBounds: diff.any\n }, {\n name: 'segment-weights',\n type: t.numbers,\n triggersBounds: diff.any\n }, {\n name: 'segment-radii',\n type: t.numbers,\n triggersBounds: diff.any\n }, {\n name: 'radius-type',\n type: t.radiusType,\n triggersBounds: diff.any\n }, {\n name: 'taxi-turn',\n type: t.bidirectionalSizeMaybePercent,\n triggersBounds: diff.any\n }, {\n name: 'taxi-turn-min-distance',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'taxi-direction',\n type: t.axisDirection,\n triggersBounds: diff.any\n }, {\n name: 'taxi-radius',\n type: t.number,\n triggersBounds: diff.any\n }, {\n name: 'edge-distances',\n type: t.edgeDistances,\n triggersBounds: diff.any\n }, {\n name: 'arrow-scale',\n type: t.positiveNumber,\n triggersBounds: diff.any\n }, {\n name: 'loop-direction',\n type: t.angle,\n triggersBounds: diff.any\n }, {\n name: 'loop-sweep',\n type: t.angle,\n triggersBounds: diff.any\n }, {\n name: 'source-distance-from-node',\n type: t.size,\n triggersBounds: diff.any\n }, {\n name: 'target-distance-from-node',\n type: t.size,\n triggersBounds: diff.any\n }];\n var ghost = [{\n name: 'ghost',\n type: t.bool,\n triggersBounds: diff.any\n }, {\n name: 'ghost-offset-x',\n type: t.bidirectionalSize,\n triggersBounds: diff.any\n }, {\n name: 'ghost-offset-y',\n type: t.bidirectionalSize,\n triggersBounds: diff.any\n }, {\n name: 'ghost-opacity',\n type: t.zeroOneNumber\n }];\n var core = [{\n name: 'selection-box-color',\n type: t.color\n }, {\n name: 'selection-box-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'selection-box-border-color',\n type: t.color\n }, {\n name: 'selection-box-border-width',\n type: t.size\n }, {\n name: 'active-bg-color',\n type: t.color\n }, {\n name: 'active-bg-opacity',\n type: t.zeroOneNumber\n }, {\n name: 'active-bg-size',\n type: t.size\n }, {\n name: 'outside-texture-bg-color',\n type: t.color\n }, {\n name: 'outside-texture-bg-opacity',\n type: t.zeroOneNumber\n }];\n\n // pie backgrounds for nodes\n var pie = [];\n styfn$2.pieBackgroundN = 16; // because the pie properties are numbered, give access to a constant N (for renderer use)\n pie.push({\n name: 'pie-size',\n type: t.sizeMaybePercent\n });\n for (var i = 1; i <= styfn$2.pieBackgroundN; i++) {\n pie.push({\n name: 'pie-' + i + '-background-color',\n type: t.color\n });\n pie.push({\n name: 'pie-' + i + '-background-size',\n type: t.percent\n });\n pie.push({\n name: 'pie-' + i + '-background-opacity',\n type: t.zeroOneNumber\n });\n }\n\n // edge arrows\n var edgeArrow = [];\n var arrowPrefixes = styfn$2.arrowPrefixes = ['source', 'mid-source', 'target', 'mid-target'];\n [{\n name: 'arrow-shape',\n type: t.arrowShape,\n triggersBounds: diff.any\n }, {\n name: 'arrow-color',\n type: t.color\n }, {\n name: 'arrow-fill',\n type: t.arrowFill\n }, {\n name: 'arrow-width',\n type: t.arrowWidth\n }].forEach(function (prop) {\n arrowPrefixes.forEach(function (prefix) {\n var name = prefix + '-' + prop.name;\n var type = prop.type,\n triggersBounds = prop.triggersBounds;\n edgeArrow.push({\n name: name,\n type: type,\n triggersBounds: triggersBounds\n });\n });\n }, {});\n var props = styfn$2.properties = [].concat(behavior, transition, visibility, overlay, underlay, ghost, commonLabel, labelDimensions, mainLabel, sourceLabel, targetLabel, nodeBody, nodeBorder, nodeOutline, backgroundImage, pie, compound, edgeLine, edgeArrow, core);\n var propGroups = styfn$2.propertyGroups = {\n // common to all eles\n behavior: behavior,\n transition: transition,\n visibility: visibility,\n overlay: overlay,\n underlay: underlay,\n ghost: ghost,\n // labels\n commonLabel: commonLabel,\n labelDimensions: labelDimensions,\n mainLabel: mainLabel,\n sourceLabel: sourceLabel,\n targetLabel: targetLabel,\n // node props\n nodeBody: nodeBody,\n nodeBorder: nodeBorder,\n nodeOutline: nodeOutline,\n backgroundImage: backgroundImage,\n pie: pie,\n compound: compound,\n // edge props\n edgeLine: edgeLine,\n edgeArrow: edgeArrow,\n core: core\n };\n var propGroupNames = styfn$2.propertyGroupNames = {};\n var propGroupKeys = styfn$2.propertyGroupKeys = Object.keys(propGroups);\n propGroupKeys.forEach(function (key) {\n propGroupNames[key] = propGroups[key].map(function (prop) {\n return prop.name;\n });\n propGroups[key].forEach(function (prop) {\n return prop.groupKey = key;\n });\n });\n\n // define aliases\n var aliases = styfn$2.aliases = [{\n name: 'content',\n pointsTo: 'label'\n }, {\n name: 'control-point-distance',\n pointsTo: 'control-point-distances'\n }, {\n name: 'control-point-weight',\n pointsTo: 'control-point-weights'\n }, {\n name: 'segment-distance',\n pointsTo: 'segment-distances'\n }, {\n name: 'segment-weight',\n pointsTo: 'segment-weights'\n }, {\n name: 'segment-radius',\n pointsTo: 'segment-radii'\n }, {\n name: 'edge-text-rotation',\n pointsTo: 'text-rotation'\n }, {\n name: 'padding-left',\n pointsTo: 'padding'\n }, {\n name: 'padding-right',\n pointsTo: 'padding'\n }, {\n name: 'padding-top',\n pointsTo: 'padding'\n }, {\n name: 'padding-bottom',\n pointsTo: 'padding'\n }];\n\n // list of property names\n styfn$2.propertyNames = props.map(function (p) {\n return p.name;\n });\n\n // allow access of properties by name ( e.g. style.properties.height )\n for (var _i = 0; _i < props.length; _i++) {\n var prop = props[_i];\n props[prop.name] = prop; // allow lookup by name\n }\n\n // map aliases\n for (var _i2 = 0; _i2 < aliases.length; _i2++) {\n var alias = aliases[_i2];\n var pointsToProp = props[alias.pointsTo];\n var aliasProp = {\n name: alias.name,\n alias: true,\n pointsTo: pointsToProp\n };\n\n // add alias prop for parsing\n props.push(aliasProp);\n props[alias.name] = aliasProp; // allow lookup by name\n }\n})();\n\nstyfn$2.getDefaultProperty = function (name) {\n return this.getDefaultProperties()[name];\n};\nstyfn$2.getDefaultProperties = function () {\n var _p = this._private;\n if (_p.defaultProperties != null) {\n return _p.defaultProperties;\n }\n var rawProps = extend({\n // core props\n 'selection-box-color': '#ddd',\n 'selection-box-opacity': 0.65,\n 'selection-box-border-color': '#aaa',\n 'selection-box-border-width': 1,\n 'active-bg-color': 'black',\n 'active-bg-opacity': 0.15,\n 'active-bg-size': 30,\n 'outside-texture-bg-color': '#000',\n 'outside-texture-bg-opacity': 0.125,\n // common node/edge props\n 'events': 'yes',\n 'text-events': 'no',\n 'text-valign': 'top',\n 'text-halign': 'center',\n 'text-justification': 'auto',\n 'line-height': 1,\n 'color': '#000',\n 'text-outline-color': '#000',\n 'text-outline-width': 0,\n 'text-outline-opacity': 1,\n 'text-opacity': 1,\n 'text-decoration': 'none',\n 'text-transform': 'none',\n 'text-wrap': 'none',\n 'text-overflow-wrap': 'whitespace',\n 'text-max-width': 9999,\n 'text-background-color': '#000',\n 'text-background-opacity': 0,\n 'text-background-shape': 'rectangle',\n 'text-background-padding': 0,\n 'text-border-opacity': 0,\n 'text-border-width': 0,\n 'text-border-style': 'solid',\n 'text-border-color': '#000',\n 'font-family': 'Helvetica Neue, Helvetica, sans-serif',\n 'font-style': 'normal',\n 'font-weight': 'normal',\n 'font-size': 16,\n 'min-zoomed-font-size': 0,\n 'text-rotation': 'none',\n 'source-text-rotation': 'none',\n 'target-text-rotation': 'none',\n 'visibility': 'visible',\n 'display': 'element',\n 'opacity': 1,\n 'z-compound-depth': 'auto',\n 'z-index-compare': 'auto',\n 'z-index': 0,\n 'label': '',\n 'text-margin-x': 0,\n 'text-margin-y': 0,\n 'source-label': '',\n 'source-text-offset': 0,\n 'source-text-margin-x': 0,\n 'source-text-margin-y': 0,\n 'target-label': '',\n 'target-text-offset': 0,\n 'target-text-margin-x': 0,\n 'target-text-margin-y': 0,\n 'overlay-opacity': 0,\n 'overlay-color': '#000',\n 'overlay-padding': 10,\n 'overlay-shape': 'round-rectangle',\n 'overlay-corner-radius': 'auto',\n 'underlay-opacity': 0,\n 'underlay-color': '#000',\n 'underlay-padding': 10,\n 'underlay-shape': 'round-rectangle',\n 'underlay-corner-radius': 'auto',\n 'transition-property': 'none',\n 'transition-duration': 0,\n 'transition-delay': 0,\n 'transition-timing-function': 'linear',\n // node props\n 'background-blacken': 0,\n 'background-color': '#999',\n 'background-fill': 'solid',\n 'background-opacity': 1,\n 'background-image': 'none',\n 'background-image-crossorigin': 'anonymous',\n 'background-image-opacity': 1,\n 'background-image-containment': 'inside',\n 'background-image-smoothing': 'yes',\n 'background-position-x': '50%',\n 'background-position-y': '50%',\n 'background-offset-x': 0,\n 'background-offset-y': 0,\n 'background-width-relative-to': 'include-padding',\n 'background-height-relative-to': 'include-padding',\n 'background-repeat': 'no-repeat',\n 'background-fit': 'none',\n 'background-clip': 'node',\n 'background-width': 'auto',\n 'background-height': 'auto',\n 'border-color': '#000',\n 'border-opacity': 1,\n 'border-width': 0,\n 'border-style': 'solid',\n 'border-dash-pattern': [4, 2],\n 'border-dash-offset': 0,\n 'border-cap': 'butt',\n 'border-join': 'miter',\n 'border-position': 'center',\n 'outline-color': '#999',\n 'outline-opacity': 1,\n 'outline-width': 0,\n 'outline-offset': 0,\n 'outline-style': 'solid',\n 'height': 30,\n 'width': 30,\n 'shape': 'ellipse',\n 'shape-polygon-points': '-1, -1, 1, -1, 1, 1, -1, 1',\n 'corner-radius': 'auto',\n 'bounds-expansion': 0,\n // node gradient\n 'background-gradient-direction': 'to-bottom',\n 'background-gradient-stop-colors': '#999',\n 'background-gradient-stop-positions': '0%',\n // ghost props\n 'ghost': 'no',\n 'ghost-offset-y': 0,\n 'ghost-offset-x': 0,\n 'ghost-opacity': 0,\n // compound props\n 'padding': 0,\n 'padding-relative-to': 'width',\n 'position': 'origin',\n 'compound-sizing-wrt-labels': 'include',\n 'min-width': 0,\n 'min-width-bias-left': 0,\n 'min-width-bias-right': 0,\n 'min-height': 0,\n 'min-height-bias-top': 0,\n 'min-height-bias-bottom': 0\n }, {\n // node pie bg\n 'pie-size': '100%'\n }, [{\n name: 'pie-{{i}}-background-color',\n value: 'black'\n }, {\n name: 'pie-{{i}}-background-size',\n value: '0%'\n }, {\n name: 'pie-{{i}}-background-opacity',\n value: 1\n }].reduce(function (css, prop) {\n for (var i = 1; i <= styfn$2.pieBackgroundN; i++) {\n var name = prop.name.replace('{{i}}', i);\n var val = prop.value;\n css[name] = val;\n }\n return css;\n }, {}), {\n // edge props\n 'line-style': 'solid',\n 'line-color': '#999',\n 'line-fill': 'solid',\n 'line-cap': 'butt',\n 'line-opacity': 1,\n 'line-outline-width': 0,\n 'line-outline-color': '#000',\n 'line-gradient-stop-colors': '#999',\n 'line-gradient-stop-positions': '0%',\n 'control-point-step-size': 40,\n 'control-point-weights': 0.5,\n 'segment-weights': 0.5,\n 'segment-distances': 20,\n 'segment-radii': 15,\n 'radius-type': 'arc-radius',\n 'taxi-turn': '50%',\n 'taxi-radius': 15,\n 'taxi-turn-min-distance': 10,\n 'taxi-direction': 'auto',\n 'edge-distances': 'intersection',\n 'curve-style': 'haystack',\n 'haystack-radius': 0,\n 'arrow-scale': 1,\n 'loop-direction': '-45deg',\n 'loop-sweep': '-90deg',\n 'source-distance-from-node': 0,\n 'target-distance-from-node': 0,\n 'source-endpoint': 'outside-to-node',\n 'target-endpoint': 'outside-to-node',\n 'line-dash-pattern': [6, 3],\n 'line-dash-offset': 0\n }, [{\n name: 'arrow-shape',\n value: 'none'\n }, {\n name: 'arrow-color',\n value: '#999'\n }, {\n name: 'arrow-fill',\n value: 'filled'\n }, {\n name: 'arrow-width',\n value: 1\n }].reduce(function (css, prop) {\n styfn$2.arrowPrefixes.forEach(function (prefix) {\n var name = prefix + '-' + prop.name;\n var val = prop.value;\n css[name] = val;\n });\n return css;\n }, {}));\n var parsedProps = {};\n for (var i = 0; i < this.properties.length; i++) {\n var prop = this.properties[i];\n if (prop.pointsTo) {\n continue;\n }\n var name = prop.name;\n var val = rawProps[name];\n var parsedProp = this.parse(name, val);\n parsedProps[name] = parsedProp;\n }\n _p.defaultProperties = parsedProps;\n return _p.defaultProperties;\n};\nstyfn$2.addDefaultStylesheet = function () {\n this.selector(':parent').css({\n 'shape': 'rectangle',\n 'padding': 10,\n 'background-color': '#eee',\n 'border-color': '#ccc',\n 'border-width': 1\n }).selector('edge').css({\n 'width': 3\n }).selector(':loop').css({\n 'curve-style': 'bezier'\n }).selector('edge:compound').css({\n 'curve-style': 'bezier',\n 'source-endpoint': 'outside-to-line',\n 'target-endpoint': 'outside-to-line'\n }).selector(':selected').css({\n 'background-color': '#0169D9',\n 'line-color': '#0169D9',\n 'source-arrow-color': '#0169D9',\n 'target-arrow-color': '#0169D9',\n 'mid-source-arrow-color': '#0169D9',\n 'mid-target-arrow-color': '#0169D9'\n }).selector(':parent:selected').css({\n 'background-color': '#CCE1F9',\n 'border-color': '#aec8e5'\n }).selector(':active').css({\n 'overlay-color': 'black',\n 'overlay-padding': 10,\n 'overlay-opacity': 0.25\n });\n this.defaultLength = this.length;\n};\n\nvar styfn$1 = {};\n\n// a caching layer for property parsing\nstyfn$1.parse = function (name, value, propIsBypass, propIsFlat) {\n var self = this;\n\n // function values can't be cached in all cases, and there isn't much benefit of caching them anyway\n if (fn$6(value)) {\n return self.parseImplWarn(name, value, propIsBypass, propIsFlat);\n }\n var flatKey = propIsFlat === 'mapping' || propIsFlat === true || propIsFlat === false || propIsFlat == null ? 'dontcare' : propIsFlat;\n var bypassKey = propIsBypass ? 't' : 'f';\n var valueKey = '' + value;\n var argHash = hashStrings(name, valueKey, bypassKey, flatKey);\n var propCache = self.propCache = self.propCache || [];\n var ret;\n if (!(ret = propCache[argHash])) {\n ret = propCache[argHash] = self.parseImplWarn(name, value, propIsBypass, propIsFlat);\n }\n\n // - bypasses can't be shared b/c the value can be changed by animations or otherwise overridden\n // - mappings can't be shared b/c mappings are per-element\n if (propIsBypass || propIsFlat === 'mapping') {\n // need a copy since props are mutated later in their lifecycles\n ret = copy(ret);\n if (ret) {\n ret.value = copy(ret.value); // because it could be an array, e.g. colour\n }\n }\n\n return ret;\n};\nstyfn$1.parseImplWarn = function (name, value, propIsBypass, propIsFlat) {\n var prop = this.parseImpl(name, value, propIsBypass, propIsFlat);\n if (!prop && value != null) {\n warn(\"The style property `\".concat(name, \": \").concat(value, \"` is invalid\"));\n }\n if (prop && (prop.name === 'width' || prop.name === 'height') && value === 'label') {\n warn('The style value of `label` is deprecated for `' + prop.name + '`');\n }\n return prop;\n};\n\n// parse a property; return null on invalid; return parsed property otherwise\n// fields :\n// - name : the name of the property\n// - value : the parsed, native-typed value of the property\n// - strValue : a string value that represents the property value in valid css\n// - bypass : true iff the property is a bypass property\nstyfn$1.parseImpl = function (name, value, propIsBypass, propIsFlat) {\n var self = this;\n name = camel2dash(name); // make sure the property name is in dash form (e.g. 'property-name' not 'propertyName')\n\n var property = self.properties[name];\n var passedValue = value;\n var types = self.types;\n if (!property) {\n return null;\n } // return null on property of unknown name\n if (value === undefined) {\n return null;\n } // can't assign undefined\n\n // the property may be an alias\n if (property.alias) {\n property = property.pointsTo;\n name = property.name;\n }\n var valueIsString = string(value);\n if (valueIsString) {\n // trim the value to make parsing easier\n value = value.trim();\n }\n var type = property.type;\n if (!type) {\n return null;\n } // no type, no luck\n\n // check if bypass is null or empty string (i.e. indication to delete bypass property)\n if (propIsBypass && (value === '' || value === null)) {\n return {\n name: name,\n value: value,\n bypass: true,\n deleteBypass: true\n };\n }\n\n // check if value is a function used as a mapper\n if (fn$6(value)) {\n return {\n name: name,\n value: value,\n strValue: 'fn',\n mapped: types.fn,\n bypass: propIsBypass\n };\n }\n\n // check if value is mapped\n var data, mapData;\n if (!valueIsString || propIsFlat || value.length < 7 || value[1] !== 'a') ; else if (value.length >= 7 && value[0] === 'd' && (data = new RegExp(types.data.regex).exec(value))) {\n if (propIsBypass) {\n return false;\n } // mappers not allowed in bypass\n\n var mapped = types.data;\n return {\n name: name,\n value: data,\n strValue: '' + value,\n mapped: mapped,\n field: data[1],\n bypass: propIsBypass\n };\n } else if (value.length >= 10 && value[0] === 'm' && (mapData = new RegExp(types.mapData.regex).exec(value))) {\n if (propIsBypass) {\n return false;\n } // mappers not allowed in bypass\n if (type.multiple) {\n return false;\n } // impossible to map to num\n\n var _mapped = types.mapData;\n\n // we can map only if the type is a colour or a number\n if (!(type.color || type.number)) {\n return false;\n }\n var valueMin = this.parse(name, mapData[4]); // parse to validate\n if (!valueMin || valueMin.mapped) {\n return false;\n } // can't be invalid or mapped\n\n var valueMax = this.parse(name, mapData[5]); // parse to validate\n if (!valueMax || valueMax.mapped) {\n return false;\n } // can't be invalid or mapped\n\n // check if valueMin and valueMax are the same\n if (valueMin.pfValue === valueMax.pfValue || valueMin.strValue === valueMax.strValue) {\n warn('`' + name + ': ' + value + '` is not a valid mapper because the output range is zero; converting to `' + name + ': ' + valueMin.strValue + '`');\n return this.parse(name, valueMin.strValue); // can't make much of a mapper without a range\n } else if (type.color) {\n var c1 = valueMin.value;\n var c2 = valueMax.value;\n var same = c1[0] === c2[0] // red\n && c1[1] === c2[1] // green\n && c1[2] === c2[2] // blue\n && (\n // optional alpha\n c1[3] === c2[3] // same alpha outright\n || (c1[3] == null || c1[3] === 1 // full opacity for colour 1?\n ) && (c2[3] == null || c2[3] === 1) // full opacity for colour 2?\n );\n\n if (same) {\n return false;\n } // can't make a mapper without a range\n }\n\n return {\n name: name,\n value: mapData,\n strValue: '' + value,\n mapped: _mapped,\n field: mapData[1],\n fieldMin: parseFloat(mapData[2]),\n // min & max are numeric\n fieldMax: parseFloat(mapData[3]),\n valueMin: valueMin.value,\n valueMax: valueMax.value,\n bypass: propIsBypass\n };\n }\n if (type.multiple && propIsFlat !== 'multiple') {\n var vals;\n if (valueIsString) {\n vals = value.split(/\\s+/);\n } else if (array(value)) {\n vals = value;\n } else {\n vals = [value];\n }\n if (type.evenMultiple && vals.length % 2 !== 0) {\n return null;\n }\n var valArr = [];\n var unitsArr = [];\n var pfValArr = [];\n var strVal = '';\n var hasEnum = false;\n for (var i = 0; i < vals.length; i++) {\n var p = self.parse(name, vals[i], propIsBypass, 'multiple');\n hasEnum = hasEnum || string(p.value);\n valArr.push(p.value);\n pfValArr.push(p.pfValue != null ? p.pfValue : p.value);\n unitsArr.push(p.units);\n strVal += (i > 0 ? ' ' : '') + p.strValue;\n }\n if (type.validate && !type.validate(valArr, unitsArr)) {\n return null;\n }\n if (type.singleEnum && hasEnum) {\n if (valArr.length === 1 && string(valArr[0])) {\n return {\n name: name,\n value: valArr[0],\n strValue: valArr[0],\n bypass: propIsBypass\n };\n } else {\n return null;\n }\n }\n return {\n name: name,\n value: valArr,\n pfValue: pfValArr,\n strValue: strVal,\n bypass: propIsBypass,\n units: unitsArr\n };\n }\n\n // several types also allow enums\n var checkEnums = function checkEnums() {\n for (var _i = 0; _i < type.enums.length; _i++) {\n var en = type.enums[_i];\n if (en === value) {\n return {\n name: name,\n value: value,\n strValue: '' + value,\n bypass: propIsBypass\n };\n }\n }\n return null;\n };\n\n // check the type and return the appropriate object\n if (type.number) {\n var units;\n var implicitUnits = 'px'; // not set => px\n\n if (type.units) {\n // use specified units if set\n units = type.units;\n }\n if (type.implicitUnits) {\n implicitUnits = type.implicitUnits;\n }\n if (!type.unitless) {\n if (valueIsString) {\n var unitsRegex = 'px|em' + (type.allowPercent ? '|\\\\%' : '');\n if (units) {\n unitsRegex = units;\n } // only allow explicit units if so set\n var match = value.match('^(' + number + ')(' + unitsRegex + ')?' + '$');\n if (match) {\n value = match[1];\n units = match[2] || implicitUnits;\n }\n } else if (!units || type.implicitUnits) {\n units = implicitUnits; // implicitly px if unspecified\n }\n }\n\n value = parseFloat(value);\n\n // if not a number and enums not allowed, then the value is invalid\n if (isNaN(value) && type.enums === undefined) {\n return null;\n }\n\n // check if this number type also accepts special keywords in place of numbers\n // (i.e. `left`, `auto`, etc)\n if (isNaN(value) && type.enums !== undefined) {\n value = passedValue;\n return checkEnums();\n }\n\n // check if value must be an integer\n if (type.integer && !integer(value)) {\n return null;\n }\n\n // check value is within range\n if (type.min !== undefined && (value < type.min || type.strictMin && value === type.min) || type.max !== undefined && (value > type.max || type.strictMax && value === type.max)) {\n return null;\n }\n var ret = {\n name: name,\n value: value,\n strValue: '' + value + (units ? units : ''),\n units: units,\n bypass: propIsBypass\n };\n\n // normalise value in pixels\n if (type.unitless || units !== 'px' && units !== 'em') {\n ret.pfValue = value;\n } else {\n ret.pfValue = units === 'px' || !units ? value : this.getEmSizeInPixels() * value;\n }\n\n // normalise value in ms\n if (units === 'ms' || units === 's') {\n ret.pfValue = units === 'ms' ? value : 1000 * value;\n }\n\n // normalise value in rad\n if (units === 'deg' || units === 'rad') {\n ret.pfValue = units === 'rad' ? value : deg2rad(value);\n }\n\n // normalize value in %\n if (units === '%') {\n ret.pfValue = value / 100;\n }\n return ret;\n } else if (type.propList) {\n var props = [];\n var propsStr = '' + value;\n if (propsStr === 'none') ; else {\n // go over each prop\n\n var propsSplit = propsStr.split(/\\s*,\\s*|\\s+/);\n for (var _i2 = 0; _i2 < propsSplit.length; _i2++) {\n var propName = propsSplit[_i2].trim();\n if (self.properties[propName]) {\n props.push(propName);\n } else {\n warn('`' + propName + '` is not a valid property name');\n }\n }\n if (props.length === 0) {\n return null;\n }\n }\n return {\n name: name,\n value: props,\n strValue: props.length === 0 ? 'none' : props.join(' '),\n bypass: propIsBypass\n };\n } else if (type.color) {\n var tuple = color2tuple(value);\n if (!tuple) {\n return null;\n }\n return {\n name: name,\n value: tuple,\n pfValue: tuple,\n strValue: 'rgb(' + tuple[0] + ',' + tuple[1] + ',' + tuple[2] + ')',\n // n.b. no spaces b/c of multiple support\n bypass: propIsBypass\n };\n } else if (type.regex || type.regexes) {\n // first check enums\n if (type.enums) {\n var enumProp = checkEnums();\n if (enumProp) {\n return enumProp;\n }\n }\n var regexes = type.regexes ? type.regexes : [type.regex];\n for (var _i3 = 0; _i3 < regexes.length; _i3++) {\n var regex = new RegExp(regexes[_i3]); // make a regex from the type string\n var m = regex.exec(value);\n if (m) {\n // regex matches\n return {\n name: name,\n value: type.singleRegexMatchValue ? m[1] : m,\n strValue: '' + value,\n bypass: propIsBypass\n };\n }\n }\n return null; // didn't match any\n } else if (type.string) {\n // just return\n return {\n name: name,\n value: '' + value,\n strValue: '' + value,\n bypass: propIsBypass\n };\n } else if (type.enums) {\n // check enums last because it's a combo type in others\n return checkEnums();\n } else {\n return null; // not a type we can handle\n }\n};\n\nvar Style = function Style(cy) {\n if (!(this instanceof Style)) {\n return new Style(cy);\n }\n if (!core(cy)) {\n error('A style must have a core reference');\n return;\n }\n this._private = {\n cy: cy,\n coreStyle: {}\n };\n this.length = 0;\n this.resetToDefault();\n};\nvar styfn = Style.prototype;\nstyfn.instanceString = function () {\n return 'style';\n};\n\n// remove all contexts\nstyfn.clear = function () {\n var _p = this._private;\n var cy = _p.cy;\n var eles = cy.elements();\n for (var i = 0; i < this.length; i++) {\n this[i] = undefined;\n }\n this.length = 0;\n _p.contextStyles = {};\n _p.propDiffs = {};\n this.cleanElements(eles, true);\n eles.forEach(function (ele) {\n var ele_p = ele[0]._private;\n ele_p.styleDirty = true;\n ele_p.appliedInitStyle = false;\n });\n return this; // chaining\n};\n\nstyfn.resetToDefault = function () {\n this.clear();\n this.addDefaultStylesheet();\n return this;\n};\n\n// builds a style object for the 'core' selector\nstyfn.core = function (propName) {\n return this._private.coreStyle[propName] || this.getDefaultProperty(propName);\n};\n\n// create a new context from the specified selector string and switch to that context\nstyfn.selector = function (selectorStr) {\n // 'core' is a special case and does not need a selector\n var selector = selectorStr === 'core' ? null : new Selector(selectorStr);\n var i = this.length++; // new context means new index\n this[i] = {\n selector: selector,\n properties: [],\n mappedProperties: [],\n index: i\n };\n return this; // chaining\n};\n\n// add one or many css rules to the current context\nstyfn.css = function () {\n var self = this;\n var args = arguments;\n if (args.length === 1) {\n var map = args[0];\n for (var i = 0; i < self.properties.length; i++) {\n var prop = self.properties[i];\n var mapVal = map[prop.name];\n if (mapVal === undefined) {\n mapVal = map[dash2camel(prop.name)];\n }\n if (mapVal !== undefined) {\n this.cssRule(prop.name, mapVal);\n }\n }\n } else if (args.length === 2) {\n this.cssRule(args[0], args[1]);\n }\n\n // do nothing if args are invalid\n\n return this; // chaining\n};\n\nstyfn.style = styfn.css;\n\n// add a single css rule to the current context\nstyfn.cssRule = function (name, value) {\n // name-value pair\n var property = this.parse(name, value);\n\n // add property to current context if valid\n if (property) {\n var i = this.length - 1;\n this[i].properties.push(property);\n this[i].properties[property.name] = property; // allow access by name as well\n\n if (property.name.match(/pie-(\\d+)-background-size/) && property.value) {\n this._private.hasPie = true;\n }\n if (property.mapped) {\n this[i].mappedProperties.push(property);\n }\n\n // add to core style if necessary\n var currentSelectorIsCore = !this[i].selector;\n if (currentSelectorIsCore) {\n this._private.coreStyle[property.name] = property;\n }\n }\n return this; // chaining\n};\n\nstyfn.append = function (style) {\n if (stylesheet(style)) {\n style.appendToStyle(this);\n } else if (array(style)) {\n this.appendFromJson(style);\n } else if (string(style)) {\n this.appendFromString(style);\n } // you probably wouldn't want to append a Style, since you'd duplicate the default parts\n\n return this;\n};\n\n// static function\nStyle.fromJson = function (cy, json) {\n var style = new Style(cy);\n style.fromJson(json);\n return style;\n};\nStyle.fromString = function (cy, string) {\n return new Style(cy).fromString(string);\n};\n[styfn$8, styfn$7, styfn$6, styfn$5, styfn$4, styfn$3, styfn$2, styfn$1].forEach(function (props) {\n extend(styfn, props);\n});\nStyle.types = styfn.types;\nStyle.properties = styfn.properties;\nStyle.propertyGroups = styfn.propertyGroups;\nStyle.propertyGroupNames = styfn.propertyGroupNames;\nStyle.propertyGroupKeys = styfn.propertyGroupKeys;\n\nvar corefn$2 = {\n style: function style(newStyle) {\n if (newStyle) {\n var s = this.setStyle(newStyle);\n s.update();\n }\n return this._private.style;\n },\n setStyle: function setStyle(style) {\n var _p = this._private;\n if (stylesheet(style)) {\n _p.style = style.generateStyle(this);\n } else if (array(style)) {\n _p.style = Style.fromJson(this, style);\n } else if (string(style)) {\n _p.style = Style.fromString(this, style);\n } else {\n _p.style = Style(this);\n }\n return _p.style;\n },\n // e.g. cy.data() changed => recalc ele mappers\n updateStyle: function updateStyle() {\n this.mutableElements().updateStyle(); // just send to all eles\n }\n};\n\nvar defaultSelectionType = 'single';\nvar corefn$1 = {\n autolock: function autolock(bool) {\n if (bool !== undefined) {\n this._private.autolock = bool ? true : false;\n } else {\n return this._private.autolock;\n }\n return this; // chaining\n },\n\n autoungrabify: function autoungrabify(bool) {\n if (bool !== undefined) {\n this._private.autoungrabify = bool ? true : false;\n } else {\n return this._private.autoungrabify;\n }\n return this; // chaining\n },\n\n autounselectify: function autounselectify(bool) {\n if (bool !== undefined) {\n this._private.autounselectify = bool ? true : false;\n } else {\n return this._private.autounselectify;\n }\n return this; // chaining\n },\n\n selectionType: function selectionType(selType) {\n var _p = this._private;\n if (_p.selectionType == null) {\n _p.selectionType = defaultSelectionType;\n }\n if (selType !== undefined) {\n if (selType === 'additive' || selType === 'single') {\n _p.selectionType = selType;\n }\n } else {\n return _p.selectionType;\n }\n return this;\n },\n panningEnabled: function panningEnabled(bool) {\n if (bool !== undefined) {\n this._private.panningEnabled = bool ? true : false;\n } else {\n return this._private.panningEnabled;\n }\n return this; // chaining\n },\n\n userPanningEnabled: function userPanningEnabled(bool) {\n if (bool !== undefined) {\n this._private.userPanningEnabled = bool ? true : false;\n } else {\n return this._private.userPanningEnabled;\n }\n return this; // chaining\n },\n\n zoomingEnabled: function zoomingEnabled(bool) {\n if (bool !== undefined) {\n this._private.zoomingEnabled = bool ? true : false;\n } else {\n return this._private.zoomingEnabled;\n }\n return this; // chaining\n },\n\n userZoomingEnabled: function userZoomingEnabled(bool) {\n if (bool !== undefined) {\n this._private.userZoomingEnabled = bool ? true : false;\n } else {\n return this._private.userZoomingEnabled;\n }\n return this; // chaining\n },\n\n boxSelectionEnabled: function boxSelectionEnabled(bool) {\n if (bool !== undefined) {\n this._private.boxSelectionEnabled = bool ? true : false;\n } else {\n return this._private.boxSelectionEnabled;\n }\n return this; // chaining\n },\n\n pan: function pan() {\n var args = arguments;\n var pan = this._private.pan;\n var dim, val, dims, x, y;\n switch (args.length) {\n case 0:\n // .pan()\n return pan;\n case 1:\n if (string(args[0])) {\n // .pan('x')\n dim = args[0];\n return pan[dim];\n } else if (plainObject(args[0])) {\n // .pan({ x: 0, y: 100 })\n if (!this._private.panningEnabled) {\n return this;\n }\n dims = args[0];\n x = dims.x;\n y = dims.y;\n if (number$1(x)) {\n pan.x = x;\n }\n if (number$1(y)) {\n pan.y = y;\n }\n this.emit('pan viewport');\n }\n break;\n case 2:\n // .pan('x', 100)\n if (!this._private.panningEnabled) {\n return this;\n }\n dim = args[0];\n val = args[1];\n if ((dim === 'x' || dim === 'y') && number$1(val)) {\n pan[dim] = val;\n }\n this.emit('pan viewport');\n break;\n // invalid\n }\n\n this.notify('viewport');\n return this; // chaining\n },\n\n panBy: function panBy(arg0, arg1) {\n var args = arguments;\n var pan = this._private.pan;\n var dim, val, dims, x, y;\n if (!this._private.panningEnabled) {\n return this;\n }\n switch (args.length) {\n case 1:\n if (plainObject(arg0)) {\n // .panBy({ x: 0, y: 100 })\n dims = args[0];\n x = dims.x;\n y = dims.y;\n if (number$1(x)) {\n pan.x += x;\n }\n if (number$1(y)) {\n pan.y += y;\n }\n this.emit('pan viewport');\n }\n break;\n case 2:\n // .panBy('x', 100)\n dim = arg0;\n val = arg1;\n if ((dim === 'x' || dim === 'y') && number$1(val)) {\n pan[dim] += val;\n }\n this.emit('pan viewport');\n break;\n // invalid\n }\n\n this.notify('viewport');\n return this; // chaining\n },\n\n fit: function fit(elements, padding) {\n var viewportState = this.getFitViewport(elements, padding);\n if (viewportState) {\n var _p = this._private;\n _p.zoom = viewportState.zoom;\n _p.pan = viewportState.pan;\n this.emit('pan zoom viewport');\n this.notify('viewport');\n }\n return this; // chaining\n },\n\n getFitViewport: function getFitViewport(elements, padding) {\n if (number$1(elements) && padding === undefined) {\n // elements is optional\n padding = elements;\n elements = undefined;\n }\n if (!this._private.panningEnabled || !this._private.zoomingEnabled) {\n return;\n }\n var bb;\n if (string(elements)) {\n var sel = elements;\n elements = this.$(sel);\n } else if (boundingBox(elements)) {\n // assume bb\n var bbe = elements;\n bb = {\n x1: bbe.x1,\n y1: bbe.y1,\n x2: bbe.x2,\n y2: bbe.y2\n };\n bb.w = bb.x2 - bb.x1;\n bb.h = bb.y2 - bb.y1;\n } else if (!elementOrCollection(elements)) {\n elements = this.mutableElements();\n }\n if (elementOrCollection(elements) && elements.empty()) {\n return;\n } // can't fit to nothing\n\n bb = bb || elements.boundingBox();\n var w = this.width();\n var h = this.height();\n var zoom;\n padding = number$1(padding) ? padding : 0;\n if (!isNaN(w) && !isNaN(h) && w > 0 && h > 0 && !isNaN(bb.w) && !isNaN(bb.h) && bb.w > 0 && bb.h > 0) {\n zoom = Math.min((w - 2 * padding) / bb.w, (h - 2 * padding) / bb.h);\n\n // crop zoom\n zoom = zoom > this._private.maxZoom ? this._private.maxZoom : zoom;\n zoom = zoom < this._private.minZoom ? this._private.minZoom : zoom;\n var pan = {\n // now pan to middle\n x: (w - zoom * (bb.x1 + bb.x2)) / 2,\n y: (h - zoom * (bb.y1 + bb.y2)) / 2\n };\n return {\n zoom: zoom,\n pan: pan\n };\n }\n return;\n },\n zoomRange: function zoomRange(min, max) {\n var _p = this._private;\n if (max == null) {\n var opts = min;\n min = opts.min;\n max = opts.max;\n }\n if (number$1(min) && number$1(max) && min <= max) {\n _p.minZoom = min;\n _p.maxZoom = max;\n } else if (number$1(min) && max === undefined && min <= _p.maxZoom) {\n _p.minZoom = min;\n } else if (number$1(max) && min === undefined && max >= _p.minZoom) {\n _p.maxZoom = max;\n }\n return this;\n },\n minZoom: function minZoom(zoom) {\n if (zoom === undefined) {\n return this._private.minZoom;\n } else {\n return this.zoomRange({\n min: zoom\n });\n }\n },\n maxZoom: function maxZoom(zoom) {\n if (zoom === undefined) {\n return this._private.maxZoom;\n } else {\n return this.zoomRange({\n max: zoom\n });\n }\n },\n getZoomedViewport: function getZoomedViewport(params) {\n var _p = this._private;\n var currentPan = _p.pan;\n var currentZoom = _p.zoom;\n var pos; // in rendered px\n var zoom;\n var bail = false;\n if (!_p.zoomingEnabled) {\n // zooming disabled\n bail = true;\n }\n if (number$1(params)) {\n // then set the zoom\n zoom = params;\n } else if (plainObject(params)) {\n // then zoom about a point\n zoom = params.level;\n if (params.position != null) {\n pos = modelToRenderedPosition(params.position, currentZoom, currentPan);\n } else if (params.renderedPosition != null) {\n pos = params.renderedPosition;\n }\n if (pos != null && !_p.panningEnabled) {\n // panning disabled\n bail = true;\n }\n }\n\n // crop zoom\n zoom = zoom > _p.maxZoom ? _p.maxZoom : zoom;\n zoom = zoom < _p.minZoom ? _p.minZoom : zoom;\n\n // can't zoom with invalid params\n if (bail || !number$1(zoom) || zoom === currentZoom || pos != null && (!number$1(pos.x) || !number$1(pos.y))) {\n return null;\n }\n if (pos != null) {\n // set zoom about position\n var pan1 = currentPan;\n var zoom1 = currentZoom;\n var zoom2 = zoom;\n var pan2 = {\n x: -zoom2 / zoom1 * (pos.x - pan1.x) + pos.x,\n y: -zoom2 / zoom1 * (pos.y - pan1.y) + pos.y\n };\n return {\n zoomed: true,\n panned: true,\n zoom: zoom2,\n pan: pan2\n };\n } else {\n // just set the zoom\n return {\n zoomed: true,\n panned: false,\n zoom: zoom,\n pan: currentPan\n };\n }\n },\n zoom: function zoom(params) {\n if (params === undefined) {\n // get\n return this._private.zoom;\n } else {\n // set\n var vp = this.getZoomedViewport(params);\n var _p = this._private;\n if (vp == null || !vp.zoomed) {\n return this;\n }\n _p.zoom = vp.zoom;\n if (vp.panned) {\n _p.pan.x = vp.pan.x;\n _p.pan.y = vp.pan.y;\n }\n this.emit('zoom' + (vp.panned ? ' pan' : '') + ' viewport');\n this.notify('viewport');\n return this; // chaining\n }\n },\n\n viewport: function viewport(opts) {\n var _p = this._private;\n var zoomDefd = true;\n var panDefd = true;\n var events = []; // to trigger\n var zoomFailed = false;\n var panFailed = false;\n if (!opts) {\n return this;\n }\n if (!number$1(opts.zoom)) {\n zoomDefd = false;\n }\n if (!plainObject(opts.pan)) {\n panDefd = false;\n }\n if (!zoomDefd && !panDefd) {\n return this;\n }\n if (zoomDefd) {\n var z = opts.zoom;\n if (z < _p.minZoom || z > _p.maxZoom || !_p.zoomingEnabled) {\n zoomFailed = true;\n } else {\n _p.zoom = z;\n events.push('zoom');\n }\n }\n if (panDefd && (!zoomFailed || !opts.cancelOnFailedZoom) && _p.panningEnabled) {\n var p = opts.pan;\n if (number$1(p.x)) {\n _p.pan.x = p.x;\n panFailed = false;\n }\n if (number$1(p.y)) {\n _p.pan.y = p.y;\n panFailed = false;\n }\n if (!panFailed) {\n events.push('pan');\n }\n }\n if (events.length > 0) {\n events.push('viewport');\n this.emit(events.join(' '));\n this.notify('viewport');\n }\n return this; // chaining\n },\n\n center: function center(elements) {\n var pan = this.getCenterPan(elements);\n if (pan) {\n this._private.pan = pan;\n this.emit('pan viewport');\n this.notify('viewport');\n }\n return this; // chaining\n },\n\n getCenterPan: function getCenterPan(elements, zoom) {\n if (!this._private.panningEnabled) {\n return;\n }\n if (string(elements)) {\n var selector = elements;\n elements = this.mutableElements().filter(selector);\n } else if (!elementOrCollection(elements)) {\n elements = this.mutableElements();\n }\n if (elements.length === 0) {\n return;\n } // can't centre pan to nothing\n\n var bb = elements.boundingBox();\n var w = this.width();\n var h = this.height();\n zoom = zoom === undefined ? this._private.zoom : zoom;\n var pan = {\n // middle\n x: (w - zoom * (bb.x1 + bb.x2)) / 2,\n y: (h - zoom * (bb.y1 + bb.y2)) / 2\n };\n return pan;\n },\n reset: function reset() {\n if (!this._private.panningEnabled || !this._private.zoomingEnabled) {\n return this;\n }\n this.viewport({\n pan: {\n x: 0,\n y: 0\n },\n zoom: 1\n });\n return this; // chaining\n },\n\n invalidateSize: function invalidateSize() {\n this._private.sizeCache = null;\n },\n size: function size() {\n var _p = this._private;\n var container = _p.container;\n var cy = this;\n return _p.sizeCache = _p.sizeCache || (container ? function () {\n var style = cy.window().getComputedStyle(container);\n var val = function val(name) {\n return parseFloat(style.getPropertyValue(name));\n };\n return {\n width: container.clientWidth - val('padding-left') - val('padding-right'),\n height: container.clientHeight - val('padding-top') - val('padding-bottom')\n };\n }() : {\n // fallback if no container (not 0 b/c can be used for dividing etc)\n width: 1,\n height: 1\n });\n },\n width: function width() {\n return this.size().width;\n },\n height: function height() {\n return this.size().height;\n },\n extent: function extent() {\n var pan = this._private.pan;\n var zoom = this._private.zoom;\n var rb = this.renderedExtent();\n var b = {\n x1: (rb.x1 - pan.x) / zoom,\n x2: (rb.x2 - pan.x) / zoom,\n y1: (rb.y1 - pan.y) / zoom,\n y2: (rb.y2 - pan.y) / zoom\n };\n b.w = b.x2 - b.x1;\n b.h = b.y2 - b.y1;\n return b;\n },\n renderedExtent: function renderedExtent() {\n var width = this.width();\n var height = this.height();\n return {\n x1: 0,\n y1: 0,\n x2: width,\n y2: height,\n w: width,\n h: height\n };\n },\n multiClickDebounceTime: function multiClickDebounceTime(_int) {\n if (_int) this._private.multiClickDebounceTime = _int;else return this._private.multiClickDebounceTime;\n return this; // chaining\n }\n};\n\n// aliases\ncorefn$1.centre = corefn$1.center;\n\n// backwards compatibility\ncorefn$1.autolockNodes = corefn$1.autolock;\ncorefn$1.autoungrabifyNodes = corefn$1.autoungrabify;\n\nvar fn = {\n data: define.data({\n field: 'data',\n bindingEvent: 'data',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'data',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true,\n updateStyle: true\n }),\n removeData: define.removeData({\n field: 'data',\n event: 'data',\n triggerFnName: 'trigger',\n triggerEvent: true,\n updateStyle: true\n }),\n scratch: define.data({\n field: 'scratch',\n bindingEvent: 'scratch',\n allowBinding: true,\n allowSetting: true,\n settingEvent: 'scratch',\n settingTriggersEvent: true,\n triggerFnName: 'trigger',\n allowGetting: true,\n updateStyle: true\n }),\n removeScratch: define.removeData({\n field: 'scratch',\n event: 'scratch',\n triggerFnName: 'trigger',\n triggerEvent: true,\n updateStyle: true\n })\n};\n\n// aliases\nfn.attr = fn.data;\nfn.removeAttr = fn.removeData;\n\nvar Core = function Core(opts) {\n var cy = this;\n opts = extend({}, opts);\n var container = opts.container;\n\n // allow for passing a wrapped jquery object\n // e.g. cytoscape({ container: $('#cy') })\n if (container && !htmlElement(container) && htmlElement(container[0])) {\n container = container[0];\n }\n var reg = container ? container._cyreg : null; // e.g. already registered some info (e.g. readies) via jquery\n reg = reg || {};\n if (reg && reg.cy) {\n reg.cy.destroy();\n reg = {}; // old instance => replace reg completely\n }\n\n var readies = reg.readies = reg.readies || [];\n if (container) {\n container._cyreg = reg;\n } // make sure container assoc'd reg points to this cy\n reg.cy = cy;\n var head = _window !== undefined && container !== undefined && !opts.headless;\n var options = opts;\n options.layout = extend({\n name: head ? 'grid' : 'null'\n }, options.layout);\n options.renderer = extend({\n name: head ? 'canvas' : 'null'\n }, options.renderer);\n var defVal = function defVal(def, val, altVal) {\n if (val !== undefined) {\n return val;\n } else if (altVal !== undefined) {\n return altVal;\n } else {\n return def;\n }\n };\n var _p = this._private = {\n container: container,\n // html dom ele container\n ready: false,\n // whether ready has been triggered\n options: options,\n // cached options\n elements: new Collection(this),\n // elements in the graph\n listeners: [],\n // list of listeners\n aniEles: new Collection(this),\n // elements being animated\n data: options.data || {},\n // data for the core\n scratch: {},\n // scratch object for core\n layout: null,\n renderer: null,\n destroyed: false,\n // whether destroy was called\n notificationsEnabled: true,\n // whether notifications are sent to the renderer\n minZoom: 1e-50,\n maxZoom: 1e50,\n zoomingEnabled: defVal(true, options.zoomingEnabled),\n userZoomingEnabled: defVal(true, options.userZoomingEnabled),\n panningEnabled: defVal(true, options.panningEnabled),\n userPanningEnabled: defVal(true, options.userPanningEnabled),\n boxSelectionEnabled: defVal(true, options.boxSelectionEnabled),\n autolock: defVal(false, options.autolock, options.autolockNodes),\n autoungrabify: defVal(false, options.autoungrabify, options.autoungrabifyNodes),\n autounselectify: defVal(false, options.autounselectify),\n styleEnabled: options.styleEnabled === undefined ? head : options.styleEnabled,\n zoom: number$1(options.zoom) ? options.zoom : 1,\n pan: {\n x: plainObject(options.pan) && number$1(options.pan.x) ? options.pan.x : 0,\n y: plainObject(options.pan) && number$1(options.pan.y) ? options.pan.y : 0\n },\n animation: {\n // object for currently-running animations\n current: [],\n queue: []\n },\n hasCompoundNodes: false,\n multiClickDebounceTime: defVal(250, options.multiClickDebounceTime)\n };\n this.createEmitter();\n\n // set selection type\n this.selectionType(options.selectionType);\n\n // init zoom bounds\n this.zoomRange({\n min: options.minZoom,\n max: options.maxZoom\n });\n var loadExtData = function loadExtData(extData, next) {\n var anyIsPromise = extData.some(promise);\n if (anyIsPromise) {\n return Promise$1.all(extData).then(next); // load all data asynchronously, then exec rest of init\n } else {\n next(extData); // exec synchronously for convenience\n }\n };\n\n // start with the default stylesheet so we have something before loading an external stylesheet\n if (_p.styleEnabled) {\n cy.setStyle([]);\n }\n\n // create the renderer\n var rendererOptions = extend({}, options, options.renderer); // allow rendering hints in top level options\n cy.initRenderer(rendererOptions);\n var setElesAndLayout = function setElesAndLayout(elements, onload, ondone) {\n cy.notifications(false);\n\n // remove old elements\n var oldEles = cy.mutableElements();\n if (oldEles.length > 0) {\n oldEles.remove();\n }\n if (elements != null) {\n if (plainObject(elements) || array(elements)) {\n cy.add(elements);\n }\n }\n cy.one('layoutready', function (e) {\n cy.notifications(true);\n cy.emit(e); // we missed this event by turning notifications off, so pass it on\n\n cy.one('load', onload);\n cy.emitAndNotify('load');\n }).one('layoutstop', function () {\n cy.one('done', ondone);\n cy.emit('done');\n });\n var layoutOpts = extend({}, cy._private.options.layout);\n layoutOpts.eles = cy.elements();\n cy.layout(layoutOpts).run();\n };\n loadExtData([options.style, options.elements], function (thens) {\n var initStyle = thens[0];\n var initEles = thens[1];\n\n // init style\n if (_p.styleEnabled) {\n cy.style().append(initStyle);\n }\n\n // initial load\n setElesAndLayout(initEles, function () {\n // onready\n cy.startAnimationLoop();\n _p.ready = true;\n\n // if a ready callback is specified as an option, the bind it\n if (fn$6(options.ready)) {\n cy.on('ready', options.ready);\n }\n\n // bind all the ready handlers registered before creating this instance\n for (var i = 0; i < readies.length; i++) {\n var fn = readies[i];\n cy.on('ready', fn);\n }\n if (reg) {\n reg.readies = [];\n } // clear b/c we've bound them all and don't want to keep it around in case a new core uses the same div etc\n\n cy.emit('ready');\n }, options.done);\n });\n};\nvar corefn = Core.prototype; // short alias\n\nextend(corefn, {\n instanceString: function instanceString() {\n return 'core';\n },\n isReady: function isReady() {\n return this._private.ready;\n },\n destroyed: function destroyed() {\n return this._private.destroyed;\n },\n ready: function ready(fn) {\n if (this.isReady()) {\n this.emitter().emit('ready', [], fn); // just calls fn as though triggered via ready event\n } else {\n this.on('ready', fn);\n }\n return this;\n },\n destroy: function destroy() {\n var cy = this;\n if (cy.destroyed()) return;\n cy.stopAnimationLoop();\n cy.destroyRenderer();\n this.emit('destroy');\n cy._private.destroyed = true;\n return cy;\n },\n hasElementWithId: function hasElementWithId(id) {\n return this._private.elements.hasElementWithId(id);\n },\n getElementById: function getElementById(id) {\n return this._private.elements.getElementById(id);\n },\n hasCompoundNodes: function hasCompoundNodes() {\n return this._private.hasCompoundNodes;\n },\n headless: function headless() {\n return this._private.renderer.isHeadless();\n },\n styleEnabled: function styleEnabled() {\n return this._private.styleEnabled;\n },\n addToPool: function addToPool(eles) {\n this._private.elements.merge(eles);\n return this; // chaining\n },\n\n removeFromPool: function removeFromPool(eles) {\n this._private.elements.unmerge(eles);\n return this;\n },\n container: function container() {\n return this._private.container || null;\n },\n window: function window() {\n var container = this._private.container;\n if (container == null) return _window;\n var ownerDocument = this._private.container.ownerDocument;\n if (ownerDocument === undefined || ownerDocument == null) {\n return _window;\n }\n return ownerDocument.defaultView || _window;\n },\n mount: function mount(container) {\n if (container == null) {\n return;\n }\n var cy = this;\n var _p = cy._private;\n var options = _p.options;\n if (!htmlElement(container) && htmlElement(container[0])) {\n container = container[0];\n }\n cy.stopAnimationLoop();\n cy.destroyRenderer();\n _p.container = container;\n _p.styleEnabled = true;\n cy.invalidateSize();\n cy.initRenderer(extend({}, options, options.renderer, {\n // allow custom renderer name to be re-used, otherwise use canvas\n name: options.renderer.name === 'null' ? 'canvas' : options.renderer.name\n }));\n cy.startAnimationLoop();\n cy.style(options.style);\n cy.emit('mount');\n return cy;\n },\n unmount: function unmount() {\n var cy = this;\n cy.stopAnimationLoop();\n cy.destroyRenderer();\n cy.initRenderer({\n name: 'null'\n });\n cy.emit('unmount');\n return cy;\n },\n options: function options() {\n return copy(this._private.options);\n },\n json: function json(obj) {\n var cy = this;\n var _p = cy._private;\n var eles = cy.mutableElements();\n var getFreshRef = function getFreshRef(ele) {\n return cy.getElementById(ele.id());\n };\n if (plainObject(obj)) {\n // set\n\n cy.startBatch();\n if (obj.elements) {\n var idInJson = {};\n var updateEles = function updateEles(jsons, gr) {\n var toAdd = [];\n var toMod = [];\n for (var i = 0; i < jsons.length; i++) {\n var json = jsons[i];\n if (!json.data.id) {\n warn('cy.json() cannot handle elements without an ID attribute');\n continue;\n }\n var id = '' + json.data.id; // id must be string\n var ele = cy.getElementById(id);\n idInJson[id] = true;\n if (ele.length !== 0) {\n // existing element should be updated\n toMod.push({\n ele: ele,\n json: json\n });\n } else {\n // otherwise should be added\n if (gr) {\n json.group = gr;\n toAdd.push(json);\n } else {\n toAdd.push(json);\n }\n }\n }\n cy.add(toAdd);\n for (var _i = 0; _i < toMod.length; _i++) {\n var _toMod$_i = toMod[_i],\n _ele = _toMod$_i.ele,\n _json = _toMod$_i.json;\n _ele.json(_json);\n }\n };\n if (array(obj.elements)) {\n // elements: []\n updateEles(obj.elements);\n } else {\n // elements: { nodes: [], edges: [] }\n var grs = ['nodes', 'edges'];\n for (var i = 0; i < grs.length; i++) {\n var gr = grs[i];\n var elements = obj.elements[gr];\n if (array(elements)) {\n updateEles(elements, gr);\n }\n }\n }\n var parentsToRemove = cy.collection();\n eles.filter(function (ele) {\n return !idInJson[ele.id()];\n }).forEach(function (ele) {\n if (ele.isParent()) {\n parentsToRemove.merge(ele);\n } else {\n ele.remove();\n }\n });\n\n // so that children are not removed w/parent\n parentsToRemove.forEach(function (ele) {\n return ele.children().move({\n parent: null\n });\n });\n\n // intermediate parents may be moved by prior line, so make sure we remove by fresh refs\n parentsToRemove.forEach(function (ele) {\n return getFreshRef(ele).remove();\n });\n }\n if (obj.style) {\n cy.style(obj.style);\n }\n if (obj.zoom != null && obj.zoom !== _p.zoom) {\n cy.zoom(obj.zoom);\n }\n if (obj.pan) {\n if (obj.pan.x !== _p.pan.x || obj.pan.y !== _p.pan.y) {\n cy.pan(obj.pan);\n }\n }\n if (obj.data) {\n cy.data(obj.data);\n }\n var fields = ['minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'panningEnabled', 'userPanningEnabled', 'boxSelectionEnabled', 'autolock', 'autoungrabify', 'autounselectify', 'multiClickDebounceTime'];\n for (var _i2 = 0; _i2 < fields.length; _i2++) {\n var f = fields[_i2];\n if (obj[f] != null) {\n cy[f](obj[f]);\n }\n }\n cy.endBatch();\n return this; // chaining\n } else {\n // get\n var flat = !!obj;\n var json = {};\n if (flat) {\n json.elements = this.elements().map(function (ele) {\n return ele.json();\n });\n } else {\n json.elements = {};\n eles.forEach(function (ele) {\n var group = ele.group();\n if (!json.elements[group]) {\n json.elements[group] = [];\n }\n json.elements[group].push(ele.json());\n });\n }\n if (this._private.styleEnabled) {\n json.style = cy.style().json();\n }\n json.data = copy(cy.data());\n var options = _p.options;\n json.zoomingEnabled = _p.zoomingEnabled;\n json.userZoomingEnabled = _p.userZoomingEnabled;\n json.zoom = _p.zoom;\n json.minZoom = _p.minZoom;\n json.maxZoom = _p.maxZoom;\n json.panningEnabled = _p.panningEnabled;\n json.userPanningEnabled = _p.userPanningEnabled;\n json.pan = copy(_p.pan);\n json.boxSelectionEnabled = _p.boxSelectionEnabled;\n json.renderer = copy(options.renderer);\n json.hideEdgesOnViewport = options.hideEdgesOnViewport;\n json.textureOnViewport = options.textureOnViewport;\n json.wheelSensitivity = options.wheelSensitivity;\n json.motionBlur = options.motionBlur;\n json.multiClickDebounceTime = options.multiClickDebounceTime;\n return json;\n }\n }\n});\ncorefn.$id = corefn.getElementById;\n[corefn$9, corefn$8, elesfn, corefn$7, corefn$6, corefn$5, corefn$4, corefn$3, corefn$2, corefn$1, fn].forEach(function (props) {\n extend(corefn, props);\n});\n\n/* eslint-disable no-unused-vars */\nvar defaults$7 = {\n fit: true,\n // whether to fit the viewport to the graph\n directed: false,\n // whether the tree is directed downwards (or edges can point in any direction if false)\n padding: 30,\n // padding on fit\n circle: false,\n // put depths in concentric circles if true, put depths top down if false\n grid: false,\n // whether to create an even grid into which the DAG is placed (circle:false only)\n spacingFactor: 1.75,\n // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)\n boundingBox: undefined,\n // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true,\n // prevents node overlap, may overflow boundingBox if not enough space\n nodeDimensionsIncludeLabels: false,\n // Excludes the label when calculating node bounding boxes for the layout algorithm\n roots: undefined,\n // the roots of the trees\n depthSort: undefined,\n // a sorting function to order nodes at equal depth. e.g. function(a, b){ return a.data('weight') - b.data('weight') }\n animate: false,\n // whether to transition the node positions\n animationDuration: 500,\n // duration of animation in ms if enabled\n animationEasing: undefined,\n // easing of animation if enabled,\n animateFilter: function animateFilter(node, i) {\n return true;\n },\n // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts\n ready: undefined,\n // callback on layoutready\n stop: undefined,\n // callback on layoutstop\n transform: function transform(node, position) {\n return position;\n } // transform a given node position. Useful for changing flow direction in discrete layouts\n};\n\nvar deprecatedOptionDefaults = {\n maximal: false,\n // whether to shift nodes down their natural BFS depths in order to avoid upwards edges (DAGS only); setting acyclic to true sets maximal to true also\n acyclic: false // whether the tree is acyclic and thus a node could be shifted (due to the maximal option) multiple times without causing an infinite loop; setting to true sets maximal to true also; if you are uncertain whether a tree is acyclic, set to false to avoid potential infinite loops\n};\n\n/* eslint-enable */\n\nvar getInfo = function getInfo(ele) {\n return ele.scratch('breadthfirst');\n};\nvar setInfo = function setInfo(ele, obj) {\n return ele.scratch('breadthfirst', obj);\n};\nfunction BreadthFirstLayout(options) {\n this.options = extend({}, defaults$7, deprecatedOptionDefaults, options);\n}\nBreadthFirstLayout.prototype.run = function () {\n var params = this.options;\n var options = params;\n var cy = params.cy;\n var eles = options.eles;\n var nodes = eles.nodes().filter(function (n) {\n return !n.isParent();\n });\n var graph = eles;\n var directed = options.directed;\n var maximal = options.acyclic || options.maximal || options.maximalAdjustments > 0; // maximalAdjustments for compat. w/ old code; also, setting acyclic to true sets maximal to true\n\n var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {\n x1: 0,\n y1: 0,\n w: cy.width(),\n h: cy.height()\n });\n var roots;\n if (elementOrCollection(options.roots)) {\n roots = options.roots;\n } else if (array(options.roots)) {\n var rootsArray = [];\n for (var i = 0; i < options.roots.length; i++) {\n var id = options.roots[i];\n var ele = cy.getElementById(id);\n rootsArray.push(ele);\n }\n roots = cy.collection(rootsArray);\n } else if (string(options.roots)) {\n roots = cy.$(options.roots);\n } else {\n if (directed) {\n roots = nodes.roots();\n } else {\n var components = eles.components();\n roots = cy.collection();\n var _loop = function _loop(_i) {\n var comp = components[_i];\n var maxDegree = comp.maxDegree(false);\n var compRoots = comp.filter(function (ele) {\n return ele.degree(false) === maxDegree;\n });\n roots = roots.add(compRoots);\n };\n for (var _i = 0; _i < components.length; _i++) {\n _loop(_i);\n }\n }\n }\n var depths = [];\n var foundByBfs = {};\n var addToDepth = function addToDepth(ele, d) {\n if (depths[d] == null) {\n depths[d] = [];\n }\n var i = depths[d].length;\n depths[d].push(ele);\n setInfo(ele, {\n index: i,\n depth: d\n });\n };\n var changeDepth = function changeDepth(ele, newDepth) {\n var _getInfo = getInfo(ele),\n depth = _getInfo.depth,\n index = _getInfo.index;\n depths[depth][index] = null;\n addToDepth(ele, newDepth);\n };\n\n // find the depths of the nodes\n graph.bfs({\n roots: roots,\n directed: options.directed,\n visit: function visit(node, edge, pNode, i, depth) {\n var ele = node[0];\n var id = ele.id();\n addToDepth(ele, depth);\n foundByBfs[id] = true;\n }\n });\n\n // check for nodes not found by bfs\n var orphanNodes = [];\n for (var _i2 = 0; _i2 < nodes.length; _i2++) {\n var _ele = nodes[_i2];\n if (foundByBfs[_ele.id()]) {\n continue;\n } else {\n orphanNodes.push(_ele);\n }\n }\n\n // assign the nodes a depth and index\n\n var assignDepthsAt = function assignDepthsAt(i) {\n var eles = depths[i];\n for (var j = 0; j < eles.length; j++) {\n var _ele2 = eles[j];\n if (_ele2 == null) {\n eles.splice(j, 1);\n j--;\n continue;\n }\n setInfo(_ele2, {\n depth: i,\n index: j\n });\n }\n };\n var assignDepths = function assignDepths() {\n for (var _i3 = 0; _i3 < depths.length; _i3++) {\n assignDepthsAt(_i3);\n }\n };\n var adjustMaximally = function adjustMaximally(ele, shifted) {\n var eInfo = getInfo(ele);\n var incomers = ele.incomers().filter(function (el) {\n return el.isNode() && eles.has(el);\n });\n var maxDepth = -1;\n var id = ele.id();\n for (var k = 0; k < incomers.length; k++) {\n var incmr = incomers[k];\n var iInfo = getInfo(incmr);\n maxDepth = Math.max(maxDepth, iInfo.depth);\n }\n if (eInfo.depth <= maxDepth) {\n if (!options.acyclic && shifted[id]) {\n return null;\n }\n var newDepth = maxDepth + 1;\n changeDepth(ele, newDepth);\n shifted[id] = newDepth;\n return true;\n }\n return false;\n };\n\n // for the directed case, try to make the edges all go down (i.e. depth i => depth i + 1)\n if (directed && maximal) {\n var Q = [];\n var shifted = {};\n var enqueue = function enqueue(n) {\n return Q.push(n);\n };\n var dequeue = function dequeue() {\n return Q.shift();\n };\n nodes.forEach(function (n) {\n return Q.push(n);\n });\n while (Q.length > 0) {\n var _ele3 = dequeue();\n var didShift = adjustMaximally(_ele3, shifted);\n if (didShift) {\n _ele3.outgoers().filter(function (el) {\n return el.isNode() && eles.has(el);\n }).forEach(enqueue);\n } else if (didShift === null) {\n warn('Detected double maximal shift for node `' + _ele3.id() + '`. Bailing maximal adjustment due to cycle. Use `options.maximal: true` only on DAGs.');\n break; // exit on failure\n }\n }\n }\n\n assignDepths(); // clear holes\n\n // find min distance we need to leave between nodes\n var minDistance = 0;\n if (options.avoidOverlap) {\n for (var _i4 = 0; _i4 < nodes.length; _i4++) {\n var n = nodes[_i4];\n var nbb = n.layoutDimensions(options);\n var w = nbb.w;\n var h = nbb.h;\n minDistance = Math.max(minDistance, w, h);\n }\n }\n\n // get the weighted percent for an element based on its connectivity to other levels\n var cachedWeightedPercent = {};\n var getWeightedPercent = function getWeightedPercent(ele) {\n if (cachedWeightedPercent[ele.id()]) {\n return cachedWeightedPercent[ele.id()];\n }\n var eleDepth = getInfo(ele).depth;\n var neighbors = ele.neighborhood();\n var percent = 0;\n var samples = 0;\n for (var _i5 = 0; _i5 < neighbors.length; _i5++) {\n var neighbor = neighbors[_i5];\n if (neighbor.isEdge() || neighbor.isParent() || !nodes.has(neighbor)) {\n continue;\n }\n var bf = getInfo(neighbor);\n if (bf == null) {\n continue;\n }\n var index = bf.index;\n var depth = bf.depth;\n\n // unassigned neighbours shouldn't affect the ordering\n if (index == null || depth == null) {\n continue;\n }\n var nDepth = depths[depth].length;\n if (depth < eleDepth) {\n // only get influenced by elements above\n percent += index / nDepth;\n samples++;\n }\n }\n samples = Math.max(1, samples);\n percent = percent / samples;\n if (samples === 0) {\n // put lone nodes at the start\n percent = 0;\n }\n cachedWeightedPercent[ele.id()] = percent;\n return percent;\n };\n\n // rearrange the indices in each depth level based on connectivity\n\n var sortFn = function sortFn(a, b) {\n var apct = getWeightedPercent(a);\n var bpct = getWeightedPercent(b);\n var diff = apct - bpct;\n if (diff === 0) {\n return ascending(a.id(), b.id()); // make sure sort doesn't have don't-care comparisons\n } else {\n return diff;\n }\n };\n if (options.depthSort !== undefined) {\n sortFn = options.depthSort;\n }\n\n // sort each level to make connected nodes closer\n for (var _i6 = 0; _i6 < depths.length; _i6++) {\n depths[_i6].sort(sortFn);\n assignDepthsAt(_i6);\n }\n\n // assign orphan nodes to a new top-level depth\n var orphanDepth = [];\n for (var _i7 = 0; _i7 < orphanNodes.length; _i7++) {\n orphanDepth.push(orphanNodes[_i7]);\n }\n depths.unshift(orphanDepth);\n assignDepths();\n var biggestDepthSize = 0;\n for (var _i8 = 0; _i8 < depths.length; _i8++) {\n biggestDepthSize = Math.max(depths[_i8].length, biggestDepthSize);\n }\n var center = {\n x: bb.x1 + bb.w / 2,\n y: bb.x1 + bb.h / 2\n };\n var maxDepthSize = depths.reduce(function (max, eles) {\n return Math.max(max, eles.length);\n }, 0);\n var getPosition = function getPosition(ele) {\n var _getInfo2 = getInfo(ele),\n depth = _getInfo2.depth,\n index = _getInfo2.index;\n var depthSize = depths[depth].length;\n var distanceX = Math.max(bb.w / ((options.grid ? maxDepthSize : depthSize) + 1), minDistance);\n var distanceY = Math.max(bb.h / (depths.length + 1), minDistance);\n var radiusStepSize = Math.min(bb.w / 2 / depths.length, bb.h / 2 / depths.length);\n radiusStepSize = Math.max(radiusStepSize, minDistance);\n if (!options.circle) {\n var epos = {\n x: center.x + (index + 1 - (depthSize + 1) / 2) * distanceX,\n y: (depth + 1) * distanceY\n };\n return epos;\n } else {\n var radius = radiusStepSize * depth + radiusStepSize - (depths.length > 0 && depths[0].length <= 3 ? radiusStepSize / 2 : 0);\n var theta = 2 * Math.PI / depths[depth].length * index;\n if (depth === 0 && depths[0].length === 1) {\n radius = 1;\n }\n return {\n x: center.x + radius * Math.cos(theta),\n y: center.y + radius * Math.sin(theta)\n };\n }\n };\n eles.nodes().layoutPositions(this, options, getPosition);\n return this; // chaining\n};\n\nvar defaults$6 = {\n fit: true,\n // whether to fit the viewport to the graph\n padding: 30,\n // the padding on fit\n boundingBox: undefined,\n // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true,\n // prevents node overlap, may overflow boundingBox and radius if not enough space\n nodeDimensionsIncludeLabels: false,\n // Excludes the label when calculating node bounding boxes for the layout algorithm\n spacingFactor: undefined,\n // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up\n radius: undefined,\n // the radius of the circle\n startAngle: 3 / 2 * Math.PI,\n // where nodes start in radians\n sweep: undefined,\n // how many radians should be between the first and last node (defaults to full circle)\n clockwise: true,\n // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)\n sort: undefined,\n // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }\n animate: false,\n // whether to transition the node positions\n animationDuration: 500,\n // duration of animation in ms if enabled\n animationEasing: undefined,\n // easing of animation if enabled\n animateFilter: function animateFilter(node, i) {\n return true;\n },\n // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts\n ready: undefined,\n // callback on layoutready\n stop: undefined,\n // callback on layoutstop\n transform: function transform(node, position) {\n return position;\n } // transform a given node position. Useful for changing flow direction in discrete layouts \n};\n\nfunction CircleLayout(options) {\n this.options = extend({}, defaults$6, options);\n}\nCircleLayout.prototype.run = function () {\n var params = this.options;\n var options = params;\n var cy = params.cy;\n var eles = options.eles;\n var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;\n var nodes = eles.nodes().not(':parent');\n if (options.sort) {\n nodes = nodes.sort(options.sort);\n }\n var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {\n x1: 0,\n y1: 0,\n w: cy.width(),\n h: cy.height()\n });\n var center = {\n x: bb.x1 + bb.w / 2,\n y: bb.y1 + bb.h / 2\n };\n var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / nodes.length : options.sweep;\n var dTheta = sweep / Math.max(1, nodes.length - 1);\n var r;\n var minDistance = 0;\n for (var i = 0; i < nodes.length; i++) {\n var n = nodes[i];\n var nbb = n.layoutDimensions(options);\n var w = nbb.w;\n var h = nbb.h;\n minDistance = Math.max(minDistance, w, h);\n }\n if (number$1(options.radius)) {\n r = options.radius;\n } else if (nodes.length <= 1) {\n r = 0;\n } else {\n r = Math.min(bb.h, bb.w) / 2 - minDistance;\n }\n\n // calculate the radius\n if (nodes.length > 1 && options.avoidOverlap) {\n // but only if more than one node (can't overlap)\n minDistance *= 1.75; // just to have some nice spacing\n\n var dcos = Math.cos(dTheta) - Math.cos(0);\n var dsin = Math.sin(dTheta) - Math.sin(0);\n var rMin = Math.sqrt(minDistance * minDistance / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping\n r = Math.max(rMin, r);\n }\n var getPos = function getPos(ele, i) {\n var theta = options.startAngle + i * dTheta * (clockwise ? 1 : -1);\n var rx = r * Math.cos(theta);\n var ry = r * Math.sin(theta);\n var pos = {\n x: center.x + rx,\n y: center.y + ry\n };\n return pos;\n };\n eles.nodes().layoutPositions(this, options, getPos);\n return this; // chaining\n};\n\nvar defaults$5 = {\n fit: true,\n // whether to fit the viewport to the graph\n padding: 30,\n // the padding on fit\n startAngle: 3 / 2 * Math.PI,\n // where nodes start in radians\n sweep: undefined,\n // how many radians should be between the first and last node (defaults to full circle)\n clockwise: true,\n // whether the layout should go clockwise (true) or counterclockwise/anticlockwise (false)\n equidistant: false,\n // whether levels have an equal radial distance betwen them, may cause bounding box overflow\n minNodeSpacing: 10,\n // min spacing between outside of nodes (used for radius adjustment)\n boundingBox: undefined,\n // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true,\n // prevents node overlap, may overflow boundingBox if not enough space\n nodeDimensionsIncludeLabels: false,\n // Excludes the label when calculating node bounding boxes for the layout algorithm\n height: undefined,\n // height of layout area (overrides container height)\n width: undefined,\n // width of layout area (overrides container width)\n spacingFactor: undefined,\n // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up\n concentric: function concentric(node) {\n // returns numeric value for each node, placing higher nodes in levels towards the centre\n return node.degree();\n },\n levelWidth: function levelWidth(nodes) {\n // the variation of concentric values in each level\n return nodes.maxDegree() / 4;\n },\n animate: false,\n // whether to transition the node positions\n animationDuration: 500,\n // duration of animation in ms if enabled\n animationEasing: undefined,\n // easing of animation if enabled\n animateFilter: function animateFilter(node, i) {\n return true;\n },\n // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts\n ready: undefined,\n // callback on layoutready\n stop: undefined,\n // callback on layoutstop\n transform: function transform(node, position) {\n return position;\n } // transform a given node position. Useful for changing flow direction in discrete layouts\n};\n\nfunction ConcentricLayout(options) {\n this.options = extend({}, defaults$5, options);\n}\nConcentricLayout.prototype.run = function () {\n var params = this.options;\n var options = params;\n var clockwise = options.counterclockwise !== undefined ? !options.counterclockwise : options.clockwise;\n var cy = params.cy;\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {\n x1: 0,\n y1: 0,\n w: cy.width(),\n h: cy.height()\n });\n var center = {\n x: bb.x1 + bb.w / 2,\n y: bb.y1 + bb.h / 2\n };\n var nodeValues = []; // { node, value }\n var maxNodeSize = 0;\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n var value = void 0;\n\n // calculate the node value\n value = options.concentric(node);\n nodeValues.push({\n value: value,\n node: node\n });\n\n // for style mapping\n node._private.scratch.concentric = value;\n }\n\n // in case we used the `concentric` in style\n nodes.updateStyle();\n\n // calculate max size now based on potentially updated mappers\n for (var _i = 0; _i < nodes.length; _i++) {\n var _node = nodes[_i];\n var nbb = _node.layoutDimensions(options);\n maxNodeSize = Math.max(maxNodeSize, nbb.w, nbb.h);\n }\n\n // sort node values in descreasing order\n nodeValues.sort(function (a, b) {\n return b.value - a.value;\n });\n var levelWidth = options.levelWidth(nodes);\n\n // put the values into levels\n var levels = [[]];\n var currentLevel = levels[0];\n for (var _i2 = 0; _i2 < nodeValues.length; _i2++) {\n var val = nodeValues[_i2];\n if (currentLevel.length > 0) {\n var diff = Math.abs(currentLevel[0].value - val.value);\n if (diff >= levelWidth) {\n currentLevel = [];\n levels.push(currentLevel);\n }\n }\n currentLevel.push(val);\n }\n\n // create positions from levels\n\n var minDist = maxNodeSize + options.minNodeSpacing; // min dist between nodes\n\n if (!options.avoidOverlap) {\n // then strictly constrain to bb\n var firstLvlHasMulti = levels.length > 0 && levels[0].length > 1;\n var maxR = Math.min(bb.w, bb.h) / 2 - minDist;\n var rStep = maxR / (levels.length + firstLvlHasMulti ? 1 : 0);\n minDist = Math.min(minDist, rStep);\n }\n\n // find the metrics for each level\n var r = 0;\n for (var _i3 = 0; _i3 < levels.length; _i3++) {\n var level = levels[_i3];\n var sweep = options.sweep === undefined ? 2 * Math.PI - 2 * Math.PI / level.length : options.sweep;\n var dTheta = level.dTheta = sweep / Math.max(1, level.length - 1);\n\n // calculate the radius\n if (level.length > 1 && options.avoidOverlap) {\n // but only if more than one node (can't overlap)\n var dcos = Math.cos(dTheta) - Math.cos(0);\n var dsin = Math.sin(dTheta) - Math.sin(0);\n var rMin = Math.sqrt(minDist * minDist / (dcos * dcos + dsin * dsin)); // s.t. no nodes overlapping\n\n r = Math.max(rMin, r);\n }\n level.r = r;\n r += minDist;\n }\n if (options.equidistant) {\n var rDeltaMax = 0;\n var _r = 0;\n for (var _i4 = 0; _i4 < levels.length; _i4++) {\n var _level = levels[_i4];\n var rDelta = _level.r - _r;\n rDeltaMax = Math.max(rDeltaMax, rDelta);\n }\n _r = 0;\n for (var _i5 = 0; _i5 < levels.length; _i5++) {\n var _level2 = levels[_i5];\n if (_i5 === 0) {\n _r = _level2.r;\n }\n _level2.r = _r;\n _r += rDeltaMax;\n }\n }\n\n // calculate the node positions\n var pos = {}; // id => position\n for (var _i6 = 0; _i6 < levels.length; _i6++) {\n var _level3 = levels[_i6];\n var _dTheta = _level3.dTheta;\n var _r2 = _level3.r;\n for (var j = 0; j < _level3.length; j++) {\n var _val = _level3[j];\n var theta = options.startAngle + (clockwise ? 1 : -1) * _dTheta * j;\n var p = {\n x: center.x + _r2 * Math.cos(theta),\n y: center.y + _r2 * Math.sin(theta)\n };\n pos[_val.node.id()] = p;\n }\n }\n\n // position the nodes\n eles.nodes().layoutPositions(this, options, function (ele) {\n var id = ele.id();\n return pos[id];\n });\n return this; // chaining\n};\n\n/*\nThe CoSE layout was written by Gerardo Huck.\nhttps://www.linkedin.com/in/gerardohuck/\n\nBased on the following article:\nhttp://dl.acm.org/citation.cfm?id=1498047\n\nModifications tracked on Github.\n*/\nvar DEBUG;\n\n/**\n * @brief : default layout options\n */\nvar defaults$4 = {\n // Called on `layoutready`\n ready: function ready() {},\n // Called on `layoutstop`\n stop: function stop() {},\n // Whether to animate while running the layout\n // true : Animate continuously as the layout is running\n // false : Just show the end result\n // 'end' : Animate with the end result, from the initial positions to the end positions\n animate: true,\n // Easing of the animation for animate:'end'\n animationEasing: undefined,\n // The duration of the animation for animate:'end'\n animationDuration: undefined,\n // A function that determines whether the node should be animated\n // All nodes animated by default on animate enabled\n // Non-animated nodes are positioned immediately when the layout starts\n animateFilter: function animateFilter(node, i) {\n return true;\n },\n // The layout animates only after this many milliseconds for animate:true\n // (prevents flashing on fast runs)\n animationThreshold: 250,\n // Number of iterations between consecutive screen positions update\n refresh: 20,\n // Whether to fit the network view after when done\n fit: true,\n // Padding on fit\n padding: 30,\n // Constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n boundingBox: undefined,\n // Excludes the label when calculating node bounding boxes for the layout algorithm\n nodeDimensionsIncludeLabels: false,\n // Randomize the initial positions of the nodes (true) or use existing positions (false)\n randomize: false,\n // Extra spacing between components in non-compound graphs\n componentSpacing: 40,\n // Node repulsion (non overlapping) multiplier\n nodeRepulsion: function nodeRepulsion(node) {\n return 2048;\n },\n // Node repulsion (overlapping) multiplier\n nodeOverlap: 4,\n // Ideal edge (non nested) length\n idealEdgeLength: function idealEdgeLength(edge) {\n return 32;\n },\n // Divisor to compute edge forces\n edgeElasticity: function edgeElasticity(edge) {\n return 32;\n },\n // Nesting factor (multiplier) to compute ideal edge length for nested edges\n nestingFactor: 1.2,\n // Gravity force (constant)\n gravity: 1,\n // Maximum number of iterations to perform\n numIter: 1000,\n // Initial temperature (maximum node displacement)\n initialTemp: 1000,\n // Cooling factor (how the temperature is reduced between consecutive iterations\n coolingFactor: 0.99,\n // Lower temperature threshold (below this point the layout will end)\n minTemp: 1.0\n};\n\n/**\n * @brief : constructor\n * @arg options : object containing layout options\n */\nfunction CoseLayout(options) {\n this.options = extend({}, defaults$4, options);\n this.options.layout = this;\n\n // Exclude any edge that has a source or target node that is not in the set of passed-in nodes\n var nodes = this.options.eles.nodes();\n var edges = this.options.eles.edges();\n var notEdges = edges.filter(function (e) {\n var sourceId = e.source().data('id');\n var targetId = e.target().data('id');\n var hasSource = nodes.some(function (n) {\n return n.data('id') === sourceId;\n });\n var hasTarget = nodes.some(function (n) {\n return n.data('id') === targetId;\n });\n return !hasSource || !hasTarget;\n });\n this.options.eles = this.options.eles.not(notEdges);\n}\n\n/**\n * @brief : runs the layout\n */\nCoseLayout.prototype.run = function () {\n var options = this.options;\n var cy = options.cy;\n var layout = this;\n layout.stopped = false;\n if (options.animate === true || options.animate === false) {\n layout.emit({\n type: 'layoutstart',\n layout: layout\n });\n }\n\n // Set DEBUG - Global variable\n if (true === options.debug) {\n DEBUG = true;\n } else {\n DEBUG = false;\n }\n\n // Initialize layout info\n var layoutInfo = createLayoutInfo(cy, layout, options);\n\n // Show LayoutInfo contents if debugging\n if (DEBUG) {\n printLayoutInfo(layoutInfo);\n }\n\n // If required, randomize node positions\n if (options.randomize) {\n randomizePositions(layoutInfo);\n }\n var startTime = performanceNow();\n var refresh = function refresh() {\n refreshPositions(layoutInfo, cy, options);\n\n // Fit the graph if necessary\n if (true === options.fit) {\n cy.fit(options.padding);\n }\n };\n var mainLoop = function mainLoop(i) {\n if (layout.stopped || i >= options.numIter) {\n // logDebug(\"Layout manually stopped. Stopping computation in step \" + i);\n return false;\n }\n\n // Do one step in the phisical simulation\n step(layoutInfo, options);\n\n // Update temperature\n layoutInfo.temperature = layoutInfo.temperature * options.coolingFactor;\n // logDebug(\"New temperature: \" + layoutInfo.temperature);\n\n if (layoutInfo.temperature < options.minTemp) {\n // logDebug(\"Temperature drop below minimum threshold. Stopping computation in step \" + i);\n return false;\n }\n return true;\n };\n var done = function done() {\n if (options.animate === true || options.animate === false) {\n refresh();\n\n // Layout has finished\n layout.one('layoutstop', options.stop);\n layout.emit({\n type: 'layoutstop',\n layout: layout\n });\n } else {\n var nodes = options.eles.nodes();\n var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes);\n nodes.layoutPositions(layout, options, getScaledPos);\n }\n };\n var i = 0;\n var loopRet = true;\n if (options.animate === true) {\n var frame = function frame() {\n var f = 0;\n while (loopRet && f < options.refresh) {\n loopRet = mainLoop(i);\n i++;\n f++;\n }\n if (!loopRet) {\n // it's done\n separateComponents(layoutInfo, options);\n done();\n } else {\n var now = performanceNow();\n if (now - startTime >= options.animationThreshold) {\n refresh();\n }\n requestAnimationFrame(frame);\n }\n };\n frame();\n } else {\n while (loopRet) {\n loopRet = mainLoop(i);\n i++;\n }\n separateComponents(layoutInfo, options);\n done();\n }\n return this; // chaining\n};\n\n/**\n * @brief : called on continuous layouts to stop them before they finish\n */\nCoseLayout.prototype.stop = function () {\n this.stopped = true;\n if (this.thread) {\n this.thread.stop();\n }\n this.emit('layoutstop');\n return this; // chaining\n};\n\nCoseLayout.prototype.destroy = function () {\n if (this.thread) {\n this.thread.stop();\n }\n return this; // chaining\n};\n\n/**\n * @brief : Creates an object which is contains all the data\n * used in the layout process\n * @arg cy : cytoscape.js object\n * @return : layoutInfo object initialized\n */\nvar createLayoutInfo = function createLayoutInfo(cy, layout, options) {\n // Shortcut\n var edges = options.eles.edges();\n var nodes = options.eles.nodes();\n var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {\n x1: 0,\n y1: 0,\n w: cy.width(),\n h: cy.height()\n });\n var layoutInfo = {\n isCompound: cy.hasCompoundNodes(),\n layoutNodes: [],\n idToIndex: {},\n nodeSize: nodes.size(),\n graphSet: [],\n indexToGraph: [],\n layoutEdges: [],\n edgeSize: edges.size(),\n temperature: options.initialTemp,\n clientWidth: bb.w,\n clientHeight: bb.h,\n boundingBox: bb\n };\n var components = options.eles.components();\n var id2cmptId = {};\n for (var i = 0; i < components.length; i++) {\n var component = components[i];\n for (var j = 0; j < component.length; j++) {\n var node = component[j];\n id2cmptId[node.id()] = i;\n }\n }\n\n // Iterate over all nodes, creating layout nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = nodes[i];\n var nbb = n.layoutDimensions(options);\n var tempNode = {};\n tempNode.isLocked = n.locked();\n tempNode.id = n.data('id');\n tempNode.parentId = n.data('parent');\n tempNode.cmptId = id2cmptId[n.id()];\n tempNode.children = [];\n tempNode.positionX = n.position('x');\n tempNode.positionY = n.position('y');\n tempNode.offsetX = 0;\n tempNode.offsetY = 0;\n tempNode.height = nbb.w;\n tempNode.width = nbb.h;\n tempNode.maxX = tempNode.positionX + tempNode.width / 2;\n tempNode.minX = tempNode.positionX - tempNode.width / 2;\n tempNode.maxY = tempNode.positionY + tempNode.height / 2;\n tempNode.minY = tempNode.positionY - tempNode.height / 2;\n tempNode.padLeft = parseFloat(n.style('padding'));\n tempNode.padRight = parseFloat(n.style('padding'));\n tempNode.padTop = parseFloat(n.style('padding'));\n tempNode.padBottom = parseFloat(n.style('padding'));\n\n // forces\n tempNode.nodeRepulsion = fn$6(options.nodeRepulsion) ? options.nodeRepulsion(n) : options.nodeRepulsion;\n\n // Add new node\n layoutInfo.layoutNodes.push(tempNode);\n // Add entry to id-index map\n layoutInfo.idToIndex[tempNode.id] = i;\n }\n\n // Inline implementation of a queue, used for traversing the graph in BFS order\n var queue = [];\n var start = 0; // Points to the start the queue\n var end = -1; // Points to the end of the queue\n\n var tempGraph = [];\n\n // Second pass to add child information and\n // initialize queue for hierarchical traversal\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n var p_id = n.parentId;\n // Check if node n has a parent node\n if (null != p_id) {\n // Add node Id to parent's list of children\n layoutInfo.layoutNodes[layoutInfo.idToIndex[p_id]].children.push(n.id);\n } else {\n // If a node doesn't have a parent, then it's in the root graph\n queue[++end] = n.id;\n tempGraph.push(n.id);\n }\n }\n\n // Add root graph to graphSet\n layoutInfo.graphSet.push(tempGraph);\n\n // Traverse the graph, level by level,\n while (start <= end) {\n // Get the node to visit and remove it from queue\n var node_id = queue[start++];\n var node_ix = layoutInfo.idToIndex[node_id];\n var node = layoutInfo.layoutNodes[node_ix];\n var children = node.children;\n if (children.length > 0) {\n // Add children nodes as a new graph to graph set\n layoutInfo.graphSet.push(children);\n // Add children to que queue to be visited\n for (var i = 0; i < children.length; i++) {\n queue[++end] = children[i];\n }\n }\n }\n\n // Create indexToGraph map\n for (var i = 0; i < layoutInfo.graphSet.length; i++) {\n var graph = layoutInfo.graphSet[i];\n for (var j = 0; j < graph.length; j++) {\n var index = layoutInfo.idToIndex[graph[j]];\n layoutInfo.indexToGraph[index] = i;\n }\n }\n\n // Iterate over all edges, creating Layout Edges\n for (var i = 0; i < layoutInfo.edgeSize; i++) {\n var e = edges[i];\n var tempEdge = {};\n tempEdge.id = e.data('id');\n tempEdge.sourceId = e.data('source');\n tempEdge.targetId = e.data('target');\n\n // Compute ideal length\n var idealLength = fn$6(options.idealEdgeLength) ? options.idealEdgeLength(e) : options.idealEdgeLength;\n var elasticity = fn$6(options.edgeElasticity) ? options.edgeElasticity(e) : options.edgeElasticity;\n\n // Check if it's an inter graph edge\n var sourceIx = layoutInfo.idToIndex[tempEdge.sourceId];\n var targetIx = layoutInfo.idToIndex[tempEdge.targetId];\n var sourceGraph = layoutInfo.indexToGraph[sourceIx];\n var targetGraph = layoutInfo.indexToGraph[targetIx];\n if (sourceGraph != targetGraph) {\n // Find lowest common graph ancestor\n var lca = findLCA(tempEdge.sourceId, tempEdge.targetId, layoutInfo);\n\n // Compute sum of node depths, relative to lca graph\n var lcaGraph = layoutInfo.graphSet[lca];\n var depth = 0;\n\n // Source depth\n var tempNode = layoutInfo.layoutNodes[sourceIx];\n while (-1 === lcaGraph.indexOf(tempNode.id)) {\n tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];\n depth++;\n }\n\n // Target depth\n tempNode = layoutInfo.layoutNodes[targetIx];\n while (-1 === lcaGraph.indexOf(tempNode.id)) {\n tempNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[tempNode.parentId]];\n depth++;\n }\n\n // logDebug('LCA of nodes ' + tempEdge.sourceId + ' and ' + tempEdge.targetId +\n // \". Index: \" + lca + \" Contents: \" + lcaGraph.toString() +\n // \". Depth: \" + depth);\n\n // Update idealLength\n idealLength *= depth * options.nestingFactor;\n }\n tempEdge.idealLength = idealLength;\n tempEdge.elasticity = elasticity;\n layoutInfo.layoutEdges.push(tempEdge);\n }\n\n // Finally, return layoutInfo object\n return layoutInfo;\n};\n\n/**\n * @brief : This function finds the index of the lowest common\n * graph ancestor between 2 nodes in the subtree\n * (from the graph hierarchy induced tree) whose\n * root is graphIx\n *\n * @arg node1: node1's ID\n * @arg node2: node2's ID\n * @arg layoutInfo: layoutInfo object\n *\n */\nvar findLCA = function findLCA(node1, node2, layoutInfo) {\n // Find their common ancester, starting from the root graph\n var res = findLCA_aux(node1, node2, 0, layoutInfo);\n if (2 > res.count) {\n // If aux function couldn't find the common ancester,\n // then it is the root graph\n return 0;\n } else {\n return res.graph;\n }\n};\n\n/**\n * @brief : Auxiliary function used for LCA computation\n *\n * @arg node1 : node1's ID\n * @arg node2 : node2's ID\n * @arg graphIx : subgraph index\n * @arg layoutInfo : layoutInfo object\n *\n * @return : object of the form {count: X, graph: Y}, where:\n * X is the number of ancestors (max: 2) found in\n * graphIx (and it's subgraphs),\n * Y is the graph index of the lowest graph containing\n * all X nodes\n */\nvar findLCA_aux = function findLCA_aux(node1, node2, graphIx, layoutInfo) {\n var graph = layoutInfo.graphSet[graphIx];\n // If both nodes belongs to graphIx\n if (-1 < graph.indexOf(node1) && -1 < graph.indexOf(node2)) {\n return {\n count: 2,\n graph: graphIx\n };\n }\n\n // Make recursive calls for all subgraphs\n var c = 0;\n for (var i = 0; i < graph.length; i++) {\n var nodeId = graph[i];\n var nodeIx = layoutInfo.idToIndex[nodeId];\n var children = layoutInfo.layoutNodes[nodeIx].children;\n\n // If the node has no child, skip it\n if (0 === children.length) {\n continue;\n }\n var childGraphIx = layoutInfo.indexToGraph[layoutInfo.idToIndex[children[0]]];\n var result = findLCA_aux(node1, node2, childGraphIx, layoutInfo);\n if (0 === result.count) {\n // Neither node1 nor node2 are present in this subgraph\n continue;\n } else if (1 === result.count) {\n // One of (node1, node2) is present in this subgraph\n c++;\n if (2 === c) {\n // We've already found both nodes, no need to keep searching\n break;\n }\n } else {\n // Both nodes are present in this subgraph\n return result;\n }\n }\n return {\n count: c,\n graph: graphIx\n };\n};\n\n/**\n * @brief: printsLayoutInfo into js console\n * Only used for debbuging\n */\nvar printLayoutInfo; \n\n/**\n * @brief : Randomizes the position of all nodes\n */\nvar randomizePositions = function randomizePositions(layoutInfo, cy) {\n var width = layoutInfo.clientWidth;\n var height = layoutInfo.clientHeight;\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n\n // No need to randomize compound nodes or locked nodes\n if (0 === n.children.length && !n.isLocked) {\n n.positionX = Math.random() * width;\n n.positionY = Math.random() * height;\n }\n }\n};\nvar getScaleInBoundsFn = function getScaleInBoundsFn(layoutInfo, options, nodes) {\n var bb = layoutInfo.boundingBox;\n var coseBB = {\n x1: Infinity,\n x2: -Infinity,\n y1: Infinity,\n y2: -Infinity\n };\n if (options.boundingBox) {\n nodes.forEach(function (node) {\n var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[node.data('id')]];\n coseBB.x1 = Math.min(coseBB.x1, lnode.positionX);\n coseBB.x2 = Math.max(coseBB.x2, lnode.positionX);\n coseBB.y1 = Math.min(coseBB.y1, lnode.positionY);\n coseBB.y2 = Math.max(coseBB.y2, lnode.positionY);\n });\n coseBB.w = coseBB.x2 - coseBB.x1;\n coseBB.h = coseBB.y2 - coseBB.y1;\n }\n return function (ele, i) {\n var lnode = layoutInfo.layoutNodes[layoutInfo.idToIndex[ele.data('id')]];\n if (options.boundingBox) {\n // then add extra bounding box constraint\n var pctX = (lnode.positionX - coseBB.x1) / coseBB.w;\n var pctY = (lnode.positionY - coseBB.y1) / coseBB.h;\n return {\n x: bb.x1 + pctX * bb.w,\n y: bb.y1 + pctY * bb.h\n };\n } else {\n return {\n x: lnode.positionX,\n y: lnode.positionY\n };\n }\n };\n};\n\n/**\n * @brief : Updates the positions of nodes in the network\n * @arg layoutInfo : LayoutInfo object\n * @arg cy : Cytoscape object\n * @arg options : Layout options\n */\nvar refreshPositions = function refreshPositions(layoutInfo, cy, options) {\n // var s = 'Refreshing positions';\n // logDebug(s);\n\n var layout = options.layout;\n var nodes = options.eles.nodes();\n var getScaledPos = getScaleInBoundsFn(layoutInfo, options, nodes);\n nodes.positions(getScaledPos);\n\n // Trigger layoutReady only on first call\n if (true !== layoutInfo.ready) {\n // s = 'Triggering layoutready';\n // logDebug(s);\n layoutInfo.ready = true;\n layout.one('layoutready', options.ready);\n layout.emit({\n type: 'layoutready',\n layout: this\n });\n }\n};\n\n/**\n * @brief : Logs a debug message in JS console, if DEBUG is ON\n */\n// var logDebug = function(text) {\n// if (DEBUG) {\n// console.debug(text);\n// }\n// };\n\n/**\n * @brief : Performs one iteration of the physical simulation\n * @arg layoutInfo : LayoutInfo object already initialized\n * @arg cy : Cytoscape object\n * @arg options : Layout options\n */\nvar step = function step(layoutInfo, options, _step) {\n // var s = \"\\n\\n###############################\";\n // s += \"\\nSTEP: \" + step;\n // s += \"\\n###############################\\n\";\n // logDebug(s);\n\n // Calculate node repulsions\n calculateNodeForces(layoutInfo, options);\n // Calculate edge forces\n calculateEdgeForces(layoutInfo);\n // Calculate gravity forces\n calculateGravityForces(layoutInfo, options);\n // Propagate forces from parent to child\n propagateForces(layoutInfo);\n // Update positions based on calculated forces\n updatePositions(layoutInfo);\n};\n\n/**\n * @brief : Computes the node repulsion forces\n */\nvar calculateNodeForces = function calculateNodeForces(layoutInfo, options) {\n // Go through each of the graphs in graphSet\n // Nodes only repel each other if they belong to the same graph\n // var s = 'calculateNodeForces';\n // logDebug(s);\n for (var i = 0; i < layoutInfo.graphSet.length; i++) {\n var graph = layoutInfo.graphSet[i];\n var numNodes = graph.length;\n\n // s = \"Set: \" + graph.toString();\n // logDebug(s);\n\n // Now get all the pairs of nodes\n // Only get each pair once, (A, B) = (B, A)\n for (var j = 0; j < numNodes; j++) {\n var node1 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];\n for (var k = j + 1; k < numNodes; k++) {\n var node2 = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[k]]];\n nodeRepulsion(node1, node2, layoutInfo, options);\n }\n }\n }\n};\nvar randomDistance = function randomDistance(max) {\n return -max + 2 * max * Math.random();\n};\n\n/**\n * @brief : Compute the node repulsion forces between a pair of nodes\n */\nvar nodeRepulsion = function nodeRepulsion(node1, node2, layoutInfo, options) {\n // var s = \"Node repulsion. Node1: \" + node1.id + \" Node2: \" + node2.id;\n\n var cmptId1 = node1.cmptId;\n var cmptId2 = node2.cmptId;\n if (cmptId1 !== cmptId2 && !layoutInfo.isCompound) {\n return;\n }\n\n // Get direction of line connecting both node centers\n var directionX = node2.positionX - node1.positionX;\n var directionY = node2.positionY - node1.positionY;\n var maxRandDist = 1;\n // s += \"\\ndirectionX: \" + directionX + \", directionY: \" + directionY;\n\n // If both centers are the same, apply a random force\n if (0 === directionX && 0 === directionY) {\n directionX = randomDistance(maxRandDist);\n directionY = randomDistance(maxRandDist);\n }\n var overlap = nodesOverlap(node1, node2, directionX, directionY);\n if (overlap > 0) {\n // s += \"\\nNodes DO overlap.\";\n // s += \"\\nOverlap: \" + overlap;\n // If nodes overlap, repulsion force is proportional\n // to the overlap\n var force = options.nodeOverlap * overlap;\n\n // Compute the module and components of the force vector\n var distance = Math.sqrt(directionX * directionX + directionY * directionY);\n // s += \"\\nDistance: \" + distance;\n var forceX = force * directionX / distance;\n var forceY = force * directionY / distance;\n } else {\n // s += \"\\nNodes do NOT overlap.\";\n // If there's no overlap, force is inversely proportional\n // to squared distance\n\n // Get clipping points for both nodes\n var point1 = findClippingPoint(node1, directionX, directionY);\n var point2 = findClippingPoint(node2, -1 * directionX, -1 * directionY);\n\n // Use clipping points to compute distance\n var distanceX = point2.x - point1.x;\n var distanceY = point2.y - point1.y;\n var distanceSqr = distanceX * distanceX + distanceY * distanceY;\n var distance = Math.sqrt(distanceSqr);\n // s += \"\\nDistance: \" + distance;\n\n // Compute the module and components of the force vector\n var force = (node1.nodeRepulsion + node2.nodeRepulsion) / distanceSqr;\n var forceX = force * distanceX / distance;\n var forceY = force * distanceY / distance;\n }\n\n // Apply force\n if (!node1.isLocked) {\n node1.offsetX -= forceX;\n node1.offsetY -= forceY;\n }\n if (!node2.isLocked) {\n node2.offsetX += forceX;\n node2.offsetY += forceY;\n }\n\n // s += \"\\nForceX: \" + forceX + \" ForceY: \" + forceY;\n // logDebug(s);\n\n return;\n};\n\n/**\n * @brief : Determines whether two nodes overlap or not\n * @return : Amount of overlapping (0 => no overlap)\n */\nvar nodesOverlap = function nodesOverlap(node1, node2, dX, dY) {\n if (dX > 0) {\n var overlapX = node1.maxX - node2.minX;\n } else {\n var overlapX = node2.maxX - node1.minX;\n }\n if (dY > 0) {\n var overlapY = node1.maxY - node2.minY;\n } else {\n var overlapY = node2.maxY - node1.minY;\n }\n if (overlapX >= 0 && overlapY >= 0) {\n return Math.sqrt(overlapX * overlapX + overlapY * overlapY);\n } else {\n return 0;\n }\n};\n\n/**\n * @brief : Finds the point in which an edge (direction dX, dY) intersects\n * the rectangular bounding box of it's source/target node\n */\nvar findClippingPoint = function findClippingPoint(node, dX, dY) {\n // Shorcuts\n var X = node.positionX;\n var Y = node.positionY;\n var H = node.height || 1;\n var W = node.width || 1;\n var dirSlope = dY / dX;\n var nodeSlope = H / W;\n\n // var s = 'Computing clipping point of node ' + node.id +\n // \" . Height: \" + H + \", Width: \" + W +\n // \"\\nDirection \" + dX + \", \" + dY;\n //\n // Compute intersection\n var res = {};\n\n // Case: Vertical direction (up)\n if (0 === dX && 0 < dY) {\n res.x = X;\n // s += \"\\nUp direction\";\n res.y = Y + H / 2;\n return res;\n }\n\n // Case: Vertical direction (down)\n if (0 === dX && 0 > dY) {\n res.x = X;\n res.y = Y + H / 2;\n // s += \"\\nDown direction\";\n\n return res;\n }\n\n // Case: Intersects the right border\n if (0 < dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) {\n res.x = X + W / 2;\n res.y = Y + W * dY / 2 / dX;\n // s += \"\\nRightborder\";\n\n return res;\n }\n\n // Case: Intersects the left border\n if (0 > dX && -1 * nodeSlope <= dirSlope && dirSlope <= nodeSlope) {\n res.x = X - W / 2;\n res.y = Y - W * dY / 2 / dX;\n // s += \"\\nLeftborder\";\n\n return res;\n }\n\n // Case: Intersects the top border\n if (0 < dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) {\n res.x = X + H * dX / 2 / dY;\n res.y = Y + H / 2;\n // s += \"\\nTop border\";\n\n return res;\n }\n\n // Case: Intersects the bottom border\n if (0 > dY && (dirSlope <= -1 * nodeSlope || dirSlope >= nodeSlope)) {\n res.x = X - H * dX / 2 / dY;\n res.y = Y - H / 2;\n // s += \"\\nBottom border\";\n\n return res;\n }\n\n // s += \"\\nClipping point found at \" + res.x + \", \" + res.y;\n // logDebug(s);\n return res;\n};\n\n/**\n * @brief : Calculates all edge forces\n */\nvar calculateEdgeForces = function calculateEdgeForces(layoutInfo, options) {\n // Iterate over all edges\n for (var i = 0; i < layoutInfo.edgeSize; i++) {\n // Get edge, source & target nodes\n var edge = layoutInfo.layoutEdges[i];\n var sourceIx = layoutInfo.idToIndex[edge.sourceId];\n var source = layoutInfo.layoutNodes[sourceIx];\n var targetIx = layoutInfo.idToIndex[edge.targetId];\n var target = layoutInfo.layoutNodes[targetIx];\n\n // Get direction of line connecting both node centers\n var directionX = target.positionX - source.positionX;\n var directionY = target.positionY - source.positionY;\n\n // If both centers are the same, do nothing.\n // A random force has already been applied as node repulsion\n if (0 === directionX && 0 === directionY) {\n continue;\n }\n\n // Get clipping points for both nodes\n var point1 = findClippingPoint(source, directionX, directionY);\n var point2 = findClippingPoint(target, -1 * directionX, -1 * directionY);\n var lx = point2.x - point1.x;\n var ly = point2.y - point1.y;\n var l = Math.sqrt(lx * lx + ly * ly);\n var force = Math.pow(edge.idealLength - l, 2) / edge.elasticity;\n if (0 !== l) {\n var forceX = force * lx / l;\n var forceY = force * ly / l;\n } else {\n var forceX = 0;\n var forceY = 0;\n }\n\n // Add this force to target and source nodes\n if (!source.isLocked) {\n source.offsetX += forceX;\n source.offsetY += forceY;\n }\n if (!target.isLocked) {\n target.offsetX -= forceX;\n target.offsetY -= forceY;\n }\n\n // var s = 'Edge force between nodes ' + source.id + ' and ' + target.id;\n // s += \"\\nDistance: \" + l + \" Force: (\" + forceX + \", \" + forceY + \")\";\n // logDebug(s);\n }\n};\n\n/**\n * @brief : Computes gravity forces for all nodes\n */\nvar calculateGravityForces = function calculateGravityForces(layoutInfo, options) {\n if (options.gravity === 0) {\n return;\n }\n var distThreshold = 1;\n\n // var s = 'calculateGravityForces';\n // logDebug(s);\n for (var i = 0; i < layoutInfo.graphSet.length; i++) {\n var graph = layoutInfo.graphSet[i];\n var numNodes = graph.length;\n\n // s = \"Set: \" + graph.toString();\n // logDebug(s);\n\n // Compute graph center\n if (0 === i) {\n var centerX = layoutInfo.clientHeight / 2;\n var centerY = layoutInfo.clientWidth / 2;\n } else {\n // Get Parent node for this graph, and use its position as center\n var temp = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[0]]];\n var parent = layoutInfo.layoutNodes[layoutInfo.idToIndex[temp.parentId]];\n var centerX = parent.positionX;\n var centerY = parent.positionY;\n }\n // s = \"Center found at: \" + centerX + \", \" + centerY;\n // logDebug(s);\n\n // Apply force to all nodes in graph\n for (var j = 0; j < numNodes; j++) {\n var node = layoutInfo.layoutNodes[layoutInfo.idToIndex[graph[j]]];\n // s = \"Node: \" + node.id;\n\n if (node.isLocked) {\n continue;\n }\n var dx = centerX - node.positionX;\n var dy = centerY - node.positionY;\n var d = Math.sqrt(dx * dx + dy * dy);\n if (d > distThreshold) {\n var fx = options.gravity * dx / d;\n var fy = options.gravity * dy / d;\n node.offsetX += fx;\n node.offsetY += fy;\n // s += \": Applied force: \" + fx + \", \" + fy;\n }\n // logDebug(s);\n }\n }\n};\n\n/**\n * @brief : This function propagates the existing offsets from\n * parent nodes to its descendents.\n * @arg layoutInfo : layoutInfo Object\n * @arg cy : cytoscape Object\n * @arg options : Layout options\n */\nvar propagateForces = function propagateForces(layoutInfo, options) {\n // Inline implementation of a queue, used for traversing the graph in BFS order\n var queue = [];\n var start = 0; // Points to the start the queue\n var end = -1; // Points to the end of the queue\n\n // logDebug('propagateForces');\n\n // Start by visiting the nodes in the root graph\n queue.push.apply(queue, layoutInfo.graphSet[0]);\n end += layoutInfo.graphSet[0].length;\n\n // Traverse the graph, level by level,\n while (start <= end) {\n // Get the node to visit and remove it from queue\n var nodeId = queue[start++];\n var nodeIndex = layoutInfo.idToIndex[nodeId];\n var node = layoutInfo.layoutNodes[nodeIndex];\n var children = node.children;\n\n // We only need to process the node if it's compound\n if (0 < children.length && !node.isLocked) {\n var offX = node.offsetX;\n var offY = node.offsetY;\n\n // var s = \"Propagating offset from parent node : \" + node.id +\n // \". OffsetX: \" + offX + \". OffsetY: \" + offY;\n // s += \"\\n Children: \" + children.toString();\n // logDebug(s);\n\n for (var i = 0; i < children.length; i++) {\n var childNode = layoutInfo.layoutNodes[layoutInfo.idToIndex[children[i]]];\n // Propagate offset\n childNode.offsetX += offX;\n childNode.offsetY += offY;\n // Add children to queue to be visited\n queue[++end] = children[i];\n }\n\n // Reset parent offsets\n node.offsetX = 0;\n node.offsetY = 0;\n }\n }\n};\n\n/**\n * @brief : Updates the layout model positions, based on\n * the accumulated forces\n */\nvar updatePositions = function updatePositions(layoutInfo, options) {\n // var s = 'Updating positions';\n // logDebug(s);\n\n // Reset boundaries for compound nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if (0 < n.children.length) {\n // logDebug(\"Resetting boundaries of compound node: \" + n.id);\n n.maxX = undefined;\n n.minX = undefined;\n n.maxY = undefined;\n n.minY = undefined;\n }\n }\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if (0 < n.children.length || n.isLocked) {\n // No need to set compound or locked node position\n // logDebug(\"Skipping position update of node: \" + n.id);\n continue;\n }\n // s = \"Node: \" + n.id + \" Previous position: (\" +\n // n.positionX + \", \" + n.positionY + \").\";\n\n // Limit displacement in order to improve stability\n var tempForce = limitForce(n.offsetX, n.offsetY, layoutInfo.temperature);\n n.positionX += tempForce.x;\n n.positionY += tempForce.y;\n n.offsetX = 0;\n n.offsetY = 0;\n n.minX = n.positionX - n.width;\n n.maxX = n.positionX + n.width;\n n.minY = n.positionY - n.height;\n n.maxY = n.positionY + n.height;\n // s += \" New Position: (\" + n.positionX + \", \" + n.positionY + \").\";\n // logDebug(s);\n\n // Update ancestry boudaries\n updateAncestryBoundaries(n, layoutInfo);\n }\n\n // Update size, position of compund nodes\n for (var i = 0; i < layoutInfo.nodeSize; i++) {\n var n = layoutInfo.layoutNodes[i];\n if (0 < n.children.length && !n.isLocked) {\n n.positionX = (n.maxX + n.minX) / 2;\n n.positionY = (n.maxY + n.minY) / 2;\n n.width = n.maxX - n.minX;\n n.height = n.maxY - n.minY;\n // s = \"Updating position, size of compound node \" + n.id;\n // s += \"\\nPositionX: \" + n.positionX + \", PositionY: \" + n.positionY;\n // s += \"\\nWidth: \" + n.width + \", Height: \" + n.height;\n // logDebug(s);\n }\n }\n};\n\n/**\n * @brief : Limits a force (forceX, forceY) to be not\n * greater (in modulo) than max.\n 8 Preserves force direction.\n */\nvar limitForce = function limitForce(forceX, forceY, max) {\n // var s = \"Limiting force: (\" + forceX + \", \" + forceY + \"). Max: \" + max;\n var force = Math.sqrt(forceX * forceX + forceY * forceY);\n if (force > max) {\n var res = {\n x: max * forceX / force,\n y: max * forceY / force\n };\n } else {\n var res = {\n x: forceX,\n y: forceY\n };\n }\n\n // s += \".\\nResult: (\" + res.x + \", \" + res.y + \")\";\n // logDebug(s);\n\n return res;\n};\n\n/**\n * @brief : Function used for keeping track of compound node\n * sizes, since they should bound all their subnodes.\n */\nvar updateAncestryBoundaries = function updateAncestryBoundaries(node, layoutInfo) {\n // var s = \"Propagating new position/size of node \" + node.id;\n var parentId = node.parentId;\n if (null == parentId) {\n // If there's no parent, we are done\n // s += \". No parent node.\";\n // logDebug(s);\n return;\n }\n\n // Get Parent Node\n var p = layoutInfo.layoutNodes[layoutInfo.idToIndex[parentId]];\n var flag = false;\n\n // MaxX\n if (null == p.maxX || node.maxX + p.padRight > p.maxX) {\n p.maxX = node.maxX + p.padRight;\n flag = true;\n // s += \"\\nNew maxX for parent node \" + p.id + \": \" + p.maxX;\n }\n\n // MinX\n if (null == p.minX || node.minX - p.padLeft < p.minX) {\n p.minX = node.minX - p.padLeft;\n flag = true;\n // s += \"\\nNew minX for parent node \" + p.id + \": \" + p.minX;\n }\n\n // MaxY\n if (null == p.maxY || node.maxY + p.padBottom > p.maxY) {\n p.maxY = node.maxY + p.padBottom;\n flag = true;\n // s += \"\\nNew maxY for parent node \" + p.id + \": \" + p.maxY;\n }\n\n // MinY\n if (null == p.minY || node.minY - p.padTop < p.minY) {\n p.minY = node.minY - p.padTop;\n flag = true;\n // s += \"\\nNew minY for parent node \" + p.id + \": \" + p.minY;\n }\n\n // If updated boundaries, propagate changes upward\n if (flag) {\n // logDebug(s);\n return updateAncestryBoundaries(p, layoutInfo);\n }\n\n // s += \". No changes in boundaries/position of parent node \" + p.id;\n // logDebug(s);\n return;\n};\nvar separateComponents = function separateComponents(layoutInfo, options) {\n var nodes = layoutInfo.layoutNodes;\n var components = [];\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n var cid = node.cmptId;\n var component = components[cid] = components[cid] || [];\n component.push(node);\n }\n var totalA = 0;\n for (var i = 0; i < components.length; i++) {\n var c = components[i];\n if (!c) {\n continue;\n }\n c.x1 = Infinity;\n c.x2 = -Infinity;\n c.y1 = Infinity;\n c.y2 = -Infinity;\n for (var j = 0; j < c.length; j++) {\n var n = c[j];\n c.x1 = Math.min(c.x1, n.positionX - n.width / 2);\n c.x2 = Math.max(c.x2, n.positionX + n.width / 2);\n c.y1 = Math.min(c.y1, n.positionY - n.height / 2);\n c.y2 = Math.max(c.y2, n.positionY + n.height / 2);\n }\n c.w = c.x2 - c.x1;\n c.h = c.y2 - c.y1;\n totalA += c.w * c.h;\n }\n components.sort(function (c1, c2) {\n return c2.w * c2.h - c1.w * c1.h;\n });\n var x = 0;\n var y = 0;\n var usedW = 0;\n var rowH = 0;\n var maxRowW = Math.sqrt(totalA) * layoutInfo.clientWidth / layoutInfo.clientHeight;\n for (var i = 0; i < components.length; i++) {\n var c = components[i];\n if (!c) {\n continue;\n }\n for (var j = 0; j < c.length; j++) {\n var n = c[j];\n if (!n.isLocked) {\n n.positionX += x - c.x1;\n n.positionY += y - c.y1;\n }\n }\n x += c.w + options.componentSpacing;\n usedW += c.w + options.componentSpacing;\n rowH = Math.max(rowH, c.h);\n if (usedW > maxRowW) {\n y += rowH + options.componentSpacing;\n x = 0;\n usedW = 0;\n rowH = 0;\n }\n }\n};\n\nvar defaults$3 = {\n fit: true,\n // whether to fit the viewport to the graph\n padding: 30,\n // padding used on fit\n boundingBox: undefined,\n // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n avoidOverlap: true,\n // prevents node overlap, may overflow boundingBox if not enough space\n avoidOverlapPadding: 10,\n // extra spacing around nodes when avoidOverlap: true\n nodeDimensionsIncludeLabels: false,\n // Excludes the label when calculating node bounding boxes for the layout algorithm\n spacingFactor: undefined,\n // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up\n condense: false,\n // uses all available space on false, uses minimal space on true\n rows: undefined,\n // force num of rows in the grid\n cols: undefined,\n // force num of columns in the grid\n position: function position(node) {},\n // returns { row, col } for element\n sort: undefined,\n // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }\n animate: false,\n // whether to transition the node positions\n animationDuration: 500,\n // duration of animation in ms if enabled\n animationEasing: undefined,\n // easing of animation if enabled\n animateFilter: function animateFilter(node, i) {\n return true;\n },\n // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts\n ready: undefined,\n // callback on layoutready\n stop: undefined,\n // callback on layoutstop\n transform: function transform(node, position) {\n return position;\n } // transform a given node position. Useful for changing flow direction in discrete layouts \n};\n\nfunction GridLayout(options) {\n this.options = extend({}, defaults$3, options);\n}\nGridLayout.prototype.run = function () {\n var params = this.options;\n var options = params;\n var cy = params.cy;\n var eles = options.eles;\n var nodes = eles.nodes().not(':parent');\n if (options.sort) {\n nodes = nodes.sort(options.sort);\n }\n var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {\n x1: 0,\n y1: 0,\n w: cy.width(),\n h: cy.height()\n });\n if (bb.h === 0 || bb.w === 0) {\n eles.nodes().layoutPositions(this, options, function (ele) {\n return {\n x: bb.x1,\n y: bb.y1\n };\n });\n } else {\n // width/height * splits^2 = cells where splits is number of times to split width\n var cells = nodes.size();\n var splits = Math.sqrt(cells * bb.h / bb.w);\n var rows = Math.round(splits);\n var cols = Math.round(bb.w / bb.h * splits);\n var small = function small(val) {\n if (val == null) {\n return Math.min(rows, cols);\n } else {\n var min = Math.min(rows, cols);\n if (min == rows) {\n rows = val;\n } else {\n cols = val;\n }\n }\n };\n var large = function large(val) {\n if (val == null) {\n return Math.max(rows, cols);\n } else {\n var max = Math.max(rows, cols);\n if (max == rows) {\n rows = val;\n } else {\n cols = val;\n }\n }\n };\n var oRows = options.rows;\n var oCols = options.cols != null ? options.cols : options.columns;\n\n // if rows or columns were set in options, use those values\n if (oRows != null && oCols != null) {\n rows = oRows;\n cols = oCols;\n } else if (oRows != null && oCols == null) {\n rows = oRows;\n cols = Math.ceil(cells / rows);\n } else if (oRows == null && oCols != null) {\n cols = oCols;\n rows = Math.ceil(cells / cols);\n }\n\n // otherwise use the automatic values and adjust accordingly\n\n // if rounding was up, see if we can reduce rows or columns\n else if (cols * rows > cells) {\n var sm = small();\n var lg = large();\n\n // reducing the small side takes away the most cells, so try it first\n if ((sm - 1) * lg >= cells) {\n small(sm - 1);\n } else if ((lg - 1) * sm >= cells) {\n large(lg - 1);\n }\n } else {\n // if rounding was too low, add rows or columns\n while (cols * rows < cells) {\n var _sm = small();\n var _lg = large();\n\n // try to add to larger side first (adds less in multiplication)\n if ((_lg + 1) * _sm >= cells) {\n large(_lg + 1);\n } else {\n small(_sm + 1);\n }\n }\n }\n var cellWidth = bb.w / cols;\n var cellHeight = bb.h / rows;\n if (options.condense) {\n cellWidth = 0;\n cellHeight = 0;\n }\n if (options.avoidOverlap) {\n for (var i = 0; i < nodes.length; i++) {\n var node = nodes[i];\n var pos = node._private.position;\n if (pos.x == null || pos.y == null) {\n // for bb\n pos.x = 0;\n pos.y = 0;\n }\n var nbb = node.layoutDimensions(options);\n var p = options.avoidOverlapPadding;\n var w = nbb.w + p;\n var h = nbb.h + p;\n cellWidth = Math.max(cellWidth, w);\n cellHeight = Math.max(cellHeight, h);\n }\n }\n var cellUsed = {}; // e.g. 'c-0-2' => true\n\n var used = function used(row, col) {\n return cellUsed['c-' + row + '-' + col] ? true : false;\n };\n var use = function use(row, col) {\n cellUsed['c-' + row + '-' + col] = true;\n };\n\n // to keep track of current cell position\n var row = 0;\n var col = 0;\n var moveToNextCell = function moveToNextCell() {\n col++;\n if (col >= cols) {\n col = 0;\n row++;\n }\n };\n\n // get a cache of all the manual positions\n var id2manPos = {};\n for (var _i = 0; _i < nodes.length; _i++) {\n var _node = nodes[_i];\n var rcPos = options.position(_node);\n if (rcPos && (rcPos.row !== undefined || rcPos.col !== undefined)) {\n // must have at least row or col def'd\n var _pos = {\n row: rcPos.row,\n col: rcPos.col\n };\n if (_pos.col === undefined) {\n // find unused col\n _pos.col = 0;\n while (used(_pos.row, _pos.col)) {\n _pos.col++;\n }\n } else if (_pos.row === undefined) {\n // find unused row\n _pos.row = 0;\n while (used(_pos.row, _pos.col)) {\n _pos.row++;\n }\n }\n id2manPos[_node.id()] = _pos;\n use(_pos.row, _pos.col);\n }\n }\n var getPos = function getPos(element, i) {\n var x, y;\n if (element.locked() || element.isParent()) {\n return false;\n }\n\n // see if we have a manual position set\n var rcPos = id2manPos[element.id()];\n if (rcPos) {\n x = rcPos.col * cellWidth + cellWidth / 2 + bb.x1;\n y = rcPos.row * cellHeight + cellHeight / 2 + bb.y1;\n } else {\n // otherwise set automatically\n\n while (used(row, col)) {\n moveToNextCell();\n }\n x = col * cellWidth + cellWidth / 2 + bb.x1;\n y = row * cellHeight + cellHeight / 2 + bb.y1;\n use(row, col);\n moveToNextCell();\n }\n return {\n x: x,\n y: y\n };\n };\n nodes.layoutPositions(this, options, getPos);\n }\n return this; // chaining\n};\n\n// default layout options\nvar defaults$2 = {\n ready: function ready() {},\n // on layoutready\n stop: function stop() {} // on layoutstop\n};\n\n// constructor\n// options : object containing layout options\nfunction NullLayout(options) {\n this.options = extend({}, defaults$2, options);\n}\n\n// runs the layout\nNullLayout.prototype.run = function () {\n var options = this.options;\n var eles = options.eles; // elements to consider in the layout\n var layout = this;\n\n // cy is automatically populated for us in the constructor\n // (disable eslint for next line as this serves as example layout code to external developers)\n // eslint-disable-next-line no-unused-vars\n options.cy;\n layout.emit('layoutstart');\n\n // puts all nodes at (0, 0)\n // n.b. most layouts would use layoutPositions(), instead of positions() and manual events\n eles.nodes().positions(function () {\n return {\n x: 0,\n y: 0\n };\n });\n\n // trigger layoutready when each node has had its position set at least once\n layout.one('layoutready', options.ready);\n layout.emit('layoutready');\n\n // trigger layoutstop when the layout stops (e.g. finishes)\n layout.one('layoutstop', options.stop);\n layout.emit('layoutstop');\n return this; // chaining\n};\n\n// called on continuous layouts to stop them before they finish\nNullLayout.prototype.stop = function () {\n return this; // chaining\n};\n\nvar defaults$1 = {\n positions: undefined,\n // map of (node id) => (position obj); or function(node){ return somPos; }\n zoom: undefined,\n // the zoom level to set (prob want fit = false if set)\n pan: undefined,\n // the pan level to set (prob want fit = false if set)\n fit: true,\n // whether to fit to viewport\n padding: 30,\n // padding on fit\n spacingFactor: undefined,\n // Applies a multiplicative factor (>0) to expand or compress the overall area that the nodes take up\n animate: false,\n // whether to transition the node positions\n animationDuration: 500,\n // duration of animation in ms if enabled\n animationEasing: undefined,\n // easing of animation if enabled\n animateFilter: function animateFilter(node, i) {\n return true;\n },\n // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts\n ready: undefined,\n // callback on layoutready\n stop: undefined,\n // callback on layoutstop\n transform: function transform(node, position) {\n return position;\n } // transform a given node position. Useful for changing flow direction in discrete layouts\n};\n\nfunction PresetLayout(options) {\n this.options = extend({}, defaults$1, options);\n}\nPresetLayout.prototype.run = function () {\n var options = this.options;\n var eles = options.eles;\n var nodes = eles.nodes();\n var posIsFn = fn$6(options.positions);\n function getPosition(node) {\n if (options.positions == null) {\n return copyPosition(node.position());\n }\n if (posIsFn) {\n return options.positions(node);\n }\n var pos = options.positions[node._private.data.id];\n if (pos == null) {\n return null;\n }\n return pos;\n }\n nodes.layoutPositions(this, options, function (node, i) {\n var position = getPosition(node);\n if (node.locked() || position == null) {\n return false;\n }\n return position;\n });\n return this; // chaining\n};\n\nvar defaults = {\n fit: true,\n // whether to fit to viewport\n padding: 30,\n // fit padding\n boundingBox: undefined,\n // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }\n animate: false,\n // whether to transition the node positions\n animationDuration: 500,\n // duration of animation in ms if enabled\n animationEasing: undefined,\n // easing of animation if enabled\n animateFilter: function animateFilter(node, i) {\n return true;\n },\n // a function that determines whether the node should be animated. All nodes animated by default on animate enabled. Non-animated nodes are positioned immediately when the layout starts\n ready: undefined,\n // callback on layoutready\n stop: undefined,\n // callback on layoutstop\n transform: function transform(node, position) {\n return position;\n } // transform a given node position. Useful for changing flow direction in discrete layouts \n};\n\nfunction RandomLayout(options) {\n this.options = extend({}, defaults, options);\n}\nRandomLayout.prototype.run = function () {\n var options = this.options;\n var cy = options.cy;\n var eles = options.eles;\n var bb = makeBoundingBox(options.boundingBox ? options.boundingBox : {\n x1: 0,\n y1: 0,\n w: cy.width(),\n h: cy.height()\n });\n var getPos = function getPos(node, i) {\n return {\n x: bb.x1 + Math.round(Math.random() * bb.w),\n y: bb.y1 + Math.round(Math.random() * bb.h)\n };\n };\n eles.nodes().layoutPositions(this, options, getPos);\n return this; // chaining\n};\n\nvar layout = [{\n name: 'breadthfirst',\n impl: BreadthFirstLayout\n}, {\n name: 'circle',\n impl: CircleLayout\n}, {\n name: 'concentric',\n impl: ConcentricLayout\n}, {\n name: 'cose',\n impl: CoseLayout\n}, {\n name: 'grid',\n impl: GridLayout\n}, {\n name: 'null',\n impl: NullLayout\n}, {\n name: 'preset',\n impl: PresetLayout\n}, {\n name: 'random',\n impl: RandomLayout\n}];\n\nfunction NullRenderer(options) {\n this.options = options;\n this.notifications = 0; // for testing\n}\n\nvar noop = function noop() {};\nvar throwImgErr = function throwImgErr() {\n throw new Error('A headless instance can not render images');\n};\nNullRenderer.prototype = {\n recalculateRenderedStyle: noop,\n notify: function notify() {\n this.notifications++;\n },\n init: noop,\n isHeadless: function isHeadless() {\n return true;\n },\n png: throwImgErr,\n jpg: throwImgErr\n};\n\nvar BRp$f = {};\nBRp$f.arrowShapeWidth = 0.3;\nBRp$f.registerArrowShapes = function () {\n var arrowShapes = this.arrowShapes = {};\n var renderer = this;\n\n // Contract for arrow shapes:\n // 0, 0 is arrow tip\n // (0, 1) is direction towards node\n // (1, 0) is right\n //\n // functional api:\n // collide: check x, y in shape\n // roughCollide: called before collide, no false negatives\n // draw: draw\n // spacing: dist(arrowTip, nodeBoundary)\n // gap: dist(edgeTip, nodeBoundary), edgeTip may != arrowTip\n\n var bbCollide = function bbCollide(x, y, size, angle, translation, edgeWidth, padding) {\n var x1 = translation.x - size / 2 - padding;\n var x2 = translation.x + size / 2 + padding;\n var y1 = translation.y - size / 2 - padding;\n var y2 = translation.y + size / 2 + padding;\n var inside = x1 <= x && x <= x2 && y1 <= y && y <= y2;\n return inside;\n };\n var transform = function transform(x, y, size, angle, translation) {\n var xRotated = x * Math.cos(angle) - y * Math.sin(angle);\n var yRotated = x * Math.sin(angle) + y * Math.cos(angle);\n var xScaled = xRotated * size;\n var yScaled = yRotated * size;\n var xTranslated = xScaled + translation.x;\n var yTranslated = yScaled + translation.y;\n return {\n x: xTranslated,\n y: yTranslated\n };\n };\n var transformPoints = function transformPoints(pts, size, angle, translation) {\n var retPts = [];\n for (var i = 0; i < pts.length; i += 2) {\n var x = pts[i];\n var y = pts[i + 1];\n retPts.push(transform(x, y, size, angle, translation));\n }\n return retPts;\n };\n var pointsToArr = function pointsToArr(pts) {\n var ret = [];\n for (var i = 0; i < pts.length; i++) {\n var p = pts[i];\n ret.push(p.x, p.y);\n }\n return ret;\n };\n var standardGap = function standardGap(edge) {\n return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').pfValue * 2;\n };\n var defineArrowShape = function defineArrowShape(name, defn) {\n if (string(defn)) {\n defn = arrowShapes[defn];\n }\n arrowShapes[name] = extend({\n name: name,\n points: [-0.15, -0.3, 0.15, -0.3, 0.15, 0.3, -0.15, 0.3],\n collide: function collide(x, y, size, angle, translation, padding) {\n var points = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));\n var inside = pointInsidePolygonPoints(x, y, points);\n return inside;\n },\n roughCollide: bbCollide,\n draw: function draw(context, size, angle, translation) {\n var points = transformPoints(this.points, size, angle, translation);\n renderer.arrowShapeImpl('polygon')(context, points);\n },\n spacing: function spacing(edge) {\n return 0;\n },\n gap: standardGap\n }, defn);\n };\n defineArrowShape('none', {\n collide: falsify,\n roughCollide: falsify,\n draw: noop$1,\n spacing: zeroify,\n gap: zeroify\n });\n defineArrowShape('triangle', {\n points: [-0.15, -0.3, 0, 0, 0.15, -0.3]\n });\n defineArrowShape('arrow', 'triangle');\n defineArrowShape('triangle-backcurve', {\n points: arrowShapes['triangle'].points,\n controlPoint: [0, -0.15],\n roughCollide: bbCollide,\n draw: function draw(context, size, angle, translation, edgeWidth) {\n var ptsTrans = transformPoints(this.points, size, angle, translation);\n var ctrlPt = this.controlPoint;\n var ctrlPtTrans = transform(ctrlPt[0], ctrlPt[1], size, angle, translation);\n renderer.arrowShapeImpl(this.name)(context, ptsTrans, ctrlPtTrans);\n },\n gap: function gap(edge) {\n return standardGap(edge) * 0.8;\n }\n });\n defineArrowShape('triangle-tee', {\n points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0],\n pointsTee: [-0.15, -0.4, -0.15, -0.5, 0.15, -0.5, 0.15, -0.4],\n collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {\n var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));\n var teePts = pointsToArr(transformPoints(this.pointsTee, size + 2 * padding, angle, translation));\n var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts);\n return inside;\n },\n draw: function draw(context, size, angle, translation, edgeWidth) {\n var triPts = transformPoints(this.points, size, angle, translation);\n var teePts = transformPoints(this.pointsTee, size, angle, translation);\n renderer.arrowShapeImpl(this.name)(context, triPts, teePts);\n }\n });\n defineArrowShape('circle-triangle', {\n radius: 0.15,\n pointsTr: [0, -0.15, 0.15, -0.45, -0.15, -0.45, 0, -0.15],\n collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {\n var t = translation;\n var circleInside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2);\n var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));\n return pointInsidePolygonPoints(x, y, triPts) || circleInside;\n },\n draw: function draw(context, size, angle, translation, edgeWidth) {\n var triPts = transformPoints(this.pointsTr, size, angle, translation);\n renderer.arrowShapeImpl(this.name)(context, triPts, translation.x, translation.y, this.radius * size);\n },\n spacing: function spacing(edge) {\n return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius;\n }\n });\n defineArrowShape('triangle-cross', {\n points: [0, 0, 0.15, -0.3, -0.15, -0.3, 0, 0],\n baseCrossLinePts: [-0.15, -0.4,\n // first half of the rectangle\n -0.15, -0.4, 0.15, -0.4,\n // second half of the rectangle\n 0.15, -0.4],\n crossLinePts: function crossLinePts(size, edgeWidth) {\n // shift points so that the distance between the cross points matches edge width\n var p = this.baseCrossLinePts.slice();\n var shiftFactor = edgeWidth / size;\n var y0 = 3;\n var y1 = 5;\n p[y0] = p[y0] - shiftFactor;\n p[y1] = p[y1] - shiftFactor;\n return p;\n },\n collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {\n var triPts = pointsToArr(transformPoints(this.points, size + 2 * padding, angle, translation));\n var teePts = pointsToArr(transformPoints(this.crossLinePts(size, edgeWidth), size + 2 * padding, angle, translation));\n var inside = pointInsidePolygonPoints(x, y, triPts) || pointInsidePolygonPoints(x, y, teePts);\n return inside;\n },\n draw: function draw(context, size, angle, translation, edgeWidth) {\n var triPts = transformPoints(this.points, size, angle, translation);\n var crossLinePts = transformPoints(this.crossLinePts(size, edgeWidth), size, angle, translation);\n renderer.arrowShapeImpl(this.name)(context, triPts, crossLinePts);\n }\n });\n defineArrowShape('vee', {\n points: [-0.15, -0.3, 0, 0, 0.15, -0.3, 0, -0.15],\n gap: function gap(edge) {\n return standardGap(edge) * 0.525;\n }\n });\n defineArrowShape('circle', {\n radius: 0.15,\n collide: function collide(x, y, size, angle, translation, edgeWidth, padding) {\n var t = translation;\n var inside = Math.pow(t.x - x, 2) + Math.pow(t.y - y, 2) <= Math.pow((size + 2 * padding) * this.radius, 2);\n return inside;\n },\n draw: function draw(context, size, angle, translation, edgeWidth) {\n renderer.arrowShapeImpl(this.name)(context, translation.x, translation.y, this.radius * size);\n },\n spacing: function spacing(edge) {\n return renderer.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.radius;\n }\n });\n defineArrowShape('tee', {\n points: [-0.15, 0, -0.15, -0.1, 0.15, -0.1, 0.15, 0],\n spacing: function spacing(edge) {\n return 1;\n },\n gap: function gap(edge) {\n return 1;\n }\n });\n defineArrowShape('square', {\n points: [-0.15, 0.00, 0.15, 0.00, 0.15, -0.3, -0.15, -0.3]\n });\n defineArrowShape('diamond', {\n points: [-0.15, -0.15, 0, -0.3, 0.15, -0.15, 0, 0],\n gap: function gap(edge) {\n return edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value;\n }\n });\n defineArrowShape('chevron', {\n points: [0, 0, -0.15, -0.15, -0.1, -0.2, 0, -0.1, 0.1, -0.2, 0.15, -0.15],\n gap: function gap(edge) {\n return 0.95 * edge.pstyle('width').pfValue * edge.pstyle('arrow-scale').value;\n }\n });\n};\n\nvar BRp$e = {};\n\n// Project mouse\nBRp$e.projectIntoViewport = function (clientX, clientY) {\n var cy = this.cy;\n var offsets = this.findContainerClientCoords();\n var offsetLeft = offsets[0];\n var offsetTop = offsets[1];\n var scale = offsets[4];\n var pan = cy.pan();\n var zoom = cy.zoom();\n var x = ((clientX - offsetLeft) / scale - pan.x) / zoom;\n var y = ((clientY - offsetTop) / scale - pan.y) / zoom;\n return [x, y];\n};\nBRp$e.findContainerClientCoords = function () {\n if (this.containerBB) {\n return this.containerBB;\n }\n var container = this.container;\n var rect = container.getBoundingClientRect();\n var style = this.cy.window().getComputedStyle(container);\n var styleValue = function styleValue(name) {\n return parseFloat(style.getPropertyValue(name));\n };\n var padding = {\n left: styleValue('padding-left'),\n right: styleValue('padding-right'),\n top: styleValue('padding-top'),\n bottom: styleValue('padding-bottom')\n };\n var border = {\n left: styleValue('border-left-width'),\n right: styleValue('border-right-width'),\n top: styleValue('border-top-width'),\n bottom: styleValue('border-bottom-width')\n };\n var clientWidth = container.clientWidth;\n var clientHeight = container.clientHeight;\n var paddingHor = padding.left + padding.right;\n var paddingVer = padding.top + padding.bottom;\n var borderHor = border.left + border.right;\n var scale = rect.width / (clientWidth + borderHor);\n var unscaledW = clientWidth - paddingHor;\n var unscaledH = clientHeight - paddingVer;\n var left = rect.left + padding.left + border.left;\n var top = rect.top + padding.top + border.top;\n return this.containerBB = [left, top, unscaledW, unscaledH, scale];\n};\nBRp$e.invalidateContainerClientCoordsCache = function () {\n this.containerBB = null;\n};\nBRp$e.findNearestElement = function (x, y, interactiveElementsOnly, isTouch) {\n return this.findNearestElements(x, y, interactiveElementsOnly, isTouch)[0];\n};\nBRp$e.findNearestElements = function (x, y, interactiveElementsOnly, isTouch) {\n var self = this;\n var r = this;\n var eles = r.getCachedZSortedEles();\n var near = []; // 1 node max, 1 edge max\n var zoom = r.cy.zoom();\n var hasCompounds = r.cy.hasCompoundNodes();\n var edgeThreshold = (isTouch ? 24 : 8) / zoom;\n var nodeThreshold = (isTouch ? 8 : 2) / zoom;\n var labelThreshold = (isTouch ? 8 : 2) / zoom;\n var minSqDist = Infinity;\n var nearEdge;\n var nearNode;\n if (interactiveElementsOnly) {\n eles = eles.interactive;\n }\n function addEle(ele, sqDist) {\n if (ele.isNode()) {\n if (nearNode) {\n return; // can't replace node\n } else {\n nearNode = ele;\n near.push(ele);\n }\n }\n if (ele.isEdge() && (sqDist == null || sqDist < minSqDist)) {\n if (nearEdge) {\n // then replace existing edge\n // can replace only if same z-index\n if (nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value && nearEdge.pstyle('z-compound-depth').value === ele.pstyle('z-compound-depth').value) {\n for (var i = 0; i < near.length; i++) {\n if (near[i].isEdge()) {\n near[i] = ele;\n nearEdge = ele;\n minSqDist = sqDist != null ? sqDist : minSqDist;\n break;\n }\n }\n }\n } else {\n near.push(ele);\n nearEdge = ele;\n minSqDist = sqDist != null ? sqDist : minSqDist;\n }\n }\n }\n function checkNode(node) {\n var width = node.outerWidth() + 2 * nodeThreshold;\n var height = node.outerHeight() + 2 * nodeThreshold;\n var hw = width / 2;\n var hh = height / 2;\n var pos = node.position();\n var cornerRadius = node.pstyle('corner-radius').value === 'auto' ? 'auto' : node.pstyle('corner-radius').pfValue;\n var rs = node._private.rscratch;\n if (pos.x - hw <= x && x <= pos.x + hw // bb check x\n && pos.y - hh <= y && y <= pos.y + hh // bb check y\n ) {\n var shape = r.nodeShapes[self.getNodeShape(node)];\n if (shape.checkPoint(x, y, 0, width, height, pos.x, pos.y, cornerRadius, rs)) {\n addEle(node, 0);\n return true;\n }\n }\n }\n function checkEdge(edge) {\n var _p = edge._private;\n var rs = _p.rscratch;\n var styleWidth = edge.pstyle('width').pfValue;\n var scale = edge.pstyle('arrow-scale').value;\n var width = styleWidth / 2 + edgeThreshold; // more like a distance radius from centre\n var widthSq = width * width;\n var width2 = width * 2;\n var src = _p.source;\n var tgt = _p.target;\n var sqDist;\n if (rs.edgeType === 'segments' || rs.edgeType === 'straight' || rs.edgeType === 'haystack') {\n var pts = rs.allpts;\n for (var i = 0; i + 3 < pts.length; i += 2) {\n if (inLineVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], width2) && widthSq > (sqDist = sqdistToFiniteLine(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3]))) {\n addEle(edge, sqDist);\n return true;\n }\n }\n } else if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') {\n var pts = rs.allpts;\n for (var i = 0; i + 5 < rs.allpts.length; i += 4) {\n if (inBezierVicinity(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5], width2) && widthSq > (sqDist = sqdistToQuadraticBezier(x, y, pts[i], pts[i + 1], pts[i + 2], pts[i + 3], pts[i + 4], pts[i + 5]))) {\n addEle(edge, sqDist);\n return true;\n }\n }\n }\n\n // if we're close to the edge but didn't hit it, maybe we hit its arrows\n\n var src = src || _p.source;\n var tgt = tgt || _p.target;\n var arSize = self.getArrowWidth(styleWidth, scale);\n var arrows = [{\n name: 'source',\n x: rs.arrowStartX,\n y: rs.arrowStartY,\n angle: rs.srcArrowAngle\n }, {\n name: 'target',\n x: rs.arrowEndX,\n y: rs.arrowEndY,\n angle: rs.tgtArrowAngle\n }, {\n name: 'mid-source',\n x: rs.midX,\n y: rs.midY,\n angle: rs.midsrcArrowAngle\n }, {\n name: 'mid-target',\n x: rs.midX,\n y: rs.midY,\n angle: rs.midtgtArrowAngle\n }];\n for (var i = 0; i < arrows.length; i++) {\n var ar = arrows[i];\n var shape = r.arrowShapes[edge.pstyle(ar.name + '-arrow-shape').value];\n var edgeWidth = edge.pstyle('width').pfValue;\n if (shape.roughCollide(x, y, arSize, ar.angle, {\n x: ar.x,\n y: ar.y\n }, edgeWidth, edgeThreshold) && shape.collide(x, y, arSize, ar.angle, {\n x: ar.x,\n y: ar.y\n }, edgeWidth, edgeThreshold)) {\n addEle(edge);\n return true;\n }\n }\n\n // for compound graphs, hitting edge may actually want a connected node instead (b/c edge may have greater z-index precedence)\n if (hasCompounds && near.length > 0) {\n checkNode(src);\n checkNode(tgt);\n }\n }\n function preprop(obj, name, pre) {\n return getPrefixedProperty(obj, name, pre);\n }\n function checkLabel(ele, prefix) {\n var _p = ele._private;\n var th = labelThreshold;\n var prefixDash;\n if (prefix) {\n prefixDash = prefix + '-';\n } else {\n prefixDash = '';\n }\n ele.boundingBox();\n var bb = _p.labelBounds[prefix || 'main'];\n var text = ele.pstyle(prefixDash + 'label').value;\n var eventsEnabled = ele.pstyle('text-events').strValue === 'yes';\n if (!eventsEnabled || !text) {\n return;\n }\n var lx = preprop(_p.rscratch, 'labelX', prefix);\n var ly = preprop(_p.rscratch, 'labelY', prefix);\n var theta = preprop(_p.rscratch, 'labelAngle', prefix);\n var ox = ele.pstyle(prefixDash + 'text-margin-x').pfValue;\n var oy = ele.pstyle(prefixDash + 'text-margin-y').pfValue;\n var lx1 = bb.x1 - th - ox; // (-ox, -oy) as bb already includes margin\n var lx2 = bb.x2 + th - ox; // and rotation is about (lx, ly)\n var ly1 = bb.y1 - th - oy;\n var ly2 = bb.y2 + th - oy;\n if (theta) {\n var cos = Math.cos(theta);\n var sin = Math.sin(theta);\n var rotate = function rotate(x, y) {\n x = x - lx;\n y = y - ly;\n return {\n x: x * cos - y * sin + lx,\n y: x * sin + y * cos + ly\n };\n };\n var px1y1 = rotate(lx1, ly1);\n var px1y2 = rotate(lx1, ly2);\n var px2y1 = rotate(lx2, ly1);\n var px2y2 = rotate(lx2, ly2);\n var points = [\n // with the margin added after the rotation is applied\n px1y1.x + ox, px1y1.y + oy, px2y1.x + ox, px2y1.y + oy, px2y2.x + ox, px2y2.y + oy, px1y2.x + ox, px1y2.y + oy];\n if (pointInsidePolygonPoints(x, y, points)) {\n addEle(ele);\n return true;\n }\n } else {\n // do a cheaper bb check\n if (inBoundingBox(bb, x, y)) {\n addEle(ele);\n return true;\n }\n }\n }\n for (var i = eles.length - 1; i >= 0; i--) {\n // reverse order for precedence\n var ele = eles[i];\n if (ele.isNode()) {\n checkNode(ele) || checkLabel(ele);\n } else {\n // then edge\n checkEdge(ele) || checkLabel(ele) || checkLabel(ele, 'source') || checkLabel(ele, 'target');\n }\n }\n return near;\n};\n\n// 'Give me everything from this box'\nBRp$e.getAllInBox = function (x1, y1, x2, y2) {\n var eles = this.getCachedZSortedEles().interactive;\n var box = [];\n var x1c = Math.min(x1, x2);\n var x2c = Math.max(x1, x2);\n var y1c = Math.min(y1, y2);\n var y2c = Math.max(y1, y2);\n x1 = x1c;\n x2 = x2c;\n y1 = y1c;\n y2 = y2c;\n var boxBb = makeBoundingBox({\n x1: x1,\n y1: y1,\n x2: x2,\n y2: y2\n });\n for (var e = 0; e < eles.length; e++) {\n var ele = eles[e];\n if (ele.isNode()) {\n var node = ele;\n var nodeBb = node.boundingBox({\n includeNodes: true,\n includeEdges: false,\n includeLabels: false\n });\n if (boundingBoxesIntersect(boxBb, nodeBb) && !boundingBoxInBoundingBox(nodeBb, boxBb)) {\n box.push(node);\n }\n } else {\n var edge = ele;\n var _p = edge._private;\n var rs = _p.rscratch;\n if (rs.startX != null && rs.startY != null && !inBoundingBox(boxBb, rs.startX, rs.startY)) {\n continue;\n }\n if (rs.endX != null && rs.endY != null && !inBoundingBox(boxBb, rs.endX, rs.endY)) {\n continue;\n }\n if (rs.edgeType === 'bezier' || rs.edgeType === 'multibezier' || rs.edgeType === 'self' || rs.edgeType === 'compound' || rs.edgeType === 'segments' || rs.edgeType === 'haystack') {\n var pts = _p.rstyle.bezierPts || _p.rstyle.linePts || _p.rstyle.haystackPts;\n var allInside = true;\n for (var i = 0; i < pts.length; i++) {\n if (!pointInBoundingBox(boxBb, pts[i])) {\n allInside = false;\n break;\n }\n }\n if (allInside) {\n box.push(edge);\n }\n } else if (rs.edgeType === 'haystack' || rs.edgeType === 'straight') {\n box.push(edge);\n }\n }\n }\n return box;\n};\n\nvar BRp$d = {};\nBRp$d.calculateArrowAngles = function (edge) {\n var rs = edge._private.rscratch;\n var isHaystack = rs.edgeType === 'haystack';\n var isBezier = rs.edgeType === 'bezier';\n var isMultibezier = rs.edgeType === 'multibezier';\n var isSegments = rs.edgeType === 'segments';\n var isCompound = rs.edgeType === 'compound';\n var isSelf = rs.edgeType === 'self';\n\n // Displacement gives direction for arrowhead orientation\n var dispX, dispY;\n var startX, startY, endX, endY, midX, midY;\n if (isHaystack) {\n startX = rs.haystackPts[0];\n startY = rs.haystackPts[1];\n endX = rs.haystackPts[2];\n endY = rs.haystackPts[3];\n } else {\n startX = rs.arrowStartX;\n startY = rs.arrowStartY;\n endX = rs.arrowEndX;\n endY = rs.arrowEndY;\n }\n midX = rs.midX;\n midY = rs.midY;\n\n // source\n //\n\n if (isSegments) {\n dispX = startX - rs.segpts[0];\n dispY = startY - rs.segpts[1];\n } else if (isMultibezier || isCompound || isSelf || isBezier) {\n var pts = rs.allpts;\n var bX = qbezierAt(pts[0], pts[2], pts[4], 0.1);\n var bY = qbezierAt(pts[1], pts[3], pts[5], 0.1);\n dispX = startX - bX;\n dispY = startY - bY;\n } else {\n dispX = startX - midX;\n dispY = startY - midY;\n }\n rs.srcArrowAngle = getAngleFromDisp(dispX, dispY);\n\n // mid target\n //\n\n var midX = rs.midX;\n var midY = rs.midY;\n if (isHaystack) {\n midX = (startX + endX) / 2;\n midY = (startY + endY) / 2;\n }\n dispX = endX - startX;\n dispY = endY - startY;\n if (isSegments) {\n var pts = rs.allpts;\n if (pts.length / 2 % 2 === 0) {\n var i2 = pts.length / 2;\n var i1 = i2 - 2;\n dispX = pts[i2] - pts[i1];\n dispY = pts[i2 + 1] - pts[i1 + 1];\n } else if (rs.isRound) {\n dispX = rs.midVector[1];\n dispY = -rs.midVector[0];\n } else {\n var i2 = pts.length / 2 - 1;\n var i1 = i2 - 2;\n dispX = pts[i2] - pts[i1];\n dispY = pts[i2 + 1] - pts[i1 + 1];\n }\n } else if (isMultibezier || isCompound || isSelf) {\n var pts = rs.allpts;\n var cpts = rs.ctrlpts;\n var bp0x, bp0y;\n var bp1x, bp1y;\n if (cpts.length / 2 % 2 === 0) {\n var p0 = pts.length / 2 - 1; // startpt\n var ic = p0 + 2;\n var p1 = ic + 2;\n bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0);\n bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0);\n bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.0001);\n bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.0001);\n } else {\n var ic = pts.length / 2 - 1; // ctrpt\n var p0 = ic - 2; // startpt\n var p1 = ic + 2; // endpt\n\n bp0x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.4999);\n bp0y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.4999);\n bp1x = qbezierAt(pts[p0], pts[ic], pts[p1], 0.5);\n bp1y = qbezierAt(pts[p0 + 1], pts[ic + 1], pts[p1 + 1], 0.5);\n }\n dispX = bp1x - bp0x;\n dispY = bp1y - bp0y;\n }\n rs.midtgtArrowAngle = getAngleFromDisp(dispX, dispY);\n rs.midDispX = dispX;\n rs.midDispY = dispY;\n\n // mid source\n //\n\n dispX *= -1;\n dispY *= -1;\n if (isSegments) {\n var pts = rs.allpts;\n if (pts.length / 2 % 2 === 0) ; else if (!rs.isRound) {\n var i2 = pts.length / 2 - 1;\n var i3 = i2 + 2;\n dispX = -(pts[i3] - pts[i2]);\n dispY = -(pts[i3 + 1] - pts[i2 + 1]);\n }\n }\n rs.midsrcArrowAngle = getAngleFromDisp(dispX, dispY);\n\n // target\n //\n\n if (isSegments) {\n dispX = endX - rs.segpts[rs.segpts.length - 2];\n dispY = endY - rs.segpts[rs.segpts.length - 1];\n } else if (isMultibezier || isCompound || isSelf || isBezier) {\n var pts = rs.allpts;\n var l = pts.length;\n var bX = qbezierAt(pts[l - 6], pts[l - 4], pts[l - 2], 0.9);\n var bY = qbezierAt(pts[l - 5], pts[l - 3], pts[l - 1], 0.9);\n dispX = endX - bX;\n dispY = endY - bY;\n } else {\n dispX = endX - midX;\n dispY = endY - midY;\n }\n rs.tgtArrowAngle = getAngleFromDisp(dispX, dispY);\n};\nBRp$d.getArrowWidth = BRp$d.getArrowHeight = function (edgeWidth, scale) {\n var cache = this.arrowWidthCache = this.arrowWidthCache || {};\n var cachedVal = cache[edgeWidth + ', ' + scale];\n if (cachedVal) {\n return cachedVal;\n }\n cachedVal = Math.max(Math.pow(edgeWidth * 13.37, 0.9), 29) * scale;\n cache[edgeWidth + ', ' + scale] = cachedVal;\n return cachedVal;\n};\n\n/**\n * Explained by Blindman67 at https://stackoverflow.com/a/44856925/11028828\n */\n\n// Declare reused variable to avoid reallocating variables every time the function is called\nvar x,\n y,\n v1 = {},\n v2 = {},\n sinA,\n sinA90,\n radDirection,\n drawDirection,\n angle,\n halfAngle,\n cRadius,\n lenOut,\n radius,\n limit;\nvar startX, startY, stopX, stopY;\nvar lastPoint;\n\n// convert 2 points into vector form, polar form, and normalised\nvar asVec = function asVec(p, pp, v) {\n v.x = pp.x - p.x;\n v.y = pp.y - p.y;\n v.len = Math.sqrt(v.x * v.x + v.y * v.y);\n v.nx = v.x / v.len;\n v.ny = v.y / v.len;\n v.ang = Math.atan2(v.ny, v.nx);\n};\nvar invertVec = function invertVec(originalV, invertedV) {\n invertedV.x = originalV.x * -1;\n invertedV.y = originalV.y * -1;\n invertedV.nx = originalV.nx * -1;\n invertedV.ny = originalV.ny * -1;\n invertedV.ang = originalV.ang > 0 ? -(Math.PI - originalV.ang) : Math.PI + originalV.ang;\n};\nvar calcCornerArc = function calcCornerArc(previousPoint, currentPoint, nextPoint, radiusMax, isArcRadius) {\n //-----------------------------------------\n // Part 1\n previousPoint !== lastPoint ? asVec(currentPoint, previousPoint, v1) : invertVec(v2, v1); // Avoid recalculating vec if it is the invert of the last one calculated\n asVec(currentPoint, nextPoint, v2);\n sinA = v1.nx * v2.ny - v1.ny * v2.nx;\n sinA90 = v1.nx * v2.nx - v1.ny * -v2.ny;\n angle = Math.asin(Math.max(-1, Math.min(1, sinA)));\n if (Math.abs(angle) < 1e-6) {\n x = currentPoint.x;\n y = currentPoint.y;\n cRadius = radius = 0;\n return;\n }\n //-----------------------------------------\n radDirection = 1;\n drawDirection = false;\n if (sinA90 < 0) {\n if (angle < 0) {\n angle = Math.PI + angle;\n } else {\n angle = Math.PI - angle;\n radDirection = -1;\n drawDirection = true;\n }\n } else {\n if (angle > 0) {\n radDirection = -1;\n drawDirection = true;\n }\n }\n if (currentPoint.radius !== undefined) {\n radius = currentPoint.radius;\n } else {\n radius = radiusMax;\n }\n //-----------------------------------------\n // Part 2\n halfAngle = angle / 2;\n //-----------------------------------------\n\n limit = Math.min(v1.len / 2, v2.len / 2);\n if (isArcRadius) {\n //-----------------------------------------\n // Part 3\n lenOut = Math.abs(Math.cos(halfAngle) * radius / Math.sin(halfAngle));\n\n //-----------------------------------------\n // Special part A\n if (lenOut > limit) {\n lenOut = limit;\n cRadius = Math.abs(lenOut * Math.sin(halfAngle) / Math.cos(halfAngle));\n } else {\n cRadius = radius;\n }\n } else {\n lenOut = Math.min(limit, radius);\n cRadius = Math.abs(lenOut * Math.sin(halfAngle) / Math.cos(halfAngle));\n }\n //-----------------------------------------\n\n //-----------------------------------------\n // Part 4\n stopX = currentPoint.x + v2.nx * lenOut;\n stopY = currentPoint.y + v2.ny * lenOut;\n //-----------------------------------------\n // Part 5\n x = stopX - v2.ny * cRadius * radDirection;\n y = stopY + v2.nx * cRadius * radDirection;\n //-----------------------------------------\n // Additional Part : calculate start point E\n startX = currentPoint.x + v1.nx * lenOut;\n startY = currentPoint.y + v1.ny * lenOut;\n\n // Save last point to avoid recalculating vector when not needed\n lastPoint = currentPoint;\n};\n\n/**\n * Draw corner provided by {@link getRoundCorner}\n *\n * @param ctx :CanvasRenderingContext2D\n * @param roundCorner {{cx:number, cy:number, radius:number, endAngle: number, startAngle: number, counterClockwise: boolean}}\n */\nfunction drawPreparedRoundCorner(ctx, roundCorner) {\n if (roundCorner.radius === 0) ctx.lineTo(roundCorner.cx, roundCorner.cy);else ctx.arc(roundCorner.cx, roundCorner.cy, roundCorner.radius, roundCorner.startAngle, roundCorner.endAngle, roundCorner.counterClockwise);\n}\n\n/**\n * Get round corner from a point and its previous and next neighbours in a path\n *\n * @param previousPoint {{x: number, y:number, radius: number?}}\n * @param currentPoint {{x: number, y:number, radius: number?}}\n * @param nextPoint {{x: number, y:number, radius: number?}}\n * @param radiusMax :number\n * @param isArcRadius :boolean\n * @return {{\n * cx:number, cy:number, radius:number,\n * startX:number, startY:number,\n * stopX:number, stopY: number,\n * endAngle: number, startAngle: number, counterClockwise: boolean\n * }}\n */\nfunction getRoundCorner(previousPoint, currentPoint, nextPoint, radiusMax) {\n var isArcRadius = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n if (radiusMax === 0 || currentPoint.radius === 0) return {\n cx: currentPoint.x,\n cy: currentPoint.y,\n radius: 0,\n startX: currentPoint.x,\n startY: currentPoint.y,\n stopX: currentPoint.x,\n stopY: currentPoint.y,\n startAngle: undefined,\n endAngle: undefined,\n counterClockwise: undefined\n };\n calcCornerArc(previousPoint, currentPoint, nextPoint, radiusMax, isArcRadius);\n return {\n cx: x,\n cy: y,\n radius: cRadius,\n startX: startX,\n startY: startY,\n stopX: stopX,\n stopY: stopY,\n startAngle: v1.ang + Math.PI / 2 * radDirection,\n endAngle: v2.ang - Math.PI / 2 * radDirection,\n counterClockwise: drawDirection\n };\n}\n\nvar BRp$c = {};\nBRp$c.findMidptPtsEtc = function (edge, pairInfo) {\n var posPts = pairInfo.posPts,\n intersectionPts = pairInfo.intersectionPts,\n vectorNormInverse = pairInfo.vectorNormInverse;\n var midptPts;\n\n // n.b. assumes all edges in bezier bundle have same endpoints specified\n var srcManEndpt = edge.pstyle('source-endpoint');\n var tgtManEndpt = edge.pstyle('target-endpoint');\n var haveManualEndPts = srcManEndpt.units != null && tgtManEndpt.units != null;\n var recalcVectorNormInverse = function recalcVectorNormInverse(x1, y1, x2, y2) {\n var dy = y2 - y1;\n var dx = x2 - x1;\n var l = Math.sqrt(dx * dx + dy * dy);\n return {\n x: -dy / l,\n y: dx / l\n };\n };\n var edgeDistances = edge.pstyle('edge-distances').value;\n switch (edgeDistances) {\n case 'node-position':\n midptPts = posPts;\n break;\n case 'intersection':\n midptPts = intersectionPts;\n break;\n case 'endpoints':\n {\n if (haveManualEndPts) {\n var _this$manualEndptToPx = this.manualEndptToPx(edge.source()[0], srcManEndpt),\n _this$manualEndptToPx2 = _slicedToArray(_this$manualEndptToPx, 2),\n x1 = _this$manualEndptToPx2[0],\n y1 = _this$manualEndptToPx2[1];\n var _this$manualEndptToPx3 = this.manualEndptToPx(edge.target()[0], tgtManEndpt),\n _this$manualEndptToPx4 = _slicedToArray(_this$manualEndptToPx3, 2),\n x2 = _this$manualEndptToPx4[0],\n y2 = _this$manualEndptToPx4[1];\n var endPts = {\n x1: x1,\n y1: y1,\n x2: x2,\n y2: y2\n };\n vectorNormInverse = recalcVectorNormInverse(x1, y1, x2, y2);\n midptPts = endPts;\n } else {\n warn(\"Edge \".concat(edge.id(), \" has edge-distances:endpoints specified without manual endpoints specified via source-endpoint and target-endpoint. Falling back on edge-distances:intersection (default).\"));\n midptPts = intersectionPts; // back to default\n }\n\n break;\n }\n }\n return {\n midptPts: midptPts,\n vectorNormInverse: vectorNormInverse\n };\n};\nBRp$c.findHaystackPoints = function (edges) {\n for (var i = 0; i < edges.length; i++) {\n var edge = edges[i];\n var _p = edge._private;\n var rs = _p.rscratch;\n if (!rs.haystack) {\n var angle = Math.random() * 2 * Math.PI;\n rs.source = {\n x: Math.cos(angle),\n y: Math.sin(angle)\n };\n angle = Math.random() * 2 * Math.PI;\n rs.target = {\n x: Math.cos(angle),\n y: Math.sin(angle)\n };\n }\n var src = _p.source;\n var tgt = _p.target;\n var srcPos = src.position();\n var tgtPos = tgt.position();\n var srcW = src.width();\n var tgtW = tgt.width();\n var srcH = src.height();\n var tgtH = tgt.height();\n var radius = edge.pstyle('haystack-radius').value;\n var halfRadius = radius / 2; // b/c have to half width/height\n\n rs.haystackPts = rs.allpts = [rs.source.x * srcW * halfRadius + srcPos.x, rs.source.y * srcH * halfRadius + srcPos.y, rs.target.x * tgtW * halfRadius + tgtPos.x, rs.target.y * tgtH * halfRadius + tgtPos.y];\n rs.midX = (rs.allpts[0] + rs.allpts[2]) / 2;\n rs.midY = (rs.allpts[1] + rs.allpts[3]) / 2;\n\n // always override as haystack in case set to different type previously\n rs.edgeType = 'haystack';\n rs.haystack = true;\n this.storeEdgeProjections(edge);\n this.calculateArrowAngles(edge);\n this.recalculateEdgeLabelProjections(edge);\n this.calculateLabelAngles(edge);\n }\n};\nBRp$c.findSegmentsPoints = function (edge, pairInfo) {\n // Segments (multiple straight lines)\n\n var rs = edge._private.rscratch;\n var segmentWs = edge.pstyle('segment-weights');\n var segmentDs = edge.pstyle('segment-distances');\n var segmentRs = edge.pstyle('segment-radii');\n var segmentTs = edge.pstyle('radius-type');\n var segmentsN = Math.min(segmentWs.pfValue.length, segmentDs.pfValue.length);\n var lastRadius = segmentRs.pfValue[segmentRs.pfValue.length - 1];\n var lastRadiusType = segmentTs.pfValue[segmentTs.pfValue.length - 1];\n rs.edgeType = 'segments';\n rs.segpts = [];\n rs.radii = [];\n rs.isArcRadius = [];\n for (var s = 0; s < segmentsN; s++) {\n var w = segmentWs.pfValue[s];\n var d = segmentDs.pfValue[s];\n var w1 = 1 - w;\n var w2 = w;\n var _this$findMidptPtsEtc = this.findMidptPtsEtc(edge, pairInfo),\n midptPts = _this$findMidptPtsEtc.midptPts,\n vectorNormInverse = _this$findMidptPtsEtc.vectorNormInverse;\n var adjustedMidpt = {\n x: midptPts.x1 * w1 + midptPts.x2 * w2,\n y: midptPts.y1 * w1 + midptPts.y2 * w2\n };\n rs.segpts.push(adjustedMidpt.x + vectorNormInverse.x * d, adjustedMidpt.y + vectorNormInverse.y * d);\n rs.radii.push(segmentRs.pfValue[s] !== undefined ? segmentRs.pfValue[s] : lastRadius);\n rs.isArcRadius.push((segmentTs.pfValue[s] !== undefined ? segmentTs.pfValue[s] : lastRadiusType) === 'arc-radius');\n }\n};\nBRp$c.findLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) {\n // Self-edge\n\n var rs = edge._private.rscratch;\n var dirCounts = pairInfo.dirCounts,\n srcPos = pairInfo.srcPos;\n var ctrlptDists = edge.pstyle('control-point-distances');\n var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;\n var loopDir = edge.pstyle('loop-direction').pfValue;\n var loopSwp = edge.pstyle('loop-sweep').pfValue;\n var stepSize = edge.pstyle('control-point-step-size').pfValue;\n rs.edgeType = 'self';\n var j = i;\n var loopDist = stepSize;\n if (edgeIsUnbundled) {\n j = 0;\n loopDist = ctrlptDist;\n }\n var loopAngle = loopDir - Math.PI / 2;\n var outAngle = loopAngle - loopSwp / 2;\n var inAngle = loopAngle + loopSwp / 2;\n\n // increase by step size for overlapping loops, keyed on direction and sweep values\n var dc = String(loopDir + '_' + loopSwp);\n j = dirCounts[dc] === undefined ? dirCounts[dc] = 0 : ++dirCounts[dc];\n rs.ctrlpts = [srcPos.x + Math.cos(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(outAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.x + Math.cos(inAngle) * 1.4 * loopDist * (j / 3 + 1), srcPos.y + Math.sin(inAngle) * 1.4 * loopDist * (j / 3 + 1)];\n};\nBRp$c.findCompoundLoopPoints = function (edge, pairInfo, i, edgeIsUnbundled) {\n // Compound edge\n\n var rs = edge._private.rscratch;\n rs.edgeType = 'compound';\n var srcPos = pairInfo.srcPos,\n tgtPos = pairInfo.tgtPos,\n srcW = pairInfo.srcW,\n srcH = pairInfo.srcH,\n tgtW = pairInfo.tgtW,\n tgtH = pairInfo.tgtH;\n var stepSize = edge.pstyle('control-point-step-size').pfValue;\n var ctrlptDists = edge.pstyle('control-point-distances');\n var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;\n var j = i;\n var loopDist = stepSize;\n if (edgeIsUnbundled) {\n j = 0;\n loopDist = ctrlptDist;\n }\n var loopW = 50;\n var loopaPos = {\n x: srcPos.x - srcW / 2,\n y: srcPos.y - srcH / 2\n };\n var loopbPos = {\n x: tgtPos.x - tgtW / 2,\n y: tgtPos.y - tgtH / 2\n };\n var loopPos = {\n x: Math.min(loopaPos.x, loopbPos.x),\n y: Math.min(loopaPos.y, loopbPos.y)\n };\n\n // avoids cases with impossible beziers\n var minCompoundStretch = 0.5;\n var compoundStretchA = Math.max(minCompoundStretch, Math.log(srcW * 0.01));\n var compoundStretchB = Math.max(minCompoundStretch, Math.log(tgtW * 0.01));\n rs.ctrlpts = [loopPos.x, loopPos.y - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchA, loopPos.x - (1 + Math.pow(loopW, 1.12) / 100) * loopDist * (j / 3 + 1) * compoundStretchB, loopPos.y];\n};\nBRp$c.findStraightEdgePoints = function (edge) {\n // Straight edge within bundle\n\n edge._private.rscratch.edgeType = 'straight';\n};\nBRp$c.findBezierPoints = function (edge, pairInfo, i, edgeIsUnbundled, edgeIsSwapped) {\n var rs = edge._private.rscratch;\n var stepSize = edge.pstyle('control-point-step-size').pfValue;\n var ctrlptDists = edge.pstyle('control-point-distances');\n var ctrlptWs = edge.pstyle('control-point-weights');\n var bezierN = ctrlptDists && ctrlptWs ? Math.min(ctrlptDists.value.length, ctrlptWs.value.length) : 1;\n var ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[0] : undefined;\n var ctrlptWeight = ctrlptWs.value[0];\n\n // (Multi)bezier\n\n var multi = edgeIsUnbundled;\n rs.edgeType = multi ? 'multibezier' : 'bezier';\n rs.ctrlpts = [];\n for (var b = 0; b < bezierN; b++) {\n var normctrlptDist = (0.5 - pairInfo.eles.length / 2 + i) * stepSize * (edgeIsSwapped ? -1 : 1);\n var manctrlptDist = void 0;\n var sign = signum(normctrlptDist);\n if (multi) {\n ctrlptDist = ctrlptDists ? ctrlptDists.pfValue[b] : stepSize; // fall back on step size\n ctrlptWeight = ctrlptWs.value[b];\n }\n if (edgeIsUnbundled) {\n // multi or single unbundled\n manctrlptDist = ctrlptDist;\n } else {\n manctrlptDist = ctrlptDist !== undefined ? sign * ctrlptDist : undefined;\n }\n var distanceFromMidpoint = manctrlptDist !== undefined ? manctrlptDist : normctrlptDist;\n var w1 = 1 - ctrlptWeight;\n var w2 = ctrlptWeight;\n var _this$findMidptPtsEtc2 = this.findMidptPtsEtc(edge, pairInfo),\n midptPts = _this$findMidptPtsEtc2.midptPts,\n vectorNormInverse = _this$findMidptPtsEtc2.vectorNormInverse;\n var adjustedMidpt = {\n x: midptPts.x1 * w1 + midptPts.x2 * w2,\n y: midptPts.y1 * w1 + midptPts.y2 * w2\n };\n rs.ctrlpts.push(adjustedMidpt.x + vectorNormInverse.x * distanceFromMidpoint, adjustedMidpt.y + vectorNormInverse.y * distanceFromMidpoint);\n }\n};\nBRp$c.findTaxiPoints = function (edge, pairInfo) {\n // Taxicab geometry with two turns maximum\n\n var rs = edge._private.rscratch;\n rs.edgeType = 'segments';\n var VERTICAL = 'vertical';\n var HORIZONTAL = 'horizontal';\n var LEFTWARD = 'leftward';\n var RIGHTWARD = 'rightward';\n var DOWNWARD = 'downward';\n var UPWARD = 'upward';\n var AUTO = 'auto';\n var posPts = pairInfo.posPts,\n srcW = pairInfo.srcW,\n srcH = pairInfo.srcH,\n tgtW = pairInfo.tgtW,\n tgtH = pairInfo.tgtH;\n var edgeDistances = edge.pstyle('edge-distances').value;\n var dIncludesNodeBody = edgeDistances !== 'node-position';\n var taxiDir = edge.pstyle('taxi-direction').value;\n var rawTaxiDir = taxiDir; // unprocessed value\n var taxiTurn = edge.pstyle('taxi-turn');\n var turnIsPercent = taxiTurn.units === '%';\n var taxiTurnPfVal = taxiTurn.pfValue;\n var turnIsNegative = taxiTurnPfVal < 0; // i.e. from target side\n var minD = edge.pstyle('taxi-turn-min-distance').pfValue;\n var dw = dIncludesNodeBody ? (srcW + tgtW) / 2 : 0;\n var dh = dIncludesNodeBody ? (srcH + tgtH) / 2 : 0;\n var pdx = posPts.x2 - posPts.x1;\n var pdy = posPts.y2 - posPts.y1;\n\n // take away the effective w/h from the magnitude of the delta value\n var subDWH = function subDWH(dxy, dwh) {\n if (dxy > 0) {\n return Math.max(dxy - dwh, 0);\n } else {\n return Math.min(dxy + dwh, 0);\n }\n };\n var dx = subDWH(pdx, dw);\n var dy = subDWH(pdy, dh);\n var isExplicitDir = false;\n if (rawTaxiDir === AUTO) {\n taxiDir = Math.abs(dx) > Math.abs(dy) ? HORIZONTAL : VERTICAL;\n } else if (rawTaxiDir === UPWARD || rawTaxiDir === DOWNWARD) {\n taxiDir = VERTICAL;\n isExplicitDir = true;\n } else if (rawTaxiDir === LEFTWARD || rawTaxiDir === RIGHTWARD) {\n taxiDir = HORIZONTAL;\n isExplicitDir = true;\n }\n var isVert = taxiDir === VERTICAL;\n var l = isVert ? dy : dx;\n var pl = isVert ? pdy : pdx;\n var sgnL = signum(pl);\n var forcedDir = false;\n if (!(isExplicitDir && (turnIsPercent || turnIsNegative)) // forcing in this case would cause weird growing in the opposite direction\n && (rawTaxiDir === DOWNWARD && pl < 0 || rawTaxiDir === UPWARD && pl > 0 || rawTaxiDir === LEFTWARD && pl > 0 || rawTaxiDir === RIGHTWARD && pl < 0)) {\n sgnL *= -1;\n l = sgnL * Math.abs(l);\n forcedDir = true;\n }\n var d;\n if (turnIsPercent) {\n var p = taxiTurnPfVal < 0 ? 1 + taxiTurnPfVal : taxiTurnPfVal;\n d = p * l;\n } else {\n var k = taxiTurnPfVal < 0 ? l : 0;\n d = k + taxiTurnPfVal * sgnL;\n }\n var getIsTooClose = function getIsTooClose(d) {\n return Math.abs(d) < minD || Math.abs(d) >= Math.abs(l);\n };\n var isTooCloseSrc = getIsTooClose(d);\n var isTooCloseTgt = getIsTooClose(Math.abs(l) - Math.abs(d));\n var isTooClose = isTooCloseSrc || isTooCloseTgt;\n if (isTooClose && !forcedDir) {\n // non-ideal routing\n if (isVert) {\n // vertical fallbacks\n var lShapeInsideSrc = Math.abs(pl) <= srcH / 2;\n var lShapeInsideTgt = Math.abs(pdx) <= tgtW / 2;\n if (lShapeInsideSrc) {\n // horizontal Z-shape (direction not respected)\n var x = (posPts.x1 + posPts.x2) / 2;\n var y1 = posPts.y1,\n y2 = posPts.y2;\n rs.segpts = [x, y1, x, y2];\n } else if (lShapeInsideTgt) {\n // vertical Z-shape (distance not respected)\n var y = (posPts.y1 + posPts.y2) / 2;\n var x1 = posPts.x1,\n x2 = posPts.x2;\n rs.segpts = [x1, y, x2, y];\n } else {\n // L-shape fallback (turn distance not respected, but works well with tree siblings)\n rs.segpts = [posPts.x1, posPts.y2];\n }\n } else {\n // horizontal fallbacks\n var _lShapeInsideSrc = Math.abs(pl) <= srcW / 2;\n var _lShapeInsideTgt = Math.abs(pdy) <= tgtH / 2;\n if (_lShapeInsideSrc) {\n // vertical Z-shape (direction not respected)\n var _y = (posPts.y1 + posPts.y2) / 2;\n var _x = posPts.x1,\n _x2 = posPts.x2;\n rs.segpts = [_x, _y, _x2, _y];\n } else if (_lShapeInsideTgt) {\n // horizontal Z-shape (turn distance not respected)\n var _x3 = (posPts.x1 + posPts.x2) / 2;\n var _y2 = posPts.y1,\n _y3 = posPts.y2;\n rs.segpts = [_x3, _y2, _x3, _y3];\n } else {\n // L-shape (turn distance not respected, but works well for tree siblings)\n rs.segpts = [posPts.x2, posPts.y1];\n }\n }\n } else {\n // ideal routing\n if (isVert) {\n var _y4 = posPts.y1 + d + (dIncludesNodeBody ? srcH / 2 * sgnL : 0);\n var _x4 = posPts.x1,\n _x5 = posPts.x2;\n rs.segpts = [_x4, _y4, _x5, _y4];\n } else {\n // horizontal\n var _x6 = posPts.x1 + d + (dIncludesNodeBody ? srcW / 2 * sgnL : 0);\n var _y5 = posPts.y1,\n _y6 = posPts.y2;\n rs.segpts = [_x6, _y5, _x6, _y6];\n }\n }\n if (rs.isRound) {\n var radius = edge.pstyle('taxi-radius').value;\n var isArcRadius = edge.pstyle('radius-type').value[0] === 'arc-radius';\n rs.radii = new Array(rs.segpts.length / 2).fill(radius);\n rs.isArcRadius = new Array(rs.segpts.length / 2).fill(isArcRadius);\n }\n};\nBRp$c.tryToCorrectInvalidPoints = function (edge, pairInfo) {\n var rs = edge._private.rscratch;\n\n // can only correct beziers for now...\n if (rs.edgeType === 'bezier') {\n var srcPos = pairInfo.srcPos,\n tgtPos = pairInfo.tgtPos,\n srcW = pairInfo.srcW,\n srcH = pairInfo.srcH,\n tgtW = pairInfo.tgtW,\n tgtH = pairInfo.tgtH,\n srcShape = pairInfo.srcShape,\n tgtShape = pairInfo.tgtShape,\n srcCornerRadius = pairInfo.srcCornerRadius,\n tgtCornerRadius = pairInfo.tgtCornerRadius,\n srcRs = pairInfo.srcRs,\n tgtRs = pairInfo.tgtRs;\n var badStart = !number$1(rs.startX) || !number$1(rs.startY);\n var badAStart = !number$1(rs.arrowStartX) || !number$1(rs.arrowStartY);\n var badEnd = !number$1(rs.endX) || !number$1(rs.endY);\n var badAEnd = !number$1(rs.arrowEndX) || !number$1(rs.arrowEndY);\n var minCpADistFactor = 3;\n var arrowW = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth;\n var minCpADist = minCpADistFactor * arrowW;\n var startACpDist = dist({\n x: rs.ctrlpts[0],\n y: rs.ctrlpts[1]\n }, {\n x: rs.startX,\n y: rs.startY\n });\n var closeStartACp = startACpDist < minCpADist;\n var endACpDist = dist({\n x: rs.ctrlpts[0],\n y: rs.ctrlpts[1]\n }, {\n x: rs.endX,\n y: rs.endY\n });\n var closeEndACp = endACpDist < minCpADist;\n var overlapping = false;\n if (badStart || badAStart || closeStartACp) {\n overlapping = true;\n\n // project control point along line from src centre to outside the src shape\n // (otherwise intersection will yield nothing)\n var cpD = {\n // delta\n x: rs.ctrlpts[0] - srcPos.x,\n y: rs.ctrlpts[1] - srcPos.y\n };\n var cpL = Math.sqrt(cpD.x * cpD.x + cpD.y * cpD.y); // length of line\n var cpM = {\n // normalised delta\n x: cpD.x / cpL,\n y: cpD.y / cpL\n };\n var radius = Math.max(srcW, srcH);\n var cpProj = {\n // *2 radius guarantees outside shape\n x: rs.ctrlpts[0] + cpM.x * 2 * radius,\n y: rs.ctrlpts[1] + cpM.y * 2 * radius\n };\n var srcCtrlPtIntn = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, cpProj.x, cpProj.y, 0, srcCornerRadius, srcRs);\n if (closeStartACp) {\n rs.ctrlpts[0] = rs.ctrlpts[0] + cpM.x * (minCpADist - startACpDist);\n rs.ctrlpts[1] = rs.ctrlpts[1] + cpM.y * (minCpADist - startACpDist);\n } else {\n rs.ctrlpts[0] = srcCtrlPtIntn[0] + cpM.x * minCpADist;\n rs.ctrlpts[1] = srcCtrlPtIntn[1] + cpM.y * minCpADist;\n }\n }\n if (badEnd || badAEnd || closeEndACp) {\n overlapping = true;\n\n // project control point along line from tgt centre to outside the tgt shape\n // (otherwise intersection will yield nothing)\n var _cpD = {\n // delta\n x: rs.ctrlpts[0] - tgtPos.x,\n y: rs.ctrlpts[1] - tgtPos.y\n };\n var _cpL = Math.sqrt(_cpD.x * _cpD.x + _cpD.y * _cpD.y); // length of line\n var _cpM = {\n // normalised delta\n x: _cpD.x / _cpL,\n y: _cpD.y / _cpL\n };\n var _radius = Math.max(srcW, srcH);\n var _cpProj = {\n // *2 radius guarantees outside shape\n x: rs.ctrlpts[0] + _cpM.x * 2 * _radius,\n y: rs.ctrlpts[1] + _cpM.y * 2 * _radius\n };\n var tgtCtrlPtIntn = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, _cpProj.x, _cpProj.y, 0, tgtCornerRadius, tgtRs);\n if (closeEndACp) {\n rs.ctrlpts[0] = rs.ctrlpts[0] + _cpM.x * (minCpADist - endACpDist);\n rs.ctrlpts[1] = rs.ctrlpts[1] + _cpM.y * (minCpADist - endACpDist);\n } else {\n rs.ctrlpts[0] = tgtCtrlPtIntn[0] + _cpM.x * minCpADist;\n rs.ctrlpts[1] = tgtCtrlPtIntn[1] + _cpM.y * minCpADist;\n }\n }\n if (overlapping) {\n // recalc endpts\n this.findEndpoints(edge);\n }\n }\n};\nBRp$c.storeAllpts = function (edge) {\n var rs = edge._private.rscratch;\n if (rs.edgeType === 'multibezier' || rs.edgeType === 'bezier' || rs.edgeType === 'self' || rs.edgeType === 'compound') {\n rs.allpts = [];\n rs.allpts.push(rs.startX, rs.startY);\n for (var b = 0; b + 1 < rs.ctrlpts.length; b += 2) {\n // ctrl pt itself\n rs.allpts.push(rs.ctrlpts[b], rs.ctrlpts[b + 1]);\n\n // the midpt between ctrlpts as intermediate destination pts\n if (b + 3 < rs.ctrlpts.length) {\n rs.allpts.push((rs.ctrlpts[b] + rs.ctrlpts[b + 2]) / 2, (rs.ctrlpts[b + 1] + rs.ctrlpts[b + 3]) / 2);\n }\n }\n rs.allpts.push(rs.endX, rs.endY);\n var m, mt;\n if (rs.ctrlpts.length / 2 % 2 === 0) {\n m = rs.allpts.length / 2 - 1;\n rs.midX = rs.allpts[m];\n rs.midY = rs.allpts[m + 1];\n } else {\n m = rs.allpts.length / 2 - 3;\n mt = 0.5;\n rs.midX = qbezierAt(rs.allpts[m], rs.allpts[m + 2], rs.allpts[m + 4], mt);\n rs.midY = qbezierAt(rs.allpts[m + 1], rs.allpts[m + 3], rs.allpts[m + 5], mt);\n }\n } else if (rs.edgeType === 'straight') {\n // need to calc these after endpts\n rs.allpts = [rs.startX, rs.startY, rs.endX, rs.endY];\n\n // default midpt for labels etc\n rs.midX = (rs.startX + rs.endX + rs.arrowStartX + rs.arrowEndX) / 4;\n rs.midY = (rs.startY + rs.endY + rs.arrowStartY + rs.arrowEndY) / 4;\n } else if (rs.edgeType === 'segments') {\n rs.allpts = [];\n rs.allpts.push(rs.startX, rs.startY);\n rs.allpts.push.apply(rs.allpts, rs.segpts);\n rs.allpts.push(rs.endX, rs.endY);\n if (rs.isRound) {\n rs.roundCorners = [];\n for (var i = 2; i + 3 < rs.allpts.length; i += 2) {\n var radius = rs.radii[i / 2 - 1];\n var isArcRadius = rs.isArcRadius[i / 2 - 1];\n rs.roundCorners.push(getRoundCorner({\n x: rs.allpts[i - 2],\n y: rs.allpts[i - 1]\n }, {\n x: rs.allpts[i],\n y: rs.allpts[i + 1],\n radius: radius\n }, {\n x: rs.allpts[i + 2],\n y: rs.allpts[i + 3]\n }, radius, isArcRadius));\n }\n }\n if (rs.segpts.length % 4 === 0) {\n var i2 = rs.segpts.length / 2;\n var i1 = i2 - 2;\n rs.midX = (rs.segpts[i1] + rs.segpts[i2]) / 2;\n rs.midY = (rs.segpts[i1 + 1] + rs.segpts[i2 + 1]) / 2;\n } else {\n var _i = rs.segpts.length / 2 - 1;\n if (!rs.isRound) {\n rs.midX = rs.segpts[_i];\n rs.midY = rs.segpts[_i + 1];\n } else {\n var point = {\n x: rs.segpts[_i],\n y: rs.segpts[_i + 1]\n };\n var corner = rs.roundCorners[_i / 2];\n var v = [point.x - corner.cx, point.y - corner.cy];\n var factor = corner.radius / Math.sqrt(Math.pow(v[0], 2) + Math.pow(v[1], 2));\n v = v.map(function (c) {\n return c * factor;\n });\n rs.midX = corner.cx + v[0];\n rs.midY = corner.cy + v[1];\n rs.midVector = v;\n }\n }\n }\n};\nBRp$c.checkForInvalidEdgeWarning = function (edge) {\n var rs = edge[0]._private.rscratch;\n if (rs.nodesOverlap || number$1(rs.startX) && number$1(rs.startY) && number$1(rs.endX) && number$1(rs.endY)) {\n rs.loggedErr = false;\n } else {\n if (!rs.loggedErr) {\n rs.loggedErr = true;\n warn('Edge `' + edge.id() + '` has invalid endpoints and so it is impossible to draw. Adjust your edge style (e.g. control points) accordingly or use an alternative edge type. This is expected behaviour when the source node and the target node overlap.');\n }\n }\n};\nBRp$c.findEdgeControlPoints = function (edges) {\n var _this = this;\n if (!edges || edges.length === 0) {\n return;\n }\n var r = this;\n var cy = r.cy;\n var hasCompounds = cy.hasCompoundNodes();\n var hashTable = {\n map: new Map$2(),\n get: function get(pairId) {\n var map2 = this.map.get(pairId[0]);\n if (map2 != null) {\n return map2.get(pairId[1]);\n } else {\n return null;\n }\n },\n set: function set(pairId, val) {\n var map2 = this.map.get(pairId[0]);\n if (map2 == null) {\n map2 = new Map$2();\n this.map.set(pairId[0], map2);\n }\n map2.set(pairId[1], val);\n }\n };\n var pairIds = [];\n var haystackEdges = [];\n\n // create a table of edge (src, tgt) => list of edges between them\n for (var i = 0; i < edges.length; i++) {\n var edge = edges[i];\n var _p = edge._private;\n var curveStyle = edge.pstyle('curve-style').value;\n\n // ignore edges who are not to be displayed\n // they shouldn't take up space\n if (edge.removed() || !edge.takesUpSpace()) {\n continue;\n }\n if (curveStyle === 'haystack') {\n haystackEdges.push(edge);\n continue;\n }\n var edgeIsUnbundled = curveStyle === 'unbundled-bezier' || curveStyle.endsWith('segments') || curveStyle === 'straight' || curveStyle === 'straight-triangle' || curveStyle.endsWith('taxi');\n var edgeIsBezier = curveStyle === 'unbundled-bezier' || curveStyle === 'bezier';\n var src = _p.source;\n var tgt = _p.target;\n var srcIndex = src.poolIndex();\n var tgtIndex = tgt.poolIndex();\n var pairId = [srcIndex, tgtIndex].sort();\n var tableEntry = hashTable.get(pairId);\n if (tableEntry == null) {\n tableEntry = {\n eles: []\n };\n hashTable.set(pairId, tableEntry);\n pairIds.push(pairId);\n }\n tableEntry.eles.push(edge);\n if (edgeIsUnbundled) {\n tableEntry.hasUnbundled = true;\n }\n if (edgeIsBezier) {\n tableEntry.hasBezier = true;\n }\n }\n\n // for each pair (src, tgt), create the ctrl pts\n // Nested for loop is OK; total number of iterations for both loops = edgeCount\n var _loop = function _loop(p) {\n var pairId = pairIds[p];\n var pairInfo = hashTable.get(pairId);\n var swappedpairInfo = void 0;\n if (!pairInfo.hasUnbundled) {\n var pllEdges = pairInfo.eles[0].parallelEdges().filter(function (e) {\n return e.isBundledBezier();\n });\n clearArray(pairInfo.eles);\n pllEdges.forEach(function (edge) {\n return pairInfo.eles.push(edge);\n });\n\n // for each pair id, the edges should be sorted by index\n pairInfo.eles.sort(function (edge1, edge2) {\n return edge1.poolIndex() - edge2.poolIndex();\n });\n }\n var firstEdge = pairInfo.eles[0];\n var src = firstEdge.source();\n var tgt = firstEdge.target();\n\n // make sure src/tgt distinction is consistent w.r.t. pairId\n if (src.poolIndex() > tgt.poolIndex()) {\n var temp = src;\n src = tgt;\n tgt = temp;\n }\n var srcPos = pairInfo.srcPos = src.position();\n var tgtPos = pairInfo.tgtPos = tgt.position();\n var srcW = pairInfo.srcW = src.outerWidth();\n var srcH = pairInfo.srcH = src.outerHeight();\n var tgtW = pairInfo.tgtW = tgt.outerWidth();\n var tgtH = pairInfo.tgtH = tgt.outerHeight();\n var srcShape = pairInfo.srcShape = r.nodeShapes[_this.getNodeShape(src)];\n var tgtShape = pairInfo.tgtShape = r.nodeShapes[_this.getNodeShape(tgt)];\n var srcCornerRadius = pairInfo.srcCornerRadius = src.pstyle('corner-radius').value === 'auto' ? 'auto' : src.pstyle('corner-radius').pfValue;\n var tgtCornerRadius = pairInfo.tgtCornerRadius = tgt.pstyle('corner-radius').value === 'auto' ? 'auto' : tgt.pstyle('corner-radius').pfValue;\n var tgtRs = pairInfo.tgtRs = tgt._private.rscratch;\n var srcRs = pairInfo.srcRs = src._private.rscratch;\n pairInfo.dirCounts = {\n 'north': 0,\n 'west': 0,\n 'south': 0,\n 'east': 0,\n 'northwest': 0,\n 'southwest': 0,\n 'northeast': 0,\n 'southeast': 0\n };\n for (var _i2 = 0; _i2 < pairInfo.eles.length; _i2++) {\n var _edge = pairInfo.eles[_i2];\n var rs = _edge[0]._private.rscratch;\n var _curveStyle = _edge.pstyle('curve-style').value;\n var _edgeIsUnbundled = _curveStyle === 'unbundled-bezier' || _curveStyle.endsWith('segments') || _curveStyle.endsWith('taxi');\n\n // whether the normalised pair order is the reverse of the edge's src-tgt order\n var edgeIsSwapped = !src.same(_edge.source());\n if (!pairInfo.calculatedIntersection && src !== tgt && (pairInfo.hasBezier || pairInfo.hasUnbundled)) {\n pairInfo.calculatedIntersection = true;\n\n // pt outside src shape to calc distance/displacement from src to tgt\n var srcOutside = srcShape.intersectLine(srcPos.x, srcPos.y, srcW, srcH, tgtPos.x, tgtPos.y, 0, srcCornerRadius, srcRs);\n var srcIntn = pairInfo.srcIntn = srcOutside;\n\n // pt outside tgt shape to calc distance/displacement from src to tgt\n var tgtOutside = tgtShape.intersectLine(tgtPos.x, tgtPos.y, tgtW, tgtH, srcPos.x, srcPos.y, 0, tgtCornerRadius, tgtRs);\n var tgtIntn = pairInfo.tgtIntn = tgtOutside;\n var intersectionPts = pairInfo.intersectionPts = {\n x1: srcOutside[0],\n x2: tgtOutside[0],\n y1: srcOutside[1],\n y2: tgtOutside[1]\n };\n var posPts = pairInfo.posPts = {\n x1: srcPos.x,\n x2: tgtPos.x,\n y1: srcPos.y,\n y2: tgtPos.y\n };\n var dy = tgtOutside[1] - srcOutside[1];\n var dx = tgtOutside[0] - srcOutside[0];\n var l = Math.sqrt(dx * dx + dy * dy);\n var vector = pairInfo.vector = {\n x: dx,\n y: dy\n };\n var vectorNorm = pairInfo.vectorNorm = {\n x: vector.x / l,\n y: vector.y / l\n };\n var vectorNormInverse = {\n x: -vectorNorm.y,\n y: vectorNorm.x\n };\n\n // if node shapes overlap, then no ctrl pts to draw\n pairInfo.nodesOverlap = !number$1(l) || tgtShape.checkPoint(srcOutside[0], srcOutside[1], 0, tgtW, tgtH, tgtPos.x, tgtPos.y, tgtCornerRadius, tgtRs) || srcShape.checkPoint(tgtOutside[0], tgtOutside[1], 0, srcW, srcH, srcPos.x, srcPos.y, srcCornerRadius, srcRs);\n pairInfo.vectorNormInverse = vectorNormInverse;\n swappedpairInfo = {\n nodesOverlap: pairInfo.nodesOverlap,\n dirCounts: pairInfo.dirCounts,\n calculatedIntersection: true,\n hasBezier: pairInfo.hasBezier,\n hasUnbundled: pairInfo.hasUnbundled,\n eles: pairInfo.eles,\n srcPos: tgtPos,\n tgtPos: srcPos,\n srcW: tgtW,\n srcH: tgtH,\n tgtW: srcW,\n tgtH: srcH,\n srcIntn: tgtIntn,\n tgtIntn: srcIntn,\n srcShape: tgtShape,\n tgtShape: srcShape,\n posPts: {\n x1: posPts.x2,\n y1: posPts.y2,\n x2: posPts.x1,\n y2: posPts.y1\n },\n intersectionPts: {\n x1: intersectionPts.x2,\n y1: intersectionPts.y2,\n x2: intersectionPts.x1,\n y2: intersectionPts.y1\n },\n vector: {\n x: -vector.x,\n y: -vector.y\n },\n vectorNorm: {\n x: -vectorNorm.x,\n y: -vectorNorm.y\n },\n vectorNormInverse: {\n x: -vectorNormInverse.x,\n y: -vectorNormInverse.y\n }\n };\n }\n var passedPairInfo = edgeIsSwapped ? swappedpairInfo : pairInfo;\n rs.nodesOverlap = passedPairInfo.nodesOverlap;\n rs.srcIntn = passedPairInfo.srcIntn;\n rs.tgtIntn = passedPairInfo.tgtIntn;\n rs.isRound = _curveStyle.startsWith('round');\n if (hasCompounds && (src.isParent() || src.isChild() || tgt.isParent() || tgt.isChild()) && (src.parents().anySame(tgt) || tgt.parents().anySame(src) || src.same(tgt) && src.isParent())) {\n _this.findCompoundLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled);\n } else if (src === tgt) {\n _this.findLoopPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled);\n } else if (_curveStyle.endsWith('segments')) {\n _this.findSegmentsPoints(_edge, passedPairInfo);\n } else if (_curveStyle.endsWith('taxi')) {\n _this.findTaxiPoints(_edge, passedPairInfo);\n } else if (_curveStyle === 'straight' || !_edgeIsUnbundled && pairInfo.eles.length % 2 === 1 && _i2 === Math.floor(pairInfo.eles.length / 2)) {\n _this.findStraightEdgePoints(_edge);\n } else {\n _this.findBezierPoints(_edge, passedPairInfo, _i2, _edgeIsUnbundled, edgeIsSwapped);\n }\n _this.findEndpoints(_edge);\n _this.tryToCorrectInvalidPoints(_edge, passedPairInfo);\n _this.checkForInvalidEdgeWarning(_edge);\n _this.storeAllpts(_edge);\n _this.storeEdgeProjections(_edge);\n _this.calculateArrowAngles(_edge);\n _this.recalculateEdgeLabelProjections(_edge);\n _this.calculateLabelAngles(_edge);\n } // for pair edges\n };\n for (var p = 0; p < pairIds.length; p++) {\n _loop(p);\n } // for pair ids\n\n // haystacks avoid the expense of pairInfo stuff (intersections etc.)\n this.findHaystackPoints(haystackEdges);\n};\nfunction getPts(pts) {\n var retPts = [];\n if (pts == null) {\n return;\n }\n for (var i = 0; i < pts.length; i += 2) {\n var x = pts[i];\n var y = pts[i + 1];\n retPts.push({\n x: x,\n y: y\n });\n }\n return retPts;\n}\nBRp$c.getSegmentPoints = function (edge) {\n var rs = edge[0]._private.rscratch;\n var type = rs.edgeType;\n if (type === 'segments') {\n this.recalculateRenderedStyle(edge);\n return getPts(rs.segpts);\n }\n};\nBRp$c.getControlPoints = function (edge) {\n var rs = edge[0]._private.rscratch;\n var type = rs.edgeType;\n if (type === 'bezier' || type === 'multibezier' || type === 'self' || type === 'compound') {\n this.recalculateRenderedStyle(edge);\n return getPts(rs.ctrlpts);\n }\n};\nBRp$c.getEdgeMidpoint = function (edge) {\n var rs = edge[0]._private.rscratch;\n this.recalculateRenderedStyle(edge);\n return {\n x: rs.midX,\n y: rs.midY\n };\n};\n\nvar BRp$b = {};\nBRp$b.manualEndptToPx = function (node, prop) {\n var r = this;\n var npos = node.position();\n var w = node.outerWidth();\n var h = node.outerHeight();\n var rs = node._private.rscratch;\n if (prop.value.length === 2) {\n var p = [prop.pfValue[0], prop.pfValue[1]];\n if (prop.units[0] === '%') {\n p[0] = p[0] * w;\n }\n if (prop.units[1] === '%') {\n p[1] = p[1] * h;\n }\n p[0] += npos.x;\n p[1] += npos.y;\n return p;\n } else {\n var angle = prop.pfValue[0];\n angle = -Math.PI / 2 + angle; // start at 12 o'clock\n\n var l = 2 * Math.max(w, h);\n var _p = [npos.x + Math.cos(angle) * l, npos.y + Math.sin(angle) * l];\n return r.nodeShapes[this.getNodeShape(node)].intersectLine(npos.x, npos.y, w, h, _p[0], _p[1], 0, node.pstyle('corner-radius').value === 'auto' ? 'auto' : node.pstyle('corner-radius').pfValue, rs);\n }\n};\nBRp$b.findEndpoints = function (edge) {\n var r = this;\n var intersect;\n var source = edge.source()[0];\n var target = edge.target()[0];\n var srcPos = source.position();\n var tgtPos = target.position();\n var tgtArShape = edge.pstyle('target-arrow-shape').value;\n var srcArShape = edge.pstyle('source-arrow-shape').value;\n var tgtDist = edge.pstyle('target-distance-from-node').pfValue;\n var srcDist = edge.pstyle('source-distance-from-node').pfValue;\n var srcRs = source._private.rscratch;\n var tgtRs = target._private.rscratch;\n var curveStyle = edge.pstyle('curve-style').value;\n var rs = edge._private.rscratch;\n var et = rs.edgeType;\n var taxi = curveStyle === 'taxi';\n var self = et === 'self' || et === 'compound';\n var bezier = et === 'bezier' || et === 'multibezier' || self;\n var multi = et !== 'bezier';\n var lines = et === 'straight' || et === 'segments';\n var segments = et === 'segments';\n var hasEndpts = bezier || multi || lines;\n var overrideEndpts = self || taxi;\n var srcManEndpt = edge.pstyle('source-endpoint');\n var srcManEndptVal = overrideEndpts ? 'outside-to-node' : srcManEndpt.value;\n var srcCornerRadius = source.pstyle('corner-radius').value === 'auto' ? 'auto' : source.pstyle('corner-radius').pfValue;\n var tgtManEndpt = edge.pstyle('target-endpoint');\n var tgtManEndptVal = overrideEndpts ? 'outside-to-node' : tgtManEndpt.value;\n var tgtCornerRadius = target.pstyle('corner-radius').value === 'auto' ? 'auto' : target.pstyle('corner-radius').pfValue;\n rs.srcManEndpt = srcManEndpt;\n rs.tgtManEndpt = tgtManEndpt;\n var p1; // last known point of edge on target side\n var p2; // last known point of edge on source side\n\n var p1_i; // point to intersect with target shape\n var p2_i; // point to intersect with source shape\n\n if (bezier) {\n var cpStart = [rs.ctrlpts[0], rs.ctrlpts[1]];\n var cpEnd = multi ? [rs.ctrlpts[rs.ctrlpts.length - 2], rs.ctrlpts[rs.ctrlpts.length - 1]] : cpStart;\n p1 = cpEnd;\n p2 = cpStart;\n } else if (lines) {\n var srcArrowFromPt = !segments ? [tgtPos.x, tgtPos.y] : rs.segpts.slice(0, 2);\n var tgtArrowFromPt = !segments ? [srcPos.x, srcPos.y] : rs.segpts.slice(rs.segpts.length - 2);\n p1 = tgtArrowFromPt;\n p2 = srcArrowFromPt;\n }\n if (tgtManEndptVal === 'inside-to-node') {\n intersect = [tgtPos.x, tgtPos.y];\n } else if (tgtManEndpt.units) {\n intersect = this.manualEndptToPx(target, tgtManEndpt);\n } else if (tgtManEndptVal === 'outside-to-line') {\n intersect = rs.tgtIntn; // use cached value from ctrlpt calc\n } else {\n if (tgtManEndptVal === 'outside-to-node' || tgtManEndptVal === 'outside-to-node-or-label') {\n p1_i = p1;\n } else if (tgtManEndptVal === 'outside-to-line' || tgtManEndptVal === 'outside-to-line-or-label') {\n p1_i = [srcPos.x, srcPos.y];\n }\n intersect = r.nodeShapes[this.getNodeShape(target)].intersectLine(tgtPos.x, tgtPos.y, target.outerWidth(), target.outerHeight(), p1_i[0], p1_i[1], 0, tgtCornerRadius, tgtRs);\n if (tgtManEndptVal === 'outside-to-node-or-label' || tgtManEndptVal === 'outside-to-line-or-label') {\n var trs = target._private.rscratch;\n var lw = trs.labelWidth;\n var lh = trs.labelHeight;\n var lx = trs.labelX;\n var ly = trs.labelY;\n var lw2 = lw / 2;\n var lh2 = lh / 2;\n var va = target.pstyle('text-valign').value;\n if (va === 'top') {\n ly -= lh2;\n } else if (va === 'bottom') {\n ly += lh2;\n }\n var ha = target.pstyle('text-halign').value;\n if (ha === 'left') {\n lx -= lw2;\n } else if (ha === 'right') {\n lx += lw2;\n }\n var labelIntersect = polygonIntersectLine(p1_i[0], p1_i[1], [lx - lw2, ly - lh2, lx + lw2, ly - lh2, lx + lw2, ly + lh2, lx - lw2, ly + lh2], tgtPos.x, tgtPos.y);\n if (labelIntersect.length > 0) {\n var refPt = srcPos;\n var intSqdist = sqdist(refPt, array2point(intersect));\n var labIntSqdist = sqdist(refPt, array2point(labelIntersect));\n var minSqDist = intSqdist;\n if (labIntSqdist < intSqdist) {\n intersect = labelIntersect;\n minSqDist = labIntSqdist;\n }\n if (labelIntersect.length > 2) {\n var labInt2SqDist = sqdist(refPt, {\n x: labelIntersect[2],\n y: labelIntersect[3]\n });\n if (labInt2SqDist < minSqDist) {\n intersect = [labelIntersect[2], labelIntersect[3]];\n }\n }\n }\n }\n }\n var arrowEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].spacing(edge) + tgtDist);\n var edgeEnd = shortenIntersection(intersect, p1, r.arrowShapes[tgtArShape].gap(edge) + tgtDist);\n rs.endX = edgeEnd[0];\n rs.endY = edgeEnd[1];\n rs.arrowEndX = arrowEnd[0];\n rs.arrowEndY = arrowEnd[1];\n if (srcManEndptVal === 'inside-to-node') {\n intersect = [srcPos.x, srcPos.y];\n } else if (srcManEndpt.units) {\n intersect = this.manualEndptToPx(source, srcManEndpt);\n } else if (srcManEndptVal === 'outside-to-line') {\n intersect = rs.srcIntn; // use cached value from ctrlpt calc\n } else {\n if (srcManEndptVal === 'outside-to-node' || srcManEndptVal === 'outside-to-node-or-label') {\n p2_i = p2;\n } else if (srcManEndptVal === 'outside-to-line' || srcManEndptVal === 'outside-to-line-or-label') {\n p2_i = [tgtPos.x, tgtPos.y];\n }\n intersect = r.nodeShapes[this.getNodeShape(source)].intersectLine(srcPos.x, srcPos.y, source.outerWidth(), source.outerHeight(), p2_i[0], p2_i[1], 0, srcCornerRadius, srcRs);\n if (srcManEndptVal === 'outside-to-node-or-label' || srcManEndptVal === 'outside-to-line-or-label') {\n var srs = source._private.rscratch;\n var _lw = srs.labelWidth;\n var _lh = srs.labelHeight;\n var _lx = srs.labelX;\n var _ly = srs.labelY;\n var _lw2 = _lw / 2;\n var _lh2 = _lh / 2;\n var _va = source.pstyle('text-valign').value;\n if (_va === 'top') {\n _ly -= _lh2;\n } else if (_va === 'bottom') {\n _ly += _lh2;\n }\n var _ha = source.pstyle('text-halign').value;\n if (_ha === 'left') {\n _lx -= _lw2;\n } else if (_ha === 'right') {\n _lx += _lw2;\n }\n var _labelIntersect = polygonIntersectLine(p2_i[0], p2_i[1], [_lx - _lw2, _ly - _lh2, _lx + _lw2, _ly - _lh2, _lx + _lw2, _ly + _lh2, _lx - _lw2, _ly + _lh2], srcPos.x, srcPos.y);\n if (_labelIntersect.length > 0) {\n var _refPt = tgtPos;\n var _intSqdist = sqdist(_refPt, array2point(intersect));\n var _labIntSqdist = sqdist(_refPt, array2point(_labelIntersect));\n var _minSqDist = _intSqdist;\n if (_labIntSqdist < _intSqdist) {\n intersect = [_labelIntersect[0], _labelIntersect[1]];\n _minSqDist = _labIntSqdist;\n }\n if (_labelIntersect.length > 2) {\n var _labInt2SqDist = sqdist(_refPt, {\n x: _labelIntersect[2],\n y: _labelIntersect[3]\n });\n if (_labInt2SqDist < _minSqDist) {\n intersect = [_labelIntersect[2], _labelIntersect[3]];\n }\n }\n }\n }\n }\n var arrowStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].spacing(edge) + srcDist);\n var edgeStart = shortenIntersection(intersect, p2, r.arrowShapes[srcArShape].gap(edge) + srcDist);\n rs.startX = edgeStart[0];\n rs.startY = edgeStart[1];\n rs.arrowStartX = arrowStart[0];\n rs.arrowStartY = arrowStart[1];\n if (hasEndpts) {\n if (!number$1(rs.startX) || !number$1(rs.startY) || !number$1(rs.endX) || !number$1(rs.endY)) {\n rs.badLine = true;\n } else {\n rs.badLine = false;\n }\n }\n};\nBRp$b.getSourceEndpoint = function (edge) {\n var rs = edge[0]._private.rscratch;\n this.recalculateRenderedStyle(edge);\n switch (rs.edgeType) {\n case 'haystack':\n return {\n x: rs.haystackPts[0],\n y: rs.haystackPts[1]\n };\n default:\n return {\n x: rs.arrowStartX,\n y: rs.arrowStartY\n };\n }\n};\nBRp$b.getTargetEndpoint = function (edge) {\n var rs = edge[0]._private.rscratch;\n this.recalculateRenderedStyle(edge);\n switch (rs.edgeType) {\n case 'haystack':\n return {\n x: rs.haystackPts[2],\n y: rs.haystackPts[3]\n };\n default:\n return {\n x: rs.arrowEndX,\n y: rs.arrowEndY\n };\n }\n};\n\nvar BRp$a = {};\nfunction pushBezierPts(r, edge, pts) {\n var qbezierAt$1 = function qbezierAt$1(p1, p2, p3, t) {\n return qbezierAt(p1, p2, p3, t);\n };\n var _p = edge._private;\n var bpts = _p.rstyle.bezierPts;\n for (var i = 0; i < r.bezierProjPcts.length; i++) {\n var p = r.bezierProjPcts[i];\n bpts.push({\n x: qbezierAt$1(pts[0], pts[2], pts[4], p),\n y: qbezierAt$1(pts[1], pts[3], pts[5], p)\n });\n }\n}\nBRp$a.storeEdgeProjections = function (edge) {\n var _p = edge._private;\n var rs = _p.rscratch;\n var et = rs.edgeType;\n\n // clear the cached points state\n _p.rstyle.bezierPts = null;\n _p.rstyle.linePts = null;\n _p.rstyle.haystackPts = null;\n if (et === 'multibezier' || et === 'bezier' || et === 'self' || et === 'compound') {\n _p.rstyle.bezierPts = [];\n for (var i = 0; i + 5 < rs.allpts.length; i += 4) {\n pushBezierPts(this, edge, rs.allpts.slice(i, i + 6));\n }\n } else if (et === 'segments') {\n var lpts = _p.rstyle.linePts = [];\n for (var i = 0; i + 1 < rs.allpts.length; i += 2) {\n lpts.push({\n x: rs.allpts[i],\n y: rs.allpts[i + 1]\n });\n }\n } else if (et === 'haystack') {\n var hpts = rs.haystackPts;\n _p.rstyle.haystackPts = [{\n x: hpts[0],\n y: hpts[1]\n }, {\n x: hpts[2],\n y: hpts[3]\n }];\n }\n _p.rstyle.arrowWidth = this.getArrowWidth(edge.pstyle('width').pfValue, edge.pstyle('arrow-scale').value) * this.arrowShapeWidth;\n};\nBRp$a.recalculateEdgeProjections = function (edges) {\n this.findEdgeControlPoints(edges);\n};\n\nvar BRp$9 = {};\nBRp$9.recalculateNodeLabelProjection = function (node) {\n var content = node.pstyle('label').strValue;\n if (emptyString(content)) {\n return;\n }\n var textX, textY;\n var _p = node._private;\n var nodeWidth = node.width();\n var nodeHeight = node.height();\n var padding = node.padding();\n var nodePos = node.position();\n var textHalign = node.pstyle('text-halign').strValue;\n var textValign = node.pstyle('text-valign').strValue;\n var rs = _p.rscratch;\n var rstyle = _p.rstyle;\n switch (textHalign) {\n case 'left':\n textX = nodePos.x - nodeWidth / 2 - padding;\n break;\n case 'right':\n textX = nodePos.x + nodeWidth / 2 + padding;\n break;\n default:\n // e.g. center\n textX = nodePos.x;\n }\n switch (textValign) {\n case 'top':\n textY = nodePos.y - nodeHeight / 2 - padding;\n break;\n case 'bottom':\n textY = nodePos.y + nodeHeight / 2 + padding;\n break;\n default:\n // e.g. middle\n textY = nodePos.y;\n }\n rs.labelX = textX;\n rs.labelY = textY;\n rstyle.labelX = textX;\n rstyle.labelY = textY;\n this.calculateLabelAngles(node);\n this.applyLabelDimensions(node);\n};\nvar lineAngleFromDelta = function lineAngleFromDelta(dx, dy) {\n var angle = Math.atan(dy / dx);\n if (dx === 0 && angle < 0) {\n angle = angle * -1;\n }\n return angle;\n};\nvar lineAngle = function lineAngle(p0, p1) {\n var dx = p1.x - p0.x;\n var dy = p1.y - p0.y;\n return lineAngleFromDelta(dx, dy);\n};\nvar bezierAngle = function bezierAngle(p0, p1, p2, t) {\n var t0 = bound(0, t - 0.001, 1);\n var t1 = bound(0, t + 0.001, 1);\n var lp0 = qbezierPtAt(p0, p1, p2, t0);\n var lp1 = qbezierPtAt(p0, p1, p2, t1);\n return lineAngle(lp0, lp1);\n};\nBRp$9.recalculateEdgeLabelProjections = function (edge) {\n var p;\n var _p = edge._private;\n var rs = _p.rscratch;\n var r = this;\n var content = {\n mid: edge.pstyle('label').strValue,\n source: edge.pstyle('source-label').strValue,\n target: edge.pstyle('target-label').strValue\n };\n if (content.mid || content.source || content.target) ; else {\n return; // no labels => no calcs\n }\n\n // add center point to style so bounding box calculations can use it\n //\n p = {\n x: rs.midX,\n y: rs.midY\n };\n var setRs = function setRs(propName, prefix, value) {\n setPrefixedProperty(_p.rscratch, propName, prefix, value);\n setPrefixedProperty(_p.rstyle, propName, prefix, value);\n };\n setRs('labelX', null, p.x);\n setRs('labelY', null, p.y);\n var midAngle = lineAngleFromDelta(rs.midDispX, rs.midDispY);\n setRs('labelAutoAngle', null, midAngle);\n var createControlPointInfo = function createControlPointInfo() {\n if (createControlPointInfo.cache) {\n return createControlPointInfo.cache;\n } // use cache so only 1x per edge\n\n var ctrlpts = [];\n\n // store each ctrlpt info init\n for (var i = 0; i + 5 < rs.allpts.length; i += 4) {\n var p0 = {\n x: rs.allpts[i],\n y: rs.allpts[i + 1]\n };\n var p1 = {\n x: rs.allpts[i + 2],\n y: rs.allpts[i + 3]\n }; // ctrlpt\n var p2 = {\n x: rs.allpts[i + 4],\n y: rs.allpts[i + 5]\n };\n ctrlpts.push({\n p0: p0,\n p1: p1,\n p2: p2,\n startDist: 0,\n length: 0,\n segments: []\n });\n }\n var bpts = _p.rstyle.bezierPts;\n var nProjs = r.bezierProjPcts.length;\n function addSegment(cp, p0, p1, t0, t1) {\n var length = dist(p0, p1);\n var prevSegment = cp.segments[cp.segments.length - 1];\n var segment = {\n p0: p0,\n p1: p1,\n t0: t0,\n t1: t1,\n startDist: prevSegment ? prevSegment.startDist + prevSegment.length : 0,\n length: length\n };\n cp.segments.push(segment);\n cp.length += length;\n }\n\n // update each ctrlpt with segment info\n for (var _i = 0; _i < ctrlpts.length; _i++) {\n var cp = ctrlpts[_i];\n var prevCp = ctrlpts[_i - 1];\n if (prevCp) {\n cp.startDist = prevCp.startDist + prevCp.length;\n }\n addSegment(cp, cp.p0, bpts[_i * nProjs], 0, r.bezierProjPcts[0]); // first\n\n for (var j = 0; j < nProjs - 1; j++) {\n addSegment(cp, bpts[_i * nProjs + j], bpts[_i * nProjs + j + 1], r.bezierProjPcts[j], r.bezierProjPcts[j + 1]);\n }\n addSegment(cp, bpts[_i * nProjs + nProjs - 1], cp.p2, r.bezierProjPcts[nProjs - 1], 1); // last\n }\n\n return createControlPointInfo.cache = ctrlpts;\n };\n var calculateEndProjection = function calculateEndProjection(prefix) {\n var angle;\n var isSrc = prefix === 'source';\n if (!content[prefix]) {\n return;\n }\n var offset = edge.pstyle(prefix + '-text-offset').pfValue;\n switch (rs.edgeType) {\n case 'self':\n case 'compound':\n case 'bezier':\n case 'multibezier':\n {\n var cps = createControlPointInfo();\n var selected;\n var startDist = 0;\n var totalDist = 0;\n\n // find the segment we're on\n for (var i = 0; i < cps.length; i++) {\n var _cp = cps[isSrc ? i : cps.length - 1 - i];\n for (var j = 0; j < _cp.segments.length; j++) {\n var _seg = _cp.segments[isSrc ? j : _cp.segments.length - 1 - j];\n var lastSeg = i === cps.length - 1 && j === _cp.segments.length - 1;\n startDist = totalDist;\n totalDist += _seg.length;\n if (totalDist >= offset || lastSeg) {\n selected = {\n cp: _cp,\n segment: _seg\n };\n break;\n }\n }\n if (selected) {\n break;\n }\n }\n var cp = selected.cp;\n var seg = selected.segment;\n var tSegment = (offset - startDist) / seg.length;\n var segDt = seg.t1 - seg.t0;\n var t = isSrc ? seg.t0 + segDt * tSegment : seg.t1 - segDt * tSegment;\n t = bound(0, t, 1);\n p = qbezierPtAt(cp.p0, cp.p1, cp.p2, t);\n angle = bezierAngle(cp.p0, cp.p1, cp.p2, t);\n break;\n }\n case 'straight':\n case 'segments':\n case 'haystack':\n {\n var d = 0,\n di,\n d0;\n var p0, p1;\n var l = rs.allpts.length;\n for (var _i2 = 0; _i2 + 3 < l; _i2 += 2) {\n if (isSrc) {\n p0 = {\n x: rs.allpts[_i2],\n y: rs.allpts[_i2 + 1]\n };\n p1 = {\n x: rs.allpts[_i2 + 2],\n y: rs.allpts[_i2 + 3]\n };\n } else {\n p0 = {\n x: rs.allpts[l - 2 - _i2],\n y: rs.allpts[l - 1 - _i2]\n };\n p1 = {\n x: rs.allpts[l - 4 - _i2],\n y: rs.allpts[l - 3 - _i2]\n };\n }\n di = dist(p0, p1);\n d0 = d;\n d += di;\n if (d >= offset) {\n break;\n }\n }\n var pD = offset - d0;\n var _t = pD / di;\n _t = bound(0, _t, 1);\n p = lineAt(p0, p1, _t);\n angle = lineAngle(p0, p1);\n break;\n }\n }\n setRs('labelX', prefix, p.x);\n setRs('labelY', prefix, p.y);\n setRs('labelAutoAngle', prefix, angle);\n };\n calculateEndProjection('source');\n calculateEndProjection('target');\n this.applyLabelDimensions(edge);\n};\nBRp$9.applyLabelDimensions = function (ele) {\n this.applyPrefixedLabelDimensions(ele);\n if (ele.isEdge()) {\n this.applyPrefixedLabelDimensions(ele, 'source');\n this.applyPrefixedLabelDimensions(ele, 'target');\n }\n};\nBRp$9.applyPrefixedLabelDimensions = function (ele, prefix) {\n var _p = ele._private;\n var text = this.getLabelText(ele, prefix);\n var labelDims = this.calculateLabelDimensions(ele, text);\n var lineHeight = ele.pstyle('line-height').pfValue;\n var textWrap = ele.pstyle('text-wrap').strValue;\n var lines = getPrefixedProperty(_p.rscratch, 'labelWrapCachedLines', prefix) || [];\n var numLines = textWrap !== 'wrap' ? 1 : Math.max(lines.length, 1);\n var normPerLineHeight = labelDims.height / numLines;\n var labelLineHeight = normPerLineHeight * lineHeight;\n var width = labelDims.width;\n var height = labelDims.height + (numLines - 1) * (lineHeight - 1) * normPerLineHeight;\n setPrefixedProperty(_p.rstyle, 'labelWidth', prefix, width);\n setPrefixedProperty(_p.rscratch, 'labelWidth', prefix, width);\n setPrefixedProperty(_p.rstyle, 'labelHeight', prefix, height);\n setPrefixedProperty(_p.rscratch, 'labelHeight', prefix, height);\n setPrefixedProperty(_p.rscratch, 'labelLineHeight', prefix, labelLineHeight);\n};\nBRp$9.getLabelText = function (ele, prefix) {\n var _p = ele._private;\n var pfd = prefix ? prefix + '-' : '';\n var text = ele.pstyle(pfd + 'label').strValue;\n var textTransform = ele.pstyle('text-transform').value;\n var rscratch = function rscratch(propName, value) {\n if (value) {\n setPrefixedProperty(_p.rscratch, propName, prefix, value);\n return value;\n } else {\n return getPrefixedProperty(_p.rscratch, propName, prefix);\n }\n };\n\n // for empty text, skip all processing\n if (!text) {\n return '';\n }\n if (textTransform == 'none') ; else if (textTransform == 'uppercase') {\n text = text.toUpperCase();\n } else if (textTransform == 'lowercase') {\n text = text.toLowerCase();\n }\n var wrapStyle = ele.pstyle('text-wrap').value;\n if (wrapStyle === 'wrap') {\n var labelKey = rscratch('labelKey');\n\n // save recalc if the label is the same as before\n if (labelKey != null && rscratch('labelWrapKey') === labelKey) {\n return rscratch('labelWrapCachedText');\n }\n var zwsp = \"\\u200B\";\n var lines = text.split('\\n');\n var maxW = ele.pstyle('text-max-width').pfValue;\n var overflow = ele.pstyle('text-overflow-wrap').value;\n var overflowAny = overflow === 'anywhere';\n var wrappedLines = [];\n var separatorRegex = /[\\s\\u200b]+|$/g; // Include end of string to add last word\n\n for (var l = 0; l < lines.length; l++) {\n var line = lines[l];\n var lineDims = this.calculateLabelDimensions(ele, line);\n var lineW = lineDims.width;\n if (overflowAny) {\n var processedLine = line.split('').join(zwsp);\n line = processedLine;\n }\n if (lineW > maxW) {\n // line is too long\n var separatorMatches = line.matchAll(separatorRegex);\n var subline = '';\n var previousIndex = 0;\n // Add fake match\n var _iterator = _createForOfIteratorHelper(separatorMatches),\n _step;\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var separatorMatch = _step.value;\n var wordSeparator = separatorMatch[0];\n var word = line.substring(previousIndex, separatorMatch.index);\n previousIndex = separatorMatch.index + wordSeparator.length;\n var testLine = subline.length === 0 ? word : subline + word + wordSeparator;\n var testDims = this.calculateLabelDimensions(ele, testLine);\n var testW = testDims.width;\n if (testW <= maxW) {\n // word fits on current line\n subline += word + wordSeparator;\n } else {\n // word starts new line\n if (subline) {\n wrappedLines.push(subline);\n }\n subline = word + wordSeparator;\n }\n }\n\n // if there's remaining text, put it in a wrapped line\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n if (!subline.match(/^[\\s\\u200b]+$/)) {\n wrappedLines.push(subline);\n }\n } else {\n // line is already short enough\n wrappedLines.push(line);\n }\n } // for\n\n rscratch('labelWrapCachedLines', wrappedLines);\n text = rscratch('labelWrapCachedText', wrappedLines.join('\\n'));\n rscratch('labelWrapKey', labelKey);\n } else if (wrapStyle === 'ellipsis') {\n var _maxW = ele.pstyle('text-max-width').pfValue;\n var ellipsized = '';\n var ellipsis = \"\\u2026\";\n var incLastCh = false;\n if (this.calculateLabelDimensions(ele, text).width < _maxW) {\n // the label already fits\n return text;\n }\n for (var i = 0; i < text.length; i++) {\n var widthWithNextCh = this.calculateLabelDimensions(ele, ellipsized + text[i] + ellipsis).width;\n if (widthWithNextCh > _maxW) {\n break;\n }\n ellipsized += text[i];\n if (i === text.length - 1) {\n incLastCh = true;\n }\n }\n if (!incLastCh) {\n ellipsized += ellipsis;\n }\n return ellipsized;\n } // if ellipsize\n\n return text;\n};\nBRp$9.getLabelJustification = function (ele) {\n var justification = ele.pstyle('text-justification').strValue;\n var textHalign = ele.pstyle('text-halign').strValue;\n if (justification === 'auto') {\n if (ele.isNode()) {\n switch (textHalign) {\n case 'left':\n return 'right';\n case 'right':\n return 'left';\n default:\n return 'center';\n }\n } else {\n return 'center';\n }\n } else {\n return justification;\n }\n};\nBRp$9.calculateLabelDimensions = function (ele, text) {\n var r = this;\n var containerWindow = r.cy.window();\n var document = containerWindow.document;\n var cacheKey = hashString(text, ele._private.labelDimsKey);\n var cache = r.labelDimCache || (r.labelDimCache = []);\n var existingVal = cache[cacheKey];\n if (existingVal != null) {\n return existingVal;\n }\n var padding = 0; // add padding around text dims, as the measurement isn't that accurate\n var fStyle = ele.pstyle('font-style').strValue;\n var size = ele.pstyle('font-size').pfValue;\n var family = ele.pstyle('font-family').strValue;\n var weight = ele.pstyle('font-weight').strValue;\n var canvas = this.labelCalcCanvas;\n var c2d = this.labelCalcCanvasContext;\n if (!canvas) {\n canvas = this.labelCalcCanvas = document.createElement('canvas');\n c2d = this.labelCalcCanvasContext = canvas.getContext('2d');\n var ds = canvas.style;\n ds.position = 'absolute';\n ds.left = '-9999px';\n ds.top = '-9999px';\n ds.zIndex = '-1';\n ds.visibility = 'hidden';\n ds.pointerEvents = 'none';\n }\n c2d.font = \"\".concat(fStyle, \" \").concat(weight, \" \").concat(size, \"px \").concat(family);\n var width = 0;\n var height = 0;\n var lines = text.split('\\n');\n for (var i = 0; i < lines.length; i++) {\n var line = lines[i];\n var metrics = c2d.measureText(line);\n var w = Math.ceil(metrics.width);\n var h = size;\n width = Math.max(w, width);\n height += h;\n }\n width += padding;\n height += padding;\n return cache[cacheKey] = {\n width: width,\n height: height\n };\n};\nBRp$9.calculateLabelAngle = function (ele, prefix) {\n var _p = ele._private;\n var rs = _p.rscratch;\n var isEdge = ele.isEdge();\n var prefixDash = prefix ? prefix + '-' : '';\n var rot = ele.pstyle(prefixDash + 'text-rotation');\n var rotStr = rot.strValue;\n if (rotStr === 'none') {\n return 0;\n } else if (isEdge && rotStr === 'autorotate') {\n return rs.labelAutoAngle;\n } else if (rotStr === 'autorotate') {\n return 0;\n } else {\n return rot.pfValue;\n }\n};\nBRp$9.calculateLabelAngles = function (ele) {\n var r = this;\n var isEdge = ele.isEdge();\n var _p = ele._private;\n var rs = _p.rscratch;\n rs.labelAngle = r.calculateLabelAngle(ele);\n if (isEdge) {\n rs.sourceLabelAngle = r.calculateLabelAngle(ele, 'source');\n rs.targetLabelAngle = r.calculateLabelAngle(ele, 'target');\n }\n};\n\nvar BRp$8 = {};\nvar TOO_SMALL_CUT_RECT = 28;\nvar warnedCutRect = false;\nBRp$8.getNodeShape = function (node) {\n var r = this;\n var shape = node.pstyle('shape').value;\n if (shape === 'cutrectangle' && (node.width() < TOO_SMALL_CUT_RECT || node.height() < TOO_SMALL_CUT_RECT)) {\n if (!warnedCutRect) {\n warn('The `cutrectangle` node shape can not be used at small sizes so `rectangle` is used instead');\n warnedCutRect = true;\n }\n return 'rectangle';\n }\n if (node.isParent()) {\n if (shape === 'rectangle' || shape === 'roundrectangle' || shape === 'round-rectangle' || shape === 'cutrectangle' || shape === 'cut-rectangle' || shape === 'barrel') {\n return shape;\n } else {\n return 'rectangle';\n }\n }\n if (shape === 'polygon') {\n var points = node.pstyle('shape-polygon-points').value;\n return r.nodeShapes.makePolygon(points).name;\n }\n return shape;\n};\n\nvar BRp$7 = {};\nBRp$7.registerCalculationListeners = function () {\n var cy = this.cy;\n var elesToUpdate = cy.collection();\n var r = this;\n var enqueue = function enqueue(eles) {\n var dirtyStyleCaches = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n elesToUpdate.merge(eles);\n if (dirtyStyleCaches) {\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var _p = ele._private;\n var rstyle = _p.rstyle;\n rstyle.clean = false;\n rstyle.cleanConnected = false;\n }\n }\n };\n r.binder(cy).on('bounds.* dirty.*', function onDirtyBounds(e) {\n var ele = e.target;\n enqueue(ele);\n }).on('style.* background.*', function onDirtyStyle(e) {\n var ele = e.target;\n enqueue(ele, false);\n });\n var updateEleCalcs = function updateEleCalcs(willDraw) {\n if (willDraw) {\n var fns = r.onUpdateEleCalcsFns;\n\n // because we need to have up-to-date style (e.g. stylesheet mappers)\n // before calculating rendered style (and pstyle might not be called yet)\n elesToUpdate.cleanStyle();\n for (var i = 0; i < elesToUpdate.length; i++) {\n var ele = elesToUpdate[i];\n var rstyle = ele._private.rstyle;\n if (ele.isNode() && !rstyle.cleanConnected) {\n enqueue(ele.connectedEdges());\n rstyle.cleanConnected = true;\n }\n }\n if (fns) {\n for (var _i = 0; _i < fns.length; _i++) {\n var fn = fns[_i];\n fn(willDraw, elesToUpdate);\n }\n }\n r.recalculateRenderedStyle(elesToUpdate);\n elesToUpdate = cy.collection();\n }\n };\n r.flushRenderedStyleQueue = function () {\n updateEleCalcs(true);\n };\n r.beforeRender(updateEleCalcs, r.beforeRenderPriorities.eleCalcs);\n};\nBRp$7.onUpdateEleCalcs = function (fn) {\n var fns = this.onUpdateEleCalcsFns = this.onUpdateEleCalcsFns || [];\n fns.push(fn);\n};\nBRp$7.recalculateRenderedStyle = function (eles, useCache) {\n var isCleanConnected = function isCleanConnected(ele) {\n return ele._private.rstyle.cleanConnected;\n };\n var edges = [];\n var nodes = [];\n\n // the renderer can't be used for calcs when destroyed, e.g. ele.boundingBox()\n if (this.destroyed) {\n return;\n }\n\n // use cache by default for perf\n if (useCache === undefined) {\n useCache = true;\n }\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var _p = ele._private;\n var rstyle = _p.rstyle;\n\n // an edge may be implicitly dirty b/c of one of its connected nodes\n // (and a request for recalc may come in between frames)\n if (ele.isEdge() && (!isCleanConnected(ele.source()) || !isCleanConnected(ele.target()))) {\n rstyle.clean = false;\n }\n\n // only update if dirty and in graph\n if (useCache && rstyle.clean || ele.removed()) {\n continue;\n }\n\n // only update if not display: none\n if (ele.pstyle('display').value === 'none') {\n continue;\n }\n if (_p.group === 'nodes') {\n nodes.push(ele);\n } else {\n // edges\n edges.push(ele);\n }\n rstyle.clean = true;\n }\n\n // update node data from projections\n for (var _i2 = 0; _i2 < nodes.length; _i2++) {\n var _ele = nodes[_i2];\n var _p2 = _ele._private;\n var _rstyle = _p2.rstyle;\n var pos = _ele.position();\n this.recalculateNodeLabelProjection(_ele);\n _rstyle.nodeX = pos.x;\n _rstyle.nodeY = pos.y;\n _rstyle.nodeW = _ele.pstyle('width').pfValue;\n _rstyle.nodeH = _ele.pstyle('height').pfValue;\n }\n this.recalculateEdgeProjections(edges);\n\n // update edge data from projections\n for (var _i3 = 0; _i3 < edges.length; _i3++) {\n var _ele2 = edges[_i3];\n var _p3 = _ele2._private;\n var _rstyle2 = _p3.rstyle;\n var rs = _p3.rscratch;\n\n // update rstyle positions\n _rstyle2.srcX = rs.arrowStartX;\n _rstyle2.srcY = rs.arrowStartY;\n _rstyle2.tgtX = rs.arrowEndX;\n _rstyle2.tgtY = rs.arrowEndY;\n _rstyle2.midX = rs.midX;\n _rstyle2.midY = rs.midY;\n _rstyle2.labelAngle = rs.labelAngle;\n _rstyle2.sourceLabelAngle = rs.sourceLabelAngle;\n _rstyle2.targetLabelAngle = rs.targetLabelAngle;\n }\n};\n\nvar BRp$6 = {};\nBRp$6.updateCachedGrabbedEles = function () {\n var eles = this.cachedZSortedEles;\n if (!eles) {\n // just let this be recalculated on the next z sort tick\n return;\n }\n eles.drag = [];\n eles.nondrag = [];\n var grabTargets = [];\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var rs = ele._private.rscratch;\n if (ele.grabbed() && !ele.isParent()) {\n grabTargets.push(ele);\n } else if (rs.inDragLayer) {\n eles.drag.push(ele);\n } else {\n eles.nondrag.push(ele);\n }\n }\n\n // put the grab target nodes last so it's on top of its neighbourhood\n for (var i = 0; i < grabTargets.length; i++) {\n var ele = grabTargets[i];\n eles.drag.push(ele);\n }\n};\nBRp$6.invalidateCachedZSortedEles = function () {\n this.cachedZSortedEles = null;\n};\nBRp$6.getCachedZSortedEles = function (forceRecalc) {\n if (forceRecalc || !this.cachedZSortedEles) {\n var eles = this.cy.mutableElements().toArray();\n eles.sort(zIndexSort);\n eles.interactive = eles.filter(function (ele) {\n return ele.interactive();\n });\n this.cachedZSortedEles = eles;\n this.updateCachedGrabbedEles();\n } else {\n eles = this.cachedZSortedEles;\n }\n return eles;\n};\n\nvar BRp$5 = {};\n[BRp$e, BRp$d, BRp$c, BRp$b, BRp$a, BRp$9, BRp$8, BRp$7, BRp$6].forEach(function (props) {\n extend(BRp$5, props);\n});\n\nvar BRp$4 = {};\nBRp$4.getCachedImage = function (url, crossOrigin, onLoad) {\n var r = this;\n var imageCache = r.imageCache = r.imageCache || {};\n var cache = imageCache[url];\n if (cache) {\n if (!cache.image.complete) {\n cache.image.addEventListener('load', onLoad);\n }\n return cache.image;\n } else {\n cache = imageCache[url] = imageCache[url] || {};\n var image = cache.image = new Image(); // eslint-disable-line no-undef\n\n image.addEventListener('load', onLoad);\n image.addEventListener('error', function () {\n image.error = true;\n });\n\n // #1582 safari doesn't load data uris with crossOrigin properly\n // https://bugs.webkit.org/show_bug.cgi?id=123978\n var dataUriPrefix = 'data:';\n var isDataUri = url.substring(0, dataUriPrefix.length).toLowerCase() === dataUriPrefix;\n if (!isDataUri) {\n // if crossorigin is 'null'(stringified), then manually set it to null \n crossOrigin = crossOrigin === 'null' ? null : crossOrigin;\n image.crossOrigin = crossOrigin; // prevent tainted canvas\n }\n\n image.src = url;\n return image;\n }\n};\n\nvar BRp$3 = {};\n\n/* global document, ResizeObserver, MutationObserver */\n\nBRp$3.registerBinding = function (target, event, handler, useCapture) {\n // eslint-disable-line no-unused-vars\n var args = Array.prototype.slice.apply(arguments, [1]); // copy\n var b = this.binder(target);\n return b.on.apply(b, args);\n};\nBRp$3.binder = function (tgt) {\n var r = this;\n var containerWindow = r.cy.window();\n var tgtIsDom = tgt === containerWindow || tgt === containerWindow.document || tgt === containerWindow.document.body || domElement(tgt);\n if (r.supportsPassiveEvents == null) {\n // from https://github.com/WICG/EventListenerOptions/blob/gh-pages/explainer.md#feature-detection\n var supportsPassive = false;\n try {\n var opts = Object.defineProperty({}, 'passive', {\n get: function get() {\n supportsPassive = true;\n return true;\n }\n });\n containerWindow.addEventListener('test', null, opts);\n } catch (err) {\n // not supported\n }\n r.supportsPassiveEvents = supportsPassive;\n }\n var on = function on(event, handler, useCapture) {\n var args = Array.prototype.slice.call(arguments);\n if (tgtIsDom && r.supportsPassiveEvents) {\n // replace useCapture w/ opts obj\n args[2] = {\n capture: useCapture != null ? useCapture : false,\n passive: false,\n once: false\n };\n }\n r.bindings.push({\n target: tgt,\n args: args\n });\n (tgt.addEventListener || tgt.on).apply(tgt, args);\n return this;\n };\n return {\n on: on,\n addEventListener: on,\n addListener: on,\n bind: on\n };\n};\nBRp$3.nodeIsDraggable = function (node) {\n return node && node.isNode() && !node.locked() && node.grabbable();\n};\nBRp$3.nodeIsGrabbable = function (node) {\n return this.nodeIsDraggable(node) && node.interactive();\n};\nBRp$3.load = function () {\n var r = this;\n var containerWindow = r.cy.window();\n var isSelected = function isSelected(ele) {\n return ele.selected();\n };\n var triggerEvents = function triggerEvents(target, names, e, position) {\n if (target == null) {\n target = r.cy;\n }\n for (var i = 0; i < names.length; i++) {\n var name = names[i];\n target.emit({\n originalEvent: e,\n type: name,\n position: position\n });\n }\n };\n var isMultSelKeyDown = function isMultSelKeyDown(e) {\n return e.shiftKey || e.metaKey || e.ctrlKey; // maybe e.altKey\n };\n\n var allowPanningPassthrough = function allowPanningPassthrough(down, downs) {\n var allowPassthrough = true;\n if (r.cy.hasCompoundNodes() && down && down.pannable()) {\n // a grabbable compound node below the ele => no passthrough panning\n for (var i = 0; downs && i < downs.length; i++) {\n var down = downs[i];\n\n //if any parent node in event hierarchy isn't pannable, reject passthrough\n if (down.isNode() && down.isParent() && !down.pannable()) {\n allowPassthrough = false;\n break;\n }\n }\n } else {\n allowPassthrough = true;\n }\n return allowPassthrough;\n };\n var setGrabbed = function setGrabbed(ele) {\n ele[0]._private.grabbed = true;\n };\n var setFreed = function setFreed(ele) {\n ele[0]._private.grabbed = false;\n };\n var setInDragLayer = function setInDragLayer(ele) {\n ele[0]._private.rscratch.inDragLayer = true;\n };\n var setOutDragLayer = function setOutDragLayer(ele) {\n ele[0]._private.rscratch.inDragLayer = false;\n };\n var setGrabTarget = function setGrabTarget(ele) {\n ele[0]._private.rscratch.isGrabTarget = true;\n };\n var removeGrabTarget = function removeGrabTarget(ele) {\n ele[0]._private.rscratch.isGrabTarget = false;\n };\n var addToDragList = function addToDragList(ele, opts) {\n var list = opts.addToList;\n var listHasEle = list.has(ele);\n if (!listHasEle && ele.grabbable() && !ele.locked()) {\n list.merge(ele);\n setGrabbed(ele);\n }\n };\n\n // helper function to determine which child nodes and inner edges\n // of a compound node to be dragged as well as the grabbed and selected nodes\n var addDescendantsToDrag = function addDescendantsToDrag(node, opts) {\n if (!node.cy().hasCompoundNodes()) {\n return;\n }\n if (opts.inDragLayer == null && opts.addToList == null) {\n return;\n } // nothing to do\n\n var innerNodes = node.descendants();\n if (opts.inDragLayer) {\n innerNodes.forEach(setInDragLayer);\n innerNodes.connectedEdges().forEach(setInDragLayer);\n }\n if (opts.addToList) {\n addToDragList(innerNodes, opts);\n }\n };\n\n // adds the given nodes and its neighbourhood to the drag layer\n var addNodesToDrag = function addNodesToDrag(nodes, opts) {\n opts = opts || {};\n var hasCompoundNodes = nodes.cy().hasCompoundNodes();\n if (opts.inDragLayer) {\n nodes.forEach(setInDragLayer);\n nodes.neighborhood().stdFilter(function (ele) {\n return !hasCompoundNodes || ele.isEdge();\n }).forEach(setInDragLayer);\n }\n if (opts.addToList) {\n nodes.forEach(function (ele) {\n addToDragList(ele, opts);\n });\n }\n addDescendantsToDrag(nodes, opts); // always add to drag\n\n // also add nodes and edges related to the topmost ancestor\n updateAncestorsInDragLayer(nodes, {\n inDragLayer: opts.inDragLayer\n });\n r.updateCachedGrabbedEles();\n };\n var addNodeToDrag = addNodesToDrag;\n var freeDraggedElements = function freeDraggedElements(grabbedEles) {\n if (!grabbedEles) {\n return;\n }\n\n // just go over all elements rather than doing a bunch of (possibly expensive) traversals\n r.getCachedZSortedEles().forEach(function (ele) {\n setFreed(ele);\n setOutDragLayer(ele);\n removeGrabTarget(ele);\n });\n r.updateCachedGrabbedEles();\n };\n\n // helper function to determine which ancestor nodes and edges should go\n // to the drag layer (or should be removed from drag layer).\n var updateAncestorsInDragLayer = function updateAncestorsInDragLayer(node, opts) {\n if (opts.inDragLayer == null && opts.addToList == null) {\n return;\n } // nothing to do\n\n if (!node.cy().hasCompoundNodes()) {\n return;\n }\n\n // find top-level parent\n var parent = node.ancestors().orphans();\n\n // no parent node: no nodes to add to the drag layer\n if (parent.same(node)) {\n return;\n }\n var nodes = parent.descendants().spawnSelf().merge(parent).unmerge(node).unmerge(node.descendants());\n var edges = nodes.connectedEdges();\n if (opts.inDragLayer) {\n edges.forEach(setInDragLayer);\n nodes.forEach(setInDragLayer);\n }\n if (opts.addToList) {\n nodes.forEach(function (ele) {\n addToDragList(ele, opts);\n });\n }\n };\n var blurActiveDomElement = function blurActiveDomElement() {\n if (document.activeElement != null && document.activeElement.blur != null) {\n document.activeElement.blur();\n }\n };\n var haveMutationsApi = typeof MutationObserver !== 'undefined';\n var haveResizeObserverApi = typeof ResizeObserver !== 'undefined';\n\n // watch for when the cy container is removed from the dom\n if (haveMutationsApi) {\n r.removeObserver = new MutationObserver(function (mutns) {\n // eslint-disable-line no-undef\n for (var i = 0; i < mutns.length; i++) {\n var mutn = mutns[i];\n var rNodes = mutn.removedNodes;\n if (rNodes) {\n for (var j = 0; j < rNodes.length; j++) {\n var rNode = rNodes[j];\n if (rNode === r.container) {\n r.destroy();\n break;\n }\n }\n }\n }\n });\n if (r.container.parentNode) {\n r.removeObserver.observe(r.container.parentNode, {\n childList: true\n });\n }\n } else {\n r.registerBinding(r.container, 'DOMNodeRemoved', function (e) {\n // eslint-disable-line no-unused-vars\n r.destroy();\n });\n }\n var onResize = debounce_1(function () {\n r.cy.resize();\n }, 100);\n if (haveMutationsApi) {\n r.styleObserver = new MutationObserver(onResize); // eslint-disable-line no-undef\n\n r.styleObserver.observe(r.container, {\n attributes: true\n });\n }\n\n // auto resize\n r.registerBinding(containerWindow, 'resize', onResize); // eslint-disable-line no-undef\n\n if (haveResizeObserverApi) {\n r.resizeObserver = new ResizeObserver(onResize); // eslint-disable-line no-undef\n\n r.resizeObserver.observe(r.container);\n }\n var forEachUp = function forEachUp(domEle, fn) {\n while (domEle != null) {\n fn(domEle);\n domEle = domEle.parentNode;\n }\n };\n var invalidateCoords = function invalidateCoords() {\n r.invalidateContainerClientCoordsCache();\n };\n forEachUp(r.container, function (domEle) {\n r.registerBinding(domEle, 'transitionend', invalidateCoords);\n r.registerBinding(domEle, 'animationend', invalidateCoords);\n r.registerBinding(domEle, 'scroll', invalidateCoords);\n });\n\n // stop right click menu from appearing on cy\n r.registerBinding(r.container, 'contextmenu', function (e) {\n e.preventDefault();\n });\n var inBoxSelection = function inBoxSelection() {\n return r.selection[4] !== 0;\n };\n var eventInContainer = function eventInContainer(e) {\n // save cycles if mouse events aren't to be captured\n var containerPageCoords = r.findContainerClientCoords();\n var x = containerPageCoords[0];\n var y = containerPageCoords[1];\n var width = containerPageCoords[2];\n var height = containerPageCoords[3];\n var positions = e.touches ? e.touches : [e];\n var atLeastOnePosInside = false;\n for (var i = 0; i < positions.length; i++) {\n var p = positions[i];\n if (x <= p.clientX && p.clientX <= x + width && y <= p.clientY && p.clientY <= y + height) {\n atLeastOnePosInside = true;\n break;\n }\n }\n if (!atLeastOnePosInside) {\n return false;\n }\n var container = r.container;\n var target = e.target;\n var tParent = target.parentNode;\n var containerIsTarget = false;\n while (tParent) {\n if (tParent === container) {\n containerIsTarget = true;\n break;\n }\n tParent = tParent.parentNode;\n }\n if (!containerIsTarget) {\n return false;\n } // if target is outisde cy container, then this event is not for us\n\n return true;\n };\n\n // Primary key\n r.registerBinding(r.container, 'mousedown', function mousedownHandler(e) {\n if (!eventInContainer(e)) {\n return;\n }\n\n // during left mouse button gestures, ignore other buttons\n if (r.hoverData.which === 1 && e.which !== 1) {\n return;\n }\n e.preventDefault();\n blurActiveDomElement();\n r.hoverData.capture = true;\n r.hoverData.which = e.which;\n var cy = r.cy;\n var gpos = [e.clientX, e.clientY];\n var pos = r.projectIntoViewport(gpos[0], gpos[1]);\n var select = r.selection;\n var nears = r.findNearestElements(pos[0], pos[1], true, false);\n var near = nears[0];\n var draggedElements = r.dragData.possibleDragElements;\n r.hoverData.mdownPos = pos;\n r.hoverData.mdownGPos = gpos;\n var checkForTaphold = function checkForTaphold() {\n r.hoverData.tapholdCancelled = false;\n clearTimeout(r.hoverData.tapholdTimeout);\n r.hoverData.tapholdTimeout = setTimeout(function () {\n if (r.hoverData.tapholdCancelled) {\n return;\n } else {\n var ele = r.hoverData.down;\n if (ele) {\n ele.emit({\n originalEvent: e,\n type: 'taphold',\n position: {\n x: pos[0],\n y: pos[1]\n }\n });\n } else {\n cy.emit({\n originalEvent: e,\n type: 'taphold',\n position: {\n x: pos[0],\n y: pos[1]\n }\n });\n }\n }\n }, r.tapholdDuration);\n };\n\n // Right click button\n if (e.which == 3) {\n r.hoverData.cxtStarted = true;\n var cxtEvt = {\n originalEvent: e,\n type: 'cxttapstart',\n position: {\n x: pos[0],\n y: pos[1]\n }\n };\n if (near) {\n near.activate();\n near.emit(cxtEvt);\n r.hoverData.down = near;\n } else {\n cy.emit(cxtEvt);\n }\n r.hoverData.downTime = new Date().getTime();\n r.hoverData.cxtDragged = false;\n\n // Primary button\n } else if (e.which == 1) {\n if (near) {\n near.activate();\n }\n\n // Element dragging\n {\n // If something is under the cursor and it is draggable, prepare to grab it\n if (near != null) {\n if (r.nodeIsGrabbable(near)) {\n var makeEvent = function makeEvent(type) {\n return {\n originalEvent: e,\n type: type,\n position: {\n x: pos[0],\n y: pos[1]\n }\n };\n };\n var triggerGrab = function triggerGrab(ele) {\n ele.emit(makeEvent('grab'));\n };\n setGrabTarget(near);\n if (!near.selected()) {\n draggedElements = r.dragData.possibleDragElements = cy.collection();\n addNodeToDrag(near, {\n addToList: draggedElements\n });\n near.emit(makeEvent('grabon')).emit(makeEvent('grab'));\n } else {\n draggedElements = r.dragData.possibleDragElements = cy.collection();\n var selectedNodes = cy.$(function (ele) {\n return ele.isNode() && ele.selected() && r.nodeIsGrabbable(ele);\n });\n addNodesToDrag(selectedNodes, {\n addToList: draggedElements\n });\n near.emit(makeEvent('grabon'));\n selectedNodes.forEach(triggerGrab);\n }\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n }\n }\n r.hoverData.down = near;\n r.hoverData.downs = nears;\n r.hoverData.downTime = new Date().getTime();\n }\n triggerEvents(near, ['mousedown', 'tapstart', 'vmousedown'], e, {\n x: pos[0],\n y: pos[1]\n });\n if (near == null) {\n select[4] = 1;\n r.data.bgActivePosistion = {\n x: pos[0],\n y: pos[1]\n };\n r.redrawHint('select', true);\n r.redraw();\n } else if (near.pannable()) {\n select[4] = 1; // for future pan\n }\n\n checkForTaphold();\n }\n\n // Initialize selection box coordinates\n select[0] = select[2] = pos[0];\n select[1] = select[3] = pos[1];\n }, false);\n r.registerBinding(containerWindow, 'mousemove', function mousemoveHandler(e) {\n // eslint-disable-line no-undef\n var capture = r.hoverData.capture;\n if (!capture && !eventInContainer(e)) {\n return;\n }\n var preventDefault = false;\n var cy = r.cy;\n var zoom = cy.zoom();\n var gpos = [e.clientX, e.clientY];\n var pos = r.projectIntoViewport(gpos[0], gpos[1]);\n var mdownPos = r.hoverData.mdownPos;\n var mdownGPos = r.hoverData.mdownGPos;\n var select = r.selection;\n var near = null;\n if (!r.hoverData.draggingEles && !r.hoverData.dragging && !r.hoverData.selecting) {\n near = r.findNearestElement(pos[0], pos[1], true, false);\n }\n var last = r.hoverData.last;\n var down = r.hoverData.down;\n var disp = [pos[0] - select[2], pos[1] - select[3]];\n var draggedElements = r.dragData.possibleDragElements;\n var isOverThresholdDrag;\n if (mdownGPos) {\n var dx = gpos[0] - mdownGPos[0];\n var dx2 = dx * dx;\n var dy = gpos[1] - mdownGPos[1];\n var dy2 = dy * dy;\n var dist2 = dx2 + dy2;\n r.hoverData.isOverThresholdDrag = isOverThresholdDrag = dist2 >= r.desktopTapThreshold2;\n }\n var multSelKeyDown = isMultSelKeyDown(e);\n if (isOverThresholdDrag) {\n r.hoverData.tapholdCancelled = true;\n }\n var updateDragDelta = function updateDragDelta() {\n var dragDelta = r.hoverData.dragDelta = r.hoverData.dragDelta || [];\n if (dragDelta.length === 0) {\n dragDelta.push(disp[0]);\n dragDelta.push(disp[1]);\n } else {\n dragDelta[0] += disp[0];\n dragDelta[1] += disp[1];\n }\n };\n preventDefault = true;\n triggerEvents(near, ['mousemove', 'vmousemove', 'tapdrag'], e, {\n x: pos[0],\n y: pos[1]\n });\n var goIntoBoxMode = function goIntoBoxMode() {\n r.data.bgActivePosistion = undefined;\n if (!r.hoverData.selecting) {\n cy.emit({\n originalEvent: e,\n type: 'boxstart',\n position: {\n x: pos[0],\n y: pos[1]\n }\n });\n }\n select[4] = 1;\n r.hoverData.selecting = true;\n r.redrawHint('select', true);\n r.redraw();\n };\n\n // trigger context drag if rmouse down\n if (r.hoverData.which === 3) {\n // but only if over threshold\n if (isOverThresholdDrag) {\n var cxtEvt = {\n originalEvent: e,\n type: 'cxtdrag',\n position: {\n x: pos[0],\n y: pos[1]\n }\n };\n if (down) {\n down.emit(cxtEvt);\n } else {\n cy.emit(cxtEvt);\n }\n r.hoverData.cxtDragged = true;\n if (!r.hoverData.cxtOver || near !== r.hoverData.cxtOver) {\n if (r.hoverData.cxtOver) {\n r.hoverData.cxtOver.emit({\n originalEvent: e,\n type: 'cxtdragout',\n position: {\n x: pos[0],\n y: pos[1]\n }\n });\n }\n r.hoverData.cxtOver = near;\n if (near) {\n near.emit({\n originalEvent: e,\n type: 'cxtdragover',\n position: {\n x: pos[0],\n y: pos[1]\n }\n });\n }\n }\n }\n\n // Check if we are drag panning the entire graph\n } else if (r.hoverData.dragging) {\n preventDefault = true;\n if (cy.panningEnabled() && cy.userPanningEnabled()) {\n var deltaP;\n if (r.hoverData.justStartedPan) {\n var mdPos = r.hoverData.mdownPos;\n deltaP = {\n x: (pos[0] - mdPos[0]) * zoom,\n y: (pos[1] - mdPos[1]) * zoom\n };\n r.hoverData.justStartedPan = false;\n } else {\n deltaP = {\n x: disp[0] * zoom,\n y: disp[1] * zoom\n };\n }\n cy.panBy(deltaP);\n cy.emit('dragpan');\n r.hoverData.dragged = true;\n }\n\n // Needs reproject due to pan changing viewport\n pos = r.projectIntoViewport(e.clientX, e.clientY);\n\n // Checks primary button down & out of time & mouse not moved much\n } else if (select[4] == 1 && (down == null || down.pannable())) {\n if (isOverThresholdDrag) {\n if (!r.hoverData.dragging && cy.boxSelectionEnabled() && (multSelKeyDown || !cy.panningEnabled() || !cy.userPanningEnabled())) {\n goIntoBoxMode();\n } else if (!r.hoverData.selecting && cy.panningEnabled() && cy.userPanningEnabled()) {\n var allowPassthrough = allowPanningPassthrough(down, r.hoverData.downs);\n if (allowPassthrough) {\n r.hoverData.dragging = true;\n r.hoverData.justStartedPan = true;\n select[4] = 0;\n r.data.bgActivePosistion = array2point(mdownPos);\n r.redrawHint('select', true);\n r.redraw();\n }\n }\n if (down && down.pannable() && down.active()) {\n down.unactivate();\n }\n }\n } else {\n if (down && down.pannable() && down.active()) {\n down.unactivate();\n }\n if ((!down || !down.grabbed()) && near != last) {\n if (last) {\n triggerEvents(last, ['mouseout', 'tapdragout'], e, {\n x: pos[0],\n y: pos[1]\n });\n }\n if (near) {\n triggerEvents(near, ['mouseover', 'tapdragover'], e, {\n x: pos[0],\n y: pos[1]\n });\n }\n r.hoverData.last = near;\n }\n if (down) {\n if (isOverThresholdDrag) {\n // then we can take action\n\n if (cy.boxSelectionEnabled() && multSelKeyDown) {\n // then selection overrides\n if (down && down.grabbed()) {\n freeDraggedElements(draggedElements);\n down.emit('freeon');\n draggedElements.emit('free');\n if (r.dragData.didDrag) {\n down.emit('dragfreeon');\n draggedElements.emit('dragfree');\n }\n }\n goIntoBoxMode();\n } else if (down && down.grabbed() && r.nodeIsDraggable(down)) {\n // drag node\n var justStartedDrag = !r.dragData.didDrag;\n if (justStartedDrag) {\n r.redrawHint('eles', true);\n }\n r.dragData.didDrag = true; // indicate that we actually did drag the node\n\n // now, add the elements to the drag layer if not done already\n if (!r.hoverData.draggingEles) {\n addNodesToDrag(draggedElements, {\n inDragLayer: true\n });\n }\n var totalShift = {\n x: 0,\n y: 0\n };\n if (number$1(disp[0]) && number$1(disp[1])) {\n totalShift.x += disp[0];\n totalShift.y += disp[1];\n if (justStartedDrag) {\n var dragDelta = r.hoverData.dragDelta;\n if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) {\n totalShift.x += dragDelta[0];\n totalShift.y += dragDelta[1];\n }\n }\n }\n r.hoverData.draggingEles = true;\n draggedElements.silentShift(totalShift).emit('position drag');\n r.redrawHint('drag', true);\n r.redraw();\n }\n } else {\n // otherwise save drag delta for when we actually start dragging so the relative grab pos is constant\n updateDragDelta();\n }\n }\n\n // prevent the dragging from triggering text selection on the page\n preventDefault = true;\n }\n select[2] = pos[0];\n select[3] = pos[1];\n if (preventDefault) {\n if (e.stopPropagation) e.stopPropagation();\n if (e.preventDefault) e.preventDefault();\n return false;\n }\n }, false);\n var clickTimeout, didDoubleClick, prevClickTimeStamp;\n r.registerBinding(containerWindow, 'mouseup', function mouseupHandler(e) {\n // eslint-disable-line no-undef\n // during left mouse button gestures, ignore other buttons\n if (r.hoverData.which === 1 && e.which !== 1 && r.hoverData.capture) {\n return;\n }\n var capture = r.hoverData.capture;\n if (!capture) {\n return;\n }\n r.hoverData.capture = false;\n var cy = r.cy;\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n var select = r.selection;\n var near = r.findNearestElement(pos[0], pos[1], true, false);\n var draggedElements = r.dragData.possibleDragElements;\n var down = r.hoverData.down;\n var multSelKeyDown = isMultSelKeyDown(e);\n if (r.data.bgActivePosistion) {\n r.redrawHint('select', true);\n r.redraw();\n }\n r.hoverData.tapholdCancelled = true;\n r.data.bgActivePosistion = undefined; // not active bg now\n\n if (down) {\n down.unactivate();\n }\n if (r.hoverData.which === 3) {\n var cxtEvt = {\n originalEvent: e,\n type: 'cxttapend',\n position: {\n x: pos[0],\n y: pos[1]\n }\n };\n if (down) {\n down.emit(cxtEvt);\n } else {\n cy.emit(cxtEvt);\n }\n if (!r.hoverData.cxtDragged) {\n var cxtTap = {\n originalEvent: e,\n type: 'cxttap',\n position: {\n x: pos[0],\n y: pos[1]\n }\n };\n if (down) {\n down.emit(cxtTap);\n } else {\n cy.emit(cxtTap);\n }\n }\n r.hoverData.cxtDragged = false;\n r.hoverData.which = null;\n } else if (r.hoverData.which === 1) {\n triggerEvents(near, ['mouseup', 'tapend', 'vmouseup'], e, {\n x: pos[0],\n y: pos[1]\n });\n if (!r.dragData.didDrag &&\n // didn't move a node around\n !r.hoverData.dragged &&\n // didn't pan\n !r.hoverData.selecting &&\n // not box selection\n !r.hoverData.isOverThresholdDrag // didn't move too much\n ) {\n triggerEvents(down, [\"click\", \"tap\", \"vclick\"], e, {\n x: pos[0],\n y: pos[1]\n });\n didDoubleClick = false;\n if (e.timeStamp - prevClickTimeStamp <= cy.multiClickDebounceTime()) {\n clickTimeout && clearTimeout(clickTimeout);\n didDoubleClick = true;\n prevClickTimeStamp = null;\n triggerEvents(down, [\"dblclick\", \"dbltap\", \"vdblclick\"], e, {\n x: pos[0],\n y: pos[1]\n });\n } else {\n clickTimeout = setTimeout(function () {\n if (didDoubleClick) return;\n triggerEvents(down, [\"oneclick\", \"onetap\", \"voneclick\"], e, {\n x: pos[0],\n y: pos[1]\n });\n }, cy.multiClickDebounceTime());\n prevClickTimeStamp = e.timeStamp;\n }\n }\n\n // Deselect all elements if nothing is currently under the mouse cursor and we aren't dragging something\n if (down == null // not mousedown on node\n && !r.dragData.didDrag // didn't move the node around\n && !r.hoverData.selecting // not box selection\n && !r.hoverData.dragged // didn't pan\n && !isMultSelKeyDown(e)) {\n cy.$(isSelected).unselect(['tapunselect']);\n if (draggedElements.length > 0) {\n r.redrawHint('eles', true);\n }\n r.dragData.possibleDragElements = draggedElements = cy.collection();\n }\n\n // Single selection\n if (near == down && !r.dragData.didDrag && !r.hoverData.selecting) {\n if (near != null && near._private.selectable) {\n if (r.hoverData.dragging) ; else if (cy.selectionType() === 'additive' || multSelKeyDown) {\n if (near.selected()) {\n near.unselect(['tapunselect']);\n } else {\n near.select(['tapselect']);\n }\n } else {\n if (!multSelKeyDown) {\n cy.$(isSelected).unmerge(near).unselect(['tapunselect']);\n near.select(['tapselect']);\n }\n }\n r.redrawHint('eles', true);\n }\n }\n if (r.hoverData.selecting) {\n var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3]));\n r.redrawHint('select', true);\n if (box.length > 0) {\n r.redrawHint('eles', true);\n }\n cy.emit({\n type: 'boxend',\n originalEvent: e,\n position: {\n x: pos[0],\n y: pos[1]\n }\n });\n var eleWouldBeSelected = function eleWouldBeSelected(ele) {\n return ele.selectable() && !ele.selected();\n };\n if (cy.selectionType() === 'additive') {\n box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');\n } else {\n if (!multSelKeyDown) {\n cy.$(isSelected).unmerge(box).unselect();\n }\n box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');\n }\n\n // always need redraw in case eles unselectable\n r.redraw();\n }\n\n // Cancel drag pan\n if (r.hoverData.dragging) {\n r.hoverData.dragging = false;\n r.redrawHint('select', true);\n r.redrawHint('eles', true);\n r.redraw();\n }\n if (!select[4]) {\n r.redrawHint('drag', true);\n r.redrawHint('eles', true);\n var downWasGrabbed = down && down.grabbed();\n freeDraggedElements(draggedElements);\n if (downWasGrabbed) {\n down.emit('freeon');\n draggedElements.emit('free');\n if (r.dragData.didDrag) {\n down.emit('dragfreeon');\n draggedElements.emit('dragfree');\n }\n }\n }\n } // else not right mouse\n\n select[4] = 0;\n r.hoverData.down = null;\n r.hoverData.cxtStarted = false;\n r.hoverData.draggingEles = false;\n r.hoverData.selecting = false;\n r.hoverData.isOverThresholdDrag = false;\n r.dragData.didDrag = false;\n r.hoverData.dragged = false;\n r.hoverData.dragDelta = [];\n r.hoverData.mdownPos = null;\n r.hoverData.mdownGPos = null;\n r.hoverData.which = null;\n }, false);\n var wheelHandler = function wheelHandler(e) {\n if (r.scrollingPage) {\n return;\n } // while scrolling, ignore wheel-to-zoom\n\n var cy = r.cy;\n var zoom = cy.zoom();\n var pan = cy.pan();\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n var rpos = [pos[0] * zoom + pan.x, pos[1] * zoom + pan.y];\n if (r.hoverData.draggingEles || r.hoverData.dragging || r.hoverData.cxtStarted || inBoxSelection()) {\n // if pan dragging or cxt dragging, wheel movements make no zoom\n e.preventDefault();\n return;\n }\n if (cy.panningEnabled() && cy.userPanningEnabled() && cy.zoomingEnabled() && cy.userZoomingEnabled()) {\n e.preventDefault();\n r.data.wheelZooming = true;\n clearTimeout(r.data.wheelTimeout);\n r.data.wheelTimeout = setTimeout(function () {\n r.data.wheelZooming = false;\n r.redrawHint('eles', true);\n r.redraw();\n }, 150);\n var diff;\n if (e.deltaY != null) {\n diff = e.deltaY / -250;\n } else if (e.wheelDeltaY != null) {\n diff = e.wheelDeltaY / 1000;\n } else {\n diff = e.wheelDelta / 1000;\n }\n diff = diff * r.wheelSensitivity;\n var needsWheelFix = e.deltaMode === 1;\n if (needsWheelFix) {\n // fixes slow wheel events on ff/linux and ff/windows\n diff *= 33;\n }\n var newZoom = cy.zoom() * Math.pow(10, diff);\n if (e.type === 'gesturechange') {\n newZoom = r.gestureStartZoom * e.scale;\n }\n cy.zoom({\n level: newZoom,\n renderedPosition: {\n x: rpos[0],\n y: rpos[1]\n }\n });\n cy.emit(e.type === 'gesturechange' ? 'pinchzoom' : 'scrollzoom');\n }\n };\n\n // Functions to help with whether mouse wheel should trigger zooming\n // --\n r.registerBinding(r.container, 'wheel', wheelHandler, true);\n\n // disable nonstandard wheel events\n // r.registerBinding(r.container, 'mousewheel', wheelHandler, true);\n // r.registerBinding(r.container, 'DOMMouseScroll', wheelHandler, true);\n // r.registerBinding(r.container, 'MozMousePixelScroll', wheelHandler, true); // older firefox\n\n r.registerBinding(containerWindow, 'scroll', function scrollHandler(e) {\n // eslint-disable-line no-unused-vars\n r.scrollingPage = true;\n clearTimeout(r.scrollingPageTimeout);\n r.scrollingPageTimeout = setTimeout(function () {\n r.scrollingPage = false;\n }, 250);\n }, true);\n\n // desktop safari pinch to zoom start\n r.registerBinding(r.container, 'gesturestart', function gestureStartHandler(e) {\n r.gestureStartZoom = r.cy.zoom();\n if (!r.hasTouchStarted) {\n // don't affect touch devices like iphone\n e.preventDefault();\n }\n }, true);\n r.registerBinding(r.container, 'gesturechange', function (e) {\n if (!r.hasTouchStarted) {\n // don't affect touch devices like iphone\n wheelHandler(e);\n }\n }, true);\n\n // Functions to help with handling mouseout/mouseover on the Cytoscape container\n // Handle mouseout on Cytoscape container\n r.registerBinding(r.container, 'mouseout', function mouseOutHandler(e) {\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n r.cy.emit({\n originalEvent: e,\n type: 'mouseout',\n position: {\n x: pos[0],\n y: pos[1]\n }\n });\n }, false);\n r.registerBinding(r.container, 'mouseover', function mouseOverHandler(e) {\n var pos = r.projectIntoViewport(e.clientX, e.clientY);\n r.cy.emit({\n originalEvent: e,\n type: 'mouseover',\n position: {\n x: pos[0],\n y: pos[1]\n }\n });\n }, false);\n var f1x1, f1y1, f2x1, f2y1; // starting points for pinch-to-zoom\n var distance1, distance1Sq; // initial distance between finger 1 and finger 2 for pinch-to-zoom\n var center1, modelCenter1; // center point on start pinch to zoom\n var offsetLeft, offsetTop;\n var containerWidth, containerHeight;\n var twoFingersStartInside;\n var distance = function distance(x1, y1, x2, y2) {\n return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n };\n var distanceSq = function distanceSq(x1, y1, x2, y2) {\n return (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);\n };\n var touchstartHandler;\n r.registerBinding(r.container, 'touchstart', touchstartHandler = function touchstartHandler(e) {\n r.hasTouchStarted = true;\n if (!eventInContainer(e)) {\n return;\n }\n blurActiveDomElement();\n r.touchData.capture = true;\n r.data.bgActivePosistion = undefined;\n var cy = r.cy;\n var now = r.touchData.now;\n var earlier = r.touchData.earlier;\n if (e.touches[0]) {\n var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);\n now[0] = pos[0];\n now[1] = pos[1];\n }\n if (e.touches[1]) {\n var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);\n now[2] = pos[0];\n now[3] = pos[1];\n }\n if (e.touches[2]) {\n var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);\n now[4] = pos[0];\n now[5] = pos[1];\n }\n\n // record starting points for pinch-to-zoom\n if (e.touches[1]) {\n r.touchData.singleTouchMoved = true;\n freeDraggedElements(r.dragData.touchDragEles);\n var offsets = r.findContainerClientCoords();\n offsetLeft = offsets[0];\n offsetTop = offsets[1];\n containerWidth = offsets[2];\n containerHeight = offsets[3];\n f1x1 = e.touches[0].clientX - offsetLeft;\n f1y1 = e.touches[0].clientY - offsetTop;\n f2x1 = e.touches[1].clientX - offsetLeft;\n f2y1 = e.touches[1].clientY - offsetTop;\n twoFingersStartInside = 0 <= f1x1 && f1x1 <= containerWidth && 0 <= f2x1 && f2x1 <= containerWidth && 0 <= f1y1 && f1y1 <= containerHeight && 0 <= f2y1 && f2y1 <= containerHeight;\n var pan = cy.pan();\n var zoom = cy.zoom();\n distance1 = distance(f1x1, f1y1, f2x1, f2y1);\n distance1Sq = distanceSq(f1x1, f1y1, f2x1, f2y1);\n center1 = [(f1x1 + f2x1) / 2, (f1y1 + f2y1) / 2];\n modelCenter1 = [(center1[0] - pan.x) / zoom, (center1[1] - pan.y) / zoom];\n\n // consider context tap\n var cxtDistThreshold = 200;\n var cxtDistThresholdSq = cxtDistThreshold * cxtDistThreshold;\n if (distance1Sq < cxtDistThresholdSq && !e.touches[2]) {\n var near1 = r.findNearestElement(now[0], now[1], true, true);\n var near2 = r.findNearestElement(now[2], now[3], true, true);\n if (near1 && near1.isNode()) {\n near1.activate().emit({\n originalEvent: e,\n type: 'cxttapstart',\n position: {\n x: now[0],\n y: now[1]\n }\n });\n r.touchData.start = near1;\n } else if (near2 && near2.isNode()) {\n near2.activate().emit({\n originalEvent: e,\n type: 'cxttapstart',\n position: {\n x: now[0],\n y: now[1]\n }\n });\n r.touchData.start = near2;\n } else {\n cy.emit({\n originalEvent: e,\n type: 'cxttapstart',\n position: {\n x: now[0],\n y: now[1]\n }\n });\n }\n if (r.touchData.start) {\n r.touchData.start._private.grabbed = false;\n }\n r.touchData.cxt = true;\n r.touchData.cxtDragged = false;\n r.data.bgActivePosistion = undefined;\n r.redraw();\n return;\n }\n }\n if (e.touches[2]) {\n // ignore\n\n // safari on ios pans the page otherwise (normally you should be able to preventdefault on touchmove...)\n if (cy.boxSelectionEnabled()) {\n e.preventDefault();\n }\n } else if (e.touches[1]) ; else if (e.touches[0]) {\n var nears = r.findNearestElements(now[0], now[1], true, true);\n var near = nears[0];\n if (near != null) {\n near.activate();\n r.touchData.start = near;\n r.touchData.starts = nears;\n if (r.nodeIsGrabbable(near)) {\n var draggedEles = r.dragData.touchDragEles = cy.collection();\n var selectedNodes = null;\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n if (near.selected()) {\n // reset drag elements, since near will be added again\n\n selectedNodes = cy.$(function (ele) {\n return ele.selected() && r.nodeIsGrabbable(ele);\n });\n addNodesToDrag(selectedNodes, {\n addToList: draggedEles\n });\n } else {\n addNodeToDrag(near, {\n addToList: draggedEles\n });\n }\n setGrabTarget(near);\n var makeEvent = function makeEvent(type) {\n return {\n originalEvent: e,\n type: type,\n position: {\n x: now[0],\n y: now[1]\n }\n };\n };\n near.emit(makeEvent('grabon'));\n if (selectedNodes) {\n selectedNodes.forEach(function (n) {\n n.emit(makeEvent('grab'));\n });\n } else {\n near.emit(makeEvent('grab'));\n }\n }\n }\n triggerEvents(near, ['touchstart', 'tapstart', 'vmousedown'], e, {\n x: now[0],\n y: now[1]\n });\n if (near == null) {\n r.data.bgActivePosistion = {\n x: pos[0],\n y: pos[1]\n };\n r.redrawHint('select', true);\n r.redraw();\n }\n\n // Tap, taphold\n // -----\n\n r.touchData.singleTouchMoved = false;\n r.touchData.singleTouchStartTime = +new Date();\n clearTimeout(r.touchData.tapholdTimeout);\n r.touchData.tapholdTimeout = setTimeout(function () {\n if (r.touchData.singleTouchMoved === false && !r.pinching // if pinching, then taphold unselect shouldn't take effect\n && !r.touchData.selecting // box selection shouldn't allow taphold through\n ) {\n triggerEvents(r.touchData.start, ['taphold'], e, {\n x: now[0],\n y: now[1]\n });\n }\n }, r.tapholdDuration);\n }\n if (e.touches.length >= 1) {\n var sPos = r.touchData.startPosition = [null, null, null, null, null, null];\n for (var i = 0; i < now.length; i++) {\n sPos[i] = earlier[i] = now[i];\n }\n var touch0 = e.touches[0];\n r.touchData.startGPosition = [touch0.clientX, touch0.clientY];\n }\n }, false);\n var touchmoveHandler;\n r.registerBinding(containerWindow, 'touchmove', touchmoveHandler = function touchmoveHandler(e) {\n // eslint-disable-line no-undef\n var capture = r.touchData.capture;\n if (!capture && !eventInContainer(e)) {\n return;\n }\n var select = r.selection;\n var cy = r.cy;\n var now = r.touchData.now;\n var earlier = r.touchData.earlier;\n var zoom = cy.zoom();\n if (e.touches[0]) {\n var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);\n now[0] = pos[0];\n now[1] = pos[1];\n }\n if (e.touches[1]) {\n var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);\n now[2] = pos[0];\n now[3] = pos[1];\n }\n if (e.touches[2]) {\n var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);\n now[4] = pos[0];\n now[5] = pos[1];\n }\n var startGPos = r.touchData.startGPosition;\n var isOverThresholdDrag;\n if (capture && e.touches[0] && startGPos) {\n var disp = [];\n for (var j = 0; j < now.length; j++) {\n disp[j] = now[j] - earlier[j];\n }\n var dx = e.touches[0].clientX - startGPos[0];\n var dx2 = dx * dx;\n var dy = e.touches[0].clientY - startGPos[1];\n var dy2 = dy * dy;\n var dist2 = dx2 + dy2;\n isOverThresholdDrag = dist2 >= r.touchTapThreshold2;\n }\n\n // context swipe cancelling\n if (capture && r.touchData.cxt) {\n e.preventDefault();\n var f1x2 = e.touches[0].clientX - offsetLeft,\n f1y2 = e.touches[0].clientY - offsetTop;\n var f2x2 = e.touches[1].clientX - offsetLeft,\n f2y2 = e.touches[1].clientY - offsetTop;\n // var distance2 = distance( f1x2, f1y2, f2x2, f2y2 );\n var distance2Sq = distanceSq(f1x2, f1y2, f2x2, f2y2);\n var factorSq = distance2Sq / distance1Sq;\n var distThreshold = 150;\n var distThresholdSq = distThreshold * distThreshold;\n var factorThreshold = 1.5;\n var factorThresholdSq = factorThreshold * factorThreshold;\n\n // cancel ctx gestures if the distance b/t the fingers increases\n if (factorSq >= factorThresholdSq || distance2Sq >= distThresholdSq) {\n r.touchData.cxt = false;\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n var cxtEvt = {\n originalEvent: e,\n type: 'cxttapend',\n position: {\n x: now[0],\n y: now[1]\n }\n };\n if (r.touchData.start) {\n r.touchData.start.unactivate().emit(cxtEvt);\n r.touchData.start = null;\n } else {\n cy.emit(cxtEvt);\n }\n }\n }\n\n // context swipe\n if (capture && r.touchData.cxt) {\n var cxtEvt = {\n originalEvent: e,\n type: 'cxtdrag',\n position: {\n x: now[0],\n y: now[1]\n }\n };\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n if (r.touchData.start) {\n r.touchData.start.emit(cxtEvt);\n } else {\n cy.emit(cxtEvt);\n }\n if (r.touchData.start) {\n r.touchData.start._private.grabbed = false;\n }\n r.touchData.cxtDragged = true;\n var near = r.findNearestElement(now[0], now[1], true, true);\n if (!r.touchData.cxtOver || near !== r.touchData.cxtOver) {\n if (r.touchData.cxtOver) {\n r.touchData.cxtOver.emit({\n originalEvent: e,\n type: 'cxtdragout',\n position: {\n x: now[0],\n y: now[1]\n }\n });\n }\n r.touchData.cxtOver = near;\n if (near) {\n near.emit({\n originalEvent: e,\n type: 'cxtdragover',\n position: {\n x: now[0],\n y: now[1]\n }\n });\n }\n }\n\n // box selection\n } else if (capture && e.touches[2] && cy.boxSelectionEnabled()) {\n e.preventDefault();\n r.data.bgActivePosistion = undefined;\n this.lastThreeTouch = +new Date();\n if (!r.touchData.selecting) {\n cy.emit({\n originalEvent: e,\n type: 'boxstart',\n position: {\n x: now[0],\n y: now[1]\n }\n });\n }\n r.touchData.selecting = true;\n r.touchData.didSelect = true;\n select[4] = 1;\n if (!select || select.length === 0 || select[0] === undefined) {\n select[0] = (now[0] + now[2] + now[4]) / 3;\n select[1] = (now[1] + now[3] + now[5]) / 3;\n select[2] = (now[0] + now[2] + now[4]) / 3 + 1;\n select[3] = (now[1] + now[3] + now[5]) / 3 + 1;\n } else {\n select[2] = (now[0] + now[2] + now[4]) / 3;\n select[3] = (now[1] + now[3] + now[5]) / 3;\n }\n r.redrawHint('select', true);\n r.redraw();\n\n // pinch to zoom\n } else if (capture && e.touches[1] && !r.touchData.didSelect // don't allow box selection to degrade to pinch-to-zoom\n && cy.zoomingEnabled() && cy.panningEnabled() && cy.userZoomingEnabled() && cy.userPanningEnabled()) {\n // two fingers => pinch to zoom\n e.preventDefault();\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n var draggedEles = r.dragData.touchDragEles;\n if (draggedEles) {\n r.redrawHint('drag', true);\n for (var i = 0; i < draggedEles.length; i++) {\n var de_p = draggedEles[i]._private;\n de_p.grabbed = false;\n de_p.rscratch.inDragLayer = false;\n }\n }\n var _start = r.touchData.start;\n\n // (x2, y2) for fingers 1 and 2\n var f1x2 = e.touches[0].clientX - offsetLeft,\n f1y2 = e.touches[0].clientY - offsetTop;\n var f2x2 = e.touches[1].clientX - offsetLeft,\n f2y2 = e.touches[1].clientY - offsetTop;\n var distance2 = distance(f1x2, f1y2, f2x2, f2y2);\n // var distance2Sq = distanceSq( f1x2, f1y2, f2x2, f2y2 );\n // var factor = Math.sqrt( distance2Sq ) / Math.sqrt( distance1Sq );\n var factor = distance2 / distance1;\n if (twoFingersStartInside) {\n // delta finger1\n var df1x = f1x2 - f1x1;\n var df1y = f1y2 - f1y1;\n\n // delta finger 2\n var df2x = f2x2 - f2x1;\n var df2y = f2y2 - f2y1;\n\n // translation is the normalised vector of the two fingers movement\n // i.e. so pinching cancels out and moving together pans\n var tx = (df1x + df2x) / 2;\n var ty = (df1y + df2y) / 2;\n\n // now calculate the zoom\n var zoom1 = cy.zoom();\n var zoom2 = zoom1 * factor;\n var pan1 = cy.pan();\n\n // the model center point converted to the current rendered pos\n var ctrx = modelCenter1[0] * zoom1 + pan1.x;\n var ctry = modelCenter1[1] * zoom1 + pan1.y;\n var pan2 = {\n x: -zoom2 / zoom1 * (ctrx - pan1.x - tx) + ctrx,\n y: -zoom2 / zoom1 * (ctry - pan1.y - ty) + ctry\n };\n\n // remove dragged eles\n if (_start && _start.active()) {\n var draggedEles = r.dragData.touchDragEles;\n freeDraggedElements(draggedEles);\n r.redrawHint('drag', true);\n r.redrawHint('eles', true);\n _start.unactivate().emit('freeon');\n draggedEles.emit('free');\n if (r.dragData.didDrag) {\n _start.emit('dragfreeon');\n draggedEles.emit('dragfree');\n }\n }\n cy.viewport({\n zoom: zoom2,\n pan: pan2,\n cancelOnFailedZoom: true\n });\n cy.emit('pinchzoom');\n distance1 = distance2;\n f1x1 = f1x2;\n f1y1 = f1y2;\n f2x1 = f2x2;\n f2y1 = f2y2;\n r.pinching = true;\n }\n\n // Re-project\n if (e.touches[0]) {\n var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);\n now[0] = pos[0];\n now[1] = pos[1];\n }\n if (e.touches[1]) {\n var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);\n now[2] = pos[0];\n now[3] = pos[1];\n }\n if (e.touches[2]) {\n var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);\n now[4] = pos[0];\n now[5] = pos[1];\n }\n } else if (e.touches[0] && !r.touchData.didSelect // don't allow box selection to degrade to single finger events like panning\n ) {\n var start = r.touchData.start;\n var last = r.touchData.last;\n var near;\n if (!r.hoverData.draggingEles && !r.swipePanning) {\n near = r.findNearestElement(now[0], now[1], true, true);\n }\n if (capture && start != null) {\n e.preventDefault();\n }\n\n // dragging nodes\n if (capture && start != null && r.nodeIsDraggable(start)) {\n if (isOverThresholdDrag) {\n // then dragging can happen\n var draggedEles = r.dragData.touchDragEles;\n var justStartedDrag = !r.dragData.didDrag;\n if (justStartedDrag) {\n addNodesToDrag(draggedEles, {\n inDragLayer: true\n });\n }\n r.dragData.didDrag = true;\n var totalShift = {\n x: 0,\n y: 0\n };\n if (number$1(disp[0]) && number$1(disp[1])) {\n totalShift.x += disp[0];\n totalShift.y += disp[1];\n if (justStartedDrag) {\n r.redrawHint('eles', true);\n var dragDelta = r.touchData.dragDelta;\n if (dragDelta && number$1(dragDelta[0]) && number$1(dragDelta[1])) {\n totalShift.x += dragDelta[0];\n totalShift.y += dragDelta[1];\n }\n }\n }\n r.hoverData.draggingEles = true;\n draggedEles.silentShift(totalShift).emit('position drag');\n r.redrawHint('drag', true);\n if (r.touchData.startPosition[0] == earlier[0] && r.touchData.startPosition[1] == earlier[1]) {\n r.redrawHint('eles', true);\n }\n r.redraw();\n } else {\n // otherwise keep track of drag delta for later\n var dragDelta = r.touchData.dragDelta = r.touchData.dragDelta || [];\n if (dragDelta.length === 0) {\n dragDelta.push(disp[0]);\n dragDelta.push(disp[1]);\n } else {\n dragDelta[0] += disp[0];\n dragDelta[1] += disp[1];\n }\n }\n }\n\n // touchmove\n {\n triggerEvents(start || near, ['touchmove', 'tapdrag', 'vmousemove'], e, {\n x: now[0],\n y: now[1]\n });\n if ((!start || !start.grabbed()) && near != last) {\n if (last) {\n last.emit({\n originalEvent: e,\n type: 'tapdragout',\n position: {\n x: now[0],\n y: now[1]\n }\n });\n }\n if (near) {\n near.emit({\n originalEvent: e,\n type: 'tapdragover',\n position: {\n x: now[0],\n y: now[1]\n }\n });\n }\n }\n r.touchData.last = near;\n }\n\n // check to cancel taphold\n if (capture) {\n for (var i = 0; i < now.length; i++) {\n if (now[i] && r.touchData.startPosition[i] && isOverThresholdDrag) {\n r.touchData.singleTouchMoved = true;\n }\n }\n }\n\n // panning\n if (capture && (start == null || start.pannable()) && cy.panningEnabled() && cy.userPanningEnabled()) {\n var allowPassthrough = allowPanningPassthrough(start, r.touchData.starts);\n if (allowPassthrough) {\n e.preventDefault();\n if (!r.data.bgActivePosistion) {\n r.data.bgActivePosistion = array2point(r.touchData.startPosition);\n }\n if (r.swipePanning) {\n cy.panBy({\n x: disp[0] * zoom,\n y: disp[1] * zoom\n });\n cy.emit('dragpan');\n } else if (isOverThresholdDrag) {\n r.swipePanning = true;\n cy.panBy({\n x: dx * zoom,\n y: dy * zoom\n });\n cy.emit('dragpan');\n if (start) {\n start.unactivate();\n r.redrawHint('select', true);\n r.touchData.start = null;\n }\n }\n }\n\n // Re-project\n var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);\n now[0] = pos[0];\n now[1] = pos[1];\n }\n }\n for (var j = 0; j < now.length; j++) {\n earlier[j] = now[j];\n }\n\n // the active bg indicator should be removed when making a swipe that is neither for dragging nodes or panning\n if (capture && e.touches.length > 0 && !r.hoverData.draggingEles && !r.swipePanning && r.data.bgActivePosistion != null) {\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n r.redraw();\n }\n }, false);\n var touchcancelHandler;\n r.registerBinding(containerWindow, 'touchcancel', touchcancelHandler = function touchcancelHandler(e) {\n // eslint-disable-line no-unused-vars\n var start = r.touchData.start;\n r.touchData.capture = false;\n if (start) {\n start.unactivate();\n }\n });\n var touchendHandler, didDoubleTouch, touchTimeout, prevTouchTimeStamp;\n r.registerBinding(containerWindow, 'touchend', touchendHandler = function touchendHandler(e) {\n // eslint-disable-line no-unused-vars\n var start = r.touchData.start;\n var capture = r.touchData.capture;\n if (capture) {\n if (e.touches.length === 0) {\n r.touchData.capture = false;\n }\n e.preventDefault();\n } else {\n return;\n }\n var select = r.selection;\n r.swipePanning = false;\n r.hoverData.draggingEles = false;\n var cy = r.cy;\n var zoom = cy.zoom();\n var now = r.touchData.now;\n var earlier = r.touchData.earlier;\n if (e.touches[0]) {\n var pos = r.projectIntoViewport(e.touches[0].clientX, e.touches[0].clientY);\n now[0] = pos[0];\n now[1] = pos[1];\n }\n if (e.touches[1]) {\n var pos = r.projectIntoViewport(e.touches[1].clientX, e.touches[1].clientY);\n now[2] = pos[0];\n now[3] = pos[1];\n }\n if (e.touches[2]) {\n var pos = r.projectIntoViewport(e.touches[2].clientX, e.touches[2].clientY);\n now[4] = pos[0];\n now[5] = pos[1];\n }\n if (start) {\n start.unactivate();\n }\n var ctxTapend;\n if (r.touchData.cxt) {\n ctxTapend = {\n originalEvent: e,\n type: 'cxttapend',\n position: {\n x: now[0],\n y: now[1]\n }\n };\n if (start) {\n start.emit(ctxTapend);\n } else {\n cy.emit(ctxTapend);\n }\n if (!r.touchData.cxtDragged) {\n var ctxTap = {\n originalEvent: e,\n type: 'cxttap',\n position: {\n x: now[0],\n y: now[1]\n }\n };\n if (start) {\n start.emit(ctxTap);\n } else {\n cy.emit(ctxTap);\n }\n }\n if (r.touchData.start) {\n r.touchData.start._private.grabbed = false;\n }\n r.touchData.cxt = false;\n r.touchData.start = null;\n r.redraw();\n return;\n }\n\n // no more box selection if we don't have three fingers\n if (!e.touches[2] && cy.boxSelectionEnabled() && r.touchData.selecting) {\n r.touchData.selecting = false;\n var box = cy.collection(r.getAllInBox(select[0], select[1], select[2], select[3]));\n select[0] = undefined;\n select[1] = undefined;\n select[2] = undefined;\n select[3] = undefined;\n select[4] = 0;\n r.redrawHint('select', true);\n cy.emit({\n type: 'boxend',\n originalEvent: e,\n position: {\n x: now[0],\n y: now[1]\n }\n });\n var eleWouldBeSelected = function eleWouldBeSelected(ele) {\n return ele.selectable() && !ele.selected();\n };\n box.emit('box').stdFilter(eleWouldBeSelected).select().emit('boxselect');\n if (box.nonempty()) {\n r.redrawHint('eles', true);\n }\n r.redraw();\n }\n if (start != null) {\n start.unactivate();\n }\n if (e.touches[2]) {\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n } else if (e.touches[1]) ; else if (e.touches[0]) ; else if (!e.touches[0]) {\n r.data.bgActivePosistion = undefined;\n r.redrawHint('select', true);\n var draggedEles = r.dragData.touchDragEles;\n if (start != null) {\n var startWasGrabbed = start._private.grabbed;\n freeDraggedElements(draggedEles);\n r.redrawHint('drag', true);\n r.redrawHint('eles', true);\n if (startWasGrabbed) {\n start.emit('freeon');\n draggedEles.emit('free');\n if (r.dragData.didDrag) {\n start.emit('dragfreeon');\n draggedEles.emit('dragfree');\n }\n }\n triggerEvents(start, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, {\n x: now[0],\n y: now[1]\n });\n start.unactivate();\n r.touchData.start = null;\n } else {\n var near = r.findNearestElement(now[0], now[1], true, true);\n triggerEvents(near, ['touchend', 'tapend', 'vmouseup', 'tapdragout'], e, {\n x: now[0],\n y: now[1]\n });\n }\n var dx = r.touchData.startPosition[0] - now[0];\n var dx2 = dx * dx;\n var dy = r.touchData.startPosition[1] - now[1];\n var dy2 = dy * dy;\n var dist2 = dx2 + dy2;\n var rdist2 = dist2 * zoom * zoom;\n\n // Tap event, roughly same as mouse click event for touch\n if (!r.touchData.singleTouchMoved) {\n if (!start) {\n cy.$(':selected').unselect(['tapunselect']);\n }\n triggerEvents(start, ['tap', 'vclick'], e, {\n x: now[0],\n y: now[1]\n });\n didDoubleTouch = false;\n if (e.timeStamp - prevTouchTimeStamp <= cy.multiClickDebounceTime()) {\n touchTimeout && clearTimeout(touchTimeout);\n didDoubleTouch = true;\n prevTouchTimeStamp = null;\n triggerEvents(start, ['dbltap', 'vdblclick'], e, {\n x: now[0],\n y: now[1]\n });\n } else {\n touchTimeout = setTimeout(function () {\n if (didDoubleTouch) return;\n triggerEvents(start, ['onetap', 'voneclick'], e, {\n x: now[0],\n y: now[1]\n });\n }, cy.multiClickDebounceTime());\n prevTouchTimeStamp = e.timeStamp;\n }\n }\n\n // Prepare to select the currently touched node, only if it hasn't been dragged past a certain distance\n if (start != null && !r.dragData.didDrag // didn't drag nodes around\n && start._private.selectable && rdist2 < r.touchTapThreshold2 && !r.pinching // pinch to zoom should not affect selection\n ) {\n if (cy.selectionType() === 'single') {\n cy.$(isSelected).unmerge(start).unselect(['tapunselect']);\n start.select(['tapselect']);\n } else {\n if (start.selected()) {\n start.unselect(['tapunselect']);\n } else {\n start.select(['tapselect']);\n }\n }\n r.redrawHint('eles', true);\n }\n r.touchData.singleTouchMoved = true;\n }\n for (var j = 0; j < now.length; j++) {\n earlier[j] = now[j];\n }\n r.dragData.didDrag = false; // reset for next touchstart\n\n if (e.touches.length === 0) {\n r.touchData.dragDelta = [];\n r.touchData.startPosition = [null, null, null, null, null, null];\n r.touchData.startGPosition = null;\n r.touchData.didSelect = false;\n }\n if (e.touches.length < 2) {\n if (e.touches.length === 1) {\n // the old start global pos'n may not be the same finger that remains\n r.touchData.startGPosition = [e.touches[0].clientX, e.touches[0].clientY];\n }\n r.pinching = false;\n r.redrawHint('eles', true);\n r.redraw();\n }\n\n //r.redraw();\n }, false);\n\n // fallback compatibility layer for ms pointer events\n if (typeof TouchEvent === 'undefined') {\n var pointers = [];\n var makeTouch = function makeTouch(e) {\n return {\n clientX: e.clientX,\n clientY: e.clientY,\n force: 1,\n identifier: e.pointerId,\n pageX: e.pageX,\n pageY: e.pageY,\n radiusX: e.width / 2,\n radiusY: e.height / 2,\n screenX: e.screenX,\n screenY: e.screenY,\n target: e.target\n };\n };\n var makePointer = function makePointer(e) {\n return {\n event: e,\n touch: makeTouch(e)\n };\n };\n var addPointer = function addPointer(e) {\n pointers.push(makePointer(e));\n };\n var removePointer = function removePointer(e) {\n for (var i = 0; i < pointers.length; i++) {\n var p = pointers[i];\n if (p.event.pointerId === e.pointerId) {\n pointers.splice(i, 1);\n return;\n }\n }\n };\n var updatePointer = function updatePointer(e) {\n var p = pointers.filter(function (p) {\n return p.event.pointerId === e.pointerId;\n })[0];\n p.event = e;\n p.touch = makeTouch(e);\n };\n var addTouchesToEvent = function addTouchesToEvent(e) {\n e.touches = pointers.map(function (p) {\n return p.touch;\n });\n };\n var pointerIsMouse = function pointerIsMouse(e) {\n return e.pointerType === 'mouse' || e.pointerType === 4;\n };\n r.registerBinding(r.container, 'pointerdown', function (e) {\n if (pointerIsMouse(e)) {\n return;\n } // mouse already handled\n\n e.preventDefault();\n addPointer(e);\n addTouchesToEvent(e);\n touchstartHandler(e);\n });\n r.registerBinding(r.container, 'pointerup', function (e) {\n if (pointerIsMouse(e)) {\n return;\n } // mouse already handled\n\n removePointer(e);\n addTouchesToEvent(e);\n touchendHandler(e);\n });\n r.registerBinding(r.container, 'pointercancel', function (e) {\n if (pointerIsMouse(e)) {\n return;\n } // mouse already handled\n\n removePointer(e);\n addTouchesToEvent(e);\n touchcancelHandler(e);\n });\n r.registerBinding(r.container, 'pointermove', function (e) {\n if (pointerIsMouse(e)) {\n return;\n } // mouse already handled\n\n e.preventDefault();\n updatePointer(e);\n addTouchesToEvent(e);\n touchmoveHandler(e);\n });\n }\n};\n\nvar BRp$2 = {};\nBRp$2.generatePolygon = function (name, points) {\n return this.nodeShapes[name] = {\n renderer: this,\n name: name,\n points: points,\n draw: function draw(context, centerX, centerY, width, height, cornerRadius) {\n this.renderer.nodeShapeImpl('polygon', context, centerX, centerY, width, height, this.points);\n },\n intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding, cornerRadius) {\n return polygonIntersectLine(x, y, this.points, nodeX, nodeY, width / 2, height / 2, padding);\n },\n checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY, cornerRadius) {\n return pointInsidePolygon(x, y, this.points, centerX, centerY, width, height, [0, -1], padding);\n }\n };\n};\nBRp$2.generateEllipse = function () {\n return this.nodeShapes['ellipse'] = {\n renderer: this,\n name: 'ellipse',\n draw: function draw(context, centerX, centerY, width, height, cornerRadius) {\n this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);\n },\n intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding, cornerRadius) {\n return intersectLineEllipse(x, y, nodeX, nodeY, width / 2 + padding, height / 2 + padding);\n },\n checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY, cornerRadius) {\n return checkInEllipse(x, y, width, height, centerX, centerY, padding);\n }\n };\n};\nBRp$2.generateRoundPolygon = function (name, points) {\n return this.nodeShapes[name] = {\n renderer: this,\n name: name,\n points: points,\n getOrCreateCorners: function getOrCreateCorners(centerX, centerY, width, height, cornerRadius, rs, field) {\n if (rs[field] !== undefined && rs[field + '-cx'] === centerX && rs[field + '-cy'] === centerY) {\n return rs[field];\n }\n rs[field] = new Array(points.length / 2);\n rs[field + '-cx'] = centerX;\n rs[field + '-cy'] = centerY;\n var halfW = width / 2;\n var halfH = height / 2;\n cornerRadius = cornerRadius === 'auto' ? getRoundPolygonRadius(width, height) : cornerRadius;\n var p = new Array(points.length / 2);\n for (var _i = 0; _i < points.length / 2; _i++) {\n p[_i] = {\n x: centerX + halfW * points[_i * 2],\n y: centerY + halfH * points[_i * 2 + 1]\n };\n }\n var i,\n p1,\n p2,\n p3,\n len = p.length;\n p1 = p[len - 1];\n // for each point\n for (i = 0; i < len; i++) {\n p2 = p[i % len];\n p3 = p[(i + 1) % len];\n rs[field][i] = getRoundCorner(p1, p2, p3, cornerRadius);\n p1 = p2;\n p2 = p3;\n }\n return rs[field];\n },\n draw: function draw(context, centerX, centerY, width, height, cornerRadius, rs) {\n this.renderer.nodeShapeImpl('round-polygon', context, centerX, centerY, width, height, this.points, this.getOrCreateCorners(centerX, centerY, width, height, cornerRadius, rs, 'drawCorners'));\n },\n intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding, cornerRadius, rs) {\n return roundPolygonIntersectLine(x, y, this.points, nodeX, nodeY, width, height, padding, this.getOrCreateCorners(nodeX, nodeY, width, height, cornerRadius, rs, 'corners'));\n },\n checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY, cornerRadius, rs) {\n return pointInsideRoundPolygon(x, y, this.points, centerX, centerY, width, height, this.getOrCreateCorners(centerX, centerY, width, height, cornerRadius, rs, 'corners'));\n }\n };\n};\nBRp$2.generateRoundRectangle = function () {\n return this.nodeShapes['round-rectangle'] = this.nodeShapes['roundrectangle'] = {\n renderer: this,\n name: 'round-rectangle',\n points: generateUnitNgonPointsFitToSquare(4, 0),\n draw: function draw(context, centerX, centerY, width, height, cornerRadius) {\n this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height, this.points, cornerRadius);\n },\n intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding, cornerRadius) {\n return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding, cornerRadius);\n },\n checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY, cornerRadius) {\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n cornerRadius = cornerRadius === 'auto' ? getRoundRectangleRadius(width, height) : cornerRadius;\n cornerRadius = Math.min(halfWidth, halfHeight, cornerRadius);\n var diam = cornerRadius * 2;\n\n // Check hBox\n if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) {\n return true;\n }\n\n // Check vBox\n if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) {\n return true;\n }\n\n // Check top left quarter circle\n if (checkInEllipse(x, y, diam, diam, centerX - halfWidth + cornerRadius, centerY - halfHeight + cornerRadius, padding)) {\n return true;\n }\n\n // Check top right quarter circle\n if (checkInEllipse(x, y, diam, diam, centerX + halfWidth - cornerRadius, centerY - halfHeight + cornerRadius, padding)) {\n return true;\n }\n\n // Check bottom right quarter circle\n if (checkInEllipse(x, y, diam, diam, centerX + halfWidth - cornerRadius, centerY + halfHeight - cornerRadius, padding)) {\n return true;\n }\n\n // Check bottom left quarter circle\n if (checkInEllipse(x, y, diam, diam, centerX - halfWidth + cornerRadius, centerY + halfHeight - cornerRadius, padding)) {\n return true;\n }\n return false;\n }\n };\n};\nBRp$2.generateCutRectangle = function () {\n return this.nodeShapes['cut-rectangle'] = this.nodeShapes['cutrectangle'] = {\n renderer: this,\n name: 'cut-rectangle',\n cornerLength: getCutRectangleCornerLength(),\n points: generateUnitNgonPointsFitToSquare(4, 0),\n draw: function draw(context, centerX, centerY, width, height, cornerRadius) {\n this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height, null, cornerRadius);\n },\n generateCutTrianglePts: function generateCutTrianglePts(width, height, centerX, centerY, cornerRadius) {\n var cl = cornerRadius === 'auto' ? this.cornerLength : cornerRadius;\n var hh = height / 2;\n var hw = width / 2;\n var xBegin = centerX - hw;\n var xEnd = centerX + hw;\n var yBegin = centerY - hh;\n var yEnd = centerY + hh;\n\n // points are in clockwise order, inner (imaginary) triangle pt on [4, 5]\n return {\n topLeft: [xBegin, yBegin + cl, xBegin + cl, yBegin, xBegin + cl, yBegin + cl],\n topRight: [xEnd - cl, yBegin, xEnd, yBegin + cl, xEnd - cl, yBegin + cl],\n bottomRight: [xEnd, yEnd - cl, xEnd - cl, yEnd, xEnd - cl, yEnd - cl],\n bottomLeft: [xBegin + cl, yEnd, xBegin, yEnd - cl, xBegin + cl, yEnd - cl]\n };\n },\n intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding, cornerRadius) {\n var cPts = this.generateCutTrianglePts(width + 2 * padding, height + 2 * padding, nodeX, nodeY, cornerRadius);\n var pts = [].concat.apply([], [cPts.topLeft.splice(0, 4), cPts.topRight.splice(0, 4), cPts.bottomRight.splice(0, 4), cPts.bottomLeft.splice(0, 4)]);\n return polygonIntersectLine(x, y, pts, nodeX, nodeY);\n },\n checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY, cornerRadius) {\n var cl = cornerRadius === 'auto' ? this.cornerLength : cornerRadius;\n // Check hBox\n if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * cl, [0, -1], padding)) {\n return true;\n }\n\n // Check vBox\n if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * cl, height, [0, -1], padding)) {\n return true;\n }\n var cutTrianglePts = this.generateCutTrianglePts(width, height, centerX, centerY);\n return pointInsidePolygonPoints(x, y, cutTrianglePts.topLeft) || pointInsidePolygonPoints(x, y, cutTrianglePts.topRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomRight) || pointInsidePolygonPoints(x, y, cutTrianglePts.bottomLeft);\n }\n };\n};\nBRp$2.generateBarrel = function () {\n return this.nodeShapes['barrel'] = {\n renderer: this,\n name: 'barrel',\n points: generateUnitNgonPointsFitToSquare(4, 0),\n draw: function draw(context, centerX, centerY, width, height, cornerRadius) {\n this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height);\n },\n intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding, cornerRadius) {\n // use two fixed t values for the bezier curve approximation\n\n var t0 = 0.15;\n var t1 = 0.5;\n var t2 = 0.85;\n var bPts = this.generateBarrelBezierPts(width + 2 * padding, height + 2 * padding, nodeX, nodeY);\n var approximateBarrelCurvePts = function approximateBarrelCurvePts(pts) {\n // approximate curve pts based on the two t values\n var m0 = qbezierPtAt({\n x: pts[0],\n y: pts[1]\n }, {\n x: pts[2],\n y: pts[3]\n }, {\n x: pts[4],\n y: pts[5]\n }, t0);\n var m1 = qbezierPtAt({\n x: pts[0],\n y: pts[1]\n }, {\n x: pts[2],\n y: pts[3]\n }, {\n x: pts[4],\n y: pts[5]\n }, t1);\n var m2 = qbezierPtAt({\n x: pts[0],\n y: pts[1]\n }, {\n x: pts[2],\n y: pts[3]\n }, {\n x: pts[4],\n y: pts[5]\n }, t2);\n return [pts[0], pts[1], m0.x, m0.y, m1.x, m1.y, m2.x, m2.y, pts[4], pts[5]];\n };\n var pts = [].concat(approximateBarrelCurvePts(bPts.topLeft), approximateBarrelCurvePts(bPts.topRight), approximateBarrelCurvePts(bPts.bottomRight), approximateBarrelCurvePts(bPts.bottomLeft));\n return polygonIntersectLine(x, y, pts, nodeX, nodeY);\n },\n generateBarrelBezierPts: function generateBarrelBezierPts(width, height, centerX, centerY) {\n var hh = height / 2;\n var hw = width / 2;\n var xBegin = centerX - hw;\n var xEnd = centerX + hw;\n var yBegin = centerY - hh;\n var yEnd = centerY + hh;\n var curveConstants = getBarrelCurveConstants(width, height);\n var hOffset = curveConstants.heightOffset;\n var wOffset = curveConstants.widthOffset;\n var ctrlPtXOffset = curveConstants.ctrlPtOffsetPct * width;\n\n // points are in clockwise order, inner (imaginary) control pt on [4, 5]\n var pts = {\n topLeft: [xBegin, yBegin + hOffset, xBegin + ctrlPtXOffset, yBegin, xBegin + wOffset, yBegin],\n topRight: [xEnd - wOffset, yBegin, xEnd - ctrlPtXOffset, yBegin, xEnd, yBegin + hOffset],\n bottomRight: [xEnd, yEnd - hOffset, xEnd - ctrlPtXOffset, yEnd, xEnd - wOffset, yEnd],\n bottomLeft: [xBegin + wOffset, yEnd, xBegin + ctrlPtXOffset, yEnd, xBegin, yEnd - hOffset]\n };\n pts.topLeft.isTop = true;\n pts.topRight.isTop = true;\n pts.bottomLeft.isBottom = true;\n pts.bottomRight.isBottom = true;\n return pts;\n },\n checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY, cornerRadius) {\n var curveConstants = getBarrelCurveConstants(width, height);\n var hOffset = curveConstants.heightOffset;\n var wOffset = curveConstants.widthOffset;\n\n // Check hBox\n if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - 2 * hOffset, [0, -1], padding)) {\n return true;\n }\n\n // Check vBox\n if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - 2 * wOffset, height, [0, -1], padding)) {\n return true;\n }\n var barrelCurvePts = this.generateBarrelBezierPts(width, height, centerX, centerY);\n var getCurveT = function getCurveT(x, y, curvePts) {\n var x0 = curvePts[4];\n var x1 = curvePts[2];\n var x2 = curvePts[0];\n var y0 = curvePts[5];\n // var y1 = curvePts[ 3 ];\n var y2 = curvePts[1];\n var xMin = Math.min(x0, x2);\n var xMax = Math.max(x0, x2);\n var yMin = Math.min(y0, y2);\n var yMax = Math.max(y0, y2);\n if (xMin <= x && x <= xMax && yMin <= y && y <= yMax) {\n var coeff = bezierPtsToQuadCoeff(x0, x1, x2);\n var roots = solveQuadratic(coeff[0], coeff[1], coeff[2], x);\n var validRoots = roots.filter(function (r) {\n return 0 <= r && r <= 1;\n });\n if (validRoots.length > 0) {\n return validRoots[0];\n }\n }\n return null;\n };\n var curveRegions = Object.keys(barrelCurvePts);\n for (var i = 0; i < curveRegions.length; i++) {\n var corner = curveRegions[i];\n var cornerPts = barrelCurvePts[corner];\n var t = getCurveT(x, y, cornerPts);\n if (t == null) {\n continue;\n }\n var y0 = cornerPts[5];\n var y1 = cornerPts[3];\n var y2 = cornerPts[1];\n var bezY = qbezierAt(y0, y1, y2, t);\n if (cornerPts.isTop && bezY <= y) {\n return true;\n }\n if (cornerPts.isBottom && y <= bezY) {\n return true;\n }\n }\n return false;\n }\n };\n};\nBRp$2.generateBottomRoundrectangle = function () {\n return this.nodeShapes['bottom-round-rectangle'] = this.nodeShapes['bottomroundrectangle'] = {\n renderer: this,\n name: 'bottom-round-rectangle',\n points: generateUnitNgonPointsFitToSquare(4, 0),\n draw: function draw(context, centerX, centerY, width, height, cornerRadius) {\n this.renderer.nodeShapeImpl(this.name, context, centerX, centerY, width, height, this.points, cornerRadius);\n },\n intersectLine: function intersectLine(nodeX, nodeY, width, height, x, y, padding, cornerRadius) {\n var topStartX = nodeX - (width / 2 + padding);\n var topStartY = nodeY - (height / 2 + padding);\n var topEndY = topStartY;\n var topEndX = nodeX + (width / 2 + padding);\n var topIntersections = finiteLinesIntersect(x, y, nodeX, nodeY, topStartX, topStartY, topEndX, topEndY, false);\n if (topIntersections.length > 0) {\n return topIntersections;\n }\n return roundRectangleIntersectLine(x, y, nodeX, nodeY, width, height, padding, cornerRadius);\n },\n checkPoint: function checkPoint(x, y, padding, width, height, centerX, centerY, cornerRadius) {\n cornerRadius = cornerRadius === 'auto' ? getRoundRectangleRadius(width, height) : cornerRadius;\n var diam = 2 * cornerRadius;\n\n // Check hBox\n if (pointInsidePolygon(x, y, this.points, centerX, centerY, width, height - diam, [0, -1], padding)) {\n return true;\n }\n\n // Check vBox\n if (pointInsidePolygon(x, y, this.points, centerX, centerY, width - diam, height, [0, -1], padding)) {\n return true;\n }\n\n // check non-rounded top side\n var outerWidth = width / 2 + 2 * padding;\n var outerHeight = height / 2 + 2 * padding;\n var points = [centerX - outerWidth, centerY - outerHeight, centerX - outerWidth, centerY, centerX + outerWidth, centerY, centerX + outerWidth, centerY - outerHeight];\n if (pointInsidePolygonPoints(x, y, points)) {\n return true;\n }\n\n // Check bottom right quarter circle\n if (checkInEllipse(x, y, diam, diam, centerX + width / 2 - cornerRadius, centerY + height / 2 - cornerRadius, padding)) {\n return true;\n }\n\n // Check bottom left quarter circle\n if (checkInEllipse(x, y, diam, diam, centerX - width / 2 + cornerRadius, centerY + height / 2 - cornerRadius, padding)) {\n return true;\n }\n return false;\n }\n };\n};\nBRp$2.registerNodeShapes = function () {\n var nodeShapes = this.nodeShapes = {};\n var renderer = this;\n this.generateEllipse();\n this.generatePolygon('triangle', generateUnitNgonPointsFitToSquare(3, 0));\n this.generateRoundPolygon('round-triangle', generateUnitNgonPointsFitToSquare(3, 0));\n this.generatePolygon('rectangle', generateUnitNgonPointsFitToSquare(4, 0));\n nodeShapes['square'] = nodeShapes['rectangle'];\n this.generateRoundRectangle();\n this.generateCutRectangle();\n this.generateBarrel();\n this.generateBottomRoundrectangle();\n {\n var diamondPoints = [0, 1, 1, 0, 0, -1, -1, 0];\n this.generatePolygon('diamond', diamondPoints);\n this.generateRoundPolygon('round-diamond', diamondPoints);\n }\n this.generatePolygon('pentagon', generateUnitNgonPointsFitToSquare(5, 0));\n this.generateRoundPolygon('round-pentagon', generateUnitNgonPointsFitToSquare(5, 0));\n this.generatePolygon('hexagon', generateUnitNgonPointsFitToSquare(6, 0));\n this.generateRoundPolygon('round-hexagon', generateUnitNgonPointsFitToSquare(6, 0));\n this.generatePolygon('heptagon', generateUnitNgonPointsFitToSquare(7, 0));\n this.generateRoundPolygon('round-heptagon', generateUnitNgonPointsFitToSquare(7, 0));\n this.generatePolygon('octagon', generateUnitNgonPointsFitToSquare(8, 0));\n this.generateRoundPolygon('round-octagon', generateUnitNgonPointsFitToSquare(8, 0));\n var star5Points = new Array(20);\n {\n var outerPoints = generateUnitNgonPoints(5, 0);\n var innerPoints = generateUnitNgonPoints(5, Math.PI / 5);\n\n // Outer radius is 1; inner radius of star is smaller\n var innerRadius = 0.5 * (3 - Math.sqrt(5));\n innerRadius *= 1.57;\n for (var i = 0; i < innerPoints.length / 2; i++) {\n innerPoints[i * 2] *= innerRadius;\n innerPoints[i * 2 + 1] *= innerRadius;\n }\n for (var i = 0; i < 20 / 4; i++) {\n star5Points[i * 4] = outerPoints[i * 2];\n star5Points[i * 4 + 1] = outerPoints[i * 2 + 1];\n star5Points[i * 4 + 2] = innerPoints[i * 2];\n star5Points[i * 4 + 3] = innerPoints[i * 2 + 1];\n }\n }\n star5Points = fitPolygonToSquare(star5Points);\n this.generatePolygon('star', star5Points);\n this.generatePolygon('vee', [-1, -1, 0, -0.333, 1, -1, 0, 1]);\n this.generatePolygon('rhomboid', [-1, -1, 0.333, -1, 1, 1, -0.333, 1]);\n this.generatePolygon('right-rhomboid', [-0.333, -1, 1, -1, 0.333, 1, -1, 1]);\n this.nodeShapes['concavehexagon'] = this.generatePolygon('concave-hexagon', [-1, -0.95, -0.75, 0, -1, 0.95, 1, 0.95, 0.75, 0, 1, -0.95]);\n {\n var tagPoints = [-1, -1, 0.25, -1, 1, 0, 0.25, 1, -1, 1];\n this.generatePolygon('tag', tagPoints);\n this.generateRoundPolygon('round-tag', tagPoints);\n }\n nodeShapes.makePolygon = function (points) {\n // use caching on user-specified polygons so they are as fast as native shapes\n\n var key = points.join('$');\n var name = 'polygon-' + key;\n var shape;\n if (shape = this[name]) {\n // got cached shape\n return shape;\n }\n\n // create and cache new shape\n return renderer.generatePolygon(name, points);\n };\n};\n\nvar BRp$1 = {};\nBRp$1.timeToRender = function () {\n return this.redrawTotalTime / this.redrawCount;\n};\nBRp$1.redraw = function (options) {\n options = options || staticEmptyObject();\n var r = this;\n if (r.averageRedrawTime === undefined) {\n r.averageRedrawTime = 0;\n }\n if (r.lastRedrawTime === undefined) {\n r.lastRedrawTime = 0;\n }\n if (r.lastDrawTime === undefined) {\n r.lastDrawTime = 0;\n }\n r.requestedFrame = true;\n r.renderOptions = options;\n};\nBRp$1.beforeRender = function (fn, priority) {\n // the renderer can't add tick callbacks when destroyed\n if (this.destroyed) {\n return;\n }\n if (priority == null) {\n error('Priority is not optional for beforeRender');\n }\n var cbs = this.beforeRenderCallbacks;\n cbs.push({\n fn: fn,\n priority: priority\n });\n\n // higher priority callbacks executed first\n cbs.sort(function (a, b) {\n return b.priority - a.priority;\n });\n};\nvar beforeRenderCallbacks = function beforeRenderCallbacks(r, willDraw, startTime) {\n var cbs = r.beforeRenderCallbacks;\n for (var i = 0; i < cbs.length; i++) {\n cbs[i].fn(willDraw, startTime);\n }\n};\nBRp$1.startRenderLoop = function () {\n var r = this;\n var cy = r.cy;\n if (r.renderLoopStarted) {\n return;\n } else {\n r.renderLoopStarted = true;\n }\n var renderFn = function renderFn(requestTime) {\n if (r.destroyed) {\n return;\n }\n if (cy.batching()) ; else if (r.requestedFrame && !r.skipFrame) {\n beforeRenderCallbacks(r, true, requestTime);\n var startTime = performanceNow();\n r.render(r.renderOptions);\n var endTime = r.lastDrawTime = performanceNow();\n if (r.averageRedrawTime === undefined) {\n r.averageRedrawTime = endTime - startTime;\n }\n if (r.redrawCount === undefined) {\n r.redrawCount = 0;\n }\n r.redrawCount++;\n if (r.redrawTotalTime === undefined) {\n r.redrawTotalTime = 0;\n }\n var duration = endTime - startTime;\n r.redrawTotalTime += duration;\n r.lastRedrawTime = duration;\n\n // use a weighted average with a bias from the previous average so we don't spike so easily\n r.averageRedrawTime = r.averageRedrawTime / 2 + duration / 2;\n r.requestedFrame = false;\n } else {\n beforeRenderCallbacks(r, false, requestTime);\n }\n r.skipFrame = false;\n requestAnimationFrame(renderFn);\n };\n requestAnimationFrame(renderFn);\n};\n\nvar BaseRenderer = function BaseRenderer(options) {\n this.init(options);\n};\nvar BR = BaseRenderer;\nvar BRp = BR.prototype;\nBRp.clientFunctions = ['redrawHint', 'render', 'renderTo', 'matchCanvasSize', 'nodeShapeImpl', 'arrowShapeImpl'];\nBRp.init = function (options) {\n var r = this;\n r.options = options;\n r.cy = options.cy;\n var ctr = r.container = options.cy.container();\n var containerWindow = r.cy.window();\n\n // prepend a stylesheet in the head such that\n if (containerWindow) {\n var document = containerWindow.document;\n var head = document.head;\n var stylesheetId = '__________cytoscape_stylesheet';\n var className = '__________cytoscape_container';\n var stylesheetAlreadyExists = document.getElementById(stylesheetId) != null;\n if (ctr.className.indexOf(className) < 0) {\n ctr.className = (ctr.className || '') + ' ' + className;\n }\n if (!stylesheetAlreadyExists) {\n var stylesheet = document.createElement('style');\n stylesheet.id = stylesheetId;\n stylesheet.textContent = '.' + className + ' { position: relative; }';\n head.insertBefore(stylesheet, head.children[0]); // first so lowest priority\n }\n\n var computedStyle = containerWindow.getComputedStyle(ctr);\n var position = computedStyle.getPropertyValue('position');\n if (position === 'static') {\n warn('A Cytoscape container has style position:static and so can not use UI extensions properly');\n }\n }\n r.selection = [undefined, undefined, undefined, undefined, 0]; // Coordinates for selection box, plus enabled flag\n\n r.bezierProjPcts = [0.05, 0.225, 0.4, 0.5, 0.6, 0.775, 0.95];\n\n //--Pointer-related data\n r.hoverData = {\n down: null,\n last: null,\n downTime: null,\n triggerMode: null,\n dragging: false,\n initialPan: [null, null],\n capture: false\n };\n r.dragData = {\n possibleDragElements: []\n };\n r.touchData = {\n start: null,\n capture: false,\n // These 3 fields related to tap, taphold events\n startPosition: [null, null, null, null, null, null],\n singleTouchStartTime: null,\n singleTouchMoved: true,\n now: [null, null, null, null, null, null],\n earlier: [null, null, null, null, null, null]\n };\n r.redraws = 0;\n r.showFps = options.showFps;\n r.debug = options.debug;\n r.hideEdgesOnViewport = options.hideEdgesOnViewport;\n r.textureOnViewport = options.textureOnViewport;\n r.wheelSensitivity = options.wheelSensitivity;\n r.motionBlurEnabled = options.motionBlur; // on by default\n r.forcedPixelRatio = number$1(options.pixelRatio) ? options.pixelRatio : null;\n r.motionBlur = options.motionBlur; // for initial kick off\n r.motionBlurOpacity = options.motionBlurOpacity;\n r.motionBlurTransparency = 1 - r.motionBlurOpacity;\n r.motionBlurPxRatio = 1;\n r.mbPxRBlurry = 1; //0.8;\n r.minMbLowQualFrames = 4;\n r.fullQualityMb = false;\n r.clearedForMotionBlur = [];\n r.desktopTapThreshold = options.desktopTapThreshold;\n r.desktopTapThreshold2 = options.desktopTapThreshold * options.desktopTapThreshold;\n r.touchTapThreshold = options.touchTapThreshold;\n r.touchTapThreshold2 = options.touchTapThreshold * options.touchTapThreshold;\n r.tapholdDuration = 500;\n r.bindings = [];\n r.beforeRenderCallbacks = [];\n r.beforeRenderPriorities = {\n // higher priority execs before lower one\n animations: 400,\n eleCalcs: 300,\n eleTxrDeq: 200,\n lyrTxrDeq: 150,\n lyrTxrSkip: 100\n };\n r.registerNodeShapes();\n r.registerArrowShapes();\n r.registerCalculationListeners();\n};\nBRp.notify = function (eventName, eles) {\n var r = this;\n var cy = r.cy;\n\n // the renderer can't be notified after it's destroyed\n if (this.destroyed) {\n return;\n }\n if (eventName === 'init') {\n r.load();\n return;\n }\n if (eventName === 'destroy') {\n r.destroy();\n return;\n }\n if (eventName === 'add' || eventName === 'remove' || eventName === 'move' && cy.hasCompoundNodes() || eventName === 'load' || eventName === 'zorder' || eventName === 'mount') {\n r.invalidateCachedZSortedEles();\n }\n if (eventName === 'viewport') {\n r.redrawHint('select', true);\n }\n if (eventName === 'load' || eventName === 'resize' || eventName === 'mount') {\n r.invalidateContainerClientCoordsCache();\n r.matchCanvasSize(r.container);\n }\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n this.startRenderLoop();\n this.redraw();\n};\nBRp.destroy = function () {\n var r = this;\n r.destroyed = true;\n r.cy.stopAnimationLoop();\n for (var i = 0; i < r.bindings.length; i++) {\n var binding = r.bindings[i];\n var b = binding;\n var tgt = b.target;\n (tgt.off || tgt.removeEventListener).apply(tgt, b.args);\n }\n r.bindings = [];\n r.beforeRenderCallbacks = [];\n r.onUpdateEleCalcsFns = [];\n if (r.removeObserver) {\n r.removeObserver.disconnect();\n }\n if (r.styleObserver) {\n r.styleObserver.disconnect();\n }\n if (r.resizeObserver) {\n r.resizeObserver.disconnect();\n }\n if (r.labelCalcDiv) {\n try {\n document.body.removeChild(r.labelCalcDiv); // eslint-disable-line no-undef\n } catch (e) {\n // ie10 issue #1014\n }\n }\n};\nBRp.isHeadless = function () {\n return false;\n};\n[BRp$f, BRp$5, BRp$4, BRp$3, BRp$2, BRp$1].forEach(function (props) {\n extend(BRp, props);\n});\n\nvar fullFpsTime = 1000 / 60; // assume 60 frames per second\n\nvar defs = {\n setupDequeueing: function setupDequeueing(opts) {\n return function setupDequeueingImpl() {\n var self = this;\n var r = this.renderer;\n if (self.dequeueingSetup) {\n return;\n } else {\n self.dequeueingSetup = true;\n }\n var queueRedraw = debounce_1(function () {\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n r.redraw();\n }, opts.deqRedrawThreshold);\n var dequeue = function dequeue(willDraw, frameStartTime) {\n var startTime = performanceNow();\n var avgRenderTime = r.averageRedrawTime;\n var renderTime = r.lastRedrawTime;\n var deqd = [];\n var extent = r.cy.extent();\n var pixelRatio = r.getPixelRatio();\n\n // if we aren't in a tick that causes a draw, then the rendered style\n // queue won't automatically be flushed before dequeueing starts\n if (!willDraw) {\n r.flushRenderedStyleQueue();\n }\n while (true) {\n // eslint-disable-line no-constant-condition\n var now = performanceNow();\n var duration = now - startTime;\n var frameDuration = now - frameStartTime;\n if (renderTime < fullFpsTime) {\n // if we're rendering faster than the ideal fps, then do dequeueing\n // during all of the remaining frame time\n\n var timeAvailable = fullFpsTime - (willDraw ? avgRenderTime : 0);\n if (frameDuration >= opts.deqFastCost * timeAvailable) {\n break;\n }\n } else {\n if (willDraw) {\n if (duration >= opts.deqCost * renderTime || duration >= opts.deqAvgCost * avgRenderTime) {\n break;\n }\n } else if (frameDuration >= opts.deqNoDrawCost * fullFpsTime) {\n break;\n }\n }\n var thisDeqd = opts.deq(self, pixelRatio, extent);\n if (thisDeqd.length > 0) {\n for (var i = 0; i < thisDeqd.length; i++) {\n deqd.push(thisDeqd[i]);\n }\n } else {\n break;\n }\n }\n\n // callbacks on dequeue\n if (deqd.length > 0) {\n opts.onDeqd(self, deqd);\n if (!willDraw && opts.shouldRedraw(self, deqd, pixelRatio, extent)) {\n queueRedraw();\n }\n }\n };\n var priority = opts.priority || noop$1;\n r.beforeRender(dequeue, priority(self));\n };\n }\n};\n\n// Allows lookups for (ele, lvl) => cache.\n// Uses keys so elements may share the same cache.\nvar ElementTextureCacheLookup = /*#__PURE__*/function () {\n function ElementTextureCacheLookup(getKey) {\n var doesEleInvalidateKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : falsify;\n _classCallCheck(this, ElementTextureCacheLookup);\n this.idsByKey = new Map$2();\n this.keyForId = new Map$2();\n this.cachesByLvl = new Map$2();\n this.lvls = [];\n this.getKey = getKey;\n this.doesEleInvalidateKey = doesEleInvalidateKey;\n }\n _createClass(ElementTextureCacheLookup, [{\n key: \"getIdsFor\",\n value: function getIdsFor(key) {\n if (key == null) {\n error(\"Can not get id list for null key\");\n }\n var idsByKey = this.idsByKey;\n var ids = this.idsByKey.get(key);\n if (!ids) {\n ids = new Set$1();\n idsByKey.set(key, ids);\n }\n return ids;\n }\n }, {\n key: \"addIdForKey\",\n value: function addIdForKey(key, id) {\n if (key != null) {\n this.getIdsFor(key).add(id);\n }\n }\n }, {\n key: \"deleteIdForKey\",\n value: function deleteIdForKey(key, id) {\n if (key != null) {\n this.getIdsFor(key)[\"delete\"](id);\n }\n }\n }, {\n key: \"getNumberOfIdsForKey\",\n value: function getNumberOfIdsForKey(key) {\n if (key == null) {\n return 0;\n } else {\n return this.getIdsFor(key).size;\n }\n }\n }, {\n key: \"updateKeyMappingFor\",\n value: function updateKeyMappingFor(ele) {\n var id = ele.id();\n var prevKey = this.keyForId.get(id);\n var currKey = this.getKey(ele);\n this.deleteIdForKey(prevKey, id);\n this.addIdForKey(currKey, id);\n this.keyForId.set(id, currKey);\n }\n }, {\n key: \"deleteKeyMappingFor\",\n value: function deleteKeyMappingFor(ele) {\n var id = ele.id();\n var prevKey = this.keyForId.get(id);\n this.deleteIdForKey(prevKey, id);\n this.keyForId[\"delete\"](id);\n }\n }, {\n key: \"keyHasChangedFor\",\n value: function keyHasChangedFor(ele) {\n var id = ele.id();\n var prevKey = this.keyForId.get(id);\n var newKey = this.getKey(ele);\n return prevKey !== newKey;\n }\n }, {\n key: \"isInvalid\",\n value: function isInvalid(ele) {\n return this.keyHasChangedFor(ele) || this.doesEleInvalidateKey(ele);\n }\n }, {\n key: \"getCachesAt\",\n value: function getCachesAt(lvl) {\n var cachesByLvl = this.cachesByLvl,\n lvls = this.lvls;\n var caches = cachesByLvl.get(lvl);\n if (!caches) {\n caches = new Map$2();\n cachesByLvl.set(lvl, caches);\n lvls.push(lvl);\n }\n return caches;\n }\n }, {\n key: \"getCache\",\n value: function getCache(key, lvl) {\n return this.getCachesAt(lvl).get(key);\n }\n }, {\n key: \"get\",\n value: function get(ele, lvl) {\n var key = this.getKey(ele);\n var cache = this.getCache(key, lvl);\n\n // getting for an element may need to add to the id list b/c eles can share keys\n if (cache != null) {\n this.updateKeyMappingFor(ele);\n }\n return cache;\n }\n }, {\n key: \"getForCachedKey\",\n value: function getForCachedKey(ele, lvl) {\n var key = this.keyForId.get(ele.id()); // n.b. use cached key, not newly computed key\n var cache = this.getCache(key, lvl);\n return cache;\n }\n }, {\n key: \"hasCache\",\n value: function hasCache(key, lvl) {\n return this.getCachesAt(lvl).has(key);\n }\n }, {\n key: \"has\",\n value: function has(ele, lvl) {\n var key = this.getKey(ele);\n return this.hasCache(key, lvl);\n }\n }, {\n key: \"setCache\",\n value: function setCache(key, lvl, cache) {\n cache.key = key;\n this.getCachesAt(lvl).set(key, cache);\n }\n }, {\n key: \"set\",\n value: function set(ele, lvl, cache) {\n var key = this.getKey(ele);\n this.setCache(key, lvl, cache);\n this.updateKeyMappingFor(ele);\n }\n }, {\n key: \"deleteCache\",\n value: function deleteCache(key, lvl) {\n this.getCachesAt(lvl)[\"delete\"](key);\n }\n }, {\n key: \"delete\",\n value: function _delete(ele, lvl) {\n var key = this.getKey(ele);\n this.deleteCache(key, lvl);\n }\n }, {\n key: \"invalidateKey\",\n value: function invalidateKey(key) {\n var _this = this;\n this.lvls.forEach(function (lvl) {\n return _this.deleteCache(key, lvl);\n });\n }\n\n // returns true if no other eles reference the invalidated cache (n.b. other eles may need the cache with the same key)\n }, {\n key: \"invalidate\",\n value: function invalidate(ele) {\n var id = ele.id();\n var key = this.keyForId.get(id); // n.b. use stored key rather than current (potential key)\n\n this.deleteKeyMappingFor(ele);\n var entireKeyInvalidated = this.doesEleInvalidateKey(ele);\n if (entireKeyInvalidated) {\n // clear mapping for current key\n this.invalidateKey(key);\n }\n return entireKeyInvalidated || this.getNumberOfIdsForKey(key) === 0;\n }\n }]);\n return ElementTextureCacheLookup;\n}();\n\nvar minTxrH = 25; // the size of the texture cache for small height eles (special case)\nvar txrStepH = 50; // the min size of the regular cache, and the size it increases with each step up\nvar minLvl$1 = -4; // when scaling smaller than that we don't need to re-render\nvar maxLvl$1 = 3; // when larger than this scale just render directly (caching is not helpful)\nvar maxZoom$1 = 7.99; // beyond this zoom level, layered textures are not used\nvar eleTxrSpacing = 8; // spacing between elements on textures to avoid blitting overlaps\nvar defTxrWidth = 1024; // default/minimum texture width\nvar maxTxrW = 1024; // the maximum width of a texture\nvar maxTxrH = 1024; // the maximum height of a texture\nvar minUtility = 0.2; // if usage of texture is less than this, it is retired\nvar maxFullness = 0.8; // fullness of texture after which queue removal is checked\nvar maxFullnessChecks = 10; // dequeued after this many checks\nvar deqCost$1 = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame\nvar deqAvgCost$1 = 0.1; // % of add'l rendering cost compared to average overall redraw time\nvar deqNoDrawCost$1 = 0.9; // % of avg frame time that can be used for dequeueing when not drawing\nvar deqFastCost$1 = 0.9; // % of frame time to be used when >60fps\nvar deqRedrawThreshold$1 = 100; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile\nvar maxDeqSize$1 = 1; // number of eles to dequeue and render at higher texture in each batch\n\nvar getTxrReasons = {\n dequeue: 'dequeue',\n downscale: 'downscale',\n highQuality: 'highQuality'\n};\nvar initDefaults = defaults$g({\n getKey: null,\n doesEleInvalidateKey: falsify,\n drawElement: null,\n getBoundingBox: null,\n getRotationPoint: null,\n getRotationOffset: null,\n isVisible: trueify,\n allowEdgeTxrCaching: true,\n allowParentTxrCaching: true\n});\nvar ElementTextureCache = function ElementTextureCache(renderer, initOptions) {\n var self = this;\n self.renderer = renderer;\n self.onDequeues = [];\n var opts = initDefaults(initOptions);\n extend(self, opts);\n self.lookup = new ElementTextureCacheLookup(opts.getKey, opts.doesEleInvalidateKey);\n self.setupDequeueing();\n};\nvar ETCp = ElementTextureCache.prototype;\nETCp.reasons = getTxrReasons;\n\n// the list of textures in which new subtextures for elements can be placed\nETCp.getTextureQueue = function (txrH) {\n var self = this;\n self.eleImgCaches = self.eleImgCaches || {};\n return self.eleImgCaches[txrH] = self.eleImgCaches[txrH] || [];\n};\n\n// the list of usused textures which can be recycled (in use in texture queue)\nETCp.getRetiredTextureQueue = function (txrH) {\n var self = this;\n var rtxtrQs = self.eleImgCaches.retired = self.eleImgCaches.retired || {};\n var rtxtrQ = rtxtrQs[txrH] = rtxtrQs[txrH] || [];\n return rtxtrQ;\n};\n\n// queue of element draw requests at different scale levels\nETCp.getElementQueue = function () {\n var self = this;\n var q = self.eleCacheQueue = self.eleCacheQueue || new heap(function (a, b) {\n return b.reqs - a.reqs;\n });\n return q;\n};\n\n// queue of element draw requests at different scale levels (element id lookup)\nETCp.getElementKeyToQueue = function () {\n var self = this;\n var k2q = self.eleKeyToCacheQueue = self.eleKeyToCacheQueue || {};\n return k2q;\n};\nETCp.getElement = function (ele, bb, pxRatio, lvl, reason) {\n var self = this;\n var r = this.renderer;\n var zoom = r.cy.zoom();\n var lookup = this.lookup;\n if (!bb || bb.w === 0 || bb.h === 0 || isNaN(bb.w) || isNaN(bb.h) || !ele.visible() || ele.removed()) {\n return null;\n }\n if (!self.allowEdgeTxrCaching && ele.isEdge() || !self.allowParentTxrCaching && ele.isParent()) {\n return null;\n }\n if (lvl == null) {\n lvl = Math.ceil(log2(zoom * pxRatio));\n }\n if (lvl < minLvl$1) {\n lvl = minLvl$1;\n } else if (zoom >= maxZoom$1 || lvl > maxLvl$1) {\n return null;\n }\n var scale = Math.pow(2, lvl);\n var eleScaledH = bb.h * scale;\n var eleScaledW = bb.w * scale;\n var scaledLabelShown = r.eleTextBiggerThanMin(ele, scale);\n if (!this.isVisible(ele, scaledLabelShown)) {\n return null;\n }\n var eleCache = lookup.get(ele, lvl);\n\n // if this get was on an unused/invalidated cache, then restore the texture usage metric\n if (eleCache && eleCache.invalidated) {\n eleCache.invalidated = false;\n eleCache.texture.invalidatedWidth -= eleCache.width;\n }\n if (eleCache) {\n return eleCache;\n }\n var txrH; // which texture height this ele belongs to\n\n if (eleScaledH <= minTxrH) {\n txrH = minTxrH;\n } else if (eleScaledH <= txrStepH) {\n txrH = txrStepH;\n } else {\n txrH = Math.ceil(eleScaledH / txrStepH) * txrStepH;\n }\n if (eleScaledH > maxTxrH || eleScaledW > maxTxrW) {\n return null; // caching large elements is not efficient\n }\n\n var txrQ = self.getTextureQueue(txrH);\n\n // first try the second last one in case it has space at the end\n var txr = txrQ[txrQ.length - 2];\n var addNewTxr = function addNewTxr() {\n return self.recycleTexture(txrH, eleScaledW) || self.addTexture(txrH, eleScaledW);\n };\n\n // try the last one if there is no second last one\n if (!txr) {\n txr = txrQ[txrQ.length - 1];\n }\n\n // if the last one doesn't exist, we need a first one\n if (!txr) {\n txr = addNewTxr();\n }\n\n // if there's no room in the current texture, we need a new one\n if (txr.width - txr.usedWidth < eleScaledW) {\n txr = addNewTxr();\n }\n var scalableFrom = function scalableFrom(otherCache) {\n return otherCache && otherCache.scaledLabelShown === scaledLabelShown;\n };\n var deqing = reason && reason === getTxrReasons.dequeue;\n var highQualityReq = reason && reason === getTxrReasons.highQuality;\n var downscaleReq = reason && reason === getTxrReasons.downscale;\n var higherCache; // the nearest cache with a higher level\n for (var l = lvl + 1; l <= maxLvl$1; l++) {\n var c = lookup.get(ele, l);\n if (c) {\n higherCache = c;\n break;\n }\n }\n var oneUpCache = higherCache && higherCache.level === lvl + 1 ? higherCache : null;\n var downscale = function downscale() {\n txr.context.drawImage(oneUpCache.texture.canvas, oneUpCache.x, 0, oneUpCache.width, oneUpCache.height, txr.usedWidth, 0, eleScaledW, eleScaledH);\n };\n\n // reset ele area in texture\n txr.context.setTransform(1, 0, 0, 1, 0, 0);\n txr.context.clearRect(txr.usedWidth, 0, eleScaledW, txrH);\n if (scalableFrom(oneUpCache)) {\n // then we can relatively cheaply rescale the existing image w/o rerendering\n downscale();\n } else if (scalableFrom(higherCache)) {\n // then use the higher cache for now and queue the next level down\n // to cheaply scale towards the smaller level\n\n if (highQualityReq) {\n for (var _l = higherCache.level; _l > lvl; _l--) {\n oneUpCache = self.getElement(ele, bb, pxRatio, _l, getTxrReasons.downscale);\n }\n downscale();\n } else {\n self.queueElement(ele, higherCache.level - 1);\n return higherCache;\n }\n } else {\n var lowerCache; // the nearest cache with a lower level\n if (!deqing && !highQualityReq && !downscaleReq) {\n for (var _l2 = lvl - 1; _l2 >= minLvl$1; _l2--) {\n var _c = lookup.get(ele, _l2);\n if (_c) {\n lowerCache = _c;\n break;\n }\n }\n }\n if (scalableFrom(lowerCache)) {\n // then use the lower quality cache for now and queue the better one for later\n\n self.queueElement(ele, lvl);\n return lowerCache;\n }\n txr.context.translate(txr.usedWidth, 0);\n txr.context.scale(scale, scale);\n this.drawElement(txr.context, ele, bb, scaledLabelShown, false);\n txr.context.scale(1 / scale, 1 / scale);\n txr.context.translate(-txr.usedWidth, 0);\n }\n eleCache = {\n x: txr.usedWidth,\n texture: txr,\n level: lvl,\n scale: scale,\n width: eleScaledW,\n height: eleScaledH,\n scaledLabelShown: scaledLabelShown\n };\n txr.usedWidth += Math.ceil(eleScaledW + eleTxrSpacing);\n txr.eleCaches.push(eleCache);\n lookup.set(ele, lvl, eleCache);\n self.checkTextureFullness(txr);\n return eleCache;\n};\nETCp.invalidateElements = function (eles) {\n for (var i = 0; i < eles.length; i++) {\n this.invalidateElement(eles[i]);\n }\n};\nETCp.invalidateElement = function (ele) {\n var self = this;\n var lookup = self.lookup;\n var caches = [];\n var invalid = lookup.isInvalid(ele);\n if (!invalid) {\n return; // override the invalidation request if the element key has not changed\n }\n\n for (var lvl = minLvl$1; lvl <= maxLvl$1; lvl++) {\n var cache = lookup.getForCachedKey(ele, lvl);\n if (cache) {\n caches.push(cache);\n }\n }\n var noOtherElesUseCache = lookup.invalidate(ele);\n if (noOtherElesUseCache) {\n for (var i = 0; i < caches.length; i++) {\n var _cache = caches[i];\n var txr = _cache.texture;\n\n // remove space from the texture it belongs to\n txr.invalidatedWidth += _cache.width;\n\n // mark the cache as invalidated\n _cache.invalidated = true;\n\n // retire the texture if its utility is low\n self.checkTextureUtility(txr);\n }\n }\n\n // remove from queue since the old req was for the old state\n self.removeFromQueue(ele);\n};\nETCp.checkTextureUtility = function (txr) {\n // invalidate all entries in the cache if the cache size is small\n if (txr.invalidatedWidth >= minUtility * txr.width) {\n this.retireTexture(txr);\n }\n};\nETCp.checkTextureFullness = function (txr) {\n // if texture has been mostly filled and passed over several times, remove\n // it from the queue so we don't need to waste time looking at it to put new things\n\n var self = this;\n var txrQ = self.getTextureQueue(txr.height);\n if (txr.usedWidth / txr.width > maxFullness && txr.fullnessChecks >= maxFullnessChecks) {\n removeFromArray(txrQ, txr);\n } else {\n txr.fullnessChecks++;\n }\n};\nETCp.retireTexture = function (txr) {\n var self = this;\n var txrH = txr.height;\n var txrQ = self.getTextureQueue(txrH);\n var lookup = this.lookup;\n\n // retire the texture from the active / searchable queue:\n\n removeFromArray(txrQ, txr);\n txr.retired = true;\n\n // remove the refs from the eles to the caches:\n\n var eleCaches = txr.eleCaches;\n for (var i = 0; i < eleCaches.length; i++) {\n var eleCache = eleCaches[i];\n lookup.deleteCache(eleCache.key, eleCache.level);\n }\n clearArray(eleCaches);\n\n // add the texture to a retired queue so it can be recycled in future:\n\n var rtxtrQ = self.getRetiredTextureQueue(txrH);\n rtxtrQ.push(txr);\n};\nETCp.addTexture = function (txrH, minW) {\n var self = this;\n var txrQ = self.getTextureQueue(txrH);\n var txr = {};\n txrQ.push(txr);\n txr.eleCaches = [];\n txr.height = txrH;\n txr.width = Math.max(defTxrWidth, minW);\n txr.usedWidth = 0;\n txr.invalidatedWidth = 0;\n txr.fullnessChecks = 0;\n txr.canvas = self.renderer.makeOffscreenCanvas(txr.width, txr.height);\n txr.context = txr.canvas.getContext('2d');\n return txr;\n};\nETCp.recycleTexture = function (txrH, minW) {\n var self = this;\n var txrQ = self.getTextureQueue(txrH);\n var rtxtrQ = self.getRetiredTextureQueue(txrH);\n for (var i = 0; i < rtxtrQ.length; i++) {\n var txr = rtxtrQ[i];\n if (txr.width >= minW) {\n txr.retired = false;\n txr.usedWidth = 0;\n txr.invalidatedWidth = 0;\n txr.fullnessChecks = 0;\n clearArray(txr.eleCaches);\n txr.context.setTransform(1, 0, 0, 1, 0, 0);\n txr.context.clearRect(0, 0, txr.width, txr.height);\n removeFromArray(rtxtrQ, txr);\n txrQ.push(txr);\n return txr;\n }\n }\n};\nETCp.queueElement = function (ele, lvl) {\n var self = this;\n var q = self.getElementQueue();\n var k2q = self.getElementKeyToQueue();\n var key = this.getKey(ele);\n var existingReq = k2q[key];\n if (existingReq) {\n // use the max lvl b/c in between lvls are cheap to make\n existingReq.level = Math.max(existingReq.level, lvl);\n existingReq.eles.merge(ele);\n existingReq.reqs++;\n q.updateItem(existingReq);\n } else {\n var req = {\n eles: ele.spawn().merge(ele),\n level: lvl,\n reqs: 1,\n key: key\n };\n q.push(req);\n k2q[key] = req;\n }\n};\nETCp.dequeue = function (pxRatio /*, extent*/) {\n var self = this;\n var q = self.getElementQueue();\n var k2q = self.getElementKeyToQueue();\n var dequeued = [];\n var lookup = self.lookup;\n for (var i = 0; i < maxDeqSize$1; i++) {\n if (q.size() > 0) {\n var req = q.pop();\n var key = req.key;\n var ele = req.eles[0]; // all eles have the same key\n var cacheExists = lookup.hasCache(ele, req.level);\n\n // clear out the key to req lookup\n k2q[key] = null;\n\n // dequeueing isn't necessary with an existing cache\n if (cacheExists) {\n continue;\n }\n dequeued.push(req);\n var bb = self.getBoundingBox(ele);\n self.getElement(ele, bb, pxRatio, req.level, getTxrReasons.dequeue);\n } else {\n break;\n }\n }\n return dequeued;\n};\nETCp.removeFromQueue = function (ele) {\n var self = this;\n var q = self.getElementQueue();\n var k2q = self.getElementKeyToQueue();\n var key = this.getKey(ele);\n var req = k2q[key];\n if (req != null) {\n if (req.eles.length === 1) {\n // remove if last ele in the req\n // bring to front of queue\n req.reqs = MAX_INT$1;\n q.updateItem(req);\n q.pop(); // remove from queue\n\n k2q[key] = null; // remove from lookup map\n } else {\n // otherwise just remove ele from req\n req.eles.unmerge(ele);\n }\n }\n};\nETCp.onDequeue = function (fn) {\n this.onDequeues.push(fn);\n};\nETCp.offDequeue = function (fn) {\n removeFromArray(this.onDequeues, fn);\n};\nETCp.setupDequeueing = defs.setupDequeueing({\n deqRedrawThreshold: deqRedrawThreshold$1,\n deqCost: deqCost$1,\n deqAvgCost: deqAvgCost$1,\n deqNoDrawCost: deqNoDrawCost$1,\n deqFastCost: deqFastCost$1,\n deq: function deq(self, pxRatio, extent) {\n return self.dequeue(pxRatio, extent);\n },\n onDeqd: function onDeqd(self, deqd) {\n for (var i = 0; i < self.onDequeues.length; i++) {\n var fn = self.onDequeues[i];\n fn(deqd);\n }\n },\n shouldRedraw: function shouldRedraw(self, deqd, pxRatio, extent) {\n for (var i = 0; i < deqd.length; i++) {\n var eles = deqd[i].eles;\n for (var j = 0; j < eles.length; j++) {\n var bb = eles[j].boundingBox();\n if (boundingBoxesIntersect(bb, extent)) {\n return true;\n }\n }\n }\n return false;\n },\n priority: function priority(self) {\n return self.renderer.beforeRenderPriorities.eleTxrDeq;\n }\n});\n\nvar defNumLayers = 1; // default number of layers to use\nvar minLvl = -4; // when scaling smaller than that we don't need to re-render\nvar maxLvl = 2; // when larger than this scale just render directly (caching is not helpful)\nvar maxZoom = 3.99; // beyond this zoom level, layered textures are not used\nvar deqRedrawThreshold = 50; // time to batch redraws together from dequeueing to allow more dequeueing calcs to happen in the meanwhile\nvar refineEleDebounceTime = 50; // time to debounce sharper ele texture updates\nvar deqCost = 0.15; // % of add'l rendering cost allowed for dequeuing ele caches each frame\nvar deqAvgCost = 0.1; // % of add'l rendering cost compared to average overall redraw time\nvar deqNoDrawCost = 0.9; // % of avg frame time that can be used for dequeueing when not drawing\nvar deqFastCost = 0.9; // % of frame time to be used when >60fps\nvar maxDeqSize = 1; // number of eles to dequeue and render at higher texture in each batch\nvar invalidThreshold = 250; // time threshold for disabling b/c of invalidations\nvar maxLayerArea = 4000 * 4000; // layers can't be bigger than this\nvar useHighQualityEleTxrReqs = true; // whether to use high quality ele txr requests (generally faster and cheaper in the longterm)\n\n// var log = function(){ console.log.apply( console, arguments ); };\n\nvar LayeredTextureCache = function LayeredTextureCache(renderer) {\n var self = this;\n var r = self.renderer = renderer;\n var cy = r.cy;\n self.layersByLevel = {}; // e.g. 2 => [ layer1, layer2, ..., layerN ]\n\n self.firstGet = true;\n self.lastInvalidationTime = performanceNow() - 2 * invalidThreshold;\n self.skipping = false;\n self.eleTxrDeqs = cy.collection();\n self.scheduleElementRefinement = debounce_1(function () {\n self.refineElementTextures(self.eleTxrDeqs);\n self.eleTxrDeqs.unmerge(self.eleTxrDeqs);\n }, refineEleDebounceTime);\n r.beforeRender(function (willDraw, now) {\n if (now - self.lastInvalidationTime <= invalidThreshold) {\n self.skipping = true;\n } else {\n self.skipping = false;\n }\n }, r.beforeRenderPriorities.lyrTxrSkip);\n var qSort = function qSort(a, b) {\n return b.reqs - a.reqs;\n };\n self.layersQueue = new heap(qSort);\n self.setupDequeueing();\n};\nvar LTCp = LayeredTextureCache.prototype;\nvar layerIdPool = 0;\nvar MAX_INT = Math.pow(2, 53) - 1;\nLTCp.makeLayer = function (bb, lvl) {\n var scale = Math.pow(2, lvl);\n var w = Math.ceil(bb.w * scale);\n var h = Math.ceil(bb.h * scale);\n var canvas = this.renderer.makeOffscreenCanvas(w, h);\n var layer = {\n id: layerIdPool = ++layerIdPool % MAX_INT,\n bb: bb,\n level: lvl,\n width: w,\n height: h,\n canvas: canvas,\n context: canvas.getContext('2d'),\n eles: [],\n elesQueue: [],\n reqs: 0\n };\n\n // log('make layer %s with w %s and h %s and lvl %s', layer.id, layer.width, layer.height, layer.level);\n\n var cxt = layer.context;\n var dx = -layer.bb.x1;\n var dy = -layer.bb.y1;\n\n // do the transform on creation to save cycles (it's the same for all eles)\n cxt.scale(scale, scale);\n cxt.translate(dx, dy);\n return layer;\n};\nLTCp.getLayers = function (eles, pxRatio, lvl) {\n var self = this;\n var r = self.renderer;\n var cy = r.cy;\n var zoom = cy.zoom();\n var firstGet = self.firstGet;\n self.firstGet = false;\n\n // log('--\\nget layers with %s eles', eles.length);\n //log eles.map(function(ele){ return ele.id() }) );\n\n if (lvl == null) {\n lvl = Math.ceil(log2(zoom * pxRatio));\n if (lvl < minLvl) {\n lvl = minLvl;\n } else if (zoom >= maxZoom || lvl > maxLvl) {\n return null;\n }\n }\n self.validateLayersElesOrdering(lvl, eles);\n var layersByLvl = self.layersByLevel;\n var scale = Math.pow(2, lvl);\n var layers = layersByLvl[lvl] = layersByLvl[lvl] || [];\n var bb;\n var lvlComplete = self.levelIsComplete(lvl, eles);\n var tmpLayers;\n var checkTempLevels = function checkTempLevels() {\n var canUseAsTmpLvl = function canUseAsTmpLvl(l) {\n self.validateLayersElesOrdering(l, eles);\n if (self.levelIsComplete(l, eles)) {\n tmpLayers = layersByLvl[l];\n return true;\n }\n };\n var checkLvls = function checkLvls(dir) {\n if (tmpLayers) {\n return;\n }\n for (var l = lvl + dir; minLvl <= l && l <= maxLvl; l += dir) {\n if (canUseAsTmpLvl(l)) {\n break;\n }\n }\n };\n checkLvls(+1);\n checkLvls(-1);\n\n // remove the invalid layers; they will be replaced as needed later in this function\n for (var i = layers.length - 1; i >= 0; i--) {\n var layer = layers[i];\n if (layer.invalid) {\n removeFromArray(layers, layer);\n }\n }\n };\n if (!lvlComplete) {\n // if the current level is incomplete, then use the closest, best quality layerset temporarily\n // and later queue the current layerset so we can get the proper quality level soon\n\n checkTempLevels();\n } else {\n // log('level complete, using existing layers\\n--');\n return layers;\n }\n var getBb = function getBb() {\n if (!bb) {\n bb = makeBoundingBox();\n for (var i = 0; i < eles.length; i++) {\n updateBoundingBox(bb, eles[i].boundingBox());\n }\n }\n return bb;\n };\n var makeLayer = function makeLayer(opts) {\n opts = opts || {};\n var after = opts.after;\n getBb();\n var area = bb.w * scale * (bb.h * scale);\n if (area > maxLayerArea) {\n return null;\n }\n var layer = self.makeLayer(bb, lvl);\n if (after != null) {\n var index = layers.indexOf(after) + 1;\n layers.splice(index, 0, layer);\n } else if (opts.insert === undefined || opts.insert) {\n // no after specified => first layer made so put at start\n layers.unshift(layer);\n }\n\n // if( tmpLayers ){\n //self.queueLayer( layer );\n // }\n\n return layer;\n };\n if (self.skipping && !firstGet) {\n // log('skip layers');\n return null;\n }\n\n // log('do layers');\n\n var layer = null;\n var maxElesPerLayer = eles.length / defNumLayers;\n var allowLazyQueueing = !firstGet;\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n var rs = ele._private.rscratch;\n var caches = rs.imgLayerCaches = rs.imgLayerCaches || {};\n\n // log('look at ele', ele.id());\n\n var existingLayer = caches[lvl];\n if (existingLayer) {\n // reuse layer for later eles\n // log('reuse layer for', ele.id());\n layer = existingLayer;\n continue;\n }\n if (!layer || layer.eles.length >= maxElesPerLayer || !boundingBoxInBoundingBox(layer.bb, ele.boundingBox())) {\n // log('make new layer for ele %s', ele.id());\n\n layer = makeLayer({\n insert: true,\n after: layer\n });\n\n // if now layer can be built then we can't use layers at this level\n if (!layer) {\n return null;\n }\n\n // log('new layer with id %s', layer.id);\n }\n\n if (tmpLayers || allowLazyQueueing) {\n // log('queue ele %s in layer %s', ele.id(), layer.id);\n self.queueLayer(layer, ele);\n } else {\n // log('draw ele %s in layer %s', ele.id(), layer.id);\n self.drawEleInLayer(layer, ele, lvl, pxRatio);\n }\n layer.eles.push(ele);\n caches[lvl] = layer;\n }\n\n // log('--');\n\n if (tmpLayers) {\n // then we only queued the current layerset and can't draw it yet\n return tmpLayers;\n }\n if (allowLazyQueueing) {\n // log('lazy queue level', lvl);\n return null;\n }\n return layers;\n};\n\n// a layer may want to use an ele cache of a higher level to avoid blurriness\n// so the layer level might not equal the ele level\nLTCp.getEleLevelForLayerLevel = function (lvl, pxRatio) {\n return lvl;\n};\nLTCp.drawEleInLayer = function (layer, ele, lvl, pxRatio) {\n var self = this;\n var r = this.renderer;\n var context = layer.context;\n var bb = ele.boundingBox();\n if (bb.w === 0 || bb.h === 0 || !ele.visible()) {\n return;\n }\n lvl = self.getEleLevelForLayerLevel(lvl, pxRatio);\n {\n r.setImgSmoothing(context, false);\n }\n {\n r.drawCachedElement(context, ele, null, null, lvl, useHighQualityEleTxrReqs);\n }\n {\n r.setImgSmoothing(context, true);\n }\n};\nLTCp.levelIsComplete = function (lvl, eles) {\n var self = this;\n var layers = self.layersByLevel[lvl];\n if (!layers || layers.length === 0) {\n return false;\n }\n var numElesInLayers = 0;\n for (var i = 0; i < layers.length; i++) {\n var layer = layers[i];\n\n // if there are any eles needed to be drawn yet, the level is not complete\n if (layer.reqs > 0) {\n return false;\n }\n\n // if the layer is invalid, the level is not complete\n if (layer.invalid) {\n return false;\n }\n numElesInLayers += layer.eles.length;\n }\n\n // we should have exactly the number of eles passed in to be complete\n if (numElesInLayers !== eles.length) {\n return false;\n }\n return true;\n};\nLTCp.validateLayersElesOrdering = function (lvl, eles) {\n var layers = this.layersByLevel[lvl];\n if (!layers) {\n return;\n }\n\n // if in a layer the eles are not in the same order, then the layer is invalid\n // (i.e. there is an ele in between the eles in the layer)\n\n for (var i = 0; i < layers.length; i++) {\n var layer = layers[i];\n var offset = -1;\n\n // find the offset\n for (var j = 0; j < eles.length; j++) {\n if (layer.eles[0] === eles[j]) {\n offset = j;\n break;\n }\n }\n if (offset < 0) {\n // then the layer has nonexistent elements and is invalid\n this.invalidateLayer(layer);\n continue;\n }\n\n // the eles in the layer must be in the same continuous order, else the layer is invalid\n\n var o = offset;\n for (var j = 0; j < layer.eles.length; j++) {\n if (layer.eles[j] !== eles[o + j]) {\n // log('invalidate based on ordering', layer.id);\n\n this.invalidateLayer(layer);\n break;\n }\n }\n }\n};\nLTCp.updateElementsInLayers = function (eles, update) {\n var self = this;\n var isEles = element(eles[0]);\n\n // collect udpated elements (cascaded from the layers) and update each\n // layer itself along the way\n for (var i = 0; i < eles.length; i++) {\n var req = isEles ? null : eles[i];\n var ele = isEles ? eles[i] : eles[i].ele;\n var rs = ele._private.rscratch;\n var caches = rs.imgLayerCaches = rs.imgLayerCaches || {};\n for (var l = minLvl; l <= maxLvl; l++) {\n var layer = caches[l];\n if (!layer) {\n continue;\n }\n\n // if update is a request from the ele cache, then it affects only\n // the matching level\n if (req && self.getEleLevelForLayerLevel(layer.level) !== req.level) {\n continue;\n }\n update(layer, ele, req);\n }\n }\n};\nLTCp.haveLayers = function () {\n var self = this;\n var haveLayers = false;\n for (var l = minLvl; l <= maxLvl; l++) {\n var layers = self.layersByLevel[l];\n if (layers && layers.length > 0) {\n haveLayers = true;\n break;\n }\n }\n return haveLayers;\n};\nLTCp.invalidateElements = function (eles) {\n var self = this;\n if (eles.length === 0) {\n return;\n }\n self.lastInvalidationTime = performanceNow();\n\n // log('update invalidate layer time from eles');\n\n if (eles.length === 0 || !self.haveLayers()) {\n return;\n }\n self.updateElementsInLayers(eles, function invalAssocLayers(layer, ele, req) {\n self.invalidateLayer(layer);\n });\n};\nLTCp.invalidateLayer = function (layer) {\n // log('update invalidate layer time');\n\n this.lastInvalidationTime = performanceNow();\n if (layer.invalid) {\n return;\n } // save cycles\n\n var lvl = layer.level;\n var eles = layer.eles;\n var layers = this.layersByLevel[lvl];\n\n // log('invalidate layer', layer.id );\n\n removeFromArray(layers, layer);\n // layer.eles = [];\n\n layer.elesQueue = [];\n layer.invalid = true;\n if (layer.replacement) {\n layer.replacement.invalid = true;\n }\n for (var i = 0; i < eles.length; i++) {\n var caches = eles[i]._private.rscratch.imgLayerCaches;\n if (caches) {\n caches[lvl] = null;\n }\n }\n};\nLTCp.refineElementTextures = function (eles) {\n var self = this;\n\n // log('refine', eles.length);\n\n self.updateElementsInLayers(eles, function refineEachEle(layer, ele, req) {\n var rLyr = layer.replacement;\n if (!rLyr) {\n rLyr = layer.replacement = self.makeLayer(layer.bb, layer.level);\n rLyr.replaces = layer;\n rLyr.eles = layer.eles;\n\n // log('make replacement layer %s for %s with level %s', rLyr.id, layer.id, rLyr.level);\n }\n\n if (!rLyr.reqs) {\n for (var i = 0; i < rLyr.eles.length; i++) {\n self.queueLayer(rLyr, rLyr.eles[i]);\n }\n\n // log('queue replacement layer refinement', rLyr.id);\n }\n });\n};\n\nLTCp.enqueueElementRefinement = function (ele) {\n this.eleTxrDeqs.merge(ele);\n this.scheduleElementRefinement();\n};\nLTCp.queueLayer = function (layer, ele) {\n var self = this;\n var q = self.layersQueue;\n var elesQ = layer.elesQueue;\n var hasId = elesQ.hasId = elesQ.hasId || {};\n\n // if a layer is going to be replaced, queuing is a waste of time\n if (layer.replacement) {\n return;\n }\n if (ele) {\n if (hasId[ele.id()]) {\n return;\n }\n elesQ.push(ele);\n hasId[ele.id()] = true;\n }\n if (layer.reqs) {\n layer.reqs++;\n q.updateItem(layer);\n } else {\n layer.reqs = 1;\n q.push(layer);\n }\n};\nLTCp.dequeue = function (pxRatio) {\n var self = this;\n var q = self.layersQueue;\n var deqd = [];\n var eleDeqs = 0;\n while (eleDeqs < maxDeqSize) {\n if (q.size() === 0) {\n break;\n }\n var layer = q.peek();\n\n // if a layer has been or will be replaced, then don't waste time with it\n if (layer.replacement) {\n // log('layer %s in queue skipped b/c it already has a replacement', layer.id);\n q.pop();\n continue;\n }\n\n // if this is a replacement layer that has been superceded, then forget it\n if (layer.replaces && layer !== layer.replaces.replacement) {\n // log('layer is no longer the most uptodate replacement; dequeued', layer.id)\n q.pop();\n continue;\n }\n if (layer.invalid) {\n // log('replacement layer %s is invalid; dequeued', layer.id);\n q.pop();\n continue;\n }\n var ele = layer.elesQueue.shift();\n if (ele) {\n // log('dequeue layer %s', layer.id);\n\n self.drawEleInLayer(layer, ele, layer.level, pxRatio);\n eleDeqs++;\n }\n if (deqd.length === 0) {\n // we need only one entry in deqd to queue redrawing etc\n deqd.push(true);\n }\n\n // if the layer has all its eles done, then remove from the queue\n if (layer.elesQueue.length === 0) {\n q.pop();\n layer.reqs = 0;\n\n // log('dequeue of layer %s complete', layer.id);\n\n // when a replacement layer is dequeued, it replaces the old layer in the level\n if (layer.replaces) {\n self.applyLayerReplacement(layer);\n }\n self.requestRedraw();\n }\n }\n return deqd;\n};\nLTCp.applyLayerReplacement = function (layer) {\n var self = this;\n var layersInLevel = self.layersByLevel[layer.level];\n var replaced = layer.replaces;\n var index = layersInLevel.indexOf(replaced);\n\n // if the replaced layer is not in the active list for the level, then replacing\n // refs would be a mistake (i.e. overwriting the true active layer)\n if (index < 0 || replaced.invalid) {\n // log('replacement layer would have no effect', layer.id);\n return;\n }\n layersInLevel[index] = layer; // replace level ref\n\n // replace refs in eles\n for (var i = 0; i < layer.eles.length; i++) {\n var _p = layer.eles[i]._private;\n var cache = _p.imgLayerCaches = _p.imgLayerCaches || {};\n if (cache) {\n cache[layer.level] = layer;\n }\n }\n\n // log('apply replacement layer %s over %s', layer.id, replaced.id);\n\n self.requestRedraw();\n};\nLTCp.requestRedraw = debounce_1(function () {\n var r = this.renderer;\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n r.redraw();\n}, 100);\nLTCp.setupDequeueing = defs.setupDequeueing({\n deqRedrawThreshold: deqRedrawThreshold,\n deqCost: deqCost,\n deqAvgCost: deqAvgCost,\n deqNoDrawCost: deqNoDrawCost,\n deqFastCost: deqFastCost,\n deq: function deq(self, pxRatio) {\n return self.dequeue(pxRatio);\n },\n onDeqd: noop$1,\n shouldRedraw: trueify,\n priority: function priority(self) {\n return self.renderer.beforeRenderPriorities.lyrTxrDeq;\n }\n});\n\nvar CRp$a = {};\nvar impl;\nfunction polygon(context, points) {\n for (var i = 0; i < points.length; i++) {\n var pt = points[i];\n context.lineTo(pt.x, pt.y);\n }\n}\nfunction triangleBackcurve(context, points, controlPoint) {\n var firstPt;\n for (var i = 0; i < points.length; i++) {\n var pt = points[i];\n if (i === 0) {\n firstPt = pt;\n }\n context.lineTo(pt.x, pt.y);\n }\n context.quadraticCurveTo(controlPoint.x, controlPoint.y, firstPt.x, firstPt.y);\n}\nfunction triangleTee(context, trianglePoints, teePoints) {\n if (context.beginPath) {\n context.beginPath();\n }\n var triPts = trianglePoints;\n for (var i = 0; i < triPts.length; i++) {\n var pt = triPts[i];\n context.lineTo(pt.x, pt.y);\n }\n var teePts = teePoints;\n var firstTeePt = teePoints[0];\n context.moveTo(firstTeePt.x, firstTeePt.y);\n for (var i = 1; i < teePts.length; i++) {\n var pt = teePts[i];\n context.lineTo(pt.x, pt.y);\n }\n if (context.closePath) {\n context.closePath();\n }\n}\nfunction circleTriangle(context, trianglePoints, rx, ry, r) {\n if (context.beginPath) {\n context.beginPath();\n }\n context.arc(rx, ry, r, 0, Math.PI * 2, false);\n var triPts = trianglePoints;\n var firstTrPt = triPts[0];\n context.moveTo(firstTrPt.x, firstTrPt.y);\n for (var i = 0; i < triPts.length; i++) {\n var pt = triPts[i];\n context.lineTo(pt.x, pt.y);\n }\n if (context.closePath) {\n context.closePath();\n }\n}\nfunction circle(context, rx, ry, r) {\n context.arc(rx, ry, r, 0, Math.PI * 2, false);\n}\nCRp$a.arrowShapeImpl = function (name) {\n return (impl || (impl = {\n 'polygon': polygon,\n 'triangle-backcurve': triangleBackcurve,\n 'triangle-tee': triangleTee,\n 'circle-triangle': circleTriangle,\n 'triangle-cross': triangleTee,\n 'circle': circle\n }))[name];\n};\n\nvar CRp$9 = {};\nCRp$9.drawElement = function (context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity) {\n var r = this;\n if (ele.isNode()) {\n r.drawNode(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity);\n } else {\n r.drawEdge(context, ele, shiftToOriginWithBb, showLabel, showOverlay, showOpacity);\n }\n};\nCRp$9.drawElementOverlay = function (context, ele) {\n var r = this;\n if (ele.isNode()) {\n r.drawNodeOverlay(context, ele);\n } else {\n r.drawEdgeOverlay(context, ele);\n }\n};\nCRp$9.drawElementUnderlay = function (context, ele) {\n var r = this;\n if (ele.isNode()) {\n r.drawNodeUnderlay(context, ele);\n } else {\n r.drawEdgeUnderlay(context, ele);\n }\n};\nCRp$9.drawCachedElementPortion = function (context, ele, eleTxrCache, pxRatio, lvl, reason, getRotation, getOpacity) {\n var r = this;\n var bb = eleTxrCache.getBoundingBox(ele);\n if (bb.w === 0 || bb.h === 0) {\n return;\n } // ignore zero size case\n\n var eleCache = eleTxrCache.getElement(ele, bb, pxRatio, lvl, reason);\n if (eleCache != null) {\n var opacity = getOpacity(r, ele);\n if (opacity === 0) {\n return;\n }\n var theta = getRotation(r, ele);\n var x1 = bb.x1,\n y1 = bb.y1,\n w = bb.w,\n h = bb.h;\n var x, y, sx, sy, smooth;\n if (theta !== 0) {\n var rotPt = eleTxrCache.getRotationPoint(ele);\n sx = rotPt.x;\n sy = rotPt.y;\n context.translate(sx, sy);\n context.rotate(theta);\n smooth = r.getImgSmoothing(context);\n if (!smooth) {\n r.setImgSmoothing(context, true);\n }\n var off = eleTxrCache.getRotationOffset(ele);\n x = off.x;\n y = off.y;\n } else {\n x = x1;\n y = y1;\n }\n var oldGlobalAlpha;\n if (opacity !== 1) {\n oldGlobalAlpha = context.globalAlpha;\n context.globalAlpha = oldGlobalAlpha * opacity;\n }\n context.drawImage(eleCache.texture.canvas, eleCache.x, 0, eleCache.width, eleCache.height, x, y, w, h);\n if (opacity !== 1) {\n context.globalAlpha = oldGlobalAlpha;\n }\n if (theta !== 0) {\n context.rotate(-theta);\n context.translate(-sx, -sy);\n if (!smooth) {\n r.setImgSmoothing(context, false);\n }\n }\n } else {\n eleTxrCache.drawElement(context, ele); // direct draw fallback\n }\n};\n\nvar getZeroRotation = function getZeroRotation() {\n return 0;\n};\nvar getLabelRotation = function getLabelRotation(r, ele) {\n return r.getTextAngle(ele, null);\n};\nvar getSourceLabelRotation = function getSourceLabelRotation(r, ele) {\n return r.getTextAngle(ele, 'source');\n};\nvar getTargetLabelRotation = function getTargetLabelRotation(r, ele) {\n return r.getTextAngle(ele, 'target');\n};\nvar getOpacity = function getOpacity(r, ele) {\n return ele.effectiveOpacity();\n};\nvar getTextOpacity = function getTextOpacity(e, ele) {\n return ele.pstyle('text-opacity').pfValue * ele.effectiveOpacity();\n};\nCRp$9.drawCachedElement = function (context, ele, pxRatio, extent, lvl, requestHighQuality) {\n var r = this;\n var _r$data = r.data,\n eleTxrCache = _r$data.eleTxrCache,\n lblTxrCache = _r$data.lblTxrCache,\n slbTxrCache = _r$data.slbTxrCache,\n tlbTxrCache = _r$data.tlbTxrCache;\n var bb = ele.boundingBox();\n var reason = requestHighQuality === true ? eleTxrCache.reasons.highQuality : null;\n if (bb.w === 0 || bb.h === 0 || !ele.visible()) {\n return;\n }\n if (!extent || boundingBoxesIntersect(bb, extent)) {\n var isEdge = ele.isEdge();\n var badLine = ele.element()._private.rscratch.badLine;\n r.drawElementUnderlay(context, ele);\n r.drawCachedElementPortion(context, ele, eleTxrCache, pxRatio, lvl, reason, getZeroRotation, getOpacity);\n if (!isEdge || !badLine) {\n r.drawCachedElementPortion(context, ele, lblTxrCache, pxRatio, lvl, reason, getLabelRotation, getTextOpacity);\n }\n if (isEdge && !badLine) {\n r.drawCachedElementPortion(context, ele, slbTxrCache, pxRatio, lvl, reason, getSourceLabelRotation, getTextOpacity);\n r.drawCachedElementPortion(context, ele, tlbTxrCache, pxRatio, lvl, reason, getTargetLabelRotation, getTextOpacity);\n }\n r.drawElementOverlay(context, ele);\n }\n};\nCRp$9.drawElements = function (context, eles) {\n var r = this;\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n r.drawElement(context, ele);\n }\n};\nCRp$9.drawCachedElements = function (context, eles, pxRatio, extent) {\n var r = this;\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n r.drawCachedElement(context, ele, pxRatio, extent);\n }\n};\nCRp$9.drawCachedNodes = function (context, eles, pxRatio, extent) {\n var r = this;\n for (var i = 0; i < eles.length; i++) {\n var ele = eles[i];\n if (!ele.isNode()) {\n continue;\n }\n r.drawCachedElement(context, ele, pxRatio, extent);\n }\n};\nCRp$9.drawLayeredElements = function (context, eles, pxRatio, extent) {\n var r = this;\n var layers = r.data.lyrTxrCache.getLayers(eles, pxRatio);\n if (layers) {\n for (var i = 0; i < layers.length; i++) {\n var layer = layers[i];\n var bb = layer.bb;\n if (bb.w === 0 || bb.h === 0) {\n continue;\n }\n context.drawImage(layer.canvas, bb.x1, bb.y1, bb.w, bb.h);\n }\n } else {\n // fall back on plain caching if no layers\n r.drawCachedElements(context, eles, pxRatio, extent);\n }\n};\n\nvar CRp$8 = {};\nCRp$8.drawEdge = function (context, edge, shiftToOriginWithBb) {\n var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;\n var r = this;\n var rs = edge._private.rscratch;\n if (shouldDrawOpacity && !edge.visible()) {\n return;\n }\n\n // if bezier ctrl pts can not be calculated, then die\n if (rs.badLine || rs.allpts == null || isNaN(rs.allpts[0])) {\n // isNaN in case edge is impossible and browser bugs (e.g. safari)\n return;\n }\n var bb;\n if (shiftToOriginWithBb) {\n bb = shiftToOriginWithBb;\n context.translate(-bb.x1, -bb.y1);\n }\n var opacity = shouldDrawOpacity ? edge.pstyle('opacity').value : 1;\n var lineOpacity = shouldDrawOpacity ? edge.pstyle('line-opacity').value : 1;\n var curveStyle = edge.pstyle('curve-style').value;\n var lineStyle = edge.pstyle('line-style').value;\n var edgeWidth = edge.pstyle('width').pfValue;\n var lineCap = edge.pstyle('line-cap').value;\n var lineOutlineWidth = edge.pstyle('line-outline-width').value;\n var lineOutlineColor = edge.pstyle('line-outline-color').value;\n var effectiveLineOpacity = opacity * lineOpacity;\n // separate arrow opacity would require arrow-opacity property\n var effectiveArrowOpacity = opacity * lineOpacity;\n var drawLine = function drawLine() {\n var strokeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveLineOpacity;\n if (curveStyle === 'straight-triangle') {\n r.eleStrokeStyle(context, edge, strokeOpacity);\n r.drawEdgeTrianglePath(edge, context, rs.allpts);\n } else {\n context.lineWidth = edgeWidth;\n context.lineCap = lineCap;\n r.eleStrokeStyle(context, edge, strokeOpacity);\n r.drawEdgePath(edge, context, rs.allpts, lineStyle);\n context.lineCap = 'butt'; // reset for other drawing functions\n }\n };\n\n var drawLineOutline = function drawLineOutline() {\n var strokeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveLineOpacity;\n context.lineWidth = edgeWidth + lineOutlineWidth;\n context.lineCap = lineCap;\n if (lineOutlineWidth > 0) {\n r.colorStrokeStyle(context, lineOutlineColor[0], lineOutlineColor[1], lineOutlineColor[2], strokeOpacity);\n } else {\n // do not draw any lineOutline\n context.lineCap = 'butt'; // reset for other drawing functions\n return;\n }\n if (curveStyle === 'straight-triangle') {\n r.drawEdgeTrianglePath(edge, context, rs.allpts);\n } else {\n r.drawEdgePath(edge, context, rs.allpts, lineStyle);\n context.lineCap = 'butt'; // reset for other drawing functions\n }\n };\n\n var drawOverlay = function drawOverlay() {\n if (!shouldDrawOverlay) {\n return;\n }\n r.drawEdgeOverlay(context, edge);\n };\n var drawUnderlay = function drawUnderlay() {\n if (!shouldDrawOverlay) {\n return;\n }\n r.drawEdgeUnderlay(context, edge);\n };\n var drawArrows = function drawArrows() {\n var arrowOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : effectiveArrowOpacity;\n r.drawArrowheads(context, edge, arrowOpacity);\n };\n var drawText = function drawText() {\n r.drawElementText(context, edge, null, drawLabel);\n };\n context.lineJoin = 'round';\n var ghost = edge.pstyle('ghost').value === 'yes';\n if (ghost) {\n var gx = edge.pstyle('ghost-offset-x').pfValue;\n var gy = edge.pstyle('ghost-offset-y').pfValue;\n var ghostOpacity = edge.pstyle('ghost-opacity').value;\n var effectiveGhostOpacity = effectiveLineOpacity * ghostOpacity;\n context.translate(gx, gy);\n drawLine(effectiveGhostOpacity);\n drawArrows(effectiveGhostOpacity);\n context.translate(-gx, -gy);\n } else {\n drawLineOutline();\n }\n drawUnderlay();\n drawLine();\n drawArrows();\n drawOverlay();\n drawText();\n if (shiftToOriginWithBb) {\n context.translate(bb.x1, bb.y1);\n }\n};\nvar drawEdgeOverlayUnderlay = function drawEdgeOverlayUnderlay(overlayOrUnderlay) {\n if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) {\n throw new Error('Invalid state');\n }\n return function (context, edge) {\n if (!edge.visible()) {\n return;\n }\n var opacity = edge.pstyle(\"\".concat(overlayOrUnderlay, \"-opacity\")).value;\n if (opacity === 0) {\n return;\n }\n var r = this;\n var usePaths = r.usePaths();\n var rs = edge._private.rscratch;\n var padding = edge.pstyle(\"\".concat(overlayOrUnderlay, \"-padding\")).pfValue;\n var width = 2 * padding;\n var color = edge.pstyle(\"\".concat(overlayOrUnderlay, \"-color\")).value;\n context.lineWidth = width;\n if (rs.edgeType === 'self' && !usePaths) {\n context.lineCap = 'butt';\n } else {\n context.lineCap = 'round';\n }\n r.colorStrokeStyle(context, color[0], color[1], color[2], opacity);\n r.drawEdgePath(edge, context, rs.allpts, 'solid');\n };\n};\nCRp$8.drawEdgeOverlay = drawEdgeOverlayUnderlay('overlay');\nCRp$8.drawEdgeUnderlay = drawEdgeOverlayUnderlay('underlay');\nCRp$8.drawEdgePath = function (edge, context, pts, type) {\n var rs = edge._private.rscratch;\n var canvasCxt = context;\n var path;\n var pathCacheHit = false;\n var usePaths = this.usePaths();\n var lineDashPattern = edge.pstyle('line-dash-pattern').pfValue;\n var lineDashOffset = edge.pstyle('line-dash-offset').pfValue;\n if (usePaths) {\n var pathCacheKey = pts.join('$');\n var keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey;\n if (keyMatches) {\n path = context = rs.pathCache;\n pathCacheHit = true;\n } else {\n path = context = new Path2D();\n rs.pathCacheKey = pathCacheKey;\n rs.pathCache = path;\n }\n }\n if (canvasCxt.setLineDash) {\n // for very outofdate browsers\n switch (type) {\n case 'dotted':\n canvasCxt.setLineDash([1, 1]);\n break;\n case 'dashed':\n canvasCxt.setLineDash(lineDashPattern);\n canvasCxt.lineDashOffset = lineDashOffset;\n break;\n case 'solid':\n canvasCxt.setLineDash([]);\n break;\n }\n }\n if (!pathCacheHit && !rs.badLine) {\n if (context.beginPath) {\n context.beginPath();\n }\n context.moveTo(pts[0], pts[1]);\n switch (rs.edgeType) {\n case 'bezier':\n case 'self':\n case 'compound':\n case 'multibezier':\n for (var i = 2; i + 3 < pts.length; i += 4) {\n context.quadraticCurveTo(pts[i], pts[i + 1], pts[i + 2], pts[i + 3]);\n }\n break;\n case 'straight':\n case 'haystack':\n for (var _i = 2; _i + 1 < pts.length; _i += 2) {\n context.lineTo(pts[_i], pts[_i + 1]);\n }\n break;\n case 'segments':\n if (rs.isRound) {\n var _iterator = _createForOfIteratorHelper(rs.roundCorners),\n _step;\n try {\n for (_iterator.s(); !(_step = _iterator.n()).done;) {\n var corner = _step.value;\n drawPreparedRoundCorner(context, corner);\n }\n } catch (err) {\n _iterator.e(err);\n } finally {\n _iterator.f();\n }\n context.lineTo(pts[pts.length - 2], pts[pts.length - 1]);\n } else {\n for (var _i2 = 2; _i2 + 1 < pts.length; _i2 += 2) {\n context.lineTo(pts[_i2], pts[_i2 + 1]);\n }\n }\n break;\n }\n }\n context = canvasCxt;\n if (usePaths) {\n context.stroke(path);\n } else {\n context.stroke();\n }\n\n // reset any line dashes\n if (context.setLineDash) {\n // for very outofdate browsers\n context.setLineDash([]);\n }\n};\nCRp$8.drawEdgeTrianglePath = function (edge, context, pts) {\n // use line stroke style for triangle fill style\n context.fillStyle = context.strokeStyle;\n var edgeWidth = edge.pstyle('width').pfValue;\n for (var i = 0; i + 1 < pts.length; i += 2) {\n var vector = [pts[i + 2] - pts[i], pts[i + 3] - pts[i + 1]];\n var length = Math.sqrt(vector[0] * vector[0] + vector[1] * vector[1]);\n var normal = [vector[1] / length, -vector[0] / length];\n var triangleHead = [normal[0] * edgeWidth / 2, normal[1] * edgeWidth / 2];\n context.beginPath();\n context.moveTo(pts[i] - triangleHead[0], pts[i + 1] - triangleHead[1]);\n context.lineTo(pts[i] + triangleHead[0], pts[i + 1] + triangleHead[1]);\n context.lineTo(pts[i + 2], pts[i + 3]);\n context.closePath();\n context.fill();\n }\n};\nCRp$8.drawArrowheads = function (context, edge, opacity) {\n var rs = edge._private.rscratch;\n var isHaystack = rs.edgeType === 'haystack';\n if (!isHaystack) {\n this.drawArrowhead(context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle, opacity);\n }\n this.drawArrowhead(context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle, opacity);\n this.drawArrowhead(context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle, opacity);\n if (!isHaystack) {\n this.drawArrowhead(context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle, opacity);\n }\n};\nCRp$8.drawArrowhead = function (context, edge, prefix, x, y, angle, opacity) {\n if (isNaN(x) || x == null || isNaN(y) || y == null || isNaN(angle) || angle == null) {\n return;\n }\n var self = this;\n var arrowShape = edge.pstyle(prefix + '-arrow-shape').value;\n if (arrowShape === 'none') {\n return;\n }\n var arrowClearFill = edge.pstyle(prefix + '-arrow-fill').value === 'hollow' ? 'both' : 'filled';\n var arrowFill = edge.pstyle(prefix + '-arrow-fill').value;\n var edgeWidth = edge.pstyle('width').pfValue;\n var pArrowWidth = edge.pstyle(prefix + '-arrow-width');\n var arrowWidth = pArrowWidth.value === 'match-line' ? edgeWidth : pArrowWidth.pfValue;\n if (pArrowWidth.units === '%') arrowWidth *= edgeWidth;\n var edgeOpacity = edge.pstyle('opacity').value;\n if (opacity === undefined) {\n opacity = edgeOpacity;\n }\n var gco = context.globalCompositeOperation;\n if (opacity !== 1 || arrowFill === 'hollow') {\n // then extra clear is needed\n context.globalCompositeOperation = 'destination-out';\n self.colorFillStyle(context, 255, 255, 255, 1);\n self.colorStrokeStyle(context, 255, 255, 255, 1);\n self.drawArrowShape(edge, context, arrowClearFill, edgeWidth, arrowShape, arrowWidth, x, y, angle);\n context.globalCompositeOperation = gco;\n } // otherwise, the opaque arrow clears it for free :)\n\n var color = edge.pstyle(prefix + '-arrow-color').value;\n self.colorFillStyle(context, color[0], color[1], color[2], opacity);\n self.colorStrokeStyle(context, color[0], color[1], color[2], opacity);\n self.drawArrowShape(edge, context, arrowFill, edgeWidth, arrowShape, arrowWidth, x, y, angle);\n};\nCRp$8.drawArrowShape = function (edge, context, fill, edgeWidth, shape, shapeWidth, x, y, angle) {\n var r = this;\n var usePaths = this.usePaths() && shape !== 'triangle-cross';\n var pathCacheHit = false;\n var path;\n var canvasContext = context;\n var translation = {\n x: x,\n y: y\n };\n var scale = edge.pstyle('arrow-scale').value;\n var size = this.getArrowWidth(edgeWidth, scale);\n var shapeImpl = r.arrowShapes[shape];\n if (usePaths) {\n var cache = r.arrowPathCache = r.arrowPathCache || [];\n var key = hashString(shape);\n var cachedPath = cache[key];\n if (cachedPath != null) {\n path = context = cachedPath;\n pathCacheHit = true;\n } else {\n path = context = new Path2D();\n cache[key] = path;\n }\n }\n if (!pathCacheHit) {\n if (context.beginPath) {\n context.beginPath();\n }\n if (usePaths) {\n // store in the path cache with values easily manipulated later\n shapeImpl.draw(context, 1, 0, {\n x: 0,\n y: 0\n }, 1);\n } else {\n shapeImpl.draw(context, size, angle, translation, edgeWidth);\n }\n if (context.closePath) {\n context.closePath();\n }\n }\n context = canvasContext;\n if (usePaths) {\n // set transform to arrow position/orientation\n context.translate(x, y);\n context.rotate(angle);\n context.scale(size, size);\n }\n if (fill === 'filled' || fill === 'both') {\n if (usePaths) {\n context.fill(path);\n } else {\n context.fill();\n }\n }\n if (fill === 'hollow' || fill === 'both') {\n context.lineWidth = shapeWidth / (usePaths ? size : 1);\n context.lineJoin = 'miter';\n if (usePaths) {\n context.stroke(path);\n } else {\n context.stroke();\n }\n }\n if (usePaths) {\n // reset transform by applying inverse\n context.scale(1 / size, 1 / size);\n context.rotate(-angle);\n context.translate(-x, -y);\n }\n};\n\nvar CRp$7 = {};\nCRp$7.safeDrawImage = function (context, img, ix, iy, iw, ih, x, y, w, h) {\n // detect problematic cases for old browsers with bad images (cheaper than try-catch)\n if (iw <= 0 || ih <= 0 || w <= 0 || h <= 0) {\n return;\n }\n try {\n context.drawImage(img, ix, iy, iw, ih, x, y, w, h);\n } catch (e) {\n warn(e);\n }\n};\nCRp$7.drawInscribedImage = function (context, img, node, index, nodeOpacity) {\n var r = this;\n var pos = node.position();\n var nodeX = pos.x;\n var nodeY = pos.y;\n var styleObj = node.cy().style();\n var getIndexedStyle = styleObj.getIndexedStyle.bind(styleObj);\n var fit = getIndexedStyle(node, 'background-fit', 'value', index);\n var repeat = getIndexedStyle(node, 'background-repeat', 'value', index);\n var nodeW = node.width();\n var nodeH = node.height();\n var paddingX2 = node.padding() * 2;\n var nodeTW = nodeW + (getIndexedStyle(node, 'background-width-relative-to', 'value', index) === 'inner' ? 0 : paddingX2);\n var nodeTH = nodeH + (getIndexedStyle(node, 'background-height-relative-to', 'value', index) === 'inner' ? 0 : paddingX2);\n var rs = node._private.rscratch;\n var clip = getIndexedStyle(node, 'background-clip', 'value', index);\n var shouldClip = clip === 'node';\n var imgOpacity = getIndexedStyle(node, 'background-image-opacity', 'value', index) * nodeOpacity;\n var smooth = getIndexedStyle(node, 'background-image-smoothing', 'value', index);\n var cornerRadius = node.pstyle('corner-radius').value;\n if (cornerRadius !== 'auto') cornerRadius = node.pstyle('corner-radius').pfValue;\n var imgW = img.width || img.cachedW;\n var imgH = img.height || img.cachedH;\n\n // workaround for broken browsers like ie\n if (null == imgW || null == imgH) {\n document.body.appendChild(img); // eslint-disable-line no-undef\n\n imgW = img.cachedW = img.width || img.offsetWidth;\n imgH = img.cachedH = img.height || img.offsetHeight;\n document.body.removeChild(img); // eslint-disable-line no-undef\n }\n\n var w = imgW;\n var h = imgH;\n if (getIndexedStyle(node, 'background-width', 'value', index) !== 'auto') {\n if (getIndexedStyle(node, 'background-width', 'units', index) === '%') {\n w = getIndexedStyle(node, 'background-width', 'pfValue', index) * nodeTW;\n } else {\n w = getIndexedStyle(node, 'background-width', 'pfValue', index);\n }\n }\n if (getIndexedStyle(node, 'background-height', 'value', index) !== 'auto') {\n if (getIndexedStyle(node, 'background-height', 'units', index) === '%') {\n h = getIndexedStyle(node, 'background-height', 'pfValue', index) * nodeTH;\n } else {\n h = getIndexedStyle(node, 'background-height', 'pfValue', index);\n }\n }\n if (w === 0 || h === 0) {\n return; // no point in drawing empty image (and chrome is broken in this case)\n }\n\n if (fit === 'contain') {\n var scale = Math.min(nodeTW / w, nodeTH / h);\n w *= scale;\n h *= scale;\n } else if (fit === 'cover') {\n var scale = Math.max(nodeTW / w, nodeTH / h);\n w *= scale;\n h *= scale;\n }\n var x = nodeX - nodeTW / 2; // left\n var posXUnits = getIndexedStyle(node, 'background-position-x', 'units', index);\n var posXPfVal = getIndexedStyle(node, 'background-position-x', 'pfValue', index);\n if (posXUnits === '%') {\n x += (nodeTW - w) * posXPfVal;\n } else {\n x += posXPfVal;\n }\n var offXUnits = getIndexedStyle(node, 'background-offset-x', 'units', index);\n var offXPfVal = getIndexedStyle(node, 'background-offset-x', 'pfValue', index);\n if (offXUnits === '%') {\n x += (nodeTW - w) * offXPfVal;\n } else {\n x += offXPfVal;\n }\n var y = nodeY - nodeTH / 2; // top\n var posYUnits = getIndexedStyle(node, 'background-position-y', 'units', index);\n var posYPfVal = getIndexedStyle(node, 'background-position-y', 'pfValue', index);\n if (posYUnits === '%') {\n y += (nodeTH - h) * posYPfVal;\n } else {\n y += posYPfVal;\n }\n var offYUnits = getIndexedStyle(node, 'background-offset-y', 'units', index);\n var offYPfVal = getIndexedStyle(node, 'background-offset-y', 'pfValue', index);\n if (offYUnits === '%') {\n y += (nodeTH - h) * offYPfVal;\n } else {\n y += offYPfVal;\n }\n if (rs.pathCache) {\n x -= nodeX;\n y -= nodeY;\n nodeX = 0;\n nodeY = 0;\n }\n var gAlpha = context.globalAlpha;\n context.globalAlpha = imgOpacity;\n var smoothingEnabled = r.getImgSmoothing(context);\n var isSmoothingSwitched = false;\n if (smooth === 'no' && smoothingEnabled) {\n r.setImgSmoothing(context, false);\n isSmoothingSwitched = true;\n } else if (smooth === 'yes' && !smoothingEnabled) {\n r.setImgSmoothing(context, true);\n isSmoothingSwitched = true;\n }\n if (repeat === 'no-repeat') {\n if (shouldClip) {\n context.save();\n if (rs.pathCache) {\n context.clip(rs.pathCache);\n } else {\n r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH, cornerRadius, rs);\n context.clip();\n }\n }\n r.safeDrawImage(context, img, 0, 0, imgW, imgH, x, y, w, h);\n if (shouldClip) {\n context.restore();\n }\n } else {\n var pattern = context.createPattern(img, repeat);\n context.fillStyle = pattern;\n r.nodeShapes[r.getNodeShape(node)].draw(context, nodeX, nodeY, nodeTW, nodeTH, cornerRadius, rs);\n context.translate(x, y);\n context.fill();\n context.translate(-x, -y);\n }\n context.globalAlpha = gAlpha;\n if (isSmoothingSwitched) {\n r.setImgSmoothing(context, smoothingEnabled);\n }\n};\n\nvar CRp$6 = {};\nCRp$6.eleTextBiggerThanMin = function (ele, scale) {\n if (!scale) {\n var zoom = ele.cy().zoom();\n var pxRatio = this.getPixelRatio();\n var lvl = Math.ceil(log2(zoom * pxRatio)); // the effective texture level\n\n scale = Math.pow(2, lvl);\n }\n var computedSize = ele.pstyle('font-size').pfValue * scale;\n var minSize = ele.pstyle('min-zoomed-font-size').pfValue;\n if (computedSize < minSize) {\n return false;\n }\n return true;\n};\nCRp$6.drawElementText = function (context, ele, shiftToOriginWithBb, force, prefix) {\n var useEleOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;\n var r = this;\n if (force == null) {\n if (useEleOpacity && !r.eleTextBiggerThanMin(ele)) {\n return;\n }\n } else if (force === false) {\n return;\n }\n if (ele.isNode()) {\n var label = ele.pstyle('label');\n if (!label || !label.value) {\n return;\n }\n var justification = r.getLabelJustification(ele);\n context.textAlign = justification;\n context.textBaseline = 'bottom';\n } else {\n var badLine = ele.element()._private.rscratch.badLine;\n var _label = ele.pstyle('label');\n var srcLabel = ele.pstyle('source-label');\n var tgtLabel = ele.pstyle('target-label');\n if (badLine || (!_label || !_label.value) && (!srcLabel || !srcLabel.value) && (!tgtLabel || !tgtLabel.value)) {\n return;\n }\n context.textAlign = 'center';\n context.textBaseline = 'bottom';\n }\n var applyRotation = !shiftToOriginWithBb;\n var bb;\n if (shiftToOriginWithBb) {\n bb = shiftToOriginWithBb;\n context.translate(-bb.x1, -bb.y1);\n }\n if (prefix == null) {\n r.drawText(context, ele, null, applyRotation, useEleOpacity);\n if (ele.isEdge()) {\n r.drawText(context, ele, 'source', applyRotation, useEleOpacity);\n r.drawText(context, ele, 'target', applyRotation, useEleOpacity);\n }\n } else {\n r.drawText(context, ele, prefix, applyRotation, useEleOpacity);\n }\n if (shiftToOriginWithBb) {\n context.translate(bb.x1, bb.y1);\n }\n};\nCRp$6.getFontCache = function (context) {\n var cache;\n this.fontCaches = this.fontCaches || [];\n for (var i = 0; i < this.fontCaches.length; i++) {\n cache = this.fontCaches[i];\n if (cache.context === context) {\n return cache;\n }\n }\n cache = {\n context: context\n };\n this.fontCaches.push(cache);\n return cache;\n};\n\n// set up canvas context with font\n// returns transformed text string\nCRp$6.setupTextStyle = function (context, ele) {\n var useEleOpacity = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : true;\n // Font style\n var labelStyle = ele.pstyle('font-style').strValue;\n var labelSize = ele.pstyle('font-size').pfValue + 'px';\n var labelFamily = ele.pstyle('font-family').strValue;\n var labelWeight = ele.pstyle('font-weight').strValue;\n var opacity = useEleOpacity ? ele.effectiveOpacity() * ele.pstyle('text-opacity').value : 1;\n var outlineOpacity = ele.pstyle('text-outline-opacity').value * opacity;\n var color = ele.pstyle('color').value;\n var outlineColor = ele.pstyle('text-outline-color').value;\n context.font = labelStyle + ' ' + labelWeight + ' ' + labelSize + ' ' + labelFamily;\n context.lineJoin = 'round'; // so text outlines aren't jagged\n\n this.colorFillStyle(context, color[0], color[1], color[2], opacity);\n this.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], outlineOpacity);\n};\n\n// TODO ensure re-used\nfunction roundRect(ctx, x, y, width, height) {\n var radius = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 5;\n var stroke = arguments.length > 6 ? arguments[6] : undefined;\n ctx.beginPath();\n ctx.moveTo(x + radius, y);\n ctx.lineTo(x + width - radius, y);\n ctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n ctx.lineTo(x + width, y + height - radius);\n ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n ctx.lineTo(x + radius, y + height);\n ctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n ctx.lineTo(x, y + radius);\n ctx.quadraticCurveTo(x, y, x + radius, y);\n ctx.closePath();\n if (stroke) ctx.stroke();else ctx.fill();\n}\nCRp$6.getTextAngle = function (ele, prefix) {\n var theta;\n var _p = ele._private;\n var rscratch = _p.rscratch;\n var pdash = prefix ? prefix + '-' : '';\n var rotation = ele.pstyle(pdash + 'text-rotation');\n var textAngle = getPrefixedProperty(rscratch, 'labelAngle', prefix);\n if (rotation.strValue === 'autorotate') {\n theta = ele.isEdge() ? textAngle : 0;\n } else if (rotation.strValue === 'none') {\n theta = 0;\n } else {\n theta = rotation.pfValue;\n }\n return theta;\n};\nCRp$6.drawText = function (context, ele, prefix) {\n var applyRotation = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n var useEleOpacity = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n var _p = ele._private;\n var rscratch = _p.rscratch;\n var parentOpacity = useEleOpacity ? ele.effectiveOpacity() : 1;\n if (useEleOpacity && (parentOpacity === 0 || ele.pstyle('text-opacity').value === 0)) {\n return;\n }\n\n // use 'main' as an alias for the main label (i.e. null prefix)\n if (prefix === 'main') {\n prefix = null;\n }\n var textX = getPrefixedProperty(rscratch, 'labelX', prefix);\n var textY = getPrefixedProperty(rscratch, 'labelY', prefix);\n var orgTextX, orgTextY; // used for rotation\n var text = this.getLabelText(ele, prefix);\n if (text != null && text !== '' && !isNaN(textX) && !isNaN(textY)) {\n this.setupTextStyle(context, ele, useEleOpacity);\n var pdash = prefix ? prefix + '-' : '';\n var textW = getPrefixedProperty(rscratch, 'labelWidth', prefix);\n var textH = getPrefixedProperty(rscratch, 'labelHeight', prefix);\n var marginX = ele.pstyle(pdash + 'text-margin-x').pfValue;\n var marginY = ele.pstyle(pdash + 'text-margin-y').pfValue;\n var isEdge = ele.isEdge();\n var halign = ele.pstyle('text-halign').value;\n var valign = ele.pstyle('text-valign').value;\n if (isEdge) {\n halign = 'center';\n valign = 'center';\n }\n textX += marginX;\n textY += marginY;\n var theta;\n if (!applyRotation) {\n theta = 0;\n } else {\n theta = this.getTextAngle(ele, prefix);\n }\n if (theta !== 0) {\n orgTextX = textX;\n orgTextY = textY;\n context.translate(orgTextX, orgTextY);\n context.rotate(theta);\n textX = 0;\n textY = 0;\n }\n switch (valign) {\n case 'top':\n break;\n case 'center':\n textY += textH / 2;\n break;\n case 'bottom':\n textY += textH;\n break;\n }\n var backgroundOpacity = ele.pstyle('text-background-opacity').value;\n var borderOpacity = ele.pstyle('text-border-opacity').value;\n var textBorderWidth = ele.pstyle('text-border-width').pfValue;\n var backgroundPadding = ele.pstyle('text-background-padding').pfValue;\n var styleShape = ele.pstyle('text-background-shape').strValue;\n var rounded = styleShape.indexOf('round') === 0;\n var roundRadius = 2;\n if (backgroundOpacity > 0 || textBorderWidth > 0 && borderOpacity > 0) {\n var bgX = textX - backgroundPadding;\n switch (halign) {\n case 'left':\n bgX -= textW;\n break;\n case 'center':\n bgX -= textW / 2;\n break;\n }\n var bgY = textY - textH - backgroundPadding;\n var bgW = textW + 2 * backgroundPadding;\n var bgH = textH + 2 * backgroundPadding;\n if (backgroundOpacity > 0) {\n var textFill = context.fillStyle;\n var textBackgroundColor = ele.pstyle('text-background-color').value;\n context.fillStyle = 'rgba(' + textBackgroundColor[0] + ',' + textBackgroundColor[1] + ',' + textBackgroundColor[2] + ',' + backgroundOpacity * parentOpacity + ')';\n if (rounded) {\n roundRect(context, bgX, bgY, bgW, bgH, roundRadius);\n } else {\n context.fillRect(bgX, bgY, bgW, bgH);\n }\n context.fillStyle = textFill;\n }\n if (textBorderWidth > 0 && borderOpacity > 0) {\n var textStroke = context.strokeStyle;\n var textLineWidth = context.lineWidth;\n var textBorderColor = ele.pstyle('text-border-color').value;\n var textBorderStyle = ele.pstyle('text-border-style').value;\n context.strokeStyle = 'rgba(' + textBorderColor[0] + ',' + textBorderColor[1] + ',' + textBorderColor[2] + ',' + borderOpacity * parentOpacity + ')';\n context.lineWidth = textBorderWidth;\n if (context.setLineDash) {\n // for very outofdate browsers\n switch (textBorderStyle) {\n case 'dotted':\n context.setLineDash([1, 1]);\n break;\n case 'dashed':\n context.setLineDash([4, 2]);\n break;\n case 'double':\n context.lineWidth = textBorderWidth / 4; // 50% reserved for white between the two borders\n context.setLineDash([]);\n break;\n case 'solid':\n context.setLineDash([]);\n break;\n }\n }\n if (rounded) {\n roundRect(context, bgX, bgY, bgW, bgH, roundRadius, 'stroke');\n } else {\n context.strokeRect(bgX, bgY, bgW, bgH);\n }\n if (textBorderStyle === 'double') {\n var whiteWidth = textBorderWidth / 2;\n if (rounded) {\n roundRect(context, bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2, roundRadius, 'stroke');\n } else {\n context.strokeRect(bgX + whiteWidth, bgY + whiteWidth, bgW - whiteWidth * 2, bgH - whiteWidth * 2);\n }\n }\n if (context.setLineDash) {\n // for very outofdate browsers\n context.setLineDash([]);\n }\n context.lineWidth = textLineWidth;\n context.strokeStyle = textStroke;\n }\n }\n var lineWidth = 2 * ele.pstyle('text-outline-width').pfValue; // *2 b/c the stroke is drawn centred on the middle\n\n if (lineWidth > 0) {\n context.lineWidth = lineWidth;\n }\n if (ele.pstyle('text-wrap').value === 'wrap') {\n var lines = getPrefixedProperty(rscratch, 'labelWrapCachedLines', prefix);\n var lineHeight = getPrefixedProperty(rscratch, 'labelLineHeight', prefix);\n var halfTextW = textW / 2;\n var justification = this.getLabelJustification(ele);\n if (justification === 'auto') ; else if (halign === 'left') {\n // auto justification : right\n if (justification === 'left') {\n textX += -textW;\n } else if (justification === 'center') {\n textX += -halfTextW;\n } // else same as auto\n } else if (halign === 'center') {\n // auto justfication : center\n if (justification === 'left') {\n textX += -halfTextW;\n } else if (justification === 'right') {\n textX += halfTextW;\n } // else same as auto\n } else if (halign === 'right') {\n // auto justification : left\n if (justification === 'center') {\n textX += halfTextW;\n } else if (justification === 'right') {\n textX += textW;\n } // else same as auto\n }\n\n switch (valign) {\n case 'top':\n textY -= (lines.length - 1) * lineHeight;\n break;\n case 'center':\n case 'bottom':\n textY -= (lines.length - 1) * lineHeight;\n break;\n }\n for (var l = 0; l < lines.length; l++) {\n if (lineWidth > 0) {\n context.strokeText(lines[l], textX, textY);\n }\n context.fillText(lines[l], textX, textY);\n textY += lineHeight;\n }\n } else {\n if (lineWidth > 0) {\n context.strokeText(text, textX, textY);\n }\n context.fillText(text, textX, textY);\n }\n if (theta !== 0) {\n context.rotate(-theta);\n context.translate(-orgTextX, -orgTextY);\n }\n }\n};\n\n/* global Path2D */\nvar CRp$5 = {};\nCRp$5.drawNode = function (context, node, shiftToOriginWithBb) {\n var drawLabel = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : true;\n var shouldDrawOverlay = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : true;\n var shouldDrawOpacity = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : true;\n var r = this;\n var nodeWidth, nodeHeight;\n var _p = node._private;\n var rs = _p.rscratch;\n var pos = node.position();\n if (!number$1(pos.x) || !number$1(pos.y)) {\n return; // can't draw node with undefined position\n }\n\n if (shouldDrawOpacity && !node.visible()) {\n return;\n }\n var eleOpacity = shouldDrawOpacity ? node.effectiveOpacity() : 1;\n var usePaths = r.usePaths();\n var path;\n var pathCacheHit = false;\n var padding = node.padding();\n nodeWidth = node.width() + 2 * padding;\n nodeHeight = node.height() + 2 * padding;\n\n //\n // setup shift\n\n var bb;\n if (shiftToOriginWithBb) {\n bb = shiftToOriginWithBb;\n context.translate(-bb.x1, -bb.y1);\n }\n\n //\n // load bg image\n\n var bgImgProp = node.pstyle('background-image');\n var urls = bgImgProp.value;\n var urlDefined = new Array(urls.length);\n var image = new Array(urls.length);\n var numImages = 0;\n for (var i = 0; i < urls.length; i++) {\n var url = urls[i];\n var defd = urlDefined[i] = url != null && url !== 'none';\n if (defd) {\n var bgImgCrossOrigin = node.cy().style().getIndexedStyle(node, 'background-image-crossorigin', 'value', i);\n numImages++;\n\n // get image, and if not loaded then ask to redraw when later loaded\n image[i] = r.getCachedImage(url, bgImgCrossOrigin, function () {\n _p.backgroundTimestamp = Date.now();\n node.emitAndNotify('background');\n });\n }\n }\n\n //\n // setup styles\n\n var darkness = node.pstyle('background-blacken').value;\n var borderWidth = node.pstyle('border-width').pfValue;\n var bgOpacity = node.pstyle('background-opacity').value * eleOpacity;\n var borderColor = node.pstyle('border-color').value;\n var borderStyle = node.pstyle('border-style').value;\n var borderJoin = node.pstyle('border-join').value;\n var borderCap = node.pstyle('border-cap').value;\n var borderPosition = node.pstyle('border-position').value;\n var borderPattern = node.pstyle('border-dash-pattern').pfValue;\n var borderOffset = node.pstyle('border-dash-offset').pfValue;\n var borderOpacity = node.pstyle('border-opacity').value * eleOpacity;\n var outlineWidth = node.pstyle('outline-width').pfValue;\n var outlineColor = node.pstyle('outline-color').value;\n var outlineStyle = node.pstyle('outline-style').value;\n var outlineOpacity = node.pstyle('outline-opacity').value * eleOpacity;\n var outlineOffset = node.pstyle('outline-offset').value;\n var cornerRadius = node.pstyle('corner-radius').value;\n if (cornerRadius !== 'auto') cornerRadius = node.pstyle('corner-radius').pfValue;\n var setupShapeColor = function setupShapeColor() {\n var bgOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : bgOpacity;\n r.eleFillStyle(context, node, bgOpy);\n };\n var setupBorderColor = function setupBorderColor() {\n var bdrOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : borderOpacity;\n r.colorStrokeStyle(context, borderColor[0], borderColor[1], borderColor[2], bdrOpy);\n };\n var setupOutlineColor = function setupOutlineColor() {\n var otlnOpy = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : outlineOpacity;\n r.colorStrokeStyle(context, outlineColor[0], outlineColor[1], outlineColor[2], otlnOpy);\n };\n\n //\n // setup shape\n\n var getPath = function getPath(width, height, shape, points) {\n var pathCache = r.nodePathCache = r.nodePathCache || [];\n var key = hashStrings(shape === 'polygon' ? shape + ',' + points.join(',') : shape, '' + height, '' + width, '' + cornerRadius);\n var cachedPath = pathCache[key];\n var path;\n var cacheHit = false;\n if (cachedPath != null) {\n path = cachedPath;\n cacheHit = true;\n rs.pathCache = path;\n } else {\n path = new Path2D();\n pathCache[key] = rs.pathCache = path;\n }\n return {\n path: path,\n cacheHit: cacheHit\n };\n };\n var styleShape = node.pstyle('shape').strValue;\n var shapePts = node.pstyle('shape-polygon-points').pfValue;\n if (usePaths) {\n context.translate(pos.x, pos.y);\n var shapePath = getPath(nodeWidth, nodeHeight, styleShape, shapePts);\n path = shapePath.path;\n pathCacheHit = shapePath.cacheHit;\n }\n var drawShape = function drawShape() {\n if (!pathCacheHit) {\n var npos = pos;\n if (usePaths) {\n npos = {\n x: 0,\n y: 0\n };\n }\n r.nodeShapes[r.getNodeShape(node)].draw(path || context, npos.x, npos.y, nodeWidth, nodeHeight, cornerRadius, rs);\n }\n if (usePaths) {\n context.fill(path);\n } else {\n context.fill();\n }\n };\n var drawImages = function drawImages() {\n var nodeOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity;\n var inside = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;\n var prevBging = _p.backgrounding;\n var totalCompleted = 0;\n for (var _i = 0; _i < image.length; _i++) {\n var bgContainment = node.cy().style().getIndexedStyle(node, 'background-image-containment', 'value', _i);\n if (inside && bgContainment === 'over' || !inside && bgContainment === 'inside') {\n totalCompleted++;\n continue;\n }\n if (urlDefined[_i] && image[_i].complete && !image[_i].error) {\n totalCompleted++;\n r.drawInscribedImage(context, image[_i], node, _i, nodeOpacity);\n }\n }\n _p.backgrounding = !(totalCompleted === numImages);\n if (prevBging !== _p.backgrounding) {\n // update style b/c :backgrounding state changed\n node.updateStyle(false);\n }\n };\n var drawPie = function drawPie() {\n var redrawShape = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n var pieOpacity = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : eleOpacity;\n if (r.hasPie(node)) {\n r.drawPie(context, node, pieOpacity);\n\n // redraw/restore path if steps after pie need it\n if (redrawShape) {\n if (!usePaths) {\n r.nodeShapes[r.getNodeShape(node)].draw(context, pos.x, pos.y, nodeWidth, nodeHeight, cornerRadius, rs);\n }\n }\n }\n };\n var darken = function darken() {\n var darkenOpacity = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : eleOpacity;\n var opacity = (darkness > 0 ? darkness : -darkness) * darkenOpacity;\n var c = darkness > 0 ? 0 : 255;\n if (darkness !== 0) {\n r.colorFillStyle(context, c, c, c, opacity);\n if (usePaths) {\n context.fill(path);\n } else {\n context.fill();\n }\n }\n };\n var drawBorder = function drawBorder() {\n if (borderWidth > 0) {\n context.lineWidth = borderWidth;\n context.lineCap = borderCap;\n context.lineJoin = borderJoin;\n if (context.setLineDash) {\n // for very outofdate browsers\n switch (borderStyle) {\n case 'dotted':\n context.setLineDash([1, 1]);\n break;\n case 'dashed':\n context.setLineDash(borderPattern);\n context.lineDashOffset = borderOffset;\n break;\n case 'solid':\n case 'double':\n context.setLineDash([]);\n break;\n }\n }\n if (borderPosition !== 'center') {\n context.save();\n context.lineWidth *= 2;\n if (borderPosition === 'inside') {\n usePaths ? context.clip(path) : context.clip();\n } else {\n var region = new Path2D();\n region.rect(-nodeWidth / 2 - borderWidth, -nodeHeight / 2 - borderWidth, nodeWidth + 2 * borderWidth, nodeHeight + 2 * borderWidth);\n region.addPath(path);\n context.clip(region, 'evenodd');\n }\n usePaths ? context.stroke(path) : context.stroke();\n context.restore();\n } else {\n usePaths ? context.stroke(path) : context.stroke();\n }\n if (borderStyle === 'double') {\n context.lineWidth = borderWidth / 3;\n var gco = context.globalCompositeOperation;\n context.globalCompositeOperation = 'destination-out';\n if (usePaths) {\n context.stroke(path);\n } else {\n context.stroke();\n }\n context.globalCompositeOperation = gco;\n }\n\n // reset in case we changed the border style\n if (context.setLineDash) {\n // for very outofdate browsers\n context.setLineDash([]);\n }\n }\n };\n var drawOutline = function drawOutline() {\n if (outlineWidth > 0) {\n context.lineWidth = outlineWidth;\n context.lineCap = 'butt';\n if (context.setLineDash) {\n // for very outofdate browsers\n switch (outlineStyle) {\n case 'dotted':\n context.setLineDash([1, 1]);\n break;\n case 'dashed':\n context.setLineDash([4, 2]);\n break;\n case 'solid':\n case 'double':\n context.setLineDash([]);\n break;\n }\n }\n var npos = pos;\n if (usePaths) {\n npos = {\n x: 0,\n y: 0\n };\n }\n var shape = r.getNodeShape(node);\n var bWidth = borderWidth;\n if (borderPosition === 'inside') bWidth = 0;\n if (borderPosition === 'outside') bWidth *= 2;\n var scaleX = (nodeWidth + bWidth + (outlineWidth + outlineOffset)) / nodeWidth;\n var scaleY = (nodeHeight + bWidth + (outlineWidth + outlineOffset)) / nodeHeight;\n var sWidth = nodeWidth * scaleX;\n var sHeight = nodeHeight * scaleY;\n var points = r.nodeShapes[shape].points;\n var _path;\n if (usePaths) {\n var outlinePath = getPath(sWidth, sHeight, shape, points);\n _path = outlinePath.path;\n }\n\n // draw the outline path, either by using expanded points or by scaling \n // the dimensions, depending on shape\n if (shape === \"ellipse\") {\n r.drawEllipsePath(_path || context, npos.x, npos.y, sWidth, sHeight);\n } else if (['round-diamond', 'round-heptagon', 'round-hexagon', 'round-octagon', 'round-pentagon', 'round-polygon', 'round-triangle', 'round-tag'].includes(shape)) {\n var sMult = 0;\n var offsetX = 0;\n var offsetY = 0;\n if (shape === 'round-diamond') {\n sMult = (bWidth + outlineOffset + outlineWidth) * 1.4;\n } else if (shape === 'round-heptagon') {\n sMult = (bWidth + outlineOffset + outlineWidth) * 1.075;\n offsetY = -(bWidth / 2 + outlineOffset + outlineWidth) / 35;\n } else if (shape === 'round-hexagon') {\n sMult = (bWidth + outlineOffset + outlineWidth) * 1.12;\n } else if (shape === 'round-pentagon') {\n sMult = (bWidth + outlineOffset + outlineWidth) * 1.13;\n offsetY = -(bWidth / 2 + outlineOffset + outlineWidth) / 15;\n } else if (shape === 'round-tag') {\n sMult = (bWidth + outlineOffset + outlineWidth) * 1.12;\n offsetX = (bWidth / 2 + outlineWidth + outlineOffset) * .07;\n } else if (shape === 'round-triangle') {\n sMult = (bWidth + outlineOffset + outlineWidth) * (Math.PI / 2);\n offsetY = -(bWidth + outlineOffset / 2 + outlineWidth) / Math.PI;\n }\n if (sMult !== 0) {\n scaleX = (nodeWidth + sMult) / nodeWidth;\n sWidth = nodeWidth * scaleX;\n if (!['round-hexagon', 'round-tag'].includes(shape)) {\n scaleY = (nodeHeight + sMult) / nodeHeight;\n sHeight = nodeHeight * scaleY;\n }\n }\n cornerRadius = cornerRadius === 'auto' ? getRoundPolygonRadius(sWidth, sHeight) : cornerRadius;\n var halfW = sWidth / 2;\n var halfH = sHeight / 2;\n var radius = cornerRadius + (bWidth + outlineWidth + outlineOffset) / 2;\n var p = new Array(points.length / 2);\n var corners = new Array(points.length / 2);\n for (var _i3 = 0; _i3 < points.length / 2; _i3++) {\n p[_i3] = {\n x: npos.x + offsetX + halfW * points[_i3 * 2],\n y: npos.y + offsetY + halfH * points[_i3 * 2 + 1]\n };\n }\n var _i2,\n p1,\n p2,\n p3,\n len = p.length;\n p1 = p[len - 1];\n // for each point\n for (_i2 = 0; _i2 < len; _i2++) {\n p2 = p[_i2 % len];\n p3 = p[(_i2 + 1) % len];\n corners[_i2] = getRoundCorner(p1, p2, p3, radius);\n p1 = p2;\n p2 = p3;\n }\n r.drawRoundPolygonPath(_path || context, npos.x + offsetX, npos.y + offsetY, nodeWidth * scaleX, nodeHeight * scaleY, points, corners);\n } else if (['roundrectangle', 'round-rectangle'].includes(shape)) {\n cornerRadius = cornerRadius === 'auto' ? getRoundRectangleRadius(sWidth, sHeight) : cornerRadius;\n r.drawRoundRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight, cornerRadius + (bWidth + outlineWidth + outlineOffset) / 2);\n } else if (['cutrectangle', 'cut-rectangle'].includes(shape)) {\n cornerRadius = cornerRadius === 'auto' ? getCutRectangleCornerLength() : cornerRadius;\n r.drawCutRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight, null, cornerRadius + (bWidth + outlineWidth + outlineOffset) / 4);\n } else if (['bottomroundrectangle', 'bottom-round-rectangle'].includes(shape)) {\n cornerRadius = cornerRadius === 'auto' ? getRoundRectangleRadius(sWidth, sHeight) : cornerRadius;\n r.drawBottomRoundRectanglePath(_path || context, npos.x, npos.y, sWidth, sHeight, cornerRadius + (bWidth + outlineWidth + outlineOffset) / 2);\n } else if (shape === \"barrel\") {\n r.drawBarrelPath(_path || context, npos.x, npos.y, sWidth, sHeight);\n } else if (shape.startsWith(\"polygon\") || ['rhomboid', 'right-rhomboid', 'round-tag', 'tag', 'vee'].includes(shape)) {\n var pad = (bWidth + outlineWidth + outlineOffset) / nodeWidth;\n points = joinLines(expandPolygon(points, pad));\n r.drawPolygonPath(_path || context, npos.x, npos.y, nodeWidth, nodeHeight, points);\n } else {\n var _pad = (bWidth + outlineWidth + outlineOffset) / nodeWidth;\n points = joinLines(expandPolygon(points, -_pad));\n r.drawPolygonPath(_path || context, npos.x, npos.y, nodeWidth, nodeHeight, points);\n }\n if (usePaths) {\n context.stroke(_path);\n } else {\n context.stroke();\n }\n if (outlineStyle === 'double') {\n context.lineWidth = bWidth / 3;\n var gco = context.globalCompositeOperation;\n context.globalCompositeOperation = 'destination-out';\n if (usePaths) {\n context.stroke(_path);\n } else {\n context.stroke();\n }\n context.globalCompositeOperation = gco;\n }\n\n // reset in case we changed the border style\n if (context.setLineDash) {\n // for very outofdate browsers\n context.setLineDash([]);\n }\n }\n };\n var drawOverlay = function drawOverlay() {\n if (shouldDrawOverlay) {\n r.drawNodeOverlay(context, node, pos, nodeWidth, nodeHeight);\n }\n };\n var drawUnderlay = function drawUnderlay() {\n if (shouldDrawOverlay) {\n r.drawNodeUnderlay(context, node, pos, nodeWidth, nodeHeight);\n }\n };\n var drawText = function drawText() {\n r.drawElementText(context, node, null, drawLabel);\n };\n var ghost = node.pstyle('ghost').value === 'yes';\n if (ghost) {\n var gx = node.pstyle('ghost-offset-x').pfValue;\n var gy = node.pstyle('ghost-offset-y').pfValue;\n var ghostOpacity = node.pstyle('ghost-opacity').value;\n var effGhostOpacity = ghostOpacity * eleOpacity;\n context.translate(gx, gy);\n setupOutlineColor();\n drawOutline();\n setupShapeColor(ghostOpacity * bgOpacity);\n drawShape();\n drawImages(effGhostOpacity, true);\n setupBorderColor(ghostOpacity * borderOpacity);\n drawBorder();\n drawPie(darkness !== 0 || borderWidth !== 0);\n drawImages(effGhostOpacity, false);\n darken(effGhostOpacity);\n context.translate(-gx, -gy);\n }\n if (usePaths) {\n context.translate(-pos.x, -pos.y);\n }\n drawUnderlay();\n if (usePaths) {\n context.translate(pos.x, pos.y);\n }\n setupOutlineColor();\n drawOutline();\n setupShapeColor();\n drawShape();\n drawImages(eleOpacity, true);\n setupBorderColor();\n drawBorder();\n drawPie(darkness !== 0 || borderWidth !== 0);\n drawImages(eleOpacity, false);\n darken();\n if (usePaths) {\n context.translate(-pos.x, -pos.y);\n }\n drawText();\n drawOverlay();\n\n //\n // clean up shift\n\n if (shiftToOriginWithBb) {\n context.translate(bb.x1, bb.y1);\n }\n};\nvar drawNodeOverlayUnderlay = function drawNodeOverlayUnderlay(overlayOrUnderlay) {\n if (!['overlay', 'underlay'].includes(overlayOrUnderlay)) {\n throw new Error('Invalid state');\n }\n return function (context, node, pos, nodeWidth, nodeHeight) {\n var r = this;\n if (!node.visible()) {\n return;\n }\n var padding = node.pstyle(\"\".concat(overlayOrUnderlay, \"-padding\")).pfValue;\n var opacity = node.pstyle(\"\".concat(overlayOrUnderlay, \"-opacity\")).value;\n var color = node.pstyle(\"\".concat(overlayOrUnderlay, \"-color\")).value;\n var shape = node.pstyle(\"\".concat(overlayOrUnderlay, \"-shape\")).value;\n var radius = node.pstyle(\"\".concat(overlayOrUnderlay, \"-corner-radius\")).value;\n if (opacity > 0) {\n pos = pos || node.position();\n if (nodeWidth == null || nodeHeight == null) {\n var _padding = node.padding();\n nodeWidth = node.width() + 2 * _padding;\n nodeHeight = node.height() + 2 * _padding;\n }\n r.colorFillStyle(context, color[0], color[1], color[2], opacity);\n r.nodeShapes[shape].draw(context, pos.x, pos.y, nodeWidth + padding * 2, nodeHeight + padding * 2, radius);\n context.fill();\n }\n };\n};\nCRp$5.drawNodeOverlay = drawNodeOverlayUnderlay('overlay');\nCRp$5.drawNodeUnderlay = drawNodeOverlayUnderlay('underlay');\n\n// does the node have at least one pie piece?\nCRp$5.hasPie = function (node) {\n node = node[0]; // ensure ele ref\n\n return node._private.hasPie;\n};\nCRp$5.drawPie = function (context, node, nodeOpacity, pos) {\n node = node[0]; // ensure ele ref\n pos = pos || node.position();\n var cyStyle = node.cy().style();\n var pieSize = node.pstyle('pie-size');\n var x = pos.x;\n var y = pos.y;\n var nodeW = node.width();\n var nodeH = node.height();\n var radius = Math.min(nodeW, nodeH) / 2; // must fit in node\n var lastPercent = 0; // what % to continue drawing pie slices from on [0, 1]\n var usePaths = this.usePaths();\n if (usePaths) {\n x = 0;\n y = 0;\n }\n if (pieSize.units === '%') {\n radius = radius * pieSize.pfValue;\n } else if (pieSize.pfValue !== undefined) {\n radius = pieSize.pfValue / 2;\n }\n for (var i = 1; i <= cyStyle.pieBackgroundN; i++) {\n // 1..N\n var size = node.pstyle('pie-' + i + '-background-size').value;\n var color = node.pstyle('pie-' + i + '-background-color').value;\n var opacity = node.pstyle('pie-' + i + '-background-opacity').value * nodeOpacity;\n var percent = size / 100; // map integer range [0, 100] to [0, 1]\n\n // percent can't push beyond 1\n if (percent + lastPercent > 1) {\n percent = 1 - lastPercent;\n }\n var angleStart = 1.5 * Math.PI + 2 * Math.PI * lastPercent; // start at 12 o'clock and go clockwise\n var angleDelta = 2 * Math.PI * percent;\n var angleEnd = angleStart + angleDelta;\n\n // ignore if\n // - zero size\n // - we're already beyond the full circle\n // - adding the current slice would go beyond the full circle\n if (size === 0 || lastPercent >= 1 || lastPercent + percent > 1) {\n continue;\n }\n context.beginPath();\n context.moveTo(x, y);\n context.arc(x, y, radius, angleStart, angleEnd);\n context.closePath();\n this.colorFillStyle(context, color[0], color[1], color[2], opacity);\n context.fill();\n lastPercent += percent;\n }\n};\n\nvar CRp$4 = {};\nvar motionBlurDelay = 100;\n\n// var isFirefox = typeof InstallTrigger !== 'undefined';\n\nCRp$4.getPixelRatio = function () {\n var context = this.data.contexts[0];\n if (this.forcedPixelRatio != null) {\n return this.forcedPixelRatio;\n }\n var containerWindow = this.cy.window();\n var backingStore = context.backingStorePixelRatio || context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1;\n return (containerWindow.devicePixelRatio || 1) / backingStore; // eslint-disable-line no-undef\n};\n\nCRp$4.paintCache = function (context) {\n var caches = this.paintCaches = this.paintCaches || [];\n var needToCreateCache = true;\n var cache;\n for (var i = 0; i < caches.length; i++) {\n cache = caches[i];\n if (cache.context === context) {\n needToCreateCache = false;\n break;\n }\n }\n if (needToCreateCache) {\n cache = {\n context: context\n };\n caches.push(cache);\n }\n return cache;\n};\nCRp$4.createGradientStyleFor = function (context, shapeStyleName, ele, fill, opacity) {\n var gradientStyle;\n var usePaths = this.usePaths();\n var colors = ele.pstyle(shapeStyleName + '-gradient-stop-colors').value,\n positions = ele.pstyle(shapeStyleName + '-gradient-stop-positions').pfValue;\n if (fill === 'radial-gradient') {\n if (ele.isEdge()) {\n var start = ele.sourceEndpoint(),\n end = ele.targetEndpoint(),\n mid = ele.midpoint();\n var d1 = dist(start, mid);\n var d2 = dist(end, mid);\n gradientStyle = context.createRadialGradient(mid.x, mid.y, 0, mid.x, mid.y, Math.max(d1, d2));\n } else {\n var pos = usePaths ? {\n x: 0,\n y: 0\n } : ele.position(),\n width = ele.paddedWidth(),\n height = ele.paddedHeight();\n gradientStyle = context.createRadialGradient(pos.x, pos.y, 0, pos.x, pos.y, Math.max(width, height));\n }\n } else {\n if (ele.isEdge()) {\n var _start = ele.sourceEndpoint(),\n _end = ele.targetEndpoint();\n gradientStyle = context.createLinearGradient(_start.x, _start.y, _end.x, _end.y);\n } else {\n var _pos = usePaths ? {\n x: 0,\n y: 0\n } : ele.position(),\n _width = ele.paddedWidth(),\n _height = ele.paddedHeight(),\n halfWidth = _width / 2,\n halfHeight = _height / 2;\n var direction = ele.pstyle('background-gradient-direction').value;\n switch (direction) {\n case 'to-bottom':\n gradientStyle = context.createLinearGradient(_pos.x, _pos.y - halfHeight, _pos.x, _pos.y + halfHeight);\n break;\n case 'to-top':\n gradientStyle = context.createLinearGradient(_pos.x, _pos.y + halfHeight, _pos.x, _pos.y - halfHeight);\n break;\n case 'to-left':\n gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y, _pos.x - halfWidth, _pos.y);\n break;\n case 'to-right':\n gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y, _pos.x + halfWidth, _pos.y);\n break;\n case 'to-bottom-right':\n case 'to-right-bottom':\n gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y - halfHeight, _pos.x + halfWidth, _pos.y + halfHeight);\n break;\n case 'to-top-right':\n case 'to-right-top':\n gradientStyle = context.createLinearGradient(_pos.x - halfWidth, _pos.y + halfHeight, _pos.x + halfWidth, _pos.y - halfHeight);\n break;\n case 'to-bottom-left':\n case 'to-left-bottom':\n gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y - halfHeight, _pos.x - halfWidth, _pos.y + halfHeight);\n break;\n case 'to-top-left':\n case 'to-left-top':\n gradientStyle = context.createLinearGradient(_pos.x + halfWidth, _pos.y + halfHeight, _pos.x - halfWidth, _pos.y - halfHeight);\n break;\n }\n }\n }\n if (!gradientStyle) return null; // invalid gradient style\n\n var hasPositions = positions.length === colors.length;\n var length = colors.length;\n for (var i = 0; i < length; i++) {\n gradientStyle.addColorStop(hasPositions ? positions[i] : i / (length - 1), 'rgba(' + colors[i][0] + ',' + colors[i][1] + ',' + colors[i][2] + ',' + opacity + ')');\n }\n return gradientStyle;\n};\nCRp$4.gradientFillStyle = function (context, ele, fill, opacity) {\n var gradientStyle = this.createGradientStyleFor(context, 'background', ele, fill, opacity);\n if (!gradientStyle) return null; // error\n context.fillStyle = gradientStyle;\n};\nCRp$4.colorFillStyle = function (context, r, g, b, a) {\n context.fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n // turn off for now, seems context does its own caching\n\n // var cache = this.paintCache(context);\n\n // var fillStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // if( cache.fillStyle !== fillStyle ){\n // context.fillStyle = cache.fillStyle = fillStyle;\n // }\n};\n\nCRp$4.eleFillStyle = function (context, ele, opacity) {\n var backgroundFill = ele.pstyle('background-fill').value;\n if (backgroundFill === 'linear-gradient' || backgroundFill === 'radial-gradient') {\n this.gradientFillStyle(context, ele, backgroundFill, opacity);\n } else {\n var backgroundColor = ele.pstyle('background-color').value;\n this.colorFillStyle(context, backgroundColor[0], backgroundColor[1], backgroundColor[2], opacity);\n }\n};\nCRp$4.gradientStrokeStyle = function (context, ele, fill, opacity) {\n var gradientStyle = this.createGradientStyleFor(context, 'line', ele, fill, opacity);\n if (!gradientStyle) return null; // error\n context.strokeStyle = gradientStyle;\n};\nCRp$4.colorStrokeStyle = function (context, r, g, b, a) {\n context.strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n // turn off for now, seems context does its own caching\n\n // var cache = this.paintCache(context);\n\n // var strokeStyle = 'rgba(' + r + ',' + g + ',' + b + ',' + a + ')';\n\n // if( cache.strokeStyle !== strokeStyle ){\n // context.strokeStyle = cache.strokeStyle = strokeStyle;\n // }\n};\n\nCRp$4.eleStrokeStyle = function (context, ele, opacity) {\n var lineFill = ele.pstyle('line-fill').value;\n if (lineFill === 'linear-gradient' || lineFill === 'radial-gradient') {\n this.gradientStrokeStyle(context, ele, lineFill, opacity);\n } else {\n var lineColor = ele.pstyle('line-color').value;\n this.colorStrokeStyle(context, lineColor[0], lineColor[1], lineColor[2], opacity);\n }\n};\n\n// Resize canvas\nCRp$4.matchCanvasSize = function (container) {\n var r = this;\n var data = r.data;\n var bb = r.findContainerClientCoords();\n var width = bb[2];\n var height = bb[3];\n var pixelRatio = r.getPixelRatio();\n var mbPxRatio = r.motionBlurPxRatio;\n if (container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE] || container === r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG]) {\n pixelRatio = mbPxRatio;\n }\n var canvasWidth = width * pixelRatio;\n var canvasHeight = height * pixelRatio;\n var canvas;\n if (canvasWidth === r.canvasWidth && canvasHeight === r.canvasHeight) {\n return; // save cycles if same\n }\n\n r.fontCaches = null; // resizing resets the style\n\n var canvasContainer = data.canvasContainer;\n canvasContainer.style.width = width + 'px';\n canvasContainer.style.height = height + 'px';\n for (var i = 0; i < r.CANVAS_LAYERS; i++) {\n canvas = data.canvases[i];\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n }\n for (var i = 0; i < r.BUFFER_COUNT; i++) {\n canvas = data.bufferCanvases[i];\n canvas.width = canvasWidth;\n canvas.height = canvasHeight;\n canvas.style.width = width + 'px';\n canvas.style.height = height + 'px';\n }\n r.textureMult = 1;\n if (pixelRatio <= 1) {\n canvas = data.bufferCanvases[r.TEXTURE_BUFFER];\n r.textureMult = 2;\n canvas.width = canvasWidth * r.textureMult;\n canvas.height = canvasHeight * r.textureMult;\n }\n r.canvasWidth = canvasWidth;\n r.canvasHeight = canvasHeight;\n};\nCRp$4.renderTo = function (cxt, zoom, pan, pxRatio) {\n this.render({\n forcedContext: cxt,\n forcedZoom: zoom,\n forcedPan: pan,\n drawAllLayers: true,\n forcedPxRatio: pxRatio\n });\n};\nCRp$4.render = function (options) {\n options = options || staticEmptyObject();\n var forcedContext = options.forcedContext;\n var drawAllLayers = options.drawAllLayers;\n var drawOnlyNodeLayer = options.drawOnlyNodeLayer;\n var forcedZoom = options.forcedZoom;\n var forcedPan = options.forcedPan;\n var r = this;\n var pixelRatio = options.forcedPxRatio === undefined ? this.getPixelRatio() : options.forcedPxRatio;\n var cy = r.cy;\n var data = r.data;\n var needDraw = data.canvasNeedsRedraw;\n var textureDraw = r.textureOnViewport && !forcedContext && (r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming);\n var motionBlur = options.motionBlur !== undefined ? options.motionBlur : r.motionBlur;\n var mbPxRatio = r.motionBlurPxRatio;\n var hasCompoundNodes = cy.hasCompoundNodes();\n var inNodeDragGesture = r.hoverData.draggingEles;\n var inBoxSelection = r.hoverData.selecting || r.touchData.selecting ? true : false;\n motionBlur = motionBlur && !forcedContext && r.motionBlurEnabled && !inBoxSelection;\n var motionBlurFadeEffect = motionBlur;\n if (!forcedContext) {\n if (r.prevPxRatio !== pixelRatio) {\n r.invalidateContainerClientCoordsCache();\n r.matchCanvasSize(r.container);\n r.redrawHint('eles', true);\n r.redrawHint('drag', true);\n }\n r.prevPxRatio = pixelRatio;\n }\n if (!forcedContext && r.motionBlurTimeout) {\n clearTimeout(r.motionBlurTimeout);\n }\n if (motionBlur) {\n if (r.mbFrames == null) {\n r.mbFrames = 0;\n }\n r.mbFrames++;\n if (r.mbFrames < 3) {\n // need several frames before even high quality motionblur\n motionBlurFadeEffect = false;\n }\n\n // go to lower quality blurry frames when several m/b frames have been rendered (avoids flashing)\n if (r.mbFrames > r.minMbLowQualFrames) {\n //r.fullQualityMb = false;\n r.motionBlurPxRatio = r.mbPxRBlurry;\n }\n }\n if (r.clearingMotionBlur) {\n r.motionBlurPxRatio = 1;\n }\n\n // b/c drawToContext() may be async w.r.t. redraw(), keep track of last texture frame\n // because a rogue async texture frame would clear needDraw\n if (r.textureDrawLastFrame && !textureDraw) {\n needDraw[r.NODE] = true;\n needDraw[r.SELECT_BOX] = true;\n }\n var style = cy.style();\n var zoom = cy.zoom();\n var effectiveZoom = forcedZoom !== undefined ? forcedZoom : zoom;\n var pan = cy.pan();\n var effectivePan = {\n x: pan.x,\n y: pan.y\n };\n var vp = {\n zoom: zoom,\n pan: {\n x: pan.x,\n y: pan.y\n }\n };\n var prevVp = r.prevViewport;\n var viewportIsDiff = prevVp === undefined || vp.zoom !== prevVp.zoom || vp.pan.x !== prevVp.pan.x || vp.pan.y !== prevVp.pan.y;\n\n // we want the low quality motionblur only when the viewport is being manipulated etc (where it's not noticed)\n if (!viewportIsDiff && !(inNodeDragGesture && !hasCompoundNodes)) {\n r.motionBlurPxRatio = 1;\n }\n if (forcedPan) {\n effectivePan = forcedPan;\n }\n\n // apply pixel ratio\n\n effectiveZoom *= pixelRatio;\n effectivePan.x *= pixelRatio;\n effectivePan.y *= pixelRatio;\n var eles = r.getCachedZSortedEles();\n function mbclear(context, x, y, w, h) {\n var gco = context.globalCompositeOperation;\n context.globalCompositeOperation = 'destination-out';\n r.colorFillStyle(context, 255, 255, 255, r.motionBlurTransparency);\n context.fillRect(x, y, w, h);\n context.globalCompositeOperation = gco;\n }\n function setContextTransform(context, clear) {\n var ePan, eZoom, w, h;\n if (!r.clearingMotionBlur && (context === data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] || context === data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG])) {\n ePan = {\n x: pan.x * mbPxRatio,\n y: pan.y * mbPxRatio\n };\n eZoom = zoom * mbPxRatio;\n w = r.canvasWidth * mbPxRatio;\n h = r.canvasHeight * mbPxRatio;\n } else {\n ePan = effectivePan;\n eZoom = effectiveZoom;\n w = r.canvasWidth;\n h = r.canvasHeight;\n }\n context.setTransform(1, 0, 0, 1, 0, 0);\n if (clear === 'motionBlur') {\n mbclear(context, 0, 0, w, h);\n } else if (!forcedContext && (clear === undefined || clear)) {\n context.clearRect(0, 0, w, h);\n }\n if (!drawAllLayers) {\n context.translate(ePan.x, ePan.y);\n context.scale(eZoom, eZoom);\n }\n if (forcedPan) {\n context.translate(forcedPan.x, forcedPan.y);\n }\n if (forcedZoom) {\n context.scale(forcedZoom, forcedZoom);\n }\n }\n if (!textureDraw) {\n r.textureDrawLastFrame = false;\n }\n if (textureDraw) {\n r.textureDrawLastFrame = true;\n if (!r.textureCache) {\n r.textureCache = {};\n r.textureCache.bb = cy.mutableElements().boundingBox();\n r.textureCache.texture = r.data.bufferCanvases[r.TEXTURE_BUFFER];\n var cxt = r.data.bufferContexts[r.TEXTURE_BUFFER];\n cxt.setTransform(1, 0, 0, 1, 0, 0);\n cxt.clearRect(0, 0, r.canvasWidth * r.textureMult, r.canvasHeight * r.textureMult);\n r.render({\n forcedContext: cxt,\n drawOnlyNodeLayer: true,\n forcedPxRatio: pixelRatio * r.textureMult\n });\n var vp = r.textureCache.viewport = {\n zoom: cy.zoom(),\n pan: cy.pan(),\n width: r.canvasWidth,\n height: r.canvasHeight\n };\n vp.mpan = {\n x: (0 - vp.pan.x) / vp.zoom,\n y: (0 - vp.pan.y) / vp.zoom\n };\n }\n needDraw[r.DRAG] = false;\n needDraw[r.NODE] = false;\n var context = data.contexts[r.NODE];\n var texture = r.textureCache.texture;\n var vp = r.textureCache.viewport;\n context.setTransform(1, 0, 0, 1, 0, 0);\n if (motionBlur) {\n mbclear(context, 0, 0, vp.width, vp.height);\n } else {\n context.clearRect(0, 0, vp.width, vp.height);\n }\n var outsideBgColor = style.core('outside-texture-bg-color').value;\n var outsideBgOpacity = style.core('outside-texture-bg-opacity').value;\n r.colorFillStyle(context, outsideBgColor[0], outsideBgColor[1], outsideBgColor[2], outsideBgOpacity);\n context.fillRect(0, 0, vp.width, vp.height);\n var zoom = cy.zoom();\n setContextTransform(context, false);\n context.clearRect(vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio);\n context.drawImage(texture, vp.mpan.x, vp.mpan.y, vp.width / vp.zoom / pixelRatio, vp.height / vp.zoom / pixelRatio);\n } else if (r.textureOnViewport && !forcedContext) {\n // clear the cache since we don't need it\n r.textureCache = null;\n }\n var extent = cy.extent();\n var vpManip = r.pinching || r.hoverData.dragging || r.swipePanning || r.data.wheelZooming || r.hoverData.draggingEles || r.cy.animated();\n var hideEdges = r.hideEdgesOnViewport && vpManip;\n var needMbClear = [];\n needMbClear[r.NODE] = !needDraw[r.NODE] && motionBlur && !r.clearedForMotionBlur[r.NODE] || r.clearingMotionBlur;\n if (needMbClear[r.NODE]) {\n r.clearedForMotionBlur[r.NODE] = true;\n }\n needMbClear[r.DRAG] = !needDraw[r.DRAG] && motionBlur && !r.clearedForMotionBlur[r.DRAG] || r.clearingMotionBlur;\n if (needMbClear[r.DRAG]) {\n r.clearedForMotionBlur[r.DRAG] = true;\n }\n if (needDraw[r.NODE] || drawAllLayers || drawOnlyNodeLayer || needMbClear[r.NODE]) {\n var useBuffer = motionBlur && !needMbClear[r.NODE] && mbPxRatio !== 1;\n var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_NODE] : data.contexts[r.NODE]);\n var clear = motionBlur && !useBuffer ? 'motionBlur' : undefined;\n setContextTransform(context, clear);\n if (hideEdges) {\n r.drawCachedNodes(context, eles.nondrag, pixelRatio, extent);\n } else {\n r.drawLayeredElements(context, eles.nondrag, pixelRatio, extent);\n }\n if (r.debug) {\n r.drawDebugPoints(context, eles.nondrag);\n }\n if (!drawAllLayers && !motionBlur) {\n needDraw[r.NODE] = false;\n }\n }\n if (!drawOnlyNodeLayer && (needDraw[r.DRAG] || drawAllLayers || needMbClear[r.DRAG])) {\n var useBuffer = motionBlur && !needMbClear[r.DRAG] && mbPxRatio !== 1;\n var context = forcedContext || (useBuffer ? r.data.bufferContexts[r.MOTIONBLUR_BUFFER_DRAG] : data.contexts[r.DRAG]);\n setContextTransform(context, motionBlur && !useBuffer ? 'motionBlur' : undefined);\n if (hideEdges) {\n r.drawCachedNodes(context, eles.drag, pixelRatio, extent);\n } else {\n r.drawCachedElements(context, eles.drag, pixelRatio, extent);\n }\n if (r.debug) {\n r.drawDebugPoints(context, eles.drag);\n }\n if (!drawAllLayers && !motionBlur) {\n needDraw[r.DRAG] = false;\n }\n }\n if (r.showFps || !drawOnlyNodeLayer && needDraw[r.SELECT_BOX] && !drawAllLayers) {\n var context = forcedContext || data.contexts[r.SELECT_BOX];\n setContextTransform(context);\n if (r.selection[4] == 1 && (r.hoverData.selecting || r.touchData.selecting)) {\n var zoom = r.cy.zoom();\n var borderWidth = style.core('selection-box-border-width').value / zoom;\n context.lineWidth = borderWidth;\n context.fillStyle = 'rgba(' + style.core('selection-box-color').value[0] + ',' + style.core('selection-box-color').value[1] + ',' + style.core('selection-box-color').value[2] + ',' + style.core('selection-box-opacity').value + ')';\n context.fillRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]);\n if (borderWidth > 0) {\n context.strokeStyle = 'rgba(' + style.core('selection-box-border-color').value[0] + ',' + style.core('selection-box-border-color').value[1] + ',' + style.core('selection-box-border-color').value[2] + ',' + style.core('selection-box-opacity').value + ')';\n context.strokeRect(r.selection[0], r.selection[1], r.selection[2] - r.selection[0], r.selection[3] - r.selection[1]);\n }\n }\n if (data.bgActivePosistion && !r.hoverData.selecting) {\n var zoom = r.cy.zoom();\n var pos = data.bgActivePosistion;\n context.fillStyle = 'rgba(' + style.core('active-bg-color').value[0] + ',' + style.core('active-bg-color').value[1] + ',' + style.core('active-bg-color').value[2] + ',' + style.core('active-bg-opacity').value + ')';\n context.beginPath();\n context.arc(pos.x, pos.y, style.core('active-bg-size').pfValue / zoom, 0, 2 * Math.PI);\n context.fill();\n }\n var timeToRender = r.lastRedrawTime;\n if (r.showFps && timeToRender) {\n timeToRender = Math.round(timeToRender);\n var fps = Math.round(1000 / timeToRender);\n context.setTransform(1, 0, 0, 1, 0, 0);\n context.fillStyle = 'rgba(255, 0, 0, 0.75)';\n context.strokeStyle = 'rgba(255, 0, 0, 0.75)';\n context.lineWidth = 1;\n context.fillText('1 frame = ' + timeToRender + ' ms = ' + fps + ' fps', 0, 20);\n var maxFps = 60;\n context.strokeRect(0, 30, 250, 20);\n context.fillRect(0, 30, 250 * Math.min(fps / maxFps, 1), 20);\n }\n if (!drawAllLayers) {\n needDraw[r.SELECT_BOX] = false;\n }\n }\n\n // motionblur: blit rendered blurry frames\n if (motionBlur && mbPxRatio !== 1) {\n var cxtNode = data.contexts[r.NODE];\n var txtNode = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_NODE];\n var cxtDrag = data.contexts[r.DRAG];\n var txtDrag = r.data.bufferCanvases[r.MOTIONBLUR_BUFFER_DRAG];\n var drawMotionBlur = function drawMotionBlur(cxt, txt, needClear) {\n cxt.setTransform(1, 0, 0, 1, 0, 0);\n if (needClear || !motionBlurFadeEffect) {\n cxt.clearRect(0, 0, r.canvasWidth, r.canvasHeight);\n } else {\n mbclear(cxt, 0, 0, r.canvasWidth, r.canvasHeight);\n }\n var pxr = mbPxRatio;\n cxt.drawImage(txt,\n // img\n 0, 0,\n // sx, sy\n r.canvasWidth * pxr, r.canvasHeight * pxr,\n // sw, sh\n 0, 0,\n // x, y\n r.canvasWidth, r.canvasHeight // w, h\n );\n };\n\n if (needDraw[r.NODE] || needMbClear[r.NODE]) {\n drawMotionBlur(cxtNode, txtNode, needMbClear[r.NODE]);\n needDraw[r.NODE] = false;\n }\n if (needDraw[r.DRAG] || needMbClear[r.DRAG]) {\n drawMotionBlur(cxtDrag, txtDrag, needMbClear[r.DRAG]);\n needDraw[r.DRAG] = false;\n }\n }\n r.prevViewport = vp;\n if (r.clearingMotionBlur) {\n r.clearingMotionBlur = false;\n r.motionBlurCleared = true;\n r.motionBlur = true;\n }\n if (motionBlur) {\n r.motionBlurTimeout = setTimeout(function () {\n r.motionBlurTimeout = null;\n r.clearedForMotionBlur[r.NODE] = false;\n r.clearedForMotionBlur[r.DRAG] = false;\n r.motionBlur = false;\n r.clearingMotionBlur = !textureDraw;\n r.mbFrames = 0;\n needDraw[r.NODE] = true;\n needDraw[r.DRAG] = true;\n r.redraw();\n }, motionBlurDelay);\n }\n if (!forcedContext) {\n cy.emit('render');\n }\n};\n\nvar CRp$3 = {};\n\n// @O Polygon drawing\nCRp$3.drawPolygonPath = function (context, x, y, width, height, points) {\n var halfW = width / 2;\n var halfH = height / 2;\n if (context.beginPath) {\n context.beginPath();\n }\n context.moveTo(x + halfW * points[0], y + halfH * points[1]);\n for (var i = 1; i < points.length / 2; i++) {\n context.lineTo(x + halfW * points[i * 2], y + halfH * points[i * 2 + 1]);\n }\n context.closePath();\n};\nCRp$3.drawRoundPolygonPath = function (context, x, y, width, height, points, corners) {\n corners.forEach(function (corner) {\n return drawPreparedRoundCorner(context, corner);\n });\n context.closePath();\n};\n\n// Round rectangle drawing\nCRp$3.drawRoundRectanglePath = function (context, x, y, width, height, radius) {\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n var cornerRadius = radius === 'auto' ? getRoundRectangleRadius(width, height) : Math.min(radius, halfHeight, halfWidth);\n if (context.beginPath) {\n context.beginPath();\n }\n\n // Start at top middle\n context.moveTo(x, y - halfHeight);\n // Arc from middle top to right side\n context.arcTo(x + halfWidth, y - halfHeight, x + halfWidth, y, cornerRadius);\n // Arc from right side to bottom\n context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius);\n // Arc from bottom to left side\n context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius);\n // Arc from left side to topBorder\n context.arcTo(x - halfWidth, y - halfHeight, x, y - halfHeight, cornerRadius);\n // Join line\n context.lineTo(x, y - halfHeight);\n context.closePath();\n};\nCRp$3.drawBottomRoundRectanglePath = function (context, x, y, width, height, radius) {\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n var cornerRadius = radius === 'auto' ? getRoundRectangleRadius(width, height) : radius;\n if (context.beginPath) {\n context.beginPath();\n }\n\n // Start at top middle\n context.moveTo(x, y - halfHeight);\n context.lineTo(x + halfWidth, y - halfHeight);\n context.lineTo(x + halfWidth, y);\n context.arcTo(x + halfWidth, y + halfHeight, x, y + halfHeight, cornerRadius);\n context.arcTo(x - halfWidth, y + halfHeight, x - halfWidth, y, cornerRadius);\n context.lineTo(x - halfWidth, y - halfHeight);\n context.lineTo(x, y - halfHeight);\n context.closePath();\n};\nCRp$3.drawCutRectanglePath = function (context, x, y, width, height, points, corners) {\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n var cornerLength = corners === 'auto' ? getCutRectangleCornerLength() : corners;\n if (context.beginPath) {\n context.beginPath();\n }\n context.moveTo(x - halfWidth + cornerLength, y - halfHeight);\n context.lineTo(x + halfWidth - cornerLength, y - halfHeight);\n context.lineTo(x + halfWidth, y - halfHeight + cornerLength);\n context.lineTo(x + halfWidth, y + halfHeight - cornerLength);\n context.lineTo(x + halfWidth - cornerLength, y + halfHeight);\n context.lineTo(x - halfWidth + cornerLength, y + halfHeight);\n context.lineTo(x - halfWidth, y + halfHeight - cornerLength);\n context.lineTo(x - halfWidth, y - halfHeight + cornerLength);\n context.closePath();\n};\nCRp$3.drawBarrelPath = function (context, x, y, width, height) {\n var halfWidth = width / 2;\n var halfHeight = height / 2;\n var xBegin = x - halfWidth;\n var xEnd = x + halfWidth;\n var yBegin = y - halfHeight;\n var yEnd = y + halfHeight;\n var barrelCurveConstants = getBarrelCurveConstants(width, height);\n var wOffset = barrelCurveConstants.widthOffset;\n var hOffset = barrelCurveConstants.heightOffset;\n var ctrlPtXOffset = barrelCurveConstants.ctrlPtOffsetPct * wOffset;\n if (context.beginPath) {\n context.beginPath();\n }\n context.moveTo(xBegin, yBegin + hOffset);\n context.lineTo(xBegin, yEnd - hOffset);\n context.quadraticCurveTo(xBegin + ctrlPtXOffset, yEnd, xBegin + wOffset, yEnd);\n context.lineTo(xEnd - wOffset, yEnd);\n context.quadraticCurveTo(xEnd - ctrlPtXOffset, yEnd, xEnd, yEnd - hOffset);\n context.lineTo(xEnd, yBegin + hOffset);\n context.quadraticCurveTo(xEnd - ctrlPtXOffset, yBegin, xEnd - wOffset, yBegin);\n context.lineTo(xBegin + wOffset, yBegin);\n context.quadraticCurveTo(xBegin + ctrlPtXOffset, yBegin, xBegin, yBegin + hOffset);\n context.closePath();\n};\nvar sin0 = Math.sin(0);\nvar cos0 = Math.cos(0);\nvar sin = {};\nvar cos = {};\nvar ellipseStepSize = Math.PI / 40;\nfor (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) {\n sin[i] = Math.sin(i);\n cos[i] = Math.cos(i);\n}\nCRp$3.drawEllipsePath = function (context, centerX, centerY, width, height) {\n if (context.beginPath) {\n context.beginPath();\n }\n if (context.ellipse) {\n context.ellipse(centerX, centerY, width / 2, height / 2, 0, 0, 2 * Math.PI);\n } else {\n var xPos, yPos;\n var rw = width / 2;\n var rh = height / 2;\n for (var i = 0 * Math.PI; i < 2 * Math.PI; i += ellipseStepSize) {\n xPos = centerX - rw * sin[i] * sin0 + rw * cos[i] * cos0;\n yPos = centerY + rh * cos[i] * sin0 + rh * sin[i] * cos0;\n if (i === 0) {\n context.moveTo(xPos, yPos);\n } else {\n context.lineTo(xPos, yPos);\n }\n }\n }\n context.closePath();\n};\n\n/* global atob, ArrayBuffer, Uint8Array, Blob */\nvar CRp$2 = {};\nCRp$2.createBuffer = function (w, h) {\n var buffer = document.createElement('canvas'); // eslint-disable-line no-undef\n buffer.width = w;\n buffer.height = h;\n return [buffer, buffer.getContext('2d')];\n};\nCRp$2.bufferCanvasImage = function (options) {\n var cy = this.cy;\n var eles = cy.mutableElements();\n var bb = eles.boundingBox();\n var ctrRect = this.findContainerClientCoords();\n var width = options.full ? Math.ceil(bb.w) : ctrRect[2];\n var height = options.full ? Math.ceil(bb.h) : ctrRect[3];\n var specdMaxDims = number$1(options.maxWidth) || number$1(options.maxHeight);\n var pxRatio = this.getPixelRatio();\n var scale = 1;\n if (options.scale !== undefined) {\n width *= options.scale;\n height *= options.scale;\n scale = options.scale;\n } else if (specdMaxDims) {\n var maxScaleW = Infinity;\n var maxScaleH = Infinity;\n if (number$1(options.maxWidth)) {\n maxScaleW = scale * options.maxWidth / width;\n }\n if (number$1(options.maxHeight)) {\n maxScaleH = scale * options.maxHeight / height;\n }\n scale = Math.min(maxScaleW, maxScaleH);\n width *= scale;\n height *= scale;\n }\n if (!specdMaxDims) {\n width *= pxRatio;\n height *= pxRatio;\n scale *= pxRatio;\n }\n var buffCanvas = document.createElement('canvas'); // eslint-disable-line no-undef\n\n buffCanvas.width = width;\n buffCanvas.height = height;\n buffCanvas.style.width = width + 'px';\n buffCanvas.style.height = height + 'px';\n var buffCxt = buffCanvas.getContext('2d');\n\n // Rasterize the layers, but only if container has nonzero size\n if (width > 0 && height > 0) {\n buffCxt.clearRect(0, 0, width, height);\n buffCxt.globalCompositeOperation = 'source-over';\n var zsortedEles = this.getCachedZSortedEles();\n if (options.full) {\n // draw the full bounds of the graph\n buffCxt.translate(-bb.x1 * scale, -bb.y1 * scale);\n buffCxt.scale(scale, scale);\n this.drawElements(buffCxt, zsortedEles);\n buffCxt.scale(1 / scale, 1 / scale);\n buffCxt.translate(bb.x1 * scale, bb.y1 * scale);\n } else {\n // draw the current view\n var pan = cy.pan();\n var translation = {\n x: pan.x * scale,\n y: pan.y * scale\n };\n scale *= cy.zoom();\n buffCxt.translate(translation.x, translation.y);\n buffCxt.scale(scale, scale);\n this.drawElements(buffCxt, zsortedEles);\n buffCxt.scale(1 / scale, 1 / scale);\n buffCxt.translate(-translation.x, -translation.y);\n }\n\n // need to fill bg at end like this in order to fill cleared transparent pixels in jpgs\n if (options.bg) {\n buffCxt.globalCompositeOperation = 'destination-over';\n buffCxt.fillStyle = options.bg;\n buffCxt.rect(0, 0, width, height);\n buffCxt.fill();\n }\n }\n return buffCanvas;\n};\nfunction b64ToBlob(b64, mimeType) {\n var bytes = atob(b64);\n var buff = new ArrayBuffer(bytes.length);\n var buffUint8 = new Uint8Array(buff);\n for (var i = 0; i < bytes.length; i++) {\n buffUint8[i] = bytes.charCodeAt(i);\n }\n return new Blob([buff], {\n type: mimeType\n });\n}\nfunction b64UriToB64(b64uri) {\n var i = b64uri.indexOf(',');\n return b64uri.substr(i + 1);\n}\nfunction output(options, canvas, mimeType) {\n var getB64Uri = function getB64Uri() {\n return canvas.toDataURL(mimeType, options.quality);\n };\n switch (options.output) {\n case 'blob-promise':\n return new Promise$1(function (resolve, reject) {\n try {\n canvas.toBlob(function (blob) {\n if (blob != null) {\n resolve(blob);\n } else {\n reject(new Error('`canvas.toBlob()` sent a null value in its callback'));\n }\n }, mimeType, options.quality);\n } catch (err) {\n reject(err);\n }\n });\n case 'blob':\n return b64ToBlob(b64UriToB64(getB64Uri()), mimeType);\n case 'base64':\n return b64UriToB64(getB64Uri());\n case 'base64uri':\n default:\n return getB64Uri();\n }\n}\nCRp$2.png = function (options) {\n return output(options, this.bufferCanvasImage(options), 'image/png');\n};\nCRp$2.jpg = function (options) {\n return output(options, this.bufferCanvasImage(options), 'image/jpeg');\n};\n\nvar CRp$1 = {};\nCRp$1.nodeShapeImpl = function (name, context, centerX, centerY, width, height, points, corners) {\n switch (name) {\n case 'ellipse':\n return this.drawEllipsePath(context, centerX, centerY, width, height);\n case 'polygon':\n return this.drawPolygonPath(context, centerX, centerY, width, height, points);\n case 'round-polygon':\n return this.drawRoundPolygonPath(context, centerX, centerY, width, height, points, corners);\n case 'roundrectangle':\n case 'round-rectangle':\n return this.drawRoundRectanglePath(context, centerX, centerY, width, height, corners);\n case 'cutrectangle':\n case 'cut-rectangle':\n return this.drawCutRectanglePath(context, centerX, centerY, width, height, points, corners);\n case 'bottomroundrectangle':\n case 'bottom-round-rectangle':\n return this.drawBottomRoundRectanglePath(context, centerX, centerY, width, height, corners);\n case 'barrel':\n return this.drawBarrelPath(context, centerX, centerY, width, height);\n }\n};\n\nvar CR = CanvasRenderer;\nvar CRp = CanvasRenderer.prototype;\nCRp.CANVAS_LAYERS = 3;\n//\nCRp.SELECT_BOX = 0;\nCRp.DRAG = 1;\nCRp.NODE = 2;\nCRp.BUFFER_COUNT = 3;\n//\nCRp.TEXTURE_BUFFER = 0;\nCRp.MOTIONBLUR_BUFFER_NODE = 1;\nCRp.MOTIONBLUR_BUFFER_DRAG = 2;\nfunction CanvasRenderer(options) {\n var r = this;\n var containerWindow = r.cy.window();\n var document = containerWindow.document;\n r.data = {\n canvases: new Array(CRp.CANVAS_LAYERS),\n contexts: new Array(CRp.CANVAS_LAYERS),\n canvasNeedsRedraw: new Array(CRp.CANVAS_LAYERS),\n bufferCanvases: new Array(CRp.BUFFER_COUNT),\n bufferContexts: new Array(CRp.CANVAS_LAYERS)\n };\n var tapHlOffAttr = '-webkit-tap-highlight-color';\n var tapHlOffStyle = 'rgba(0,0,0,0)';\n r.data.canvasContainer = document.createElement('div'); // eslint-disable-line no-undef\n var containerStyle = r.data.canvasContainer.style;\n r.data.canvasContainer.style[tapHlOffAttr] = tapHlOffStyle;\n containerStyle.position = 'relative';\n containerStyle.zIndex = '0';\n containerStyle.overflow = 'hidden';\n var container = options.cy.container();\n container.appendChild(r.data.canvasContainer);\n container.style[tapHlOffAttr] = tapHlOffStyle;\n var styleMap = {\n '-webkit-user-select': 'none',\n '-moz-user-select': '-moz-none',\n 'user-select': 'none',\n '-webkit-tap-highlight-color': 'rgba(0,0,0,0)',\n 'outline-style': 'none'\n };\n if (ms()) {\n styleMap['-ms-touch-action'] = 'none';\n styleMap['touch-action'] = 'none';\n }\n for (var i = 0; i < CRp.CANVAS_LAYERS; i++) {\n var canvas = r.data.canvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef\n r.data.contexts[i] = canvas.getContext('2d');\n Object.keys(styleMap).forEach(function (k) {\n canvas.style[k] = styleMap[k];\n });\n canvas.style.position = 'absolute';\n canvas.setAttribute('data-id', 'layer' + i);\n canvas.style.zIndex = String(CRp.CANVAS_LAYERS - i);\n r.data.canvasContainer.appendChild(canvas);\n r.data.canvasNeedsRedraw[i] = false;\n }\n r.data.topCanvas = r.data.canvases[0];\n r.data.canvases[CRp.NODE].setAttribute('data-id', 'layer' + CRp.NODE + '-node');\n r.data.canvases[CRp.SELECT_BOX].setAttribute('data-id', 'layer' + CRp.SELECT_BOX + '-selectbox');\n r.data.canvases[CRp.DRAG].setAttribute('data-id', 'layer' + CRp.DRAG + '-drag');\n for (var i = 0; i < CRp.BUFFER_COUNT; i++) {\n r.data.bufferCanvases[i] = document.createElement('canvas'); // eslint-disable-line no-undef\n r.data.bufferContexts[i] = r.data.bufferCanvases[i].getContext('2d');\n r.data.bufferCanvases[i].style.position = 'absolute';\n r.data.bufferCanvases[i].setAttribute('data-id', 'buffer' + i);\n r.data.bufferCanvases[i].style.zIndex = String(-i - 1);\n r.data.bufferCanvases[i].style.visibility = 'hidden';\n //r.data.canvasContainer.appendChild(r.data.bufferCanvases[i]);\n }\n\n r.pathsEnabled = true;\n var emptyBb = makeBoundingBox();\n var getBoxCenter = function getBoxCenter(bb) {\n return {\n x: (bb.x1 + bb.x2) / 2,\n y: (bb.y1 + bb.y2) / 2\n };\n };\n var getCenterOffset = function getCenterOffset(bb) {\n return {\n x: -bb.w / 2,\n y: -bb.h / 2\n };\n };\n var backgroundTimestampHasChanged = function backgroundTimestampHasChanged(ele) {\n var _p = ele[0]._private;\n var same = _p.oldBackgroundTimestamp === _p.backgroundTimestamp;\n return !same;\n };\n var getStyleKey = function getStyleKey(ele) {\n return ele[0]._private.nodeKey;\n };\n var getLabelKey = function getLabelKey(ele) {\n return ele[0]._private.labelStyleKey;\n };\n var getSourceLabelKey = function getSourceLabelKey(ele) {\n return ele[0]._private.sourceLabelStyleKey;\n };\n var getTargetLabelKey = function getTargetLabelKey(ele) {\n return ele[0]._private.targetLabelStyleKey;\n };\n var drawElement = function drawElement(context, ele, bb, scaledLabelShown, useEleOpacity) {\n return r.drawElement(context, ele, bb, false, false, useEleOpacity);\n };\n var drawLabel = function drawLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {\n return r.drawElementText(context, ele, bb, scaledLabelShown, 'main', useEleOpacity);\n };\n var drawSourceLabel = function drawSourceLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {\n return r.drawElementText(context, ele, bb, scaledLabelShown, 'source', useEleOpacity);\n };\n var drawTargetLabel = function drawTargetLabel(context, ele, bb, scaledLabelShown, useEleOpacity) {\n return r.drawElementText(context, ele, bb, scaledLabelShown, 'target', useEleOpacity);\n };\n var getElementBox = function getElementBox(ele) {\n ele.boundingBox();\n return ele[0]._private.bodyBounds;\n };\n var getLabelBox = function getLabelBox(ele) {\n ele.boundingBox();\n return ele[0]._private.labelBounds.main || emptyBb;\n };\n var getSourceLabelBox = function getSourceLabelBox(ele) {\n ele.boundingBox();\n return ele[0]._private.labelBounds.source || emptyBb;\n };\n var getTargetLabelBox = function getTargetLabelBox(ele) {\n ele.boundingBox();\n return ele[0]._private.labelBounds.target || emptyBb;\n };\n var isLabelVisibleAtScale = function isLabelVisibleAtScale(ele, scaledLabelShown) {\n return scaledLabelShown;\n };\n var getElementRotationPoint = function getElementRotationPoint(ele) {\n return getBoxCenter(getElementBox(ele));\n };\n var addTextMargin = function addTextMargin(prefix, pt, ele) {\n var pre = prefix ? prefix + '-' : '';\n return {\n x: pt.x + ele.pstyle(pre + 'text-margin-x').pfValue,\n y: pt.y + ele.pstyle(pre + 'text-margin-y').pfValue\n };\n };\n var getRsPt = function getRsPt(ele, x, y) {\n var rs = ele[0]._private.rscratch;\n return {\n x: rs[x],\n y: rs[y]\n };\n };\n var getLabelRotationPoint = function getLabelRotationPoint(ele) {\n return addTextMargin('', getRsPt(ele, 'labelX', 'labelY'), ele);\n };\n var getSourceLabelRotationPoint = function getSourceLabelRotationPoint(ele) {\n return addTextMargin('source', getRsPt(ele, 'sourceLabelX', 'sourceLabelY'), ele);\n };\n var getTargetLabelRotationPoint = function getTargetLabelRotationPoint(ele) {\n return addTextMargin('target', getRsPt(ele, 'targetLabelX', 'targetLabelY'), ele);\n };\n var getElementRotationOffset = function getElementRotationOffset(ele) {\n return getCenterOffset(getElementBox(ele));\n };\n var getSourceLabelRotationOffset = function getSourceLabelRotationOffset(ele) {\n return getCenterOffset(getSourceLabelBox(ele));\n };\n var getTargetLabelRotationOffset = function getTargetLabelRotationOffset(ele) {\n return getCenterOffset(getTargetLabelBox(ele));\n };\n var getLabelRotationOffset = function getLabelRotationOffset(ele) {\n var bb = getLabelBox(ele);\n var p = getCenterOffset(getLabelBox(ele));\n if (ele.isNode()) {\n switch (ele.pstyle('text-halign').value) {\n case 'left':\n p.x = -bb.w;\n break;\n case 'right':\n p.x = 0;\n break;\n }\n switch (ele.pstyle('text-valign').value) {\n case 'top':\n p.y = -bb.h;\n break;\n case 'bottom':\n p.y = 0;\n break;\n }\n }\n return p;\n };\n var eleTxrCache = r.data.eleTxrCache = new ElementTextureCache(r, {\n getKey: getStyleKey,\n doesEleInvalidateKey: backgroundTimestampHasChanged,\n drawElement: drawElement,\n getBoundingBox: getElementBox,\n getRotationPoint: getElementRotationPoint,\n getRotationOffset: getElementRotationOffset,\n allowEdgeTxrCaching: false,\n allowParentTxrCaching: false\n });\n var lblTxrCache = r.data.lblTxrCache = new ElementTextureCache(r, {\n getKey: getLabelKey,\n drawElement: drawLabel,\n getBoundingBox: getLabelBox,\n getRotationPoint: getLabelRotationPoint,\n getRotationOffset: getLabelRotationOffset,\n isVisible: isLabelVisibleAtScale\n });\n var slbTxrCache = r.data.slbTxrCache = new ElementTextureCache(r, {\n getKey: getSourceLabelKey,\n drawElement: drawSourceLabel,\n getBoundingBox: getSourceLabelBox,\n getRotationPoint: getSourceLabelRotationPoint,\n getRotationOffset: getSourceLabelRotationOffset,\n isVisible: isLabelVisibleAtScale\n });\n var tlbTxrCache = r.data.tlbTxrCache = new ElementTextureCache(r, {\n getKey: getTargetLabelKey,\n drawElement: drawTargetLabel,\n getBoundingBox: getTargetLabelBox,\n getRotationPoint: getTargetLabelRotationPoint,\n getRotationOffset: getTargetLabelRotationOffset,\n isVisible: isLabelVisibleAtScale\n });\n var lyrTxrCache = r.data.lyrTxrCache = new LayeredTextureCache(r);\n r.onUpdateEleCalcs(function invalidateTextureCaches(willDraw, eles) {\n // each cache should check for sub-key diff to see that the update affects that cache particularly\n eleTxrCache.invalidateElements(eles);\n lblTxrCache.invalidateElements(eles);\n slbTxrCache.invalidateElements(eles);\n tlbTxrCache.invalidateElements(eles);\n\n // any change invalidates the layers\n lyrTxrCache.invalidateElements(eles);\n\n // update the old bg timestamp so diffs can be done in the ele txr caches\n for (var _i = 0; _i < eles.length; _i++) {\n var _p = eles[_i]._private;\n _p.oldBackgroundTimestamp = _p.backgroundTimestamp;\n }\n });\n var refineInLayers = function refineInLayers(reqs) {\n for (var i = 0; i < reqs.length; i++) {\n lyrTxrCache.enqueueElementRefinement(reqs[i].ele);\n }\n };\n eleTxrCache.onDequeue(refineInLayers);\n lblTxrCache.onDequeue(refineInLayers);\n slbTxrCache.onDequeue(refineInLayers);\n tlbTxrCache.onDequeue(refineInLayers);\n}\nCRp.redrawHint = function (group, bool) {\n var r = this;\n switch (group) {\n case 'eles':\n r.data.canvasNeedsRedraw[CRp.NODE] = bool;\n break;\n case 'drag':\n r.data.canvasNeedsRedraw[CRp.DRAG] = bool;\n break;\n case 'select':\n r.data.canvasNeedsRedraw[CRp.SELECT_BOX] = bool;\n break;\n }\n};\n\n// whether to use Path2D caching for drawing\nvar pathsImpld = typeof Path2D !== 'undefined';\nCRp.path2dEnabled = function (on) {\n if (on === undefined) {\n return this.pathsEnabled;\n }\n this.pathsEnabled = on ? true : false;\n};\nCRp.usePaths = function () {\n return pathsImpld && this.pathsEnabled;\n};\nCRp.setImgSmoothing = function (context, bool) {\n if (context.imageSmoothingEnabled != null) {\n context.imageSmoothingEnabled = bool;\n } else {\n context.webkitImageSmoothingEnabled = bool;\n context.mozImageSmoothingEnabled = bool;\n context.msImageSmoothingEnabled = bool;\n }\n};\nCRp.getImgSmoothing = function (context) {\n if (context.imageSmoothingEnabled != null) {\n return context.imageSmoothingEnabled;\n } else {\n return context.webkitImageSmoothingEnabled || context.mozImageSmoothingEnabled || context.msImageSmoothingEnabled;\n }\n};\nCRp.makeOffscreenCanvas = function (width, height) {\n var canvas;\n if ((typeof OffscreenCanvas === \"undefined\" ? \"undefined\" : _typeof(OffscreenCanvas)) !== (\"undefined\" )) {\n canvas = new OffscreenCanvas(width, height);\n } else {\n var containerWindow = this.cy.window();\n var document = containerWindow.document;\n canvas = document.createElement('canvas'); // eslint-disable-line no-undef\n canvas.width = width;\n canvas.height = height;\n }\n return canvas;\n};\n[CRp$a, CRp$9, CRp$8, CRp$7, CRp$6, CRp$5, CRp$4, CRp$3, CRp$2, CRp$1].forEach(function (props) {\n extend(CRp, props);\n});\n\nvar renderer = [{\n name: 'null',\n impl: NullRenderer\n}, {\n name: 'base',\n impl: BR\n}, {\n name: 'canvas',\n impl: CR\n}];\n\nvar incExts = [{\n type: 'layout',\n extensions: layout\n}, {\n type: 'renderer',\n extensions: renderer\n}];\n\n// registered extensions to cytoscape, indexed by name\nvar extensions = {};\n\n// registered modules for extensions, indexed by name\nvar modules = {};\nfunction setExtension(type, name, registrant) {\n var ext = registrant;\n var overrideErr = function overrideErr(field) {\n warn('Can not register `' + name + '` for `' + type + '` since `' + field + '` already exists in the prototype and can not be overridden');\n };\n if (type === 'core') {\n if (Core.prototype[name]) {\n return overrideErr(name);\n } else {\n Core.prototype[name] = registrant;\n }\n } else if (type === 'collection') {\n if (Collection.prototype[name]) {\n return overrideErr(name);\n } else {\n Collection.prototype[name] = registrant;\n }\n } else if (type === 'layout') {\n // fill in missing layout functions in the prototype\n\n var Layout = function Layout(options) {\n this.options = options;\n registrant.call(this, options);\n\n // make sure layout has _private for use w/ std apis like .on()\n if (!plainObject(this._private)) {\n this._private = {};\n }\n this._private.cy = options.cy;\n this._private.listeners = [];\n this.createEmitter();\n };\n var layoutProto = Layout.prototype = Object.create(registrant.prototype);\n var optLayoutFns = [];\n for (var i = 0; i < optLayoutFns.length; i++) {\n var fnName = optLayoutFns[i];\n layoutProto[fnName] = layoutProto[fnName] || function () {\n return this;\n };\n }\n\n // either .start() or .run() is defined, so autogen the other\n if (layoutProto.start && !layoutProto.run) {\n layoutProto.run = function () {\n this.start();\n return this;\n };\n } else if (!layoutProto.start && layoutProto.run) {\n layoutProto.start = function () {\n this.run();\n return this;\n };\n }\n var regStop = registrant.prototype.stop;\n layoutProto.stop = function () {\n var opts = this.options;\n if (opts && opts.animate) {\n var anis = this.animations;\n if (anis) {\n for (var _i = 0; _i < anis.length; _i++) {\n anis[_i].stop();\n }\n }\n }\n if (regStop) {\n regStop.call(this);\n } else {\n this.emit('layoutstop');\n }\n return this;\n };\n if (!layoutProto.destroy) {\n layoutProto.destroy = function () {\n return this;\n };\n }\n layoutProto.cy = function () {\n return this._private.cy;\n };\n var getCy = function getCy(layout) {\n return layout._private.cy;\n };\n var emitterOpts = {\n addEventFields: function addEventFields(layout, evt) {\n evt.layout = layout;\n evt.cy = getCy(layout);\n evt.target = layout;\n },\n bubble: function bubble() {\n return true;\n },\n parent: function parent(layout) {\n return getCy(layout);\n }\n };\n extend(layoutProto, {\n createEmitter: function createEmitter() {\n this._private.emitter = new Emitter(emitterOpts, this);\n return this;\n },\n emitter: function emitter() {\n return this._private.emitter;\n },\n on: function on(evt, cb) {\n this.emitter().on(evt, cb);\n return this;\n },\n one: function one(evt, cb) {\n this.emitter().one(evt, cb);\n return this;\n },\n once: function once(evt, cb) {\n this.emitter().one(evt, cb);\n return this;\n },\n removeListener: function removeListener(evt, cb) {\n this.emitter().removeListener(evt, cb);\n return this;\n },\n removeAllListeners: function removeAllListeners() {\n this.emitter().removeAllListeners();\n return this;\n },\n emit: function emit(evt, params) {\n this.emitter().emit(evt, params);\n return this;\n }\n });\n define.eventAliasesOn(layoutProto);\n ext = Layout; // replace with our wrapped layout\n } else if (type === 'renderer' && name !== 'null' && name !== 'base') {\n // user registered renderers inherit from base\n\n var BaseRenderer = getExtension('renderer', 'base');\n var bProto = BaseRenderer.prototype;\n var RegistrantRenderer = registrant;\n var rProto = registrant.prototype;\n var Renderer = function Renderer() {\n BaseRenderer.apply(this, arguments);\n RegistrantRenderer.apply(this, arguments);\n };\n var proto = Renderer.prototype;\n for (var pName in bProto) {\n var pVal = bProto[pName];\n var existsInR = rProto[pName] != null;\n if (existsInR) {\n return overrideErr(pName);\n }\n proto[pName] = pVal; // take impl from base\n }\n\n for (var _pName in rProto) {\n proto[_pName] = rProto[_pName]; // take impl from registrant\n }\n\n bProto.clientFunctions.forEach(function (name) {\n proto[name] = proto[name] || function () {\n error('Renderer does not implement `renderer.' + name + '()` on its prototype');\n };\n });\n ext = Renderer;\n } else if (type === '__proto__' || type === 'constructor' || type === 'prototype') {\n // to avoid potential prototype pollution\n return error(type + ' is an illegal type to be registered, possibly lead to prototype pollutions');\n }\n return setMap({\n map: extensions,\n keys: [type, name],\n value: ext\n });\n}\nfunction getExtension(type, name) {\n return getMap({\n map: extensions,\n keys: [type, name]\n });\n}\nfunction setModule(type, name, moduleType, moduleName, registrant) {\n return setMap({\n map: modules,\n keys: [type, name, moduleType, moduleName],\n value: registrant\n });\n}\nfunction getModule(type, name, moduleType, moduleName) {\n return getMap({\n map: modules,\n keys: [type, name, moduleType, moduleName]\n });\n}\nvar extension = function extension() {\n // e.g. extension('renderer', 'svg')\n if (arguments.length === 2) {\n return getExtension.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', { ... })\n else if (arguments.length === 3) {\n return setExtension.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse')\n else if (arguments.length === 4) {\n return getModule.apply(null, arguments);\n }\n\n // e.g. extension('renderer', 'svg', 'nodeShape', 'ellipse', { ... })\n else if (arguments.length === 5) {\n return setModule.apply(null, arguments);\n } else {\n error('Invalid extension access syntax');\n }\n};\n\n// allows a core instance to access extensions internally\nCore.prototype.extension = extension;\n\n// included extensions\nincExts.forEach(function (group) {\n group.extensions.forEach(function (ext) {\n setExtension(group.type, ext.name, ext.impl);\n });\n});\n\n// a dummy stylesheet object that doesn't need a reference to the core\n// (useful for init)\nvar Stylesheet = function Stylesheet() {\n if (!(this instanceof Stylesheet)) {\n return new Stylesheet();\n }\n this.length = 0;\n};\nvar sheetfn = Stylesheet.prototype;\nsheetfn.instanceString = function () {\n return 'stylesheet';\n};\n\n// just store the selector to be parsed later\nsheetfn.selector = function (selector) {\n var i = this.length++;\n this[i] = {\n selector: selector,\n properties: []\n };\n return this; // chaining\n};\n\n// just store the property to be parsed later\nsheetfn.css = function (name, value) {\n var i = this.length - 1;\n if (string(name)) {\n this[i].properties.push({\n name: name,\n value: value\n });\n } else if (plainObject(name)) {\n var map = name;\n var propNames = Object.keys(map);\n for (var j = 0; j < propNames.length; j++) {\n var key = propNames[j];\n var mapVal = map[key];\n if (mapVal == null) {\n continue;\n }\n var prop = Style.properties[key] || Style.properties[dash2camel(key)];\n if (prop == null) {\n continue;\n }\n var _name = prop.name;\n var _value = mapVal;\n this[i].properties.push({\n name: _name,\n value: _value\n });\n }\n }\n return this; // chaining\n};\n\nsheetfn.style = sheetfn.css;\n\n// generate a real style object from the dummy stylesheet\nsheetfn.generateStyle = function (cy) {\n var style = new Style(cy);\n return this.appendToStyle(style);\n};\n\n// append a dummy stylesheet object on a real style object\nsheetfn.appendToStyle = function (style) {\n for (var i = 0; i < this.length; i++) {\n var context = this[i];\n var selector = context.selector;\n var props = context.properties;\n style.selector(selector); // apply selector\n\n for (var j = 0; j < props.length; j++) {\n var prop = props[j];\n style.css(prop.name, prop.value); // apply property\n }\n }\n\n return style;\n};\n\nvar version = \"3.30.2\";\n\nvar cytoscape = function cytoscape(options) {\n // if no options specified, use default\n if (options === undefined) {\n options = {};\n }\n\n // create instance\n if (plainObject(options)) {\n return new Core(options);\n }\n\n // allow for registration of extensions\n else if (string(options)) {\n return extension.apply(extension, arguments);\n }\n};\n\n// e.g. cytoscape.use( require('cytoscape-foo'), bar )\ncytoscape.use = function (ext) {\n var args = Array.prototype.slice.call(arguments, 1); // args to pass to ext\n\n args.unshift(cytoscape); // cytoscape is first arg to ext\n\n ext.apply(null, args);\n return this;\n};\ncytoscape.warnings = function (bool) {\n return warnings(bool);\n};\n\n// replaced by build system\ncytoscape.version = version;\n\n// expose public apis (mostly for extensions)\ncytoscape.stylesheet = cytoscape.Stylesheet = Stylesheet;\n\nexport { cytoscape as default };\n", "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"layoutBase\"] = factory();\n\telse\n\t\troot[\"layoutBase\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 26);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction LayoutConstants() {}\n\n/**\r\n * Layout Quality: 0:draft, 1:default, 2:proof\r\n */\nLayoutConstants.QUALITY = 1;\n\n/**\r\n * Default parameters\r\n */\nLayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED = false;\nLayoutConstants.DEFAULT_INCREMENTAL = false;\nLayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT = true;\nLayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT = false;\nLayoutConstants.DEFAULT_ANIMATION_PERIOD = 50;\nLayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES = false;\n\n// -----------------------------------------------------------------------------\n// Section: General other constants\n// -----------------------------------------------------------------------------\n/*\r\n * Margins of a graph to be applied on bouding rectangle of its contents. We\r\n * assume margins on all four sides to be uniform.\r\n */\nLayoutConstants.DEFAULT_GRAPH_MARGIN = 15;\n\n/*\r\n * Whether to consider labels in node dimensions or not\r\n */\nLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = false;\n\n/*\r\n * Default dimension of a non-compound node.\r\n */\nLayoutConstants.SIMPLE_NODE_SIZE = 40;\n\n/*\r\n * Default dimension of a non-compound node.\r\n */\nLayoutConstants.SIMPLE_NODE_HALF_SIZE = LayoutConstants.SIMPLE_NODE_SIZE / 2;\n\n/*\r\n * Empty compound node size. When a compound node is empty, its both\r\n * dimensions should be of this value.\r\n */\nLayoutConstants.EMPTY_COMPOUND_NODE_SIZE = 40;\n\n/*\r\n * Minimum length that an edge should take during layout\r\n */\nLayoutConstants.MIN_EDGE_LENGTH = 1;\n\n/*\r\n * World boundaries that layout operates on\r\n */\nLayoutConstants.WORLD_BOUNDARY = 1000000;\n\n/*\r\n * World boundaries that random positioning can be performed with\r\n */\nLayoutConstants.INITIAL_WORLD_BOUNDARY = LayoutConstants.WORLD_BOUNDARY / 1000;\n\n/*\r\n * Coordinates of the world center\r\n */\nLayoutConstants.WORLD_CENTER_X = 1200;\nLayoutConstants.WORLD_CENTER_Y = 900;\n\nmodule.exports = LayoutConstants;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraphObject = __webpack_require__(2);\nvar IGeometry = __webpack_require__(8);\nvar IMath = __webpack_require__(9);\n\nfunction LEdge(source, target, vEdge) {\n LGraphObject.call(this, vEdge);\n\n this.isOverlapingSourceAndTarget = false;\n this.vGraphObject = vEdge;\n this.bendpoints = [];\n this.source = source;\n this.target = target;\n}\n\nLEdge.prototype = Object.create(LGraphObject.prototype);\n\nfor (var prop in LGraphObject) {\n LEdge[prop] = LGraphObject[prop];\n}\n\nLEdge.prototype.getSource = function () {\n return this.source;\n};\n\nLEdge.prototype.getTarget = function () {\n return this.target;\n};\n\nLEdge.prototype.isInterGraph = function () {\n return this.isInterGraph;\n};\n\nLEdge.prototype.getLength = function () {\n return this.length;\n};\n\nLEdge.prototype.isOverlapingSourceAndTarget = function () {\n return this.isOverlapingSourceAndTarget;\n};\n\nLEdge.prototype.getBendpoints = function () {\n return this.bendpoints;\n};\n\nLEdge.prototype.getLca = function () {\n return this.lca;\n};\n\nLEdge.prototype.getSourceInLca = function () {\n return this.sourceInLca;\n};\n\nLEdge.prototype.getTargetInLca = function () {\n return this.targetInLca;\n};\n\nLEdge.prototype.getOtherEnd = function (node) {\n if (this.source === node) {\n return this.target;\n } else if (this.target === node) {\n return this.source;\n } else {\n throw \"Node is not incident with this edge\";\n }\n};\n\nLEdge.prototype.getOtherEndInGraph = function (node, graph) {\n var otherEnd = this.getOtherEnd(node);\n var root = graph.getGraphManager().getRoot();\n\n while (true) {\n if (otherEnd.getOwner() == graph) {\n return otherEnd;\n }\n\n if (otherEnd.getOwner() == root) {\n break;\n }\n\n otherEnd = otherEnd.getOwner().getParent();\n }\n\n return null;\n};\n\nLEdge.prototype.updateLength = function () {\n var clipPointCoordinates = new Array(4);\n\n this.isOverlapingSourceAndTarget = IGeometry.getIntersection(this.target.getRect(), this.source.getRect(), clipPointCoordinates);\n\n if (!this.isOverlapingSourceAndTarget) {\n this.lengthX = clipPointCoordinates[0] - clipPointCoordinates[2];\n this.lengthY = clipPointCoordinates[1] - clipPointCoordinates[3];\n\n if (Math.abs(this.lengthX) < 1.0) {\n this.lengthX = IMath.sign(this.lengthX);\n }\n\n if (Math.abs(this.lengthY) < 1.0) {\n this.lengthY = IMath.sign(this.lengthY);\n }\n\n this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY);\n }\n};\n\nLEdge.prototype.updateLengthSimple = function () {\n this.lengthX = this.target.getCenterX() - this.source.getCenterX();\n this.lengthY = this.target.getCenterY() - this.source.getCenterY();\n\n if (Math.abs(this.lengthX) < 1.0) {\n this.lengthX = IMath.sign(this.lengthX);\n }\n\n if (Math.abs(this.lengthY) < 1.0) {\n this.lengthY = IMath.sign(this.lengthY);\n }\n\n this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY);\n};\n\nmodule.exports = LEdge;\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction LGraphObject(vGraphObject) {\n this.vGraphObject = vGraphObject;\n}\n\nmodule.exports = LGraphObject;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraphObject = __webpack_require__(2);\nvar Integer = __webpack_require__(10);\nvar RectangleD = __webpack_require__(13);\nvar LayoutConstants = __webpack_require__(0);\nvar RandomSeed = __webpack_require__(16);\nvar PointD = __webpack_require__(4);\n\nfunction LNode(gm, loc, size, vNode) {\n //Alternative constructor 1 : LNode(LGraphManager gm, Point loc, Dimension size, Object vNode)\n if (size == null && vNode == null) {\n vNode = loc;\n }\n\n LGraphObject.call(this, vNode);\n\n //Alternative constructor 2 : LNode(Layout layout, Object vNode)\n if (gm.graphManager != null) gm = gm.graphManager;\n\n this.estimatedSize = Integer.MIN_VALUE;\n this.inclusionTreeDepth = Integer.MAX_VALUE;\n this.vGraphObject = vNode;\n this.edges = [];\n this.graphManager = gm;\n\n if (size != null && loc != null) this.rect = new RectangleD(loc.x, loc.y, size.width, size.height);else this.rect = new RectangleD();\n}\n\nLNode.prototype = Object.create(LGraphObject.prototype);\nfor (var prop in LGraphObject) {\n LNode[prop] = LGraphObject[prop];\n}\n\nLNode.prototype.getEdges = function () {\n return this.edges;\n};\n\nLNode.prototype.getChild = function () {\n return this.child;\n};\n\nLNode.prototype.getOwner = function () {\n // if (this.owner != null) {\n // if (!(this.owner == null || this.owner.getNodes().indexOf(this) > -1)) {\n // throw \"assert failed\";\n // }\n // }\n\n return this.owner;\n};\n\nLNode.prototype.getWidth = function () {\n return this.rect.width;\n};\n\nLNode.prototype.setWidth = function (width) {\n this.rect.width = width;\n};\n\nLNode.prototype.getHeight = function () {\n return this.rect.height;\n};\n\nLNode.prototype.setHeight = function (height) {\n this.rect.height = height;\n};\n\nLNode.prototype.getCenterX = function () {\n return this.rect.x + this.rect.width / 2;\n};\n\nLNode.prototype.getCenterY = function () {\n return this.rect.y + this.rect.height / 2;\n};\n\nLNode.prototype.getCenter = function () {\n return new PointD(this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2);\n};\n\nLNode.prototype.getLocation = function () {\n return new PointD(this.rect.x, this.rect.y);\n};\n\nLNode.prototype.getRect = function () {\n return this.rect;\n};\n\nLNode.prototype.getDiagonal = function () {\n return Math.sqrt(this.rect.width * this.rect.width + this.rect.height * this.rect.height);\n};\n\n/**\n * This method returns half the diagonal length of this node.\n */\nLNode.prototype.getHalfTheDiagonal = function () {\n return Math.sqrt(this.rect.height * this.rect.height + this.rect.width * this.rect.width) / 2;\n};\n\nLNode.prototype.setRect = function (upperLeft, dimension) {\n this.rect.x = upperLeft.x;\n this.rect.y = upperLeft.y;\n this.rect.width = dimension.width;\n this.rect.height = dimension.height;\n};\n\nLNode.prototype.setCenter = function (cx, cy) {\n this.rect.x = cx - this.rect.width / 2;\n this.rect.y = cy - this.rect.height / 2;\n};\n\nLNode.prototype.setLocation = function (x, y) {\n this.rect.x = x;\n this.rect.y = y;\n};\n\nLNode.prototype.moveBy = function (dx, dy) {\n this.rect.x += dx;\n this.rect.y += dy;\n};\n\nLNode.prototype.getEdgeListToNode = function (to) {\n var edgeList = [];\n var edge;\n var self = this;\n\n self.edges.forEach(function (edge) {\n\n if (edge.target == to) {\n if (edge.source != self) throw \"Incorrect edge source!\";\n\n edgeList.push(edge);\n }\n });\n\n return edgeList;\n};\n\nLNode.prototype.getEdgesBetween = function (other) {\n var edgeList = [];\n var edge;\n\n var self = this;\n self.edges.forEach(function (edge) {\n\n if (!(edge.source == self || edge.target == self)) throw \"Incorrect edge source and/or target\";\n\n if (edge.target == other || edge.source == other) {\n edgeList.push(edge);\n }\n });\n\n return edgeList;\n};\n\nLNode.prototype.getNeighborsList = function () {\n var neighbors = new Set();\n\n var self = this;\n self.edges.forEach(function (edge) {\n\n if (edge.source == self) {\n neighbors.add(edge.target);\n } else {\n if (edge.target != self) {\n throw \"Incorrect incidency!\";\n }\n\n neighbors.add(edge.source);\n }\n });\n\n return neighbors;\n};\n\nLNode.prototype.withChildren = function () {\n var withNeighborsList = new Set();\n var childNode;\n var children;\n\n withNeighborsList.add(this);\n\n if (this.child != null) {\n var nodes = this.child.getNodes();\n for (var i = 0; i < nodes.length; i++) {\n childNode = nodes[i];\n children = childNode.withChildren();\n children.forEach(function (node) {\n withNeighborsList.add(node);\n });\n }\n }\n\n return withNeighborsList;\n};\n\nLNode.prototype.getNoOfChildren = function () {\n var noOfChildren = 0;\n var childNode;\n\n if (this.child == null) {\n noOfChildren = 1;\n } else {\n var nodes = this.child.getNodes();\n for (var i = 0; i < nodes.length; i++) {\n childNode = nodes[i];\n\n noOfChildren += childNode.getNoOfChildren();\n }\n }\n\n if (noOfChildren == 0) {\n noOfChildren = 1;\n }\n return noOfChildren;\n};\n\nLNode.prototype.getEstimatedSize = function () {\n if (this.estimatedSize == Integer.MIN_VALUE) {\n throw \"assert failed\";\n }\n return this.estimatedSize;\n};\n\nLNode.prototype.calcEstimatedSize = function () {\n if (this.child == null) {\n return this.estimatedSize = (this.rect.width + this.rect.height) / 2;\n } else {\n this.estimatedSize = this.child.calcEstimatedSize();\n this.rect.width = this.estimatedSize;\n this.rect.height = this.estimatedSize;\n\n return this.estimatedSize;\n }\n};\n\nLNode.prototype.scatter = function () {\n var randomCenterX;\n var randomCenterY;\n\n var minX = -LayoutConstants.INITIAL_WORLD_BOUNDARY;\n var maxX = LayoutConstants.INITIAL_WORLD_BOUNDARY;\n randomCenterX = LayoutConstants.WORLD_CENTER_X + RandomSeed.nextDouble() * (maxX - minX) + minX;\n\n var minY = -LayoutConstants.INITIAL_WORLD_BOUNDARY;\n var maxY = LayoutConstants.INITIAL_WORLD_BOUNDARY;\n randomCenterY = LayoutConstants.WORLD_CENTER_Y + RandomSeed.nextDouble() * (maxY - minY) + minY;\n\n this.rect.x = randomCenterX;\n this.rect.y = randomCenterY;\n};\n\nLNode.prototype.updateBounds = function () {\n if (this.getChild() == null) {\n throw \"assert failed\";\n }\n if (this.getChild().getNodes().length != 0) {\n // wrap the children nodes by re-arranging the boundaries\n var childGraph = this.getChild();\n childGraph.updateBounds(true);\n\n this.rect.x = childGraph.getLeft();\n this.rect.y = childGraph.getTop();\n\n this.setWidth(childGraph.getRight() - childGraph.getLeft());\n this.setHeight(childGraph.getBottom() - childGraph.getTop());\n\n // Update compound bounds considering its label properties \n if (LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS) {\n\n var width = childGraph.getRight() - childGraph.getLeft();\n var height = childGraph.getBottom() - childGraph.getTop();\n\n if (this.labelWidth > width) {\n this.rect.x -= (this.labelWidth - width) / 2;\n this.setWidth(this.labelWidth);\n }\n\n if (this.labelHeight > height) {\n if (this.labelPos == \"center\") {\n this.rect.y -= (this.labelHeight - height) / 2;\n } else if (this.labelPos == \"top\") {\n this.rect.y -= this.labelHeight - height;\n }\n this.setHeight(this.labelHeight);\n }\n }\n }\n};\n\nLNode.prototype.getInclusionTreeDepth = function () {\n if (this.inclusionTreeDepth == Integer.MAX_VALUE) {\n throw \"assert failed\";\n }\n return this.inclusionTreeDepth;\n};\n\nLNode.prototype.transform = function (trans) {\n var left = this.rect.x;\n\n if (left > LayoutConstants.WORLD_BOUNDARY) {\n left = LayoutConstants.WORLD_BOUNDARY;\n } else if (left < -LayoutConstants.WORLD_BOUNDARY) {\n left = -LayoutConstants.WORLD_BOUNDARY;\n }\n\n var top = this.rect.y;\n\n if (top > LayoutConstants.WORLD_BOUNDARY) {\n top = LayoutConstants.WORLD_BOUNDARY;\n } else if (top < -LayoutConstants.WORLD_BOUNDARY) {\n top = -LayoutConstants.WORLD_BOUNDARY;\n }\n\n var leftTop = new PointD(left, top);\n var vLeftTop = trans.inverseTransformPoint(leftTop);\n\n this.setLocation(vLeftTop.x, vLeftTop.y);\n};\n\nLNode.prototype.getLeft = function () {\n return this.rect.x;\n};\n\nLNode.prototype.getRight = function () {\n return this.rect.x + this.rect.width;\n};\n\nLNode.prototype.getTop = function () {\n return this.rect.y;\n};\n\nLNode.prototype.getBottom = function () {\n return this.rect.y + this.rect.height;\n};\n\nLNode.prototype.getParent = function () {\n if (this.owner == null) {\n return null;\n }\n\n return this.owner.getParent();\n};\n\nmodule.exports = LNode;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction PointD(x, y) {\n if (x == null && y == null) {\n this.x = 0;\n this.y = 0;\n } else {\n this.x = x;\n this.y = y;\n }\n}\n\nPointD.prototype.getX = function () {\n return this.x;\n};\n\nPointD.prototype.getY = function () {\n return this.y;\n};\n\nPointD.prototype.setX = function (x) {\n this.x = x;\n};\n\nPointD.prototype.setY = function (y) {\n this.y = y;\n};\n\nPointD.prototype.getDifference = function (pt) {\n return new DimensionD(this.x - pt.x, this.y - pt.y);\n};\n\nPointD.prototype.getCopy = function () {\n return new PointD(this.x, this.y);\n};\n\nPointD.prototype.translate = function (dim) {\n this.x += dim.width;\n this.y += dim.height;\n return this;\n};\n\nmodule.exports = PointD;\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraphObject = __webpack_require__(2);\nvar Integer = __webpack_require__(10);\nvar LayoutConstants = __webpack_require__(0);\nvar LGraphManager = __webpack_require__(6);\nvar LNode = __webpack_require__(3);\nvar LEdge = __webpack_require__(1);\nvar RectangleD = __webpack_require__(13);\nvar Point = __webpack_require__(12);\nvar LinkedList = __webpack_require__(11);\n\nfunction LGraph(parent, obj2, vGraph) {\n LGraphObject.call(this, vGraph);\n this.estimatedSize = Integer.MIN_VALUE;\n this.margin = LayoutConstants.DEFAULT_GRAPH_MARGIN;\n this.edges = [];\n this.nodes = [];\n this.isConnected = false;\n this.parent = parent;\n\n if (obj2 != null && obj2 instanceof LGraphManager) {\n this.graphManager = obj2;\n } else if (obj2 != null && obj2 instanceof Layout) {\n this.graphManager = obj2.graphManager;\n }\n}\n\nLGraph.prototype = Object.create(LGraphObject.prototype);\nfor (var prop in LGraphObject) {\n LGraph[prop] = LGraphObject[prop];\n}\n\nLGraph.prototype.getNodes = function () {\n return this.nodes;\n};\n\nLGraph.prototype.getEdges = function () {\n return this.edges;\n};\n\nLGraph.prototype.getGraphManager = function () {\n return this.graphManager;\n};\n\nLGraph.prototype.getParent = function () {\n return this.parent;\n};\n\nLGraph.prototype.getLeft = function () {\n return this.left;\n};\n\nLGraph.prototype.getRight = function () {\n return this.right;\n};\n\nLGraph.prototype.getTop = function () {\n return this.top;\n};\n\nLGraph.prototype.getBottom = function () {\n return this.bottom;\n};\n\nLGraph.prototype.isConnected = function () {\n return this.isConnected;\n};\n\nLGraph.prototype.add = function (obj1, sourceNode, targetNode) {\n if (sourceNode == null && targetNode == null) {\n var newNode = obj1;\n if (this.graphManager == null) {\n throw \"Graph has no graph mgr!\";\n }\n if (this.getNodes().indexOf(newNode) > -1) {\n throw \"Node already in graph!\";\n }\n newNode.owner = this;\n this.getNodes().push(newNode);\n\n return newNode;\n } else {\n var newEdge = obj1;\n if (!(this.getNodes().indexOf(sourceNode) > -1 && this.getNodes().indexOf(targetNode) > -1)) {\n throw \"Source or target not in graph!\";\n }\n\n if (!(sourceNode.owner == targetNode.owner && sourceNode.owner == this)) {\n throw \"Both owners must be this graph!\";\n }\n\n if (sourceNode.owner != targetNode.owner) {\n return null;\n }\n\n // set source and target\n newEdge.source = sourceNode;\n newEdge.target = targetNode;\n\n // set as intra-graph edge\n newEdge.isInterGraph = false;\n\n // add to graph edge list\n this.getEdges().push(newEdge);\n\n // add to incidency lists\n sourceNode.edges.push(newEdge);\n\n if (targetNode != sourceNode) {\n targetNode.edges.push(newEdge);\n }\n\n return newEdge;\n }\n};\n\nLGraph.prototype.remove = function (obj) {\n var node = obj;\n if (obj instanceof LNode) {\n if (node == null) {\n throw \"Node is null!\";\n }\n if (!(node.owner != null && node.owner == this)) {\n throw \"Owner graph is invalid!\";\n }\n if (this.graphManager == null) {\n throw \"Owner graph manager is invalid!\";\n }\n // remove incident edges first (make a copy to do it safely)\n var edgesToBeRemoved = node.edges.slice();\n var edge;\n var s = edgesToBeRemoved.length;\n for (var i = 0; i < s; i++) {\n edge = edgesToBeRemoved[i];\n\n if (edge.isInterGraph) {\n this.graphManager.remove(edge);\n } else {\n edge.source.owner.remove(edge);\n }\n }\n\n // now the node itself\n var index = this.nodes.indexOf(node);\n if (index == -1) {\n throw \"Node not in owner node list!\";\n }\n\n this.nodes.splice(index, 1);\n } else if (obj instanceof LEdge) {\n var edge = obj;\n if (edge == null) {\n throw \"Edge is null!\";\n }\n if (!(edge.source != null && edge.target != null)) {\n throw \"Source and/or target is null!\";\n }\n if (!(edge.source.owner != null && edge.target.owner != null && edge.source.owner == this && edge.target.owner == this)) {\n throw \"Source and/or target owner is invalid!\";\n }\n\n var sourceIndex = edge.source.edges.indexOf(edge);\n var targetIndex = edge.target.edges.indexOf(edge);\n if (!(sourceIndex > -1 && targetIndex > -1)) {\n throw \"Source and/or target doesn't know this edge!\";\n }\n\n edge.source.edges.splice(sourceIndex, 1);\n\n if (edge.target != edge.source) {\n edge.target.edges.splice(targetIndex, 1);\n }\n\n var index = edge.source.owner.getEdges().indexOf(edge);\n if (index == -1) {\n throw \"Not in owner's edge list!\";\n }\n\n edge.source.owner.getEdges().splice(index, 1);\n }\n};\n\nLGraph.prototype.updateLeftTop = function () {\n var top = Integer.MAX_VALUE;\n var left = Integer.MAX_VALUE;\n var nodeTop;\n var nodeLeft;\n var margin;\n\n var nodes = this.getNodes();\n var s = nodes.length;\n\n for (var i = 0; i < s; i++) {\n var lNode = nodes[i];\n nodeTop = lNode.getTop();\n nodeLeft = lNode.getLeft();\n\n if (top > nodeTop) {\n top = nodeTop;\n }\n\n if (left > nodeLeft) {\n left = nodeLeft;\n }\n }\n\n // Do we have any nodes in this graph?\n if (top == Integer.MAX_VALUE) {\n return null;\n }\n\n if (nodes[0].getParent().paddingLeft != undefined) {\n margin = nodes[0].getParent().paddingLeft;\n } else {\n margin = this.margin;\n }\n\n this.left = left - margin;\n this.top = top - margin;\n\n // Apply the margins and return the result\n return new Point(this.left, this.top);\n};\n\nLGraph.prototype.updateBounds = function (recursive) {\n // calculate bounds\n var left = Integer.MAX_VALUE;\n var right = -Integer.MAX_VALUE;\n var top = Integer.MAX_VALUE;\n var bottom = -Integer.MAX_VALUE;\n var nodeLeft;\n var nodeRight;\n var nodeTop;\n var nodeBottom;\n var margin;\n\n var nodes = this.nodes;\n var s = nodes.length;\n for (var i = 0; i < s; i++) {\n var lNode = nodes[i];\n\n if (recursive && lNode.child != null) {\n lNode.updateBounds();\n }\n nodeLeft = lNode.getLeft();\n nodeRight = lNode.getRight();\n nodeTop = lNode.getTop();\n nodeBottom = lNode.getBottom();\n\n if (left > nodeLeft) {\n left = nodeLeft;\n }\n\n if (right < nodeRight) {\n right = nodeRight;\n }\n\n if (top > nodeTop) {\n top = nodeTop;\n }\n\n if (bottom < nodeBottom) {\n bottom = nodeBottom;\n }\n }\n\n var boundingRect = new RectangleD(left, top, right - left, bottom - top);\n if (left == Integer.MAX_VALUE) {\n this.left = this.parent.getLeft();\n this.right = this.parent.getRight();\n this.top = this.parent.getTop();\n this.bottom = this.parent.getBottom();\n }\n\n if (nodes[0].getParent().paddingLeft != undefined) {\n margin = nodes[0].getParent().paddingLeft;\n } else {\n margin = this.margin;\n }\n\n this.left = boundingRect.x - margin;\n this.right = boundingRect.x + boundingRect.width + margin;\n this.top = boundingRect.y - margin;\n this.bottom = boundingRect.y + boundingRect.height + margin;\n};\n\nLGraph.calculateBounds = function (nodes) {\n var left = Integer.MAX_VALUE;\n var right = -Integer.MAX_VALUE;\n var top = Integer.MAX_VALUE;\n var bottom = -Integer.MAX_VALUE;\n var nodeLeft;\n var nodeRight;\n var nodeTop;\n var nodeBottom;\n\n var s = nodes.length;\n\n for (var i = 0; i < s; i++) {\n var lNode = nodes[i];\n nodeLeft = lNode.getLeft();\n nodeRight = lNode.getRight();\n nodeTop = lNode.getTop();\n nodeBottom = lNode.getBottom();\n\n if (left > nodeLeft) {\n left = nodeLeft;\n }\n\n if (right < nodeRight) {\n right = nodeRight;\n }\n\n if (top > nodeTop) {\n top = nodeTop;\n }\n\n if (bottom < nodeBottom) {\n bottom = nodeBottom;\n }\n }\n\n var boundingRect = new RectangleD(left, top, right - left, bottom - top);\n\n return boundingRect;\n};\n\nLGraph.prototype.getInclusionTreeDepth = function () {\n if (this == this.graphManager.getRoot()) {\n return 1;\n } else {\n return this.parent.getInclusionTreeDepth();\n }\n};\n\nLGraph.prototype.getEstimatedSize = function () {\n if (this.estimatedSize == Integer.MIN_VALUE) {\n throw \"assert failed\";\n }\n return this.estimatedSize;\n};\n\nLGraph.prototype.calcEstimatedSize = function () {\n var size = 0;\n var nodes = this.nodes;\n var s = nodes.length;\n\n for (var i = 0; i < s; i++) {\n var lNode = nodes[i];\n size += lNode.calcEstimatedSize();\n }\n\n if (size == 0) {\n this.estimatedSize = LayoutConstants.EMPTY_COMPOUND_NODE_SIZE;\n } else {\n this.estimatedSize = size / Math.sqrt(this.nodes.length);\n }\n\n return this.estimatedSize;\n};\n\nLGraph.prototype.updateConnected = function () {\n var self = this;\n if (this.nodes.length == 0) {\n this.isConnected = true;\n return;\n }\n\n var queue = new LinkedList();\n var visited = new Set();\n var currentNode = this.nodes[0];\n var neighborEdges;\n var currentNeighbor;\n var childrenOfNode = currentNode.withChildren();\n childrenOfNode.forEach(function (node) {\n queue.push(node);\n visited.add(node);\n });\n\n while (queue.length !== 0) {\n currentNode = queue.shift();\n\n // Traverse all neighbors of this node\n neighborEdges = currentNode.getEdges();\n var size = neighborEdges.length;\n for (var i = 0; i < size; i++) {\n var neighborEdge = neighborEdges[i];\n currentNeighbor = neighborEdge.getOtherEndInGraph(currentNode, this);\n\n // Add unvisited neighbors to the list to visit\n if (currentNeighbor != null && !visited.has(currentNeighbor)) {\n var childrenOfNeighbor = currentNeighbor.withChildren();\n\n childrenOfNeighbor.forEach(function (node) {\n queue.push(node);\n visited.add(node);\n });\n }\n }\n }\n\n this.isConnected = false;\n\n if (visited.size >= this.nodes.length) {\n var noOfVisitedInThisGraph = 0;\n\n visited.forEach(function (visitedNode) {\n if (visitedNode.owner == self) {\n noOfVisitedInThisGraph++;\n }\n });\n\n if (noOfVisitedInThisGraph == this.nodes.length) {\n this.isConnected = true;\n }\n }\n};\n\nmodule.exports = LGraph;\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraph;\nvar LEdge = __webpack_require__(1);\n\nfunction LGraphManager(layout) {\n LGraph = __webpack_require__(5); // It may be better to initilize this out of this function but it gives an error (Right-hand side of 'instanceof' is not callable) now.\n this.layout = layout;\n\n this.graphs = [];\n this.edges = [];\n}\n\nLGraphManager.prototype.addRoot = function () {\n var ngraph = this.layout.newGraph();\n var nnode = this.layout.newNode(null);\n var root = this.add(ngraph, nnode);\n this.setRootGraph(root);\n return this.rootGraph;\n};\n\nLGraphManager.prototype.add = function (newGraph, parentNode, newEdge, sourceNode, targetNode) {\n //there are just 2 parameters are passed then it adds an LGraph else it adds an LEdge\n if (newEdge == null && sourceNode == null && targetNode == null) {\n if (newGraph == null) {\n throw \"Graph is null!\";\n }\n if (parentNode == null) {\n throw \"Parent node is null!\";\n }\n if (this.graphs.indexOf(newGraph) > -1) {\n throw \"Graph already in this graph mgr!\";\n }\n\n this.graphs.push(newGraph);\n\n if (newGraph.parent != null) {\n throw \"Already has a parent!\";\n }\n if (parentNode.child != null) {\n throw \"Already has a child!\";\n }\n\n newGraph.parent = parentNode;\n parentNode.child = newGraph;\n\n return newGraph;\n } else {\n //change the order of the parameters\n targetNode = newEdge;\n sourceNode = parentNode;\n newEdge = newGraph;\n var sourceGraph = sourceNode.getOwner();\n var targetGraph = targetNode.getOwner();\n\n if (!(sourceGraph != null && sourceGraph.getGraphManager() == this)) {\n throw \"Source not in this graph mgr!\";\n }\n if (!(targetGraph != null && targetGraph.getGraphManager() == this)) {\n throw \"Target not in this graph mgr!\";\n }\n\n if (sourceGraph == targetGraph) {\n newEdge.isInterGraph = false;\n return sourceGraph.add(newEdge, sourceNode, targetNode);\n } else {\n newEdge.isInterGraph = true;\n\n // set source and target\n newEdge.source = sourceNode;\n newEdge.target = targetNode;\n\n // add edge to inter-graph edge list\n if (this.edges.indexOf(newEdge) > -1) {\n throw \"Edge already in inter-graph edge list!\";\n }\n\n this.edges.push(newEdge);\n\n // add edge to source and target incidency lists\n if (!(newEdge.source != null && newEdge.target != null)) {\n throw \"Edge source and/or target is null!\";\n }\n\n if (!(newEdge.source.edges.indexOf(newEdge) == -1 && newEdge.target.edges.indexOf(newEdge) == -1)) {\n throw \"Edge already in source and/or target incidency list!\";\n }\n\n newEdge.source.edges.push(newEdge);\n newEdge.target.edges.push(newEdge);\n\n return newEdge;\n }\n }\n};\n\nLGraphManager.prototype.remove = function (lObj) {\n if (lObj instanceof LGraph) {\n var graph = lObj;\n if (graph.getGraphManager() != this) {\n throw \"Graph not in this graph mgr\";\n }\n if (!(graph == this.rootGraph || graph.parent != null && graph.parent.graphManager == this)) {\n throw \"Invalid parent node!\";\n }\n\n // first the edges (make a copy to do it safely)\n var edgesToBeRemoved = [];\n\n edgesToBeRemoved = edgesToBeRemoved.concat(graph.getEdges());\n\n var edge;\n var s = edgesToBeRemoved.length;\n for (var i = 0; i < s; i++) {\n edge = edgesToBeRemoved[i];\n graph.remove(edge);\n }\n\n // then the nodes (make a copy to do it safely)\n var nodesToBeRemoved = [];\n\n nodesToBeRemoved = nodesToBeRemoved.concat(graph.getNodes());\n\n var node;\n s = nodesToBeRemoved.length;\n for (var i = 0; i < s; i++) {\n node = nodesToBeRemoved[i];\n graph.remove(node);\n }\n\n // check if graph is the root\n if (graph == this.rootGraph) {\n this.setRootGraph(null);\n }\n\n // now remove the graph itself\n var index = this.graphs.indexOf(graph);\n this.graphs.splice(index, 1);\n\n // also reset the parent of the graph\n graph.parent = null;\n } else if (lObj instanceof LEdge) {\n edge = lObj;\n if (edge == null) {\n throw \"Edge is null!\";\n }\n if (!edge.isInterGraph) {\n throw \"Not an inter-graph edge!\";\n }\n if (!(edge.source != null && edge.target != null)) {\n throw \"Source and/or target is null!\";\n }\n\n // remove edge from source and target nodes' incidency lists\n\n if (!(edge.source.edges.indexOf(edge) != -1 && edge.target.edges.indexOf(edge) != -1)) {\n throw \"Source and/or target doesn't know this edge!\";\n }\n\n var index = edge.source.edges.indexOf(edge);\n edge.source.edges.splice(index, 1);\n index = edge.target.edges.indexOf(edge);\n edge.target.edges.splice(index, 1);\n\n // remove edge from owner graph manager's inter-graph edge list\n\n if (!(edge.source.owner != null && edge.source.owner.getGraphManager() != null)) {\n throw \"Edge owner graph or owner graph manager is null!\";\n }\n if (edge.source.owner.getGraphManager().edges.indexOf(edge) == -1) {\n throw \"Not in owner graph manager's edge list!\";\n }\n\n var index = edge.source.owner.getGraphManager().edges.indexOf(edge);\n edge.source.owner.getGraphManager().edges.splice(index, 1);\n }\n};\n\nLGraphManager.prototype.updateBounds = function () {\n this.rootGraph.updateBounds(true);\n};\n\nLGraphManager.prototype.getGraphs = function () {\n return this.graphs;\n};\n\nLGraphManager.prototype.getAllNodes = function () {\n if (this.allNodes == null) {\n var nodeList = [];\n var graphs = this.getGraphs();\n var s = graphs.length;\n for (var i = 0; i < s; i++) {\n nodeList = nodeList.concat(graphs[i].getNodes());\n }\n this.allNodes = nodeList;\n }\n return this.allNodes;\n};\n\nLGraphManager.prototype.resetAllNodes = function () {\n this.allNodes = null;\n};\n\nLGraphManager.prototype.resetAllEdges = function () {\n this.allEdges = null;\n};\n\nLGraphManager.prototype.resetAllNodesToApplyGravitation = function () {\n this.allNodesToApplyGravitation = null;\n};\n\nLGraphManager.prototype.getAllEdges = function () {\n if (this.allEdges == null) {\n var edgeList = [];\n var graphs = this.getGraphs();\n var s = graphs.length;\n for (var i = 0; i < graphs.length; i++) {\n edgeList = edgeList.concat(graphs[i].getEdges());\n }\n\n edgeList = edgeList.concat(this.edges);\n\n this.allEdges = edgeList;\n }\n return this.allEdges;\n};\n\nLGraphManager.prototype.getAllNodesToApplyGravitation = function () {\n return this.allNodesToApplyGravitation;\n};\n\nLGraphManager.prototype.setAllNodesToApplyGravitation = function (nodeList) {\n if (this.allNodesToApplyGravitation != null) {\n throw \"assert failed\";\n }\n\n this.allNodesToApplyGravitation = nodeList;\n};\n\nLGraphManager.prototype.getRoot = function () {\n return this.rootGraph;\n};\n\nLGraphManager.prototype.setRootGraph = function (graph) {\n if (graph.getGraphManager() != this) {\n throw \"Root not in this graph mgr!\";\n }\n\n this.rootGraph = graph;\n // root graph must have a root node associated with it for convenience\n if (graph.parent == null) {\n graph.parent = this.layout.newNode(\"Root node\");\n }\n};\n\nLGraphManager.prototype.getLayout = function () {\n return this.layout;\n};\n\nLGraphManager.prototype.isOneAncestorOfOther = function (firstNode, secondNode) {\n if (!(firstNode != null && secondNode != null)) {\n throw \"assert failed\";\n }\n\n if (firstNode == secondNode) {\n return true;\n }\n // Is second node an ancestor of the first one?\n var ownerGraph = firstNode.getOwner();\n var parentNode;\n\n do {\n parentNode = ownerGraph.getParent();\n\n if (parentNode == null) {\n break;\n }\n\n if (parentNode == secondNode) {\n return true;\n }\n\n ownerGraph = parentNode.getOwner();\n if (ownerGraph == null) {\n break;\n }\n } while (true);\n // Is first node an ancestor of the second one?\n ownerGraph = secondNode.getOwner();\n\n do {\n parentNode = ownerGraph.getParent();\n\n if (parentNode == null) {\n break;\n }\n\n if (parentNode == firstNode) {\n return true;\n }\n\n ownerGraph = parentNode.getOwner();\n if (ownerGraph == null) {\n break;\n }\n } while (true);\n\n return false;\n};\n\nLGraphManager.prototype.calcLowestCommonAncestors = function () {\n var edge;\n var sourceNode;\n var targetNode;\n var sourceAncestorGraph;\n var targetAncestorGraph;\n\n var edges = this.getAllEdges();\n var s = edges.length;\n for (var i = 0; i < s; i++) {\n edge = edges[i];\n\n sourceNode = edge.source;\n targetNode = edge.target;\n edge.lca = null;\n edge.sourceInLca = sourceNode;\n edge.targetInLca = targetNode;\n\n if (sourceNode == targetNode) {\n edge.lca = sourceNode.getOwner();\n continue;\n }\n\n sourceAncestorGraph = sourceNode.getOwner();\n\n while (edge.lca == null) {\n edge.targetInLca = targetNode;\n targetAncestorGraph = targetNode.getOwner();\n\n while (edge.lca == null) {\n if (targetAncestorGraph == sourceAncestorGraph) {\n edge.lca = targetAncestorGraph;\n break;\n }\n\n if (targetAncestorGraph == this.rootGraph) {\n break;\n }\n\n if (edge.lca != null) {\n throw \"assert failed\";\n }\n edge.targetInLca = targetAncestorGraph.getParent();\n targetAncestorGraph = edge.targetInLca.getOwner();\n }\n\n if (sourceAncestorGraph == this.rootGraph) {\n break;\n }\n\n if (edge.lca == null) {\n edge.sourceInLca = sourceAncestorGraph.getParent();\n sourceAncestorGraph = edge.sourceInLca.getOwner();\n }\n }\n\n if (edge.lca == null) {\n throw \"assert failed\";\n }\n }\n};\n\nLGraphManager.prototype.calcLowestCommonAncestor = function (firstNode, secondNode) {\n if (firstNode == secondNode) {\n return firstNode.getOwner();\n }\n var firstOwnerGraph = firstNode.getOwner();\n\n do {\n if (firstOwnerGraph == null) {\n break;\n }\n var secondOwnerGraph = secondNode.getOwner();\n\n do {\n if (secondOwnerGraph == null) {\n break;\n }\n\n if (secondOwnerGraph == firstOwnerGraph) {\n return secondOwnerGraph;\n }\n secondOwnerGraph = secondOwnerGraph.getParent().getOwner();\n } while (true);\n\n firstOwnerGraph = firstOwnerGraph.getParent().getOwner();\n } while (true);\n\n return firstOwnerGraph;\n};\n\nLGraphManager.prototype.calcInclusionTreeDepths = function (graph, depth) {\n if (graph == null && depth == null) {\n graph = this.rootGraph;\n depth = 1;\n }\n var node;\n\n var nodes = graph.getNodes();\n var s = nodes.length;\n for (var i = 0; i < s; i++) {\n node = nodes[i];\n node.inclusionTreeDepth = depth;\n\n if (node.child != null) {\n this.calcInclusionTreeDepths(node.child, depth + 1);\n }\n }\n};\n\nLGraphManager.prototype.includesInvalidEdge = function () {\n var edge;\n\n var s = this.edges.length;\n for (var i = 0; i < s; i++) {\n edge = this.edges[i];\n\n if (this.isOneAncestorOfOther(edge.source, edge.target)) {\n return true;\n }\n }\n return false;\n};\n\nmodule.exports = LGraphManager;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LayoutConstants = __webpack_require__(0);\n\nfunction FDLayoutConstants() {}\n\n//FDLayoutConstants inherits static props in LayoutConstants\nfor (var prop in LayoutConstants) {\n FDLayoutConstants[prop] = LayoutConstants[prop];\n}\n\nFDLayoutConstants.MAX_ITERATIONS = 2500;\n\nFDLayoutConstants.DEFAULT_EDGE_LENGTH = 50;\nFDLayoutConstants.DEFAULT_SPRING_STRENGTH = 0.45;\nFDLayoutConstants.DEFAULT_REPULSION_STRENGTH = 4500.0;\nFDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = 0.4;\nFDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = 1.0;\nFDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = 3.8;\nFDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = 1.5;\nFDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION = true;\nFDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION = true;\nFDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = 0.3;\nFDLayoutConstants.COOLING_ADAPTATION_FACTOR = 0.33;\nFDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT = 1000;\nFDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT = 5000;\nFDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL = 100.0;\nFDLayoutConstants.MAX_NODE_DISPLACEMENT = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL * 3;\nFDLayoutConstants.MIN_REPULSION_DIST = FDLayoutConstants.DEFAULT_EDGE_LENGTH / 10.0;\nFDLayoutConstants.CONVERGENCE_CHECK_PERIOD = 100;\nFDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = 0.1;\nFDLayoutConstants.MIN_EDGE_LENGTH = 1;\nFDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD = 10;\n\nmodule.exports = FDLayoutConstants;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/**\n * This class maintains a list of static geometry related utility methods.\n *\n *\n * Copyright: i-Vis Research Group, Bilkent University, 2007 - present\n */\n\nvar Point = __webpack_require__(12);\n\nfunction IGeometry() {}\n\n/**\n * This method calculates *half* the amount in x and y directions of the two\n * input rectangles needed to separate them keeping their respective\n * positioning, and returns the result in the input array. An input\n * separation buffer added to the amount in both directions. We assume that\n * the two rectangles do intersect.\n */\nIGeometry.calcSeparationAmount = function (rectA, rectB, overlapAmount, separationBuffer) {\n if (!rectA.intersects(rectB)) {\n throw \"assert failed\";\n }\n\n var directions = new Array(2);\n\n this.decideDirectionsForOverlappingNodes(rectA, rectB, directions);\n\n overlapAmount[0] = Math.min(rectA.getRight(), rectB.getRight()) - Math.max(rectA.x, rectB.x);\n overlapAmount[1] = Math.min(rectA.getBottom(), rectB.getBottom()) - Math.max(rectA.y, rectB.y);\n\n // update the overlapping amounts for the following cases:\n if (rectA.getX() <= rectB.getX() && rectA.getRight() >= rectB.getRight()) {\n /* Case x.1:\n *\n * rectA\n * \t| |\n * \t| _________ |\n * \t| | | |\n * \t|________|_______|______|\n * \t\t\t | |\n * | |\n * rectB\n */\n overlapAmount[0] += Math.min(rectB.getX() - rectA.getX(), rectA.getRight() - rectB.getRight());\n } else if (rectB.getX() <= rectA.getX() && rectB.getRight() >= rectA.getRight()) {\n /* Case x.2:\n *\n * rectB\n * \t| |\n * \t| _________ |\n * \t| | | |\n * \t|________|_______|______|\n * \t\t\t | |\n * | |\n * rectA\n */\n overlapAmount[0] += Math.min(rectA.getX() - rectB.getX(), rectB.getRight() - rectA.getRight());\n }\n if (rectA.getY() <= rectB.getY() && rectA.getBottom() >= rectB.getBottom()) {\n /* Case y.1:\n * ________ rectA\n * |\n * |\n * ______|____ rectB\n * | |\n * | |\n * ______|____|\n * |\n * |\n * |________\n *\n */\n overlapAmount[1] += Math.min(rectB.getY() - rectA.getY(), rectA.getBottom() - rectB.getBottom());\n } else if (rectB.getY() <= rectA.getY() && rectB.getBottom() >= rectA.getBottom()) {\n /* Case y.2:\n * ________ rectB\n * |\n * |\n * ______|____ rectA\n * | |\n * | |\n * ______|____|\n * |\n * |\n * |________\n *\n */\n overlapAmount[1] += Math.min(rectA.getY() - rectB.getY(), rectB.getBottom() - rectA.getBottom());\n }\n\n // find slope of the line passes two centers\n var slope = Math.abs((rectB.getCenterY() - rectA.getCenterY()) / (rectB.getCenterX() - rectA.getCenterX()));\n // if centers are overlapped\n if (rectB.getCenterY() === rectA.getCenterY() && rectB.getCenterX() === rectA.getCenterX()) {\n // assume the slope is 1 (45 degree)\n slope = 1.0;\n }\n\n var moveByY = slope * overlapAmount[0];\n var moveByX = overlapAmount[1] / slope;\n if (overlapAmount[0] < moveByX) {\n moveByX = overlapAmount[0];\n } else {\n moveByY = overlapAmount[1];\n }\n // return half the amount so that if each rectangle is moved by these\n // amounts in opposite directions, overlap will be resolved\n overlapAmount[0] = -1 * directions[0] * (moveByX / 2 + separationBuffer);\n overlapAmount[1] = -1 * directions[1] * (moveByY / 2 + separationBuffer);\n};\n\n/**\n * This method decides the separation direction of overlapping nodes\n *\n * if directions[0] = -1, then rectA goes left\n * if directions[0] = 1, then rectA goes right\n * if directions[1] = -1, then rectA goes up\n * if directions[1] = 1, then rectA goes down\n */\nIGeometry.decideDirectionsForOverlappingNodes = function (rectA, rectB, directions) {\n if (rectA.getCenterX() < rectB.getCenterX()) {\n directions[0] = -1;\n } else {\n directions[0] = 1;\n }\n\n if (rectA.getCenterY() < rectB.getCenterY()) {\n directions[1] = -1;\n } else {\n directions[1] = 1;\n }\n};\n\n/**\n * This method calculates the intersection (clipping) points of the two\n * input rectangles with line segment defined by the centers of these two\n * rectangles. The clipping points are saved in the input double array and\n * whether or not the two rectangles overlap is returned.\n */\nIGeometry.getIntersection2 = function (rectA, rectB, result) {\n //result[0-1] will contain clipPoint of rectA, result[2-3] will contain clipPoint of rectB\n var p1x = rectA.getCenterX();\n var p1y = rectA.getCenterY();\n var p2x = rectB.getCenterX();\n var p2y = rectB.getCenterY();\n\n //if two rectangles intersect, then clipping points are centers\n if (rectA.intersects(rectB)) {\n result[0] = p1x;\n result[1] = p1y;\n result[2] = p2x;\n result[3] = p2y;\n return true;\n }\n //variables for rectA\n var topLeftAx = rectA.getX();\n var topLeftAy = rectA.getY();\n var topRightAx = rectA.getRight();\n var bottomLeftAx = rectA.getX();\n var bottomLeftAy = rectA.getBottom();\n var bottomRightAx = rectA.getRight();\n var halfWidthA = rectA.getWidthHalf();\n var halfHeightA = rectA.getHeightHalf();\n //variables for rectB\n var topLeftBx = rectB.getX();\n var topLeftBy = rectB.getY();\n var topRightBx = rectB.getRight();\n var bottomLeftBx = rectB.getX();\n var bottomLeftBy = rectB.getBottom();\n var bottomRightBx = rectB.getRight();\n var halfWidthB = rectB.getWidthHalf();\n var halfHeightB = rectB.getHeightHalf();\n\n //flag whether clipping points are found\n var clipPointAFound = false;\n var clipPointBFound = false;\n\n // line is vertical\n if (p1x === p2x) {\n if (p1y > p2y) {\n result[0] = p1x;\n result[1] = topLeftAy;\n result[2] = p2x;\n result[3] = bottomLeftBy;\n return false;\n } else if (p1y < p2y) {\n result[0] = p1x;\n result[1] = bottomLeftAy;\n result[2] = p2x;\n result[3] = topLeftBy;\n return false;\n } else {\n //not line, return null;\n }\n }\n // line is horizontal\n else if (p1y === p2y) {\n if (p1x > p2x) {\n result[0] = topLeftAx;\n result[1] = p1y;\n result[2] = topRightBx;\n result[3] = p2y;\n return false;\n } else if (p1x < p2x) {\n result[0] = topRightAx;\n result[1] = p1y;\n result[2] = topLeftBx;\n result[3] = p2y;\n return false;\n } else {\n //not valid line, return null;\n }\n } else {\n //slopes of rectA's and rectB's diagonals\n var slopeA = rectA.height / rectA.width;\n var slopeB = rectB.height / rectB.width;\n\n //slope of line between center of rectA and center of rectB\n var slopePrime = (p2y - p1y) / (p2x - p1x);\n var cardinalDirectionA = void 0;\n var cardinalDirectionB = void 0;\n var tempPointAx = void 0;\n var tempPointAy = void 0;\n var tempPointBx = void 0;\n var tempPointBy = void 0;\n\n //determine whether clipping point is the corner of nodeA\n if (-slopeA === slopePrime) {\n if (p1x > p2x) {\n result[0] = bottomLeftAx;\n result[1] = bottomLeftAy;\n clipPointAFound = true;\n } else {\n result[0] = topRightAx;\n result[1] = topLeftAy;\n clipPointAFound = true;\n }\n } else if (slopeA === slopePrime) {\n if (p1x > p2x) {\n result[0] = topLeftAx;\n result[1] = topLeftAy;\n clipPointAFound = true;\n } else {\n result[0] = bottomRightAx;\n result[1] = bottomLeftAy;\n clipPointAFound = true;\n }\n }\n\n //determine whether clipping point is the corner of nodeB\n if (-slopeB === slopePrime) {\n if (p2x > p1x) {\n result[2] = bottomLeftBx;\n result[3] = bottomLeftBy;\n clipPointBFound = true;\n } else {\n result[2] = topRightBx;\n result[3] = topLeftBy;\n clipPointBFound = true;\n }\n } else if (slopeB === slopePrime) {\n if (p2x > p1x) {\n result[2] = topLeftBx;\n result[3] = topLeftBy;\n clipPointBFound = true;\n } else {\n result[2] = bottomRightBx;\n result[3] = bottomLeftBy;\n clipPointBFound = true;\n }\n }\n\n //if both clipping points are corners\n if (clipPointAFound && clipPointBFound) {\n return false;\n }\n\n //determine Cardinal Direction of rectangles\n if (p1x > p2x) {\n if (p1y > p2y) {\n cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 4);\n cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 2);\n } else {\n cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 3);\n cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 1);\n }\n } else {\n if (p1y > p2y) {\n cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 1);\n cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 3);\n } else {\n cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 2);\n cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 4);\n }\n }\n //calculate clipping Point if it is not found before\n if (!clipPointAFound) {\n switch (cardinalDirectionA) {\n case 1:\n tempPointAy = topLeftAy;\n tempPointAx = p1x + -halfHeightA / slopePrime;\n result[0] = tempPointAx;\n result[1] = tempPointAy;\n break;\n case 2:\n tempPointAx = bottomRightAx;\n tempPointAy = p1y + halfWidthA * slopePrime;\n result[0] = tempPointAx;\n result[1] = tempPointAy;\n break;\n case 3:\n tempPointAy = bottomLeftAy;\n tempPointAx = p1x + halfHeightA / slopePrime;\n result[0] = tempPointAx;\n result[1] = tempPointAy;\n break;\n case 4:\n tempPointAx = bottomLeftAx;\n tempPointAy = p1y + -halfWidthA * slopePrime;\n result[0] = tempPointAx;\n result[1] = tempPointAy;\n break;\n }\n }\n if (!clipPointBFound) {\n switch (cardinalDirectionB) {\n case 1:\n tempPointBy = topLeftBy;\n tempPointBx = p2x + -halfHeightB / slopePrime;\n result[2] = tempPointBx;\n result[3] = tempPointBy;\n break;\n case 2:\n tempPointBx = bottomRightBx;\n tempPointBy = p2y + halfWidthB * slopePrime;\n result[2] = tempPointBx;\n result[3] = tempPointBy;\n break;\n case 3:\n tempPointBy = bottomLeftBy;\n tempPointBx = p2x + halfHeightB / slopePrime;\n result[2] = tempPointBx;\n result[3] = tempPointBy;\n break;\n case 4:\n tempPointBx = bottomLeftBx;\n tempPointBy = p2y + -halfWidthB * slopePrime;\n result[2] = tempPointBx;\n result[3] = tempPointBy;\n break;\n }\n }\n }\n return false;\n};\n\n/**\n * This method returns in which cardinal direction does input point stays\n * 1: North\n * 2: East\n * 3: South\n * 4: West\n */\nIGeometry.getCardinalDirection = function (slope, slopePrime, line) {\n if (slope > slopePrime) {\n return line;\n } else {\n return 1 + line % 4;\n }\n};\n\n/**\n * This method calculates the intersection of the two lines defined by\n * point pairs (s1,s2) and (f1,f2).\n */\nIGeometry.getIntersection = function (s1, s2, f1, f2) {\n if (f2 == null) {\n return this.getIntersection2(s1, s2, f1);\n }\n\n var x1 = s1.x;\n var y1 = s1.y;\n var x2 = s2.x;\n var y2 = s2.y;\n var x3 = f1.x;\n var y3 = f1.y;\n var x4 = f2.x;\n var y4 = f2.y;\n var x = void 0,\n y = void 0; // intersection point\n var a1 = void 0,\n a2 = void 0,\n b1 = void 0,\n b2 = void 0,\n c1 = void 0,\n c2 = void 0; // coefficients of line eqns.\n var denom = void 0;\n\n a1 = y2 - y1;\n b1 = x1 - x2;\n c1 = x2 * y1 - x1 * y2; // { a1*x + b1*y + c1 = 0 is line 1 }\n\n a2 = y4 - y3;\n b2 = x3 - x4;\n c2 = x4 * y3 - x3 * y4; // { a2*x + b2*y + c2 = 0 is line 2 }\n\n denom = a1 * b2 - a2 * b1;\n\n if (denom === 0) {\n return null;\n }\n\n x = (b1 * c2 - b2 * c1) / denom;\n y = (a2 * c1 - a1 * c2) / denom;\n\n return new Point(x, y);\n};\n\n/**\n * This method finds and returns the angle of the vector from the + x-axis\n * in clockwise direction (compatible w/ Java coordinate system!).\n */\nIGeometry.angleOfVector = function (Cx, Cy, Nx, Ny) {\n var C_angle = void 0;\n\n if (Cx !== Nx) {\n C_angle = Math.atan((Ny - Cy) / (Nx - Cx));\n\n if (Nx < Cx) {\n C_angle += Math.PI;\n } else if (Ny < Cy) {\n C_angle += this.TWO_PI;\n }\n } else if (Ny < Cy) {\n C_angle = this.ONE_AND_HALF_PI; // 270 degrees\n } else {\n C_angle = this.HALF_PI; // 90 degrees\n }\n\n return C_angle;\n};\n\n/**\n * This method checks whether the given two line segments (one with point\n * p1 and p2, the other with point p3 and p4) intersect at a point other\n * than these points.\n */\nIGeometry.doIntersect = function (p1, p2, p3, p4) {\n var a = p1.x;\n var b = p1.y;\n var c = p2.x;\n var d = p2.y;\n var p = p3.x;\n var q = p3.y;\n var r = p4.x;\n var s = p4.y;\n var det = (c - a) * (s - q) - (r - p) * (d - b);\n\n if (det === 0) {\n return false;\n } else {\n var lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det;\n var gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det;\n return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1;\n }\n};\n\n// -----------------------------------------------------------------------------\n// Section: Class Constants\n// -----------------------------------------------------------------------------\n/**\n * Some useful pre-calculated constants\n */\nIGeometry.HALF_PI = 0.5 * Math.PI;\nIGeometry.ONE_AND_HALF_PI = 1.5 * Math.PI;\nIGeometry.TWO_PI = 2.0 * Math.PI;\nIGeometry.THREE_PI = 3.0 * Math.PI;\n\nmodule.exports = IGeometry;\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction IMath() {}\n\n/**\n * This method returns the sign of the input value.\n */\nIMath.sign = function (value) {\n if (value > 0) {\n return 1;\n } else if (value < 0) {\n return -1;\n } else {\n return 0;\n }\n};\n\nIMath.floor = function (value) {\n return value < 0 ? Math.ceil(value) : Math.floor(value);\n};\n\nIMath.ceil = function (value) {\n return value < 0 ? Math.floor(value) : Math.ceil(value);\n};\n\nmodule.exports = IMath;\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction Integer() {}\n\nInteger.MAX_VALUE = 2147483647;\nInteger.MIN_VALUE = -2147483648;\n\nmodule.exports = Integer;\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar nodeFrom = function nodeFrom(value) {\n return { value: value, next: null, prev: null };\n};\n\nvar add = function add(prev, node, next, list) {\n if (prev !== null) {\n prev.next = node;\n } else {\n list.head = node;\n }\n\n if (next !== null) {\n next.prev = node;\n } else {\n list.tail = node;\n }\n\n node.prev = prev;\n node.next = next;\n\n list.length++;\n\n return node;\n};\n\nvar _remove = function _remove(node, list) {\n var prev = node.prev,\n next = node.next;\n\n\n if (prev !== null) {\n prev.next = next;\n } else {\n list.head = next;\n }\n\n if (next !== null) {\n next.prev = prev;\n } else {\n list.tail = prev;\n }\n\n node.prev = node.next = null;\n\n list.length--;\n\n return node;\n};\n\nvar LinkedList = function () {\n function LinkedList(vals) {\n var _this = this;\n\n _classCallCheck(this, LinkedList);\n\n this.length = 0;\n this.head = null;\n this.tail = null;\n\n if (vals != null) {\n vals.forEach(function (v) {\n return _this.push(v);\n });\n }\n }\n\n _createClass(LinkedList, [{\n key: \"size\",\n value: function size() {\n return this.length;\n }\n }, {\n key: \"insertBefore\",\n value: function insertBefore(val, otherNode) {\n return add(otherNode.prev, nodeFrom(val), otherNode, this);\n }\n }, {\n key: \"insertAfter\",\n value: function insertAfter(val, otherNode) {\n return add(otherNode, nodeFrom(val), otherNode.next, this);\n }\n }, {\n key: \"insertNodeBefore\",\n value: function insertNodeBefore(newNode, otherNode) {\n return add(otherNode.prev, newNode, otherNode, this);\n }\n }, {\n key: \"insertNodeAfter\",\n value: function insertNodeAfter(newNode, otherNode) {\n return add(otherNode, newNode, otherNode.next, this);\n }\n }, {\n key: \"push\",\n value: function push(val) {\n return add(this.tail, nodeFrom(val), null, this);\n }\n }, {\n key: \"unshift\",\n value: function unshift(val) {\n return add(null, nodeFrom(val), this.head, this);\n }\n }, {\n key: \"remove\",\n value: function remove(node) {\n return _remove(node, this);\n }\n }, {\n key: \"pop\",\n value: function pop() {\n return _remove(this.tail, this).value;\n }\n }, {\n key: \"popNode\",\n value: function popNode() {\n return _remove(this.tail, this);\n }\n }, {\n key: \"shift\",\n value: function shift() {\n return _remove(this.head, this).value;\n }\n }, {\n key: \"shiftNode\",\n value: function shiftNode() {\n return _remove(this.head, this);\n }\n }, {\n key: \"get_object_at\",\n value: function get_object_at(index) {\n if (index <= this.length()) {\n var i = 1;\n var current = this.head;\n while (i < index) {\n current = current.next;\n i++;\n }\n return current.value;\n }\n }\n }, {\n key: \"set_object_at\",\n value: function set_object_at(index, value) {\n if (index <= this.length()) {\n var i = 1;\n var current = this.head;\n while (i < index) {\n current = current.next;\n i++;\n }\n current.value = value;\n }\n }\n }]);\n\n return LinkedList;\n}();\n\nmodule.exports = LinkedList;\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/*\r\n *This class is the javascript implementation of the Point.java class in jdk\r\n */\nfunction Point(x, y, p) {\n this.x = null;\n this.y = null;\n if (x == null && y == null && p == null) {\n this.x = 0;\n this.y = 0;\n } else if (typeof x == 'number' && typeof y == 'number' && p == null) {\n this.x = x;\n this.y = y;\n } else if (x.constructor.name == 'Point' && y == null && p == null) {\n p = x;\n this.x = p.x;\n this.y = p.y;\n }\n}\n\nPoint.prototype.getX = function () {\n return this.x;\n};\n\nPoint.prototype.getY = function () {\n return this.y;\n};\n\nPoint.prototype.getLocation = function () {\n return new Point(this.x, this.y);\n};\n\nPoint.prototype.setLocation = function (x, y, p) {\n if (x.constructor.name == 'Point' && y == null && p == null) {\n p = x;\n this.setLocation(p.x, p.y);\n } else if (typeof x == 'number' && typeof y == 'number' && p == null) {\n //if both parameters are integer just move (x,y) location\n if (parseInt(x) == x && parseInt(y) == y) {\n this.move(x, y);\n } else {\n this.x = Math.floor(x + 0.5);\n this.y = Math.floor(y + 0.5);\n }\n }\n};\n\nPoint.prototype.move = function (x, y) {\n this.x = x;\n this.y = y;\n};\n\nPoint.prototype.translate = function (dx, dy) {\n this.x += dx;\n this.y += dy;\n};\n\nPoint.prototype.equals = function (obj) {\n if (obj.constructor.name == \"Point\") {\n var pt = obj;\n return this.x == pt.x && this.y == pt.y;\n }\n return this == obj;\n};\n\nPoint.prototype.toString = function () {\n return new Point().constructor.name + \"[x=\" + this.x + \",y=\" + this.y + \"]\";\n};\n\nmodule.exports = Point;\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction RectangleD(x, y, width, height) {\n this.x = 0;\n this.y = 0;\n this.width = 0;\n this.height = 0;\n\n if (x != null && y != null && width != null && height != null) {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n }\n}\n\nRectangleD.prototype.getX = function () {\n return this.x;\n};\n\nRectangleD.prototype.setX = function (x) {\n this.x = x;\n};\n\nRectangleD.prototype.getY = function () {\n return this.y;\n};\n\nRectangleD.prototype.setY = function (y) {\n this.y = y;\n};\n\nRectangleD.prototype.getWidth = function () {\n return this.width;\n};\n\nRectangleD.prototype.setWidth = function (width) {\n this.width = width;\n};\n\nRectangleD.prototype.getHeight = function () {\n return this.height;\n};\n\nRectangleD.prototype.setHeight = function (height) {\n this.height = height;\n};\n\nRectangleD.prototype.getRight = function () {\n return this.x + this.width;\n};\n\nRectangleD.prototype.getBottom = function () {\n return this.y + this.height;\n};\n\nRectangleD.prototype.intersects = function (a) {\n if (this.getRight() < a.x) {\n return false;\n }\n\n if (this.getBottom() < a.y) {\n return false;\n }\n\n if (a.getRight() < this.x) {\n return false;\n }\n\n if (a.getBottom() < this.y) {\n return false;\n }\n\n return true;\n};\n\nRectangleD.prototype.getCenterX = function () {\n return this.x + this.width / 2;\n};\n\nRectangleD.prototype.getMinX = function () {\n return this.getX();\n};\n\nRectangleD.prototype.getMaxX = function () {\n return this.getX() + this.width;\n};\n\nRectangleD.prototype.getCenterY = function () {\n return this.y + this.height / 2;\n};\n\nRectangleD.prototype.getMinY = function () {\n return this.getY();\n};\n\nRectangleD.prototype.getMaxY = function () {\n return this.getY() + this.height;\n};\n\nRectangleD.prototype.getWidthHalf = function () {\n return this.width / 2;\n};\n\nRectangleD.prototype.getHeightHalf = function () {\n return this.height / 2;\n};\n\nmodule.exports = RectangleD;\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction UniqueIDGeneretor() {}\n\nUniqueIDGeneretor.lastID = 0;\n\nUniqueIDGeneretor.createID = function (obj) {\n if (UniqueIDGeneretor.isPrimitive(obj)) {\n return obj;\n }\n if (obj.uniqueID != null) {\n return obj.uniqueID;\n }\n obj.uniqueID = UniqueIDGeneretor.getString();\n UniqueIDGeneretor.lastID++;\n return obj.uniqueID;\n};\n\nUniqueIDGeneretor.getString = function (id) {\n if (id == null) id = UniqueIDGeneretor.lastID;\n return \"Object#\" + id + \"\";\n};\n\nUniqueIDGeneretor.isPrimitive = function (arg) {\n var type = typeof arg === \"undefined\" ? \"undefined\" : _typeof(arg);\n return arg == null || type != \"object\" && type != \"function\";\n};\n\nmodule.exports = UniqueIDGeneretor;\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar LayoutConstants = __webpack_require__(0);\nvar LGraphManager = __webpack_require__(6);\nvar LNode = __webpack_require__(3);\nvar LEdge = __webpack_require__(1);\nvar LGraph = __webpack_require__(5);\nvar PointD = __webpack_require__(4);\nvar Transform = __webpack_require__(17);\nvar Emitter = __webpack_require__(27);\n\nfunction Layout(isRemoteUse) {\n Emitter.call(this);\n\n //Layout Quality: 0:draft, 1:default, 2:proof\n this.layoutQuality = LayoutConstants.QUALITY;\n //Whether layout should create bendpoints as needed or not\n this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;\n //Whether layout should be incremental or not\n this.incremental = LayoutConstants.DEFAULT_INCREMENTAL;\n //Whether we animate from before to after layout node positions\n this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT;\n //Whether we animate the layout process or not\n this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT;\n //Number iterations that should be done between two successive animations\n this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD;\n /**\r\n * Whether or not leaf nodes (non-compound nodes) are of uniform sizes. When\r\n * they are, both spring and repulsion forces between two leaf nodes can be\r\n * calculated without the expensive clipping point calculations, resulting\r\n * in major speed-up.\r\n */\n this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES;\n /**\r\n * This is used for creation of bendpoints by using dummy nodes and edges.\r\n * Maps an LEdge to its dummy bendpoint path.\r\n */\n this.edgeToDummyNodes = new Map();\n this.graphManager = new LGraphManager(this);\n this.isLayoutFinished = false;\n this.isSubLayout = false;\n this.isRemoteUse = false;\n\n if (isRemoteUse != null) {\n this.isRemoteUse = isRemoteUse;\n }\n}\n\nLayout.RANDOM_SEED = 1;\n\nLayout.prototype = Object.create(Emitter.prototype);\n\nLayout.prototype.getGraphManager = function () {\n return this.graphManager;\n};\n\nLayout.prototype.getAllNodes = function () {\n return this.graphManager.getAllNodes();\n};\n\nLayout.prototype.getAllEdges = function () {\n return this.graphManager.getAllEdges();\n};\n\nLayout.prototype.getAllNodesToApplyGravitation = function () {\n return this.graphManager.getAllNodesToApplyGravitation();\n};\n\nLayout.prototype.newGraphManager = function () {\n var gm = new LGraphManager(this);\n this.graphManager = gm;\n return gm;\n};\n\nLayout.prototype.newGraph = function (vGraph) {\n return new LGraph(null, this.graphManager, vGraph);\n};\n\nLayout.prototype.newNode = function (vNode) {\n return new LNode(this.graphManager, vNode);\n};\n\nLayout.prototype.newEdge = function (vEdge) {\n return new LEdge(null, null, vEdge);\n};\n\nLayout.prototype.checkLayoutSuccess = function () {\n return this.graphManager.getRoot() == null || this.graphManager.getRoot().getNodes().length == 0 || this.graphManager.includesInvalidEdge();\n};\n\nLayout.prototype.runLayout = function () {\n this.isLayoutFinished = false;\n\n if (this.tilingPreLayout) {\n this.tilingPreLayout();\n }\n\n this.initParameters();\n var isLayoutSuccessfull;\n\n if (this.checkLayoutSuccess()) {\n isLayoutSuccessfull = false;\n } else {\n isLayoutSuccessfull = this.layout();\n }\n\n if (LayoutConstants.ANIMATE === 'during') {\n // If this is a 'during' layout animation. Layout is not finished yet. \n // We need to perform these in index.js when layout is really finished.\n return false;\n }\n\n if (isLayoutSuccessfull) {\n if (!this.isSubLayout) {\n this.doPostLayout();\n }\n }\n\n if (this.tilingPostLayout) {\n this.tilingPostLayout();\n }\n\n this.isLayoutFinished = true;\n\n return isLayoutSuccessfull;\n};\n\n/**\r\n * This method performs the operations required after layout.\r\n */\nLayout.prototype.doPostLayout = function () {\n //assert !isSubLayout : \"Should not be called on sub-layout!\";\n // Propagate geometric changes to v-level objects\n if (!this.incremental) {\n this.transform();\n }\n this.update();\n};\n\n/**\r\n * This method updates the geometry of the target graph according to\r\n * calculated layout.\r\n */\nLayout.prototype.update2 = function () {\n // update bend points\n if (this.createBendsAsNeeded) {\n this.createBendpointsFromDummyNodes();\n\n // reset all edges, since the topology has changed\n this.graphManager.resetAllEdges();\n }\n\n // perform edge, node and root updates if layout is not called\n // remotely\n if (!this.isRemoteUse) {\n // update all edges\n var edge;\n var allEdges = this.graphManager.getAllEdges();\n for (var i = 0; i < allEdges.length; i++) {\n edge = allEdges[i];\n // this.update(edge);\n }\n\n // recursively update nodes\n var node;\n var nodes = this.graphManager.getRoot().getNodes();\n for (var i = 0; i < nodes.length; i++) {\n node = nodes[i];\n // this.update(node);\n }\n\n // update root graph\n this.update(this.graphManager.getRoot());\n }\n};\n\nLayout.prototype.update = function (obj) {\n if (obj == null) {\n this.update2();\n } else if (obj instanceof LNode) {\n var node = obj;\n if (node.getChild() != null) {\n // since node is compound, recursively update child nodes\n var nodes = node.getChild().getNodes();\n for (var i = 0; i < nodes.length; i++) {\n update(nodes[i]);\n }\n }\n\n // if the l-level node is associated with a v-level graph object,\n // then it is assumed that the v-level node implements the\n // interface Updatable.\n if (node.vGraphObject != null) {\n // cast to Updatable without any type check\n var vNode = node.vGraphObject;\n\n // call the update method of the interface\n vNode.update(node);\n }\n } else if (obj instanceof LEdge) {\n var edge = obj;\n // if the l-level edge is associated with a v-level graph object,\n // then it is assumed that the v-level edge implements the\n // interface Updatable.\n\n if (edge.vGraphObject != null) {\n // cast to Updatable without any type check\n var vEdge = edge.vGraphObject;\n\n // call the update method of the interface\n vEdge.update(edge);\n }\n } else if (obj instanceof LGraph) {\n var graph = obj;\n // if the l-level graph is associated with a v-level graph object,\n // then it is assumed that the v-level object implements the\n // interface Updatable.\n\n if (graph.vGraphObject != null) {\n // cast to Updatable without any type check\n var vGraph = graph.vGraphObject;\n\n // call the update method of the interface\n vGraph.update(graph);\n }\n }\n};\n\n/**\r\n * This method is used to set all layout parameters to default values\r\n * determined at compile time.\r\n */\nLayout.prototype.initParameters = function () {\n if (!this.isSubLayout) {\n this.layoutQuality = LayoutConstants.QUALITY;\n this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT;\n this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD;\n this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT;\n this.incremental = LayoutConstants.DEFAULT_INCREMENTAL;\n this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;\n this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES;\n }\n\n if (this.animationDuringLayout) {\n this.animationOnLayout = false;\n }\n};\n\nLayout.prototype.transform = function (newLeftTop) {\n if (newLeftTop == undefined) {\n this.transform(new PointD(0, 0));\n } else {\n // create a transformation object (from Eclipse to layout). When an\n // inverse transform is applied, we get upper-left coordinate of the\n // drawing or the root graph at given input coordinate (some margins\n // already included in calculation of left-top).\n\n var trans = new Transform();\n var leftTop = this.graphManager.getRoot().updateLeftTop();\n\n if (leftTop != null) {\n trans.setWorldOrgX(newLeftTop.x);\n trans.setWorldOrgY(newLeftTop.y);\n\n trans.setDeviceOrgX(leftTop.x);\n trans.setDeviceOrgY(leftTop.y);\n\n var nodes = this.getAllNodes();\n var node;\n\n for (var i = 0; i < nodes.length; i++) {\n node = nodes[i];\n node.transform(trans);\n }\n }\n }\n};\n\nLayout.prototype.positionNodesRandomly = function (graph) {\n\n if (graph == undefined) {\n //assert !this.incremental;\n this.positionNodesRandomly(this.getGraphManager().getRoot());\n this.getGraphManager().getRoot().updateBounds(true);\n } else {\n var lNode;\n var childGraph;\n\n var nodes = graph.getNodes();\n for (var i = 0; i < nodes.length; i++) {\n lNode = nodes[i];\n childGraph = lNode.getChild();\n\n if (childGraph == null) {\n lNode.scatter();\n } else if (childGraph.getNodes().length == 0) {\n lNode.scatter();\n } else {\n this.positionNodesRandomly(childGraph);\n lNode.updateBounds();\n }\n }\n }\n};\n\n/**\r\n * This method returns a list of trees where each tree is represented as a\r\n * list of l-nodes. The method returns a list of size 0 when:\r\n * - The graph is not flat or\r\n * - One of the component(s) of the graph is not a tree.\r\n */\nLayout.prototype.getFlatForest = function () {\n var flatForest = [];\n var isForest = true;\n\n // Quick reference for all nodes in the graph manager associated with\n // this layout. The list should not be changed.\n var allNodes = this.graphManager.getRoot().getNodes();\n\n // First be sure that the graph is flat\n var isFlat = true;\n\n for (var i = 0; i < allNodes.length; i++) {\n if (allNodes[i].getChild() != null) {\n isFlat = false;\n }\n }\n\n // Return empty forest if the graph is not flat.\n if (!isFlat) {\n return flatForest;\n }\n\n // Run BFS for each component of the graph.\n\n var visited = new Set();\n var toBeVisited = [];\n var parents = new Map();\n var unProcessedNodes = [];\n\n unProcessedNodes = unProcessedNodes.concat(allNodes);\n\n // Each iteration of this loop finds a component of the graph and\n // decides whether it is a tree or not. If it is a tree, adds it to the\n // forest and continued with the next component.\n\n while (unProcessedNodes.length > 0 && isForest) {\n toBeVisited.push(unProcessedNodes[0]);\n\n // Start the BFS. Each iteration of this loop visits a node in a\n // BFS manner.\n while (toBeVisited.length > 0 && isForest) {\n //pool operation\n var currentNode = toBeVisited[0];\n toBeVisited.splice(0, 1);\n visited.add(currentNode);\n\n // Traverse all neighbors of this node\n var neighborEdges = currentNode.getEdges();\n\n for (var i = 0; i < neighborEdges.length; i++) {\n var currentNeighbor = neighborEdges[i].getOtherEnd(currentNode);\n\n // If BFS is not growing from this neighbor.\n if (parents.get(currentNode) != currentNeighbor) {\n // We haven't previously visited this neighbor.\n if (!visited.has(currentNeighbor)) {\n toBeVisited.push(currentNeighbor);\n parents.set(currentNeighbor, currentNode);\n }\n // Since we have previously visited this neighbor and\n // this neighbor is not parent of currentNode, given\n // graph contains a component that is not tree, hence\n // it is not a forest.\n else {\n isForest = false;\n break;\n }\n }\n }\n }\n\n // The graph contains a component that is not a tree. Empty\n // previously found trees. The method will end.\n if (!isForest) {\n flatForest = [];\n }\n // Save currently visited nodes as a tree in our forest. Reset\n // visited and parents lists. Continue with the next component of\n // the graph, if any.\n else {\n var temp = [].concat(_toConsumableArray(visited));\n flatForest.push(temp);\n //flatForest = flatForest.concat(temp);\n //unProcessedNodes.removeAll(visited);\n for (var i = 0; i < temp.length; i++) {\n var value = temp[i];\n var index = unProcessedNodes.indexOf(value);\n if (index > -1) {\n unProcessedNodes.splice(index, 1);\n }\n }\n visited = new Set();\n parents = new Map();\n }\n }\n\n return flatForest;\n};\n\n/**\r\n * This method creates dummy nodes (an l-level node with minimal dimensions)\r\n * for the given edge (one per bendpoint). The existing l-level structure\r\n * is updated accordingly.\r\n */\nLayout.prototype.createDummyNodesForBendpoints = function (edge) {\n var dummyNodes = [];\n var prev = edge.source;\n\n var graph = this.graphManager.calcLowestCommonAncestor(edge.source, edge.target);\n\n for (var i = 0; i < edge.bendpoints.length; i++) {\n // create new dummy node\n var dummyNode = this.newNode(null);\n dummyNode.setRect(new Point(0, 0), new Dimension(1, 1));\n\n graph.add(dummyNode);\n\n // create new dummy edge between prev and dummy node\n var dummyEdge = this.newEdge(null);\n this.graphManager.add(dummyEdge, prev, dummyNode);\n\n dummyNodes.add(dummyNode);\n prev = dummyNode;\n }\n\n var dummyEdge = this.newEdge(null);\n this.graphManager.add(dummyEdge, prev, edge.target);\n\n this.edgeToDummyNodes.set(edge, dummyNodes);\n\n // remove real edge from graph manager if it is inter-graph\n if (edge.isInterGraph()) {\n this.graphManager.remove(edge);\n }\n // else, remove the edge from the current graph\n else {\n graph.remove(edge);\n }\n\n return dummyNodes;\n};\n\n/**\r\n * This method creates bendpoints for edges from the dummy nodes\r\n * at l-level.\r\n */\nLayout.prototype.createBendpointsFromDummyNodes = function () {\n var edges = [];\n edges = edges.concat(this.graphManager.getAllEdges());\n edges = [].concat(_toConsumableArray(this.edgeToDummyNodes.keys())).concat(edges);\n\n for (var k = 0; k < edges.length; k++) {\n var lEdge = edges[k];\n\n if (lEdge.bendpoints.length > 0) {\n var path = this.edgeToDummyNodes.get(lEdge);\n\n for (var i = 0; i < path.length; i++) {\n var dummyNode = path[i];\n var p = new PointD(dummyNode.getCenterX(), dummyNode.getCenterY());\n\n // update bendpoint's location according to dummy node\n var ebp = lEdge.bendpoints.get(i);\n ebp.x = p.x;\n ebp.y = p.y;\n\n // remove the dummy node, dummy edges incident with this\n // dummy node is also removed (within the remove method)\n dummyNode.getOwner().remove(dummyNode);\n }\n\n // add the real edge to graph\n this.graphManager.add(lEdge, lEdge.source, lEdge.target);\n }\n }\n};\n\nLayout.transform = function (sliderValue, defaultValue, minDiv, maxMul) {\n if (minDiv != undefined && maxMul != undefined) {\n var value = defaultValue;\n\n if (sliderValue <= 50) {\n var minValue = defaultValue / minDiv;\n value -= (defaultValue - minValue) / 50 * (50 - sliderValue);\n } else {\n var maxValue = defaultValue * maxMul;\n value += (maxValue - defaultValue) / 50 * (sliderValue - 50);\n }\n\n return value;\n } else {\n var a, b;\n\n if (sliderValue <= 50) {\n a = 9.0 * defaultValue / 500.0;\n b = defaultValue / 10.0;\n } else {\n a = 9.0 * defaultValue / 50.0;\n b = -8 * defaultValue;\n }\n\n return a * sliderValue + b;\n }\n};\n\n/**\r\n * This method finds and returns the center of the given nodes, assuming\r\n * that the given nodes form a tree in themselves.\r\n */\nLayout.findCenterOfTree = function (nodes) {\n var list = [];\n list = list.concat(nodes);\n\n var removedNodes = [];\n var remainingDegrees = new Map();\n var foundCenter = false;\n var centerNode = null;\n\n if (list.length == 1 || list.length == 2) {\n foundCenter = true;\n centerNode = list[0];\n }\n\n for (var i = 0; i < list.length; i++) {\n var node = list[i];\n var degree = node.getNeighborsList().size;\n remainingDegrees.set(node, node.getNeighborsList().size);\n\n if (degree == 1) {\n removedNodes.push(node);\n }\n }\n\n var tempList = [];\n tempList = tempList.concat(removedNodes);\n\n while (!foundCenter) {\n var tempList2 = [];\n tempList2 = tempList2.concat(tempList);\n tempList = [];\n\n for (var i = 0; i < list.length; i++) {\n var node = list[i];\n\n var index = list.indexOf(node);\n if (index >= 0) {\n list.splice(index, 1);\n }\n\n var neighbours = node.getNeighborsList();\n\n neighbours.forEach(function (neighbour) {\n if (removedNodes.indexOf(neighbour) < 0) {\n var otherDegree = remainingDegrees.get(neighbour);\n var newDegree = otherDegree - 1;\n\n if (newDegree == 1) {\n tempList.push(neighbour);\n }\n\n remainingDegrees.set(neighbour, newDegree);\n }\n });\n }\n\n removedNodes = removedNodes.concat(tempList);\n\n if (list.length == 1 || list.length == 2) {\n foundCenter = true;\n centerNode = list[0];\n }\n }\n\n return centerNode;\n};\n\n/**\r\n * During the coarsening process, this layout may be referenced by two graph managers\r\n * this setter function grants access to change the currently being used graph manager\r\n */\nLayout.prototype.setGraphManager = function (gm) {\n this.graphManager = gm;\n};\n\nmodule.exports = Layout;\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction RandomSeed() {}\n// adapted from: https://stackoverflow.com/a/19303725\nRandomSeed.seed = 1;\nRandomSeed.x = 0;\n\nRandomSeed.nextDouble = function () {\n RandomSeed.x = Math.sin(RandomSeed.seed++) * 10000;\n return RandomSeed.x - Math.floor(RandomSeed.x);\n};\n\nmodule.exports = RandomSeed;\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar PointD = __webpack_require__(4);\n\nfunction Transform(x, y) {\n this.lworldOrgX = 0.0;\n this.lworldOrgY = 0.0;\n this.ldeviceOrgX = 0.0;\n this.ldeviceOrgY = 0.0;\n this.lworldExtX = 1.0;\n this.lworldExtY = 1.0;\n this.ldeviceExtX = 1.0;\n this.ldeviceExtY = 1.0;\n}\n\nTransform.prototype.getWorldOrgX = function () {\n return this.lworldOrgX;\n};\n\nTransform.prototype.setWorldOrgX = function (wox) {\n this.lworldOrgX = wox;\n};\n\nTransform.prototype.getWorldOrgY = function () {\n return this.lworldOrgY;\n};\n\nTransform.prototype.setWorldOrgY = function (woy) {\n this.lworldOrgY = woy;\n};\n\nTransform.prototype.getWorldExtX = function () {\n return this.lworldExtX;\n};\n\nTransform.prototype.setWorldExtX = function (wex) {\n this.lworldExtX = wex;\n};\n\nTransform.prototype.getWorldExtY = function () {\n return this.lworldExtY;\n};\n\nTransform.prototype.setWorldExtY = function (wey) {\n this.lworldExtY = wey;\n};\n\n/* Device related */\n\nTransform.prototype.getDeviceOrgX = function () {\n return this.ldeviceOrgX;\n};\n\nTransform.prototype.setDeviceOrgX = function (dox) {\n this.ldeviceOrgX = dox;\n};\n\nTransform.prototype.getDeviceOrgY = function () {\n return this.ldeviceOrgY;\n};\n\nTransform.prototype.setDeviceOrgY = function (doy) {\n this.ldeviceOrgY = doy;\n};\n\nTransform.prototype.getDeviceExtX = function () {\n return this.ldeviceExtX;\n};\n\nTransform.prototype.setDeviceExtX = function (dex) {\n this.ldeviceExtX = dex;\n};\n\nTransform.prototype.getDeviceExtY = function () {\n return this.ldeviceExtY;\n};\n\nTransform.prototype.setDeviceExtY = function (dey) {\n this.ldeviceExtY = dey;\n};\n\nTransform.prototype.transformX = function (x) {\n var xDevice = 0.0;\n var worldExtX = this.lworldExtX;\n if (worldExtX != 0.0) {\n xDevice = this.ldeviceOrgX + (x - this.lworldOrgX) * this.ldeviceExtX / worldExtX;\n }\n\n return xDevice;\n};\n\nTransform.prototype.transformY = function (y) {\n var yDevice = 0.0;\n var worldExtY = this.lworldExtY;\n if (worldExtY != 0.0) {\n yDevice = this.ldeviceOrgY + (y - this.lworldOrgY) * this.ldeviceExtY / worldExtY;\n }\n\n return yDevice;\n};\n\nTransform.prototype.inverseTransformX = function (x) {\n var xWorld = 0.0;\n var deviceExtX = this.ldeviceExtX;\n if (deviceExtX != 0.0) {\n xWorld = this.lworldOrgX + (x - this.ldeviceOrgX) * this.lworldExtX / deviceExtX;\n }\n\n return xWorld;\n};\n\nTransform.prototype.inverseTransformY = function (y) {\n var yWorld = 0.0;\n var deviceExtY = this.ldeviceExtY;\n if (deviceExtY != 0.0) {\n yWorld = this.lworldOrgY + (y - this.ldeviceOrgY) * this.lworldExtY / deviceExtY;\n }\n return yWorld;\n};\n\nTransform.prototype.inverseTransformPoint = function (inPoint) {\n var outPoint = new PointD(this.inverseTransformX(inPoint.x), this.inverseTransformY(inPoint.y));\n return outPoint;\n};\n\nmodule.exports = Transform;\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar Layout = __webpack_require__(15);\nvar FDLayoutConstants = __webpack_require__(7);\nvar LayoutConstants = __webpack_require__(0);\nvar IGeometry = __webpack_require__(8);\nvar IMath = __webpack_require__(9);\n\nfunction FDLayout() {\n Layout.call(this);\n\n this.useSmartIdealEdgeLengthCalculation = FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;\n this.idealEdgeLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH;\n this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH;\n this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH;\n this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;\n this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;\n this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;\n this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;\n this.displacementThresholdPerNode = 3.0 * FDLayoutConstants.DEFAULT_EDGE_LENGTH / 100;\n this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;\n this.initialCoolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;\n this.totalDisplacement = 0.0;\n this.oldTotalDisplacement = 0.0;\n this.maxIterations = FDLayoutConstants.MAX_ITERATIONS;\n}\n\nFDLayout.prototype = Object.create(Layout.prototype);\n\nfor (var prop in Layout) {\n FDLayout[prop] = Layout[prop];\n}\n\nFDLayout.prototype.initParameters = function () {\n Layout.prototype.initParameters.call(this, arguments);\n\n this.totalIterations = 0;\n this.notAnimatedIterations = 0;\n\n this.useFRGridVariant = FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION;\n\n this.grid = [];\n};\n\nFDLayout.prototype.calcIdealEdgeLengths = function () {\n var edge;\n var lcaDepth;\n var source;\n var target;\n var sizeOfSourceInLca;\n var sizeOfTargetInLca;\n\n var allEdges = this.getGraphManager().getAllEdges();\n for (var i = 0; i < allEdges.length; i++) {\n edge = allEdges[i];\n\n edge.idealLength = this.idealEdgeLength;\n\n if (edge.isInterGraph) {\n source = edge.getSource();\n target = edge.getTarget();\n\n sizeOfSourceInLca = edge.getSourceInLca().getEstimatedSize();\n sizeOfTargetInLca = edge.getTargetInLca().getEstimatedSize();\n\n if (this.useSmartIdealEdgeLengthCalculation) {\n edge.idealLength += sizeOfSourceInLca + sizeOfTargetInLca - 2 * LayoutConstants.SIMPLE_NODE_SIZE;\n }\n\n lcaDepth = edge.getLca().getInclusionTreeDepth();\n\n edge.idealLength += FDLayoutConstants.DEFAULT_EDGE_LENGTH * FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR * (source.getInclusionTreeDepth() + target.getInclusionTreeDepth() - 2 * lcaDepth);\n }\n }\n};\n\nFDLayout.prototype.initSpringEmbedder = function () {\n\n var s = this.getAllNodes().length;\n if (this.incremental) {\n if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) {\n this.coolingFactor = Math.max(this.coolingFactor * FDLayoutConstants.COOLING_ADAPTATION_FACTOR, this.coolingFactor - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * this.coolingFactor * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR));\n }\n this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL;\n } else {\n if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) {\n this.coolingFactor = Math.max(FDLayoutConstants.COOLING_ADAPTATION_FACTOR, 1.0 - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR));\n } else {\n this.coolingFactor = 1.0;\n }\n this.initialCoolingFactor = this.coolingFactor;\n this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT;\n }\n\n this.maxIterations = Math.max(this.getAllNodes().length * 5, this.maxIterations);\n\n this.totalDisplacementThreshold = this.displacementThresholdPerNode * this.getAllNodes().length;\n\n this.repulsionRange = this.calcRepulsionRange();\n};\n\nFDLayout.prototype.calcSpringForces = function () {\n var lEdges = this.getAllEdges();\n var edge;\n\n for (var i = 0; i < lEdges.length; i++) {\n edge = lEdges[i];\n\n this.calcSpringForce(edge, edge.idealLength);\n }\n};\n\nFDLayout.prototype.calcRepulsionForces = function () {\n var gridUpdateAllowed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n var forceToNodeSurroundingUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var i, j;\n var nodeA, nodeB;\n var lNodes = this.getAllNodes();\n var processedNodeSet;\n\n if (this.useFRGridVariant) {\n if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed) {\n this.updateGrid();\n }\n\n processedNodeSet = new Set();\n\n // calculate repulsion forces between each nodes and its surrounding\n for (i = 0; i < lNodes.length; i++) {\n nodeA = lNodes[i];\n this.calculateRepulsionForceOfANode(nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate);\n processedNodeSet.add(nodeA);\n }\n } else {\n for (i = 0; i < lNodes.length; i++) {\n nodeA = lNodes[i];\n\n for (j = i + 1; j < lNodes.length; j++) {\n nodeB = lNodes[j];\n\n // If both nodes are not members of the same graph, skip.\n if (nodeA.getOwner() != nodeB.getOwner()) {\n continue;\n }\n\n this.calcRepulsionForce(nodeA, nodeB);\n }\n }\n }\n};\n\nFDLayout.prototype.calcGravitationalForces = function () {\n var node;\n var lNodes = this.getAllNodesToApplyGravitation();\n\n for (var i = 0; i < lNodes.length; i++) {\n node = lNodes[i];\n this.calcGravitationalForce(node);\n }\n};\n\nFDLayout.prototype.moveNodes = function () {\n var lNodes = this.getAllNodes();\n var node;\n\n for (var i = 0; i < lNodes.length; i++) {\n node = lNodes[i];\n node.move();\n }\n};\n\nFDLayout.prototype.calcSpringForce = function (edge, idealLength) {\n var sourceNode = edge.getSource();\n var targetNode = edge.getTarget();\n\n var length;\n var springForce;\n var springForceX;\n var springForceY;\n\n // Update edge length\n if (this.uniformLeafNodeSizes && sourceNode.getChild() == null && targetNode.getChild() == null) {\n edge.updateLengthSimple();\n } else {\n edge.updateLength();\n\n if (edge.isOverlapingSourceAndTarget) {\n return;\n }\n }\n\n length = edge.getLength();\n\n if (length == 0) return;\n\n // Calculate spring forces\n springForce = this.springConstant * (length - idealLength);\n\n // Project force onto x and y axes\n springForceX = springForce * (edge.lengthX / length);\n springForceY = springForce * (edge.lengthY / length);\n\n // Apply forces on the end nodes\n sourceNode.springForceX += springForceX;\n sourceNode.springForceY += springForceY;\n targetNode.springForceX -= springForceX;\n targetNode.springForceY -= springForceY;\n};\n\nFDLayout.prototype.calcRepulsionForce = function (nodeA, nodeB) {\n var rectA = nodeA.getRect();\n var rectB = nodeB.getRect();\n var overlapAmount = new Array(2);\n var clipPoints = new Array(4);\n var distanceX;\n var distanceY;\n var distanceSquared;\n var distance;\n var repulsionForce;\n var repulsionForceX;\n var repulsionForceY;\n\n if (rectA.intersects(rectB)) // two nodes overlap\n {\n // calculate separation amount in x and y directions\n IGeometry.calcSeparationAmount(rectA, rectB, overlapAmount, FDLayoutConstants.DEFAULT_EDGE_LENGTH / 2.0);\n\n repulsionForceX = 2 * overlapAmount[0];\n repulsionForceY = 2 * overlapAmount[1];\n\n var childrenConstant = nodeA.noOfChildren * nodeB.noOfChildren / (nodeA.noOfChildren + nodeB.noOfChildren);\n\n // Apply forces on the two nodes\n nodeA.repulsionForceX -= childrenConstant * repulsionForceX;\n nodeA.repulsionForceY -= childrenConstant * repulsionForceY;\n nodeB.repulsionForceX += childrenConstant * repulsionForceX;\n nodeB.repulsionForceY += childrenConstant * repulsionForceY;\n } else // no overlap\n {\n // calculate distance\n\n if (this.uniformLeafNodeSizes && nodeA.getChild() == null && nodeB.getChild() == null) // simply base repulsion on distance of node centers\n {\n distanceX = rectB.getCenterX() - rectA.getCenterX();\n distanceY = rectB.getCenterY() - rectA.getCenterY();\n } else // use clipping points\n {\n IGeometry.getIntersection(rectA, rectB, clipPoints);\n\n distanceX = clipPoints[2] - clipPoints[0];\n distanceY = clipPoints[3] - clipPoints[1];\n }\n\n // No repulsion range. FR grid variant should take care of this.\n if (Math.abs(distanceX) < FDLayoutConstants.MIN_REPULSION_DIST) {\n distanceX = IMath.sign(distanceX) * FDLayoutConstants.MIN_REPULSION_DIST;\n }\n\n if (Math.abs(distanceY) < FDLayoutConstants.MIN_REPULSION_DIST) {\n distanceY = IMath.sign(distanceY) * FDLayoutConstants.MIN_REPULSION_DIST;\n }\n\n distanceSquared = distanceX * distanceX + distanceY * distanceY;\n distance = Math.sqrt(distanceSquared);\n\n repulsionForce = this.repulsionConstant * nodeA.noOfChildren * nodeB.noOfChildren / distanceSquared;\n\n // Project force onto x and y axes\n repulsionForceX = repulsionForce * distanceX / distance;\n repulsionForceY = repulsionForce * distanceY / distance;\n\n // Apply forces on the two nodes \n nodeA.repulsionForceX -= repulsionForceX;\n nodeA.repulsionForceY -= repulsionForceY;\n nodeB.repulsionForceX += repulsionForceX;\n nodeB.repulsionForceY += repulsionForceY;\n }\n};\n\nFDLayout.prototype.calcGravitationalForce = function (node) {\n var ownerGraph;\n var ownerCenterX;\n var ownerCenterY;\n var distanceX;\n var distanceY;\n var absDistanceX;\n var absDistanceY;\n var estimatedSize;\n ownerGraph = node.getOwner();\n\n ownerCenterX = (ownerGraph.getRight() + ownerGraph.getLeft()) / 2;\n ownerCenterY = (ownerGraph.getTop() + ownerGraph.getBottom()) / 2;\n distanceX = node.getCenterX() - ownerCenterX;\n distanceY = node.getCenterY() - ownerCenterY;\n absDistanceX = Math.abs(distanceX) + node.getWidth() / 2;\n absDistanceY = Math.abs(distanceY) + node.getHeight() / 2;\n\n if (node.getOwner() == this.graphManager.getRoot()) // in the root graph\n {\n estimatedSize = ownerGraph.getEstimatedSize() * this.gravityRangeFactor;\n\n if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) {\n node.gravitationForceX = -this.gravityConstant * distanceX;\n node.gravitationForceY = -this.gravityConstant * distanceY;\n }\n } else // inside a compound\n {\n estimatedSize = ownerGraph.getEstimatedSize() * this.compoundGravityRangeFactor;\n\n if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) {\n node.gravitationForceX = -this.gravityConstant * distanceX * this.compoundGravityConstant;\n node.gravitationForceY = -this.gravityConstant * distanceY * this.compoundGravityConstant;\n }\n }\n};\n\nFDLayout.prototype.isConverged = function () {\n var converged;\n var oscilating = false;\n\n if (this.totalIterations > this.maxIterations / 3) {\n oscilating = Math.abs(this.totalDisplacement - this.oldTotalDisplacement) < 2;\n }\n\n converged = this.totalDisplacement < this.totalDisplacementThreshold;\n\n this.oldTotalDisplacement = this.totalDisplacement;\n\n return converged || oscilating;\n};\n\nFDLayout.prototype.animate = function () {\n if (this.animationDuringLayout && !this.isSubLayout) {\n if (this.notAnimatedIterations == this.animationPeriod) {\n this.update();\n this.notAnimatedIterations = 0;\n } else {\n this.notAnimatedIterations++;\n }\n }\n};\n\n//This method calculates the number of children (weight) for all nodes\nFDLayout.prototype.calcNoOfChildrenForAllNodes = function () {\n var node;\n var allNodes = this.graphManager.getAllNodes();\n\n for (var i = 0; i < allNodes.length; i++) {\n node = allNodes[i];\n node.noOfChildren = node.getNoOfChildren();\n }\n};\n\n// -----------------------------------------------------------------------------\n// Section: FR-Grid Variant Repulsion Force Calculation\n// -----------------------------------------------------------------------------\n\nFDLayout.prototype.calcGrid = function (graph) {\n\n var sizeX = 0;\n var sizeY = 0;\n\n sizeX = parseInt(Math.ceil((graph.getRight() - graph.getLeft()) / this.repulsionRange));\n sizeY = parseInt(Math.ceil((graph.getBottom() - graph.getTop()) / this.repulsionRange));\n\n var grid = new Array(sizeX);\n\n for (var i = 0; i < sizeX; i++) {\n grid[i] = new Array(sizeY);\n }\n\n for (var i = 0; i < sizeX; i++) {\n for (var j = 0; j < sizeY; j++) {\n grid[i][j] = new Array();\n }\n }\n\n return grid;\n};\n\nFDLayout.prototype.addNodeToGrid = function (v, left, top) {\n\n var startX = 0;\n var finishX = 0;\n var startY = 0;\n var finishY = 0;\n\n startX = parseInt(Math.floor((v.getRect().x - left) / this.repulsionRange));\n finishX = parseInt(Math.floor((v.getRect().width + v.getRect().x - left) / this.repulsionRange));\n startY = parseInt(Math.floor((v.getRect().y - top) / this.repulsionRange));\n finishY = parseInt(Math.floor((v.getRect().height + v.getRect().y - top) / this.repulsionRange));\n\n for (var i = startX; i <= finishX; i++) {\n for (var j = startY; j <= finishY; j++) {\n this.grid[i][j].push(v);\n v.setGridCoordinates(startX, finishX, startY, finishY);\n }\n }\n};\n\nFDLayout.prototype.updateGrid = function () {\n var i;\n var nodeA;\n var lNodes = this.getAllNodes();\n\n this.grid = this.calcGrid(this.graphManager.getRoot());\n\n // put all nodes to proper grid cells\n for (i = 0; i < lNodes.length; i++) {\n nodeA = lNodes[i];\n this.addNodeToGrid(nodeA, this.graphManager.getRoot().getLeft(), this.graphManager.getRoot().getTop());\n }\n};\n\nFDLayout.prototype.calculateRepulsionForceOfANode = function (nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate) {\n\n if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed || forceToNodeSurroundingUpdate) {\n var surrounding = new Set();\n nodeA.surrounding = new Array();\n var nodeB;\n var grid = this.grid;\n\n for (var i = nodeA.startX - 1; i < nodeA.finishX + 2; i++) {\n for (var j = nodeA.startY - 1; j < nodeA.finishY + 2; j++) {\n if (!(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)) {\n for (var k = 0; k < grid[i][j].length; k++) {\n nodeB = grid[i][j][k];\n\n // If both nodes are not members of the same graph, \n // or both nodes are the same, skip.\n if (nodeA.getOwner() != nodeB.getOwner() || nodeA == nodeB) {\n continue;\n }\n\n // check if the repulsion force between\n // nodeA and nodeB has already been calculated\n if (!processedNodeSet.has(nodeB) && !surrounding.has(nodeB)) {\n var distanceX = Math.abs(nodeA.getCenterX() - nodeB.getCenterX()) - (nodeA.getWidth() / 2 + nodeB.getWidth() / 2);\n var distanceY = Math.abs(nodeA.getCenterY() - nodeB.getCenterY()) - (nodeA.getHeight() / 2 + nodeB.getHeight() / 2);\n\n // if the distance between nodeA and nodeB \n // is less then calculation range\n if (distanceX <= this.repulsionRange && distanceY <= this.repulsionRange) {\n //then add nodeB to surrounding of nodeA\n surrounding.add(nodeB);\n }\n }\n }\n }\n }\n }\n\n nodeA.surrounding = [].concat(_toConsumableArray(surrounding));\n }\n for (i = 0; i < nodeA.surrounding.length; i++) {\n this.calcRepulsionForce(nodeA, nodeA.surrounding[i]);\n }\n};\n\nFDLayout.prototype.calcRepulsionRange = function () {\n return 0.0;\n};\n\nmodule.exports = FDLayout;\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LEdge = __webpack_require__(1);\nvar FDLayoutConstants = __webpack_require__(7);\n\nfunction FDLayoutEdge(source, target, vEdge) {\n LEdge.call(this, source, target, vEdge);\n this.idealLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH;\n}\n\nFDLayoutEdge.prototype = Object.create(LEdge.prototype);\n\nfor (var prop in LEdge) {\n FDLayoutEdge[prop] = LEdge[prop];\n}\n\nmodule.exports = FDLayoutEdge;\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LNode = __webpack_require__(3);\n\nfunction FDLayoutNode(gm, loc, size, vNode) {\n // alternative constructor is handled inside LNode\n LNode.call(this, gm, loc, size, vNode);\n //Spring, repulsion and gravitational forces acting on this node\n this.springForceX = 0;\n this.springForceY = 0;\n this.repulsionForceX = 0;\n this.repulsionForceY = 0;\n this.gravitationForceX = 0;\n this.gravitationForceY = 0;\n //Amount by which this node is to be moved in this iteration\n this.displacementX = 0;\n this.displacementY = 0;\n\n //Start and finish grid coordinates that this node is fallen into\n this.startX = 0;\n this.finishX = 0;\n this.startY = 0;\n this.finishY = 0;\n\n //Geometric neighbors of this node\n this.surrounding = [];\n}\n\nFDLayoutNode.prototype = Object.create(LNode.prototype);\n\nfor (var prop in LNode) {\n FDLayoutNode[prop] = LNode[prop];\n}\n\nFDLayoutNode.prototype.setGridCoordinates = function (_startX, _finishX, _startY, _finishY) {\n this.startX = _startX;\n this.finishX = _finishX;\n this.startY = _startY;\n this.finishY = _finishY;\n};\n\nmodule.exports = FDLayoutNode;\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction DimensionD(width, height) {\n this.width = 0;\n this.height = 0;\n if (width !== null && height !== null) {\n this.height = height;\n this.width = width;\n }\n}\n\nDimensionD.prototype.getWidth = function () {\n return this.width;\n};\n\nDimensionD.prototype.setWidth = function (width) {\n this.width = width;\n};\n\nDimensionD.prototype.getHeight = function () {\n return this.height;\n};\n\nDimensionD.prototype.setHeight = function (height) {\n this.height = height;\n};\n\nmodule.exports = DimensionD;\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar UniqueIDGeneretor = __webpack_require__(14);\n\nfunction HashMap() {\n this.map = {};\n this.keys = [];\n}\n\nHashMap.prototype.put = function (key, value) {\n var theId = UniqueIDGeneretor.createID(key);\n if (!this.contains(theId)) {\n this.map[theId] = value;\n this.keys.push(key);\n }\n};\n\nHashMap.prototype.contains = function (key) {\n var theId = UniqueIDGeneretor.createID(key);\n return this.map[key] != null;\n};\n\nHashMap.prototype.get = function (key) {\n var theId = UniqueIDGeneretor.createID(key);\n return this.map[theId];\n};\n\nHashMap.prototype.keySet = function () {\n return this.keys;\n};\n\nmodule.exports = HashMap;\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar UniqueIDGeneretor = __webpack_require__(14);\n\nfunction HashSet() {\n this.set = {};\n}\n;\n\nHashSet.prototype.add = function (obj) {\n var theId = UniqueIDGeneretor.createID(obj);\n if (!this.contains(theId)) this.set[theId] = obj;\n};\n\nHashSet.prototype.remove = function (obj) {\n delete this.set[UniqueIDGeneretor.createID(obj)];\n};\n\nHashSet.prototype.clear = function () {\n this.set = {};\n};\n\nHashSet.prototype.contains = function (obj) {\n return this.set[UniqueIDGeneretor.createID(obj)] == obj;\n};\n\nHashSet.prototype.isEmpty = function () {\n return this.size() === 0;\n};\n\nHashSet.prototype.size = function () {\n return Object.keys(this.set).length;\n};\n\n//concats this.set to the given list\nHashSet.prototype.addAllTo = function (list) {\n var keys = Object.keys(this.set);\n var length = keys.length;\n for (var i = 0; i < length; i++) {\n list.push(this.set[keys[i]]);\n }\n};\n\nHashSet.prototype.size = function () {\n return Object.keys(this.set).length;\n};\n\nHashSet.prototype.addAll = function (list) {\n var s = list.length;\n for (var i = 0; i < s; i++) {\n var v = list[i];\n this.add(v);\n }\n};\n\nmodule.exports = HashSet;\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * A classic Quicksort algorithm with Hoare's partition\n * - Works also on LinkedList objects\n *\n * Copyright: i-Vis Research Group, Bilkent University, 2007 - present\n */\n\nvar LinkedList = __webpack_require__(11);\n\nvar Quicksort = function () {\n function Quicksort(A, compareFunction) {\n _classCallCheck(this, Quicksort);\n\n if (compareFunction !== null || compareFunction !== undefined) this.compareFunction = this._defaultCompareFunction;\n\n var length = void 0;\n if (A instanceof LinkedList) length = A.size();else length = A.length;\n\n this._quicksort(A, 0, length - 1);\n }\n\n _createClass(Quicksort, [{\n key: '_quicksort',\n value: function _quicksort(A, p, r) {\n if (p < r) {\n var q = this._partition(A, p, r);\n this._quicksort(A, p, q);\n this._quicksort(A, q + 1, r);\n }\n }\n }, {\n key: '_partition',\n value: function _partition(A, p, r) {\n var x = this._get(A, p);\n var i = p;\n var j = r;\n while (true) {\n while (this.compareFunction(x, this._get(A, j))) {\n j--;\n }while (this.compareFunction(this._get(A, i), x)) {\n i++;\n }if (i < j) {\n this._swap(A, i, j);\n i++;\n j--;\n } else return j;\n }\n }\n }, {\n key: '_get',\n value: function _get(object, index) {\n if (object instanceof LinkedList) return object.get_object_at(index);else return object[index];\n }\n }, {\n key: '_set',\n value: function _set(object, index, value) {\n if (object instanceof LinkedList) object.set_object_at(index, value);else object[index] = value;\n }\n }, {\n key: '_swap',\n value: function _swap(A, i, j) {\n var temp = this._get(A, i);\n this._set(A, i, this._get(A, j));\n this._set(A, j, temp);\n }\n }, {\n key: '_defaultCompareFunction',\n value: function _defaultCompareFunction(a, b) {\n return b > a;\n }\n }]);\n\n return Quicksort;\n}();\n\nmodule.exports = Quicksort;\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Needleman-Wunsch algorithm is an procedure to compute the optimal global alignment of two string\n * sequences by S.B.Needleman and C.D.Wunsch (1970).\n *\n * Aside from the inputs, you can assign the scores for,\n * - Match: The two characters at the current index are same.\n * - Mismatch: The two characters at the current index are different.\n * - Insertion/Deletion(gaps): The best alignment involves one letter aligning to a gap in the other string.\n */\n\nvar NeedlemanWunsch = function () {\n function NeedlemanWunsch(sequence1, sequence2) {\n var match_score = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var mismatch_penalty = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1;\n var gap_penalty = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;\n\n _classCallCheck(this, NeedlemanWunsch);\n\n this.sequence1 = sequence1;\n this.sequence2 = sequence2;\n this.match_score = match_score;\n this.mismatch_penalty = mismatch_penalty;\n this.gap_penalty = gap_penalty;\n\n // Just the remove redundancy\n this.iMax = sequence1.length + 1;\n this.jMax = sequence2.length + 1;\n\n // Grid matrix of scores\n this.grid = new Array(this.iMax);\n for (var i = 0; i < this.iMax; i++) {\n this.grid[i] = new Array(this.jMax);\n\n for (var j = 0; j < this.jMax; j++) {\n this.grid[i][j] = 0;\n }\n }\n\n // Traceback matrix (2D array, each cell is an array of boolean values for [`Diag`, `Up`, `Left`] positions)\n this.tracebackGrid = new Array(this.iMax);\n for (var _i = 0; _i < this.iMax; _i++) {\n this.tracebackGrid[_i] = new Array(this.jMax);\n\n for (var _j = 0; _j < this.jMax; _j++) {\n this.tracebackGrid[_i][_j] = [null, null, null];\n }\n }\n\n // The aligned sequences (return multiple possibilities)\n this.alignments = [];\n\n // Final alignment score\n this.score = -1;\n\n // Calculate scores and tracebacks\n this.computeGrids();\n }\n\n _createClass(NeedlemanWunsch, [{\n key: \"getScore\",\n value: function getScore() {\n return this.score;\n }\n }, {\n key: \"getAlignments\",\n value: function getAlignments() {\n return this.alignments;\n }\n\n // Main dynamic programming procedure\n\n }, {\n key: \"computeGrids\",\n value: function computeGrids() {\n // Fill in the first row\n for (var j = 1; j < this.jMax; j++) {\n this.grid[0][j] = this.grid[0][j - 1] + this.gap_penalty;\n this.tracebackGrid[0][j] = [false, false, true];\n }\n\n // Fill in the first column\n for (var i = 1; i < this.iMax; i++) {\n this.grid[i][0] = this.grid[i - 1][0] + this.gap_penalty;\n this.tracebackGrid[i][0] = [false, true, false];\n }\n\n // Fill the rest of the grid\n for (var _i2 = 1; _i2 < this.iMax; _i2++) {\n for (var _j2 = 1; _j2 < this.jMax; _j2++) {\n // Find the max score(s) among [`Diag`, `Up`, `Left`]\n var diag = void 0;\n if (this.sequence1[_i2 - 1] === this.sequence2[_j2 - 1]) diag = this.grid[_i2 - 1][_j2 - 1] + this.match_score;else diag = this.grid[_i2 - 1][_j2 - 1] + this.mismatch_penalty;\n\n var up = this.grid[_i2 - 1][_j2] + this.gap_penalty;\n var left = this.grid[_i2][_j2 - 1] + this.gap_penalty;\n\n // If there exists multiple max values, capture them for multiple paths\n var maxOf = [diag, up, left];\n var indices = this.arrayAllMaxIndexes(maxOf);\n\n // Update Grids\n this.grid[_i2][_j2] = maxOf[indices[0]];\n this.tracebackGrid[_i2][_j2] = [indices.includes(0), indices.includes(1), indices.includes(2)];\n }\n }\n\n // Update alignment score\n this.score = this.grid[this.iMax - 1][this.jMax - 1];\n }\n\n // Gets all possible valid sequence combinations\n\n }, {\n key: \"alignmentTraceback\",\n value: function alignmentTraceback() {\n var inProcessAlignments = [];\n\n inProcessAlignments.push({ pos: [this.sequence1.length, this.sequence2.length],\n seq1: \"\",\n seq2: \"\"\n });\n\n while (inProcessAlignments[0]) {\n var current = inProcessAlignments[0];\n var directions = this.tracebackGrid[current.pos[0]][current.pos[1]];\n\n if (directions[0]) {\n inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1] - 1],\n seq1: this.sequence1[current.pos[0] - 1] + current.seq1,\n seq2: this.sequence2[current.pos[1] - 1] + current.seq2\n });\n }\n if (directions[1]) {\n inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1]],\n seq1: this.sequence1[current.pos[0] - 1] + current.seq1,\n seq2: '-' + current.seq2\n });\n }\n if (directions[2]) {\n inProcessAlignments.push({ pos: [current.pos[0], current.pos[1] - 1],\n seq1: '-' + current.seq1,\n seq2: this.sequence2[current.pos[1] - 1] + current.seq2\n });\n }\n\n if (current.pos[0] === 0 && current.pos[1] === 0) this.alignments.push({ sequence1: current.seq1,\n sequence2: current.seq2\n });\n\n inProcessAlignments.shift();\n }\n\n return this.alignments;\n }\n\n // Helper Functions\n\n }, {\n key: \"getAllIndexes\",\n value: function getAllIndexes(arr, val) {\n var indexes = [],\n i = -1;\n while ((i = arr.indexOf(val, i + 1)) !== -1) {\n indexes.push(i);\n }\n return indexes;\n }\n }, {\n key: \"arrayAllMaxIndexes\",\n value: function arrayAllMaxIndexes(array) {\n return this.getAllIndexes(array, Math.max.apply(null, array));\n }\n }]);\n\n return NeedlemanWunsch;\n}();\n\nmodule.exports = NeedlemanWunsch;\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar layoutBase = function layoutBase() {\n return;\n};\n\nlayoutBase.FDLayout = __webpack_require__(18);\nlayoutBase.FDLayoutConstants = __webpack_require__(7);\nlayoutBase.FDLayoutEdge = __webpack_require__(19);\nlayoutBase.FDLayoutNode = __webpack_require__(20);\nlayoutBase.DimensionD = __webpack_require__(21);\nlayoutBase.HashMap = __webpack_require__(22);\nlayoutBase.HashSet = __webpack_require__(23);\nlayoutBase.IGeometry = __webpack_require__(8);\nlayoutBase.IMath = __webpack_require__(9);\nlayoutBase.Integer = __webpack_require__(10);\nlayoutBase.Point = __webpack_require__(12);\nlayoutBase.PointD = __webpack_require__(4);\nlayoutBase.RandomSeed = __webpack_require__(16);\nlayoutBase.RectangleD = __webpack_require__(13);\nlayoutBase.Transform = __webpack_require__(17);\nlayoutBase.UniqueIDGeneretor = __webpack_require__(14);\nlayoutBase.Quicksort = __webpack_require__(24);\nlayoutBase.LinkedList = __webpack_require__(11);\nlayoutBase.LGraphObject = __webpack_require__(2);\nlayoutBase.LGraph = __webpack_require__(5);\nlayoutBase.LEdge = __webpack_require__(1);\nlayoutBase.LGraphManager = __webpack_require__(6);\nlayoutBase.LNode = __webpack_require__(3);\nlayoutBase.Layout = __webpack_require__(15);\nlayoutBase.LayoutConstants = __webpack_require__(0);\nlayoutBase.NeedlemanWunsch = __webpack_require__(25);\n\nmodule.exports = layoutBase;\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction Emitter() {\n this.listeners = [];\n}\n\nvar p = Emitter.prototype;\n\np.addListener = function (event, callback) {\n this.listeners.push({\n event: event,\n callback: callback\n });\n};\n\np.removeListener = function (event, callback) {\n for (var i = this.listeners.length; i >= 0; i--) {\n var l = this.listeners[i];\n\n if (l.event === event && l.callback === callback) {\n this.listeners.splice(i, 1);\n }\n }\n};\n\np.emit = function (event, data) {\n for (var i = 0; i < this.listeners.length; i++) {\n var l = this.listeners[i];\n\n if (event === l.event) {\n l.callback(data);\n }\n }\n};\n\nmodule.exports = Emitter;\n\n/***/ })\n/******/ ]);\n});", "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"layout-base\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"layout-base\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"coseBase\"] = factory(require(\"layout-base\"));\n\telse\n\t\troot[\"coseBase\"] = factory(root[\"layoutBase\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 7);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports) {\n\nmodule.exports = __WEBPACK_EXTERNAL_MODULE_0__;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar FDLayoutConstants = __webpack_require__(0).FDLayoutConstants;\n\nfunction CoSEConstants() {}\n\n//CoSEConstants inherits static props in FDLayoutConstants\nfor (var prop in FDLayoutConstants) {\n CoSEConstants[prop] = FDLayoutConstants[prop];\n}\n\nCoSEConstants.DEFAULT_USE_MULTI_LEVEL_SCALING = false;\nCoSEConstants.DEFAULT_RADIAL_SEPARATION = FDLayoutConstants.DEFAULT_EDGE_LENGTH;\nCoSEConstants.DEFAULT_COMPONENT_SEPERATION = 60;\nCoSEConstants.TILE = true;\nCoSEConstants.TILING_PADDING_VERTICAL = 10;\nCoSEConstants.TILING_PADDING_HORIZONTAL = 10;\nCoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = false; // make this true when cose is used incrementally as a part of other non-incremental layout\n\nmodule.exports = CoSEConstants;\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar FDLayoutEdge = __webpack_require__(0).FDLayoutEdge;\n\nfunction CoSEEdge(source, target, vEdge) {\n FDLayoutEdge.call(this, source, target, vEdge);\n}\n\nCoSEEdge.prototype = Object.create(FDLayoutEdge.prototype);\nfor (var prop in FDLayoutEdge) {\n CoSEEdge[prop] = FDLayoutEdge[prop];\n}\n\nmodule.exports = CoSEEdge;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraph = __webpack_require__(0).LGraph;\n\nfunction CoSEGraph(parent, graphMgr, vGraph) {\n LGraph.call(this, parent, graphMgr, vGraph);\n}\n\nCoSEGraph.prototype = Object.create(LGraph.prototype);\nfor (var prop in LGraph) {\n CoSEGraph[prop] = LGraph[prop];\n}\n\nmodule.exports = CoSEGraph;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraphManager = __webpack_require__(0).LGraphManager;\n\nfunction CoSEGraphManager(layout) {\n LGraphManager.call(this, layout);\n}\n\nCoSEGraphManager.prototype = Object.create(LGraphManager.prototype);\nfor (var prop in LGraphManager) {\n CoSEGraphManager[prop] = LGraphManager[prop];\n}\n\nmodule.exports = CoSEGraphManager;\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar FDLayoutNode = __webpack_require__(0).FDLayoutNode;\nvar IMath = __webpack_require__(0).IMath;\n\nfunction CoSENode(gm, loc, size, vNode) {\n FDLayoutNode.call(this, gm, loc, size, vNode);\n}\n\nCoSENode.prototype = Object.create(FDLayoutNode.prototype);\nfor (var prop in FDLayoutNode) {\n CoSENode[prop] = FDLayoutNode[prop];\n}\n\nCoSENode.prototype.move = function () {\n var layout = this.graphManager.getLayout();\n this.displacementX = layout.coolingFactor * (this.springForceX + this.repulsionForceX + this.gravitationForceX) / this.noOfChildren;\n this.displacementY = layout.coolingFactor * (this.springForceY + this.repulsionForceY + this.gravitationForceY) / this.noOfChildren;\n\n if (Math.abs(this.displacementX) > layout.coolingFactor * layout.maxNodeDisplacement) {\n this.displacementX = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementX);\n }\n\n if (Math.abs(this.displacementY) > layout.coolingFactor * layout.maxNodeDisplacement) {\n this.displacementY = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementY);\n }\n\n // a simple node, just move it\n if (this.child == null) {\n this.moveBy(this.displacementX, this.displacementY);\n }\n // an empty compound node, again just move it\n else if (this.child.getNodes().length == 0) {\n this.moveBy(this.displacementX, this.displacementY);\n }\n // non-empty compound node, propogate movement to children as well\n else {\n this.propogateDisplacementToChildren(this.displacementX, this.displacementY);\n }\n\n layout.totalDisplacement += Math.abs(this.displacementX) + Math.abs(this.displacementY);\n\n this.springForceX = 0;\n this.springForceY = 0;\n this.repulsionForceX = 0;\n this.repulsionForceY = 0;\n this.gravitationForceX = 0;\n this.gravitationForceY = 0;\n this.displacementX = 0;\n this.displacementY = 0;\n};\n\nCoSENode.prototype.propogateDisplacementToChildren = function (dX, dY) {\n var nodes = this.getChild().getNodes();\n var node;\n for (var i = 0; i < nodes.length; i++) {\n node = nodes[i];\n if (node.getChild() == null) {\n node.moveBy(dX, dY);\n node.displacementX += dX;\n node.displacementY += dY;\n } else {\n node.propogateDisplacementToChildren(dX, dY);\n }\n }\n};\n\nCoSENode.prototype.setPred1 = function (pred1) {\n this.pred1 = pred1;\n};\n\nCoSENode.prototype.getPred1 = function () {\n return pred1;\n};\n\nCoSENode.prototype.getPred2 = function () {\n return pred2;\n};\n\nCoSENode.prototype.setNext = function (next) {\n this.next = next;\n};\n\nCoSENode.prototype.getNext = function () {\n return next;\n};\n\nCoSENode.prototype.setProcessed = function (processed) {\n this.processed = processed;\n};\n\nCoSENode.prototype.isProcessed = function () {\n return processed;\n};\n\nmodule.exports = CoSENode;\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar FDLayout = __webpack_require__(0).FDLayout;\nvar CoSEGraphManager = __webpack_require__(4);\nvar CoSEGraph = __webpack_require__(3);\nvar CoSENode = __webpack_require__(5);\nvar CoSEEdge = __webpack_require__(2);\nvar CoSEConstants = __webpack_require__(1);\nvar FDLayoutConstants = __webpack_require__(0).FDLayoutConstants;\nvar LayoutConstants = __webpack_require__(0).LayoutConstants;\nvar Point = __webpack_require__(0).Point;\nvar PointD = __webpack_require__(0).PointD;\nvar Layout = __webpack_require__(0).Layout;\nvar Integer = __webpack_require__(0).Integer;\nvar IGeometry = __webpack_require__(0).IGeometry;\nvar LGraph = __webpack_require__(0).LGraph;\nvar Transform = __webpack_require__(0).Transform;\n\nfunction CoSELayout() {\n FDLayout.call(this);\n\n this.toBeTiled = {}; // Memorize if a node is to be tiled or is tiled\n}\n\nCoSELayout.prototype = Object.create(FDLayout.prototype);\n\nfor (var prop in FDLayout) {\n CoSELayout[prop] = FDLayout[prop];\n}\n\nCoSELayout.prototype.newGraphManager = function () {\n var gm = new CoSEGraphManager(this);\n this.graphManager = gm;\n return gm;\n};\n\nCoSELayout.prototype.newGraph = function (vGraph) {\n return new CoSEGraph(null, this.graphManager, vGraph);\n};\n\nCoSELayout.prototype.newNode = function (vNode) {\n return new CoSENode(this.graphManager, vNode);\n};\n\nCoSELayout.prototype.newEdge = function (vEdge) {\n return new CoSEEdge(null, null, vEdge);\n};\n\nCoSELayout.prototype.initParameters = function () {\n FDLayout.prototype.initParameters.call(this, arguments);\n if (!this.isSubLayout) {\n if (CoSEConstants.DEFAULT_EDGE_LENGTH < 10) {\n this.idealEdgeLength = 10;\n } else {\n this.idealEdgeLength = CoSEConstants.DEFAULT_EDGE_LENGTH;\n }\n\n this.useSmartIdealEdgeLengthCalculation = CoSEConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;\n this.springConstant = FDLayoutConstants.DEFAULT_SPRING_STRENGTH;\n this.repulsionConstant = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH;\n this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;\n this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;\n this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;\n this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;\n\n // variables for tree reduction support\n this.prunedNodesAll = [];\n this.growTreeIterations = 0;\n this.afterGrowthIterations = 0;\n this.isTreeGrowing = false;\n this.isGrowthFinished = false;\n\n // variables for cooling\n this.coolingCycle = 0;\n this.maxCoolingCycle = this.maxIterations / FDLayoutConstants.CONVERGENCE_CHECK_PERIOD;\n this.finalTemperature = FDLayoutConstants.CONVERGENCE_CHECK_PERIOD / this.maxIterations;\n this.coolingAdjuster = 1;\n }\n};\n\nCoSELayout.prototype.layout = function () {\n var createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;\n if (createBendsAsNeeded) {\n this.createBendpoints();\n this.graphManager.resetAllEdges();\n }\n\n this.level = 0;\n return this.classicLayout();\n};\n\nCoSELayout.prototype.classicLayout = function () {\n this.nodesWithGravity = this.calculateNodesToApplyGravitationTo();\n this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity);\n this.calcNoOfChildrenForAllNodes();\n this.graphManager.calcLowestCommonAncestors();\n this.graphManager.calcInclusionTreeDepths();\n this.graphManager.getRoot().calcEstimatedSize();\n this.calcIdealEdgeLengths();\n\n if (!this.incremental) {\n var forest = this.getFlatForest();\n\n // The graph associated with this layout is flat and a forest\n if (forest.length > 0) {\n this.positionNodesRadially(forest);\n }\n // The graph associated with this layout is not flat or a forest\n else {\n // Reduce the trees when incremental mode is not enabled and graph is not a forest \n this.reduceTrees();\n // Update nodes that gravity will be applied\n this.graphManager.resetAllNodesToApplyGravitation();\n var allNodes = new Set(this.getAllNodes());\n var intersection = this.nodesWithGravity.filter(function (x) {\n return allNodes.has(x);\n });\n this.graphManager.setAllNodesToApplyGravitation(intersection);\n\n this.positionNodesRandomly();\n }\n } else {\n if (CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL) {\n // Reduce the trees in incremental mode if only this constant is set to true \n this.reduceTrees();\n // Update nodes that gravity will be applied\n this.graphManager.resetAllNodesToApplyGravitation();\n var allNodes = new Set(this.getAllNodes());\n var intersection = this.nodesWithGravity.filter(function (x) {\n return allNodes.has(x);\n });\n this.graphManager.setAllNodesToApplyGravitation(intersection);\n }\n }\n\n this.initSpringEmbedder();\n this.runSpringEmbedder();\n\n return true;\n};\n\nCoSELayout.prototype.tick = function () {\n this.totalIterations++;\n\n if (this.totalIterations === this.maxIterations && !this.isTreeGrowing && !this.isGrowthFinished) {\n if (this.prunedNodesAll.length > 0) {\n this.isTreeGrowing = true;\n } else {\n return true;\n }\n }\n\n if (this.totalIterations % FDLayoutConstants.CONVERGENCE_CHECK_PERIOD == 0 && !this.isTreeGrowing && !this.isGrowthFinished) {\n if (this.isConverged()) {\n if (this.prunedNodesAll.length > 0) {\n this.isTreeGrowing = true;\n } else {\n return true;\n }\n }\n\n this.coolingCycle++;\n\n if (this.layoutQuality == 0) {\n // quality - \"draft\"\n this.coolingAdjuster = this.coolingCycle;\n } else if (this.layoutQuality == 1) {\n // quality - \"default\"\n this.coolingAdjuster = this.coolingCycle / 3;\n }\n\n // cooling schedule is based on http://www.btluke.com/simanf1.html -> cooling schedule 3\n this.coolingFactor = Math.max(this.initialCoolingFactor - Math.pow(this.coolingCycle, Math.log(100 * (this.initialCoolingFactor - this.finalTemperature)) / Math.log(this.maxCoolingCycle)) / 100 * this.coolingAdjuster, this.finalTemperature);\n this.animationPeriod = Math.ceil(this.initialAnimationPeriod * Math.sqrt(this.coolingFactor));\n }\n // Operations while tree is growing again \n if (this.isTreeGrowing) {\n if (this.growTreeIterations % 10 == 0) {\n if (this.prunedNodesAll.length > 0) {\n this.graphManager.updateBounds();\n this.updateGrid();\n this.growTree(this.prunedNodesAll);\n // Update nodes that gravity will be applied\n this.graphManager.resetAllNodesToApplyGravitation();\n var allNodes = new Set(this.getAllNodes());\n var intersection = this.nodesWithGravity.filter(function (x) {\n return allNodes.has(x);\n });\n this.graphManager.setAllNodesToApplyGravitation(intersection);\n\n this.graphManager.updateBounds();\n this.updateGrid();\n this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;\n } else {\n this.isTreeGrowing = false;\n this.isGrowthFinished = true;\n }\n }\n this.growTreeIterations++;\n }\n // Operations after growth is finished\n if (this.isGrowthFinished) {\n if (this.isConverged()) {\n return true;\n }\n if (this.afterGrowthIterations % 10 == 0) {\n this.graphManager.updateBounds();\n this.updateGrid();\n }\n this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL * ((100 - this.afterGrowthIterations) / 100);\n this.afterGrowthIterations++;\n }\n\n var gridUpdateAllowed = !this.isTreeGrowing && !this.isGrowthFinished;\n var forceToNodeSurroundingUpdate = this.growTreeIterations % 10 == 1 && this.isTreeGrowing || this.afterGrowthIterations % 10 == 1 && this.isGrowthFinished;\n\n this.totalDisplacement = 0;\n this.graphManager.updateBounds();\n this.calcSpringForces();\n this.calcRepulsionForces(gridUpdateAllowed, forceToNodeSurroundingUpdate);\n this.calcGravitationalForces();\n this.moveNodes();\n this.animate();\n\n return false; // Layout is not ended yet return false\n};\n\nCoSELayout.prototype.getPositionsData = function () {\n var allNodes = this.graphManager.getAllNodes();\n var pData = {};\n for (var i = 0; i < allNodes.length; i++) {\n var rect = allNodes[i].rect;\n var id = allNodes[i].id;\n pData[id] = {\n id: id,\n x: rect.getCenterX(),\n y: rect.getCenterY(),\n w: rect.width,\n h: rect.height\n };\n }\n\n return pData;\n};\n\nCoSELayout.prototype.runSpringEmbedder = function () {\n this.initialAnimationPeriod = 25;\n this.animationPeriod = this.initialAnimationPeriod;\n var layoutEnded = false;\n\n // If aminate option is 'during' signal that layout is supposed to start iterating\n if (FDLayoutConstants.ANIMATE === 'during') {\n this.emit('layoutstarted');\n } else {\n // If aminate option is 'during' tick() function will be called on index.js\n while (!layoutEnded) {\n layoutEnded = this.tick();\n }\n\n this.graphManager.updateBounds();\n }\n};\n\nCoSELayout.prototype.calculateNodesToApplyGravitationTo = function () {\n var nodeList = [];\n var graph;\n\n var graphs = this.graphManager.getGraphs();\n var size = graphs.length;\n var i;\n for (i = 0; i < size; i++) {\n graph = graphs[i];\n\n graph.updateConnected();\n\n if (!graph.isConnected) {\n nodeList = nodeList.concat(graph.getNodes());\n }\n }\n\n return nodeList;\n};\n\nCoSELayout.prototype.createBendpoints = function () {\n var edges = [];\n edges = edges.concat(this.graphManager.getAllEdges());\n var visited = new Set();\n var i;\n for (i = 0; i < edges.length; i++) {\n var edge = edges[i];\n\n if (!visited.has(edge)) {\n var source = edge.getSource();\n var target = edge.getTarget();\n\n if (source == target) {\n edge.getBendpoints().push(new PointD());\n edge.getBendpoints().push(new PointD());\n this.createDummyNodesForBendpoints(edge);\n visited.add(edge);\n } else {\n var edgeList = [];\n\n edgeList = edgeList.concat(source.getEdgeListToNode(target));\n edgeList = edgeList.concat(target.getEdgeListToNode(source));\n\n if (!visited.has(edgeList[0])) {\n if (edgeList.length > 1) {\n var k;\n for (k = 0; k < edgeList.length; k++) {\n var multiEdge = edgeList[k];\n multiEdge.getBendpoints().push(new PointD());\n this.createDummyNodesForBendpoints(multiEdge);\n }\n }\n edgeList.forEach(function (edge) {\n visited.add(edge);\n });\n }\n }\n }\n\n if (visited.size == edges.length) {\n break;\n }\n }\n};\n\nCoSELayout.prototype.positionNodesRadially = function (forest) {\n // We tile the trees to a grid row by row; first tree starts at (0,0)\n var currentStartingPoint = new Point(0, 0);\n var numberOfColumns = Math.ceil(Math.sqrt(forest.length));\n var height = 0;\n var currentY = 0;\n var currentX = 0;\n var point = new PointD(0, 0);\n\n for (var i = 0; i < forest.length; i++) {\n if (i % numberOfColumns == 0) {\n // Start of a new row, make the x coordinate 0, increment the\n // y coordinate with the max height of the previous row\n currentX = 0;\n currentY = height;\n\n if (i != 0) {\n currentY += CoSEConstants.DEFAULT_COMPONENT_SEPERATION;\n }\n\n height = 0;\n }\n\n var tree = forest[i];\n\n // Find the center of the tree\n var centerNode = Layout.findCenterOfTree(tree);\n\n // Set the staring point of the next tree\n currentStartingPoint.x = currentX;\n currentStartingPoint.y = currentY;\n\n // Do a radial layout starting with the center\n point = CoSELayout.radialLayout(tree, centerNode, currentStartingPoint);\n\n if (point.y > height) {\n height = Math.floor(point.y);\n }\n\n currentX = Math.floor(point.x + CoSEConstants.DEFAULT_COMPONENT_SEPERATION);\n }\n\n this.transform(new PointD(LayoutConstants.WORLD_CENTER_X - point.x / 2, LayoutConstants.WORLD_CENTER_Y - point.y / 2));\n};\n\nCoSELayout.radialLayout = function (tree, centerNode, startingPoint) {\n var radialSep = Math.max(this.maxDiagonalInTree(tree), CoSEConstants.DEFAULT_RADIAL_SEPARATION);\n CoSELayout.branchRadialLayout(centerNode, null, 0, 359, 0, radialSep);\n var bounds = LGraph.calculateBounds(tree);\n\n var transform = new Transform();\n transform.setDeviceOrgX(bounds.getMinX());\n transform.setDeviceOrgY(bounds.getMinY());\n transform.setWorldOrgX(startingPoint.x);\n transform.setWorldOrgY(startingPoint.y);\n\n for (var i = 0; i < tree.length; i++) {\n var node = tree[i];\n node.transform(transform);\n }\n\n var bottomRight = new PointD(bounds.getMaxX(), bounds.getMaxY());\n\n return transform.inverseTransformPoint(bottomRight);\n};\n\nCoSELayout.branchRadialLayout = function (node, parentOfNode, startAngle, endAngle, distance, radialSeparation) {\n // First, position this node by finding its angle.\n var halfInterval = (endAngle - startAngle + 1) / 2;\n\n if (halfInterval < 0) {\n halfInterval += 180;\n }\n\n var nodeAngle = (halfInterval + startAngle) % 360;\n var teta = nodeAngle * IGeometry.TWO_PI / 360;\n\n // Make polar to java cordinate conversion.\n var cos_teta = Math.cos(teta);\n var x_ = distance * Math.cos(teta);\n var y_ = distance * Math.sin(teta);\n\n node.setCenter(x_, y_);\n\n // Traverse all neighbors of this node and recursively call this\n // function.\n var neighborEdges = [];\n neighborEdges = neighborEdges.concat(node.getEdges());\n var childCount = neighborEdges.length;\n\n if (parentOfNode != null) {\n childCount--;\n }\n\n var branchCount = 0;\n\n var incEdgesCount = neighborEdges.length;\n var startIndex;\n\n var edges = node.getEdgesBetween(parentOfNode);\n\n // If there are multiple edges, prune them until there remains only one\n // edge.\n while (edges.length > 1) {\n //neighborEdges.remove(edges.remove(0));\n var temp = edges[0];\n edges.splice(0, 1);\n var index = neighborEdges.indexOf(temp);\n if (index >= 0) {\n neighborEdges.splice(index, 1);\n }\n incEdgesCount--;\n childCount--;\n }\n\n if (parentOfNode != null) {\n //assert edges.length == 1;\n startIndex = (neighborEdges.indexOf(edges[0]) + 1) % incEdgesCount;\n } else {\n startIndex = 0;\n }\n\n var stepAngle = Math.abs(endAngle - startAngle) / childCount;\n\n for (var i = startIndex; branchCount != childCount; i = ++i % incEdgesCount) {\n var currentNeighbor = neighborEdges[i].getOtherEnd(node);\n\n // Don't back traverse to root node in current tree.\n if (currentNeighbor == parentOfNode) {\n continue;\n }\n\n var childStartAngle = (startAngle + branchCount * stepAngle) % 360;\n var childEndAngle = (childStartAngle + stepAngle) % 360;\n\n CoSELayout.branchRadialLayout(currentNeighbor, node, childStartAngle, childEndAngle, distance + radialSeparation, radialSeparation);\n\n branchCount++;\n }\n};\n\nCoSELayout.maxDiagonalInTree = function (tree) {\n var maxDiagonal = Integer.MIN_VALUE;\n\n for (var i = 0; i < tree.length; i++) {\n var node = tree[i];\n var diagonal = node.getDiagonal();\n\n if (diagonal > maxDiagonal) {\n maxDiagonal = diagonal;\n }\n }\n\n return maxDiagonal;\n};\n\nCoSELayout.prototype.calcRepulsionRange = function () {\n // formula is 2 x (level + 1) x idealEdgeLength\n return 2 * (this.level + 1) * this.idealEdgeLength;\n};\n\n// Tiling methods\n\n// Group zero degree members whose parents are not to be tiled, create dummy parents where needed and fill memberGroups by their dummp parent id's\nCoSELayout.prototype.groupZeroDegreeMembers = function () {\n var self = this;\n // array of [parent_id x oneDegreeNode_id]\n var tempMemberGroups = {}; // A temporary map of parent node and its zero degree members\n this.memberGroups = {}; // A map of dummy parent node and its zero degree members whose parents are not to be tiled\n this.idToDummyNode = {}; // A map of id to dummy node \n\n var zeroDegree = []; // List of zero degree nodes whose parents are not to be tiled\n var allNodes = this.graphManager.getAllNodes();\n\n // Fill zero degree list\n for (var i = 0; i < allNodes.length; i++) {\n var node = allNodes[i];\n var parent = node.getParent();\n // If a node has zero degree and its parent is not to be tiled if exists add that node to zeroDegres list\n if (this.getNodeDegreeWithChildren(node) === 0 && (parent.id == undefined || !this.getToBeTiled(parent))) {\n zeroDegree.push(node);\n }\n }\n\n // Create a map of parent node and its zero degree members\n for (var i = 0; i < zeroDegree.length; i++) {\n var node = zeroDegree[i]; // Zero degree node itself\n var p_id = node.getParent().id; // Parent id\n\n if (typeof tempMemberGroups[p_id] === \"undefined\") tempMemberGroups[p_id] = [];\n\n tempMemberGroups[p_id] = tempMemberGroups[p_id].concat(node); // Push node to the list belongs to its parent in tempMemberGroups\n }\n\n // If there are at least two nodes at a level, create a dummy compound for them\n Object.keys(tempMemberGroups).forEach(function (p_id) {\n if (tempMemberGroups[p_id].length > 1) {\n var dummyCompoundId = \"DummyCompound_\" + p_id; // The id of dummy compound which will be created soon\n self.memberGroups[dummyCompoundId] = tempMemberGroups[p_id]; // Add dummy compound to memberGroups\n\n var parent = tempMemberGroups[p_id][0].getParent(); // The parent of zero degree nodes will be the parent of new dummy compound\n\n // Create a dummy compound with calculated id\n var dummyCompound = new CoSENode(self.graphManager);\n dummyCompound.id = dummyCompoundId;\n dummyCompound.paddingLeft = parent.paddingLeft || 0;\n dummyCompound.paddingRight = parent.paddingRight || 0;\n dummyCompound.paddingBottom = parent.paddingBottom || 0;\n dummyCompound.paddingTop = parent.paddingTop || 0;\n\n self.idToDummyNode[dummyCompoundId] = dummyCompound;\n\n var dummyParentGraph = self.getGraphManager().add(self.newGraph(), dummyCompound);\n var parentGraph = parent.getChild();\n\n // Add dummy compound to parent the graph\n parentGraph.add(dummyCompound);\n\n // For each zero degree node in this level remove it from its parent graph and add it to the graph of dummy parent\n for (var i = 0; i < tempMemberGroups[p_id].length; i++) {\n var node = tempMemberGroups[p_id][i];\n\n parentGraph.remove(node);\n dummyParentGraph.add(node);\n }\n }\n });\n};\n\nCoSELayout.prototype.clearCompounds = function () {\n var childGraphMap = {};\n var idToNode = {};\n\n // Get compound ordering by finding the inner one first\n this.performDFSOnCompounds();\n\n for (var i = 0; i < this.compoundOrder.length; i++) {\n\n idToNode[this.compoundOrder[i].id] = this.compoundOrder[i];\n childGraphMap[this.compoundOrder[i].id] = [].concat(this.compoundOrder[i].getChild().getNodes());\n\n // Remove children of compounds\n this.graphManager.remove(this.compoundOrder[i].getChild());\n this.compoundOrder[i].child = null;\n }\n\n this.graphManager.resetAllNodes();\n\n // Tile the removed children\n this.tileCompoundMembers(childGraphMap, idToNode);\n};\n\nCoSELayout.prototype.clearZeroDegreeMembers = function () {\n var self = this;\n var tiledZeroDegreePack = this.tiledZeroDegreePack = [];\n\n Object.keys(this.memberGroups).forEach(function (id) {\n var compoundNode = self.idToDummyNode[id]; // Get the dummy compound\n\n tiledZeroDegreePack[id] = self.tileNodes(self.memberGroups[id], compoundNode.paddingLeft + compoundNode.paddingRight);\n\n // Set the width and height of the dummy compound as calculated\n compoundNode.rect.width = tiledZeroDegreePack[id].width;\n compoundNode.rect.height = tiledZeroDegreePack[id].height;\n });\n};\n\nCoSELayout.prototype.repopulateCompounds = function () {\n for (var i = this.compoundOrder.length - 1; i >= 0; i--) {\n var lCompoundNode = this.compoundOrder[i];\n var id = lCompoundNode.id;\n var horizontalMargin = lCompoundNode.paddingLeft;\n var verticalMargin = lCompoundNode.paddingTop;\n\n this.adjustLocations(this.tiledMemberPack[id], lCompoundNode.rect.x, lCompoundNode.rect.y, horizontalMargin, verticalMargin);\n }\n};\n\nCoSELayout.prototype.repopulateZeroDegreeMembers = function () {\n var self = this;\n var tiledPack = this.tiledZeroDegreePack;\n\n Object.keys(tiledPack).forEach(function (id) {\n var compoundNode = self.idToDummyNode[id]; // Get the dummy compound by its id\n var horizontalMargin = compoundNode.paddingLeft;\n var verticalMargin = compoundNode.paddingTop;\n\n // Adjust the positions of nodes wrt its compound\n self.adjustLocations(tiledPack[id], compoundNode.rect.x, compoundNode.rect.y, horizontalMargin, verticalMargin);\n });\n};\n\nCoSELayout.prototype.getToBeTiled = function (node) {\n var id = node.id;\n //firstly check the previous results\n if (this.toBeTiled[id] != null) {\n return this.toBeTiled[id];\n }\n\n //only compound nodes are to be tiled\n var childGraph = node.getChild();\n if (childGraph == null) {\n this.toBeTiled[id] = false;\n return false;\n }\n\n var children = childGraph.getNodes(); // Get the children nodes\n\n //a compound node is not to be tiled if all of its compound children are not to be tiled\n for (var i = 0; i < children.length; i++) {\n var theChild = children[i];\n\n if (this.getNodeDegree(theChild) > 0) {\n this.toBeTiled[id] = false;\n return false;\n }\n\n //pass the children not having the compound structure\n if (theChild.getChild() == null) {\n this.toBeTiled[theChild.id] = false;\n continue;\n }\n\n if (!this.getToBeTiled(theChild)) {\n this.toBeTiled[id] = false;\n return false;\n }\n }\n this.toBeTiled[id] = true;\n return true;\n};\n\n// Get degree of a node depending of its edges and independent of its children\nCoSELayout.prototype.getNodeDegree = function (node) {\n var id = node.id;\n var edges = node.getEdges();\n var degree = 0;\n\n // For the edges connected\n for (var i = 0; i < edges.length; i++) {\n var edge = edges[i];\n if (edge.getSource().id !== edge.getTarget().id) {\n degree = degree + 1;\n }\n }\n return degree;\n};\n\n// Get degree of a node with its children\nCoSELayout.prototype.getNodeDegreeWithChildren = function (node) {\n var degree = this.getNodeDegree(node);\n if (node.getChild() == null) {\n return degree;\n }\n var children = node.getChild().getNodes();\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n degree += this.getNodeDegreeWithChildren(child);\n }\n return degree;\n};\n\nCoSELayout.prototype.performDFSOnCompounds = function () {\n this.compoundOrder = [];\n this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes());\n};\n\nCoSELayout.prototype.fillCompexOrderByDFS = function (children) {\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n if (child.getChild() != null) {\n this.fillCompexOrderByDFS(child.getChild().getNodes());\n }\n if (this.getToBeTiled(child)) {\n this.compoundOrder.push(child);\n }\n }\n};\n\n/**\n* This method places each zero degree member wrt given (x,y) coordinates (top left).\n*/\nCoSELayout.prototype.adjustLocations = function (organization, x, y, compoundHorizontalMargin, compoundVerticalMargin) {\n x += compoundHorizontalMargin;\n y += compoundVerticalMargin;\n\n var left = x;\n\n for (var i = 0; i < organization.rows.length; i++) {\n var row = organization.rows[i];\n x = left;\n var maxHeight = 0;\n\n for (var j = 0; j < row.length; j++) {\n var lnode = row[j];\n\n lnode.rect.x = x; // + lnode.rect.width / 2;\n lnode.rect.y = y; // + lnode.rect.height / 2;\n\n x += lnode.rect.width + organization.horizontalPadding;\n\n if (lnode.rect.height > maxHeight) maxHeight = lnode.rect.height;\n }\n\n y += maxHeight + organization.verticalPadding;\n }\n};\n\nCoSELayout.prototype.tileCompoundMembers = function (childGraphMap, idToNode) {\n var self = this;\n this.tiledMemberPack = [];\n\n Object.keys(childGraphMap).forEach(function (id) {\n // Get the compound node\n var compoundNode = idToNode[id];\n\n self.tiledMemberPack[id] = self.tileNodes(childGraphMap[id], compoundNode.paddingLeft + compoundNode.paddingRight);\n\n compoundNode.rect.width = self.tiledMemberPack[id].width;\n compoundNode.rect.height = self.tiledMemberPack[id].height;\n });\n};\n\nCoSELayout.prototype.tileNodes = function (nodes, minWidth) {\n var verticalPadding = CoSEConstants.TILING_PADDING_VERTICAL;\n var horizontalPadding = CoSEConstants.TILING_PADDING_HORIZONTAL;\n var organization = {\n rows: [],\n rowWidth: [],\n rowHeight: [],\n width: 0,\n height: minWidth, // assume minHeight equals to minWidth\n verticalPadding: verticalPadding,\n horizontalPadding: horizontalPadding\n };\n\n // Sort the nodes in ascending order of their areas\n nodes.sort(function (n1, n2) {\n if (n1.rect.width * n1.rect.height > n2.rect.width * n2.rect.height) return -1;\n if (n1.rect.width * n1.rect.height < n2.rect.width * n2.rect.height) return 1;\n return 0;\n });\n\n // Create the organization -> tile members\n for (var i = 0; i < nodes.length; i++) {\n var lNode = nodes[i];\n\n if (organization.rows.length == 0) {\n this.insertNodeToRow(organization, lNode, 0, minWidth);\n } else if (this.canAddHorizontal(organization, lNode.rect.width, lNode.rect.height)) {\n this.insertNodeToRow(organization, lNode, this.getShortestRowIndex(organization), minWidth);\n } else {\n this.insertNodeToRow(organization, lNode, organization.rows.length, minWidth);\n }\n\n this.shiftToLastRow(organization);\n }\n\n return organization;\n};\n\nCoSELayout.prototype.insertNodeToRow = function (organization, node, rowIndex, minWidth) {\n var minCompoundSize = minWidth;\n\n // Add new row if needed\n if (rowIndex == organization.rows.length) {\n var secondDimension = [];\n\n organization.rows.push(secondDimension);\n organization.rowWidth.push(minCompoundSize);\n organization.rowHeight.push(0);\n }\n\n // Update row width\n var w = organization.rowWidth[rowIndex] + node.rect.width;\n\n if (organization.rows[rowIndex].length > 0) {\n w += organization.horizontalPadding;\n }\n\n organization.rowWidth[rowIndex] = w;\n // Update compound width\n if (organization.width < w) {\n organization.width = w;\n }\n\n // Update height\n var h = node.rect.height;\n if (rowIndex > 0) h += organization.verticalPadding;\n\n var extraHeight = 0;\n if (h > organization.rowHeight[rowIndex]) {\n extraHeight = organization.rowHeight[rowIndex];\n organization.rowHeight[rowIndex] = h;\n extraHeight = organization.rowHeight[rowIndex] - extraHeight;\n }\n\n organization.height += extraHeight;\n\n // Insert node\n organization.rows[rowIndex].push(node);\n};\n\n//Scans the rows of an organization and returns the one with the min width\nCoSELayout.prototype.getShortestRowIndex = function (organization) {\n var r = -1;\n var min = Number.MAX_VALUE;\n\n for (var i = 0; i < organization.rows.length; i++) {\n if (organization.rowWidth[i] < min) {\n r = i;\n min = organization.rowWidth[i];\n }\n }\n return r;\n};\n\n//Scans the rows of an organization and returns the one with the max width\nCoSELayout.prototype.getLongestRowIndex = function (organization) {\n var r = -1;\n var max = Number.MIN_VALUE;\n\n for (var i = 0; i < organization.rows.length; i++) {\n\n if (organization.rowWidth[i] > max) {\n r = i;\n max = organization.rowWidth[i];\n }\n }\n\n return r;\n};\n\n/**\n* This method checks whether adding extra width to the organization violates\n* the aspect ratio(1) or not.\n*/\nCoSELayout.prototype.canAddHorizontal = function (organization, extraWidth, extraHeight) {\n\n var sri = this.getShortestRowIndex(organization);\n\n if (sri < 0) {\n return true;\n }\n\n var min = organization.rowWidth[sri];\n\n if (min + organization.horizontalPadding + extraWidth <= organization.width) return true;\n\n var hDiff = 0;\n\n // Adding to an existing row\n if (organization.rowHeight[sri] < extraHeight) {\n if (sri > 0) hDiff = extraHeight + organization.verticalPadding - organization.rowHeight[sri];\n }\n\n var add_to_row_ratio;\n if (organization.width - min >= extraWidth + organization.horizontalPadding) {\n add_to_row_ratio = (organization.height + hDiff) / (min + extraWidth + organization.horizontalPadding);\n } else {\n add_to_row_ratio = (organization.height + hDiff) / organization.width;\n }\n\n // Adding a new row for this node\n hDiff = extraHeight + organization.verticalPadding;\n var add_new_row_ratio;\n if (organization.width < extraWidth) {\n add_new_row_ratio = (organization.height + hDiff) / extraWidth;\n } else {\n add_new_row_ratio = (organization.height + hDiff) / organization.width;\n }\n\n if (add_new_row_ratio < 1) add_new_row_ratio = 1 / add_new_row_ratio;\n\n if (add_to_row_ratio < 1) add_to_row_ratio = 1 / add_to_row_ratio;\n\n return add_to_row_ratio < add_new_row_ratio;\n};\n\n//If moving the last node from the longest row and adding it to the last\n//row makes the bounding box smaller, do it.\nCoSELayout.prototype.shiftToLastRow = function (organization) {\n var longest = this.getLongestRowIndex(organization);\n var last = organization.rowWidth.length - 1;\n var row = organization.rows[longest];\n var node = row[row.length - 1];\n\n var diff = node.width + organization.horizontalPadding;\n\n // Check if there is enough space on the last row\n if (organization.width - organization.rowWidth[last] > diff && longest != last) {\n // Remove the last element of the longest row\n row.splice(-1, 1);\n\n // Push it to the last row\n organization.rows[last].push(node);\n\n organization.rowWidth[longest] = organization.rowWidth[longest] - diff;\n organization.rowWidth[last] = organization.rowWidth[last] + diff;\n organization.width = organization.rowWidth[instance.getLongestRowIndex(organization)];\n\n // Update heights of the organization\n var maxHeight = Number.MIN_VALUE;\n for (var i = 0; i < row.length; i++) {\n if (row[i].height > maxHeight) maxHeight = row[i].height;\n }\n if (longest > 0) maxHeight += organization.verticalPadding;\n\n var prevTotal = organization.rowHeight[longest] + organization.rowHeight[last];\n\n organization.rowHeight[longest] = maxHeight;\n if (organization.rowHeight[last] < node.height + organization.verticalPadding) organization.rowHeight[last] = node.height + organization.verticalPadding;\n\n var finalTotal = organization.rowHeight[longest] + organization.rowHeight[last];\n organization.height += finalTotal - prevTotal;\n\n this.shiftToLastRow(organization);\n }\n};\n\nCoSELayout.prototype.tilingPreLayout = function () {\n if (CoSEConstants.TILE) {\n // Find zero degree nodes and create a compound for each level\n this.groupZeroDegreeMembers();\n // Tile and clear children of each compound\n this.clearCompounds();\n // Separately tile and clear zero degree nodes for each level\n this.clearZeroDegreeMembers();\n }\n};\n\nCoSELayout.prototype.tilingPostLayout = function () {\n if (CoSEConstants.TILE) {\n this.repopulateZeroDegreeMembers();\n this.repopulateCompounds();\n }\n};\n\n// -----------------------------------------------------------------------------\n// Section: Tree Reduction methods\n// -----------------------------------------------------------------------------\n// Reduce trees \nCoSELayout.prototype.reduceTrees = function () {\n var prunedNodesAll = [];\n var containsLeaf = true;\n var node;\n\n while (containsLeaf) {\n var allNodes = this.graphManager.getAllNodes();\n var prunedNodesInStepTemp = [];\n containsLeaf = false;\n\n for (var i = 0; i < allNodes.length; i++) {\n node = allNodes[i];\n if (node.getEdges().length == 1 && !node.getEdges()[0].isInterGraph && node.getChild() == null) {\n prunedNodesInStepTemp.push([node, node.getEdges()[0], node.getOwner()]);\n containsLeaf = true;\n }\n }\n if (containsLeaf == true) {\n var prunedNodesInStep = [];\n for (var j = 0; j < prunedNodesInStepTemp.length; j++) {\n if (prunedNodesInStepTemp[j][0].getEdges().length == 1) {\n prunedNodesInStep.push(prunedNodesInStepTemp[j]);\n prunedNodesInStepTemp[j][0].getOwner().remove(prunedNodesInStepTemp[j][0]);\n }\n }\n prunedNodesAll.push(prunedNodesInStep);\n this.graphManager.resetAllNodes();\n this.graphManager.resetAllEdges();\n }\n }\n this.prunedNodesAll = prunedNodesAll;\n};\n\n// Grow tree one step \nCoSELayout.prototype.growTree = function (prunedNodesAll) {\n var lengthOfPrunedNodesInStep = prunedNodesAll.length;\n var prunedNodesInStep = prunedNodesAll[lengthOfPrunedNodesInStep - 1];\n\n var nodeData;\n for (var i = 0; i < prunedNodesInStep.length; i++) {\n nodeData = prunedNodesInStep[i];\n\n this.findPlaceforPrunedNode(nodeData);\n\n nodeData[2].add(nodeData[0]);\n nodeData[2].add(nodeData[1], nodeData[1].source, nodeData[1].target);\n }\n\n prunedNodesAll.splice(prunedNodesAll.length - 1, 1);\n this.graphManager.resetAllNodes();\n this.graphManager.resetAllEdges();\n};\n\n// Find an appropriate position to replace pruned node, this method can be improved\nCoSELayout.prototype.findPlaceforPrunedNode = function (nodeData) {\n\n var gridForPrunedNode;\n var nodeToConnect;\n var prunedNode = nodeData[0];\n if (prunedNode == nodeData[1].source) {\n nodeToConnect = nodeData[1].target;\n } else {\n nodeToConnect = nodeData[1].source;\n }\n var startGridX = nodeToConnect.startX;\n var finishGridX = nodeToConnect.finishX;\n var startGridY = nodeToConnect.startY;\n var finishGridY = nodeToConnect.finishY;\n\n var upNodeCount = 0;\n var downNodeCount = 0;\n var rightNodeCount = 0;\n var leftNodeCount = 0;\n var controlRegions = [upNodeCount, rightNodeCount, downNodeCount, leftNodeCount];\n\n if (startGridY > 0) {\n for (var i = startGridX; i <= finishGridX; i++) {\n controlRegions[0] += this.grid[i][startGridY - 1].length + this.grid[i][startGridY].length - 1;\n }\n }\n if (finishGridX < this.grid.length - 1) {\n for (var i = startGridY; i <= finishGridY; i++) {\n controlRegions[1] += this.grid[finishGridX + 1][i].length + this.grid[finishGridX][i].length - 1;\n }\n }\n if (finishGridY < this.grid[0].length - 1) {\n for (var i = startGridX; i <= finishGridX; i++) {\n controlRegions[2] += this.grid[i][finishGridY + 1].length + this.grid[i][finishGridY].length - 1;\n }\n }\n if (startGridX > 0) {\n for (var i = startGridY; i <= finishGridY; i++) {\n controlRegions[3] += this.grid[startGridX - 1][i].length + this.grid[startGridX][i].length - 1;\n }\n }\n var min = Integer.MAX_VALUE;\n var minCount;\n var minIndex;\n for (var j = 0; j < controlRegions.length; j++) {\n if (controlRegions[j] < min) {\n min = controlRegions[j];\n minCount = 1;\n minIndex = j;\n } else if (controlRegions[j] == min) {\n minCount++;\n }\n }\n\n if (minCount == 3 && min == 0) {\n if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[2] == 0) {\n gridForPrunedNode = 1;\n } else if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[3] == 0) {\n gridForPrunedNode = 0;\n } else if (controlRegions[0] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {\n gridForPrunedNode = 3;\n } else if (controlRegions[1] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {\n gridForPrunedNode = 2;\n }\n } else if (minCount == 2 && min == 0) {\n var random = Math.floor(Math.random() * 2);\n if (controlRegions[0] == 0 && controlRegions[1] == 0) {\n ;\n if (random == 0) {\n gridForPrunedNode = 0;\n } else {\n gridForPrunedNode = 1;\n }\n } else if (controlRegions[0] == 0 && controlRegions[2] == 0) {\n if (random == 0) {\n gridForPrunedNode = 0;\n } else {\n gridForPrunedNode = 2;\n }\n } else if (controlRegions[0] == 0 && controlRegions[3] == 0) {\n if (random == 0) {\n gridForPrunedNode = 0;\n } else {\n gridForPrunedNode = 3;\n }\n } else if (controlRegions[1] == 0 && controlRegions[2] == 0) {\n if (random == 0) {\n gridForPrunedNode = 1;\n } else {\n gridForPrunedNode = 2;\n }\n } else if (controlRegions[1] == 0 && controlRegions[3] == 0) {\n if (random == 0) {\n gridForPrunedNode = 1;\n } else {\n gridForPrunedNode = 3;\n }\n } else {\n if (random == 0) {\n gridForPrunedNode = 2;\n } else {\n gridForPrunedNode = 3;\n }\n }\n } else if (minCount == 4 && min == 0) {\n var random = Math.floor(Math.random() * 4);\n gridForPrunedNode = random;\n } else {\n gridForPrunedNode = minIndex;\n }\n\n if (gridForPrunedNode == 0) {\n prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() - nodeToConnect.getHeight() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getHeight() / 2);\n } else if (gridForPrunedNode == 1) {\n prunedNode.setCenter(nodeToConnect.getCenterX() + nodeToConnect.getWidth() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getWidth() / 2, nodeToConnect.getCenterY());\n } else if (gridForPrunedNode == 2) {\n prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() + nodeToConnect.getHeight() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getHeight() / 2);\n } else {\n prunedNode.setCenter(nodeToConnect.getCenterX() - nodeToConnect.getWidth() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getWidth() / 2, nodeToConnect.getCenterY());\n }\n};\n\nmodule.exports = CoSELayout;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar coseBase = {};\n\ncoseBase.layoutBase = __webpack_require__(0);\ncoseBase.CoSEConstants = __webpack_require__(1);\ncoseBase.CoSEEdge = __webpack_require__(2);\ncoseBase.CoSEGraph = __webpack_require__(3);\ncoseBase.CoSEGraphManager = __webpack_require__(4);\ncoseBase.CoSELayout = __webpack_require__(6);\ncoseBase.CoSENode = __webpack_require__(5);\n\nmodule.exports = coseBase;\n\n/***/ })\n/******/ ]);\n});", "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"cose-base\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"cose-base\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"cytoscapeCoseBilkent\"] = factory(require(\"cose-base\"));\n\telse\n\t\troot[\"cytoscapeCoseBilkent\"] = factory(root[\"coseBase\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 1);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports) {\n\nmodule.exports = __WEBPACK_EXTERNAL_MODULE_0__;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LayoutConstants = __webpack_require__(0).layoutBase.LayoutConstants;\nvar FDLayoutConstants = __webpack_require__(0).layoutBase.FDLayoutConstants;\nvar CoSEConstants = __webpack_require__(0).CoSEConstants;\nvar CoSELayout = __webpack_require__(0).CoSELayout;\nvar CoSENode = __webpack_require__(0).CoSENode;\nvar PointD = __webpack_require__(0).layoutBase.PointD;\nvar DimensionD = __webpack_require__(0).layoutBase.DimensionD;\n\nvar defaults = {\n // Called on `layoutready`\n ready: function ready() {},\n // Called on `layoutstop`\n stop: function stop() {},\n // 'draft', 'default' or 'proof\" \n // - 'draft' fast cooling rate \n // - 'default' moderate cooling rate \n // - \"proof\" slow cooling rate\n quality: 'default',\n // include labels in node dimensions\n nodeDimensionsIncludeLabels: false,\n // number of ticks per frame; higher is faster but more jerky\n refresh: 30,\n // Whether to fit the network view after when done\n fit: true,\n // Padding on fit\n padding: 10,\n // Whether to enable incremental mode\n randomize: true,\n // Node repulsion (non overlapping) multiplier\n nodeRepulsion: 4500,\n // Ideal edge (non nested) length\n idealEdgeLength: 50,\n // Divisor to compute edge forces\n edgeElasticity: 0.45,\n // Nesting factor (multiplier) to compute ideal edge length for nested edges\n nestingFactor: 0.1,\n // Gravity force (constant)\n gravity: 0.25,\n // Maximum number of iterations to perform\n numIter: 2500,\n // For enabling tiling\n tile: true,\n // Type of layout animation. The option set is {'during', 'end', false}\n animate: 'end',\n // Duration for animate:end\n animationDuration: 500,\n // Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)\n tilingPaddingVertical: 10,\n // Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function)\n tilingPaddingHorizontal: 10,\n // Gravity range (constant) for compounds\n gravityRangeCompound: 1.5,\n // Gravity force (constant) for compounds\n gravityCompound: 1.0,\n // Gravity range (constant)\n gravityRange: 3.8,\n // Initial cooling factor for incremental layout\n initialEnergyOnIncremental: 0.5\n};\n\nfunction extend(defaults, options) {\n var obj = {};\n\n for (var i in defaults) {\n obj[i] = defaults[i];\n }\n\n for (var i in options) {\n obj[i] = options[i];\n }\n\n return obj;\n};\n\nfunction _CoSELayout(_options) {\n this.options = extend(defaults, _options);\n getUserOptions(this.options);\n}\n\nvar getUserOptions = function getUserOptions(options) {\n if (options.nodeRepulsion != null) CoSEConstants.DEFAULT_REPULSION_STRENGTH = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = options.nodeRepulsion;\n if (options.idealEdgeLength != null) CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength;\n if (options.edgeElasticity != null) CoSEConstants.DEFAULT_SPRING_STRENGTH = FDLayoutConstants.DEFAULT_SPRING_STRENGTH = options.edgeElasticity;\n if (options.nestingFactor != null) CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor;\n if (options.gravity != null) CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity;\n if (options.numIter != null) CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter;\n if (options.gravityRange != null) CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange;\n if (options.gravityCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound;\n if (options.gravityRangeCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound;\n if (options.initialEnergyOnIncremental != null) CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental;\n\n if (options.quality == 'draft') LayoutConstants.QUALITY = 0;else if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 1;\n\n CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels;\n CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = !options.randomize;\n CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate;\n CoSEConstants.TILE = options.tile;\n CoSEConstants.TILING_PADDING_VERTICAL = typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical;\n CoSEConstants.TILING_PADDING_HORIZONTAL = typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal;\n};\n\n_CoSELayout.prototype.run = function () {\n var ready;\n var frameId;\n var options = this.options;\n var idToLNode = this.idToLNode = {};\n var layout = this.layout = new CoSELayout();\n var self = this;\n\n self.stopped = false;\n\n this.cy = this.options.cy;\n\n this.cy.trigger({ type: 'layoutstart', layout: this });\n\n var gm = layout.newGraphManager();\n this.gm = gm;\n\n var nodes = this.options.eles.nodes();\n var edges = this.options.eles.edges();\n\n this.root = gm.addRoot();\n this.processChildrenList(this.root, this.getTopMostNodes(nodes), layout);\n\n for (var i = 0; i < edges.length; i++) {\n var edge = edges[i];\n var sourceNode = this.idToLNode[edge.data(\"source\")];\n var targetNode = this.idToLNode[edge.data(\"target\")];\n if (sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) {\n var e1 = gm.add(layout.newEdge(), sourceNode, targetNode);\n e1.id = edge.id();\n }\n }\n\n var getPositions = function getPositions(ele, i) {\n if (typeof ele === \"number\") {\n ele = i;\n }\n var theId = ele.data('id');\n var lNode = self.idToLNode[theId];\n\n return {\n x: lNode.getRect().getCenterX(),\n y: lNode.getRect().getCenterY()\n };\n };\n\n /*\n * Reposition nodes in iterations animatedly\n */\n var iterateAnimated = function iterateAnimated() {\n // Thigs to perform after nodes are repositioned on screen\n var afterReposition = function afterReposition() {\n if (options.fit) {\n options.cy.fit(options.eles, options.padding);\n }\n\n if (!ready) {\n ready = true;\n self.cy.one('layoutready', options.ready);\n self.cy.trigger({ type: 'layoutready', layout: self });\n }\n };\n\n var ticksPerFrame = self.options.refresh;\n var isDone;\n\n for (var i = 0; i < ticksPerFrame && !isDone; i++) {\n isDone = self.stopped || self.layout.tick();\n }\n\n // If layout is done\n if (isDone) {\n // If the layout is not a sublayout and it is successful perform post layout.\n if (layout.checkLayoutSuccess() && !layout.isSubLayout) {\n layout.doPostLayout();\n }\n\n // If layout has a tilingPostLayout function property call it.\n if (layout.tilingPostLayout) {\n layout.tilingPostLayout();\n }\n\n layout.isLayoutFinished = true;\n\n self.options.eles.nodes().positions(getPositions);\n\n afterReposition();\n\n // trigger layoutstop when the layout stops (e.g. finishes)\n self.cy.one('layoutstop', self.options.stop);\n self.cy.trigger({ type: 'layoutstop', layout: self });\n\n if (frameId) {\n cancelAnimationFrame(frameId);\n }\n\n ready = false;\n return;\n }\n\n var animationData = self.layout.getPositionsData(); // Get positions of layout nodes note that all nodes may not be layout nodes because of tiling\n\n // Position nodes, for the nodes whose id does not included in data (because they are removed from their parents and included in dummy compounds)\n // use position of their ancestors or dummy ancestors\n options.eles.nodes().positions(function (ele, i) {\n if (typeof ele === \"number\") {\n ele = i;\n }\n // If ele is a compound node, then its position will be defined by its children\n if (!ele.isParent()) {\n var theId = ele.id();\n var pNode = animationData[theId];\n var temp = ele;\n // If pNode is undefined search until finding position data of its first ancestor (It may be dummy as well)\n while (pNode == null) {\n pNode = animationData[temp.data('parent')] || animationData['DummyCompound_' + temp.data('parent')];\n animationData[theId] = pNode;\n temp = temp.parent()[0];\n if (temp == undefined) {\n break;\n }\n }\n if (pNode != null) {\n return {\n x: pNode.x,\n y: pNode.y\n };\n } else {\n return {\n x: ele.position('x'),\n y: ele.position('y')\n };\n }\n }\n });\n\n afterReposition();\n\n frameId = requestAnimationFrame(iterateAnimated);\n };\n\n /*\n * Listen 'layoutstarted' event and start animated iteration if animate option is 'during'\n */\n layout.addListener('layoutstarted', function () {\n if (self.options.animate === 'during') {\n frameId = requestAnimationFrame(iterateAnimated);\n }\n });\n\n layout.runLayout(); // Run cose layout\n\n /*\n * If animate option is not 'during' ('end' or false) perform these here (If it is 'during' similar things are already performed)\n */\n if (this.options.animate !== \"during\") {\n self.options.eles.nodes().not(\":parent\").layoutPositions(self, self.options, getPositions); // Use layout positions to reposition the nodes it considers the options parameter\n ready = false;\n }\n\n return this; // chaining\n};\n\n//Get the top most ones of a list of nodes\n_CoSELayout.prototype.getTopMostNodes = function (nodes) {\n var nodesMap = {};\n for (var i = 0; i < nodes.length; i++) {\n nodesMap[nodes[i].id()] = true;\n }\n var roots = nodes.filter(function (ele, i) {\n if (typeof ele === \"number\") {\n ele = i;\n }\n var parent = ele.parent()[0];\n while (parent != null) {\n if (nodesMap[parent.id()]) {\n return false;\n }\n parent = parent.parent()[0];\n }\n return true;\n });\n\n return roots;\n};\n\n_CoSELayout.prototype.processChildrenList = function (parent, children, layout) {\n var size = children.length;\n for (var i = 0; i < size; i++) {\n var theChild = children[i];\n var children_of_children = theChild.children();\n var theNode;\n\n var dimensions = theChild.layoutDimensions({\n nodeDimensionsIncludeLabels: this.options.nodeDimensionsIncludeLabels\n });\n\n if (theChild.outerWidth() != null && theChild.outerHeight() != null) {\n theNode = parent.add(new CoSENode(layout.graphManager, new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));\n } else {\n theNode = parent.add(new CoSENode(this.graphManager));\n }\n // Attach id to the layout node\n theNode.id = theChild.data(\"id\");\n // Attach the paddings of cy node to layout node\n theNode.paddingLeft = parseInt(theChild.css('padding'));\n theNode.paddingTop = parseInt(theChild.css('padding'));\n theNode.paddingRight = parseInt(theChild.css('padding'));\n theNode.paddingBottom = parseInt(theChild.css('padding'));\n\n //Attach the label properties to compound if labels will be included in node dimensions \n if (this.options.nodeDimensionsIncludeLabels) {\n if (theChild.isParent()) {\n var labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false }).w;\n var labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false }).h;\n var labelPos = theChild.css(\"text-halign\");\n theNode.labelWidth = labelWidth;\n theNode.labelHeight = labelHeight;\n theNode.labelPos = labelPos;\n }\n }\n\n // Map the layout node\n this.idToLNode[theChild.data(\"id\")] = theNode;\n\n if (isNaN(theNode.rect.x)) {\n theNode.rect.x = 0;\n }\n\n if (isNaN(theNode.rect.y)) {\n theNode.rect.y = 0;\n }\n\n if (children_of_children != null && children_of_children.length > 0) {\n var theNewGraph;\n theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode);\n this.processChildrenList(theNewGraph, children_of_children, layout);\n }\n }\n};\n\n/**\n * @brief : called on continuous layouts to stop them before they finish\n */\n_CoSELayout.prototype.stop = function () {\n this.stopped = true;\n\n return this; // chaining\n};\n\nvar register = function register(cytoscape) {\n // var Layout = getLayout( cytoscape );\n\n cytoscape('layout', 'cose-bilkent', _CoSELayout);\n};\n\n// auto reg for globals\nif (typeof cytoscape !== 'undefined') {\n register(cytoscape);\n}\n\nmodule.exports = register;\n\n/***/ })\n/******/ ]);\n});", "import {\n createText\n} from \"./chunk-5N55DQE6.mjs\";\nimport {\n parseFontSize\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n selectSvgElement\n} from \"./chunk-F2XFN3BY.mjs\";\nimport {\n __name,\n defaultConfig_default,\n getConfig2 as getConfig,\n log,\n sanitizeText,\n setupGraphViewbox\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/mindmap/parser/mindmap.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 4], $V1 = [1, 13], $V2 = [1, 12], $V3 = [1, 15], $V4 = [1, 16], $V5 = [1, 20], $V6 = [1, 19], $V7 = [6, 7, 8], $V8 = [1, 26], $V9 = [1, 24], $Va = [1, 25], $Vb = [6, 7, 11], $Vc = [1, 6, 13, 15, 16, 19, 22], $Vd = [1, 33], $Ve = [1, 34], $Vf = [1, 6, 7, 11, 13, 15, 16, 19, 22];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"mindMap\": 4, \"spaceLines\": 5, \"SPACELINE\": 6, \"NL\": 7, \"MINDMAP\": 8, \"document\": 9, \"stop\": 10, \"EOF\": 11, \"statement\": 12, \"SPACELIST\": 13, \"node\": 14, \"ICON\": 15, \"CLASS\": 16, \"nodeWithId\": 17, \"nodeWithoutId\": 18, \"NODE_DSTART\": 19, \"NODE_DESCR\": 20, \"NODE_DEND\": 21, \"NODE_ID\": 22, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 6: \"SPACELINE\", 7: \"NL\", 8: \"MINDMAP\", 11: \"EOF\", 13: \"SPACELIST\", 15: \"ICON\", 16: \"CLASS\", 19: \"NODE_DSTART\", 20: \"NODE_DESCR\", 21: \"NODE_DEND\", 22: \"NODE_ID\" },\n productions_: [0, [3, 1], [3, 2], [5, 1], [5, 2], [5, 2], [4, 2], [4, 3], [10, 1], [10, 1], [10, 1], [10, 2], [10, 2], [9, 3], [9, 2], [12, 2], [12, 2], [12, 2], [12, 1], [12, 1], [12, 1], [12, 1], [12, 1], [14, 1], [14, 1], [18, 3], [17, 1], [17, 4]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 6:\n case 7:\n return yy;\n break;\n case 8:\n yy.getLogger().trace(\"Stop NL \");\n break;\n case 9:\n yy.getLogger().trace(\"Stop EOF \");\n break;\n case 11:\n yy.getLogger().trace(\"Stop NL2 \");\n break;\n case 12:\n yy.getLogger().trace(\"Stop EOF2 \");\n break;\n case 15:\n yy.getLogger().info(\"Node: \", $$[$0].id);\n yy.addNode($$[$0 - 1].length, $$[$0].id, $$[$0].descr, $$[$0].type);\n break;\n case 16:\n yy.getLogger().trace(\"Icon: \", $$[$0]);\n yy.decorateNode({ icon: $$[$0] });\n break;\n case 17:\n case 21:\n yy.decorateNode({ class: $$[$0] });\n break;\n case 18:\n yy.getLogger().trace(\"SPACELIST\");\n break;\n case 19:\n yy.getLogger().trace(\"Node: \", $$[$0].id);\n yy.addNode(0, $$[$0].id, $$[$0].descr, $$[$0].type);\n break;\n case 20:\n yy.decorateNode({ icon: $$[$0] });\n break;\n case 25:\n yy.getLogger().trace(\"node found ..\", $$[$0 - 2]);\n this.$ = { id: $$[$0 - 1], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) };\n break;\n case 26:\n this.$ = { id: $$[$0], descr: $$[$0], type: yy.nodeType.DEFAULT };\n break;\n case 27:\n yy.getLogger().trace(\"node found ..\", $$[$0 - 3]);\n this.$ = { id: $$[$0 - 3], descr: $$[$0 - 1], type: yy.getType($$[$0 - 2], $$[$0]) };\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: 2, 5: 3, 6: [1, 5], 8: $V0 }, { 1: [3] }, { 1: [2, 1] }, { 4: 6, 6: [1, 7], 7: [1, 8], 8: $V0 }, { 6: $V1, 7: [1, 10], 9: 9, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($V7, [2, 3]), { 1: [2, 2] }, o($V7, [2, 4]), o($V7, [2, 5]), { 1: [2, 6], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V1, 9: 22, 12: 11, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, { 6: $V8, 7: $V9, 10: 23, 11: $Va }, o($Vb, [2, 22], { 17: 17, 18: 18, 14: 27, 15: [1, 28], 16: [1, 29], 19: $V5, 22: $V6 }), o($Vb, [2, 18]), o($Vb, [2, 19]), o($Vb, [2, 20]), o($Vb, [2, 21]), o($Vb, [2, 23]), o($Vb, [2, 24]), o($Vb, [2, 26], { 19: [1, 30] }), { 20: [1, 31] }, { 6: $V8, 7: $V9, 10: 32, 11: $Va }, { 1: [2, 7], 6: $V1, 12: 21, 13: $V2, 14: 14, 15: $V3, 16: $V4, 17: 17, 18: 18, 19: $V5, 22: $V6 }, o($Vc, [2, 14], { 7: $Vd, 11: $Ve }), o($Vf, [2, 8]), o($Vf, [2, 9]), o($Vf, [2, 10]), o($Vb, [2, 15]), o($Vb, [2, 16]), o($Vb, [2, 17]), { 20: [1, 35] }, { 21: [1, 36] }, o($Vc, [2, 13], { 7: $Vd, 11: $Ve }), o($Vf, [2, 11]), o($Vf, [2, 12]), { 21: [1, 37] }, o($Vb, [2, 25]), o($Vb, [2, 27])],\n defaultActions: { 2: [2, 1], 6: [2, 2] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n yy.getLogger().trace(\"Found comment\", yy_.yytext);\n return 6;\n break;\n case 1:\n return 8;\n break;\n case 2:\n this.begin(\"CLASS\");\n break;\n case 3:\n this.popState();\n return 16;\n break;\n case 4:\n this.popState();\n break;\n case 5:\n yy.getLogger().trace(\"Begin icon\");\n this.begin(\"ICON\");\n break;\n case 6:\n yy.getLogger().trace(\"SPACELINE\");\n return 6;\n break;\n case 7:\n return 7;\n break;\n case 8:\n return 15;\n break;\n case 9:\n yy.getLogger().trace(\"end icon\");\n this.popState();\n break;\n case 10:\n yy.getLogger().trace(\"Exploding node\");\n this.begin(\"NODE\");\n return 19;\n break;\n case 11:\n yy.getLogger().trace(\"Cloud\");\n this.begin(\"NODE\");\n return 19;\n break;\n case 12:\n yy.getLogger().trace(\"Explosion Bang\");\n this.begin(\"NODE\");\n return 19;\n break;\n case 13:\n yy.getLogger().trace(\"Cloud Bang\");\n this.begin(\"NODE\");\n return 19;\n break;\n case 14:\n this.begin(\"NODE\");\n return 19;\n break;\n case 15:\n this.begin(\"NODE\");\n return 19;\n break;\n case 16:\n this.begin(\"NODE\");\n return 19;\n break;\n case 17:\n this.begin(\"NODE\");\n return 19;\n break;\n case 18:\n return 13;\n break;\n case 19:\n return 22;\n break;\n case 20:\n return 11;\n break;\n case 21:\n this.begin(\"NSTR2\");\n break;\n case 22:\n return \"NODE_DESCR\";\n break;\n case 23:\n this.popState();\n break;\n case 24:\n yy.getLogger().trace(\"Starting NSTR\");\n this.begin(\"NSTR\");\n break;\n case 25:\n yy.getLogger().trace(\"description:\", yy_.yytext);\n return \"NODE_DESCR\";\n break;\n case 26:\n this.popState();\n break;\n case 27:\n this.popState();\n yy.getLogger().trace(\"node end ))\");\n return \"NODE_DEND\";\n break;\n case 28:\n this.popState();\n yy.getLogger().trace(\"node end )\");\n return \"NODE_DEND\";\n break;\n case 29:\n this.popState();\n yy.getLogger().trace(\"node end ...\", yy_.yytext);\n return \"NODE_DEND\";\n break;\n case 30:\n this.popState();\n yy.getLogger().trace(\"node end ((\");\n return \"NODE_DEND\";\n break;\n case 31:\n this.popState();\n yy.getLogger().trace(\"node end (-\");\n return \"NODE_DEND\";\n break;\n case 32:\n this.popState();\n yy.getLogger().trace(\"node end (-\");\n return \"NODE_DEND\";\n break;\n case 33:\n this.popState();\n yy.getLogger().trace(\"node end ((\");\n return \"NODE_DEND\";\n break;\n case 34:\n this.popState();\n yy.getLogger().trace(\"node end ((\");\n return \"NODE_DEND\";\n break;\n case 35:\n yy.getLogger().trace(\"Long description:\", yy_.yytext);\n return 20;\n break;\n case 36:\n yy.getLogger().trace(\"Long description:\", yy_.yytext);\n return 20;\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:\\s*%%.*)/i, /^(?:mindmap\\b)/i, /^(?::::)/i, /^(?:.+)/i, /^(?:\\n)/i, /^(?:::icon\\()/i, /^(?:[\\s]+[\\n])/i, /^(?:[\\n]+)/i, /^(?:[^\\)]+)/i, /^(?:\\))/i, /^(?:-\\))/i, /^(?:\\(-)/i, /^(?:\\)\\))/i, /^(?:\\))/i, /^(?:\\(\\()/i, /^(?:\\{\\{)/i, /^(?:\\()/i, /^(?:\\[)/i, /^(?:[\\s]+)/i, /^(?:[^\\(\\[\\n\\)\\{\\}]+)/i, /^(?:$)/i, /^(?:[\"][`])/i, /^(?:[^`\"]+)/i, /^(?:[`][\"])/i, /^(?:[\"])/i, /^(?:[^\"]+)/i, /^(?:[\"])/i, /^(?:[\\)]\\))/i, /^(?:[\\)])/i, /^(?:[\\]])/i, /^(?:\\}\\})/i, /^(?:\\(-)/i, /^(?:-\\))/i, /^(?:\\(\\()/i, /^(?:\\()/i, /^(?:[^\\)\\]\\(\\}]+)/i, /^(?:.+(?!\\(\\())/i],\n conditions: { \"CLASS\": { \"rules\": [3, 4], \"inclusive\": false }, \"ICON\": { \"rules\": [8, 9], \"inclusive\": false }, \"NSTR2\": { \"rules\": [22, 23], \"inclusive\": false }, \"NSTR\": { \"rules\": [25, 26], \"inclusive\": false }, \"NODE\": { \"rules\": [21, 24, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 2, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar mindmap_default = parser;\n\n// src/diagrams/mindmap/mindmapDb.ts\nvar nodes = [];\nvar cnt = 0;\nvar elements = {};\nvar clear = /* @__PURE__ */ __name(() => {\n nodes = [];\n cnt = 0;\n elements = {};\n}, \"clear\");\nvar getParent = /* @__PURE__ */ __name(function(level) {\n for (let i = nodes.length - 1; i >= 0; i--) {\n if (nodes[i].level < level) {\n return nodes[i];\n }\n }\n return null;\n}, \"getParent\");\nvar getMindmap = /* @__PURE__ */ __name(() => {\n return nodes.length > 0 ? nodes[0] : null;\n}, \"getMindmap\");\nvar addNode = /* @__PURE__ */ __name((level, id, descr, type) => {\n log.info(\"addNode\", level, id, descr, type);\n const conf = getConfig();\n let padding = conf.mindmap?.padding ?? defaultConfig_default.mindmap.padding;\n switch (type) {\n case nodeType.ROUNDED_RECT:\n case nodeType.RECT:\n case nodeType.HEXAGON:\n padding *= 2;\n }\n const node = {\n id: cnt++,\n nodeId: sanitizeText(id, conf),\n level,\n descr: sanitizeText(descr, conf),\n type,\n children: [],\n width: conf.mindmap?.maxNodeWidth ?? defaultConfig_default.mindmap.maxNodeWidth,\n padding\n };\n const parent = getParent(level);\n if (parent) {\n parent.children.push(node);\n nodes.push(node);\n } else {\n if (nodes.length === 0) {\n nodes.push(node);\n } else {\n throw new Error(\n 'There can be only one root. No parent could be found for (\"' + node.descr + '\")'\n );\n }\n }\n}, \"addNode\");\nvar nodeType = {\n DEFAULT: 0,\n NO_BORDER: 0,\n ROUNDED_RECT: 1,\n RECT: 2,\n CIRCLE: 3,\n CLOUD: 4,\n BANG: 5,\n HEXAGON: 6\n};\nvar getType = /* @__PURE__ */ __name((startStr, endStr) => {\n log.debug(\"In get type\", startStr, endStr);\n switch (startStr) {\n case \"[\":\n return nodeType.RECT;\n case \"(\":\n return endStr === \")\" ? nodeType.ROUNDED_RECT : nodeType.CLOUD;\n case \"((\":\n return nodeType.CIRCLE;\n case \")\":\n return nodeType.CLOUD;\n case \"))\":\n return nodeType.BANG;\n case \"{{\":\n return nodeType.HEXAGON;\n default:\n return nodeType.DEFAULT;\n }\n}, \"getType\");\nvar setElementForId = /* @__PURE__ */ __name((id, element) => {\n elements[id] = element;\n}, \"setElementForId\");\nvar decorateNode = /* @__PURE__ */ __name((decoration) => {\n if (!decoration) {\n return;\n }\n const config = getConfig();\n const node = nodes[nodes.length - 1];\n if (decoration.icon) {\n node.icon = sanitizeText(decoration.icon, config);\n }\n if (decoration.class) {\n node.class = sanitizeText(decoration.class, config);\n }\n}, \"decorateNode\");\nvar type2Str = /* @__PURE__ */ __name((type) => {\n switch (type) {\n case nodeType.DEFAULT:\n return \"no-border\";\n case nodeType.RECT:\n return \"rect\";\n case nodeType.ROUNDED_RECT:\n return \"rounded-rect\";\n case nodeType.CIRCLE:\n return \"circle\";\n case nodeType.CLOUD:\n return \"cloud\";\n case nodeType.BANG:\n return \"bang\";\n case nodeType.HEXAGON:\n return \"hexgon\";\n default:\n return \"no-border\";\n }\n}, \"type2Str\");\nvar getLogger = /* @__PURE__ */ __name(() => log, \"getLogger\");\nvar getElementById = /* @__PURE__ */ __name((id) => elements[id], \"getElementById\");\nvar db = {\n clear,\n addNode,\n getMindmap,\n nodeType,\n getType,\n setElementForId,\n decorateNode,\n type2Str,\n getLogger,\n getElementById\n};\nvar mindmapDb_default = db;\n\n// src/diagrams/mindmap/mindmapRenderer.ts\nimport cytoscape from \"cytoscape\";\nimport coseBilkent from \"cytoscape-cose-bilkent\";\nimport { select } from \"d3\";\n\n// src/diagrams/mindmap/svgDraw.ts\nvar MAX_SECTIONS = 12;\nvar defaultBkg = /* @__PURE__ */ __name(function(db2, elem, node, section) {\n const rd = 5;\n elem.append(\"path\").attr(\"id\", \"node-\" + node.id).attr(\"class\", \"node-bkg node-\" + db2.type2Str(node.type)).attr(\n \"d\",\n `M0 ${node.height - rd} v${-node.height + 2 * rd} q0,-5 5,-5 h${node.width - 2 * rd} q5,0 5,5 v${node.height - rd} H0 Z`\n );\n elem.append(\"line\").attr(\"class\", \"node-line-\" + section).attr(\"x1\", 0).attr(\"y1\", node.height).attr(\"x2\", node.width).attr(\"y2\", node.height);\n}, \"defaultBkg\");\nvar rectBkg = /* @__PURE__ */ __name(function(db2, elem, node) {\n elem.append(\"rect\").attr(\"id\", \"node-\" + node.id).attr(\"class\", \"node-bkg node-\" + db2.type2Str(node.type)).attr(\"height\", node.height).attr(\"width\", node.width);\n}, \"rectBkg\");\nvar cloudBkg = /* @__PURE__ */ __name(function(db2, elem, node) {\n const w = node.width;\n const h = node.height;\n const r1 = 0.15 * w;\n const r2 = 0.25 * w;\n const r3 = 0.35 * w;\n const r4 = 0.2 * w;\n elem.append(\"path\").attr(\"id\", \"node-\" + node.id).attr(\"class\", \"node-bkg node-\" + db2.type2Str(node.type)).attr(\n \"d\",\n `M0 0 a${r1},${r1} 0 0,1 ${w * 0.25},${-1 * w * 0.1}\n a${r3},${r3} 1 0,1 ${w * 0.4},${-1 * w * 0.1}\n a${r2},${r2} 1 0,1 ${w * 0.35},${1 * w * 0.2}\n\n a${r1},${r1} 1 0,1 ${w * 0.15},${1 * h * 0.35}\n a${r4},${r4} 1 0,1 ${-1 * w * 0.15},${1 * h * 0.65}\n\n a${r2},${r1} 1 0,1 ${-1 * w * 0.25},${w * 0.15}\n a${r3},${r3} 1 0,1 ${-1 * w * 0.5},${0}\n a${r1},${r1} 1 0,1 ${-1 * w * 0.25},${-1 * w * 0.15}\n\n a${r1},${r1} 1 0,1 ${-1 * w * 0.1},${-1 * h * 0.35}\n a${r4},${r4} 1 0,1 ${w * 0.1},${-1 * h * 0.65}\n\n H0 V0 Z`\n );\n}, \"cloudBkg\");\nvar bangBkg = /* @__PURE__ */ __name(function(db2, elem, node) {\n const w = node.width;\n const h = node.height;\n const r = 0.15 * w;\n elem.append(\"path\").attr(\"id\", \"node-\" + node.id).attr(\"class\", \"node-bkg node-\" + db2.type2Str(node.type)).attr(\n \"d\",\n `M0 0 a${r},${r} 1 0,0 ${w * 0.25},${-1 * h * 0.1}\n a${r},${r} 1 0,0 ${w * 0.25},${0}\n a${r},${r} 1 0,0 ${w * 0.25},${0}\n a${r},${r} 1 0,0 ${w * 0.25},${1 * h * 0.1}\n\n a${r},${r} 1 0,0 ${w * 0.15},${1 * h * 0.33}\n a${r * 0.8},${r * 0.8} 1 0,0 ${0},${1 * h * 0.34}\n a${r},${r} 1 0,0 ${-1 * w * 0.15},${1 * h * 0.33}\n\n a${r},${r} 1 0,0 ${-1 * w * 0.25},${h * 0.15}\n a${r},${r} 1 0,0 ${-1 * w * 0.25},${0}\n a${r},${r} 1 0,0 ${-1 * w * 0.25},${0}\n a${r},${r} 1 0,0 ${-1 * w * 0.25},${-1 * h * 0.15}\n\n a${r},${r} 1 0,0 ${-1 * w * 0.1},${-1 * h * 0.33}\n a${r * 0.8},${r * 0.8} 1 0,0 ${0},${-1 * h * 0.34}\n a${r},${r} 1 0,0 ${w * 0.1},${-1 * h * 0.33}\n\n H0 V0 Z`\n );\n}, \"bangBkg\");\nvar circleBkg = /* @__PURE__ */ __name(function(db2, elem, node) {\n elem.append(\"circle\").attr(\"id\", \"node-\" + node.id).attr(\"class\", \"node-bkg node-\" + db2.type2Str(node.type)).attr(\"r\", node.width / 2);\n}, \"circleBkg\");\nfunction insertPolygonShape(parent, w, h, points, node) {\n return parent.insert(\"polygon\", \":first-child\").attr(\n \"points\",\n points.map(function(d) {\n return d.x + \",\" + d.y;\n }).join(\" \")\n ).attr(\"transform\", \"translate(\" + (node.width - w) / 2 + \", \" + h + \")\");\n}\n__name(insertPolygonShape, \"insertPolygonShape\");\nvar hexagonBkg = /* @__PURE__ */ __name(function(_db, elem, node) {\n const h = node.height;\n const f = 4;\n const m = h / f;\n const w = node.width - node.padding + 2 * m;\n const points = [\n { x: m, y: 0 },\n { x: w - m, y: 0 },\n { x: w, y: -h / 2 },\n { x: w - m, y: -h },\n { x: m, y: -h },\n { x: 0, y: -h / 2 }\n ];\n insertPolygonShape(elem, w, h, points, node);\n}, \"hexagonBkg\");\nvar roundedRectBkg = /* @__PURE__ */ __name(function(db2, elem, node) {\n elem.append(\"rect\").attr(\"id\", \"node-\" + node.id).attr(\"class\", \"node-bkg node-\" + db2.type2Str(node.type)).attr(\"height\", node.height).attr(\"rx\", node.padding).attr(\"ry\", node.padding).attr(\"width\", node.width);\n}, \"roundedRectBkg\");\nvar drawNode = /* @__PURE__ */ __name(async function(db2, elem, node, fullSection, conf) {\n const htmlLabels = conf.htmlLabels;\n const section = fullSection % (MAX_SECTIONS - 1);\n const nodeElem = elem.append(\"g\");\n node.section = section;\n let sectionClass = \"section-\" + section;\n if (section < 0) {\n sectionClass += \" section-root\";\n }\n nodeElem.attr(\"class\", (node.class ? node.class + \" \" : \"\") + \"mindmap-node \" + sectionClass);\n const bkgElem = nodeElem.append(\"g\");\n const textElem = nodeElem.append(\"g\");\n const description = node.descr.replace(/()/g, \"\\n\");\n await createText(\n textElem,\n description,\n {\n useHtmlLabels: htmlLabels,\n width: node.width,\n classes: \"mindmap-node-label\"\n },\n conf\n );\n if (!htmlLabels) {\n textElem.attr(\"dy\", \"1em\").attr(\"alignment-baseline\", \"middle\").attr(\"dominant-baseline\", \"middle\").attr(\"text-anchor\", \"middle\");\n }\n const bbox = textElem.node().getBBox();\n const [fontSize] = parseFontSize(conf.fontSize);\n node.height = bbox.height + fontSize * 1.1 * 0.5 + node.padding;\n node.width = bbox.width + 2 * node.padding;\n if (node.icon) {\n if (node.type === db2.nodeType.CIRCLE) {\n node.height += 50;\n node.width += 50;\n const icon = nodeElem.append(\"foreignObject\").attr(\"height\", \"50px\").attr(\"width\", node.width).attr(\"style\", \"text-align: center;\");\n icon.append(\"div\").attr(\"class\", \"icon-container\").append(\"i\").attr(\"class\", \"node-icon-\" + section + \" \" + node.icon);\n textElem.attr(\n \"transform\",\n \"translate(\" + node.width / 2 + \", \" + (node.height / 2 - 1.5 * node.padding) + \")\"\n );\n } else {\n node.width += 50;\n const orgHeight = node.height;\n node.height = Math.max(orgHeight, 60);\n const heightDiff = Math.abs(node.height - orgHeight);\n const icon = nodeElem.append(\"foreignObject\").attr(\"width\", \"60px\").attr(\"height\", node.height).attr(\"style\", \"text-align: center;margin-top:\" + heightDiff / 2 + \"px;\");\n icon.append(\"div\").attr(\"class\", \"icon-container\").append(\"i\").attr(\"class\", \"node-icon-\" + section + \" \" + node.icon);\n textElem.attr(\n \"transform\",\n \"translate(\" + (25 + node.width / 2) + \", \" + (heightDiff / 2 + node.padding / 2) + \")\"\n );\n }\n } else {\n if (!htmlLabels) {\n const dx = node.width / 2;\n const dy = node.padding / 2;\n textElem.attr(\"transform\", \"translate(\" + dx + \", \" + dy + \")\");\n } else {\n const dx = (node.width - bbox.width) / 2;\n const dy = (node.height - bbox.height) / 2;\n textElem.attr(\"transform\", \"translate(\" + dx + \", \" + dy + \")\");\n }\n }\n switch (node.type) {\n case db2.nodeType.DEFAULT:\n defaultBkg(db2, bkgElem, node, section);\n break;\n case db2.nodeType.ROUNDED_RECT:\n roundedRectBkg(db2, bkgElem, node, section);\n break;\n case db2.nodeType.RECT:\n rectBkg(db2, bkgElem, node, section);\n break;\n case db2.nodeType.CIRCLE:\n bkgElem.attr(\"transform\", \"translate(\" + node.width / 2 + \", \" + +node.height / 2 + \")\");\n circleBkg(db2, bkgElem, node, section);\n break;\n case db2.nodeType.CLOUD:\n cloudBkg(db2, bkgElem, node, section);\n break;\n case db2.nodeType.BANG:\n bangBkg(db2, bkgElem, node, section);\n break;\n case db2.nodeType.HEXAGON:\n hexagonBkg(db2, bkgElem, node, section);\n break;\n }\n db2.setElementForId(node.id, nodeElem);\n return node.height;\n}, \"drawNode\");\nvar positionNode = /* @__PURE__ */ __name(function(db2, node) {\n const nodeElem = db2.getElementById(node.id);\n const x = node.x || 0;\n const y = node.y || 0;\n nodeElem.attr(\"transform\", \"translate(\" + x + \",\" + y + \")\");\n}, \"positionNode\");\n\n// src/diagrams/mindmap/mindmapRenderer.ts\ncytoscape.use(coseBilkent);\nasync function drawNodes(db2, svg, mindmap, section, conf) {\n await drawNode(db2, svg, mindmap, section, conf);\n if (mindmap.children) {\n await Promise.all(\n mindmap.children.map(\n (child, index) => drawNodes(db2, svg, child, section < 0 ? index : section, conf)\n )\n );\n }\n}\n__name(drawNodes, \"drawNodes\");\nfunction drawEdges(edgesEl, cy) {\n cy.edges().map((edge, id) => {\n const data = edge.data();\n if (edge[0]._private.bodyBounds) {\n const bounds = edge[0]._private.rscratch;\n log.trace(\"Edge: \", id, data);\n edgesEl.insert(\"path\").attr(\n \"d\",\n `M ${bounds.startX},${bounds.startY} L ${bounds.midX},${bounds.midY} L${bounds.endX},${bounds.endY} `\n ).attr(\"class\", \"edge section-edge-\" + data.section + \" edge-depth-\" + data.depth);\n }\n });\n}\n__name(drawEdges, \"drawEdges\");\nfunction addNodes(mindmap, cy, conf, level) {\n cy.add({\n group: \"nodes\",\n data: {\n id: mindmap.id.toString(),\n labelText: mindmap.descr,\n height: mindmap.height,\n width: mindmap.width,\n level,\n nodeId: mindmap.id,\n padding: mindmap.padding,\n type: mindmap.type\n },\n position: {\n x: mindmap.x,\n y: mindmap.y\n }\n });\n if (mindmap.children) {\n mindmap.children.forEach((child) => {\n addNodes(child, cy, conf, level + 1);\n cy.add({\n group: \"edges\",\n data: {\n id: `${mindmap.id}_${child.id}`,\n source: mindmap.id,\n target: child.id,\n depth: level,\n section: child.section\n }\n });\n });\n }\n}\n__name(addNodes, \"addNodes\");\nfunction layoutMindmap(node, conf) {\n return new Promise((resolve) => {\n const renderEl = select(\"body\").append(\"div\").attr(\"id\", \"cy\").attr(\"style\", \"display:none\");\n const cy = cytoscape({\n container: document.getElementById(\"cy\"),\n // container to render in\n style: [\n {\n selector: \"edge\",\n style: {\n \"curve-style\": \"bezier\"\n }\n }\n ]\n });\n renderEl.remove();\n addNodes(node, cy, conf, 0);\n cy.nodes().forEach(function(n) {\n n.layoutDimensions = () => {\n const data = n.data();\n return { w: data.width, h: data.height };\n };\n });\n cy.layout({\n name: \"cose-bilkent\",\n // @ts-ignore Types for cose-bilkent are not correct?\n quality: \"proof\",\n styleEnabled: false,\n animate: false\n }).run();\n cy.ready((e) => {\n log.info(\"Ready\", e);\n resolve(cy);\n });\n });\n}\n__name(layoutMindmap, \"layoutMindmap\");\nfunction positionNodes(db2, cy) {\n cy.nodes().map((node, id) => {\n const data = node.data();\n data.x = node.position().x;\n data.y = node.position().y;\n positionNode(db2, data);\n const el = db2.getElementById(data.nodeId);\n log.info(\"Id:\", id, \"Position: (\", node.position().x, \", \", node.position().y, \")\", data);\n el.attr(\n \"transform\",\n `translate(${node.position().x - data.width / 2}, ${node.position().y - data.height / 2})`\n );\n el.attr(\"attr\", `apa-${id})`);\n });\n}\n__name(positionNodes, \"positionNodes\");\nvar draw = /* @__PURE__ */ __name(async (text, id, _version, diagObj) => {\n log.debug(\"Rendering mindmap diagram\\n\" + text);\n const db2 = diagObj.db;\n const mm = db2.getMindmap();\n if (!mm) {\n return;\n }\n const conf = getConfig();\n conf.htmlLabels = false;\n const svg = selectSvgElement(id);\n const edgesElem = svg.append(\"g\");\n edgesElem.attr(\"class\", \"mindmap-edges\");\n const nodesElem = svg.append(\"g\");\n nodesElem.attr(\"class\", \"mindmap-nodes\");\n await drawNodes(db2, nodesElem, mm, -1, conf);\n const cy = await layoutMindmap(mm, conf);\n drawEdges(edgesElem, cy);\n positionNodes(db2, cy);\n setupGraphViewbox(\n void 0,\n svg,\n conf.mindmap?.padding ?? defaultConfig_default.mindmap.padding,\n conf.mindmap?.useMaxWidth ?? defaultConfig_default.mindmap.useMaxWidth\n );\n}, \"draw\");\nvar mindmapRenderer_default = {\n draw\n};\n\n// src/diagrams/mindmap/styles.ts\nimport { darken, lighten, isDark } from \"khroma\";\nvar genSections = /* @__PURE__ */ __name((options) => {\n let sections = \"\";\n for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {\n options[\"lineColor\" + i] = options[\"lineColor\" + i] || options[\"cScaleInv\" + i];\n if (isDark(options[\"lineColor\" + i])) {\n options[\"lineColor\" + i] = lighten(options[\"lineColor\" + i], 20);\n } else {\n options[\"lineColor\" + i] = darken(options[\"lineColor\" + i], 20);\n }\n }\n for (let i = 0; i < options.THEME_COLOR_LIMIT; i++) {\n const sw = \"\" + (17 - 3 * i);\n sections += `\n .section-${i - 1} rect, .section-${i - 1} path, .section-${i - 1} circle, .section-${i - 1} polygon, .section-${i - 1} path {\n fill: ${options[\"cScale\" + i]};\n }\n .section-${i - 1} text {\n fill: ${options[\"cScaleLabel\" + i]};\n }\n .node-icon-${i - 1} {\n font-size: 40px;\n color: ${options[\"cScaleLabel\" + i]};\n }\n .section-edge-${i - 1}{\n stroke: ${options[\"cScale\" + i]};\n }\n .edge-depth-${i - 1}{\n stroke-width: ${sw};\n }\n .section-${i - 1} line {\n stroke: ${options[\"cScaleInv\" + i]} ;\n stroke-width: 3;\n }\n\n .disabled, .disabled circle, .disabled text {\n fill: lightgray;\n }\n .disabled text {\n fill: #efefef;\n }\n `;\n }\n return sections;\n}, \"genSections\");\nvar getStyles = /* @__PURE__ */ __name((options) => `\n .edge {\n stroke-width: 3;\n }\n ${genSections(options)}\n .section-root rect, .section-root path, .section-root circle, .section-root polygon {\n fill: ${options.git0};\n }\n .section-root text {\n fill: ${options.gitBranchLabel0};\n }\n .icon-container {\n height:100%;\n display: flex;\n justify-content: center;\n align-items: center;\n }\n .edge {\n fill: none;\n }\n .mindmap-node-label {\n dy: 1em;\n alignment-baseline: middle;\n text-anchor: middle;\n dominant-baseline: middle;\n text-align: center;\n }\n`, \"getStyles\");\nvar styles_default = getStyles;\n\n// src/diagrams/mindmap/mindmap-definition.ts\nvar diagram = {\n db: mindmapDb_default,\n renderer: mindmapRenderer_default,\n parser: mindmap_default,\n styles: styles_default\n};\nexport {\n diagram\n};\n", "export default function max(values, valueof) {\n let max;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (max < value || (max === undefined && value >= value))) {\n max = value;\n }\n }\n }\n return max;\n}\n", "export default function min(values, valueof) {\n let min;\n if (valueof === undefined) {\n for (const value of values) {\n if (value != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if ((value = valueof(value, ++index, values)) != null\n && (min > value || (min === undefined && value >= value))) {\n min = value;\n }\n }\n }\n return min;\n}\n", "export default function sum(values, valueof) {\n let sum = 0;\n if (valueof === undefined) {\n for (let value of values) {\n if (value = +value) {\n sum += value;\n }\n }\n } else {\n let index = -1;\n for (let value of values) {\n if (value = +valueof(value, ++index, values)) {\n sum += value;\n }\n }\n }\n return sum;\n}\n", "export {default as bisect, bisectRight, bisectLeft, bisectCenter} from \"./bisect.js\";\nexport {default as ascending} from \"./ascending.js\";\nexport {default as bisector} from \"./bisector.js\";\nexport {default as count} from \"./count.js\";\nexport {default as cross} from \"./cross.js\";\nexport {default as cumsum} from \"./cumsum.js\";\nexport {default as descending} from \"./descending.js\";\nexport {default as deviation} from \"./deviation.js\";\nexport {default as extent} from \"./extent.js\";\nexport {Adder, fsum, fcumsum} from \"./fsum.js\";\nexport {default as group, groups, index, indexes, rollup, rollups} from \"./group.js\";\nexport {default as groupSort} from \"./groupSort.js\";\nexport {default as bin, default as histogram} from \"./bin.js\"; // Deprecated; use bin.\nexport {default as thresholdFreedmanDiaconis} from \"./threshold/freedmanDiaconis.js\";\nexport {default as thresholdScott} from \"./threshold/scott.js\";\nexport {default as thresholdSturges} from \"./threshold/sturges.js\";\nexport {default as max} from \"./max.js\";\nexport {default as maxIndex} from \"./maxIndex.js\";\nexport {default as mean} from \"./mean.js\";\nexport {default as median} from \"./median.js\";\nexport {default as merge} from \"./merge.js\";\nexport {default as min} from \"./min.js\";\nexport {default as minIndex} from \"./minIndex.js\";\nexport {default as nice} from \"./nice.js\";\nexport {default as pairs} from \"./pairs.js\";\nexport {default as permute} from \"./permute.js\";\nexport {default as quantile, quantileSorted} from \"./quantile.js\";\nexport {default as quickselect} from \"./quickselect.js\";\nexport {default as range} from \"./range.js\";\nexport {default as least} from \"./least.js\";\nexport {default as leastIndex} from \"./leastIndex.js\";\nexport {default as greatest} from \"./greatest.js\";\nexport {default as greatestIndex} from \"./greatestIndex.js\";\nexport {default as scan} from \"./scan.js\"; // Deprecated; use leastIndex.\nexport {default as shuffle, shuffler} from \"./shuffle.js\";\nexport {default as sum} from \"./sum.js\";\nexport {default as ticks, tickIncrement, tickStep} from \"./ticks.js\";\nexport {default as transpose} from \"./transpose.js\";\nexport {default as variance} from \"./variance.js\";\nexport {default as zip} from \"./zip.js\";\nexport {default as every} from \"./every.js\";\nexport {default as some} from \"./some.js\";\nexport {default as filter} from \"./filter.js\";\nexport {default as map} from \"./map.js\";\nexport {default as reduce} from \"./reduce.js\";\nexport {default as reverse} from \"./reverse.js\";\nexport {default as sort} from \"./sort.js\";\nexport {default as difference} from \"./difference.js\";\nexport {default as disjoint} from \"./disjoint.js\";\nexport {default as intersection} from \"./intersection.js\";\nexport {default as subset} from \"./subset.js\";\nexport {default as superset} from \"./superset.js\";\nexport {default as union} from \"./union.js\";\nexport {InternMap, InternSet} from \"internmap\";\n", "import {min} from \"d3-array\";\n\nfunction targetDepth(d) {\n return d.target.depth;\n}\n\nexport function left(node) {\n return node.depth;\n}\n\nexport function right(node, n) {\n return n - 1 - node.height;\n}\n\nexport function justify(node, n) {\n return node.sourceLinks.length ? node.depth : n - 1;\n}\n\nexport function center(node) {\n return node.targetLinks.length ? node.depth\n : node.sourceLinks.length ? min(node.sourceLinks, targetDepth) - 1\n : 0;\n}\n", "export default function constant(x) {\n return function() {\n return x;\n };\n}\n", "import {max, min, sum} from \"d3-array\";\nimport {justify} from \"./align.js\";\nimport constant from \"./constant.js\";\n\nfunction ascendingSourceBreadth(a, b) {\n return ascendingBreadth(a.source, b.source) || a.index - b.index;\n}\n\nfunction ascendingTargetBreadth(a, b) {\n return ascendingBreadth(a.target, b.target) || a.index - b.index;\n}\n\nfunction ascendingBreadth(a, b) {\n return a.y0 - b.y0;\n}\n\nfunction value(d) {\n return d.value;\n}\n\nfunction defaultId(d) {\n return d.index;\n}\n\nfunction defaultNodes(graph) {\n return graph.nodes;\n}\n\nfunction defaultLinks(graph) {\n return graph.links;\n}\n\nfunction find(nodeById, id) {\n const node = nodeById.get(id);\n if (!node) throw new Error(\"missing: \" + id);\n return node;\n}\n\nfunction computeLinkBreadths({nodes}) {\n for (const node of nodes) {\n let y0 = node.y0;\n let y1 = y0;\n for (const link of node.sourceLinks) {\n link.y0 = y0 + link.width / 2;\n y0 += link.width;\n }\n for (const link of node.targetLinks) {\n link.y1 = y1 + link.width / 2;\n y1 += link.width;\n }\n }\n}\n\nexport default function Sankey() {\n let x0 = 0, y0 = 0, x1 = 1, y1 = 1; // extent\n let dx = 24; // nodeWidth\n let dy = 8, py; // nodePadding\n let id = defaultId;\n let align = justify;\n let sort;\n let linkSort;\n let nodes = defaultNodes;\n let links = defaultLinks;\n let iterations = 6;\n\n function sankey() {\n const graph = {nodes: nodes.apply(null, arguments), links: links.apply(null, arguments)};\n computeNodeLinks(graph);\n computeNodeValues(graph);\n computeNodeDepths(graph);\n computeNodeHeights(graph);\n computeNodeBreadths(graph);\n computeLinkBreadths(graph);\n return graph;\n }\n\n sankey.update = function(graph) {\n computeLinkBreadths(graph);\n return graph;\n };\n\n sankey.nodeId = function(_) {\n return arguments.length ? (id = typeof _ === \"function\" ? _ : constant(_), sankey) : id;\n };\n\n sankey.nodeAlign = function(_) {\n return arguments.length ? (align = typeof _ === \"function\" ? _ : constant(_), sankey) : align;\n };\n\n sankey.nodeSort = function(_) {\n return arguments.length ? (sort = _, sankey) : sort;\n };\n\n sankey.nodeWidth = function(_) {\n return arguments.length ? (dx = +_, sankey) : dx;\n };\n\n sankey.nodePadding = function(_) {\n return arguments.length ? (dy = py = +_, sankey) : dy;\n };\n\n sankey.nodes = function(_) {\n return arguments.length ? (nodes = typeof _ === \"function\" ? _ : constant(_), sankey) : nodes;\n };\n\n sankey.links = function(_) {\n return arguments.length ? (links = typeof _ === \"function\" ? _ : constant(_), sankey) : links;\n };\n\n sankey.linkSort = function(_) {\n return arguments.length ? (linkSort = _, sankey) : linkSort;\n };\n\n sankey.size = function(_) {\n return arguments.length ? (x0 = y0 = 0, x1 = +_[0], y1 = +_[1], sankey) : [x1 - x0, y1 - y0];\n };\n\n sankey.extent = function(_) {\n return arguments.length ? (x0 = +_[0][0], x1 = +_[1][0], y0 = +_[0][1], y1 = +_[1][1], sankey) : [[x0, y0], [x1, y1]];\n };\n\n sankey.iterations = function(_) {\n return arguments.length ? (iterations = +_, sankey) : iterations;\n };\n\n function computeNodeLinks({nodes, links}) {\n for (const [i, node] of nodes.entries()) {\n node.index = i;\n node.sourceLinks = [];\n node.targetLinks = [];\n }\n const nodeById = new Map(nodes.map((d, i) => [id(d, i, nodes), d]));\n for (const [i, link] of links.entries()) {\n link.index = i;\n let {source, target} = link;\n if (typeof source !== \"object\") source = link.source = find(nodeById, source);\n if (typeof target !== \"object\") target = link.target = find(nodeById, target);\n source.sourceLinks.push(link);\n target.targetLinks.push(link);\n }\n if (linkSort != null) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(linkSort);\n targetLinks.sort(linkSort);\n }\n }\n }\n\n function computeNodeValues({nodes}) {\n for (const node of nodes) {\n node.value = node.fixedValue === undefined\n ? Math.max(sum(node.sourceLinks, value), sum(node.targetLinks, value))\n : node.fixedValue;\n }\n }\n\n function computeNodeDepths({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.depth = x;\n for (const {target} of node.sourceLinks) {\n next.add(target);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeHeights({nodes}) {\n const n = nodes.length;\n let current = new Set(nodes);\n let next = new Set;\n let x = 0;\n while (current.size) {\n for (const node of current) {\n node.height = x;\n for (const {source} of node.targetLinks) {\n next.add(source);\n }\n }\n if (++x > n) throw new Error(\"circular link\");\n current = next;\n next = new Set;\n }\n }\n\n function computeNodeLayers({nodes}) {\n const x = max(nodes, d => d.depth) + 1;\n const kx = (x1 - x0 - dx) / (x - 1);\n const columns = new Array(x);\n for (const node of nodes) {\n const i = Math.max(0, Math.min(x - 1, Math.floor(align.call(null, node, x))));\n node.layer = i;\n node.x0 = x0 + i * kx;\n node.x1 = node.x0 + dx;\n if (columns[i]) columns[i].push(node);\n else columns[i] = [node];\n }\n if (sort) for (const column of columns) {\n column.sort(sort);\n }\n return columns;\n }\n\n function initializeNodeBreadths(columns) {\n const ky = min(columns, c => (y1 - y0 - (c.length - 1) * py) / sum(c, value));\n for (const nodes of columns) {\n let y = y0;\n for (const node of nodes) {\n node.y0 = y;\n node.y1 = y + node.value * ky;\n y = node.y1 + py;\n for (const link of node.sourceLinks) {\n link.width = link.value * ky;\n }\n }\n y = (y1 - y + py) / (nodes.length + 1);\n for (let i = 0; i < nodes.length; ++i) {\n const node = nodes[i];\n node.y0 += y * (i + 1);\n node.y1 += y * (i + 1);\n }\n reorderLinks(nodes);\n }\n }\n\n function computeNodeBreadths(graph) {\n const columns = computeNodeLayers(graph);\n py = Math.min(dy, (y1 - y0) / (max(columns, c => c.length) - 1));\n initializeNodeBreadths(columns);\n for (let i = 0; i < iterations; ++i) {\n const alpha = Math.pow(0.99, i);\n const beta = Math.max(1 - alpha, (i + 1) / iterations);\n relaxRightToLeft(columns, alpha, beta);\n relaxLeftToRight(columns, alpha, beta);\n }\n }\n\n // Reposition each node based on its incoming (target) links.\n function relaxLeftToRight(columns, alpha, beta) {\n for (let i = 1, n = columns.length; i < n; ++i) {\n const column = columns[i];\n for (const target of column) {\n let y = 0;\n let w = 0;\n for (const {source, value} of target.targetLinks) {\n let v = value * (target.layer - source.layer);\n y += targetTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - target.y0) * alpha;\n target.y0 += dy;\n target.y1 += dy;\n reorderNodeLinks(target);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n // Reposition each node based on its outgoing (source) links.\n function relaxRightToLeft(columns, alpha, beta) {\n for (let n = columns.length, i = n - 2; i >= 0; --i) {\n const column = columns[i];\n for (const source of column) {\n let y = 0;\n let w = 0;\n for (const {target, value} of source.sourceLinks) {\n let v = value * (target.layer - source.layer);\n y += sourceTop(source, target) * v;\n w += v;\n }\n if (!(w > 0)) continue;\n let dy = (y / w - source.y0) * alpha;\n source.y0 += dy;\n source.y1 += dy;\n reorderNodeLinks(source);\n }\n if (sort === undefined) column.sort(ascendingBreadth);\n resolveCollisions(column, beta);\n }\n }\n\n function resolveCollisions(nodes, alpha) {\n const i = nodes.length >> 1;\n const subject = nodes[i];\n resolveCollisionsBottomToTop(nodes, subject.y0 - py, i - 1, alpha);\n resolveCollisionsTopToBottom(nodes, subject.y1 + py, i + 1, alpha);\n resolveCollisionsBottomToTop(nodes, y1, nodes.length - 1, alpha);\n resolveCollisionsTopToBottom(nodes, y0, 0, alpha);\n }\n\n // Push any overlapping nodes down.\n function resolveCollisionsTopToBottom(nodes, y, i, alpha) {\n for (; i < nodes.length; ++i) {\n const node = nodes[i];\n const dy = (y - node.y0) * alpha;\n if (dy > 1e-6) node.y0 += dy, node.y1 += dy;\n y = node.y1 + py;\n }\n }\n\n // Push any overlapping nodes up.\n function resolveCollisionsBottomToTop(nodes, y, i, alpha) {\n for (; i >= 0; --i) {\n const node = nodes[i];\n const dy = (node.y1 - y) * alpha;\n if (dy > 1e-6) node.y0 -= dy, node.y1 -= dy;\n y = node.y0 - py;\n }\n }\n\n function reorderNodeLinks({sourceLinks, targetLinks}) {\n if (linkSort === undefined) {\n for (const {source: {sourceLinks}} of targetLinks) {\n sourceLinks.sort(ascendingTargetBreadth);\n }\n for (const {target: {targetLinks}} of sourceLinks) {\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n function reorderLinks(nodes) {\n if (linkSort === undefined) {\n for (const {sourceLinks, targetLinks} of nodes) {\n sourceLinks.sort(ascendingTargetBreadth);\n targetLinks.sort(ascendingSourceBreadth);\n }\n }\n }\n\n // Returns the target.y0 that would produce an ideal link from source to target.\n function targetTop(source, target) {\n let y = source.y0 - (source.sourceLinks.length - 1) * py / 2;\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y += width + py;\n }\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y -= width;\n }\n return y;\n }\n\n // Returns the source.y0 that would produce an ideal link from source to target.\n function sourceTop(source, target) {\n let y = target.y0 - (target.targetLinks.length - 1) * py / 2;\n for (const {source: node, width} of target.targetLinks) {\n if (node === source) break;\n y += width + py;\n }\n for (const {target: node, width} of source.sourceLinks) {\n if (node === target) break;\n y -= width;\n }\n return y;\n }\n\n return sankey;\n}\n", "var pi = Math.PI,\n tau = 2 * pi,\n epsilon = 1e-6,\n tauEpsilon = tau - epsilon;\n\nfunction Path() {\n this._x0 = this._y0 = // start of current subpath\n this._x1 = this._y1 = null; // end of current subpath\n this._ = \"\";\n}\n\nfunction path() {\n return new Path;\n}\n\nPath.prototype = path.prototype = {\n constructor: Path,\n moveTo: function(x, y) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y);\n },\n closePath: function() {\n if (this._x1 !== null) {\n this._x1 = this._x0, this._y1 = this._y0;\n this._ += \"Z\";\n }\n },\n lineTo: function(x, y) {\n this._ += \"L\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n quadraticCurveTo: function(x1, y1, x, y) {\n this._ += \"Q\" + (+x1) + \",\" + (+y1) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n bezierCurveTo: function(x1, y1, x2, y2, x, y) {\n this._ += \"C\" + (+x1) + \",\" + (+y1) + \",\" + (+x2) + \",\" + (+y2) + \",\" + (this._x1 = +x) + \",\" + (this._y1 = +y);\n },\n arcTo: function(x1, y1, x2, y2, r) {\n x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r;\n var x0 = this._x1,\n y0 = this._y1,\n x21 = x2 - x1,\n y21 = y2 - y1,\n x01 = x0 - x1,\n y01 = y0 - y1,\n l01_2 = x01 * x01 + y01 * y01;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x1,y1).\n if (this._x1 === null) {\n this._ += \"M\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Or, is (x1,y1) coincident with (x0,y0)? Do nothing.\n else if (!(l01_2 > epsilon));\n\n // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear?\n // Equivalently, is (x1,y1) coincident with (x2,y2)?\n // Or, is the radius zero? Line to (x1,y1).\n else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) {\n this._ += \"L\" + (this._x1 = x1) + \",\" + (this._y1 = y1);\n }\n\n // Otherwise, draw an arc!\n else {\n var x20 = x2 - x0,\n y20 = y2 - y0,\n l21_2 = x21 * x21 + y21 * y21,\n l20_2 = x20 * x20 + y20 * y20,\n l21 = Math.sqrt(l21_2),\n l01 = Math.sqrt(l01_2),\n l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2),\n t01 = l / l01,\n t21 = l / l21;\n\n // If the start tangent is not coincident with (x0,y0), line to.\n if (Math.abs(t01 - 1) > epsilon) {\n this._ += \"L\" + (x1 + t01 * x01) + \",\" + (y1 + t01 * y01);\n }\n\n this._ += \"A\" + r + \",\" + r + \",0,0,\" + (+(y01 * x20 > x01 * y20)) + \",\" + (this._x1 = x1 + t21 * x21) + \",\" + (this._y1 = y1 + t21 * y21);\n }\n },\n arc: function(x, y, r, a0, a1, ccw) {\n x = +x, y = +y, r = +r, ccw = !!ccw;\n var dx = r * Math.cos(a0),\n dy = r * Math.sin(a0),\n x0 = x + dx,\n y0 = y + dy,\n cw = 1 ^ ccw,\n da = ccw ? a0 - a1 : a1 - a0;\n\n // Is the radius negative? Error.\n if (r < 0) throw new Error(\"negative radius: \" + r);\n\n // Is this path empty? Move to (x0,y0).\n if (this._x1 === null) {\n this._ += \"M\" + x0 + \",\" + y0;\n }\n\n // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0).\n else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) {\n this._ += \"L\" + x0 + \",\" + y0;\n }\n\n // Is this arc empty? We\u2019re done.\n if (!r) return;\n\n // Does the angle go the wrong way? Flip the direction.\n if (da < 0) da = da % tau + tau;\n\n // Is this a complete circle? Draw two arcs to complete the circle.\n if (da > tauEpsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (x - dx) + \",\" + (y - dy) + \"A\" + r + \",\" + r + \",0,1,\" + cw + \",\" + (this._x1 = x0) + \",\" + (this._y1 = y0);\n }\n\n // Is this arc non-empty? Draw an arc!\n else if (da > epsilon) {\n this._ += \"A\" + r + \",\" + r + \",0,\" + (+(da >= pi)) + \",\" + cw + \",\" + (this._x1 = x + r * Math.cos(a1)) + \",\" + (this._y1 = y + r * Math.sin(a1));\n }\n },\n rect: function(x, y, w, h) {\n this._ += \"M\" + (this._x0 = this._x1 = +x) + \",\" + (this._y0 = this._y1 = +y) + \"h\" + (+w) + \"v\" + (+h) + \"h\" + (-w) + \"Z\";\n },\n toString: function() {\n return this._;\n }\n};\n\nexport default path;\n", "export {default as path} from \"./path.js\";\n", "export default function(x) {\n return function constant() {\n return x;\n };\n}\n", "export function x(p) {\n return p[0];\n}\n\nexport function y(p) {\n return p[1];\n}\n", "export var slice = Array.prototype.slice;\n", "import {path} from \"d3-path\";\nimport {slice} from \"../array.js\";\nimport constant from \"../constant.js\";\nimport {x as pointX, y as pointY} from \"../point.js\";\nimport pointRadial from \"../pointRadial.js\";\n\nfunction linkSource(d) {\n return d.source;\n}\n\nfunction linkTarget(d) {\n return d.target;\n}\n\nfunction link(curve) {\n var source = linkSource,\n target = linkTarget,\n x = pointX,\n y = pointY,\n context = null;\n\n function link() {\n var buffer, argv = slice.call(arguments), s = source.apply(this, argv), t = target.apply(this, argv);\n if (!context) context = buffer = path();\n curve(context, +x.apply(this, (argv[0] = s, argv)), +y.apply(this, argv), +x.apply(this, (argv[0] = t, argv)), +y.apply(this, argv));\n if (buffer) return context = null, buffer + \"\" || null;\n }\n\n link.source = function(_) {\n return arguments.length ? (source = _, link) : source;\n };\n\n link.target = function(_) {\n return arguments.length ? (target = _, link) : target;\n };\n\n link.x = function(_) {\n return arguments.length ? (x = typeof _ === \"function\" ? _ : constant(+_), link) : x;\n };\n\n link.y = function(_) {\n return arguments.length ? (y = typeof _ === \"function\" ? _ : constant(+_), link) : y;\n };\n\n link.context = function(_) {\n return arguments.length ? ((context = _ == null ? null : _), link) : context;\n };\n\n return link;\n}\n\nfunction curveHorizontal(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0 = (x0 + x1) / 2, y0, x0, y1, x1, y1);\n}\n\nfunction curveVertical(context, x0, y0, x1, y1) {\n context.moveTo(x0, y0);\n context.bezierCurveTo(x0, y0 = (y0 + y1) / 2, x1, y0, x1, y1);\n}\n\nfunction curveRadial(context, x0, y0, x1, y1) {\n var p0 = pointRadial(x0, y0),\n p1 = pointRadial(x0, y0 = (y0 + y1) / 2),\n p2 = pointRadial(x1, y0),\n p3 = pointRadial(x1, y1);\n context.moveTo(p0[0], p0[1]);\n context.bezierCurveTo(p1[0], p1[1], p2[0], p2[1], p3[0], p3[1]);\n}\n\nexport function linkHorizontal() {\n return link(curveHorizontal);\n}\n\nexport function linkVertical() {\n return link(curveVertical);\n}\n\nexport function linkRadial() {\n var l = link(curveRadial);\n l.angle = l.x, delete l.x;\n l.radius = l.y, delete l.y;\n return l;\n}\n", "export {default as arc} from \"./arc.js\";\nexport {default as area} from \"./area.js\";\nexport {default as line} from \"./line.js\";\nexport {default as pie} from \"./pie.js\";\nexport {default as areaRadial, default as radialArea} from \"./areaRadial.js\"; // Note: radialArea is deprecated!\nexport {default as lineRadial, default as radialLine} from \"./lineRadial.js\"; // Note: radialLine is deprecated!\nexport {default as pointRadial} from \"./pointRadial.js\";\nexport {linkHorizontal, linkVertical, linkRadial} from \"./link/index.js\";\n\nexport {default as symbol, symbols} from \"./symbol.js\";\nexport {default as symbolCircle} from \"./symbol/circle.js\";\nexport {default as symbolCross} from \"./symbol/cross.js\";\nexport {default as symbolDiamond} from \"./symbol/diamond.js\";\nexport {default as symbolSquare} from \"./symbol/square.js\";\nexport {default as symbolStar} from \"./symbol/star.js\";\nexport {default as symbolTriangle} from \"./symbol/triangle.js\";\nexport {default as symbolWye} from \"./symbol/wye.js\";\n\nexport {default as curveBasisClosed} from \"./curve/basisClosed.js\";\nexport {default as curveBasisOpen} from \"./curve/basisOpen.js\";\nexport {default as curveBasis} from \"./curve/basis.js\";\nexport {default as curveBundle} from \"./curve/bundle.js\";\nexport {default as curveCardinalClosed} from \"./curve/cardinalClosed.js\";\nexport {default as curveCardinalOpen} from \"./curve/cardinalOpen.js\";\nexport {default as curveCardinal} from \"./curve/cardinal.js\";\nexport {default as curveCatmullRomClosed} from \"./curve/catmullRomClosed.js\";\nexport {default as curveCatmullRomOpen} from \"./curve/catmullRomOpen.js\";\nexport {default as curveCatmullRom} from \"./curve/catmullRom.js\";\nexport {default as curveLinearClosed} from \"./curve/linearClosed.js\";\nexport {default as curveLinear} from \"./curve/linear.js\";\nexport {monotoneX as curveMonotoneX, monotoneY as curveMonotoneY} from \"./curve/monotone.js\";\nexport {default as curveNatural} from \"./curve/natural.js\";\nexport {default as curveStep, stepAfter as curveStepAfter, stepBefore as curveStepBefore} from \"./curve/step.js\";\n\nexport {default as stack} from \"./stack.js\";\nexport {default as stackOffsetExpand} from \"./offset/expand.js\";\nexport {default as stackOffsetDiverging} from \"./offset/diverging.js\";\nexport {default as stackOffsetNone} from \"./offset/none.js\";\nexport {default as stackOffsetSilhouette} from \"./offset/silhouette.js\";\nexport {default as stackOffsetWiggle} from \"./offset/wiggle.js\";\nexport {default as stackOrderAppearance} from \"./order/appearance.js\";\nexport {default as stackOrderAscending} from \"./order/ascending.js\";\nexport {default as stackOrderDescending} from \"./order/descending.js\";\nexport {default as stackOrderInsideOut} from \"./order/insideOut.js\";\nexport {default as stackOrderNone} from \"./order/none.js\";\nexport {default as stackOrderReverse} from \"./order/reverse.js\";\n", "import {linkHorizontal} from \"d3-shape\";\n\nfunction horizontalSource(d) {\n return [d.source.x1, d.y0];\n}\n\nfunction horizontalTarget(d) {\n return [d.target.x0, d.y1];\n}\n\nexport default function() {\n return linkHorizontal()\n .source(horizontalSource)\n .target(horizontalTarget);\n}\n", "export {default as sankey} from \"./sankey.js\";\nexport {center as sankeyCenter, left as sankeyLeft, right as sankeyRight, justify as sankeyJustify} from \"./align.js\";\nexport {default as sankeyLinkHorizontal} from \"./sankeyLinkHorizontal.js\";\n", "import {\n __name,\n clear,\n common_default,\n defaultConfig2 as defaultConfig,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n getDiagramTitle,\n setAccDescription,\n setAccTitle,\n setDiagramTitle,\n setupGraphViewbox\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/sankey/parser/sankey.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 9], $V1 = [1, 10], $V2 = [1, 5, 10, 12];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"start\": 3, \"SANKEY\": 4, \"NEWLINE\": 5, \"csv\": 6, \"opt_eof\": 7, \"record\": 8, \"csv_tail\": 9, \"EOF\": 10, \"field[source]\": 11, \"COMMA\": 12, \"field[target]\": 13, \"field[value]\": 14, \"field\": 15, \"escaped\": 16, \"non_escaped\": 17, \"DQUOTE\": 18, \"ESCAPED_TEXT\": 19, \"NON_ESCAPED_TEXT\": 20, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 4: \"SANKEY\", 5: \"NEWLINE\", 10: \"EOF\", 11: \"field[source]\", 12: \"COMMA\", 13: \"field[target]\", 14: \"field[value]\", 18: \"DQUOTE\", 19: \"ESCAPED_TEXT\", 20: \"NON_ESCAPED_TEXT\" },\n productions_: [0, [3, 4], [6, 2], [9, 2], [9, 0], [7, 1], [7, 0], [8, 5], [15, 1], [15, 1], [16, 3], [17, 1]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 7:\n const source = yy.findOrCreateNode($$[$0 - 4].trim().replaceAll('\"\"', '\"'));\n const target = yy.findOrCreateNode($$[$0 - 2].trim().replaceAll('\"\"', '\"'));\n const value = parseFloat($$[$0].trim());\n yy.addLink(source, target, value);\n break;\n case 8:\n case 9:\n case 11:\n this.$ = $$[$0];\n break;\n case 10:\n this.$ = $$[$0 - 1];\n break;\n }\n }, \"anonymous\"),\n table: [{ 3: 1, 4: [1, 2] }, { 1: [3] }, { 5: [1, 3] }, { 6: 4, 8: 5, 15: 6, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 1: [2, 6], 7: 11, 10: [1, 12] }, o($V1, [2, 4], { 9: 13, 5: [1, 14] }), { 12: [1, 15] }, o($V2, [2, 8]), o($V2, [2, 9]), { 19: [1, 16] }, o($V2, [2, 11]), { 1: [2, 1] }, { 1: [2, 5] }, o($V1, [2, 2]), { 6: 17, 8: 5, 15: 6, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 15: 18, 16: 7, 17: 8, 18: $V0, 20: $V1 }, { 18: [1, 19] }, o($V1, [2, 3]), { 12: [1, 20] }, o($V2, [2, 10]), { 15: 21, 16: 7, 17: 8, 18: $V0, 20: $V1 }, o([1, 5, 10], [2, 7])],\n defaultActions: { 11: [2, 1], 12: [2, 5] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: { \"case-insensitive\": true },\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n this.pushState(\"csv\");\n return 4;\n break;\n case 1:\n return 10;\n break;\n case 2:\n return 5;\n break;\n case 3:\n return 12;\n break;\n case 4:\n this.pushState(\"escaped_text\");\n return 18;\n break;\n case 5:\n return 20;\n break;\n case 6:\n this.popState(\"escaped_text\");\n return 18;\n break;\n case 7:\n return 19;\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:sankey-beta\\b)/i, /^(?:$)/i, /^(?:((\\u000D\\u000A)|(\\u000A)))/i, /^(?:(\\u002C))/i, /^(?:(\\u0022))/i, /^(?:([\\u0020-\\u0021\\u0023-\\u002B\\u002D-\\u007E])*)/i, /^(?:(\\u0022)(?!(\\u0022)))/i, /^(?:(([\\u0020-\\u0021\\u0023-\\u002B\\u002D-\\u007E])|(\\u002C)|(\\u000D)|(\\u000A)|(\\u0022)(\\u0022))*)/i],\n conditions: { \"csv\": { \"rules\": [1, 2, 3, 4, 5, 6, 7], \"inclusive\": false }, \"escaped_text\": { \"rules\": [6, 7], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 2, 3, 4, 5, 6, 7], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar sankey_default = parser;\n\n// src/diagrams/sankey/sankeyDB.ts\nvar links = [];\nvar nodes = [];\nvar nodesMap = /* @__PURE__ */ new Map();\nvar clear2 = /* @__PURE__ */ __name(() => {\n links = [];\n nodes = [];\n nodesMap = /* @__PURE__ */ new Map();\n clear();\n}, \"clear\");\nvar SankeyLink = class {\n constructor(source, target, value = 0) {\n this.source = source;\n this.target = target;\n this.value = value;\n }\n static {\n __name(this, \"SankeyLink\");\n }\n};\nvar addLink = /* @__PURE__ */ __name((source, target, value) => {\n links.push(new SankeyLink(source, target, value));\n}, \"addLink\");\nvar SankeyNode = class {\n constructor(ID) {\n this.ID = ID;\n }\n static {\n __name(this, \"SankeyNode\");\n }\n};\nvar findOrCreateNode = /* @__PURE__ */ __name((ID) => {\n ID = common_default.sanitizeText(ID, getConfig());\n let node = nodesMap.get(ID);\n if (node === void 0) {\n node = new SankeyNode(ID);\n nodesMap.set(ID, node);\n nodes.push(node);\n }\n return node;\n}, \"findOrCreateNode\");\nvar getNodes = /* @__PURE__ */ __name(() => nodes, \"getNodes\");\nvar getLinks = /* @__PURE__ */ __name(() => links, \"getLinks\");\nvar getGraph = /* @__PURE__ */ __name(() => ({\n nodes: nodes.map((node) => ({ id: node.ID })),\n links: links.map((link) => ({\n source: link.source.ID,\n target: link.target.ID,\n value: link.value\n }))\n}), \"getGraph\");\nvar sankeyDB_default = {\n nodesMap,\n getConfig: /* @__PURE__ */ __name(() => getConfig().sankey, \"getConfig\"),\n getNodes,\n getLinks,\n getGraph,\n addLink,\n findOrCreateNode,\n getAccTitle,\n setAccTitle,\n getAccDescription,\n setAccDescription,\n getDiagramTitle,\n setDiagramTitle,\n clear: clear2\n};\n\n// src/diagrams/sankey/sankeyRenderer.ts\nimport {\n select as d3select,\n scaleOrdinal as d3scaleOrdinal,\n schemeTableau10 as d3schemeTableau10\n} from \"d3\";\nimport {\n sankey as d3Sankey,\n sankeyLinkHorizontal as d3SankeyLinkHorizontal,\n sankeyLeft as d3SankeyLeft,\n sankeyRight as d3SankeyRight,\n sankeyCenter as d3SankeyCenter,\n sankeyJustify as d3SankeyJustify\n} from \"d3-sankey\";\n\n// src/rendering-util/uid.ts\nvar Uid = class _Uid {\n static {\n __name(this, \"Uid\");\n }\n static {\n this.count = 0;\n }\n static next(name) {\n return new _Uid(name + ++_Uid.count);\n }\n constructor(id) {\n this.id = id;\n this.href = `#${id}`;\n }\n toString() {\n return \"url(\" + this.href + \")\";\n }\n};\n\n// src/diagrams/sankey/sankeyRenderer.ts\nvar alignmentsMap = {\n left: d3SankeyLeft,\n right: d3SankeyRight,\n center: d3SankeyCenter,\n justify: d3SankeyJustify\n};\nvar draw = /* @__PURE__ */ __name(function(text, id, _version, diagObj) {\n const { securityLevel, sankey: conf } = getConfig();\n const defaultSankeyConfig = defaultConfig.sankey;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = d3select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? d3select(sandboxElement.nodes()[0].contentDocument.body) : d3select(\"body\");\n const svg = securityLevel === \"sandbox\" ? root.select(`[id=\"${id}\"]`) : d3select(`[id=\"${id}\"]`);\n const width = conf?.width ?? defaultSankeyConfig.width;\n const height = conf?.height ?? defaultSankeyConfig.width;\n const useMaxWidth = conf?.useMaxWidth ?? defaultSankeyConfig.useMaxWidth;\n const nodeAlignment = conf?.nodeAlignment ?? defaultSankeyConfig.nodeAlignment;\n const prefix = conf?.prefix ?? defaultSankeyConfig.prefix;\n const suffix = conf?.suffix ?? defaultSankeyConfig.suffix;\n const showValues = conf?.showValues ?? defaultSankeyConfig.showValues;\n const graph = diagObj.db.getGraph();\n const nodeAlign = alignmentsMap[nodeAlignment];\n const nodeWidth = 10;\n const sankey = d3Sankey().nodeId((d) => d.id).nodeWidth(nodeWidth).nodePadding(10 + (showValues ? 15 : 0)).nodeAlign(nodeAlign).extent([\n [0, 0],\n [width, height]\n ]);\n sankey(graph);\n const colorScheme = d3scaleOrdinal(d3schemeTableau10);\n svg.append(\"g\").attr(\"class\", \"nodes\").selectAll(\".node\").data(graph.nodes).join(\"g\").attr(\"class\", \"node\").attr(\"id\", (d) => (d.uid = Uid.next(\"node-\")).id).attr(\"transform\", function(d) {\n return \"translate(\" + d.x0 + \",\" + d.y0 + \")\";\n }).attr(\"x\", (d) => d.x0).attr(\"y\", (d) => d.y0).append(\"rect\").attr(\"height\", (d) => {\n return d.y1 - d.y0;\n }).attr(\"width\", (d) => d.x1 - d.x0).attr(\"fill\", (d) => colorScheme(d.id));\n const getText = /* @__PURE__ */ __name(({ id: id2, value }) => {\n if (!showValues) {\n return id2;\n }\n return `${id2}\n${prefix}${Math.round(value * 100) / 100}${suffix}`;\n }, \"getText\");\n svg.append(\"g\").attr(\"class\", \"node-labels\").attr(\"font-family\", \"sans-serif\").attr(\"font-size\", 14).selectAll(\"text\").data(graph.nodes).join(\"text\").attr(\"x\", (d) => d.x0 < width / 2 ? d.x1 + 6 : d.x0 - 6).attr(\"y\", (d) => (d.y1 + d.y0) / 2).attr(\"dy\", `${showValues ? \"0\" : \"0.35\"}em`).attr(\"text-anchor\", (d) => d.x0 < width / 2 ? \"start\" : \"end\").text(getText);\n const link = svg.append(\"g\").attr(\"class\", \"links\").attr(\"fill\", \"none\").attr(\"stroke-opacity\", 0.5).selectAll(\".link\").data(graph.links).join(\"g\").attr(\"class\", \"link\").style(\"mix-blend-mode\", \"multiply\");\n const linkColor = conf?.linkColor ?? \"gradient\";\n if (linkColor === \"gradient\") {\n const gradient = link.append(\"linearGradient\").attr(\"id\", (d) => (d.uid = Uid.next(\"linearGradient-\")).id).attr(\"gradientUnits\", \"userSpaceOnUse\").attr(\"x1\", (d) => d.source.x1).attr(\"x2\", (d) => d.target.x0);\n gradient.append(\"stop\").attr(\"offset\", \"0%\").attr(\"stop-color\", (d) => colorScheme(d.source.id));\n gradient.append(\"stop\").attr(\"offset\", \"100%\").attr(\"stop-color\", (d) => colorScheme(d.target.id));\n }\n let coloring;\n switch (linkColor) {\n case \"gradient\":\n coloring = /* @__PURE__ */ __name((d) => d.uid, \"coloring\");\n break;\n case \"source\":\n coloring = /* @__PURE__ */ __name((d) => colorScheme(d.source.id), \"coloring\");\n break;\n case \"target\":\n coloring = /* @__PURE__ */ __name((d) => colorScheme(d.target.id), \"coloring\");\n break;\n default:\n coloring = linkColor;\n }\n link.append(\"path\").attr(\"d\", d3SankeyLinkHorizontal()).attr(\"stroke\", coloring).attr(\"stroke-width\", (d) => Math.max(1, d.width));\n setupGraphViewbox(void 0, svg, 0, useMaxWidth);\n}, \"draw\");\nvar sankeyRenderer_default = {\n draw\n};\n\n// src/diagrams/sankey/sankeyUtils.ts\nvar prepareTextForParsing = /* @__PURE__ */ __name((text) => {\n const textToParse = text.replaceAll(/^[^\\S\\n\\r]+|[^\\S\\n\\r]+$/g, \"\").replaceAll(/([\\n\\r])+/g, \"\\n\").trim();\n return textToParse;\n}, \"prepareTextForParsing\");\n\n// src/diagrams/sankey/sankeyDiagram.ts\nvar originalParse = sankey_default.parse.bind(sankey_default);\nsankey_default.parse = (text) => originalParse(prepareTextForParsing(text));\nvar diagram = {\n parser: sankey_default,\n db: sankeyDB_default,\n renderer: sankeyRenderer_default\n};\nexport {\n diagram\n};\n", "import {\n populateCommonDb\n} from \"./chunk-OQCM5LHU.mjs\";\nimport {\n cleanAndMerge\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n selectSvgElement\n} from \"./chunk-F2XFN3BY.mjs\";\nimport {\n __name,\n clear,\n configureSvgSize,\n defaultConfig_default,\n getAccDescription,\n getAccTitle,\n getConfig,\n getDiagramTitle,\n log,\n setAccDescription,\n setAccTitle,\n setDiagramTitle\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/packet/db.ts\nvar defaultPacketData = {\n packet: []\n};\nvar data = structuredClone(defaultPacketData);\nvar DEFAULT_PACKET_CONFIG = defaultConfig_default.packet;\nvar getConfig2 = /* @__PURE__ */ __name(() => {\n const config = cleanAndMerge({\n ...DEFAULT_PACKET_CONFIG,\n ...getConfig().packet\n });\n if (config.showBits) {\n config.paddingY += 10;\n }\n return config;\n}, \"getConfig\");\nvar getPacket = /* @__PURE__ */ __name(() => data.packet, \"getPacket\");\nvar pushWord = /* @__PURE__ */ __name((word) => {\n if (word.length > 0) {\n data.packet.push(word);\n }\n}, \"pushWord\");\nvar clear2 = /* @__PURE__ */ __name(() => {\n clear();\n data = structuredClone(defaultPacketData);\n}, \"clear\");\nvar db = {\n pushWord,\n getPacket,\n getConfig: getConfig2,\n clear: clear2,\n setAccTitle,\n getAccTitle,\n setDiagramTitle,\n getDiagramTitle,\n getAccDescription,\n setAccDescription\n};\n\n// src/diagrams/packet/parser.ts\nimport { parse } from \"@mermaid-js/parser\";\nvar maxPacketSize = 1e4;\nvar populate = /* @__PURE__ */ __name((ast) => {\n populateCommonDb(ast, db);\n let lastByte = -1;\n let word = [];\n let row = 1;\n const { bitsPerRow } = db.getConfig();\n for (let { start, end, label } of ast.blocks) {\n if (end && end < start) {\n throw new Error(`Packet block ${start} - ${end} is invalid. End must be greater than start.`);\n }\n if (start !== lastByte + 1) {\n throw new Error(\n `Packet block ${start} - ${end ?? start} is not contiguous. It should start from ${lastByte + 1}.`\n );\n }\n lastByte = end ?? start;\n log.debug(`Packet block ${start} - ${lastByte} with label ${label}`);\n while (word.length <= bitsPerRow + 1 && db.getPacket().length < maxPacketSize) {\n const [block, nextBlock] = getNextFittingBlock({ start, end, label }, row, bitsPerRow);\n word.push(block);\n if (block.end + 1 === row * bitsPerRow) {\n db.pushWord(word);\n word = [];\n row++;\n }\n if (!nextBlock) {\n break;\n }\n ({ start, end, label } = nextBlock);\n }\n }\n db.pushWord(word);\n}, \"populate\");\nvar getNextFittingBlock = /* @__PURE__ */ __name((block, row, bitsPerRow) => {\n if (block.end === void 0) {\n block.end = block.start;\n }\n if (block.start > block.end) {\n throw new Error(`Block start ${block.start} is greater than block end ${block.end}.`);\n }\n if (block.end + 1 <= row * bitsPerRow) {\n return [block, void 0];\n }\n return [\n {\n start: block.start,\n end: row * bitsPerRow - 1,\n label: block.label\n },\n {\n start: row * bitsPerRow,\n end: block.end,\n label: block.label\n }\n ];\n}, \"getNextFittingBlock\");\nvar parser = {\n parse: /* @__PURE__ */ __name(async (input) => {\n const ast = await parse(\"packet\", input);\n log.debug(ast);\n populate(ast);\n }, \"parse\")\n};\n\n// src/diagrams/packet/renderer.ts\nvar draw = /* @__PURE__ */ __name((_text, id, _version, diagram2) => {\n const db2 = diagram2.db;\n const config = db2.getConfig();\n const { rowHeight, paddingY, bitWidth, bitsPerRow } = config;\n const words = db2.getPacket();\n const title = db2.getDiagramTitle();\n const totalRowHeight = rowHeight + paddingY;\n const svgHeight = totalRowHeight * (words.length + 1) - (title ? 0 : rowHeight);\n const svgWidth = bitWidth * bitsPerRow + 2;\n const svg = selectSvgElement(id);\n svg.attr(\"viewbox\", `0 0 ${svgWidth} ${svgHeight}`);\n configureSvgSize(svg, svgHeight, svgWidth, config.useMaxWidth);\n for (const [word, packet] of words.entries()) {\n drawWord(svg, packet, word, config);\n }\n svg.append(\"text\").text(title).attr(\"x\", svgWidth / 2).attr(\"y\", svgHeight - totalRowHeight / 2).attr(\"dominant-baseline\", \"middle\").attr(\"text-anchor\", \"middle\").attr(\"class\", \"packetTitle\");\n}, \"draw\");\nvar drawWord = /* @__PURE__ */ __name((svg, word, rowNumber, { rowHeight, paddingX, paddingY, bitWidth, bitsPerRow, showBits }) => {\n const group = svg.append(\"g\");\n const wordY = rowNumber * (rowHeight + paddingY) + paddingY;\n for (const block of word) {\n const blockX = block.start % bitsPerRow * bitWidth + 1;\n const width = (block.end - block.start + 1) * bitWidth - paddingX;\n group.append(\"rect\").attr(\"x\", blockX).attr(\"y\", wordY).attr(\"width\", width).attr(\"height\", rowHeight).attr(\"class\", \"packetBlock\");\n group.append(\"text\").attr(\"x\", blockX + width / 2).attr(\"y\", wordY + rowHeight / 2).attr(\"class\", \"packetLabel\").attr(\"dominant-baseline\", \"middle\").attr(\"text-anchor\", \"middle\").text(block.label);\n if (!showBits) {\n continue;\n }\n const isSingleBlock = block.end === block.start;\n const bitNumberY = wordY - 2;\n group.append(\"text\").attr(\"x\", blockX + (isSingleBlock ? width / 2 : 0)).attr(\"y\", bitNumberY).attr(\"class\", \"packetByte start\").attr(\"dominant-baseline\", \"auto\").attr(\"text-anchor\", isSingleBlock ? \"middle\" : \"start\").text(block.start);\n if (!isSingleBlock) {\n group.append(\"text\").attr(\"x\", blockX + width).attr(\"y\", bitNumberY).attr(\"class\", \"packetByte end\").attr(\"dominant-baseline\", \"auto\").attr(\"text-anchor\", \"end\").text(block.end);\n }\n }\n}, \"drawWord\");\nvar renderer = { draw };\n\n// src/diagrams/packet/styles.ts\nvar defaultPacketStyleOptions = {\n byteFontSize: \"10px\",\n startByteColor: \"black\",\n endByteColor: \"black\",\n labelColor: \"black\",\n labelFontSize: \"12px\",\n titleColor: \"black\",\n titleFontSize: \"14px\",\n blockStrokeColor: \"black\",\n blockStrokeWidth: \"1\",\n blockFillColor: \"#efefef\"\n};\nvar styles = /* @__PURE__ */ __name(({ packet } = {}) => {\n const options = cleanAndMerge(defaultPacketStyleOptions, packet);\n return `\n\t.packetByte {\n\t\tfont-size: ${options.byteFontSize};\n\t}\n\t.packetByte.start {\n\t\tfill: ${options.startByteColor};\n\t}\n\t.packetByte.end {\n\t\tfill: ${options.endByteColor};\n\t}\n\t.packetLabel {\n\t\tfill: ${options.labelColor};\n\t\tfont-size: ${options.labelFontSize};\n\t}\n\t.packetTitle {\n\t\tfill: ${options.titleColor};\n\t\tfont-size: ${options.titleFontSize};\n\t}\n\t.packetBlock {\n\t\tstroke: ${options.blockStrokeColor};\n\t\tstroke-width: ${options.blockStrokeWidth};\n\t\tfill: ${options.blockFillColor};\n\t}\n\t`;\n}, \"styles\");\n\n// src/diagrams/packet/diagram.ts\nvar diagram = {\n parser,\n db,\n renderer,\n styles\n};\nexport {\n diagram\n};\n", "import {\n insertEdge,\n insertEdgeLabel,\n markers_default,\n positionEdgeLabel\n} from \"./chunk-UGV5ZQQN.mjs\";\nimport {\n insertNode,\n positionNode\n} from \"./chunk-YWFND7JV.mjs\";\nimport \"./chunk-23ATMZXV.mjs\";\nimport \"./chunk-5N55DQE6.mjs\";\nimport {\n getStylesFromArray\n} from \"./chunk-2EDTWDYI.mjs\";\nimport {\n __name,\n clear,\n common_default,\n configureSvgSize,\n getConfig,\n getConfig2,\n log\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/block/parser/block.jison\nvar parser = function() {\n var o = /* @__PURE__ */ __name(function(k, v, o2, l) {\n for (o2 = o2 || {}, l = k.length; l--; o2[k[l]] = v) ;\n return o2;\n }, \"o\"), $V0 = [1, 7], $V1 = [1, 13], $V2 = [1, 14], $V3 = [1, 15], $V4 = [1, 19], $V5 = [1, 16], $V6 = [1, 17], $V7 = [1, 18], $V8 = [8, 30], $V9 = [8, 21, 28, 29, 30, 31, 32, 40, 44, 47], $Va = [1, 23], $Vb = [1, 24], $Vc = [8, 15, 16, 21, 28, 29, 30, 31, 32, 40, 44, 47], $Vd = [8, 15, 16, 21, 27, 28, 29, 30, 31, 32, 40, 44, 47], $Ve = [1, 49];\n var parser2 = {\n trace: /* @__PURE__ */ __name(function trace() {\n }, \"trace\"),\n yy: {},\n symbols_: { \"error\": 2, \"spaceLines\": 3, \"SPACELINE\": 4, \"NL\": 5, \"separator\": 6, \"SPACE\": 7, \"EOF\": 8, \"start\": 9, \"BLOCK_DIAGRAM_KEY\": 10, \"document\": 11, \"stop\": 12, \"statement\": 13, \"link\": 14, \"LINK\": 15, \"START_LINK\": 16, \"LINK_LABEL\": 17, \"STR\": 18, \"nodeStatement\": 19, \"columnsStatement\": 20, \"SPACE_BLOCK\": 21, \"blockStatement\": 22, \"classDefStatement\": 23, \"cssClassStatement\": 24, \"styleStatement\": 25, \"node\": 26, \"SIZE\": 27, \"COLUMNS\": 28, \"id-block\": 29, \"end\": 30, \"block\": 31, \"NODE_ID\": 32, \"nodeShapeNLabel\": 33, \"dirList\": 34, \"DIR\": 35, \"NODE_DSTART\": 36, \"NODE_DEND\": 37, \"BLOCK_ARROW_START\": 38, \"BLOCK_ARROW_END\": 39, \"classDef\": 40, \"CLASSDEF_ID\": 41, \"CLASSDEF_STYLEOPTS\": 42, \"DEFAULT\": 43, \"class\": 44, \"CLASSENTITY_IDS\": 45, \"STYLECLASS\": 46, \"style\": 47, \"STYLE_ENTITY_IDS\": 48, \"STYLE_DEFINITION_DATA\": 49, \"$accept\": 0, \"$end\": 1 },\n terminals_: { 2: \"error\", 4: \"SPACELINE\", 5: \"NL\", 7: \"SPACE\", 8: \"EOF\", 10: \"BLOCK_DIAGRAM_KEY\", 15: \"LINK\", 16: \"START_LINK\", 17: \"LINK_LABEL\", 18: \"STR\", 21: \"SPACE_BLOCK\", 27: \"SIZE\", 28: \"COLUMNS\", 29: \"id-block\", 30: \"end\", 31: \"block\", 32: \"NODE_ID\", 35: \"DIR\", 36: \"NODE_DSTART\", 37: \"NODE_DEND\", 38: \"BLOCK_ARROW_START\", 39: \"BLOCK_ARROW_END\", 40: \"classDef\", 41: \"CLASSDEF_ID\", 42: \"CLASSDEF_STYLEOPTS\", 43: \"DEFAULT\", 44: \"class\", 45: \"CLASSENTITY_IDS\", 46: \"STYLECLASS\", 47: \"style\", 48: \"STYLE_ENTITY_IDS\", 49: \"STYLE_DEFINITION_DATA\" },\n productions_: [0, [3, 1], [3, 2], [3, 2], [6, 1], [6, 1], [6, 1], [9, 3], [12, 1], [12, 1], [12, 2], [12, 2], [11, 1], [11, 2], [14, 1], [14, 4], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [13, 1], [19, 3], [19, 2], [19, 1], [20, 1], [22, 4], [22, 3], [26, 1], [26, 2], [34, 1], [34, 2], [33, 3], [33, 4], [23, 3], [23, 3], [24, 3], [25, 3]],\n performAction: /* @__PURE__ */ __name(function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$) {\n var $0 = $$.length - 1;\n switch (yystate) {\n case 4:\n yy.getLogger().debug(\"Rule: separator (NL) \");\n break;\n case 5:\n yy.getLogger().debug(\"Rule: separator (Space) \");\n break;\n case 6:\n yy.getLogger().debug(\"Rule: separator (EOF) \");\n break;\n case 7:\n yy.getLogger().debug(\"Rule: hierarchy: \", $$[$0 - 1]);\n yy.setHierarchy($$[$0 - 1]);\n break;\n case 8:\n yy.getLogger().debug(\"Stop NL \");\n break;\n case 9:\n yy.getLogger().debug(\"Stop EOF \");\n break;\n case 10:\n yy.getLogger().debug(\"Stop NL2 \");\n break;\n case 11:\n yy.getLogger().debug(\"Stop EOF2 \");\n break;\n case 12:\n yy.getLogger().debug(\"Rule: statement: \", $$[$0]);\n typeof $$[$0].length === \"number\" ? this.$ = $$[$0] : this.$ = [$$[$0]];\n break;\n case 13:\n yy.getLogger().debug(\"Rule: statement #2: \", $$[$0 - 1]);\n this.$ = [$$[$0 - 1]].concat($$[$0]);\n break;\n case 14:\n yy.getLogger().debug(\"Rule: link: \", $$[$0], yytext);\n this.$ = { edgeTypeStr: $$[$0], label: \"\" };\n break;\n case 15:\n yy.getLogger().debug(\"Rule: LABEL link: \", $$[$0 - 3], $$[$0 - 1], $$[$0]);\n this.$ = { edgeTypeStr: $$[$0], label: $$[$0 - 1] };\n break;\n case 18:\n const num = parseInt($$[$0]);\n const spaceId = yy.generateId();\n this.$ = { id: spaceId, type: \"space\", label: \"\", width: num, children: [] };\n break;\n case 23:\n yy.getLogger().debug(\"Rule: (nodeStatement link node) \", $$[$0 - 2], $$[$0 - 1], $$[$0], \" typestr: \", $$[$0 - 1].edgeTypeStr);\n const edgeData = yy.edgeStrToEdgeData($$[$0 - 1].edgeTypeStr);\n this.$ = [\n { id: $$[$0 - 2].id, label: $$[$0 - 2].label, type: $$[$0 - 2].type, directions: $$[$0 - 2].directions },\n { id: $$[$0 - 2].id + \"-\" + $$[$0].id, start: $$[$0 - 2].id, end: $$[$0].id, label: $$[$0 - 1].label, type: \"edge\", directions: $$[$0].directions, arrowTypeEnd: edgeData, arrowTypeStart: \"arrow_open\" },\n { id: $$[$0].id, label: $$[$0].label, type: yy.typeStr2Type($$[$0].typeStr), directions: $$[$0].directions }\n ];\n break;\n case 24:\n yy.getLogger().debug(\"Rule: nodeStatement (abc88 node size) \", $$[$0 - 1], $$[$0]);\n this.$ = { id: $$[$0 - 1].id, label: $$[$0 - 1].label, type: yy.typeStr2Type($$[$0 - 1].typeStr), directions: $$[$0 - 1].directions, widthInColumns: parseInt($$[$0], 10) };\n break;\n case 25:\n yy.getLogger().debug(\"Rule: nodeStatement (node) \", $$[$0]);\n this.$ = { id: $$[$0].id, label: $$[$0].label, type: yy.typeStr2Type($$[$0].typeStr), directions: $$[$0].directions, widthInColumns: 1 };\n break;\n case 26:\n yy.getLogger().debug(\"APA123\", this ? this : \"na\");\n yy.getLogger().debug(\"COLUMNS: \", $$[$0]);\n this.$ = { type: \"column-setting\", columns: $$[$0] === \"auto\" ? -1 : parseInt($$[$0]) };\n break;\n case 27:\n yy.getLogger().debug(\"Rule: id-block statement : \", $$[$0 - 2], $$[$0 - 1]);\n const id2 = yy.generateId();\n this.$ = { ...$$[$0 - 2], type: \"composite\", children: $$[$0 - 1] };\n break;\n case 28:\n yy.getLogger().debug(\"Rule: blockStatement : \", $$[$0 - 2], $$[$0 - 1], $$[$0]);\n const id = yy.generateId();\n this.$ = { id, type: \"composite\", label: \"\", children: $$[$0 - 1] };\n break;\n case 29:\n yy.getLogger().debug(\"Rule: node (NODE_ID separator): \", $$[$0]);\n this.$ = { id: $$[$0] };\n break;\n case 30:\n yy.getLogger().debug(\"Rule: node (NODE_ID nodeShapeNLabel separator): \", $$[$0 - 1], $$[$0]);\n this.$ = { id: $$[$0 - 1], label: $$[$0].label, typeStr: $$[$0].typeStr, directions: $$[$0].directions };\n break;\n case 31:\n yy.getLogger().debug(\"Rule: dirList: \", $$[$0]);\n this.$ = [$$[$0]];\n break;\n case 32:\n yy.getLogger().debug(\"Rule: dirList: \", $$[$0 - 1], $$[$0]);\n this.$ = [$$[$0 - 1]].concat($$[$0]);\n break;\n case 33:\n yy.getLogger().debug(\"Rule: nodeShapeNLabel: \", $$[$0 - 2], $$[$0 - 1], $$[$0]);\n this.$ = { typeStr: $$[$0 - 2] + $$[$0], label: $$[$0 - 1] };\n break;\n case 34:\n yy.getLogger().debug(\"Rule: BLOCK_ARROW nodeShapeNLabel: \", $$[$0 - 3], $$[$0 - 2], \" #3:\", $$[$0 - 1], $$[$0]);\n this.$ = { typeStr: $$[$0 - 3] + $$[$0], label: $$[$0 - 2], directions: $$[$0 - 1] };\n break;\n case 35:\n case 36:\n this.$ = { type: \"classDef\", id: $$[$0 - 1].trim(), css: $$[$0].trim() };\n break;\n case 37:\n this.$ = { type: \"applyClass\", id: $$[$0 - 1].trim(), styleClass: $$[$0].trim() };\n break;\n case 38:\n this.$ = { type: \"applyStyles\", id: $$[$0 - 1].trim(), stylesStr: $$[$0].trim() };\n break;\n }\n }, \"anonymous\"),\n table: [{ 9: 1, 10: [1, 2] }, { 1: [3] }, { 11: 3, 13: 4, 19: 5, 20: 6, 21: $V0, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 28: $V1, 29: $V2, 31: $V3, 32: $V4, 40: $V5, 44: $V6, 47: $V7 }, { 8: [1, 20] }, o($V8, [2, 12], { 13: 4, 19: 5, 20: 6, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 11: 21, 21: $V0, 28: $V1, 29: $V2, 31: $V3, 32: $V4, 40: $V5, 44: $V6, 47: $V7 }), o($V9, [2, 16], { 14: 22, 15: $Va, 16: $Vb }), o($V9, [2, 17]), o($V9, [2, 18]), o($V9, [2, 19]), o($V9, [2, 20]), o($V9, [2, 21]), o($V9, [2, 22]), o($Vc, [2, 25], { 27: [1, 25] }), o($V9, [2, 26]), { 19: 26, 26: 12, 32: $V4 }, { 11: 27, 13: 4, 19: 5, 20: 6, 21: $V0, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 28: $V1, 29: $V2, 31: $V3, 32: $V4, 40: $V5, 44: $V6, 47: $V7 }, { 41: [1, 28], 43: [1, 29] }, { 45: [1, 30] }, { 48: [1, 31] }, o($Vd, [2, 29], { 33: 32, 36: [1, 33], 38: [1, 34] }), { 1: [2, 7] }, o($V8, [2, 13]), { 26: 35, 32: $V4 }, { 32: [2, 14] }, { 17: [1, 36] }, o($Vc, [2, 24]), { 11: 37, 13: 4, 14: 22, 15: $Va, 16: $Vb, 19: 5, 20: 6, 21: $V0, 22: 8, 23: 9, 24: 10, 25: 11, 26: 12, 28: $V1, 29: $V2, 31: $V3, 32: $V4, 40: $V5, 44: $V6, 47: $V7 }, { 30: [1, 38] }, { 42: [1, 39] }, { 42: [1, 40] }, { 46: [1, 41] }, { 49: [1, 42] }, o($Vd, [2, 30]), { 18: [1, 43] }, { 18: [1, 44] }, o($Vc, [2, 23]), { 18: [1, 45] }, { 30: [1, 46] }, o($V9, [2, 28]), o($V9, [2, 35]), o($V9, [2, 36]), o($V9, [2, 37]), o($V9, [2, 38]), { 37: [1, 47] }, { 34: 48, 35: $Ve }, { 15: [1, 50] }, o($V9, [2, 27]), o($Vd, [2, 33]), { 39: [1, 51] }, { 34: 52, 35: $Ve, 39: [2, 31] }, { 32: [2, 15] }, o($Vd, [2, 34]), { 39: [2, 32] }],\n defaultActions: { 20: [2, 7], 23: [2, 14], 50: [2, 15], 52: [2, 32] },\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (hash.recoverable) {\n this.trace(str);\n } else {\n var error = new Error(str);\n error.hash = hash;\n throw error;\n }\n }, \"parseError\"),\n parse: /* @__PURE__ */ __name(function parse(input) {\n var self = this, stack = [0], tstack = [], vstack = [null], lstack = [], table = this.table, yytext = \"\", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;\n var args = lstack.slice.call(arguments, 1);\n var lexer2 = Object.create(this.lexer);\n var sharedState = { yy: {} };\n for (var k in this.yy) {\n if (Object.prototype.hasOwnProperty.call(this.yy, k)) {\n sharedState.yy[k] = this.yy[k];\n }\n }\n lexer2.setInput(input, sharedState.yy);\n sharedState.yy.lexer = lexer2;\n sharedState.yy.parser = this;\n if (typeof lexer2.yylloc == \"undefined\") {\n lexer2.yylloc = {};\n }\n var yyloc = lexer2.yylloc;\n lstack.push(yyloc);\n var ranges = lexer2.options && lexer2.options.ranges;\n if (typeof sharedState.yy.parseError === \"function\") {\n this.parseError = sharedState.yy.parseError;\n } else {\n this.parseError = Object.getPrototypeOf(this).parseError;\n }\n function popStack(n) {\n stack.length = stack.length - 2 * n;\n vstack.length = vstack.length - n;\n lstack.length = lstack.length - n;\n }\n __name(popStack, \"popStack\");\n function lex() {\n var token;\n token = tstack.pop() || lexer2.lex() || EOF;\n if (typeof token !== \"number\") {\n if (token instanceof Array) {\n tstack = token;\n token = tstack.pop();\n }\n token = self.symbols_[token] || token;\n }\n return token;\n }\n __name(lex, \"lex\");\n var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;\n while (true) {\n state = stack[stack.length - 1];\n if (this.defaultActions[state]) {\n action = this.defaultActions[state];\n } else {\n if (symbol === null || typeof symbol == \"undefined\") {\n symbol = lex();\n }\n action = table[state] && table[state][symbol];\n }\n if (typeof action === \"undefined\" || !action.length || !action[0]) {\n var errStr = \"\";\n expected = [];\n for (p in table[state]) {\n if (this.terminals_[p] && p > TERROR) {\n expected.push(\"'\" + this.terminals_[p] + \"'\");\n }\n }\n if (lexer2.showPosition) {\n errStr = \"Parse error on line \" + (yylineno + 1) + \":\\n\" + lexer2.showPosition() + \"\\nExpecting \" + expected.join(\", \") + \", got '\" + (this.terminals_[symbol] || symbol) + \"'\";\n } else {\n errStr = \"Parse error on line \" + (yylineno + 1) + \": Unexpected \" + (symbol == EOF ? \"end of input\" : \"'\" + (this.terminals_[symbol] || symbol) + \"'\");\n }\n this.parseError(errStr, {\n text: lexer2.match,\n token: this.terminals_[symbol] || symbol,\n line: lexer2.yylineno,\n loc: yyloc,\n expected\n });\n }\n if (action[0] instanceof Array && action.length > 1) {\n throw new Error(\"Parse Error: multiple actions possible at state: \" + state + \", token: \" + symbol);\n }\n switch (action[0]) {\n case 1:\n stack.push(symbol);\n vstack.push(lexer2.yytext);\n lstack.push(lexer2.yylloc);\n stack.push(action[1]);\n symbol = null;\n if (!preErrorSymbol) {\n yyleng = lexer2.yyleng;\n yytext = lexer2.yytext;\n yylineno = lexer2.yylineno;\n yyloc = lexer2.yylloc;\n if (recovering > 0) {\n recovering--;\n }\n } else {\n symbol = preErrorSymbol;\n preErrorSymbol = null;\n }\n break;\n case 2:\n len = this.productions_[action[1]][1];\n yyval.$ = vstack[vstack.length - len];\n yyval._$ = {\n first_line: lstack[lstack.length - (len || 1)].first_line,\n last_line: lstack[lstack.length - 1].last_line,\n first_column: lstack[lstack.length - (len || 1)].first_column,\n last_column: lstack[lstack.length - 1].last_column\n };\n if (ranges) {\n yyval._$.range = [\n lstack[lstack.length - (len || 1)].range[0],\n lstack[lstack.length - 1].range[1]\n ];\n }\n r = this.performAction.apply(yyval, [\n yytext,\n yyleng,\n yylineno,\n sharedState.yy,\n action[1],\n vstack,\n lstack\n ].concat(args));\n if (typeof r !== \"undefined\") {\n return r;\n }\n if (len) {\n stack = stack.slice(0, -1 * len * 2);\n vstack = vstack.slice(0, -1 * len);\n lstack = lstack.slice(0, -1 * len);\n }\n stack.push(this.productions_[action[1]][0]);\n vstack.push(yyval.$);\n lstack.push(yyval._$);\n newState = table[stack[stack.length - 2]][stack[stack.length - 1]];\n stack.push(newState);\n break;\n case 3:\n return true;\n }\n }\n return true;\n }, \"parse\")\n };\n var lexer = /* @__PURE__ */ function() {\n var lexer2 = {\n EOF: 1,\n parseError: /* @__PURE__ */ __name(function parseError(str, hash) {\n if (this.yy.parser) {\n this.yy.parser.parseError(str, hash);\n } else {\n throw new Error(str);\n }\n }, \"parseError\"),\n // resets the lexer, sets new input\n setInput: /* @__PURE__ */ __name(function(input, yy) {\n this.yy = yy || this.yy || {};\n this._input = input;\n this._more = this._backtrack = this.done = false;\n this.yylineno = this.yyleng = 0;\n this.yytext = this.matched = this.match = \"\";\n this.conditionStack = [\"INITIAL\"];\n this.yylloc = {\n first_line: 1,\n first_column: 0,\n last_line: 1,\n last_column: 0\n };\n if (this.options.ranges) {\n this.yylloc.range = [0, 0];\n }\n this.offset = 0;\n return this;\n }, \"setInput\"),\n // consumes and returns one char from the input\n input: /* @__PURE__ */ __name(function() {\n var ch = this._input[0];\n this.yytext += ch;\n this.yyleng++;\n this.offset++;\n this.match += ch;\n this.matched += ch;\n var lines = ch.match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno++;\n this.yylloc.last_line++;\n } else {\n this.yylloc.last_column++;\n }\n if (this.options.ranges) {\n this.yylloc.range[1]++;\n }\n this._input = this._input.slice(1);\n return ch;\n }, \"input\"),\n // unshifts one char (or a string) into the input\n unput: /* @__PURE__ */ __name(function(ch) {\n var len = ch.length;\n var lines = ch.split(/(?:\\r\\n?|\\n)/g);\n this._input = ch + this._input;\n this.yytext = this.yytext.substr(0, this.yytext.length - len);\n this.offset -= len;\n var oldLines = this.match.split(/(?:\\r\\n?|\\n)/g);\n this.match = this.match.substr(0, this.match.length - 1);\n this.matched = this.matched.substr(0, this.matched.length - 1);\n if (lines.length - 1) {\n this.yylineno -= lines.length - 1;\n }\n var r = this.yylloc.range;\n this.yylloc = {\n first_line: this.yylloc.first_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.first_column,\n last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len\n };\n if (this.options.ranges) {\n this.yylloc.range = [r[0], r[0] + this.yyleng - len];\n }\n this.yyleng = this.yytext.length;\n return this;\n }, \"unput\"),\n // When called from action, caches matched text and appends it on next action\n more: /* @__PURE__ */ __name(function() {\n this._more = true;\n return this;\n }, \"more\"),\n // When called from action, signals the lexer that this rule fails to match the input, so the next matching rule (regex) should be tested instead.\n reject: /* @__PURE__ */ __name(function() {\n if (this.options.backtrack_lexer) {\n this._backtrack = true;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". You can only invoke reject() in the lexer when the lexer is of the backtracking persuasion (options.backtrack_lexer = true).\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n return this;\n }, \"reject\"),\n // retain first n characters of the match\n less: /* @__PURE__ */ __name(function(n) {\n this.unput(this.match.slice(n));\n }, \"less\"),\n // displays already matched input, i.e. for error messages\n pastInput: /* @__PURE__ */ __name(function() {\n var past = this.matched.substr(0, this.matched.length - this.match.length);\n return (past.length > 20 ? \"...\" : \"\") + past.substr(-20).replace(/\\n/g, \"\");\n }, \"pastInput\"),\n // displays upcoming input, i.e. for error messages\n upcomingInput: /* @__PURE__ */ __name(function() {\n var next = this.match;\n if (next.length < 20) {\n next += this._input.substr(0, 20 - next.length);\n }\n return (next.substr(0, 20) + (next.length > 20 ? \"...\" : \"\")).replace(/\\n/g, \"\");\n }, \"upcomingInput\"),\n // displays the character position where the lexing error occurred, i.e. for error messages\n showPosition: /* @__PURE__ */ __name(function() {\n var pre = this.pastInput();\n var c = new Array(pre.length + 1).join(\"-\");\n return pre + this.upcomingInput() + \"\\n\" + c + \"^\";\n }, \"showPosition\"),\n // test the lexed token: return FALSE when not a match, otherwise return token\n test_match: /* @__PURE__ */ __name(function(match, indexed_rule) {\n var token, lines, backup;\n if (this.options.backtrack_lexer) {\n backup = {\n yylineno: this.yylineno,\n yylloc: {\n first_line: this.yylloc.first_line,\n last_line: this.last_line,\n first_column: this.yylloc.first_column,\n last_column: this.yylloc.last_column\n },\n yytext: this.yytext,\n match: this.match,\n matches: this.matches,\n matched: this.matched,\n yyleng: this.yyleng,\n offset: this.offset,\n _more: this._more,\n _input: this._input,\n yy: this.yy,\n conditionStack: this.conditionStack.slice(0),\n done: this.done\n };\n if (this.options.ranges) {\n backup.yylloc.range = this.yylloc.range.slice(0);\n }\n }\n lines = match[0].match(/(?:\\r\\n?|\\n).*/g);\n if (lines) {\n this.yylineno += lines.length;\n }\n this.yylloc = {\n first_line: this.yylloc.last_line,\n last_line: this.yylineno + 1,\n first_column: this.yylloc.last_column,\n last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\\r?\\n?/)[0].length : this.yylloc.last_column + match[0].length\n };\n this.yytext += match[0];\n this.match += match[0];\n this.matches = match;\n this.yyleng = this.yytext.length;\n if (this.options.ranges) {\n this.yylloc.range = [this.offset, this.offset += this.yyleng];\n }\n this._more = false;\n this._backtrack = false;\n this._input = this._input.slice(match[0].length);\n this.matched += match[0];\n token = this.performAction.call(this, this.yy, this, indexed_rule, this.conditionStack[this.conditionStack.length - 1]);\n if (this.done && this._input) {\n this.done = false;\n }\n if (token) {\n return token;\n } else if (this._backtrack) {\n for (var k in backup) {\n this[k] = backup[k];\n }\n return false;\n }\n return false;\n }, \"test_match\"),\n // return next match in input\n next: /* @__PURE__ */ __name(function() {\n if (this.done) {\n return this.EOF;\n }\n if (!this._input) {\n this.done = true;\n }\n var token, match, tempMatch, index;\n if (!this._more) {\n this.yytext = \"\";\n this.match = \"\";\n }\n var rules = this._currentRules();\n for (var i = 0; i < rules.length; i++) {\n tempMatch = this._input.match(this.rules[rules[i]]);\n if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {\n match = tempMatch;\n index = i;\n if (this.options.backtrack_lexer) {\n token = this.test_match(tempMatch, rules[i]);\n if (token !== false) {\n return token;\n } else if (this._backtrack) {\n match = false;\n continue;\n } else {\n return false;\n }\n } else if (!this.options.flex) {\n break;\n }\n }\n }\n if (match) {\n token = this.test_match(match, rules[index]);\n if (token !== false) {\n return token;\n }\n return false;\n }\n if (this._input === \"\") {\n return this.EOF;\n } else {\n return this.parseError(\"Lexical error on line \" + (this.yylineno + 1) + \". Unrecognized text.\\n\" + this.showPosition(), {\n text: \"\",\n token: null,\n line: this.yylineno\n });\n }\n }, \"next\"),\n // return next match that has a token\n lex: /* @__PURE__ */ __name(function lex() {\n var r = this.next();\n if (r) {\n return r;\n } else {\n return this.lex();\n }\n }, \"lex\"),\n // activates a new lexer condition state (pushes the new lexer condition state onto the condition stack)\n begin: /* @__PURE__ */ __name(function begin(condition) {\n this.conditionStack.push(condition);\n }, \"begin\"),\n // pop the previously active lexer condition state off the condition stack\n popState: /* @__PURE__ */ __name(function popState() {\n var n = this.conditionStack.length - 1;\n if (n > 0) {\n return this.conditionStack.pop();\n } else {\n return this.conditionStack[0];\n }\n }, \"popState\"),\n // produce the lexer rule set which is active for the currently active lexer condition state\n _currentRules: /* @__PURE__ */ __name(function _currentRules() {\n if (this.conditionStack.length && this.conditionStack[this.conditionStack.length - 1]) {\n return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules;\n } else {\n return this.conditions[\"INITIAL\"].rules;\n }\n }, \"_currentRules\"),\n // return the currently active lexer condition state; when an index argument is provided it produces the N-th previous condition state, if available\n topState: /* @__PURE__ */ __name(function topState(n) {\n n = this.conditionStack.length - 1 - Math.abs(n || 0);\n if (n >= 0) {\n return this.conditionStack[n];\n } else {\n return \"INITIAL\";\n }\n }, \"topState\"),\n // alias for begin(condition)\n pushState: /* @__PURE__ */ __name(function pushState(condition) {\n this.begin(condition);\n }, \"pushState\"),\n // return the number of states currently on the stack\n stateStackSize: /* @__PURE__ */ __name(function stateStackSize() {\n return this.conditionStack.length;\n }, \"stateStackSize\"),\n options: {},\n performAction: /* @__PURE__ */ __name(function anonymous(yy, yy_, $avoiding_name_collisions, YY_START) {\n var YYSTATE = YY_START;\n switch ($avoiding_name_collisions) {\n case 0:\n return 10;\n break;\n case 1:\n yy.getLogger().debug(\"Found space-block\");\n return 31;\n break;\n case 2:\n yy.getLogger().debug(\"Found nl-block\");\n return 31;\n break;\n case 3:\n yy.getLogger().debug(\"Found space-block\");\n return 29;\n break;\n case 4:\n yy.getLogger().debug(\".\", yy_.yytext);\n break;\n case 5:\n yy.getLogger().debug(\"_\", yy_.yytext);\n break;\n case 6:\n return 5;\n break;\n case 7:\n yy_.yytext = -1;\n return 28;\n break;\n case 8:\n yy_.yytext = yy_.yytext.replace(/columns\\s+/, \"\");\n yy.getLogger().debug(\"COLUMNS (LEX)\", yy_.yytext);\n return 28;\n break;\n case 9:\n this.pushState(\"md_string\");\n break;\n case 10:\n return \"MD_STR\";\n break;\n case 11:\n this.popState();\n break;\n case 12:\n this.pushState(\"string\");\n break;\n case 13:\n yy.getLogger().debug(\"LEX: POPPING STR:\", yy_.yytext);\n this.popState();\n break;\n case 14:\n yy.getLogger().debug(\"LEX: STR end:\", yy_.yytext);\n return \"STR\";\n break;\n case 15:\n yy_.yytext = yy_.yytext.replace(/space\\:/, \"\");\n yy.getLogger().debug(\"SPACE NUM (LEX)\", yy_.yytext);\n return 21;\n break;\n case 16:\n yy_.yytext = \"1\";\n yy.getLogger().debug(\"COLUMNS (LEX)\", yy_.yytext);\n return 21;\n break;\n case 17:\n return 43;\n break;\n case 18:\n return \"LINKSTYLE\";\n break;\n case 19:\n return \"INTERPOLATE\";\n break;\n case 20:\n this.pushState(\"CLASSDEF\");\n return 40;\n break;\n case 21:\n this.popState();\n this.pushState(\"CLASSDEFID\");\n return \"DEFAULT_CLASSDEF_ID\";\n break;\n case 22:\n this.popState();\n this.pushState(\"CLASSDEFID\");\n return 41;\n break;\n case 23:\n this.popState();\n return 42;\n break;\n case 24:\n this.pushState(\"CLASS\");\n return 44;\n break;\n case 25:\n this.popState();\n this.pushState(\"CLASS_STYLE\");\n return 45;\n break;\n case 26:\n this.popState();\n return 46;\n break;\n case 27:\n this.pushState(\"STYLE_STMNT\");\n return 47;\n break;\n case 28:\n this.popState();\n this.pushState(\"STYLE_DEFINITION\");\n return 48;\n break;\n case 29:\n this.popState();\n return 49;\n break;\n case 30:\n this.pushState(\"acc_title\");\n return \"acc_title\";\n break;\n case 31:\n this.popState();\n return \"acc_title_value\";\n break;\n case 32:\n this.pushState(\"acc_descr\");\n return \"acc_descr\";\n break;\n case 33:\n this.popState();\n return \"acc_descr_value\";\n break;\n case 34:\n this.pushState(\"acc_descr_multiline\");\n break;\n case 35:\n this.popState();\n break;\n case 36:\n return \"acc_descr_multiline_value\";\n break;\n case 37:\n return 30;\n break;\n case 38:\n this.popState();\n yy.getLogger().debug(\"Lex: ((\");\n return \"NODE_DEND\";\n break;\n case 39:\n this.popState();\n yy.getLogger().debug(\"Lex: ((\");\n return \"NODE_DEND\";\n break;\n case 40:\n this.popState();\n yy.getLogger().debug(\"Lex: ))\");\n return \"NODE_DEND\";\n break;\n case 41:\n this.popState();\n yy.getLogger().debug(\"Lex: ((\");\n return \"NODE_DEND\";\n break;\n case 42:\n this.popState();\n yy.getLogger().debug(\"Lex: ((\");\n return \"NODE_DEND\";\n break;\n case 43:\n this.popState();\n yy.getLogger().debug(\"Lex: (-\");\n return \"NODE_DEND\";\n break;\n case 44:\n this.popState();\n yy.getLogger().debug(\"Lex: -)\");\n return \"NODE_DEND\";\n break;\n case 45:\n this.popState();\n yy.getLogger().debug(\"Lex: ((\");\n return \"NODE_DEND\";\n break;\n case 46:\n this.popState();\n yy.getLogger().debug(\"Lex: ]]\");\n return \"NODE_DEND\";\n break;\n case 47:\n this.popState();\n yy.getLogger().debug(\"Lex: (\");\n return \"NODE_DEND\";\n break;\n case 48:\n this.popState();\n yy.getLogger().debug(\"Lex: ])\");\n return \"NODE_DEND\";\n break;\n case 49:\n this.popState();\n yy.getLogger().debug(\"Lex: /]\");\n return \"NODE_DEND\";\n break;\n case 50:\n this.popState();\n yy.getLogger().debug(\"Lex: /]\");\n return \"NODE_DEND\";\n break;\n case 51:\n this.popState();\n yy.getLogger().debug(\"Lex: )]\");\n return \"NODE_DEND\";\n break;\n case 52:\n this.popState();\n yy.getLogger().debug(\"Lex: )\");\n return \"NODE_DEND\";\n break;\n case 53:\n this.popState();\n yy.getLogger().debug(\"Lex: ]>\");\n return \"NODE_DEND\";\n break;\n case 54:\n this.popState();\n yy.getLogger().debug(\"Lex: ]\");\n return \"NODE_DEND\";\n break;\n case 55:\n yy.getLogger().debug(\"Lexa: -)\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 56:\n yy.getLogger().debug(\"Lexa: (-\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 57:\n yy.getLogger().debug(\"Lexa: ))\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 58:\n yy.getLogger().debug(\"Lexa: )\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 59:\n yy.getLogger().debug(\"Lex: (((\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 60:\n yy.getLogger().debug(\"Lexa: )\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 61:\n yy.getLogger().debug(\"Lexa: )\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 62:\n yy.getLogger().debug(\"Lexa: )\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 63:\n yy.getLogger().debug(\"Lexc: >\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 64:\n yy.getLogger().debug(\"Lexa: ([\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 65:\n yy.getLogger().debug(\"Lexa: )\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 66:\n this.pushState(\"NODE\");\n return 36;\n break;\n case 67:\n this.pushState(\"NODE\");\n return 36;\n break;\n case 68:\n this.pushState(\"NODE\");\n return 36;\n break;\n case 69:\n this.pushState(\"NODE\");\n return 36;\n break;\n case 70:\n this.pushState(\"NODE\");\n return 36;\n break;\n case 71:\n this.pushState(\"NODE\");\n return 36;\n break;\n case 72:\n this.pushState(\"NODE\");\n return 36;\n break;\n case 73:\n yy.getLogger().debug(\"Lexa: [\");\n this.pushState(\"NODE\");\n return 36;\n break;\n case 74:\n this.pushState(\"BLOCK_ARROW\");\n yy.getLogger().debug(\"LEX ARR START\");\n return 38;\n break;\n case 75:\n yy.getLogger().debug(\"Lex: NODE_ID\", yy_.yytext);\n return 32;\n break;\n case 76:\n yy.getLogger().debug(\"Lex: EOF\", yy_.yytext);\n return 8;\n break;\n case 77:\n this.pushState(\"md_string\");\n break;\n case 78:\n this.pushState(\"md_string\");\n break;\n case 79:\n return \"NODE_DESCR\";\n break;\n case 80:\n this.popState();\n break;\n case 81:\n yy.getLogger().debug(\"Lex: Starting string\");\n this.pushState(\"string\");\n break;\n case 82:\n yy.getLogger().debug(\"LEX ARR: Starting string\");\n this.pushState(\"string\");\n break;\n case 83:\n yy.getLogger().debug(\"LEX: NODE_DESCR:\", yy_.yytext);\n return \"NODE_DESCR\";\n break;\n case 84:\n yy.getLogger().debug(\"LEX POPPING\");\n this.popState();\n break;\n case 85:\n yy.getLogger().debug(\"Lex: =>BAE\");\n this.pushState(\"ARROW_DIR\");\n break;\n case 86:\n yy_.yytext = yy_.yytext.replace(/^,\\s*/, \"\");\n yy.getLogger().debug(\"Lex (right): dir:\", yy_.yytext);\n return \"DIR\";\n break;\n case 87:\n yy_.yytext = yy_.yytext.replace(/^,\\s*/, \"\");\n yy.getLogger().debug(\"Lex (left):\", yy_.yytext);\n return \"DIR\";\n break;\n case 88:\n yy_.yytext = yy_.yytext.replace(/^,\\s*/, \"\");\n yy.getLogger().debug(\"Lex (x):\", yy_.yytext);\n return \"DIR\";\n break;\n case 89:\n yy_.yytext = yy_.yytext.replace(/^,\\s*/, \"\");\n yy.getLogger().debug(\"Lex (y):\", yy_.yytext);\n return \"DIR\";\n break;\n case 90:\n yy_.yytext = yy_.yytext.replace(/^,\\s*/, \"\");\n yy.getLogger().debug(\"Lex (up):\", yy_.yytext);\n return \"DIR\";\n break;\n case 91:\n yy_.yytext = yy_.yytext.replace(/^,\\s*/, \"\");\n yy.getLogger().debug(\"Lex (down):\", yy_.yytext);\n return \"DIR\";\n break;\n case 92:\n yy_.yytext = \"]>\";\n yy.getLogger().debug(\"Lex (ARROW_DIR end):\", yy_.yytext);\n this.popState();\n this.popState();\n return \"BLOCK_ARROW_END\";\n break;\n case 93:\n yy.getLogger().debug(\"Lex: LINK\", \"#\" + yy_.yytext + \"#\");\n return 15;\n break;\n case 94:\n yy.getLogger().debug(\"Lex: LINK\", yy_.yytext);\n return 15;\n break;\n case 95:\n yy.getLogger().debug(\"Lex: LINK\", yy_.yytext);\n return 15;\n break;\n case 96:\n yy.getLogger().debug(\"Lex: LINK\", yy_.yytext);\n return 15;\n break;\n case 97:\n yy.getLogger().debug(\"Lex: START_LINK\", yy_.yytext);\n this.pushState(\"LLABEL\");\n return 16;\n break;\n case 98:\n yy.getLogger().debug(\"Lex: START_LINK\", yy_.yytext);\n this.pushState(\"LLABEL\");\n return 16;\n break;\n case 99:\n yy.getLogger().debug(\"Lex: START_LINK\", yy_.yytext);\n this.pushState(\"LLABEL\");\n return 16;\n break;\n case 100:\n this.pushState(\"md_string\");\n break;\n case 101:\n yy.getLogger().debug(\"Lex: Starting string\");\n this.pushState(\"string\");\n return \"LINK_LABEL\";\n break;\n case 102:\n this.popState();\n yy.getLogger().debug(\"Lex: LINK\", \"#\" + yy_.yytext + \"#\");\n return 15;\n break;\n case 103:\n this.popState();\n yy.getLogger().debug(\"Lex: LINK\", yy_.yytext);\n return 15;\n break;\n case 104:\n this.popState();\n yy.getLogger().debug(\"Lex: LINK\", yy_.yytext);\n return 15;\n break;\n case 105:\n yy.getLogger().debug(\"Lex: COLON\", yy_.yytext);\n yy_.yytext = yy_.yytext.slice(1);\n return 27;\n break;\n }\n }, \"anonymous\"),\n rules: [/^(?:block-beta\\b)/, /^(?:block\\s+)/, /^(?:block\\n+)/, /^(?:block:)/, /^(?:[\\s]+)/, /^(?:[\\n]+)/, /^(?:((\\u000D\\u000A)|(\\u000A)))/, /^(?:columns\\s+auto\\b)/, /^(?:columns\\s+[\\d]+)/, /^(?:[\"][`])/, /^(?:[^`\"]+)/, /^(?:[`][\"])/, /^(?:[\"])/, /^(?:[\"])/, /^(?:[^\"]*)/, /^(?:space[:]\\d+)/, /^(?:space\\b)/, /^(?:default\\b)/, /^(?:linkStyle\\b)/, /^(?:interpolate\\b)/, /^(?:classDef\\s+)/, /^(?:DEFAULT\\s+)/, /^(?:\\w+\\s+)/, /^(?:[^\\n]*)/, /^(?:class\\s+)/, /^(?:(\\w+)+((,\\s*\\w+)*))/, /^(?:[^\\n]*)/, /^(?:style\\s+)/, /^(?:(\\w+)+((,\\s*\\w+)*))/, /^(?:[^\\n]*)/, /^(?:accTitle\\s*:\\s*)/, /^(?:(?!\\n||)*[^\\n]*)/, /^(?:accDescr\\s*:\\s*)/, /^(?:(?!\\n||)*[^\\n]*)/, /^(?:accDescr\\s*\\{\\s*)/, /^(?:[\\}])/, /^(?:[^\\}]*)/, /^(?:end\\b\\s*)/, /^(?:\\(\\(\\()/, /^(?:\\)\\)\\))/, /^(?:[\\)]\\))/, /^(?:\\}\\})/, /^(?:\\})/, /^(?:\\(-)/, /^(?:-\\))/, /^(?:\\(\\()/, /^(?:\\]\\])/, /^(?:\\()/, /^(?:\\]\\))/, /^(?:\\\\\\])/, /^(?:\\/\\])/, /^(?:\\)\\])/, /^(?:[\\)])/, /^(?:\\]>)/, /^(?:[\\]])/, /^(?:-\\))/, /^(?:\\(-)/, /^(?:\\)\\))/, /^(?:\\))/, /^(?:\\(\\(\\()/, /^(?:\\(\\()/, /^(?:\\{\\{)/, /^(?:\\{)/, /^(?:>)/, /^(?:\\(\\[)/, /^(?:\\()/, /^(?:\\[\\[)/, /^(?:\\[\\|)/, /^(?:\\[\\()/, /^(?:\\)\\)\\))/, /^(?:\\[\\\\)/, /^(?:\\[\\/)/, /^(?:\\[\\\\)/, /^(?:\\[)/, /^(?:<\\[)/, /^(?:[^\\(\\[\\n\\-\\)\\{\\}\\s\\<\\>:]+)/, /^(?:$)/, /^(?:[\"][`])/, /^(?:[\"][`])/, /^(?:[^`\"]+)/, /^(?:[`][\"])/, /^(?:[\"])/, /^(?:[\"])/, /^(?:[^\"]+)/, /^(?:[\"])/, /^(?:\\]>\\s*\\()/, /^(?:,?\\s*right\\s*)/, /^(?:,?\\s*left\\s*)/, /^(?:,?\\s*x\\s*)/, /^(?:,?\\s*y\\s*)/, /^(?:,?\\s*up\\s*)/, /^(?:,?\\s*down\\s*)/, /^(?:\\)\\s*)/, /^(?:\\s*[xo<]?--+[-xo>]\\s*)/, /^(?:\\s*[xo<]?==+[=xo>]\\s*)/, /^(?:\\s*[xo<]?-?\\.+-[xo>]?\\s*)/, /^(?:\\s*~~[\\~]+\\s*)/, /^(?:\\s*[xo<]?--\\s*)/, /^(?:\\s*[xo<]?==\\s*)/, /^(?:\\s*[xo<]?-\\.\\s*)/, /^(?:[\"][`])/, /^(?:[\"])/, /^(?:\\s*[xo<]?--+[-xo>]\\s*)/, /^(?:\\s*[xo<]?==+[=xo>]\\s*)/, /^(?:\\s*[xo<]?-?\\.+-[xo>]?\\s*)/, /^(?::\\d+)/],\n conditions: { \"STYLE_DEFINITION\": { \"rules\": [29], \"inclusive\": false }, \"STYLE_STMNT\": { \"rules\": [28], \"inclusive\": false }, \"CLASSDEFID\": { \"rules\": [23], \"inclusive\": false }, \"CLASSDEF\": { \"rules\": [21, 22], \"inclusive\": false }, \"CLASS_STYLE\": { \"rules\": [26], \"inclusive\": false }, \"CLASS\": { \"rules\": [25], \"inclusive\": false }, \"LLABEL\": { \"rules\": [100, 101, 102, 103, 104], \"inclusive\": false }, \"ARROW_DIR\": { \"rules\": [86, 87, 88, 89, 90, 91, 92], \"inclusive\": false }, \"BLOCK_ARROW\": { \"rules\": [77, 82, 85], \"inclusive\": false }, \"NODE\": { \"rules\": [38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 78, 81], \"inclusive\": false }, \"md_string\": { \"rules\": [10, 11, 79, 80], \"inclusive\": false }, \"space\": { \"rules\": [], \"inclusive\": false }, \"string\": { \"rules\": [13, 14, 83, 84], \"inclusive\": false }, \"acc_descr_multiline\": { \"rules\": [35, 36], \"inclusive\": false }, \"acc_descr\": { \"rules\": [33], \"inclusive\": false }, \"acc_title\": { \"rules\": [31], \"inclusive\": false }, \"INITIAL\": { \"rules\": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 20, 24, 27, 30, 32, 34, 37, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 93, 94, 95, 96, 97, 98, 99, 105], \"inclusive\": true } }\n };\n return lexer2;\n }();\n parser2.lexer = lexer;\n function Parser() {\n this.yy = {};\n }\n __name(Parser, \"Parser\");\n Parser.prototype = parser2;\n parser2.Parser = Parser;\n return new Parser();\n}();\nparser.parser = parser;\nvar block_default = parser;\n\n// src/diagrams/block/blockDB.ts\nimport clone from \"lodash-es/clone.js\";\nvar blockDatabase = /* @__PURE__ */ new Map();\nvar edgeList = [];\nvar edgeCount = /* @__PURE__ */ new Map();\nvar COLOR_KEYWORD = \"color\";\nvar FILL_KEYWORD = \"fill\";\nvar BG_FILL = \"bgFill\";\nvar STYLECLASS_SEP = \",\";\nvar config = getConfig2();\nvar classes = /* @__PURE__ */ new Map();\nvar sanitizeText = /* @__PURE__ */ __name((txt) => common_default.sanitizeText(txt, config), \"sanitizeText\");\nvar addStyleClass = /* @__PURE__ */ __name(function(id, styleAttributes = \"\") {\n let foundClass = classes.get(id);\n if (!foundClass) {\n foundClass = { id, styles: [], textStyles: [] };\n classes.set(id, foundClass);\n }\n if (styleAttributes !== void 0 && styleAttributes !== null) {\n styleAttributes.split(STYLECLASS_SEP).forEach((attrib) => {\n const fixedAttrib = attrib.replace(/([^;]*);/, \"$1\").trim();\n if (RegExp(COLOR_KEYWORD).exec(attrib)) {\n const newStyle1 = fixedAttrib.replace(FILL_KEYWORD, BG_FILL);\n const newStyle2 = newStyle1.replace(COLOR_KEYWORD, FILL_KEYWORD);\n foundClass.textStyles.push(newStyle2);\n }\n foundClass.styles.push(fixedAttrib);\n });\n }\n}, \"addStyleClass\");\nvar addStyle2Node = /* @__PURE__ */ __name(function(id, styles = \"\") {\n const foundBlock = blockDatabase.get(id);\n if (styles !== void 0 && styles !== null) {\n foundBlock.styles = styles.split(STYLECLASS_SEP);\n }\n}, \"addStyle2Node\");\nvar setCssClass = /* @__PURE__ */ __name(function(itemIds, cssClassName) {\n itemIds.split(\",\").forEach(function(id) {\n let foundBlock = blockDatabase.get(id);\n if (foundBlock === void 0) {\n const trimmedId = id.trim();\n foundBlock = { id: trimmedId, type: \"na\", children: [] };\n blockDatabase.set(trimmedId, foundBlock);\n }\n if (!foundBlock.classes) {\n foundBlock.classes = [];\n }\n foundBlock.classes.push(cssClassName);\n });\n}, \"setCssClass\");\nvar populateBlockDatabase = /* @__PURE__ */ __name((_blockList, parent) => {\n const blockList = _blockList.flat();\n const children = [];\n for (const block of blockList) {\n if (block.label) {\n block.label = sanitizeText(block.label);\n }\n if (block.type === \"classDef\") {\n addStyleClass(block.id, block.css);\n continue;\n }\n if (block.type === \"applyClass\") {\n setCssClass(block.id, block?.styleClass ?? \"\");\n continue;\n }\n if (block.type === \"applyStyles\") {\n if (block?.stylesStr) {\n addStyle2Node(block.id, block?.stylesStr);\n }\n continue;\n }\n if (block.type === \"column-setting\") {\n parent.columns = block.columns ?? -1;\n } else if (block.type === \"edge\") {\n const count = (edgeCount.get(block.id) ?? 0) + 1;\n edgeCount.set(block.id, count);\n block.id = count + \"-\" + block.id;\n edgeList.push(block);\n } else {\n if (!block.label) {\n if (block.type === \"composite\") {\n block.label = \"\";\n } else {\n block.label = block.id;\n }\n }\n const existingBlock = blockDatabase.get(block.id);\n if (existingBlock === void 0) {\n blockDatabase.set(block.id, block);\n } else {\n if (block.type !== \"na\") {\n existingBlock.type = block.type;\n }\n if (block.label !== block.id) {\n existingBlock.label = block.label;\n }\n }\n if (block.children) {\n populateBlockDatabase(block.children, block);\n }\n if (block.type === \"space\") {\n const w = block.width ?? 1;\n for (let j = 0; j < w; j++) {\n const newBlock = clone(block);\n newBlock.id = newBlock.id + \"-\" + j;\n blockDatabase.set(newBlock.id, newBlock);\n children.push(newBlock);\n }\n } else if (existingBlock === void 0) {\n children.push(block);\n }\n }\n }\n parent.children = children;\n}, \"populateBlockDatabase\");\nvar blocks = [];\nvar rootBlock = { id: \"root\", type: \"composite\", children: [], columns: -1 };\nvar clear2 = /* @__PURE__ */ __name(() => {\n log.debug(\"Clear called\");\n clear();\n rootBlock = { id: \"root\", type: \"composite\", children: [], columns: -1 };\n blockDatabase = /* @__PURE__ */ new Map([[\"root\", rootBlock]]);\n blocks = [];\n classes = /* @__PURE__ */ new Map();\n edgeList = [];\n edgeCount = /* @__PURE__ */ new Map();\n}, \"clear\");\nfunction typeStr2Type(typeStr) {\n log.debug(\"typeStr2Type\", typeStr);\n switch (typeStr) {\n case \"[]\":\n return \"square\";\n case \"()\":\n log.debug(\"we have a round\");\n return \"round\";\n case \"(())\":\n return \"circle\";\n case \">]\":\n return \"rect_left_inv_arrow\";\n case \"{}\":\n return \"diamond\";\n case \"{{}}\":\n return \"hexagon\";\n case \"([])\":\n return \"stadium\";\n case \"[[]]\":\n return \"subroutine\";\n case \"[()]\":\n return \"cylinder\";\n case \"((()))\":\n return \"doublecircle\";\n case \"[//]\":\n return \"lean_right\";\n case \"[\\\\\\\\]\":\n return \"lean_left\";\n case \"[/\\\\]\":\n return \"trapezoid\";\n case \"[\\\\/]\":\n return \"inv_trapezoid\";\n case \"<[]>\":\n return \"block_arrow\";\n default:\n return \"na\";\n }\n}\n__name(typeStr2Type, \"typeStr2Type\");\nfunction edgeTypeStr2Type(typeStr) {\n log.debug(\"typeStr2Type\", typeStr);\n switch (typeStr) {\n case \"==\":\n return \"thick\";\n default:\n return \"normal\";\n }\n}\n__name(edgeTypeStr2Type, \"edgeTypeStr2Type\");\nfunction edgeStrToEdgeData(typeStr) {\n switch (typeStr.trim()) {\n case \"--x\":\n return \"arrow_cross\";\n case \"--o\":\n return \"arrow_circle\";\n default:\n return \"arrow_point\";\n }\n}\n__name(edgeStrToEdgeData, \"edgeStrToEdgeData\");\nvar cnt = 0;\nvar generateId = /* @__PURE__ */ __name(() => {\n cnt++;\n return \"id-\" + Math.random().toString(36).substr(2, 12) + \"-\" + cnt;\n}, \"generateId\");\nvar setHierarchy = /* @__PURE__ */ __name((block) => {\n rootBlock.children = block;\n populateBlockDatabase(block, rootBlock);\n blocks = rootBlock.children;\n}, \"setHierarchy\");\nvar getColumns = /* @__PURE__ */ __name((blockId) => {\n const block = blockDatabase.get(blockId);\n if (!block) {\n return -1;\n }\n if (block.columns) {\n return block.columns;\n }\n if (!block.children) {\n return -1;\n }\n return block.children.length;\n}, \"getColumns\");\nvar getBlocksFlat = /* @__PURE__ */ __name(() => {\n return [...blockDatabase.values()];\n}, \"getBlocksFlat\");\nvar getBlocks = /* @__PURE__ */ __name(() => {\n return blocks || [];\n}, \"getBlocks\");\nvar getEdges = /* @__PURE__ */ __name(() => {\n return edgeList;\n}, \"getEdges\");\nvar getBlock = /* @__PURE__ */ __name((id) => {\n return blockDatabase.get(id);\n}, \"getBlock\");\nvar setBlock = /* @__PURE__ */ __name((block) => {\n blockDatabase.set(block.id, block);\n}, \"setBlock\");\nvar getLogger = /* @__PURE__ */ __name(() => console, \"getLogger\");\nvar getClasses = /* @__PURE__ */ __name(function() {\n return classes;\n}, \"getClasses\");\nvar db = {\n getConfig: /* @__PURE__ */ __name(() => getConfig().block, \"getConfig\"),\n typeStr2Type,\n edgeTypeStr2Type,\n edgeStrToEdgeData,\n getLogger,\n getBlocksFlat,\n getBlocks,\n getEdges,\n setHierarchy,\n getBlock,\n setBlock,\n getColumns,\n getClasses,\n clear: clear2,\n generateId\n};\nvar blockDB_default = db;\n\n// src/diagrams/block/styles.ts\nimport * as khroma from \"khroma\";\nvar fade = /* @__PURE__ */ __name((color, opacity) => {\n const channel2 = khroma.channel;\n const r = channel2(color, \"r\");\n const g = channel2(color, \"g\");\n const b = channel2(color, \"b\");\n return khroma.rgba(r, g, b, opacity);\n}, \"fade\");\nvar getStyles = /* @__PURE__ */ __name((options) => `.label {\n font-family: ${options.fontFamily};\n color: ${options.nodeTextColor || options.textColor};\n }\n .cluster-label text {\n fill: ${options.titleColor};\n }\n .cluster-label span,p {\n color: ${options.titleColor};\n }\n\n\n\n .label text,span,p {\n fill: ${options.nodeTextColor || options.textColor};\n color: ${options.nodeTextColor || options.textColor};\n }\n\n .node rect,\n .node circle,\n .node ellipse,\n .node polygon,\n .node path {\n fill: ${options.mainBkg};\n stroke: ${options.nodeBorder};\n stroke-width: 1px;\n }\n .flowchart-label text {\n text-anchor: middle;\n }\n // .flowchart-label .text-outer-tspan {\n // text-anchor: middle;\n // }\n // .flowchart-label .text-inner-tspan {\n // text-anchor: start;\n // }\n\n .node .label {\n text-align: center;\n }\n .node.clickable {\n cursor: pointer;\n }\n\n .arrowheadPath {\n fill: ${options.arrowheadColor};\n }\n\n .edgePath .path {\n stroke: ${options.lineColor};\n stroke-width: 2.0px;\n }\n\n .flowchart-link {\n stroke: ${options.lineColor};\n fill: none;\n }\n\n .edgeLabel {\n background-color: ${options.edgeLabelBackground};\n rect {\n opacity: 0.5;\n background-color: ${options.edgeLabelBackground};\n fill: ${options.edgeLabelBackground};\n }\n text-align: center;\n }\n\n /* For html labels only */\n .labelBkg {\n background-color: ${fade(options.edgeLabelBackground, 0.5)};\n // background-color:\n }\n\n .node .cluster {\n // fill: ${fade(options.mainBkg, 0.5)};\n fill: ${fade(options.clusterBkg, 0.5)};\n stroke: ${fade(options.clusterBorder, 0.2)};\n box-shadow: rgba(50, 50, 93, 0.25) 0px 13px 27px -5px, rgba(0, 0, 0, 0.3) 0px 8px 16px -8px;\n stroke-width: 1px;\n }\n\n .cluster text {\n fill: ${options.titleColor};\n }\n\n .cluster span,p {\n color: ${options.titleColor};\n }\n /* .cluster div {\n color: ${options.titleColor};\n } */\n\n div.mermaidTooltip {\n position: absolute;\n text-align: center;\n max-width: 200px;\n padding: 2px;\n font-family: ${options.fontFamily};\n font-size: 12px;\n background: ${options.tertiaryColor};\n border: 1px solid ${options.border2};\n border-radius: 2px;\n pointer-events: none;\n z-index: 100;\n }\n\n .flowchartTitleText {\n text-anchor: middle;\n font-size: 18px;\n fill: ${options.textColor};\n }\n`, \"getStyles\");\nvar styles_default = getStyles;\n\n// src/diagrams/block/blockRenderer.ts\nimport { select as d3select } from \"d3\";\n\n// src/diagrams/block/layout.ts\nvar padding = getConfig2()?.block?.padding ?? 8;\nfunction calculateBlockPosition(columns, position) {\n if (columns === 0 || !Number.isInteger(columns)) {\n throw new Error(\"Columns must be an integer !== 0.\");\n }\n if (position < 0 || !Number.isInteger(position)) {\n throw new Error(\"Position must be a non-negative integer.\" + position);\n }\n if (columns < 0) {\n return { px: position, py: 0 };\n }\n if (columns === 1) {\n return { px: 0, py: position };\n }\n const px = position % columns;\n const py = Math.floor(position / columns);\n return { px, py };\n}\n__name(calculateBlockPosition, \"calculateBlockPosition\");\nvar getMaxChildSize = /* @__PURE__ */ __name((block) => {\n let maxWidth = 0;\n let maxHeight = 0;\n for (const child of block.children) {\n const { width, height, x, y } = child.size ?? { width: 0, height: 0, x: 0, y: 0 };\n log.debug(\n \"getMaxChildSize abc95 child:\",\n child.id,\n \"width:\",\n width,\n \"height:\",\n height,\n \"x:\",\n x,\n \"y:\",\n y,\n child.type\n );\n if (child.type === \"space\") {\n continue;\n }\n if (width > maxWidth) {\n maxWidth = width / (block.widthInColumns ?? 1);\n }\n if (height > maxHeight) {\n maxHeight = height;\n }\n }\n return { width: maxWidth, height: maxHeight };\n}, \"getMaxChildSize\");\nfunction setBlockSizes(block, db2, siblingWidth = 0, siblingHeight = 0) {\n log.debug(\n \"setBlockSizes abc95 (start)\",\n block.id,\n block?.size?.x,\n \"block width =\",\n block?.size,\n \"sieblingWidth\",\n siblingWidth\n );\n if (!block?.size?.width) {\n block.size = {\n width: siblingWidth,\n height: siblingHeight,\n x: 0,\n y: 0\n };\n }\n let maxWidth = 0;\n let maxHeight = 0;\n if (block.children?.length > 0) {\n for (const child of block.children) {\n setBlockSizes(child, db2);\n }\n const childSize = getMaxChildSize(block);\n maxWidth = childSize.width;\n maxHeight = childSize.height;\n log.debug(\"setBlockSizes abc95 maxWidth of\", block.id, \":s children is \", maxWidth, maxHeight);\n for (const child of block.children) {\n if (child.size) {\n log.debug(\n `abc95 Setting size of children of ${block.id} id=${child.id} ${maxWidth} ${maxHeight} ${JSON.stringify(child.size)}`\n );\n child.size.width = maxWidth * (child.widthInColumns ?? 1) + padding * ((child.widthInColumns ?? 1) - 1);\n child.size.height = maxHeight;\n child.size.x = 0;\n child.size.y = 0;\n log.debug(\n `abc95 updating size of ${block.id} children child:${child.id} maxWidth:${maxWidth} maxHeight:${maxHeight}`\n );\n }\n }\n for (const child of block.children) {\n setBlockSizes(child, db2, maxWidth, maxHeight);\n }\n const columns = block.columns ?? -1;\n let numItems = 0;\n for (const child of block.children) {\n numItems += child.widthInColumns ?? 1;\n }\n let xSize = block.children.length;\n if (columns > 0 && columns < numItems) {\n xSize = columns;\n }\n const ySize = Math.ceil(numItems / xSize);\n let width = xSize * (maxWidth + padding) + padding;\n let height = ySize * (maxHeight + padding) + padding;\n if (width < siblingWidth) {\n log.debug(\n `Detected to small siebling: abc95 ${block.id} sieblingWidth ${siblingWidth} sieblingHeight ${siblingHeight} width ${width}`\n );\n width = siblingWidth;\n height = siblingHeight;\n const childWidth = (siblingWidth - xSize * padding - padding) / xSize;\n const childHeight = (siblingHeight - ySize * padding - padding) / ySize;\n log.debug(\"Size indata abc88\", block.id, \"childWidth\", childWidth, \"maxWidth\", maxWidth);\n log.debug(\"Size indata abc88\", block.id, \"childHeight\", childHeight, \"maxHeight\", maxHeight);\n log.debug(\"Size indata abc88 xSize\", xSize, \"padding\", padding);\n for (const child of block.children) {\n if (child.size) {\n child.size.width = childWidth;\n child.size.height = childHeight;\n child.size.x = 0;\n child.size.y = 0;\n }\n }\n }\n log.debug(\n `abc95 (finale calc) ${block.id} xSize ${xSize} ySize ${ySize} columns ${columns}${block.children.length} width=${Math.max(width, block.size?.width || 0)}`\n );\n if (width < (block?.size?.width || 0)) {\n width = block?.size?.width || 0;\n const num = columns > 0 ? Math.min(block.children.length, columns) : block.children.length;\n if (num > 0) {\n const childWidth = (width - num * padding - padding) / num;\n log.debug(\"abc95 (growing to fit) width\", block.id, width, block.size?.width, childWidth);\n for (const child of block.children) {\n if (child.size) {\n child.size.width = childWidth;\n }\n }\n }\n }\n block.size = {\n width,\n height,\n x: 0,\n y: 0\n };\n }\n log.debug(\n \"setBlockSizes abc94 (done)\",\n block.id,\n block?.size?.x,\n block?.size?.width,\n block?.size?.y,\n block?.size?.height\n );\n}\n__name(setBlockSizes, \"setBlockSizes\");\nfunction layoutBlocks(block, db2) {\n log.debug(\n `abc85 layout blocks (=>layoutBlocks) ${block.id} x: ${block?.size?.x} y: ${block?.size?.y} width: ${block?.size?.width}`\n );\n const columns = block.columns ?? -1;\n log.debug(\"layoutBlocks columns abc95\", block.id, \"=>\", columns, block);\n if (block.children && // find max width of children\n block.children.length > 0) {\n const width = block?.children[0]?.size?.width ?? 0;\n const widthOfChildren = block.children.length * width + (block.children.length - 1) * padding;\n log.debug(\"widthOfChildren 88\", widthOfChildren, \"posX\");\n let columnPos = 0;\n log.debug(\"abc91 block?.size?.x\", block.id, block?.size?.x);\n let startingPosX = block?.size?.x ? block?.size?.x + (-block?.size?.width / 2 || 0) : -padding;\n let rowPos = 0;\n for (const child of block.children) {\n const parent = block;\n if (!child.size) {\n continue;\n }\n const { width: width2, height } = child.size;\n const { px, py } = calculateBlockPosition(columns, columnPos);\n if (py != rowPos) {\n rowPos = py;\n startingPosX = block?.size?.x ? block?.size?.x + (-block?.size?.width / 2 || 0) : -padding;\n log.debug(\"New row in layout for block\", block.id, \" and child \", child.id, rowPos);\n }\n log.debug(\n `abc89 layout blocks (child) id: ${child.id} Pos: ${columnPos} (px, py) ${px},${py} (${parent?.size?.x},${parent?.size?.y}) parent: ${parent.id} width: ${width2}${padding}`\n );\n if (parent.size) {\n const halfWidth = width2 / 2;\n child.size.x = startingPosX + padding + halfWidth;\n log.debug(\n `abc91 layout blocks (calc) px, pyid:${child.id} startingPos=X${startingPosX} new startingPosX${child.size.x} ${halfWidth} padding=${padding} width=${width2} halfWidth=${halfWidth} => x:${child.size.x} y:${child.size.y} ${child.widthInColumns} (width * (child?.w || 1)) / 2 ${width2 * (child?.widthInColumns ?? 1) / 2}`\n );\n startingPosX = child.size.x + halfWidth;\n child.size.y = parent.size.y - parent.size.height / 2 + py * (height + padding) + height / 2 + padding;\n log.debug(\n `abc88 layout blocks (calc) px, pyid:${child.id}startingPosX${startingPosX}${padding}${halfWidth}=>x:${child.size.x}y:${child.size.y}${child.widthInColumns}(width * (child?.w || 1)) / 2${width2 * (child?.widthInColumns ?? 1) / 2}`\n );\n }\n if (child.children) {\n layoutBlocks(child, db2);\n }\n columnPos += child?.widthInColumns ?? 1;\n log.debug(\"abc88 columnsPos\", child, columnPos);\n }\n }\n log.debug(\n `layout blocks (<==layoutBlocks) ${block.id} x: ${block?.size?.x} y: ${block?.size?.y} width: ${block?.size?.width}`\n );\n}\n__name(layoutBlocks, \"layoutBlocks\");\nfunction findBounds(block, { minX, minY, maxX, maxY } = { minX: 0, minY: 0, maxX: 0, maxY: 0 }) {\n if (block.size && block.id !== \"root\") {\n const { x, y, width, height } = block.size;\n if (x - width / 2 < minX) {\n minX = x - width / 2;\n }\n if (y - height / 2 < minY) {\n minY = y - height / 2;\n }\n if (x + width / 2 > maxX) {\n maxX = x + width / 2;\n }\n if (y + height / 2 > maxY) {\n maxY = y + height / 2;\n }\n }\n if (block.children) {\n for (const child of block.children) {\n ({ minX, minY, maxX, maxY } = findBounds(child, { minX, minY, maxX, maxY }));\n }\n }\n return { minX, minY, maxX, maxY };\n}\n__name(findBounds, \"findBounds\");\nfunction layout(db2) {\n const root = db2.getBlock(\"root\");\n if (!root) {\n return;\n }\n setBlockSizes(root, db2, 0, 0);\n layoutBlocks(root, db2);\n log.debug(\"getBlocks\", JSON.stringify(root, null, 2));\n const { minX, minY, maxX, maxY } = findBounds(root);\n const height = maxY - minY;\n const width = maxX - minX;\n return { x: minX, y: minY, width, height };\n}\n__name(layout, \"layout\");\n\n// src/diagrams/block/renderHelpers.ts\nimport * as graphlib from \"dagre-d3-es/src/graphlib/index.js\";\nfunction getNodeFromBlock(block, db2, positioned = false) {\n const vertex = block;\n let classStr = \"default\";\n if ((vertex?.classes?.length || 0) > 0) {\n classStr = (vertex?.classes ?? []).join(\" \");\n }\n classStr = classStr + \" flowchart-label\";\n let radius = 0;\n let shape = \"\";\n let padding2;\n switch (vertex.type) {\n case \"round\":\n radius = 5;\n shape = \"rect\";\n break;\n case \"composite\":\n radius = 0;\n shape = \"composite\";\n padding2 = 0;\n break;\n case \"square\":\n shape = \"rect\";\n break;\n case \"diamond\":\n shape = \"question\";\n break;\n case \"hexagon\":\n shape = \"hexagon\";\n break;\n case \"block_arrow\":\n shape = \"block_arrow\";\n break;\n case \"odd\":\n shape = \"rect_left_inv_arrow\";\n break;\n case \"lean_right\":\n shape = \"lean_right\";\n break;\n case \"lean_left\":\n shape = \"lean_left\";\n break;\n case \"trapezoid\":\n shape = \"trapezoid\";\n break;\n case \"inv_trapezoid\":\n shape = \"inv_trapezoid\";\n break;\n case \"rect_left_inv_arrow\":\n shape = \"rect_left_inv_arrow\";\n break;\n case \"circle\":\n shape = \"circle\";\n break;\n case \"ellipse\":\n shape = \"ellipse\";\n break;\n case \"stadium\":\n shape = \"stadium\";\n break;\n case \"subroutine\":\n shape = \"subroutine\";\n break;\n case \"cylinder\":\n shape = \"cylinder\";\n break;\n case \"group\":\n shape = \"rect\";\n break;\n case \"doublecircle\":\n shape = \"doublecircle\";\n break;\n default:\n shape = \"rect\";\n }\n const styles = getStylesFromArray(vertex?.styles ?? []);\n const vertexText = vertex.label;\n const bounds = vertex.size ?? { width: 0, height: 0, x: 0, y: 0 };\n const node = {\n labelStyle: styles.labelStyle,\n shape,\n labelText: vertexText,\n rx: radius,\n ry: radius,\n class: classStr,\n style: styles.style,\n id: vertex.id,\n directions: vertex.directions,\n width: bounds.width,\n height: bounds.height,\n x: bounds.x,\n y: bounds.y,\n positioned,\n intersect: void 0,\n type: vertex.type,\n padding: padding2 ?? getConfig()?.block?.padding ?? 0\n };\n return node;\n}\n__name(getNodeFromBlock, \"getNodeFromBlock\");\nasync function calculateBlockSize(elem, block, db2) {\n const node = getNodeFromBlock(block, db2, false);\n if (node.type === \"group\") {\n return;\n }\n const nodeEl = await insertNode(elem, node);\n const boundingBox = nodeEl.node().getBBox();\n const obj = db2.getBlock(node.id);\n obj.size = { width: boundingBox.width, height: boundingBox.height, x: 0, y: 0, node: nodeEl };\n db2.setBlock(obj);\n nodeEl.remove();\n}\n__name(calculateBlockSize, \"calculateBlockSize\");\nasync function insertBlockPositioned(elem, block, db2) {\n const node = getNodeFromBlock(block, db2, true);\n const obj = db2.getBlock(node.id);\n if (obj.type !== \"space\") {\n await insertNode(elem, node);\n block.intersect = node?.intersect;\n positionNode(node);\n }\n}\n__name(insertBlockPositioned, \"insertBlockPositioned\");\nasync function performOperations(elem, blocks2, db2, operation) {\n for (const block of blocks2) {\n await operation(elem, block, db2);\n if (block.children) {\n await performOperations(elem, block.children, db2, operation);\n }\n }\n}\n__name(performOperations, \"performOperations\");\nasync function calculateBlockSizes(elem, blocks2, db2) {\n await performOperations(elem, blocks2, db2, calculateBlockSize);\n}\n__name(calculateBlockSizes, \"calculateBlockSizes\");\nasync function insertBlocks(elem, blocks2, db2) {\n await performOperations(elem, blocks2, db2, insertBlockPositioned);\n}\n__name(insertBlocks, \"insertBlocks\");\nasync function insertEdges(elem, edges, blocks2, db2, id) {\n const g = new graphlib.Graph({\n multigraph: true,\n compound: true\n });\n g.setGraph({\n rankdir: \"TB\",\n nodesep: 10,\n ranksep: 10,\n marginx: 8,\n marginy: 8\n });\n for (const block of blocks2) {\n if (block.size) {\n g.setNode(block.id, {\n width: block.size.width,\n height: block.size.height,\n intersect: block.intersect\n });\n }\n }\n for (const edge of edges) {\n if (edge.start && edge.end) {\n const startBlock = db2.getBlock(edge.start);\n const endBlock = db2.getBlock(edge.end);\n if (startBlock?.size && endBlock?.size) {\n const start = startBlock.size;\n const end = endBlock.size;\n const points = [\n { x: start.x, y: start.y },\n { x: start.x + (end.x - start.x) / 2, y: start.y + (end.y - start.y) / 2 },\n { x: end.x, y: end.y }\n ];\n insertEdge(\n elem,\n { v: edge.start, w: edge.end, name: edge.id },\n {\n ...edge,\n arrowTypeEnd: edge.arrowTypeEnd,\n arrowTypeStart: edge.arrowTypeStart,\n points,\n classes: \"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1\"\n },\n void 0,\n \"block\",\n g,\n id\n );\n if (edge.label) {\n await insertEdgeLabel(elem, {\n ...edge,\n label: edge.label,\n labelStyle: \"stroke: #333; stroke-width: 1.5px;fill:none;\",\n arrowTypeEnd: edge.arrowTypeEnd,\n arrowTypeStart: edge.arrowTypeStart,\n points,\n classes: \"edge-thickness-normal edge-pattern-solid flowchart-link LS-a1 LE-b1\"\n });\n positionEdgeLabel(\n { ...edge, x: points[1].x, y: points[1].y },\n {\n originalPath: points\n }\n );\n }\n }\n }\n }\n}\n__name(insertEdges, \"insertEdges\");\n\n// src/diagrams/block/blockRenderer.ts\nvar getClasses2 = /* @__PURE__ */ __name(function(text, diagObj) {\n return diagObj.db.getClasses();\n}, \"getClasses\");\nvar draw = /* @__PURE__ */ __name(async function(text, id, _version, diagObj) {\n const { securityLevel, block: conf } = getConfig();\n const db2 = diagObj.db;\n let sandboxElement;\n if (securityLevel === \"sandbox\") {\n sandboxElement = d3select(\"#i\" + id);\n }\n const root = securityLevel === \"sandbox\" ? d3select(sandboxElement.nodes()[0].contentDocument.body) : d3select(\"body\");\n const svg = securityLevel === \"sandbox\" ? root.select(`[id=\"${id}\"]`) : d3select(`[id=\"${id}\"]`);\n const markers = [\"point\", \"circle\", \"cross\"];\n markers_default(svg, markers, diagObj.type, id);\n const bl = db2.getBlocks();\n const blArr = db2.getBlocksFlat();\n const edges = db2.getEdges();\n const nodes = svg.insert(\"g\").attr(\"class\", \"block\");\n await calculateBlockSizes(nodes, bl, db2);\n const bounds = layout(db2);\n await insertBlocks(nodes, bl, db2);\n await insertEdges(nodes, edges, blArr, db2, id);\n if (bounds) {\n const bounds2 = bounds;\n const magicFactor = Math.max(1, Math.round(0.125 * (bounds2.width / bounds2.height)));\n const height = bounds2.height + magicFactor + 10;\n const width = bounds2.width + 10;\n const { useMaxWidth } = conf;\n configureSvgSize(svg, height, width, !!useMaxWidth);\n log.debug(\"Here Bounds\", bounds, bounds2);\n svg.attr(\n \"viewBox\",\n `${bounds2.x - 5} ${bounds2.y - 5} ${bounds2.width + 10} ${bounds2.height + 10}`\n );\n }\n}, \"draw\");\nvar blockRenderer_default = {\n draw,\n getClasses: getClasses2\n};\n\n// src/diagrams/block/blockDiagram.ts\nvar diagram = {\n parser: block_default,\n db: blockDB_default,\n renderer: blockRenderer_default,\n styles: styles_default\n};\nexport {\n diagram\n};\n", "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"layoutBase\"] = factory();\n\telse\n\t\troot[\"layoutBase\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 28);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction LayoutConstants() {}\n\n/**\r\n * Layout Quality: 0:draft, 1:default, 2:proof\r\n */\nLayoutConstants.QUALITY = 1;\n\n/**\r\n * Default parameters\r\n */\nLayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED = false;\nLayoutConstants.DEFAULT_INCREMENTAL = false;\nLayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT = true;\nLayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT = false;\nLayoutConstants.DEFAULT_ANIMATION_PERIOD = 50;\nLayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES = false;\n\n// -----------------------------------------------------------------------------\n// Section: General other constants\n// -----------------------------------------------------------------------------\n/*\r\n * Margins of a graph to be applied on bouding rectangle of its contents. We\r\n * assume margins on all four sides to be uniform.\r\n */\nLayoutConstants.DEFAULT_GRAPH_MARGIN = 15;\n\n/*\r\n * Whether to consider labels in node dimensions or not\r\n */\nLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = false;\n\n/*\r\n * Default dimension of a non-compound node.\r\n */\nLayoutConstants.SIMPLE_NODE_SIZE = 40;\n\n/*\r\n * Default dimension of a non-compound node.\r\n */\nLayoutConstants.SIMPLE_NODE_HALF_SIZE = LayoutConstants.SIMPLE_NODE_SIZE / 2;\n\n/*\r\n * Empty compound node size. When a compound node is empty, its both\r\n * dimensions should be of this value.\r\n */\nLayoutConstants.EMPTY_COMPOUND_NODE_SIZE = 40;\n\n/*\r\n * Minimum length that an edge should take during layout\r\n */\nLayoutConstants.MIN_EDGE_LENGTH = 1;\n\n/*\r\n * World boundaries that layout operates on\r\n */\nLayoutConstants.WORLD_BOUNDARY = 1000000;\n\n/*\r\n * World boundaries that random positioning can be performed with\r\n */\nLayoutConstants.INITIAL_WORLD_BOUNDARY = LayoutConstants.WORLD_BOUNDARY / 1000;\n\n/*\r\n * Coordinates of the world center\r\n */\nLayoutConstants.WORLD_CENTER_X = 1200;\nLayoutConstants.WORLD_CENTER_Y = 900;\n\nmodule.exports = LayoutConstants;\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraphObject = __webpack_require__(2);\nvar IGeometry = __webpack_require__(8);\nvar IMath = __webpack_require__(9);\n\nfunction LEdge(source, target, vEdge) {\n LGraphObject.call(this, vEdge);\n\n this.isOverlapingSourceAndTarget = false;\n this.vGraphObject = vEdge;\n this.bendpoints = [];\n this.source = source;\n this.target = target;\n}\n\nLEdge.prototype = Object.create(LGraphObject.prototype);\n\nfor (var prop in LGraphObject) {\n LEdge[prop] = LGraphObject[prop];\n}\n\nLEdge.prototype.getSource = function () {\n return this.source;\n};\n\nLEdge.prototype.getTarget = function () {\n return this.target;\n};\n\nLEdge.prototype.isInterGraph = function () {\n return this.isInterGraph;\n};\n\nLEdge.prototype.getLength = function () {\n return this.length;\n};\n\nLEdge.prototype.isOverlapingSourceAndTarget = function () {\n return this.isOverlapingSourceAndTarget;\n};\n\nLEdge.prototype.getBendpoints = function () {\n return this.bendpoints;\n};\n\nLEdge.prototype.getLca = function () {\n return this.lca;\n};\n\nLEdge.prototype.getSourceInLca = function () {\n return this.sourceInLca;\n};\n\nLEdge.prototype.getTargetInLca = function () {\n return this.targetInLca;\n};\n\nLEdge.prototype.getOtherEnd = function (node) {\n if (this.source === node) {\n return this.target;\n } else if (this.target === node) {\n return this.source;\n } else {\n throw \"Node is not incident with this edge\";\n }\n};\n\nLEdge.prototype.getOtherEndInGraph = function (node, graph) {\n var otherEnd = this.getOtherEnd(node);\n var root = graph.getGraphManager().getRoot();\n\n while (true) {\n if (otherEnd.getOwner() == graph) {\n return otherEnd;\n }\n\n if (otherEnd.getOwner() == root) {\n break;\n }\n\n otherEnd = otherEnd.getOwner().getParent();\n }\n\n return null;\n};\n\nLEdge.prototype.updateLength = function () {\n var clipPointCoordinates = new Array(4);\n\n this.isOverlapingSourceAndTarget = IGeometry.getIntersection(this.target.getRect(), this.source.getRect(), clipPointCoordinates);\n\n if (!this.isOverlapingSourceAndTarget) {\n this.lengthX = clipPointCoordinates[0] - clipPointCoordinates[2];\n this.lengthY = clipPointCoordinates[1] - clipPointCoordinates[3];\n\n if (Math.abs(this.lengthX) < 1.0) {\n this.lengthX = IMath.sign(this.lengthX);\n }\n\n if (Math.abs(this.lengthY) < 1.0) {\n this.lengthY = IMath.sign(this.lengthY);\n }\n\n this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY);\n }\n};\n\nLEdge.prototype.updateLengthSimple = function () {\n this.lengthX = this.target.getCenterX() - this.source.getCenterX();\n this.lengthY = this.target.getCenterY() - this.source.getCenterY();\n\n if (Math.abs(this.lengthX) < 1.0) {\n this.lengthX = IMath.sign(this.lengthX);\n }\n\n if (Math.abs(this.lengthY) < 1.0) {\n this.lengthY = IMath.sign(this.lengthY);\n }\n\n this.length = Math.sqrt(this.lengthX * this.lengthX + this.lengthY * this.lengthY);\n};\n\nmodule.exports = LEdge;\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction LGraphObject(vGraphObject) {\n this.vGraphObject = vGraphObject;\n}\n\nmodule.exports = LGraphObject;\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraphObject = __webpack_require__(2);\nvar Integer = __webpack_require__(10);\nvar RectangleD = __webpack_require__(13);\nvar LayoutConstants = __webpack_require__(0);\nvar RandomSeed = __webpack_require__(16);\nvar PointD = __webpack_require__(5);\n\nfunction LNode(gm, loc, size, vNode) {\n //Alternative constructor 1 : LNode(LGraphManager gm, Point loc, Dimension size, Object vNode)\n if (size == null && vNode == null) {\n vNode = loc;\n }\n\n LGraphObject.call(this, vNode);\n\n //Alternative constructor 2 : LNode(Layout layout, Object vNode)\n if (gm.graphManager != null) gm = gm.graphManager;\n\n this.estimatedSize = Integer.MIN_VALUE;\n this.inclusionTreeDepth = Integer.MAX_VALUE;\n this.vGraphObject = vNode;\n this.edges = [];\n this.graphManager = gm;\n\n if (size != null && loc != null) this.rect = new RectangleD(loc.x, loc.y, size.width, size.height);else this.rect = new RectangleD();\n}\n\nLNode.prototype = Object.create(LGraphObject.prototype);\nfor (var prop in LGraphObject) {\n LNode[prop] = LGraphObject[prop];\n}\n\nLNode.prototype.getEdges = function () {\n return this.edges;\n};\n\nLNode.prototype.getChild = function () {\n return this.child;\n};\n\nLNode.prototype.getOwner = function () {\n // if (this.owner != null) {\n // if (!(this.owner == null || this.owner.getNodes().indexOf(this) > -1)) {\n // throw \"assert failed\";\n // }\n // }\n\n return this.owner;\n};\n\nLNode.prototype.getWidth = function () {\n return this.rect.width;\n};\n\nLNode.prototype.setWidth = function (width) {\n this.rect.width = width;\n};\n\nLNode.prototype.getHeight = function () {\n return this.rect.height;\n};\n\nLNode.prototype.setHeight = function (height) {\n this.rect.height = height;\n};\n\nLNode.prototype.getCenterX = function () {\n return this.rect.x + this.rect.width / 2;\n};\n\nLNode.prototype.getCenterY = function () {\n return this.rect.y + this.rect.height / 2;\n};\n\nLNode.prototype.getCenter = function () {\n return new PointD(this.rect.x + this.rect.width / 2, this.rect.y + this.rect.height / 2);\n};\n\nLNode.prototype.getLocation = function () {\n return new PointD(this.rect.x, this.rect.y);\n};\n\nLNode.prototype.getRect = function () {\n return this.rect;\n};\n\nLNode.prototype.getDiagonal = function () {\n return Math.sqrt(this.rect.width * this.rect.width + this.rect.height * this.rect.height);\n};\n\n/**\n * This method returns half the diagonal length of this node.\n */\nLNode.prototype.getHalfTheDiagonal = function () {\n return Math.sqrt(this.rect.height * this.rect.height + this.rect.width * this.rect.width) / 2;\n};\n\nLNode.prototype.setRect = function (upperLeft, dimension) {\n this.rect.x = upperLeft.x;\n this.rect.y = upperLeft.y;\n this.rect.width = dimension.width;\n this.rect.height = dimension.height;\n};\n\nLNode.prototype.setCenter = function (cx, cy) {\n this.rect.x = cx - this.rect.width / 2;\n this.rect.y = cy - this.rect.height / 2;\n};\n\nLNode.prototype.setLocation = function (x, y) {\n this.rect.x = x;\n this.rect.y = y;\n};\n\nLNode.prototype.moveBy = function (dx, dy) {\n this.rect.x += dx;\n this.rect.y += dy;\n};\n\nLNode.prototype.getEdgeListToNode = function (to) {\n var edgeList = [];\n var edge;\n var self = this;\n\n self.edges.forEach(function (edge) {\n\n if (edge.target == to) {\n if (edge.source != self) throw \"Incorrect edge source!\";\n\n edgeList.push(edge);\n }\n });\n\n return edgeList;\n};\n\nLNode.prototype.getEdgesBetween = function (other) {\n var edgeList = [];\n var edge;\n\n var self = this;\n self.edges.forEach(function (edge) {\n\n if (!(edge.source == self || edge.target == self)) throw \"Incorrect edge source and/or target\";\n\n if (edge.target == other || edge.source == other) {\n edgeList.push(edge);\n }\n });\n\n return edgeList;\n};\n\nLNode.prototype.getNeighborsList = function () {\n var neighbors = new Set();\n\n var self = this;\n self.edges.forEach(function (edge) {\n\n if (edge.source == self) {\n neighbors.add(edge.target);\n } else {\n if (edge.target != self) {\n throw \"Incorrect incidency!\";\n }\n\n neighbors.add(edge.source);\n }\n });\n\n return neighbors;\n};\n\nLNode.prototype.withChildren = function () {\n var withNeighborsList = new Set();\n var childNode;\n var children;\n\n withNeighborsList.add(this);\n\n if (this.child != null) {\n var nodes = this.child.getNodes();\n for (var i = 0; i < nodes.length; i++) {\n childNode = nodes[i];\n children = childNode.withChildren();\n children.forEach(function (node) {\n withNeighborsList.add(node);\n });\n }\n }\n\n return withNeighborsList;\n};\n\nLNode.prototype.getNoOfChildren = function () {\n var noOfChildren = 0;\n var childNode;\n\n if (this.child == null) {\n noOfChildren = 1;\n } else {\n var nodes = this.child.getNodes();\n for (var i = 0; i < nodes.length; i++) {\n childNode = nodes[i];\n\n noOfChildren += childNode.getNoOfChildren();\n }\n }\n\n if (noOfChildren == 0) {\n noOfChildren = 1;\n }\n return noOfChildren;\n};\n\nLNode.prototype.getEstimatedSize = function () {\n if (this.estimatedSize == Integer.MIN_VALUE) {\n throw \"assert failed\";\n }\n return this.estimatedSize;\n};\n\nLNode.prototype.calcEstimatedSize = function () {\n if (this.child == null) {\n return this.estimatedSize = (this.rect.width + this.rect.height) / 2;\n } else {\n this.estimatedSize = this.child.calcEstimatedSize();\n this.rect.width = this.estimatedSize;\n this.rect.height = this.estimatedSize;\n\n return this.estimatedSize;\n }\n};\n\nLNode.prototype.scatter = function () {\n var randomCenterX;\n var randomCenterY;\n\n var minX = -LayoutConstants.INITIAL_WORLD_BOUNDARY;\n var maxX = LayoutConstants.INITIAL_WORLD_BOUNDARY;\n randomCenterX = LayoutConstants.WORLD_CENTER_X + RandomSeed.nextDouble() * (maxX - minX) + minX;\n\n var minY = -LayoutConstants.INITIAL_WORLD_BOUNDARY;\n var maxY = LayoutConstants.INITIAL_WORLD_BOUNDARY;\n randomCenterY = LayoutConstants.WORLD_CENTER_Y + RandomSeed.nextDouble() * (maxY - minY) + minY;\n\n this.rect.x = randomCenterX;\n this.rect.y = randomCenterY;\n};\n\nLNode.prototype.updateBounds = function () {\n if (this.getChild() == null) {\n throw \"assert failed\";\n }\n if (this.getChild().getNodes().length != 0) {\n // wrap the children nodes by re-arranging the boundaries\n var childGraph = this.getChild();\n childGraph.updateBounds(true);\n\n this.rect.x = childGraph.getLeft();\n this.rect.y = childGraph.getTop();\n\n this.setWidth(childGraph.getRight() - childGraph.getLeft());\n this.setHeight(childGraph.getBottom() - childGraph.getTop());\n\n // Update compound bounds considering its label properties \n if (LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS) {\n\n var width = childGraph.getRight() - childGraph.getLeft();\n var height = childGraph.getBottom() - childGraph.getTop();\n\n if (this.labelWidth) {\n if (this.labelPosHorizontal == \"left\") {\n this.rect.x -= this.labelWidth;\n this.setWidth(width + this.labelWidth);\n } else if (this.labelPosHorizontal == \"center\" && this.labelWidth > width) {\n this.rect.x -= (this.labelWidth - width) / 2;\n this.setWidth(this.labelWidth);\n } else if (this.labelPosHorizontal == \"right\") {\n this.setWidth(width + this.labelWidth);\n }\n }\n\n if (this.labelHeight) {\n if (this.labelPosVertical == \"top\") {\n this.rect.y -= this.labelHeight;\n this.setHeight(height + this.labelHeight);\n } else if (this.labelPosVertical == \"center\" && this.labelHeight > height) {\n this.rect.y -= (this.labelHeight - height) / 2;\n this.setHeight(this.labelHeight);\n } else if (this.labelPosVertical == \"bottom\") {\n this.setHeight(height + this.labelHeight);\n }\n }\n }\n }\n};\n\nLNode.prototype.getInclusionTreeDepth = function () {\n if (this.inclusionTreeDepth == Integer.MAX_VALUE) {\n throw \"assert failed\";\n }\n return this.inclusionTreeDepth;\n};\n\nLNode.prototype.transform = function (trans) {\n var left = this.rect.x;\n\n if (left > LayoutConstants.WORLD_BOUNDARY) {\n left = LayoutConstants.WORLD_BOUNDARY;\n } else if (left < -LayoutConstants.WORLD_BOUNDARY) {\n left = -LayoutConstants.WORLD_BOUNDARY;\n }\n\n var top = this.rect.y;\n\n if (top > LayoutConstants.WORLD_BOUNDARY) {\n top = LayoutConstants.WORLD_BOUNDARY;\n } else if (top < -LayoutConstants.WORLD_BOUNDARY) {\n top = -LayoutConstants.WORLD_BOUNDARY;\n }\n\n var leftTop = new PointD(left, top);\n var vLeftTop = trans.inverseTransformPoint(leftTop);\n\n this.setLocation(vLeftTop.x, vLeftTop.y);\n};\n\nLNode.prototype.getLeft = function () {\n return this.rect.x;\n};\n\nLNode.prototype.getRight = function () {\n return this.rect.x + this.rect.width;\n};\n\nLNode.prototype.getTop = function () {\n return this.rect.y;\n};\n\nLNode.prototype.getBottom = function () {\n return this.rect.y + this.rect.height;\n};\n\nLNode.prototype.getParent = function () {\n if (this.owner == null) {\n return null;\n }\n\n return this.owner.getParent();\n};\n\nmodule.exports = LNode;\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LayoutConstants = __webpack_require__(0);\n\nfunction FDLayoutConstants() {}\n\n//FDLayoutConstants inherits static props in LayoutConstants\nfor (var prop in LayoutConstants) {\n FDLayoutConstants[prop] = LayoutConstants[prop];\n}\n\nFDLayoutConstants.MAX_ITERATIONS = 2500;\n\nFDLayoutConstants.DEFAULT_EDGE_LENGTH = 50;\nFDLayoutConstants.DEFAULT_SPRING_STRENGTH = 0.45;\nFDLayoutConstants.DEFAULT_REPULSION_STRENGTH = 4500.0;\nFDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = 0.4;\nFDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = 1.0;\nFDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = 3.8;\nFDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = 1.5;\nFDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION = true;\nFDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION = true;\nFDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = 0.3;\nFDLayoutConstants.COOLING_ADAPTATION_FACTOR = 0.33;\nFDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT = 1000;\nFDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT = 5000;\nFDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL = 100.0;\nFDLayoutConstants.MAX_NODE_DISPLACEMENT = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL * 3;\nFDLayoutConstants.MIN_REPULSION_DIST = FDLayoutConstants.DEFAULT_EDGE_LENGTH / 10.0;\nFDLayoutConstants.CONVERGENCE_CHECK_PERIOD = 100;\nFDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = 0.1;\nFDLayoutConstants.MIN_EDGE_LENGTH = 1;\nFDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD = 10;\n\nmodule.exports = FDLayoutConstants;\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction PointD(x, y) {\n if (x == null && y == null) {\n this.x = 0;\n this.y = 0;\n } else {\n this.x = x;\n this.y = y;\n }\n}\n\nPointD.prototype.getX = function () {\n return this.x;\n};\n\nPointD.prototype.getY = function () {\n return this.y;\n};\n\nPointD.prototype.setX = function (x) {\n this.x = x;\n};\n\nPointD.prototype.setY = function (y) {\n this.y = y;\n};\n\nPointD.prototype.getDifference = function (pt) {\n return new DimensionD(this.x - pt.x, this.y - pt.y);\n};\n\nPointD.prototype.getCopy = function () {\n return new PointD(this.x, this.y);\n};\n\nPointD.prototype.translate = function (dim) {\n this.x += dim.width;\n this.y += dim.height;\n return this;\n};\n\nmodule.exports = PointD;\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraphObject = __webpack_require__(2);\nvar Integer = __webpack_require__(10);\nvar LayoutConstants = __webpack_require__(0);\nvar LGraphManager = __webpack_require__(7);\nvar LNode = __webpack_require__(3);\nvar LEdge = __webpack_require__(1);\nvar RectangleD = __webpack_require__(13);\nvar Point = __webpack_require__(12);\nvar LinkedList = __webpack_require__(11);\n\nfunction LGraph(parent, obj2, vGraph) {\n LGraphObject.call(this, vGraph);\n this.estimatedSize = Integer.MIN_VALUE;\n this.margin = LayoutConstants.DEFAULT_GRAPH_MARGIN;\n this.edges = [];\n this.nodes = [];\n this.isConnected = false;\n this.parent = parent;\n\n if (obj2 != null && obj2 instanceof LGraphManager) {\n this.graphManager = obj2;\n } else if (obj2 != null && obj2 instanceof Layout) {\n this.graphManager = obj2.graphManager;\n }\n}\n\nLGraph.prototype = Object.create(LGraphObject.prototype);\nfor (var prop in LGraphObject) {\n LGraph[prop] = LGraphObject[prop];\n}\n\nLGraph.prototype.getNodes = function () {\n return this.nodes;\n};\n\nLGraph.prototype.getEdges = function () {\n return this.edges;\n};\n\nLGraph.prototype.getGraphManager = function () {\n return this.graphManager;\n};\n\nLGraph.prototype.getParent = function () {\n return this.parent;\n};\n\nLGraph.prototype.getLeft = function () {\n return this.left;\n};\n\nLGraph.prototype.getRight = function () {\n return this.right;\n};\n\nLGraph.prototype.getTop = function () {\n return this.top;\n};\n\nLGraph.prototype.getBottom = function () {\n return this.bottom;\n};\n\nLGraph.prototype.isConnected = function () {\n return this.isConnected;\n};\n\nLGraph.prototype.add = function (obj1, sourceNode, targetNode) {\n if (sourceNode == null && targetNode == null) {\n var newNode = obj1;\n if (this.graphManager == null) {\n throw \"Graph has no graph mgr!\";\n }\n if (this.getNodes().indexOf(newNode) > -1) {\n throw \"Node already in graph!\";\n }\n newNode.owner = this;\n this.getNodes().push(newNode);\n\n return newNode;\n } else {\n var newEdge = obj1;\n if (!(this.getNodes().indexOf(sourceNode) > -1 && this.getNodes().indexOf(targetNode) > -1)) {\n throw \"Source or target not in graph!\";\n }\n\n if (!(sourceNode.owner == targetNode.owner && sourceNode.owner == this)) {\n throw \"Both owners must be this graph!\";\n }\n\n if (sourceNode.owner != targetNode.owner) {\n return null;\n }\n\n // set source and target\n newEdge.source = sourceNode;\n newEdge.target = targetNode;\n\n // set as intra-graph edge\n newEdge.isInterGraph = false;\n\n // add to graph edge list\n this.getEdges().push(newEdge);\n\n // add to incidency lists\n sourceNode.edges.push(newEdge);\n\n if (targetNode != sourceNode) {\n targetNode.edges.push(newEdge);\n }\n\n return newEdge;\n }\n};\n\nLGraph.prototype.remove = function (obj) {\n var node = obj;\n if (obj instanceof LNode) {\n if (node == null) {\n throw \"Node is null!\";\n }\n if (!(node.owner != null && node.owner == this)) {\n throw \"Owner graph is invalid!\";\n }\n if (this.graphManager == null) {\n throw \"Owner graph manager is invalid!\";\n }\n // remove incident edges first (make a copy to do it safely)\n var edgesToBeRemoved = node.edges.slice();\n var edge;\n var s = edgesToBeRemoved.length;\n for (var i = 0; i < s; i++) {\n edge = edgesToBeRemoved[i];\n\n if (edge.isInterGraph) {\n this.graphManager.remove(edge);\n } else {\n edge.source.owner.remove(edge);\n }\n }\n\n // now the node itself\n var index = this.nodes.indexOf(node);\n if (index == -1) {\n throw \"Node not in owner node list!\";\n }\n\n this.nodes.splice(index, 1);\n } else if (obj instanceof LEdge) {\n var edge = obj;\n if (edge == null) {\n throw \"Edge is null!\";\n }\n if (!(edge.source != null && edge.target != null)) {\n throw \"Source and/or target is null!\";\n }\n if (!(edge.source.owner != null && edge.target.owner != null && edge.source.owner == this && edge.target.owner == this)) {\n throw \"Source and/or target owner is invalid!\";\n }\n\n var sourceIndex = edge.source.edges.indexOf(edge);\n var targetIndex = edge.target.edges.indexOf(edge);\n if (!(sourceIndex > -1 && targetIndex > -1)) {\n throw \"Source and/or target doesn't know this edge!\";\n }\n\n edge.source.edges.splice(sourceIndex, 1);\n\n if (edge.target != edge.source) {\n edge.target.edges.splice(targetIndex, 1);\n }\n\n var index = edge.source.owner.getEdges().indexOf(edge);\n if (index == -1) {\n throw \"Not in owner's edge list!\";\n }\n\n edge.source.owner.getEdges().splice(index, 1);\n }\n};\n\nLGraph.prototype.updateLeftTop = function () {\n var top = Integer.MAX_VALUE;\n var left = Integer.MAX_VALUE;\n var nodeTop;\n var nodeLeft;\n var margin;\n\n var nodes = this.getNodes();\n var s = nodes.length;\n\n for (var i = 0; i < s; i++) {\n var lNode = nodes[i];\n nodeTop = lNode.getTop();\n nodeLeft = lNode.getLeft();\n\n if (top > nodeTop) {\n top = nodeTop;\n }\n\n if (left > nodeLeft) {\n left = nodeLeft;\n }\n }\n\n // Do we have any nodes in this graph?\n if (top == Integer.MAX_VALUE) {\n return null;\n }\n\n if (nodes[0].getParent().paddingLeft != undefined) {\n margin = nodes[0].getParent().paddingLeft;\n } else {\n margin = this.margin;\n }\n\n this.left = left - margin;\n this.top = top - margin;\n\n // Apply the margins and return the result\n return new Point(this.left, this.top);\n};\n\nLGraph.prototype.updateBounds = function (recursive) {\n // calculate bounds\n var left = Integer.MAX_VALUE;\n var right = -Integer.MAX_VALUE;\n var top = Integer.MAX_VALUE;\n var bottom = -Integer.MAX_VALUE;\n var nodeLeft;\n var nodeRight;\n var nodeTop;\n var nodeBottom;\n var margin;\n\n var nodes = this.nodes;\n var s = nodes.length;\n for (var i = 0; i < s; i++) {\n var lNode = nodes[i];\n\n if (recursive && lNode.child != null) {\n lNode.updateBounds();\n }\n nodeLeft = lNode.getLeft();\n nodeRight = lNode.getRight();\n nodeTop = lNode.getTop();\n nodeBottom = lNode.getBottom();\n\n if (left > nodeLeft) {\n left = nodeLeft;\n }\n\n if (right < nodeRight) {\n right = nodeRight;\n }\n\n if (top > nodeTop) {\n top = nodeTop;\n }\n\n if (bottom < nodeBottom) {\n bottom = nodeBottom;\n }\n }\n\n var boundingRect = new RectangleD(left, top, right - left, bottom - top);\n if (left == Integer.MAX_VALUE) {\n this.left = this.parent.getLeft();\n this.right = this.parent.getRight();\n this.top = this.parent.getTop();\n this.bottom = this.parent.getBottom();\n }\n\n if (nodes[0].getParent().paddingLeft != undefined) {\n margin = nodes[0].getParent().paddingLeft;\n } else {\n margin = this.margin;\n }\n\n this.left = boundingRect.x - margin;\n this.right = boundingRect.x + boundingRect.width + margin;\n this.top = boundingRect.y - margin;\n this.bottom = boundingRect.y + boundingRect.height + margin;\n};\n\nLGraph.calculateBounds = function (nodes) {\n var left = Integer.MAX_VALUE;\n var right = -Integer.MAX_VALUE;\n var top = Integer.MAX_VALUE;\n var bottom = -Integer.MAX_VALUE;\n var nodeLeft;\n var nodeRight;\n var nodeTop;\n var nodeBottom;\n\n var s = nodes.length;\n\n for (var i = 0; i < s; i++) {\n var lNode = nodes[i];\n nodeLeft = lNode.getLeft();\n nodeRight = lNode.getRight();\n nodeTop = lNode.getTop();\n nodeBottom = lNode.getBottom();\n\n if (left > nodeLeft) {\n left = nodeLeft;\n }\n\n if (right < nodeRight) {\n right = nodeRight;\n }\n\n if (top > nodeTop) {\n top = nodeTop;\n }\n\n if (bottom < nodeBottom) {\n bottom = nodeBottom;\n }\n }\n\n var boundingRect = new RectangleD(left, top, right - left, bottom - top);\n\n return boundingRect;\n};\n\nLGraph.prototype.getInclusionTreeDepth = function () {\n if (this == this.graphManager.getRoot()) {\n return 1;\n } else {\n return this.parent.getInclusionTreeDepth();\n }\n};\n\nLGraph.prototype.getEstimatedSize = function () {\n if (this.estimatedSize == Integer.MIN_VALUE) {\n throw \"assert failed\";\n }\n return this.estimatedSize;\n};\n\nLGraph.prototype.calcEstimatedSize = function () {\n var size = 0;\n var nodes = this.nodes;\n var s = nodes.length;\n\n for (var i = 0; i < s; i++) {\n var lNode = nodes[i];\n size += lNode.calcEstimatedSize();\n }\n\n if (size == 0) {\n this.estimatedSize = LayoutConstants.EMPTY_COMPOUND_NODE_SIZE;\n } else {\n this.estimatedSize = size / Math.sqrt(this.nodes.length);\n }\n\n return this.estimatedSize;\n};\n\nLGraph.prototype.updateConnected = function () {\n var self = this;\n if (this.nodes.length == 0) {\n this.isConnected = true;\n return;\n }\n\n var queue = new LinkedList();\n var visited = new Set();\n var currentNode = this.nodes[0];\n var neighborEdges;\n var currentNeighbor;\n var childrenOfNode = currentNode.withChildren();\n childrenOfNode.forEach(function (node) {\n queue.push(node);\n visited.add(node);\n });\n\n while (queue.length !== 0) {\n currentNode = queue.shift();\n\n // Traverse all neighbors of this node\n neighborEdges = currentNode.getEdges();\n var size = neighborEdges.length;\n for (var i = 0; i < size; i++) {\n var neighborEdge = neighborEdges[i];\n currentNeighbor = neighborEdge.getOtherEndInGraph(currentNode, this);\n\n // Add unvisited neighbors to the list to visit\n if (currentNeighbor != null && !visited.has(currentNeighbor)) {\n var childrenOfNeighbor = currentNeighbor.withChildren();\n\n childrenOfNeighbor.forEach(function (node) {\n queue.push(node);\n visited.add(node);\n });\n }\n }\n }\n\n this.isConnected = false;\n\n if (visited.size >= this.nodes.length) {\n var noOfVisitedInThisGraph = 0;\n\n visited.forEach(function (visitedNode) {\n if (visitedNode.owner == self) {\n noOfVisitedInThisGraph++;\n }\n });\n\n if (noOfVisitedInThisGraph == this.nodes.length) {\n this.isConnected = true;\n }\n }\n};\n\nmodule.exports = LGraph;\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LGraph;\nvar LEdge = __webpack_require__(1);\n\nfunction LGraphManager(layout) {\n LGraph = __webpack_require__(6); // It may be better to initilize this out of this function but it gives an error (Right-hand side of 'instanceof' is not callable) now.\n this.layout = layout;\n\n this.graphs = [];\n this.edges = [];\n}\n\nLGraphManager.prototype.addRoot = function () {\n var ngraph = this.layout.newGraph();\n var nnode = this.layout.newNode(null);\n var root = this.add(ngraph, nnode);\n this.setRootGraph(root);\n return this.rootGraph;\n};\n\nLGraphManager.prototype.add = function (newGraph, parentNode, newEdge, sourceNode, targetNode) {\n //there are just 2 parameters are passed then it adds an LGraph else it adds an LEdge\n if (newEdge == null && sourceNode == null && targetNode == null) {\n if (newGraph == null) {\n throw \"Graph is null!\";\n }\n if (parentNode == null) {\n throw \"Parent node is null!\";\n }\n if (this.graphs.indexOf(newGraph) > -1) {\n throw \"Graph already in this graph mgr!\";\n }\n\n this.graphs.push(newGraph);\n\n if (newGraph.parent != null) {\n throw \"Already has a parent!\";\n }\n if (parentNode.child != null) {\n throw \"Already has a child!\";\n }\n\n newGraph.parent = parentNode;\n parentNode.child = newGraph;\n\n return newGraph;\n } else {\n //change the order of the parameters\n targetNode = newEdge;\n sourceNode = parentNode;\n newEdge = newGraph;\n var sourceGraph = sourceNode.getOwner();\n var targetGraph = targetNode.getOwner();\n\n if (!(sourceGraph != null && sourceGraph.getGraphManager() == this)) {\n throw \"Source not in this graph mgr!\";\n }\n if (!(targetGraph != null && targetGraph.getGraphManager() == this)) {\n throw \"Target not in this graph mgr!\";\n }\n\n if (sourceGraph == targetGraph) {\n newEdge.isInterGraph = false;\n return sourceGraph.add(newEdge, sourceNode, targetNode);\n } else {\n newEdge.isInterGraph = true;\n\n // set source and target\n newEdge.source = sourceNode;\n newEdge.target = targetNode;\n\n // add edge to inter-graph edge list\n if (this.edges.indexOf(newEdge) > -1) {\n throw \"Edge already in inter-graph edge list!\";\n }\n\n this.edges.push(newEdge);\n\n // add edge to source and target incidency lists\n if (!(newEdge.source != null && newEdge.target != null)) {\n throw \"Edge source and/or target is null!\";\n }\n\n if (!(newEdge.source.edges.indexOf(newEdge) == -1 && newEdge.target.edges.indexOf(newEdge) == -1)) {\n throw \"Edge already in source and/or target incidency list!\";\n }\n\n newEdge.source.edges.push(newEdge);\n newEdge.target.edges.push(newEdge);\n\n return newEdge;\n }\n }\n};\n\nLGraphManager.prototype.remove = function (lObj) {\n if (lObj instanceof LGraph) {\n var graph = lObj;\n if (graph.getGraphManager() != this) {\n throw \"Graph not in this graph mgr\";\n }\n if (!(graph == this.rootGraph || graph.parent != null && graph.parent.graphManager == this)) {\n throw \"Invalid parent node!\";\n }\n\n // first the edges (make a copy to do it safely)\n var edgesToBeRemoved = [];\n\n edgesToBeRemoved = edgesToBeRemoved.concat(graph.getEdges());\n\n var edge;\n var s = edgesToBeRemoved.length;\n for (var i = 0; i < s; i++) {\n edge = edgesToBeRemoved[i];\n graph.remove(edge);\n }\n\n // then the nodes (make a copy to do it safely)\n var nodesToBeRemoved = [];\n\n nodesToBeRemoved = nodesToBeRemoved.concat(graph.getNodes());\n\n var node;\n s = nodesToBeRemoved.length;\n for (var i = 0; i < s; i++) {\n node = nodesToBeRemoved[i];\n graph.remove(node);\n }\n\n // check if graph is the root\n if (graph == this.rootGraph) {\n this.setRootGraph(null);\n }\n\n // now remove the graph itself\n var index = this.graphs.indexOf(graph);\n this.graphs.splice(index, 1);\n\n // also reset the parent of the graph\n graph.parent = null;\n } else if (lObj instanceof LEdge) {\n edge = lObj;\n if (edge == null) {\n throw \"Edge is null!\";\n }\n if (!edge.isInterGraph) {\n throw \"Not an inter-graph edge!\";\n }\n if (!(edge.source != null && edge.target != null)) {\n throw \"Source and/or target is null!\";\n }\n\n // remove edge from source and target nodes' incidency lists\n\n if (!(edge.source.edges.indexOf(edge) != -1 && edge.target.edges.indexOf(edge) != -1)) {\n throw \"Source and/or target doesn't know this edge!\";\n }\n\n var index = edge.source.edges.indexOf(edge);\n edge.source.edges.splice(index, 1);\n index = edge.target.edges.indexOf(edge);\n edge.target.edges.splice(index, 1);\n\n // remove edge from owner graph manager's inter-graph edge list\n\n if (!(edge.source.owner != null && edge.source.owner.getGraphManager() != null)) {\n throw \"Edge owner graph or owner graph manager is null!\";\n }\n if (edge.source.owner.getGraphManager().edges.indexOf(edge) == -1) {\n throw \"Not in owner graph manager's edge list!\";\n }\n\n var index = edge.source.owner.getGraphManager().edges.indexOf(edge);\n edge.source.owner.getGraphManager().edges.splice(index, 1);\n }\n};\n\nLGraphManager.prototype.updateBounds = function () {\n this.rootGraph.updateBounds(true);\n};\n\nLGraphManager.prototype.getGraphs = function () {\n return this.graphs;\n};\n\nLGraphManager.prototype.getAllNodes = function () {\n if (this.allNodes == null) {\n var nodeList = [];\n var graphs = this.getGraphs();\n var s = graphs.length;\n for (var i = 0; i < s; i++) {\n nodeList = nodeList.concat(graphs[i].getNodes());\n }\n this.allNodes = nodeList;\n }\n return this.allNodes;\n};\n\nLGraphManager.prototype.resetAllNodes = function () {\n this.allNodes = null;\n};\n\nLGraphManager.prototype.resetAllEdges = function () {\n this.allEdges = null;\n};\n\nLGraphManager.prototype.resetAllNodesToApplyGravitation = function () {\n this.allNodesToApplyGravitation = null;\n};\n\nLGraphManager.prototype.getAllEdges = function () {\n if (this.allEdges == null) {\n var edgeList = [];\n var graphs = this.getGraphs();\n var s = graphs.length;\n for (var i = 0; i < graphs.length; i++) {\n edgeList = edgeList.concat(graphs[i].getEdges());\n }\n\n edgeList = edgeList.concat(this.edges);\n\n this.allEdges = edgeList;\n }\n return this.allEdges;\n};\n\nLGraphManager.prototype.getAllNodesToApplyGravitation = function () {\n return this.allNodesToApplyGravitation;\n};\n\nLGraphManager.prototype.setAllNodesToApplyGravitation = function (nodeList) {\n if (this.allNodesToApplyGravitation != null) {\n throw \"assert failed\";\n }\n\n this.allNodesToApplyGravitation = nodeList;\n};\n\nLGraphManager.prototype.getRoot = function () {\n return this.rootGraph;\n};\n\nLGraphManager.prototype.setRootGraph = function (graph) {\n if (graph.getGraphManager() != this) {\n throw \"Root not in this graph mgr!\";\n }\n\n this.rootGraph = graph;\n // root graph must have a root node associated with it for convenience\n if (graph.parent == null) {\n graph.parent = this.layout.newNode(\"Root node\");\n }\n};\n\nLGraphManager.prototype.getLayout = function () {\n return this.layout;\n};\n\nLGraphManager.prototype.isOneAncestorOfOther = function (firstNode, secondNode) {\n if (!(firstNode != null && secondNode != null)) {\n throw \"assert failed\";\n }\n\n if (firstNode == secondNode) {\n return true;\n }\n // Is second node an ancestor of the first one?\n var ownerGraph = firstNode.getOwner();\n var parentNode;\n\n do {\n parentNode = ownerGraph.getParent();\n\n if (parentNode == null) {\n break;\n }\n\n if (parentNode == secondNode) {\n return true;\n }\n\n ownerGraph = parentNode.getOwner();\n if (ownerGraph == null) {\n break;\n }\n } while (true);\n // Is first node an ancestor of the second one?\n ownerGraph = secondNode.getOwner();\n\n do {\n parentNode = ownerGraph.getParent();\n\n if (parentNode == null) {\n break;\n }\n\n if (parentNode == firstNode) {\n return true;\n }\n\n ownerGraph = parentNode.getOwner();\n if (ownerGraph == null) {\n break;\n }\n } while (true);\n\n return false;\n};\n\nLGraphManager.prototype.calcLowestCommonAncestors = function () {\n var edge;\n var sourceNode;\n var targetNode;\n var sourceAncestorGraph;\n var targetAncestorGraph;\n\n var edges = this.getAllEdges();\n var s = edges.length;\n for (var i = 0; i < s; i++) {\n edge = edges[i];\n\n sourceNode = edge.source;\n targetNode = edge.target;\n edge.lca = null;\n edge.sourceInLca = sourceNode;\n edge.targetInLca = targetNode;\n\n if (sourceNode == targetNode) {\n edge.lca = sourceNode.getOwner();\n continue;\n }\n\n sourceAncestorGraph = sourceNode.getOwner();\n\n while (edge.lca == null) {\n edge.targetInLca = targetNode;\n targetAncestorGraph = targetNode.getOwner();\n\n while (edge.lca == null) {\n if (targetAncestorGraph == sourceAncestorGraph) {\n edge.lca = targetAncestorGraph;\n break;\n }\n\n if (targetAncestorGraph == this.rootGraph) {\n break;\n }\n\n if (edge.lca != null) {\n throw \"assert failed\";\n }\n edge.targetInLca = targetAncestorGraph.getParent();\n targetAncestorGraph = edge.targetInLca.getOwner();\n }\n\n if (sourceAncestorGraph == this.rootGraph) {\n break;\n }\n\n if (edge.lca == null) {\n edge.sourceInLca = sourceAncestorGraph.getParent();\n sourceAncestorGraph = edge.sourceInLca.getOwner();\n }\n }\n\n if (edge.lca == null) {\n throw \"assert failed\";\n }\n }\n};\n\nLGraphManager.prototype.calcLowestCommonAncestor = function (firstNode, secondNode) {\n if (firstNode == secondNode) {\n return firstNode.getOwner();\n }\n var firstOwnerGraph = firstNode.getOwner();\n\n do {\n if (firstOwnerGraph == null) {\n break;\n }\n var secondOwnerGraph = secondNode.getOwner();\n\n do {\n if (secondOwnerGraph == null) {\n break;\n }\n\n if (secondOwnerGraph == firstOwnerGraph) {\n return secondOwnerGraph;\n }\n secondOwnerGraph = secondOwnerGraph.getParent().getOwner();\n } while (true);\n\n firstOwnerGraph = firstOwnerGraph.getParent().getOwner();\n } while (true);\n\n return firstOwnerGraph;\n};\n\nLGraphManager.prototype.calcInclusionTreeDepths = function (graph, depth) {\n if (graph == null && depth == null) {\n graph = this.rootGraph;\n depth = 1;\n }\n var node;\n\n var nodes = graph.getNodes();\n var s = nodes.length;\n for (var i = 0; i < s; i++) {\n node = nodes[i];\n node.inclusionTreeDepth = depth;\n\n if (node.child != null) {\n this.calcInclusionTreeDepths(node.child, depth + 1);\n }\n }\n};\n\nLGraphManager.prototype.includesInvalidEdge = function () {\n var edge;\n var edgesToRemove = [];\n\n var s = this.edges.length;\n for (var i = 0; i < s; i++) {\n edge = this.edges[i];\n\n if (this.isOneAncestorOfOther(edge.source, edge.target)) {\n edgesToRemove.push(edge);\n }\n }\n\n // Remove invalid edges from graph manager\n for (var i = 0; i < edgesToRemove.length; i++) {\n this.remove(edgesToRemove[i]);\n }\n\n // Invalid edges are cleared, so return false\n return false;\n};\n\nmodule.exports = LGraphManager;\n\n/***/ }),\n/* 8 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/**\n * This class maintains a list of static geometry related utility methods.\n *\n *\n * Copyright: i-Vis Research Group, Bilkent University, 2007 - present\n */\n\nvar Point = __webpack_require__(12);\n\nfunction IGeometry() {}\n\n/**\n * This method calculates *half* the amount in x and y directions of the two\n * input rectangles needed to separate them keeping their respective\n * positioning, and returns the result in the input array. An input\n * separation buffer added to the amount in both directions. We assume that\n * the two rectangles do intersect.\n */\nIGeometry.calcSeparationAmount = function (rectA, rectB, overlapAmount, separationBuffer) {\n if (!rectA.intersects(rectB)) {\n throw \"assert failed\";\n }\n\n var directions = new Array(2);\n\n this.decideDirectionsForOverlappingNodes(rectA, rectB, directions);\n\n overlapAmount[0] = Math.min(rectA.getRight(), rectB.getRight()) - Math.max(rectA.x, rectB.x);\n overlapAmount[1] = Math.min(rectA.getBottom(), rectB.getBottom()) - Math.max(rectA.y, rectB.y);\n\n // update the overlapping amounts for the following cases:\n if (rectA.getX() <= rectB.getX() && rectA.getRight() >= rectB.getRight()) {\n /* Case x.1:\n *\n * rectA\n * \t| |\n * \t| _________ |\n * \t| | | |\n * \t|________|_______|______|\n * \t\t\t | |\n * | |\n * rectB\n */\n overlapAmount[0] += Math.min(rectB.getX() - rectA.getX(), rectA.getRight() - rectB.getRight());\n } else if (rectB.getX() <= rectA.getX() && rectB.getRight() >= rectA.getRight()) {\n /* Case x.2:\n *\n * rectB\n * \t| |\n * \t| _________ |\n * \t| | | |\n * \t|________|_______|______|\n * \t\t\t | |\n * | |\n * rectA\n */\n overlapAmount[0] += Math.min(rectA.getX() - rectB.getX(), rectB.getRight() - rectA.getRight());\n }\n if (rectA.getY() <= rectB.getY() && rectA.getBottom() >= rectB.getBottom()) {\n /* Case y.1:\n * ________ rectA\n * |\n * |\n * ______|____ rectB\n * | |\n * | |\n * ______|____|\n * |\n * |\n * |________\n *\n */\n overlapAmount[1] += Math.min(rectB.getY() - rectA.getY(), rectA.getBottom() - rectB.getBottom());\n } else if (rectB.getY() <= rectA.getY() && rectB.getBottom() >= rectA.getBottom()) {\n /* Case y.2:\n * ________ rectB\n * |\n * |\n * ______|____ rectA\n * | |\n * | |\n * ______|____|\n * |\n * |\n * |________\n *\n */\n overlapAmount[1] += Math.min(rectA.getY() - rectB.getY(), rectB.getBottom() - rectA.getBottom());\n }\n\n // find slope of the line passes two centers\n var slope = Math.abs((rectB.getCenterY() - rectA.getCenterY()) / (rectB.getCenterX() - rectA.getCenterX()));\n // if centers are overlapped\n if (rectB.getCenterY() === rectA.getCenterY() && rectB.getCenterX() === rectA.getCenterX()) {\n // assume the slope is 1 (45 degree)\n slope = 1.0;\n }\n\n var moveByY = slope * overlapAmount[0];\n var moveByX = overlapAmount[1] / slope;\n if (overlapAmount[0] < moveByX) {\n moveByX = overlapAmount[0];\n } else {\n moveByY = overlapAmount[1];\n }\n // return half the amount so that if each rectangle is moved by these\n // amounts in opposite directions, overlap will be resolved\n overlapAmount[0] = -1 * directions[0] * (moveByX / 2 + separationBuffer);\n overlapAmount[1] = -1 * directions[1] * (moveByY / 2 + separationBuffer);\n};\n\n/**\n * This method decides the separation direction of overlapping nodes\n *\n * if directions[0] = -1, then rectA goes left\n * if directions[0] = 1, then rectA goes right\n * if directions[1] = -1, then rectA goes up\n * if directions[1] = 1, then rectA goes down\n */\nIGeometry.decideDirectionsForOverlappingNodes = function (rectA, rectB, directions) {\n if (rectA.getCenterX() < rectB.getCenterX()) {\n directions[0] = -1;\n } else {\n directions[0] = 1;\n }\n\n if (rectA.getCenterY() < rectB.getCenterY()) {\n directions[1] = -1;\n } else {\n directions[1] = 1;\n }\n};\n\n/**\n * This method calculates the intersection (clipping) points of the two\n * input rectangles with line segment defined by the centers of these two\n * rectangles. The clipping points are saved in the input double array and\n * whether or not the two rectangles overlap is returned.\n */\nIGeometry.getIntersection2 = function (rectA, rectB, result) {\n //result[0-1] will contain clipPoint of rectA, result[2-3] will contain clipPoint of rectB\n var p1x = rectA.getCenterX();\n var p1y = rectA.getCenterY();\n var p2x = rectB.getCenterX();\n var p2y = rectB.getCenterY();\n\n //if two rectangles intersect, then clipping points are centers\n if (rectA.intersects(rectB)) {\n result[0] = p1x;\n result[1] = p1y;\n result[2] = p2x;\n result[3] = p2y;\n return true;\n }\n //variables for rectA\n var topLeftAx = rectA.getX();\n var topLeftAy = rectA.getY();\n var topRightAx = rectA.getRight();\n var bottomLeftAx = rectA.getX();\n var bottomLeftAy = rectA.getBottom();\n var bottomRightAx = rectA.getRight();\n var halfWidthA = rectA.getWidthHalf();\n var halfHeightA = rectA.getHeightHalf();\n //variables for rectB\n var topLeftBx = rectB.getX();\n var topLeftBy = rectB.getY();\n var topRightBx = rectB.getRight();\n var bottomLeftBx = rectB.getX();\n var bottomLeftBy = rectB.getBottom();\n var bottomRightBx = rectB.getRight();\n var halfWidthB = rectB.getWidthHalf();\n var halfHeightB = rectB.getHeightHalf();\n\n //flag whether clipping points are found\n var clipPointAFound = false;\n var clipPointBFound = false;\n\n // line is vertical\n if (p1x === p2x) {\n if (p1y > p2y) {\n result[0] = p1x;\n result[1] = topLeftAy;\n result[2] = p2x;\n result[3] = bottomLeftBy;\n return false;\n } else if (p1y < p2y) {\n result[0] = p1x;\n result[1] = bottomLeftAy;\n result[2] = p2x;\n result[3] = topLeftBy;\n return false;\n } else {\n //not line, return null;\n }\n }\n // line is horizontal\n else if (p1y === p2y) {\n if (p1x > p2x) {\n result[0] = topLeftAx;\n result[1] = p1y;\n result[2] = topRightBx;\n result[3] = p2y;\n return false;\n } else if (p1x < p2x) {\n result[0] = topRightAx;\n result[1] = p1y;\n result[2] = topLeftBx;\n result[3] = p2y;\n return false;\n } else {\n //not valid line, return null;\n }\n } else {\n //slopes of rectA's and rectB's diagonals\n var slopeA = rectA.height / rectA.width;\n var slopeB = rectB.height / rectB.width;\n\n //slope of line between center of rectA and center of rectB\n var slopePrime = (p2y - p1y) / (p2x - p1x);\n var cardinalDirectionA = void 0;\n var cardinalDirectionB = void 0;\n var tempPointAx = void 0;\n var tempPointAy = void 0;\n var tempPointBx = void 0;\n var tempPointBy = void 0;\n\n //determine whether clipping point is the corner of nodeA\n if (-slopeA === slopePrime) {\n if (p1x > p2x) {\n result[0] = bottomLeftAx;\n result[1] = bottomLeftAy;\n clipPointAFound = true;\n } else {\n result[0] = topRightAx;\n result[1] = topLeftAy;\n clipPointAFound = true;\n }\n } else if (slopeA === slopePrime) {\n if (p1x > p2x) {\n result[0] = topLeftAx;\n result[1] = topLeftAy;\n clipPointAFound = true;\n } else {\n result[0] = bottomRightAx;\n result[1] = bottomLeftAy;\n clipPointAFound = true;\n }\n }\n\n //determine whether clipping point is the corner of nodeB\n if (-slopeB === slopePrime) {\n if (p2x > p1x) {\n result[2] = bottomLeftBx;\n result[3] = bottomLeftBy;\n clipPointBFound = true;\n } else {\n result[2] = topRightBx;\n result[3] = topLeftBy;\n clipPointBFound = true;\n }\n } else if (slopeB === slopePrime) {\n if (p2x > p1x) {\n result[2] = topLeftBx;\n result[3] = topLeftBy;\n clipPointBFound = true;\n } else {\n result[2] = bottomRightBx;\n result[3] = bottomLeftBy;\n clipPointBFound = true;\n }\n }\n\n //if both clipping points are corners\n if (clipPointAFound && clipPointBFound) {\n return false;\n }\n\n //determine Cardinal Direction of rectangles\n if (p1x > p2x) {\n if (p1y > p2y) {\n cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 4);\n cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 2);\n } else {\n cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 3);\n cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 1);\n }\n } else {\n if (p1y > p2y) {\n cardinalDirectionA = this.getCardinalDirection(-slopeA, slopePrime, 1);\n cardinalDirectionB = this.getCardinalDirection(-slopeB, slopePrime, 3);\n } else {\n cardinalDirectionA = this.getCardinalDirection(slopeA, slopePrime, 2);\n cardinalDirectionB = this.getCardinalDirection(slopeB, slopePrime, 4);\n }\n }\n //calculate clipping Point if it is not found before\n if (!clipPointAFound) {\n switch (cardinalDirectionA) {\n case 1:\n tempPointAy = topLeftAy;\n tempPointAx = p1x + -halfHeightA / slopePrime;\n result[0] = tempPointAx;\n result[1] = tempPointAy;\n break;\n case 2:\n tempPointAx = bottomRightAx;\n tempPointAy = p1y + halfWidthA * slopePrime;\n result[0] = tempPointAx;\n result[1] = tempPointAy;\n break;\n case 3:\n tempPointAy = bottomLeftAy;\n tempPointAx = p1x + halfHeightA / slopePrime;\n result[0] = tempPointAx;\n result[1] = tempPointAy;\n break;\n case 4:\n tempPointAx = bottomLeftAx;\n tempPointAy = p1y + -halfWidthA * slopePrime;\n result[0] = tempPointAx;\n result[1] = tempPointAy;\n break;\n }\n }\n if (!clipPointBFound) {\n switch (cardinalDirectionB) {\n case 1:\n tempPointBy = topLeftBy;\n tempPointBx = p2x + -halfHeightB / slopePrime;\n result[2] = tempPointBx;\n result[3] = tempPointBy;\n break;\n case 2:\n tempPointBx = bottomRightBx;\n tempPointBy = p2y + halfWidthB * slopePrime;\n result[2] = tempPointBx;\n result[3] = tempPointBy;\n break;\n case 3:\n tempPointBy = bottomLeftBy;\n tempPointBx = p2x + halfHeightB / slopePrime;\n result[2] = tempPointBx;\n result[3] = tempPointBy;\n break;\n case 4:\n tempPointBx = bottomLeftBx;\n tempPointBy = p2y + -halfWidthB * slopePrime;\n result[2] = tempPointBx;\n result[3] = tempPointBy;\n break;\n }\n }\n }\n return false;\n};\n\n/**\n * This method returns in which cardinal direction does input point stays\n * 1: North\n * 2: East\n * 3: South\n * 4: West\n */\nIGeometry.getCardinalDirection = function (slope, slopePrime, line) {\n if (slope > slopePrime) {\n return line;\n } else {\n return 1 + line % 4;\n }\n};\n\n/**\n * This method calculates the intersection of the two lines defined by\n * point pairs (s1,s2) and (f1,f2).\n */\nIGeometry.getIntersection = function (s1, s2, f1, f2) {\n if (f2 == null) {\n return this.getIntersection2(s1, s2, f1);\n }\n\n var x1 = s1.x;\n var y1 = s1.y;\n var x2 = s2.x;\n var y2 = s2.y;\n var x3 = f1.x;\n var y3 = f1.y;\n var x4 = f2.x;\n var y4 = f2.y;\n var x = void 0,\n y = void 0; // intersection point\n var a1 = void 0,\n a2 = void 0,\n b1 = void 0,\n b2 = void 0,\n c1 = void 0,\n c2 = void 0; // coefficients of line eqns.\n var denom = void 0;\n\n a1 = y2 - y1;\n b1 = x1 - x2;\n c1 = x2 * y1 - x1 * y2; // { a1*x + b1*y + c1 = 0 is line 1 }\n\n a2 = y4 - y3;\n b2 = x3 - x4;\n c2 = x4 * y3 - x3 * y4; // { a2*x + b2*y + c2 = 0 is line 2 }\n\n denom = a1 * b2 - a2 * b1;\n\n if (denom === 0) {\n return null;\n }\n\n x = (b1 * c2 - b2 * c1) / denom;\n y = (a2 * c1 - a1 * c2) / denom;\n\n return new Point(x, y);\n};\n\n/**\n * This method finds and returns the angle of the vector from the + x-axis\n * in clockwise direction (compatible w/ Java coordinate system!).\n */\nIGeometry.angleOfVector = function (Cx, Cy, Nx, Ny) {\n var C_angle = void 0;\n\n if (Cx !== Nx) {\n C_angle = Math.atan((Ny - Cy) / (Nx - Cx));\n\n if (Nx < Cx) {\n C_angle += Math.PI;\n } else if (Ny < Cy) {\n C_angle += this.TWO_PI;\n }\n } else if (Ny < Cy) {\n C_angle = this.ONE_AND_HALF_PI; // 270 degrees\n } else {\n C_angle = this.HALF_PI; // 90 degrees\n }\n\n return C_angle;\n};\n\n/**\n * This method checks whether the given two line segments (one with point\n * p1 and p2, the other with point p3 and p4) intersect at a point other\n * than these points.\n */\nIGeometry.doIntersect = function (p1, p2, p3, p4) {\n var a = p1.x;\n var b = p1.y;\n var c = p2.x;\n var d = p2.y;\n var p = p3.x;\n var q = p3.y;\n var r = p4.x;\n var s = p4.y;\n var det = (c - a) * (s - q) - (r - p) * (d - b);\n\n if (det === 0) {\n return false;\n } else {\n var lambda = ((s - q) * (r - a) + (p - r) * (s - b)) / det;\n var gamma = ((b - d) * (r - a) + (c - a) * (s - b)) / det;\n return 0 < lambda && lambda < 1 && 0 < gamma && gamma < 1;\n }\n};\n\n/**\n * This method checks and calculates the intersection of \n * a line segment and a circle.\n */\nIGeometry.findCircleLineIntersections = function (Ex, Ey, Lx, Ly, Cx, Cy, r) {\n\n // E is the starting point of the ray,\n // L is the end point of the ray,\n // C is the center of sphere you're testing against\n // r is the radius of that sphere\n\n // Compute:\n // d = L - E ( Direction vector of ray, from start to end )\n // f = E - C ( Vector from center sphere to ray start )\n\n // Then the intersection is found by..\n // P = E + t * d\n // This is a parametric equation:\n // Px = Ex + tdx\n // Py = Ey + tdy\n\n // get a, b, c values\n var a = (Lx - Ex) * (Lx - Ex) + (Ly - Ey) * (Ly - Ey);\n var b = 2 * ((Ex - Cx) * (Lx - Ex) + (Ey - Cy) * (Ly - Ey));\n var c = (Ex - Cx) * (Ex - Cx) + (Ey - Cy) * (Ey - Cy) - r * r;\n\n // get discriminant\n var disc = b * b - 4 * a * c;\n if (disc >= 0) {\n // insert into quadratic formula\n var t1 = (-b + Math.sqrt(b * b - 4 * a * c)) / (2 * a);\n var t2 = (-b - Math.sqrt(b * b - 4 * a * c)) / (2 * a);\n var intersections = null;\n if (t1 >= 0 && t1 <= 1) {\n // t1 is the intersection, and it's closer than t2\n // (since t1 uses -b - discriminant)\n // Impale, Poke\n return [t1];\n }\n\n // here t1 didn't intersect so we are either started\n // inside the sphere or completely past it\n if (t2 >= 0 && t2 <= 1) {\n // ExitWound\n return [t2];\n }\n\n return intersections;\n } else return null;\n};\n\n// -----------------------------------------------------------------------------\n// Section: Class Constants\n// -----------------------------------------------------------------------------\n/**\n * Some useful pre-calculated constants\n */\nIGeometry.HALF_PI = 0.5 * Math.PI;\nIGeometry.ONE_AND_HALF_PI = 1.5 * Math.PI;\nIGeometry.TWO_PI = 2.0 * Math.PI;\nIGeometry.THREE_PI = 3.0 * Math.PI;\n\nmodule.exports = IGeometry;\n\n/***/ }),\n/* 9 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction IMath() {}\n\n/**\n * This method returns the sign of the input value.\n */\nIMath.sign = function (value) {\n if (value > 0) {\n return 1;\n } else if (value < 0) {\n return -1;\n } else {\n return 0;\n }\n};\n\nIMath.floor = function (value) {\n return value < 0 ? Math.ceil(value) : Math.floor(value);\n};\n\nIMath.ceil = function (value) {\n return value < 0 ? Math.floor(value) : Math.ceil(value);\n};\n\nmodule.exports = IMath;\n\n/***/ }),\n/* 10 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction Integer() {}\n\nInteger.MAX_VALUE = 2147483647;\nInteger.MIN_VALUE = -2147483648;\n\nmodule.exports = Integer;\n\n/***/ }),\n/* 11 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\nvar nodeFrom = function nodeFrom(value) {\n return { value: value, next: null, prev: null };\n};\n\nvar add = function add(prev, node, next, list) {\n if (prev !== null) {\n prev.next = node;\n } else {\n list.head = node;\n }\n\n if (next !== null) {\n next.prev = node;\n } else {\n list.tail = node;\n }\n\n node.prev = prev;\n node.next = next;\n\n list.length++;\n\n return node;\n};\n\nvar _remove = function _remove(node, list) {\n var prev = node.prev,\n next = node.next;\n\n\n if (prev !== null) {\n prev.next = next;\n } else {\n list.head = next;\n }\n\n if (next !== null) {\n next.prev = prev;\n } else {\n list.tail = prev;\n }\n\n node.prev = node.next = null;\n\n list.length--;\n\n return node;\n};\n\nvar LinkedList = function () {\n function LinkedList(vals) {\n var _this = this;\n\n _classCallCheck(this, LinkedList);\n\n this.length = 0;\n this.head = null;\n this.tail = null;\n\n if (vals != null) {\n vals.forEach(function (v) {\n return _this.push(v);\n });\n }\n }\n\n _createClass(LinkedList, [{\n key: \"size\",\n value: function size() {\n return this.length;\n }\n }, {\n key: \"insertBefore\",\n value: function insertBefore(val, otherNode) {\n return add(otherNode.prev, nodeFrom(val), otherNode, this);\n }\n }, {\n key: \"insertAfter\",\n value: function insertAfter(val, otherNode) {\n return add(otherNode, nodeFrom(val), otherNode.next, this);\n }\n }, {\n key: \"insertNodeBefore\",\n value: function insertNodeBefore(newNode, otherNode) {\n return add(otherNode.prev, newNode, otherNode, this);\n }\n }, {\n key: \"insertNodeAfter\",\n value: function insertNodeAfter(newNode, otherNode) {\n return add(otherNode, newNode, otherNode.next, this);\n }\n }, {\n key: \"push\",\n value: function push(val) {\n return add(this.tail, nodeFrom(val), null, this);\n }\n }, {\n key: \"unshift\",\n value: function unshift(val) {\n return add(null, nodeFrom(val), this.head, this);\n }\n }, {\n key: \"remove\",\n value: function remove(node) {\n return _remove(node, this);\n }\n }, {\n key: \"pop\",\n value: function pop() {\n return _remove(this.tail, this).value;\n }\n }, {\n key: \"popNode\",\n value: function popNode() {\n return _remove(this.tail, this);\n }\n }, {\n key: \"shift\",\n value: function shift() {\n return _remove(this.head, this).value;\n }\n }, {\n key: \"shiftNode\",\n value: function shiftNode() {\n return _remove(this.head, this);\n }\n }, {\n key: \"get_object_at\",\n value: function get_object_at(index) {\n if (index <= this.length()) {\n var i = 1;\n var current = this.head;\n while (i < index) {\n current = current.next;\n i++;\n }\n return current.value;\n }\n }\n }, {\n key: \"set_object_at\",\n value: function set_object_at(index, value) {\n if (index <= this.length()) {\n var i = 1;\n var current = this.head;\n while (i < index) {\n current = current.next;\n i++;\n }\n current.value = value;\n }\n }\n }]);\n\n return LinkedList;\n}();\n\nmodule.exports = LinkedList;\n\n/***/ }),\n/* 12 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n/*\r\n *This class is the javascript implementation of the Point.java class in jdk\r\n */\nfunction Point(x, y, p) {\n this.x = null;\n this.y = null;\n if (x == null && y == null && p == null) {\n this.x = 0;\n this.y = 0;\n } else if (typeof x == 'number' && typeof y == 'number' && p == null) {\n this.x = x;\n this.y = y;\n } else if (x.constructor.name == 'Point' && y == null && p == null) {\n p = x;\n this.x = p.x;\n this.y = p.y;\n }\n}\n\nPoint.prototype.getX = function () {\n return this.x;\n};\n\nPoint.prototype.getY = function () {\n return this.y;\n};\n\nPoint.prototype.getLocation = function () {\n return new Point(this.x, this.y);\n};\n\nPoint.prototype.setLocation = function (x, y, p) {\n if (x.constructor.name == 'Point' && y == null && p == null) {\n p = x;\n this.setLocation(p.x, p.y);\n } else if (typeof x == 'number' && typeof y == 'number' && p == null) {\n //if both parameters are integer just move (x,y) location\n if (parseInt(x) == x && parseInt(y) == y) {\n this.move(x, y);\n } else {\n this.x = Math.floor(x + 0.5);\n this.y = Math.floor(y + 0.5);\n }\n }\n};\n\nPoint.prototype.move = function (x, y) {\n this.x = x;\n this.y = y;\n};\n\nPoint.prototype.translate = function (dx, dy) {\n this.x += dx;\n this.y += dy;\n};\n\nPoint.prototype.equals = function (obj) {\n if (obj.constructor.name == \"Point\") {\n var pt = obj;\n return this.x == pt.x && this.y == pt.y;\n }\n return this == obj;\n};\n\nPoint.prototype.toString = function () {\n return new Point().constructor.name + \"[x=\" + this.x + \",y=\" + this.y + \"]\";\n};\n\nmodule.exports = Point;\n\n/***/ }),\n/* 13 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction RectangleD(x, y, width, height) {\n this.x = 0;\n this.y = 0;\n this.width = 0;\n this.height = 0;\n\n if (x != null && y != null && width != null && height != null) {\n this.x = x;\n this.y = y;\n this.width = width;\n this.height = height;\n }\n}\n\nRectangleD.prototype.getX = function () {\n return this.x;\n};\n\nRectangleD.prototype.setX = function (x) {\n this.x = x;\n};\n\nRectangleD.prototype.getY = function () {\n return this.y;\n};\n\nRectangleD.prototype.setY = function (y) {\n this.y = y;\n};\n\nRectangleD.prototype.getWidth = function () {\n return this.width;\n};\n\nRectangleD.prototype.setWidth = function (width) {\n this.width = width;\n};\n\nRectangleD.prototype.getHeight = function () {\n return this.height;\n};\n\nRectangleD.prototype.setHeight = function (height) {\n this.height = height;\n};\n\nRectangleD.prototype.getRight = function () {\n return this.x + this.width;\n};\n\nRectangleD.prototype.getBottom = function () {\n return this.y + this.height;\n};\n\nRectangleD.prototype.intersects = function (a) {\n if (this.getRight() < a.x) {\n return false;\n }\n\n if (this.getBottom() < a.y) {\n return false;\n }\n\n if (a.getRight() < this.x) {\n return false;\n }\n\n if (a.getBottom() < this.y) {\n return false;\n }\n\n return true;\n};\n\nRectangleD.prototype.getCenterX = function () {\n return this.x + this.width / 2;\n};\n\nRectangleD.prototype.getMinX = function () {\n return this.getX();\n};\n\nRectangleD.prototype.getMaxX = function () {\n return this.getX() + this.width;\n};\n\nRectangleD.prototype.getCenterY = function () {\n return this.y + this.height / 2;\n};\n\nRectangleD.prototype.getMinY = function () {\n return this.getY();\n};\n\nRectangleD.prototype.getMaxY = function () {\n return this.getY() + this.height;\n};\n\nRectangleD.prototype.getWidthHalf = function () {\n return this.width / 2;\n};\n\nRectangleD.prototype.getHeightHalf = function () {\n return this.height / 2;\n};\n\nmodule.exports = RectangleD;\n\n/***/ }),\n/* 14 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nfunction UniqueIDGeneretor() {}\n\nUniqueIDGeneretor.lastID = 0;\n\nUniqueIDGeneretor.createID = function (obj) {\n if (UniqueIDGeneretor.isPrimitive(obj)) {\n return obj;\n }\n if (obj.uniqueID != null) {\n return obj.uniqueID;\n }\n obj.uniqueID = UniqueIDGeneretor.getString();\n UniqueIDGeneretor.lastID++;\n return obj.uniqueID;\n};\n\nUniqueIDGeneretor.getString = function (id) {\n if (id == null) id = UniqueIDGeneretor.lastID;\n return \"Object#\" + id + \"\";\n};\n\nUniqueIDGeneretor.isPrimitive = function (arg) {\n var type = typeof arg === \"undefined\" ? \"undefined\" : _typeof(arg);\n return arg == null || type != \"object\" && type != \"function\";\n};\n\nmodule.exports = UniqueIDGeneretor;\n\n/***/ }),\n/* 15 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar LayoutConstants = __webpack_require__(0);\nvar LGraphManager = __webpack_require__(7);\nvar LNode = __webpack_require__(3);\nvar LEdge = __webpack_require__(1);\nvar LGraph = __webpack_require__(6);\nvar PointD = __webpack_require__(5);\nvar Transform = __webpack_require__(17);\nvar Emitter = __webpack_require__(29);\n\nfunction Layout(isRemoteUse) {\n Emitter.call(this);\n\n //Layout Quality: 0:draft, 1:default, 2:proof\n this.layoutQuality = LayoutConstants.QUALITY;\n //Whether layout should create bendpoints as needed or not\n this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;\n //Whether layout should be incremental or not\n this.incremental = LayoutConstants.DEFAULT_INCREMENTAL;\n //Whether we animate from before to after layout node positions\n this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT;\n //Whether we animate the layout process or not\n this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT;\n //Number iterations that should be done between two successive animations\n this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD;\n /**\r\n * Whether or not leaf nodes (non-compound nodes) are of uniform sizes. When\r\n * they are, both spring and repulsion forces between two leaf nodes can be\r\n * calculated without the expensive clipping point calculations, resulting\r\n * in major speed-up.\r\n */\n this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES;\n /**\r\n * This is used for creation of bendpoints by using dummy nodes and edges.\r\n * Maps an LEdge to its dummy bendpoint path.\r\n */\n this.edgeToDummyNodes = new Map();\n this.graphManager = new LGraphManager(this);\n this.isLayoutFinished = false;\n this.isSubLayout = false;\n this.isRemoteUse = false;\n\n if (isRemoteUse != null) {\n this.isRemoteUse = isRemoteUse;\n }\n}\n\nLayout.RANDOM_SEED = 1;\n\nLayout.prototype = Object.create(Emitter.prototype);\n\nLayout.prototype.getGraphManager = function () {\n return this.graphManager;\n};\n\nLayout.prototype.getAllNodes = function () {\n return this.graphManager.getAllNodes();\n};\n\nLayout.prototype.getAllEdges = function () {\n return this.graphManager.getAllEdges();\n};\n\nLayout.prototype.getAllNodesToApplyGravitation = function () {\n return this.graphManager.getAllNodesToApplyGravitation();\n};\n\nLayout.prototype.newGraphManager = function () {\n var gm = new LGraphManager(this);\n this.graphManager = gm;\n return gm;\n};\n\nLayout.prototype.newGraph = function (vGraph) {\n return new LGraph(null, this.graphManager, vGraph);\n};\n\nLayout.prototype.newNode = function (vNode) {\n return new LNode(this.graphManager, vNode);\n};\n\nLayout.prototype.newEdge = function (vEdge) {\n return new LEdge(null, null, vEdge);\n};\n\nLayout.prototype.checkLayoutSuccess = function () {\n return this.graphManager.getRoot() == null || this.graphManager.getRoot().getNodes().length == 0 || this.graphManager.includesInvalidEdge();\n};\n\nLayout.prototype.runLayout = function () {\n this.isLayoutFinished = false;\n\n if (this.tilingPreLayout) {\n this.tilingPreLayout();\n }\n\n this.initParameters();\n var isLayoutSuccessfull;\n\n if (this.checkLayoutSuccess()) {\n isLayoutSuccessfull = false;\n } else {\n isLayoutSuccessfull = this.layout();\n }\n\n if (LayoutConstants.ANIMATE === 'during') {\n // If this is a 'during' layout animation. Layout is not finished yet. \n // We need to perform these in index.js when layout is really finished.\n return false;\n }\n\n if (isLayoutSuccessfull) {\n if (!this.isSubLayout) {\n this.doPostLayout();\n }\n }\n\n if (this.tilingPostLayout) {\n this.tilingPostLayout();\n }\n\n this.isLayoutFinished = true;\n\n return isLayoutSuccessfull;\n};\n\n/**\r\n * This method performs the operations required after layout.\r\n */\nLayout.prototype.doPostLayout = function () {\n //assert !isSubLayout : \"Should not be called on sub-layout!\";\n // Propagate geometric changes to v-level objects\n if (!this.incremental) {\n this.transform();\n }\n this.update();\n};\n\n/**\r\n * This method updates the geometry of the target graph according to\r\n * calculated layout.\r\n */\nLayout.prototype.update2 = function () {\n // update bend points\n if (this.createBendsAsNeeded) {\n this.createBendpointsFromDummyNodes();\n\n // reset all edges, since the topology has changed\n this.graphManager.resetAllEdges();\n }\n\n // perform edge, node and root updates if layout is not called\n // remotely\n if (!this.isRemoteUse) {\n // update all edges\n var edge;\n var allEdges = this.graphManager.getAllEdges();\n for (var i = 0; i < allEdges.length; i++) {\n edge = allEdges[i];\n // this.update(edge);\n }\n\n // recursively update nodes\n var node;\n var nodes = this.graphManager.getRoot().getNodes();\n for (var i = 0; i < nodes.length; i++) {\n node = nodes[i];\n // this.update(node);\n }\n\n // update root graph\n this.update(this.graphManager.getRoot());\n }\n};\n\nLayout.prototype.update = function (obj) {\n if (obj == null) {\n this.update2();\n } else if (obj instanceof LNode) {\n var node = obj;\n if (node.getChild() != null) {\n // since node is compound, recursively update child nodes\n var nodes = node.getChild().getNodes();\n for (var i = 0; i < nodes.length; i++) {\n update(nodes[i]);\n }\n }\n\n // if the l-level node is associated with a v-level graph object,\n // then it is assumed that the v-level node implements the\n // interface Updatable.\n if (node.vGraphObject != null) {\n // cast to Updatable without any type check\n var vNode = node.vGraphObject;\n\n // call the update method of the interface\n vNode.update(node);\n }\n } else if (obj instanceof LEdge) {\n var edge = obj;\n // if the l-level edge is associated with a v-level graph object,\n // then it is assumed that the v-level edge implements the\n // interface Updatable.\n\n if (edge.vGraphObject != null) {\n // cast to Updatable without any type check\n var vEdge = edge.vGraphObject;\n\n // call the update method of the interface\n vEdge.update(edge);\n }\n } else if (obj instanceof LGraph) {\n var graph = obj;\n // if the l-level graph is associated with a v-level graph object,\n // then it is assumed that the v-level object implements the\n // interface Updatable.\n\n if (graph.vGraphObject != null) {\n // cast to Updatable without any type check\n var vGraph = graph.vGraphObject;\n\n // call the update method of the interface\n vGraph.update(graph);\n }\n }\n};\n\n/**\r\n * This method is used to set all layout parameters to default values\r\n * determined at compile time.\r\n */\nLayout.prototype.initParameters = function () {\n if (!this.isSubLayout) {\n this.layoutQuality = LayoutConstants.QUALITY;\n this.animationDuringLayout = LayoutConstants.DEFAULT_ANIMATION_DURING_LAYOUT;\n this.animationPeriod = LayoutConstants.DEFAULT_ANIMATION_PERIOD;\n this.animationOnLayout = LayoutConstants.DEFAULT_ANIMATION_ON_LAYOUT;\n this.incremental = LayoutConstants.DEFAULT_INCREMENTAL;\n this.createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;\n this.uniformLeafNodeSizes = LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES;\n }\n\n if (this.animationDuringLayout) {\n this.animationOnLayout = false;\n }\n};\n\nLayout.prototype.transform = function (newLeftTop) {\n if (newLeftTop == undefined) {\n this.transform(new PointD(0, 0));\n } else {\n // create a transformation object (from Eclipse to layout). When an\n // inverse transform is applied, we get upper-left coordinate of the\n // drawing or the root graph at given input coordinate (some margins\n // already included in calculation of left-top).\n\n var trans = new Transform();\n var leftTop = this.graphManager.getRoot().updateLeftTop();\n\n if (leftTop != null) {\n trans.setWorldOrgX(newLeftTop.x);\n trans.setWorldOrgY(newLeftTop.y);\n\n trans.setDeviceOrgX(leftTop.x);\n trans.setDeviceOrgY(leftTop.y);\n\n var nodes = this.getAllNodes();\n var node;\n\n for (var i = 0; i < nodes.length; i++) {\n node = nodes[i];\n node.transform(trans);\n }\n }\n }\n};\n\nLayout.prototype.positionNodesRandomly = function (graph) {\n\n if (graph == undefined) {\n //assert !this.incremental;\n this.positionNodesRandomly(this.getGraphManager().getRoot());\n this.getGraphManager().getRoot().updateBounds(true);\n } else {\n var lNode;\n var childGraph;\n\n var nodes = graph.getNodes();\n for (var i = 0; i < nodes.length; i++) {\n lNode = nodes[i];\n childGraph = lNode.getChild();\n\n if (childGraph == null) {\n lNode.scatter();\n } else if (childGraph.getNodes().length == 0) {\n lNode.scatter();\n } else {\n this.positionNodesRandomly(childGraph);\n lNode.updateBounds();\n }\n }\n }\n};\n\n/**\r\n * This method returns a list of trees where each tree is represented as a\r\n * list of l-nodes. The method returns a list of size 0 when:\r\n * - The graph is not flat or\r\n * - One of the component(s) of the graph is not a tree.\r\n */\nLayout.prototype.getFlatForest = function () {\n var flatForest = [];\n var isForest = true;\n\n // Quick reference for all nodes in the graph manager associated with\n // this layout. The list should not be changed.\n var allNodes = this.graphManager.getRoot().getNodes();\n\n // First be sure that the graph is flat\n var isFlat = true;\n\n for (var i = 0; i < allNodes.length; i++) {\n if (allNodes[i].getChild() != null) {\n isFlat = false;\n }\n }\n\n // Return empty forest if the graph is not flat.\n if (!isFlat) {\n return flatForest;\n }\n\n // Run BFS for each component of the graph.\n\n var visited = new Set();\n var toBeVisited = [];\n var parents = new Map();\n var unProcessedNodes = [];\n\n unProcessedNodes = unProcessedNodes.concat(allNodes);\n\n // Each iteration of this loop finds a component of the graph and\n // decides whether it is a tree or not. If it is a tree, adds it to the\n // forest and continued with the next component.\n\n while (unProcessedNodes.length > 0 && isForest) {\n toBeVisited.push(unProcessedNodes[0]);\n\n // Start the BFS. Each iteration of this loop visits a node in a\n // BFS manner.\n while (toBeVisited.length > 0 && isForest) {\n //pool operation\n var currentNode = toBeVisited[0];\n toBeVisited.splice(0, 1);\n visited.add(currentNode);\n\n // Traverse all neighbors of this node\n var neighborEdges = currentNode.getEdges();\n\n for (var i = 0; i < neighborEdges.length; i++) {\n var currentNeighbor = neighborEdges[i].getOtherEnd(currentNode);\n\n // If BFS is not growing from this neighbor.\n if (parents.get(currentNode) != currentNeighbor) {\n // We haven't previously visited this neighbor.\n if (!visited.has(currentNeighbor)) {\n toBeVisited.push(currentNeighbor);\n parents.set(currentNeighbor, currentNode);\n }\n // Since we have previously visited this neighbor and\n // this neighbor is not parent of currentNode, given\n // graph contains a component that is not tree, hence\n // it is not a forest.\n else {\n isForest = false;\n break;\n }\n }\n }\n }\n\n // The graph contains a component that is not a tree. Empty\n // previously found trees. The method will end.\n if (!isForest) {\n flatForest = [];\n }\n // Save currently visited nodes as a tree in our forest. Reset\n // visited and parents lists. Continue with the next component of\n // the graph, if any.\n else {\n var temp = [].concat(_toConsumableArray(visited));\n flatForest.push(temp);\n //flatForest = flatForest.concat(temp);\n //unProcessedNodes.removeAll(visited);\n for (var i = 0; i < temp.length; i++) {\n var value = temp[i];\n var index = unProcessedNodes.indexOf(value);\n if (index > -1) {\n unProcessedNodes.splice(index, 1);\n }\n }\n visited = new Set();\n parents = new Map();\n }\n }\n\n return flatForest;\n};\n\n/**\r\n * This method creates dummy nodes (an l-level node with minimal dimensions)\r\n * for the given edge (one per bendpoint). The existing l-level structure\r\n * is updated accordingly.\r\n */\nLayout.prototype.createDummyNodesForBendpoints = function (edge) {\n var dummyNodes = [];\n var prev = edge.source;\n\n var graph = this.graphManager.calcLowestCommonAncestor(edge.source, edge.target);\n\n for (var i = 0; i < edge.bendpoints.length; i++) {\n // create new dummy node\n var dummyNode = this.newNode(null);\n dummyNode.setRect(new Point(0, 0), new Dimension(1, 1));\n\n graph.add(dummyNode);\n\n // create new dummy edge between prev and dummy node\n var dummyEdge = this.newEdge(null);\n this.graphManager.add(dummyEdge, prev, dummyNode);\n\n dummyNodes.add(dummyNode);\n prev = dummyNode;\n }\n\n var dummyEdge = this.newEdge(null);\n this.graphManager.add(dummyEdge, prev, edge.target);\n\n this.edgeToDummyNodes.set(edge, dummyNodes);\n\n // remove real edge from graph manager if it is inter-graph\n if (edge.isInterGraph()) {\n this.graphManager.remove(edge);\n }\n // else, remove the edge from the current graph\n else {\n graph.remove(edge);\n }\n\n return dummyNodes;\n};\n\n/**\r\n * This method creates bendpoints for edges from the dummy nodes\r\n * at l-level.\r\n */\nLayout.prototype.createBendpointsFromDummyNodes = function () {\n var edges = [];\n edges = edges.concat(this.graphManager.getAllEdges());\n edges = [].concat(_toConsumableArray(this.edgeToDummyNodes.keys())).concat(edges);\n\n for (var k = 0; k < edges.length; k++) {\n var lEdge = edges[k];\n\n if (lEdge.bendpoints.length > 0) {\n var path = this.edgeToDummyNodes.get(lEdge);\n\n for (var i = 0; i < path.length; i++) {\n var dummyNode = path[i];\n var p = new PointD(dummyNode.getCenterX(), dummyNode.getCenterY());\n\n // update bendpoint's location according to dummy node\n var ebp = lEdge.bendpoints.get(i);\n ebp.x = p.x;\n ebp.y = p.y;\n\n // remove the dummy node, dummy edges incident with this\n // dummy node is also removed (within the remove method)\n dummyNode.getOwner().remove(dummyNode);\n }\n\n // add the real edge to graph\n this.graphManager.add(lEdge, lEdge.source, lEdge.target);\n }\n }\n};\n\nLayout.transform = function (sliderValue, defaultValue, minDiv, maxMul) {\n if (minDiv != undefined && maxMul != undefined) {\n var value = defaultValue;\n\n if (sliderValue <= 50) {\n var minValue = defaultValue / minDiv;\n value -= (defaultValue - minValue) / 50 * (50 - sliderValue);\n } else {\n var maxValue = defaultValue * maxMul;\n value += (maxValue - defaultValue) / 50 * (sliderValue - 50);\n }\n\n return value;\n } else {\n var a, b;\n\n if (sliderValue <= 50) {\n a = 9.0 * defaultValue / 500.0;\n b = defaultValue / 10.0;\n } else {\n a = 9.0 * defaultValue / 50.0;\n b = -8 * defaultValue;\n }\n\n return a * sliderValue + b;\n }\n};\n\n/**\r\n * This method finds and returns the center of the given nodes, assuming\r\n * that the given nodes form a tree in themselves.\r\n */\nLayout.findCenterOfTree = function (nodes) {\n var list = [];\n list = list.concat(nodes);\n\n var removedNodes = [];\n var remainingDegrees = new Map();\n var foundCenter = false;\n var centerNode = null;\n\n if (list.length == 1 || list.length == 2) {\n foundCenter = true;\n centerNode = list[0];\n }\n\n for (var i = 0; i < list.length; i++) {\n var node = list[i];\n var degree = node.getNeighborsList().size;\n remainingDegrees.set(node, node.getNeighborsList().size);\n\n if (degree == 1) {\n removedNodes.push(node);\n }\n }\n\n var tempList = [];\n tempList = tempList.concat(removedNodes);\n\n while (!foundCenter) {\n var tempList2 = [];\n tempList2 = tempList2.concat(tempList);\n tempList = [];\n\n for (var i = 0; i < list.length; i++) {\n var node = list[i];\n\n var index = list.indexOf(node);\n if (index >= 0) {\n list.splice(index, 1);\n }\n\n var neighbours = node.getNeighborsList();\n\n neighbours.forEach(function (neighbour) {\n if (removedNodes.indexOf(neighbour) < 0) {\n var otherDegree = remainingDegrees.get(neighbour);\n var newDegree = otherDegree - 1;\n\n if (newDegree == 1) {\n tempList.push(neighbour);\n }\n\n remainingDegrees.set(neighbour, newDegree);\n }\n });\n }\n\n removedNodes = removedNodes.concat(tempList);\n\n if (list.length == 1 || list.length == 2) {\n foundCenter = true;\n centerNode = list[0];\n }\n }\n\n return centerNode;\n};\n\n/**\r\n * During the coarsening process, this layout may be referenced by two graph managers\r\n * this setter function grants access to change the currently being used graph manager\r\n */\nLayout.prototype.setGraphManager = function (gm) {\n this.graphManager = gm;\n};\n\nmodule.exports = Layout;\n\n/***/ }),\n/* 16 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction RandomSeed() {}\n// adapted from: https://stackoverflow.com/a/19303725\nRandomSeed.seed = 1;\nRandomSeed.x = 0;\n\nRandomSeed.nextDouble = function () {\n RandomSeed.x = Math.sin(RandomSeed.seed++) * 10000;\n return RandomSeed.x - Math.floor(RandomSeed.x);\n};\n\nmodule.exports = RandomSeed;\n\n/***/ }),\n/* 17 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar PointD = __webpack_require__(5);\n\nfunction Transform(x, y) {\n this.lworldOrgX = 0.0;\n this.lworldOrgY = 0.0;\n this.ldeviceOrgX = 0.0;\n this.ldeviceOrgY = 0.0;\n this.lworldExtX = 1.0;\n this.lworldExtY = 1.0;\n this.ldeviceExtX = 1.0;\n this.ldeviceExtY = 1.0;\n}\n\nTransform.prototype.getWorldOrgX = function () {\n return this.lworldOrgX;\n};\n\nTransform.prototype.setWorldOrgX = function (wox) {\n this.lworldOrgX = wox;\n};\n\nTransform.prototype.getWorldOrgY = function () {\n return this.lworldOrgY;\n};\n\nTransform.prototype.setWorldOrgY = function (woy) {\n this.lworldOrgY = woy;\n};\n\nTransform.prototype.getWorldExtX = function () {\n return this.lworldExtX;\n};\n\nTransform.prototype.setWorldExtX = function (wex) {\n this.lworldExtX = wex;\n};\n\nTransform.prototype.getWorldExtY = function () {\n return this.lworldExtY;\n};\n\nTransform.prototype.setWorldExtY = function (wey) {\n this.lworldExtY = wey;\n};\n\n/* Device related */\n\nTransform.prototype.getDeviceOrgX = function () {\n return this.ldeviceOrgX;\n};\n\nTransform.prototype.setDeviceOrgX = function (dox) {\n this.ldeviceOrgX = dox;\n};\n\nTransform.prototype.getDeviceOrgY = function () {\n return this.ldeviceOrgY;\n};\n\nTransform.prototype.setDeviceOrgY = function (doy) {\n this.ldeviceOrgY = doy;\n};\n\nTransform.prototype.getDeviceExtX = function () {\n return this.ldeviceExtX;\n};\n\nTransform.prototype.setDeviceExtX = function (dex) {\n this.ldeviceExtX = dex;\n};\n\nTransform.prototype.getDeviceExtY = function () {\n return this.ldeviceExtY;\n};\n\nTransform.prototype.setDeviceExtY = function (dey) {\n this.ldeviceExtY = dey;\n};\n\nTransform.prototype.transformX = function (x) {\n var xDevice = 0.0;\n var worldExtX = this.lworldExtX;\n if (worldExtX != 0.0) {\n xDevice = this.ldeviceOrgX + (x - this.lworldOrgX) * this.ldeviceExtX / worldExtX;\n }\n\n return xDevice;\n};\n\nTransform.prototype.transformY = function (y) {\n var yDevice = 0.0;\n var worldExtY = this.lworldExtY;\n if (worldExtY != 0.0) {\n yDevice = this.ldeviceOrgY + (y - this.lworldOrgY) * this.ldeviceExtY / worldExtY;\n }\n\n return yDevice;\n};\n\nTransform.prototype.inverseTransformX = function (x) {\n var xWorld = 0.0;\n var deviceExtX = this.ldeviceExtX;\n if (deviceExtX != 0.0) {\n xWorld = this.lworldOrgX + (x - this.ldeviceOrgX) * this.lworldExtX / deviceExtX;\n }\n\n return xWorld;\n};\n\nTransform.prototype.inverseTransformY = function (y) {\n var yWorld = 0.0;\n var deviceExtY = this.ldeviceExtY;\n if (deviceExtY != 0.0) {\n yWorld = this.lworldOrgY + (y - this.ldeviceOrgY) * this.lworldExtY / deviceExtY;\n }\n return yWorld;\n};\n\nTransform.prototype.inverseTransformPoint = function (inPoint) {\n var outPoint = new PointD(this.inverseTransformX(inPoint.x), this.inverseTransformY(inPoint.y));\n return outPoint;\n};\n\nmodule.exports = Transform;\n\n/***/ }),\n/* 18 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar Layout = __webpack_require__(15);\nvar FDLayoutConstants = __webpack_require__(4);\nvar LayoutConstants = __webpack_require__(0);\nvar IGeometry = __webpack_require__(8);\nvar IMath = __webpack_require__(9);\n\nfunction FDLayout() {\n Layout.call(this);\n\n this.useSmartIdealEdgeLengthCalculation = FDLayoutConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;\n this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;\n this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;\n this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;\n this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;\n this.displacementThresholdPerNode = 3.0 * FDLayoutConstants.DEFAULT_EDGE_LENGTH / 100;\n this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;\n this.initialCoolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;\n this.totalDisplacement = 0.0;\n this.oldTotalDisplacement = 0.0;\n this.maxIterations = FDLayoutConstants.MAX_ITERATIONS;\n}\n\nFDLayout.prototype = Object.create(Layout.prototype);\n\nfor (var prop in Layout) {\n FDLayout[prop] = Layout[prop];\n}\n\nFDLayout.prototype.initParameters = function () {\n Layout.prototype.initParameters.call(this, arguments);\n\n this.totalIterations = 0;\n this.notAnimatedIterations = 0;\n\n this.useFRGridVariant = FDLayoutConstants.DEFAULT_USE_SMART_REPULSION_RANGE_CALCULATION;\n\n this.grid = [];\n};\n\nFDLayout.prototype.calcIdealEdgeLengths = function () {\n var edge;\n var originalIdealLength;\n var lcaDepth;\n var source;\n var target;\n var sizeOfSourceInLca;\n var sizeOfTargetInLca;\n\n var allEdges = this.getGraphManager().getAllEdges();\n for (var i = 0; i < allEdges.length; i++) {\n edge = allEdges[i];\n\n originalIdealLength = edge.idealLength;\n\n if (edge.isInterGraph) {\n source = edge.getSource();\n target = edge.getTarget();\n\n sizeOfSourceInLca = edge.getSourceInLca().getEstimatedSize();\n sizeOfTargetInLca = edge.getTargetInLca().getEstimatedSize();\n\n if (this.useSmartIdealEdgeLengthCalculation) {\n edge.idealLength += sizeOfSourceInLca + sizeOfTargetInLca - 2 * LayoutConstants.SIMPLE_NODE_SIZE;\n }\n\n lcaDepth = edge.getLca().getInclusionTreeDepth();\n\n edge.idealLength += originalIdealLength * FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR * (source.getInclusionTreeDepth() + target.getInclusionTreeDepth() - 2 * lcaDepth);\n }\n }\n};\n\nFDLayout.prototype.initSpringEmbedder = function () {\n\n var s = this.getAllNodes().length;\n if (this.incremental) {\n if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) {\n this.coolingFactor = Math.max(this.coolingFactor * FDLayoutConstants.COOLING_ADAPTATION_FACTOR, this.coolingFactor - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * this.coolingFactor * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR));\n }\n this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT_INCREMENTAL;\n } else {\n if (s > FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) {\n this.coolingFactor = Math.max(FDLayoutConstants.COOLING_ADAPTATION_FACTOR, 1.0 - (s - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) / (FDLayoutConstants.ADAPTATION_UPPER_NODE_LIMIT - FDLayoutConstants.ADAPTATION_LOWER_NODE_LIMIT) * (1 - FDLayoutConstants.COOLING_ADAPTATION_FACTOR));\n } else {\n this.coolingFactor = 1.0;\n }\n this.initialCoolingFactor = this.coolingFactor;\n this.maxNodeDisplacement = FDLayoutConstants.MAX_NODE_DISPLACEMENT;\n }\n\n this.maxIterations = Math.max(this.getAllNodes().length * 5, this.maxIterations);\n\n // Reassign this attribute by using new constant value\n this.displacementThresholdPerNode = 3.0 * FDLayoutConstants.DEFAULT_EDGE_LENGTH / 100;\n this.totalDisplacementThreshold = this.displacementThresholdPerNode * this.getAllNodes().length;\n\n this.repulsionRange = this.calcRepulsionRange();\n};\n\nFDLayout.prototype.calcSpringForces = function () {\n var lEdges = this.getAllEdges();\n var edge;\n\n for (var i = 0; i < lEdges.length; i++) {\n edge = lEdges[i];\n\n this.calcSpringForce(edge, edge.idealLength);\n }\n};\n\nFDLayout.prototype.calcRepulsionForces = function () {\n var gridUpdateAllowed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;\n var forceToNodeSurroundingUpdate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;\n\n var i, j;\n var nodeA, nodeB;\n var lNodes = this.getAllNodes();\n var processedNodeSet;\n\n if (this.useFRGridVariant) {\n if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed) {\n this.updateGrid();\n }\n\n processedNodeSet = new Set();\n\n // calculate repulsion forces between each nodes and its surrounding\n for (i = 0; i < lNodes.length; i++) {\n nodeA = lNodes[i];\n this.calculateRepulsionForceOfANode(nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate);\n processedNodeSet.add(nodeA);\n }\n } else {\n for (i = 0; i < lNodes.length; i++) {\n nodeA = lNodes[i];\n\n for (j = i + 1; j < lNodes.length; j++) {\n nodeB = lNodes[j];\n\n // If both nodes are not members of the same graph, skip.\n if (nodeA.getOwner() != nodeB.getOwner()) {\n continue;\n }\n\n this.calcRepulsionForce(nodeA, nodeB);\n }\n }\n }\n};\n\nFDLayout.prototype.calcGravitationalForces = function () {\n var node;\n var lNodes = this.getAllNodesToApplyGravitation();\n\n for (var i = 0; i < lNodes.length; i++) {\n node = lNodes[i];\n this.calcGravitationalForce(node);\n }\n};\n\nFDLayout.prototype.moveNodes = function () {\n var lNodes = this.getAllNodes();\n var node;\n\n for (var i = 0; i < lNodes.length; i++) {\n node = lNodes[i];\n node.move();\n }\n};\n\nFDLayout.prototype.calcSpringForce = function (edge, idealLength) {\n var sourceNode = edge.getSource();\n var targetNode = edge.getTarget();\n\n var length;\n var springForce;\n var springForceX;\n var springForceY;\n\n // Update edge length\n if (this.uniformLeafNodeSizes && sourceNode.getChild() == null && targetNode.getChild() == null) {\n edge.updateLengthSimple();\n } else {\n edge.updateLength();\n\n if (edge.isOverlapingSourceAndTarget) {\n return;\n }\n }\n\n length = edge.getLength();\n\n if (length == 0) return;\n\n // Calculate spring forces\n springForce = edge.edgeElasticity * (length - idealLength);\n\n // Project force onto x and y axes\n springForceX = springForce * (edge.lengthX / length);\n springForceY = springForce * (edge.lengthY / length);\n\n // Apply forces on the end nodes\n sourceNode.springForceX += springForceX;\n sourceNode.springForceY += springForceY;\n targetNode.springForceX -= springForceX;\n targetNode.springForceY -= springForceY;\n};\n\nFDLayout.prototype.calcRepulsionForce = function (nodeA, nodeB) {\n var rectA = nodeA.getRect();\n var rectB = nodeB.getRect();\n var overlapAmount = new Array(2);\n var clipPoints = new Array(4);\n var distanceX;\n var distanceY;\n var distanceSquared;\n var distance;\n var repulsionForce;\n var repulsionForceX;\n var repulsionForceY;\n\n if (rectA.intersects(rectB)) // two nodes overlap\n {\n // calculate separation amount in x and y directions\n IGeometry.calcSeparationAmount(rectA, rectB, overlapAmount, FDLayoutConstants.DEFAULT_EDGE_LENGTH / 2.0);\n\n repulsionForceX = 2 * overlapAmount[0];\n repulsionForceY = 2 * overlapAmount[1];\n\n var childrenConstant = nodeA.noOfChildren * nodeB.noOfChildren / (nodeA.noOfChildren + nodeB.noOfChildren);\n\n // Apply forces on the two nodes\n nodeA.repulsionForceX -= childrenConstant * repulsionForceX;\n nodeA.repulsionForceY -= childrenConstant * repulsionForceY;\n nodeB.repulsionForceX += childrenConstant * repulsionForceX;\n nodeB.repulsionForceY += childrenConstant * repulsionForceY;\n } else // no overlap\n {\n // calculate distance\n\n if (this.uniformLeafNodeSizes && nodeA.getChild() == null && nodeB.getChild() == null) // simply base repulsion on distance of node centers\n {\n distanceX = rectB.getCenterX() - rectA.getCenterX();\n distanceY = rectB.getCenterY() - rectA.getCenterY();\n } else // use clipping points\n {\n IGeometry.getIntersection(rectA, rectB, clipPoints);\n\n distanceX = clipPoints[2] - clipPoints[0];\n distanceY = clipPoints[3] - clipPoints[1];\n }\n\n // No repulsion range. FR grid variant should take care of this.\n if (Math.abs(distanceX) < FDLayoutConstants.MIN_REPULSION_DIST) {\n distanceX = IMath.sign(distanceX) * FDLayoutConstants.MIN_REPULSION_DIST;\n }\n\n if (Math.abs(distanceY) < FDLayoutConstants.MIN_REPULSION_DIST) {\n distanceY = IMath.sign(distanceY) * FDLayoutConstants.MIN_REPULSION_DIST;\n }\n\n distanceSquared = distanceX * distanceX + distanceY * distanceY;\n distance = Math.sqrt(distanceSquared);\n\n // Here we use half of the nodes' repulsion values for backward compatibility\n repulsionForce = (nodeA.nodeRepulsion / 2 + nodeB.nodeRepulsion / 2) * nodeA.noOfChildren * nodeB.noOfChildren / distanceSquared;\n\n // Project force onto x and y axes\n repulsionForceX = repulsionForce * distanceX / distance;\n repulsionForceY = repulsionForce * distanceY / distance;\n\n // Apply forces on the two nodes \n nodeA.repulsionForceX -= repulsionForceX;\n nodeA.repulsionForceY -= repulsionForceY;\n nodeB.repulsionForceX += repulsionForceX;\n nodeB.repulsionForceY += repulsionForceY;\n }\n};\n\nFDLayout.prototype.calcGravitationalForce = function (node) {\n var ownerGraph;\n var ownerCenterX;\n var ownerCenterY;\n var distanceX;\n var distanceY;\n var absDistanceX;\n var absDistanceY;\n var estimatedSize;\n ownerGraph = node.getOwner();\n\n ownerCenterX = (ownerGraph.getRight() + ownerGraph.getLeft()) / 2;\n ownerCenterY = (ownerGraph.getTop() + ownerGraph.getBottom()) / 2;\n distanceX = node.getCenterX() - ownerCenterX;\n distanceY = node.getCenterY() - ownerCenterY;\n absDistanceX = Math.abs(distanceX) + node.getWidth() / 2;\n absDistanceY = Math.abs(distanceY) + node.getHeight() / 2;\n\n if (node.getOwner() == this.graphManager.getRoot()) // in the root graph\n {\n estimatedSize = ownerGraph.getEstimatedSize() * this.gravityRangeFactor;\n\n if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) {\n node.gravitationForceX = -this.gravityConstant * distanceX;\n node.gravitationForceY = -this.gravityConstant * distanceY;\n }\n } else // inside a compound\n {\n estimatedSize = ownerGraph.getEstimatedSize() * this.compoundGravityRangeFactor;\n\n if (absDistanceX > estimatedSize || absDistanceY > estimatedSize) {\n node.gravitationForceX = -this.gravityConstant * distanceX * this.compoundGravityConstant;\n node.gravitationForceY = -this.gravityConstant * distanceY * this.compoundGravityConstant;\n }\n }\n};\n\nFDLayout.prototype.isConverged = function () {\n var converged;\n var oscilating = false;\n\n if (this.totalIterations > this.maxIterations / 3) {\n oscilating = Math.abs(this.totalDisplacement - this.oldTotalDisplacement) < 2;\n }\n\n converged = this.totalDisplacement < this.totalDisplacementThreshold;\n\n this.oldTotalDisplacement = this.totalDisplacement;\n\n return converged || oscilating;\n};\n\nFDLayout.prototype.animate = function () {\n if (this.animationDuringLayout && !this.isSubLayout) {\n if (this.notAnimatedIterations == this.animationPeriod) {\n this.update();\n this.notAnimatedIterations = 0;\n } else {\n this.notAnimatedIterations++;\n }\n }\n};\n\n//This method calculates the number of children (weight) for all nodes\nFDLayout.prototype.calcNoOfChildrenForAllNodes = function () {\n var node;\n var allNodes = this.graphManager.getAllNodes();\n\n for (var i = 0; i < allNodes.length; i++) {\n node = allNodes[i];\n node.noOfChildren = node.getNoOfChildren();\n }\n};\n\n// -----------------------------------------------------------------------------\n// Section: FR-Grid Variant Repulsion Force Calculation\n// -----------------------------------------------------------------------------\n\nFDLayout.prototype.calcGrid = function (graph) {\n\n var sizeX = 0;\n var sizeY = 0;\n\n sizeX = parseInt(Math.ceil((graph.getRight() - graph.getLeft()) / this.repulsionRange));\n sizeY = parseInt(Math.ceil((graph.getBottom() - graph.getTop()) / this.repulsionRange));\n\n var grid = new Array(sizeX);\n\n for (var i = 0; i < sizeX; i++) {\n grid[i] = new Array(sizeY);\n }\n\n for (var i = 0; i < sizeX; i++) {\n for (var j = 0; j < sizeY; j++) {\n grid[i][j] = new Array();\n }\n }\n\n return grid;\n};\n\nFDLayout.prototype.addNodeToGrid = function (v, left, top) {\n\n var startX = 0;\n var finishX = 0;\n var startY = 0;\n var finishY = 0;\n\n startX = parseInt(Math.floor((v.getRect().x - left) / this.repulsionRange));\n finishX = parseInt(Math.floor((v.getRect().width + v.getRect().x - left) / this.repulsionRange));\n startY = parseInt(Math.floor((v.getRect().y - top) / this.repulsionRange));\n finishY = parseInt(Math.floor((v.getRect().height + v.getRect().y - top) / this.repulsionRange));\n\n for (var i = startX; i <= finishX; i++) {\n for (var j = startY; j <= finishY; j++) {\n this.grid[i][j].push(v);\n v.setGridCoordinates(startX, finishX, startY, finishY);\n }\n }\n};\n\nFDLayout.prototype.updateGrid = function () {\n var i;\n var nodeA;\n var lNodes = this.getAllNodes();\n\n this.grid = this.calcGrid(this.graphManager.getRoot());\n\n // put all nodes to proper grid cells\n for (i = 0; i < lNodes.length; i++) {\n nodeA = lNodes[i];\n this.addNodeToGrid(nodeA, this.graphManager.getRoot().getLeft(), this.graphManager.getRoot().getTop());\n }\n};\n\nFDLayout.prototype.calculateRepulsionForceOfANode = function (nodeA, processedNodeSet, gridUpdateAllowed, forceToNodeSurroundingUpdate) {\n\n if (this.totalIterations % FDLayoutConstants.GRID_CALCULATION_CHECK_PERIOD == 1 && gridUpdateAllowed || forceToNodeSurroundingUpdate) {\n var surrounding = new Set();\n nodeA.surrounding = new Array();\n var nodeB;\n var grid = this.grid;\n\n for (var i = nodeA.startX - 1; i < nodeA.finishX + 2; i++) {\n for (var j = nodeA.startY - 1; j < nodeA.finishY + 2; j++) {\n if (!(i < 0 || j < 0 || i >= grid.length || j >= grid[0].length)) {\n for (var k = 0; k < grid[i][j].length; k++) {\n nodeB = grid[i][j][k];\n\n // If both nodes are not members of the same graph, \n // or both nodes are the same, skip.\n if (nodeA.getOwner() != nodeB.getOwner() || nodeA == nodeB) {\n continue;\n }\n\n // check if the repulsion force between\n // nodeA and nodeB has already been calculated\n if (!processedNodeSet.has(nodeB) && !surrounding.has(nodeB)) {\n var distanceX = Math.abs(nodeA.getCenterX() - nodeB.getCenterX()) - (nodeA.getWidth() / 2 + nodeB.getWidth() / 2);\n var distanceY = Math.abs(nodeA.getCenterY() - nodeB.getCenterY()) - (nodeA.getHeight() / 2 + nodeB.getHeight() / 2);\n\n // if the distance between nodeA and nodeB \n // is less then calculation range\n if (distanceX <= this.repulsionRange && distanceY <= this.repulsionRange) {\n //then add nodeB to surrounding of nodeA\n surrounding.add(nodeB);\n }\n }\n }\n }\n }\n }\n\n nodeA.surrounding = [].concat(_toConsumableArray(surrounding));\n }\n for (i = 0; i < nodeA.surrounding.length; i++) {\n this.calcRepulsionForce(nodeA, nodeA.surrounding[i]);\n }\n};\n\nFDLayout.prototype.calcRepulsionRange = function () {\n return 0.0;\n};\n\nmodule.exports = FDLayout;\n\n/***/ }),\n/* 19 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LEdge = __webpack_require__(1);\nvar FDLayoutConstants = __webpack_require__(4);\n\nfunction FDLayoutEdge(source, target, vEdge) {\n LEdge.call(this, source, target, vEdge);\n\n // Ideal length and elasticity value for this edge\n this.idealLength = FDLayoutConstants.DEFAULT_EDGE_LENGTH;\n this.edgeElasticity = FDLayoutConstants.DEFAULT_SPRING_STRENGTH;\n}\n\nFDLayoutEdge.prototype = Object.create(LEdge.prototype);\n\nfor (var prop in LEdge) {\n FDLayoutEdge[prop] = LEdge[prop];\n}\n\nmodule.exports = FDLayoutEdge;\n\n/***/ }),\n/* 20 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar LNode = __webpack_require__(3);\nvar FDLayoutConstants = __webpack_require__(4);\n\nfunction FDLayoutNode(gm, loc, size, vNode) {\n // alternative constructor is handled inside LNode\n LNode.call(this, gm, loc, size, vNode);\n\n // Repulsion value of this node\n this.nodeRepulsion = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH;\n\n //Spring, repulsion and gravitational forces acting on this node\n this.springForceX = 0;\n this.springForceY = 0;\n this.repulsionForceX = 0;\n this.repulsionForceY = 0;\n this.gravitationForceX = 0;\n this.gravitationForceY = 0;\n //Amount by which this node is to be moved in this iteration\n this.displacementX = 0;\n this.displacementY = 0;\n\n //Start and finish grid coordinates that this node is fallen into\n this.startX = 0;\n this.finishX = 0;\n this.startY = 0;\n this.finishY = 0;\n\n //Geometric neighbors of this node\n this.surrounding = [];\n}\n\nFDLayoutNode.prototype = Object.create(LNode.prototype);\n\nfor (var prop in LNode) {\n FDLayoutNode[prop] = LNode[prop];\n}\n\nFDLayoutNode.prototype.setGridCoordinates = function (_startX, _finishX, _startY, _finishY) {\n this.startX = _startX;\n this.finishX = _finishX;\n this.startY = _startY;\n this.finishY = _finishY;\n};\n\nmodule.exports = FDLayoutNode;\n\n/***/ }),\n/* 21 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction DimensionD(width, height) {\n this.width = 0;\n this.height = 0;\n if (width !== null && height !== null) {\n this.height = height;\n this.width = width;\n }\n}\n\nDimensionD.prototype.getWidth = function () {\n return this.width;\n};\n\nDimensionD.prototype.setWidth = function (width) {\n this.width = width;\n};\n\nDimensionD.prototype.getHeight = function () {\n return this.height;\n};\n\nDimensionD.prototype.setHeight = function (height) {\n this.height = height;\n};\n\nmodule.exports = DimensionD;\n\n/***/ }),\n/* 22 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar UniqueIDGeneretor = __webpack_require__(14);\n\nfunction HashMap() {\n this.map = {};\n this.keys = [];\n}\n\nHashMap.prototype.put = function (key, value) {\n var theId = UniqueIDGeneretor.createID(key);\n if (!this.contains(theId)) {\n this.map[theId] = value;\n this.keys.push(key);\n }\n};\n\nHashMap.prototype.contains = function (key) {\n var theId = UniqueIDGeneretor.createID(key);\n return this.map[key] != null;\n};\n\nHashMap.prototype.get = function (key) {\n var theId = UniqueIDGeneretor.createID(key);\n return this.map[theId];\n};\n\nHashMap.prototype.keySet = function () {\n return this.keys;\n};\n\nmodule.exports = HashMap;\n\n/***/ }),\n/* 23 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar UniqueIDGeneretor = __webpack_require__(14);\n\nfunction HashSet() {\n this.set = {};\n}\n;\n\nHashSet.prototype.add = function (obj) {\n var theId = UniqueIDGeneretor.createID(obj);\n if (!this.contains(theId)) this.set[theId] = obj;\n};\n\nHashSet.prototype.remove = function (obj) {\n delete this.set[UniqueIDGeneretor.createID(obj)];\n};\n\nHashSet.prototype.clear = function () {\n this.set = {};\n};\n\nHashSet.prototype.contains = function (obj) {\n return this.set[UniqueIDGeneretor.createID(obj)] == obj;\n};\n\nHashSet.prototype.isEmpty = function () {\n return this.size() === 0;\n};\n\nHashSet.prototype.size = function () {\n return Object.keys(this.set).length;\n};\n\n//concats this.set to the given list\nHashSet.prototype.addAllTo = function (list) {\n var keys = Object.keys(this.set);\n var length = keys.length;\n for (var i = 0; i < length; i++) {\n list.push(this.set[keys[i]]);\n }\n};\n\nHashSet.prototype.size = function () {\n return Object.keys(this.set).length;\n};\n\nHashSet.prototype.addAll = function (list) {\n var s = list.length;\n for (var i = 0; i < s; i++) {\n var v = list[i];\n this.add(v);\n }\n};\n\nmodule.exports = HashSet;\n\n/***/ }),\n/* 24 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n// Some matrix (1d and 2d array) operations\nfunction Matrix() {}\n\n/**\n * matrix multiplication\n * array1, array2 and result are 2d arrays\n */\nMatrix.multMat = function (array1, array2) {\n var result = [];\n\n for (var i = 0; i < array1.length; i++) {\n result[i] = [];\n for (var j = 0; j < array2[0].length; j++) {\n result[i][j] = 0;\n for (var k = 0; k < array1[0].length; k++) {\n result[i][j] += array1[i][k] * array2[k][j];\n }\n }\n }\n return result;\n};\n\n/**\n * matrix transpose\n * array and result are 2d arrays\n */\nMatrix.transpose = function (array) {\n var result = [];\n\n for (var i = 0; i < array[0].length; i++) {\n result[i] = [];\n for (var j = 0; j < array.length; j++) {\n result[i][j] = array[j][i];\n }\n }\n\n return result;\n};\n\n/**\n * multiply array with constant\n * array and result are 1d arrays\n */\nMatrix.multCons = function (array, constant) {\n var result = [];\n\n for (var i = 0; i < array.length; i++) {\n result[i] = array[i] * constant;\n }\n\n return result;\n};\n\n/**\n * substract two arrays\n * array1, array2 and result are 1d arrays\n */\nMatrix.minusOp = function (array1, array2) {\n var result = [];\n\n for (var i = 0; i < array1.length; i++) {\n result[i] = array1[i] - array2[i];\n }\n\n return result;\n};\n\n/**\n * dot product of two arrays with same size\n * array1 and array2 are 1d arrays\n */\nMatrix.dotProduct = function (array1, array2) {\n var product = 0;\n\n for (var i = 0; i < array1.length; i++) {\n product += array1[i] * array2[i];\n }\n\n return product;\n};\n\n/**\n * magnitude of an array\n * array is 1d array\n */\nMatrix.mag = function (array) {\n return Math.sqrt(this.dotProduct(array, array));\n};\n\n/**\n * normalization of an array\n * array and result are 1d array\n */\nMatrix.normalize = function (array) {\n var result = [];\n var magnitude = this.mag(array);\n\n for (var i = 0; i < array.length; i++) {\n result[i] = array[i] / magnitude;\n }\n\n return result;\n};\n\n/**\n * multiply an array with centering matrix\n * array and result are 1d array\n */\nMatrix.multGamma = function (array) {\n var result = [];\n var sum = 0;\n\n for (var i = 0; i < array.length; i++) {\n sum += array[i];\n }\n\n sum *= -1 / array.length;\n\n for (var _i = 0; _i < array.length; _i++) {\n result[_i] = sum + array[_i];\n }\n return result;\n};\n\n/**\n * a special matrix multiplication\n * result = 0.5 * C * INV * C^T * array\n * array and result are 1d, C and INV are 2d arrays\n */\nMatrix.multL = function (array, C, INV) {\n var result = [];\n var temp1 = [];\n var temp2 = [];\n\n // multiply by C^T\n for (var i = 0; i < C[0].length; i++) {\n var sum = 0;\n for (var j = 0; j < C.length; j++) {\n sum += -0.5 * C[j][i] * array[j];\n }\n temp1[i] = sum;\n }\n // multiply the result by INV\n for (var _i2 = 0; _i2 < INV.length; _i2++) {\n var _sum = 0;\n for (var _j = 0; _j < INV.length; _j++) {\n _sum += INV[_i2][_j] * temp1[_j];\n }\n temp2[_i2] = _sum;\n }\n // multiply the result by C\n for (var _i3 = 0; _i3 < C.length; _i3++) {\n var _sum2 = 0;\n for (var _j2 = 0; _j2 < C[0].length; _j2++) {\n _sum2 += C[_i3][_j2] * temp2[_j2];\n }\n result[_i3] = _sum2;\n }\n\n return result;\n};\n\nmodule.exports = Matrix;\n\n/***/ }),\n/* 25 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * A classic Quicksort algorithm with Hoare's partition\n * - Works also on LinkedList objects\n *\n * Copyright: i-Vis Research Group, Bilkent University, 2007 - present\n */\n\nvar LinkedList = __webpack_require__(11);\n\nvar Quicksort = function () {\n function Quicksort(A, compareFunction) {\n _classCallCheck(this, Quicksort);\n\n if (compareFunction !== null || compareFunction !== undefined) this.compareFunction = this._defaultCompareFunction;\n\n var length = void 0;\n if (A instanceof LinkedList) length = A.size();else length = A.length;\n\n this._quicksort(A, 0, length - 1);\n }\n\n _createClass(Quicksort, [{\n key: '_quicksort',\n value: function _quicksort(A, p, r) {\n if (p < r) {\n var q = this._partition(A, p, r);\n this._quicksort(A, p, q);\n this._quicksort(A, q + 1, r);\n }\n }\n }, {\n key: '_partition',\n value: function _partition(A, p, r) {\n var x = this._get(A, p);\n var i = p;\n var j = r;\n while (true) {\n while (this.compareFunction(x, this._get(A, j))) {\n j--;\n }while (this.compareFunction(this._get(A, i), x)) {\n i++;\n }if (i < j) {\n this._swap(A, i, j);\n i++;\n j--;\n } else return j;\n }\n }\n }, {\n key: '_get',\n value: function _get(object, index) {\n if (object instanceof LinkedList) return object.get_object_at(index);else return object[index];\n }\n }, {\n key: '_set',\n value: function _set(object, index, value) {\n if (object instanceof LinkedList) object.set_object_at(index, value);else object[index] = value;\n }\n }, {\n key: '_swap',\n value: function _swap(A, i, j) {\n var temp = this._get(A, i);\n this._set(A, i, this._get(A, j));\n this._set(A, j, temp);\n }\n }, {\n key: '_defaultCompareFunction',\n value: function _defaultCompareFunction(a, b) {\n return b > a;\n }\n }]);\n\n return Quicksort;\n}();\n\nmodule.exports = Quicksort;\n\n/***/ }),\n/* 26 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\n// Singular Value Decomposition implementation\nfunction SVD() {};\n\n/* Below singular value decomposition (svd) code including hypot function is adopted from https://github.com/dragonfly-ai/JamaJS\n Some changes are applied to make the code compatible with the fcose code and to make it independent from Jama.\n Input matrix is changed to a 2D array instead of Jama matrix. Matrix dimensions are taken according to 2D array instead of using Jama functions.\n An object that includes singular value components is created for return. \n The types of input parameters of the hypot function are removed. \n let is used instead of var for the variable initialization.\n*/\n/*\n Apache License\n Version 2.0, January 2004\n http://www.apache.org/licenses/\n\n TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n 1. Definitions.\n\n \"License\" shall mean the terms and conditions for use, reproduction,\n and distribution as defined by Sections 1 through 9 of this document.\n\n \"Licensor\" shall mean the copyright owner or entity authorized by\n the copyright owner that is granting the License.\n\n \"Legal Entity\" shall mean the union of the acting entity and all\n other entities that control, are controlled by, or are under common\n control with that entity. For the purposes of this definition,\n \"control\" means (i) the power, direct or indirect, to cause the\n direction or management of such entity, whether by contract or\n otherwise, or (ii) ownership of fifty percent (50%) or more of the\n outstanding shares, or (iii) beneficial ownership of such entity.\n\n \"You\" (or \"Your\") shall mean an individual or Legal Entity\n exercising permissions granted by this License.\n\n \"Source\" form shall mean the preferred form for making modifications,\n including but not limited to software source code, documentation\n source, and configuration files.\n\n \"Object\" form shall mean any form resulting from mechanical\n transformation or translation of a Source form, including but\n not limited to compiled object code, generated documentation,\n and conversions to other media types.\n\n \"Work\" shall mean the work of authorship, whether in Source or\n Object form, made available under the License, as indicated by a\n copyright notice that is included in or attached to the work\n (an example is provided in the Appendix below).\n\n \"Derivative Works\" shall mean any work, whether in Source or Object\n form, that is based on (or derived from) the Work and for which the\n editorial revisions, annotations, elaborations, or other modifications\n represent, as a whole, an original work of authorship. For the purposes\n of this License, Derivative Works shall not include works that remain\n separable from, or merely link (or bind by name) to the interfaces of,\n the Work and Derivative Works thereof.\n\n \"Contribution\" shall mean any work of authorship, including\n the original version of the Work and any modifications or additions\n to that Work or Derivative Works thereof, that is intentionally\n submitted to Licensor for inclusion in the Work by the copyright owner\n or by an individual or Legal Entity authorized to submit on behalf of\n the copyright owner. For the purposes of this definition, \"submitted\"\n means any form of electronic, verbal, or written communication sent\n to the Licensor or its representatives, including but not limited to\n communication on electronic mailing lists, source code control systems,\n and issue tracking systems that are managed by, or on behalf of, the\n Licensor for the purpose of discussing and improving the Work, but\n excluding communication that is conspicuously marked or otherwise\n designated in writing by the copyright owner as \"Not a Contribution.\"\n\n \"Contributor\" shall mean Licensor and any individual or Legal Entity\n on behalf of whom a Contribution has been received by Licensor and\n subsequently incorporated within the Work.\n\n 2. Grant of Copyright License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n copyright license to reproduce, prepare Derivative Works of,\n publicly display, publicly perform, sublicense, and distribute the\n Work and such Derivative Works in Source or Object form.\n\n 3. Grant of Patent License. Subject to the terms and conditions of\n this License, each Contributor hereby grants to You a perpetual,\n worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n (except as stated in this section) patent license to make, have made,\n use, offer to sell, sell, import, and otherwise transfer the Work,\n where such license applies only to those patent claims licensable\n by such Contributor that are necessarily infringed by their\n Contribution(s) alone or by combination of their Contribution(s)\n with the Work to which such Contribution(s) was submitted. If You\n institute patent litigation against any entity (including a\n cross-claim or counterclaim in a lawsuit) alleging that the Work\n or a Contribution incorporated within the Work constitutes direct\n or contributory patent infringement, then any patent licenses\n granted to You under this License for that Work shall terminate\n as of the date such litigation is filed.\n\n 4. Redistribution. You may reproduce and distribute copies of the\n Work or Derivative Works thereof in any medium, with or without\n modifications, and in Source or Object form, provided that You\n meet the following conditions:\n\n (a) You must give any other recipients of the Work or\n Derivative Works a copy of this License; and\n\n (b) You must cause any modified files to carry prominent notices\n stating that You changed the files; and\n\n (c) You must retain, in the Source form of any Derivative Works\n that You distribute, all copyright, patent, trademark, and\n attribution notices from the Source form of the Work,\n excluding those notices that do not pertain to any part of\n the Derivative Works; and\n\n (d) If the Work includes a \"NOTICE\" text file as part of its\n distribution, then any Derivative Works that You distribute must\n include a readable copy of the attribution notices contained\n within such NOTICE file, excluding those notices that do not\n pertain to any part of the Derivative Works, in at least one\n of the following places: within a NOTICE text file distributed\n as part of the Derivative Works; within the Source form or\n documentation, if provided along with the Derivative Works; or,\n within a display generated by the Derivative Works, if and\n wherever such third-party notices normally appear. The contents\n of the NOTICE file are for informational purposes only and\n do not modify the License. You may add Your own attribution\n notices within Derivative Works that You distribute, alongside\n or as an addendum to the NOTICE text from the Work, provided\n that such additional attribution notices cannot be construed\n as modifying the License.\n\n You may add Your own copyright statement to Your modifications and\n may provide additional or different license terms and conditions\n for use, reproduction, or distribution of Your modifications, or\n for any such Derivative Works as a whole, provided Your use,\n reproduction, and distribution of the Work otherwise complies with\n the conditions stated in this License.\n\n 5. Submission of Contributions. Unless You explicitly state otherwise,\n any Contribution intentionally submitted for inclusion in the Work\n by You to the Licensor shall be under the terms and conditions of\n this License, without any additional terms or conditions.\n Notwithstanding the above, nothing herein shall supersede or modify\n the terms of any separate license agreement you may have executed\n with Licensor regarding such Contributions.\n\n 6. Trademarks. This License does not grant permission to use the trade\n names, trademarks, service marks, or product names of the Licensor,\n except as required for reasonable and customary use in describing the\n origin of the Work and reproducing the content of the NOTICE file.\n\n 7. Disclaimer of Warranty. Unless required by applicable law or\n agreed to in writing, Licensor provides the Work (and each\n Contributor provides its Contributions) on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n implied, including, without limitation, any warranties or conditions\n of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n PARTICULAR PURPOSE. You are solely responsible for determining the\n appropriateness of using or redistributing the Work and assume any\n risks associated with Your exercise of permissions under this License.\n\n 8. Limitation of Liability. In no event and under no legal theory,\n whether in tort (including negligence), contract, or otherwise,\n unless required by applicable law (such as deliberate and grossly\n negligent acts) or agreed to in writing, shall any Contributor be\n liable to You for damages, including any direct, indirect, special,\n incidental, or consequential damages of any character arising as a\n result of this License or out of the use or inability to use the\n Work (including but not limited to damages for loss of goodwill,\n work stoppage, computer failure or malfunction, or any and all\n other commercial damages or losses), even if such Contributor\n has been advised of the possibility of such damages.\n\n 9. Accepting Warranty or Additional Liability. While redistributing\n the Work or Derivative Works thereof, You may choose to offer,\n and charge a fee for, acceptance of support, warranty, indemnity,\n or other liability obligations and/or rights consistent with this\n License. However, in accepting such obligations, You may act only\n on Your own behalf and on Your sole responsibility, not on behalf\n of any other Contributor, and only if You agree to indemnify,\n defend, and hold each Contributor harmless for any liability\n incurred by, or claims asserted against, such Contributor by reason\n of your accepting any such warranty or additional liability.\n\n END OF TERMS AND CONDITIONS\n\n APPENDIX: How to apply the Apache License to your work.\n\n To apply the Apache License to your work, attach the following\n boilerplate notice, with the fields enclosed by brackets \"{}\"\n replaced with your own identifying information. (Don't include\n the brackets!) The text should be enclosed in the appropriate\n comment syntax for the file format. We also recommend that a\n file or class name and description of purpose be included on the\n same \"printed page\" as the copyright notice for easier\n identification within third-party archives.\n\n Copyright {yyyy} {name of copyright owner}\n\n Licensed under the Apache License, Version 2.0 (the \"License\");\n you may not use this file except in compliance with the License.\n You may obtain a copy of the License at\n\n http://www.apache.org/licenses/LICENSE-2.0\n\n Unless required by applicable law or agreed to in writing, software\n distributed under the License is distributed on an \"AS IS\" BASIS,\n WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n See the License for the specific language governing permissions and\n limitations under the License.\n*/\n\nSVD.svd = function (A) {\n this.U = null;\n this.V = null;\n this.s = null;\n this.m = 0;\n this.n = 0;\n this.m = A.length;\n this.n = A[0].length;\n var nu = Math.min(this.m, this.n);\n this.s = function (s) {\n var a = [];\n while (s-- > 0) {\n a.push(0);\n }return a;\n }(Math.min(this.m + 1, this.n));\n this.U = function (dims) {\n var allocate = function allocate(dims) {\n if (dims.length == 0) {\n return 0;\n } else {\n var array = [];\n for (var i = 0; i < dims[0]; i++) {\n array.push(allocate(dims.slice(1)));\n }\n return array;\n }\n };\n return allocate(dims);\n }([this.m, nu]);\n this.V = function (dims) {\n var allocate = function allocate(dims) {\n if (dims.length == 0) {\n return 0;\n } else {\n var array = [];\n for (var i = 0; i < dims[0]; i++) {\n array.push(allocate(dims.slice(1)));\n }\n return array;\n }\n };\n return allocate(dims);\n }([this.n, this.n]);\n var e = function (s) {\n var a = [];\n while (s-- > 0) {\n a.push(0);\n }return a;\n }(this.n);\n var work = function (s) {\n var a = [];\n while (s-- > 0) {\n a.push(0);\n }return a;\n }(this.m);\n var wantu = true;\n var wantv = true;\n var nct = Math.min(this.m - 1, this.n);\n var nrt = Math.max(0, Math.min(this.n - 2, this.m));\n for (var k = 0; k < Math.max(nct, nrt); k++) {\n if (k < nct) {\n this.s[k] = 0;\n for (var i = k; i < this.m; i++) {\n this.s[k] = SVD.hypot(this.s[k], A[i][k]);\n }\n ;\n if (this.s[k] !== 0.0) {\n if (A[k][k] < 0.0) {\n this.s[k] = -this.s[k];\n }\n for (var _i = k; _i < this.m; _i++) {\n A[_i][k] /= this.s[k];\n }\n ;\n A[k][k] += 1.0;\n }\n this.s[k] = -this.s[k];\n }\n for (var j = k + 1; j < this.n; j++) {\n if (function (lhs, rhs) {\n return lhs && rhs;\n }(k < nct, this.s[k] !== 0.0)) {\n var t = 0;\n for (var _i2 = k; _i2 < this.m; _i2++) {\n t += A[_i2][k] * A[_i2][j];\n }\n ;\n t = -t / A[k][k];\n for (var _i3 = k; _i3 < this.m; _i3++) {\n A[_i3][j] += t * A[_i3][k];\n }\n ;\n }\n e[j] = A[k][j];\n }\n ;\n if (function (lhs, rhs) {\n return lhs && rhs;\n }(wantu, k < nct)) {\n for (var _i4 = k; _i4 < this.m; _i4++) {\n this.U[_i4][k] = A[_i4][k];\n }\n ;\n }\n if (k < nrt) {\n e[k] = 0;\n for (var _i5 = k + 1; _i5 < this.n; _i5++) {\n e[k] = SVD.hypot(e[k], e[_i5]);\n }\n ;\n if (e[k] !== 0.0) {\n if (e[k + 1] < 0.0) {\n e[k] = -e[k];\n }\n for (var _i6 = k + 1; _i6 < this.n; _i6++) {\n e[_i6] /= e[k];\n }\n ;\n e[k + 1] += 1.0;\n }\n e[k] = -e[k];\n if (function (lhs, rhs) {\n return lhs && rhs;\n }(k + 1 < this.m, e[k] !== 0.0)) {\n for (var _i7 = k + 1; _i7 < this.m; _i7++) {\n work[_i7] = 0.0;\n }\n ;\n for (var _j = k + 1; _j < this.n; _j++) {\n for (var _i8 = k + 1; _i8 < this.m; _i8++) {\n work[_i8] += e[_j] * A[_i8][_j];\n }\n ;\n }\n ;\n for (var _j2 = k + 1; _j2 < this.n; _j2++) {\n var _t = -e[_j2] / e[k + 1];\n for (var _i9 = k + 1; _i9 < this.m; _i9++) {\n A[_i9][_j2] += _t * work[_i9];\n }\n ;\n }\n ;\n }\n if (wantv) {\n for (var _i10 = k + 1; _i10 < this.n; _i10++) {\n this.V[_i10][k] = e[_i10];\n };\n }\n }\n };\n var p = Math.min(this.n, this.m + 1);\n if (nct < this.n) {\n this.s[nct] = A[nct][nct];\n }\n if (this.m < p) {\n this.s[p - 1] = 0.0;\n }\n if (nrt + 1 < p) {\n e[nrt] = A[nrt][p - 1];\n }\n e[p - 1] = 0.0;\n if (wantu) {\n for (var _j3 = nct; _j3 < nu; _j3++) {\n for (var _i11 = 0; _i11 < this.m; _i11++) {\n this.U[_i11][_j3] = 0.0;\n }\n ;\n this.U[_j3][_j3] = 1.0;\n };\n for (var _k = nct - 1; _k >= 0; _k--) {\n if (this.s[_k] !== 0.0) {\n for (var _j4 = _k + 1; _j4 < nu; _j4++) {\n var _t2 = 0;\n for (var _i12 = _k; _i12 < this.m; _i12++) {\n _t2 += this.U[_i12][_k] * this.U[_i12][_j4];\n };\n _t2 = -_t2 / this.U[_k][_k];\n for (var _i13 = _k; _i13 < this.m; _i13++) {\n this.U[_i13][_j4] += _t2 * this.U[_i13][_k];\n };\n };\n for (var _i14 = _k; _i14 < this.m; _i14++) {\n this.U[_i14][_k] = -this.U[_i14][_k];\n };\n this.U[_k][_k] = 1.0 + this.U[_k][_k];\n for (var _i15 = 0; _i15 < _k - 1; _i15++) {\n this.U[_i15][_k] = 0.0;\n };\n } else {\n for (var _i16 = 0; _i16 < this.m; _i16++) {\n this.U[_i16][_k] = 0.0;\n };\n this.U[_k][_k] = 1.0;\n }\n };\n }\n if (wantv) {\n for (var _k2 = this.n - 1; _k2 >= 0; _k2--) {\n if (function (lhs, rhs) {\n return lhs && rhs;\n }(_k2 < nrt, e[_k2] !== 0.0)) {\n for (var _j5 = _k2 + 1; _j5 < nu; _j5++) {\n var _t3 = 0;\n for (var _i17 = _k2 + 1; _i17 < this.n; _i17++) {\n _t3 += this.V[_i17][_k2] * this.V[_i17][_j5];\n };\n _t3 = -_t3 / this.V[_k2 + 1][_k2];\n for (var _i18 = _k2 + 1; _i18 < this.n; _i18++) {\n this.V[_i18][_j5] += _t3 * this.V[_i18][_k2];\n };\n };\n }\n for (var _i19 = 0; _i19 < this.n; _i19++) {\n this.V[_i19][_k2] = 0.0;\n };\n this.V[_k2][_k2] = 1.0;\n };\n }\n var pp = p - 1;\n var iter = 0;\n var eps = Math.pow(2.0, -52.0);\n var tiny = Math.pow(2.0, -966.0);\n while (p > 0) {\n var _k3 = void 0;\n var kase = void 0;\n for (_k3 = p - 2; _k3 >= -1; _k3--) {\n if (_k3 === -1) {\n break;\n }\n if (Math.abs(e[_k3]) <= tiny + eps * (Math.abs(this.s[_k3]) + Math.abs(this.s[_k3 + 1]))) {\n e[_k3] = 0.0;\n break;\n }\n };\n if (_k3 === p - 2) {\n kase = 4;\n } else {\n var ks = void 0;\n for (ks = p - 1; ks >= _k3; ks--) {\n if (ks === _k3) {\n break;\n }\n var _t4 = (ks !== p ? Math.abs(e[ks]) : 0.0) + (ks !== _k3 + 1 ? Math.abs(e[ks - 1]) : 0.0);\n if (Math.abs(this.s[ks]) <= tiny + eps * _t4) {\n this.s[ks] = 0.0;\n break;\n }\n };\n if (ks === _k3) {\n kase = 3;\n } else if (ks === p - 1) {\n kase = 1;\n } else {\n kase = 2;\n _k3 = ks;\n }\n }\n _k3++;\n switch (kase) {\n case 1:\n {\n var f = e[p - 2];\n e[p - 2] = 0.0;\n for (var _j6 = p - 2; _j6 >= _k3; _j6--) {\n var _t5 = SVD.hypot(this.s[_j6], f);\n var cs = this.s[_j6] / _t5;\n var sn = f / _t5;\n this.s[_j6] = _t5;\n if (_j6 !== _k3) {\n f = -sn * e[_j6 - 1];\n e[_j6 - 1] = cs * e[_j6 - 1];\n }\n if (wantv) {\n for (var _i20 = 0; _i20 < this.n; _i20++) {\n _t5 = cs * this.V[_i20][_j6] + sn * this.V[_i20][p - 1];\n this.V[_i20][p - 1] = -sn * this.V[_i20][_j6] + cs * this.V[_i20][p - 1];\n this.V[_i20][_j6] = _t5;\n };\n }\n };\n };\n break;\n case 2:\n {\n var _f = e[_k3 - 1];\n e[_k3 - 1] = 0.0;\n for (var _j7 = _k3; _j7 < p; _j7++) {\n var _t6 = SVD.hypot(this.s[_j7], _f);\n var _cs = this.s[_j7] / _t6;\n var _sn = _f / _t6;\n this.s[_j7] = _t6;\n _f = -_sn * e[_j7];\n e[_j7] = _cs * e[_j7];\n if (wantu) {\n for (var _i21 = 0; _i21 < this.m; _i21++) {\n _t6 = _cs * this.U[_i21][_j7] + _sn * this.U[_i21][_k3 - 1];\n this.U[_i21][_k3 - 1] = -_sn * this.U[_i21][_j7] + _cs * this.U[_i21][_k3 - 1];\n this.U[_i21][_j7] = _t6;\n };\n }\n };\n };\n break;\n case 3:\n {\n var scale = Math.max(Math.max(Math.max(Math.max(Math.abs(this.s[p - 1]), Math.abs(this.s[p - 2])), Math.abs(e[p - 2])), Math.abs(this.s[_k3])), Math.abs(e[_k3]));\n var sp = this.s[p - 1] / scale;\n var spm1 = this.s[p - 2] / scale;\n var epm1 = e[p - 2] / scale;\n var sk = this.s[_k3] / scale;\n var ek = e[_k3] / scale;\n var b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) / 2.0;\n var c = sp * epm1 * (sp * epm1);\n var shift = 0.0;\n if (function (lhs, rhs) {\n return lhs || rhs;\n }(b !== 0.0, c !== 0.0)) {\n shift = Math.sqrt(b * b + c);\n if (b < 0.0) {\n shift = -shift;\n }\n shift = c / (b + shift);\n }\n var _f2 = (sk + sp) * (sk - sp) + shift;\n var g = sk * ek;\n for (var _j8 = _k3; _j8 < p - 1; _j8++) {\n var _t7 = SVD.hypot(_f2, g);\n var _cs2 = _f2 / _t7;\n var _sn2 = g / _t7;\n if (_j8 !== _k3) {\n e[_j8 - 1] = _t7;\n }\n _f2 = _cs2 * this.s[_j8] + _sn2 * e[_j8];\n e[_j8] = _cs2 * e[_j8] - _sn2 * this.s[_j8];\n g = _sn2 * this.s[_j8 + 1];\n this.s[_j8 + 1] = _cs2 * this.s[_j8 + 1];\n if (wantv) {\n for (var _i22 = 0; _i22 < this.n; _i22++) {\n _t7 = _cs2 * this.V[_i22][_j8] + _sn2 * this.V[_i22][_j8 + 1];\n this.V[_i22][_j8 + 1] = -_sn2 * this.V[_i22][_j8] + _cs2 * this.V[_i22][_j8 + 1];\n this.V[_i22][_j8] = _t7;\n };\n }\n _t7 = SVD.hypot(_f2, g);\n _cs2 = _f2 / _t7;\n _sn2 = g / _t7;\n this.s[_j8] = _t7;\n _f2 = _cs2 * e[_j8] + _sn2 * this.s[_j8 + 1];\n this.s[_j8 + 1] = -_sn2 * e[_j8] + _cs2 * this.s[_j8 + 1];\n g = _sn2 * e[_j8 + 1];\n e[_j8 + 1] = _cs2 * e[_j8 + 1];\n if (wantu && _j8 < this.m - 1) {\n for (var _i23 = 0; _i23 < this.m; _i23++) {\n _t7 = _cs2 * this.U[_i23][_j8] + _sn2 * this.U[_i23][_j8 + 1];\n this.U[_i23][_j8 + 1] = -_sn2 * this.U[_i23][_j8] + _cs2 * this.U[_i23][_j8 + 1];\n this.U[_i23][_j8] = _t7;\n };\n }\n };\n e[p - 2] = _f2;\n iter = iter + 1;\n };\n break;\n case 4:\n {\n if (this.s[_k3] <= 0.0) {\n this.s[_k3] = this.s[_k3] < 0.0 ? -this.s[_k3] : 0.0;\n if (wantv) {\n for (var _i24 = 0; _i24 <= pp; _i24++) {\n this.V[_i24][_k3] = -this.V[_i24][_k3];\n };\n }\n }\n while (_k3 < pp) {\n if (this.s[_k3] >= this.s[_k3 + 1]) {\n break;\n }\n var _t8 = this.s[_k3];\n this.s[_k3] = this.s[_k3 + 1];\n this.s[_k3 + 1] = _t8;\n if (wantv && _k3 < this.n - 1) {\n for (var _i25 = 0; _i25 < this.n; _i25++) {\n _t8 = this.V[_i25][_k3 + 1];\n this.V[_i25][_k3 + 1] = this.V[_i25][_k3];\n this.V[_i25][_k3] = _t8;\n };\n }\n if (wantu && _k3 < this.m - 1) {\n for (var _i26 = 0; _i26 < this.m; _i26++) {\n _t8 = this.U[_i26][_k3 + 1];\n this.U[_i26][_k3 + 1] = this.U[_i26][_k3];\n this.U[_i26][_k3] = _t8;\n };\n }\n _k3++;\n };\n iter = 0;\n p--;\n };\n break;\n }\n };\n var result = { U: this.U, V: this.V, S: this.s };\n return result;\n};\n\n// sqrt(a^2 + b^2) without under/overflow.\nSVD.hypot = function (a, b) {\n var r = void 0;\n if (Math.abs(a) > Math.abs(b)) {\n r = b / a;\n r = Math.abs(a) * Math.sqrt(1 + r * r);\n } else if (b != 0) {\n r = a / b;\n r = Math.abs(b) * Math.sqrt(1 + r * r);\n } else {\n r = 0.0;\n }\n return r;\n};\n\nmodule.exports = SVD;\n\n/***/ }),\n/* 27 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n * Needleman-Wunsch algorithm is an procedure to compute the optimal global alignment of two string\n * sequences by S.B.Needleman and C.D.Wunsch (1970).\n *\n * Aside from the inputs, you can assign the scores for,\n * - Match: The two characters at the current index are same.\n * - Mismatch: The two characters at the current index are different.\n * - Insertion/Deletion(gaps): The best alignment involves one letter aligning to a gap in the other string.\n */\n\nvar NeedlemanWunsch = function () {\n function NeedlemanWunsch(sequence1, sequence2) {\n var match_score = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var mismatch_penalty = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1;\n var gap_penalty = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : -1;\n\n _classCallCheck(this, NeedlemanWunsch);\n\n this.sequence1 = sequence1;\n this.sequence2 = sequence2;\n this.match_score = match_score;\n this.mismatch_penalty = mismatch_penalty;\n this.gap_penalty = gap_penalty;\n\n // Just the remove redundancy\n this.iMax = sequence1.length + 1;\n this.jMax = sequence2.length + 1;\n\n // Grid matrix of scores\n this.grid = new Array(this.iMax);\n for (var i = 0; i < this.iMax; i++) {\n this.grid[i] = new Array(this.jMax);\n\n for (var j = 0; j < this.jMax; j++) {\n this.grid[i][j] = 0;\n }\n }\n\n // Traceback matrix (2D array, each cell is an array of boolean values for [`Diag`, `Up`, `Left`] positions)\n this.tracebackGrid = new Array(this.iMax);\n for (var _i = 0; _i < this.iMax; _i++) {\n this.tracebackGrid[_i] = new Array(this.jMax);\n\n for (var _j = 0; _j < this.jMax; _j++) {\n this.tracebackGrid[_i][_j] = [null, null, null];\n }\n }\n\n // The aligned sequences (return multiple possibilities)\n this.alignments = [];\n\n // Final alignment score\n this.score = -1;\n\n // Calculate scores and tracebacks\n this.computeGrids();\n }\n\n _createClass(NeedlemanWunsch, [{\n key: \"getScore\",\n value: function getScore() {\n return this.score;\n }\n }, {\n key: \"getAlignments\",\n value: function getAlignments() {\n return this.alignments;\n }\n\n // Main dynamic programming procedure\n\n }, {\n key: \"computeGrids\",\n value: function computeGrids() {\n // Fill in the first row\n for (var j = 1; j < this.jMax; j++) {\n this.grid[0][j] = this.grid[0][j - 1] + this.gap_penalty;\n this.tracebackGrid[0][j] = [false, false, true];\n }\n\n // Fill in the first column\n for (var i = 1; i < this.iMax; i++) {\n this.grid[i][0] = this.grid[i - 1][0] + this.gap_penalty;\n this.tracebackGrid[i][0] = [false, true, false];\n }\n\n // Fill the rest of the grid\n for (var _i2 = 1; _i2 < this.iMax; _i2++) {\n for (var _j2 = 1; _j2 < this.jMax; _j2++) {\n // Find the max score(s) among [`Diag`, `Up`, `Left`]\n var diag = void 0;\n if (this.sequence1[_i2 - 1] === this.sequence2[_j2 - 1]) diag = this.grid[_i2 - 1][_j2 - 1] + this.match_score;else diag = this.grid[_i2 - 1][_j2 - 1] + this.mismatch_penalty;\n\n var up = this.grid[_i2 - 1][_j2] + this.gap_penalty;\n var left = this.grid[_i2][_j2 - 1] + this.gap_penalty;\n\n // If there exists multiple max values, capture them for multiple paths\n var maxOf = [diag, up, left];\n var indices = this.arrayAllMaxIndexes(maxOf);\n\n // Update Grids\n this.grid[_i2][_j2] = maxOf[indices[0]];\n this.tracebackGrid[_i2][_j2] = [indices.includes(0), indices.includes(1), indices.includes(2)];\n }\n }\n\n // Update alignment score\n this.score = this.grid[this.iMax - 1][this.jMax - 1];\n }\n\n // Gets all possible valid sequence combinations\n\n }, {\n key: \"alignmentTraceback\",\n value: function alignmentTraceback() {\n var inProcessAlignments = [];\n\n inProcessAlignments.push({ pos: [this.sequence1.length, this.sequence2.length],\n seq1: \"\",\n seq2: \"\"\n });\n\n while (inProcessAlignments[0]) {\n var current = inProcessAlignments[0];\n var directions = this.tracebackGrid[current.pos[0]][current.pos[1]];\n\n if (directions[0]) {\n inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1] - 1],\n seq1: this.sequence1[current.pos[0] - 1] + current.seq1,\n seq2: this.sequence2[current.pos[1] - 1] + current.seq2\n });\n }\n if (directions[1]) {\n inProcessAlignments.push({ pos: [current.pos[0] - 1, current.pos[1]],\n seq1: this.sequence1[current.pos[0] - 1] + current.seq1,\n seq2: '-' + current.seq2\n });\n }\n if (directions[2]) {\n inProcessAlignments.push({ pos: [current.pos[0], current.pos[1] - 1],\n seq1: '-' + current.seq1,\n seq2: this.sequence2[current.pos[1] - 1] + current.seq2\n });\n }\n\n if (current.pos[0] === 0 && current.pos[1] === 0) this.alignments.push({ sequence1: current.seq1,\n sequence2: current.seq2\n });\n\n inProcessAlignments.shift();\n }\n\n return this.alignments;\n }\n\n // Helper Functions\n\n }, {\n key: \"getAllIndexes\",\n value: function getAllIndexes(arr, val) {\n var indexes = [],\n i = -1;\n while ((i = arr.indexOf(val, i + 1)) !== -1) {\n indexes.push(i);\n }\n return indexes;\n }\n }, {\n key: \"arrayAllMaxIndexes\",\n value: function arrayAllMaxIndexes(array) {\n return this.getAllIndexes(array, Math.max.apply(null, array));\n }\n }]);\n\n return NeedlemanWunsch;\n}();\n\nmodule.exports = NeedlemanWunsch;\n\n/***/ }),\n/* 28 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nvar layoutBase = function layoutBase() {\n return;\n};\n\nlayoutBase.FDLayout = __webpack_require__(18);\nlayoutBase.FDLayoutConstants = __webpack_require__(4);\nlayoutBase.FDLayoutEdge = __webpack_require__(19);\nlayoutBase.FDLayoutNode = __webpack_require__(20);\nlayoutBase.DimensionD = __webpack_require__(21);\nlayoutBase.HashMap = __webpack_require__(22);\nlayoutBase.HashSet = __webpack_require__(23);\nlayoutBase.IGeometry = __webpack_require__(8);\nlayoutBase.IMath = __webpack_require__(9);\nlayoutBase.Integer = __webpack_require__(10);\nlayoutBase.Point = __webpack_require__(12);\nlayoutBase.PointD = __webpack_require__(5);\nlayoutBase.RandomSeed = __webpack_require__(16);\nlayoutBase.RectangleD = __webpack_require__(13);\nlayoutBase.Transform = __webpack_require__(17);\nlayoutBase.UniqueIDGeneretor = __webpack_require__(14);\nlayoutBase.Quicksort = __webpack_require__(25);\nlayoutBase.LinkedList = __webpack_require__(11);\nlayoutBase.LGraphObject = __webpack_require__(2);\nlayoutBase.LGraph = __webpack_require__(6);\nlayoutBase.LEdge = __webpack_require__(1);\nlayoutBase.LGraphManager = __webpack_require__(7);\nlayoutBase.LNode = __webpack_require__(3);\nlayoutBase.Layout = __webpack_require__(15);\nlayoutBase.LayoutConstants = __webpack_require__(0);\nlayoutBase.NeedlemanWunsch = __webpack_require__(27);\nlayoutBase.Matrix = __webpack_require__(24);\nlayoutBase.SVD = __webpack_require__(26);\n\nmodule.exports = layoutBase;\n\n/***/ }),\n/* 29 */\n/***/ (function(module, exports, __webpack_require__) {\n\n\"use strict\";\n\n\nfunction Emitter() {\n this.listeners = [];\n}\n\nvar p = Emitter.prototype;\n\np.addListener = function (event, callback) {\n this.listeners.push({\n event: event,\n callback: callback\n });\n};\n\np.removeListener = function (event, callback) {\n for (var i = this.listeners.length; i >= 0; i--) {\n var l = this.listeners[i];\n\n if (l.event === event && l.callback === callback) {\n this.listeners.splice(i, 1);\n }\n }\n};\n\np.emit = function (event, data) {\n for (var i = 0; i < this.listeners.length; i++) {\n var l = this.listeners[i];\n\n if (event === l.event) {\n l.callback(data);\n }\n }\n};\n\nmodule.exports = Emitter;\n\n/***/ })\n/******/ ]);\n});", "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"layout-base\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"layout-base\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"coseBase\"] = factory(require(\"layout-base\"));\n\telse\n\t\troot[\"coseBase\"] = factory(root[\"layoutBase\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE__551__) {\nreturn /******/ (() => { // webpackBootstrap\n/******/ \t\"use strict\";\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 45:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar coseBase = {};\n\ncoseBase.layoutBase = __webpack_require__(551);\ncoseBase.CoSEConstants = __webpack_require__(806);\ncoseBase.CoSEEdge = __webpack_require__(767);\ncoseBase.CoSEGraph = __webpack_require__(880);\ncoseBase.CoSEGraphManager = __webpack_require__(578);\ncoseBase.CoSELayout = __webpack_require__(765);\ncoseBase.CoSENode = __webpack_require__(991);\ncoseBase.ConstraintHandler = __webpack_require__(902);\n\nmodule.exports = coseBase;\n\n/***/ }),\n\n/***/ 806:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar FDLayoutConstants = __webpack_require__(551).FDLayoutConstants;\n\nfunction CoSEConstants() {}\n\n//CoSEConstants inherits static props in FDLayoutConstants\nfor (var prop in FDLayoutConstants) {\n CoSEConstants[prop] = FDLayoutConstants[prop];\n}\n\nCoSEConstants.DEFAULT_USE_MULTI_LEVEL_SCALING = false;\nCoSEConstants.DEFAULT_RADIAL_SEPARATION = FDLayoutConstants.DEFAULT_EDGE_LENGTH;\nCoSEConstants.DEFAULT_COMPONENT_SEPERATION = 60;\nCoSEConstants.TILE = true;\nCoSEConstants.TILING_PADDING_VERTICAL = 10;\nCoSEConstants.TILING_PADDING_HORIZONTAL = 10;\nCoSEConstants.TRANSFORM_ON_CONSTRAINT_HANDLING = true;\nCoSEConstants.ENFORCE_CONSTRAINTS = true;\nCoSEConstants.APPLY_LAYOUT = true;\nCoSEConstants.RELAX_MOVEMENT_ON_CONSTRAINTS = true;\nCoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = true; // this should be set to false if there will be a constraint\n// This constant is for differentiating whether actual layout algorithm that uses cose-base wants to apply only incremental layout or \n// an incremental layout on top of a randomized layout. If it is only incremental layout, then this constant should be true.\nCoSEConstants.PURE_INCREMENTAL = CoSEConstants.DEFAULT_INCREMENTAL;\n\nmodule.exports = CoSEConstants;\n\n/***/ }),\n\n/***/ 767:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar FDLayoutEdge = __webpack_require__(551).FDLayoutEdge;\n\nfunction CoSEEdge(source, target, vEdge) {\n FDLayoutEdge.call(this, source, target, vEdge);\n}\n\nCoSEEdge.prototype = Object.create(FDLayoutEdge.prototype);\nfor (var prop in FDLayoutEdge) {\n CoSEEdge[prop] = FDLayoutEdge[prop];\n}\n\nmodule.exports = CoSEEdge;\n\n/***/ }),\n\n/***/ 880:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar LGraph = __webpack_require__(551).LGraph;\n\nfunction CoSEGraph(parent, graphMgr, vGraph) {\n LGraph.call(this, parent, graphMgr, vGraph);\n}\n\nCoSEGraph.prototype = Object.create(LGraph.prototype);\nfor (var prop in LGraph) {\n CoSEGraph[prop] = LGraph[prop];\n}\n\nmodule.exports = CoSEGraph;\n\n/***/ }),\n\n/***/ 578:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar LGraphManager = __webpack_require__(551).LGraphManager;\n\nfunction CoSEGraphManager(layout) {\n LGraphManager.call(this, layout);\n}\n\nCoSEGraphManager.prototype = Object.create(LGraphManager.prototype);\nfor (var prop in LGraphManager) {\n CoSEGraphManager[prop] = LGraphManager[prop];\n}\n\nmodule.exports = CoSEGraphManager;\n\n/***/ }),\n\n/***/ 765:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar FDLayout = __webpack_require__(551).FDLayout;\nvar CoSEGraphManager = __webpack_require__(578);\nvar CoSEGraph = __webpack_require__(880);\nvar CoSENode = __webpack_require__(991);\nvar CoSEEdge = __webpack_require__(767);\nvar CoSEConstants = __webpack_require__(806);\nvar ConstraintHandler = __webpack_require__(902);\nvar FDLayoutConstants = __webpack_require__(551).FDLayoutConstants;\nvar LayoutConstants = __webpack_require__(551).LayoutConstants;\nvar Point = __webpack_require__(551).Point;\nvar PointD = __webpack_require__(551).PointD;\nvar DimensionD = __webpack_require__(551).DimensionD;\nvar Layout = __webpack_require__(551).Layout;\nvar Integer = __webpack_require__(551).Integer;\nvar IGeometry = __webpack_require__(551).IGeometry;\nvar LGraph = __webpack_require__(551).LGraph;\nvar Transform = __webpack_require__(551).Transform;\nvar LinkedList = __webpack_require__(551).LinkedList;\n\nfunction CoSELayout() {\n FDLayout.call(this);\n\n this.toBeTiled = {}; // Memorize if a node is to be tiled or is tiled\n this.constraints = {}; // keep layout constraints\n}\n\nCoSELayout.prototype = Object.create(FDLayout.prototype);\n\nfor (var prop in FDLayout) {\n CoSELayout[prop] = FDLayout[prop];\n}\n\nCoSELayout.prototype.newGraphManager = function () {\n var gm = new CoSEGraphManager(this);\n this.graphManager = gm;\n return gm;\n};\n\nCoSELayout.prototype.newGraph = function (vGraph) {\n return new CoSEGraph(null, this.graphManager, vGraph);\n};\n\nCoSELayout.prototype.newNode = function (vNode) {\n return new CoSENode(this.graphManager, vNode);\n};\n\nCoSELayout.prototype.newEdge = function (vEdge) {\n return new CoSEEdge(null, null, vEdge);\n};\n\nCoSELayout.prototype.initParameters = function () {\n FDLayout.prototype.initParameters.call(this, arguments);\n if (!this.isSubLayout) {\n if (CoSEConstants.DEFAULT_EDGE_LENGTH < 10) {\n this.idealEdgeLength = 10;\n } else {\n this.idealEdgeLength = CoSEConstants.DEFAULT_EDGE_LENGTH;\n }\n\n this.useSmartIdealEdgeLengthCalculation = CoSEConstants.DEFAULT_USE_SMART_IDEAL_EDGE_LENGTH_CALCULATION;\n this.gravityConstant = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH;\n this.compoundGravityConstant = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH;\n this.gravityRangeFactor = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR;\n this.compoundGravityRangeFactor = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR;\n\n // variables for tree reduction support\n this.prunedNodesAll = [];\n this.growTreeIterations = 0;\n this.afterGrowthIterations = 0;\n this.isTreeGrowing = false;\n this.isGrowthFinished = false;\n }\n};\n\n// This method is used to set CoSE related parameters used by spring embedder.\nCoSELayout.prototype.initSpringEmbedder = function () {\n FDLayout.prototype.initSpringEmbedder.call(this);\n\n // variables for cooling\n this.coolingCycle = 0;\n this.maxCoolingCycle = this.maxIterations / FDLayoutConstants.CONVERGENCE_CHECK_PERIOD;\n this.finalTemperature = 0.04;\n this.coolingAdjuster = 1;\n};\n\nCoSELayout.prototype.layout = function () {\n var createBendsAsNeeded = LayoutConstants.DEFAULT_CREATE_BENDS_AS_NEEDED;\n if (createBendsAsNeeded) {\n this.createBendpoints();\n this.graphManager.resetAllEdges();\n }\n\n this.level = 0;\n return this.classicLayout();\n};\n\nCoSELayout.prototype.classicLayout = function () {\n this.nodesWithGravity = this.calculateNodesToApplyGravitationTo();\n this.graphManager.setAllNodesToApplyGravitation(this.nodesWithGravity);\n this.calcNoOfChildrenForAllNodes();\n this.graphManager.calcLowestCommonAncestors();\n this.graphManager.calcInclusionTreeDepths();\n this.graphManager.getRoot().calcEstimatedSize();\n this.calcIdealEdgeLengths();\n\n if (!this.incremental) {\n var forest = this.getFlatForest();\n\n // The graph associated with this layout is flat and a forest\n if (forest.length > 0) {\n this.positionNodesRadially(forest);\n }\n // The graph associated with this layout is not flat or a forest\n else {\n // Reduce the trees when incremental mode is not enabled and graph is not a forest \n this.reduceTrees();\n // Update nodes that gravity will be applied\n this.graphManager.resetAllNodesToApplyGravitation();\n var allNodes = new Set(this.getAllNodes());\n var intersection = this.nodesWithGravity.filter(function (x) {\n return allNodes.has(x);\n });\n this.graphManager.setAllNodesToApplyGravitation(intersection);\n\n this.positionNodesRandomly();\n }\n } else {\n if (CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL) {\n // Reduce the trees in incremental mode if only this constant is set to true \n this.reduceTrees();\n // Update nodes that gravity will be applied\n this.graphManager.resetAllNodesToApplyGravitation();\n var allNodes = new Set(this.getAllNodes());\n var intersection = this.nodesWithGravity.filter(function (x) {\n return allNodes.has(x);\n });\n this.graphManager.setAllNodesToApplyGravitation(intersection);\n }\n }\n\n if (Object.keys(this.constraints).length > 0) {\n ConstraintHandler.handleConstraints(this);\n this.initConstraintVariables();\n }\n\n this.initSpringEmbedder();\n if (CoSEConstants.APPLY_LAYOUT) {\n this.runSpringEmbedder();\n }\n\n return true;\n};\n\nCoSELayout.prototype.tick = function () {\n this.totalIterations++;\n\n if (this.totalIterations === this.maxIterations && !this.isTreeGrowing && !this.isGrowthFinished) {\n if (this.prunedNodesAll.length > 0) {\n this.isTreeGrowing = true;\n } else {\n return true;\n }\n }\n\n if (this.totalIterations % FDLayoutConstants.CONVERGENCE_CHECK_PERIOD == 0 && !this.isTreeGrowing && !this.isGrowthFinished) {\n if (this.isConverged()) {\n if (this.prunedNodesAll.length > 0) {\n this.isTreeGrowing = true;\n } else {\n return true;\n }\n }\n\n this.coolingCycle++;\n\n if (this.layoutQuality == 0) {\n // quality - \"draft\"\n this.coolingAdjuster = this.coolingCycle;\n } else if (this.layoutQuality == 1) {\n // quality - \"default\"\n this.coolingAdjuster = this.coolingCycle / 3;\n }\n\n // cooling schedule is based on http://www.btluke.com/simanf1.html -> cooling schedule 3\n this.coolingFactor = Math.max(this.initialCoolingFactor - Math.pow(this.coolingCycle, Math.log(100 * (this.initialCoolingFactor - this.finalTemperature)) / Math.log(this.maxCoolingCycle)) / 100 * this.coolingAdjuster, this.finalTemperature);\n this.animationPeriod = Math.ceil(this.initialAnimationPeriod * Math.sqrt(this.coolingFactor));\n }\n // Operations while tree is growing again \n if (this.isTreeGrowing) {\n if (this.growTreeIterations % 10 == 0) {\n if (this.prunedNodesAll.length > 0) {\n this.graphManager.updateBounds();\n this.updateGrid();\n this.growTree(this.prunedNodesAll);\n // Update nodes that gravity will be applied\n this.graphManager.resetAllNodesToApplyGravitation();\n var allNodes = new Set(this.getAllNodes());\n var intersection = this.nodesWithGravity.filter(function (x) {\n return allNodes.has(x);\n });\n this.graphManager.setAllNodesToApplyGravitation(intersection);\n\n this.graphManager.updateBounds();\n this.updateGrid();\n if (CoSEConstants.PURE_INCREMENTAL) this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL / 2;else this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL;\n } else {\n this.isTreeGrowing = false;\n this.isGrowthFinished = true;\n }\n }\n this.growTreeIterations++;\n }\n // Operations after growth is finished\n if (this.isGrowthFinished) {\n if (this.isConverged()) {\n return true;\n }\n if (this.afterGrowthIterations % 10 == 0) {\n this.graphManager.updateBounds();\n this.updateGrid();\n }\n if (CoSEConstants.PURE_INCREMENTAL) this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL / 2 * ((100 - this.afterGrowthIterations) / 100);else this.coolingFactor = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL * ((100 - this.afterGrowthIterations) / 100);\n this.afterGrowthIterations++;\n }\n\n var gridUpdateAllowed = !this.isTreeGrowing && !this.isGrowthFinished;\n var forceToNodeSurroundingUpdate = this.growTreeIterations % 10 == 1 && this.isTreeGrowing || this.afterGrowthIterations % 10 == 1 && this.isGrowthFinished;\n\n this.totalDisplacement = 0;\n this.graphManager.updateBounds();\n this.calcSpringForces();\n this.calcRepulsionForces(gridUpdateAllowed, forceToNodeSurroundingUpdate);\n this.calcGravitationalForces();\n this.moveNodes();\n this.animate();\n\n return false; // Layout is not ended yet return false\n};\n\nCoSELayout.prototype.getPositionsData = function () {\n var allNodes = this.graphManager.getAllNodes();\n var pData = {};\n for (var i = 0; i < allNodes.length; i++) {\n var rect = allNodes[i].rect;\n var id = allNodes[i].id;\n pData[id] = {\n id: id,\n x: rect.getCenterX(),\n y: rect.getCenterY(),\n w: rect.width,\n h: rect.height\n };\n }\n\n return pData;\n};\n\nCoSELayout.prototype.runSpringEmbedder = function () {\n this.initialAnimationPeriod = 25;\n this.animationPeriod = this.initialAnimationPeriod;\n var layoutEnded = false;\n\n // If aminate option is 'during' signal that layout is supposed to start iterating\n if (FDLayoutConstants.ANIMATE === 'during') {\n this.emit('layoutstarted');\n } else {\n // If aminate option is 'during' tick() function will be called on index.js\n while (!layoutEnded) {\n layoutEnded = this.tick();\n }\n\n this.graphManager.updateBounds();\n }\n};\n\n// overrides moveNodes method in FDLayout\nCoSELayout.prototype.moveNodes = function () {\n var lNodes = this.getAllNodes();\n var node;\n\n // calculate displacement for each node \n for (var i = 0; i < lNodes.length; i++) {\n node = lNodes[i];\n node.calculateDisplacement();\n }\n\n if (Object.keys(this.constraints).length > 0) {\n this.updateDisplacements();\n }\n\n // move each node\n for (var i = 0; i < lNodes.length; i++) {\n node = lNodes[i];\n node.move();\n }\n};\n\n// constraint related methods: initConstraintVariables and updateDisplacements\n\n// initialize constraint related variables\nCoSELayout.prototype.initConstraintVariables = function () {\n var self = this;\n this.idToNodeMap = new Map();\n this.fixedNodeSet = new Set();\n\n var allNodes = this.graphManager.getAllNodes();\n\n // fill idToNodeMap\n for (var i = 0; i < allNodes.length; i++) {\n var node = allNodes[i];\n this.idToNodeMap.set(node.id, node);\n }\n\n // calculate fixed node weight for given compound node\n var calculateCompoundWeight = function calculateCompoundWeight(compoundNode) {\n var nodes = compoundNode.getChild().getNodes();\n var node;\n var fixedNodeWeight = 0;\n for (var i = 0; i < nodes.length; i++) {\n node = nodes[i];\n if (node.getChild() == null) {\n if (self.fixedNodeSet.has(node.id)) {\n fixedNodeWeight += 100;\n }\n } else {\n fixedNodeWeight += calculateCompoundWeight(node);\n }\n }\n return fixedNodeWeight;\n };\n\n if (this.constraints.fixedNodeConstraint) {\n // fill fixedNodeSet\n this.constraints.fixedNodeConstraint.forEach(function (nodeData) {\n self.fixedNodeSet.add(nodeData.nodeId);\n });\n\n // assign fixed node weights to compounds if they contain fixed nodes\n var allNodes = this.graphManager.getAllNodes();\n var node;\n\n for (var i = 0; i < allNodes.length; i++) {\n node = allNodes[i];\n if (node.getChild() != null) {\n var fixedNodeWeight = calculateCompoundWeight(node);\n if (fixedNodeWeight > 0) {\n node.fixedNodeWeight = fixedNodeWeight;\n }\n }\n }\n }\n\n if (this.constraints.relativePlacementConstraint) {\n var nodeToDummyForVerticalAlignment = new Map();\n var nodeToDummyForHorizontalAlignment = new Map();\n this.dummyToNodeForVerticalAlignment = new Map();\n this.dummyToNodeForHorizontalAlignment = new Map();\n this.fixedNodesOnHorizontal = new Set();\n this.fixedNodesOnVertical = new Set();\n\n // fill maps and sets\n this.fixedNodeSet.forEach(function (nodeId) {\n self.fixedNodesOnHorizontal.add(nodeId);\n self.fixedNodesOnVertical.add(nodeId);\n });\n\n if (this.constraints.alignmentConstraint) {\n if (this.constraints.alignmentConstraint.vertical) {\n var verticalAlignment = this.constraints.alignmentConstraint.vertical;\n for (var i = 0; i < verticalAlignment.length; i++) {\n this.dummyToNodeForVerticalAlignment.set(\"dummy\" + i, []);\n verticalAlignment[i].forEach(function (nodeId) {\n nodeToDummyForVerticalAlignment.set(nodeId, \"dummy\" + i);\n self.dummyToNodeForVerticalAlignment.get(\"dummy\" + i).push(nodeId);\n if (self.fixedNodeSet.has(nodeId)) {\n self.fixedNodesOnHorizontal.add(\"dummy\" + i);\n }\n });\n }\n }\n if (this.constraints.alignmentConstraint.horizontal) {\n var horizontalAlignment = this.constraints.alignmentConstraint.horizontal;\n for (var i = 0; i < horizontalAlignment.length; i++) {\n this.dummyToNodeForHorizontalAlignment.set(\"dummy\" + i, []);\n horizontalAlignment[i].forEach(function (nodeId) {\n nodeToDummyForHorizontalAlignment.set(nodeId, \"dummy\" + i);\n self.dummyToNodeForHorizontalAlignment.get(\"dummy\" + i).push(nodeId);\n if (self.fixedNodeSet.has(nodeId)) {\n self.fixedNodesOnVertical.add(\"dummy\" + i);\n }\n });\n }\n }\n }\n\n if (CoSEConstants.RELAX_MOVEMENT_ON_CONSTRAINTS) {\n\n this.shuffle = function (array) {\n var j, x, i;\n for (i = array.length - 1; i >= 2 * array.length / 3; i--) {\n j = Math.floor(Math.random() * (i + 1));\n x = array[i];\n array[i] = array[j];\n array[j] = x;\n }\n return array;\n };\n\n this.nodesInRelativeHorizontal = [];\n this.nodesInRelativeVertical = [];\n this.nodeToRelativeConstraintMapHorizontal = new Map();\n this.nodeToRelativeConstraintMapVertical = new Map();\n this.nodeToTempPositionMapHorizontal = new Map();\n this.nodeToTempPositionMapVertical = new Map();\n\n // fill arrays and maps\n this.constraints.relativePlacementConstraint.forEach(function (constraint) {\n if (constraint.left) {\n var nodeIdLeft = nodeToDummyForVerticalAlignment.has(constraint.left) ? nodeToDummyForVerticalAlignment.get(constraint.left) : constraint.left;\n var nodeIdRight = nodeToDummyForVerticalAlignment.has(constraint.right) ? nodeToDummyForVerticalAlignment.get(constraint.right) : constraint.right;\n\n if (!self.nodesInRelativeHorizontal.includes(nodeIdLeft)) {\n self.nodesInRelativeHorizontal.push(nodeIdLeft);\n self.nodeToRelativeConstraintMapHorizontal.set(nodeIdLeft, []);\n if (self.dummyToNodeForVerticalAlignment.has(nodeIdLeft)) {\n self.nodeToTempPositionMapHorizontal.set(nodeIdLeft, self.idToNodeMap.get(self.dummyToNodeForVerticalAlignment.get(nodeIdLeft)[0]).getCenterX());\n } else {\n self.nodeToTempPositionMapHorizontal.set(nodeIdLeft, self.idToNodeMap.get(nodeIdLeft).getCenterX());\n }\n }\n if (!self.nodesInRelativeHorizontal.includes(nodeIdRight)) {\n self.nodesInRelativeHorizontal.push(nodeIdRight);\n self.nodeToRelativeConstraintMapHorizontal.set(nodeIdRight, []);\n if (self.dummyToNodeForVerticalAlignment.has(nodeIdRight)) {\n self.nodeToTempPositionMapHorizontal.set(nodeIdRight, self.idToNodeMap.get(self.dummyToNodeForVerticalAlignment.get(nodeIdRight)[0]).getCenterX());\n } else {\n self.nodeToTempPositionMapHorizontal.set(nodeIdRight, self.idToNodeMap.get(nodeIdRight).getCenterX());\n }\n }\n\n self.nodeToRelativeConstraintMapHorizontal.get(nodeIdLeft).push({ right: nodeIdRight, gap: constraint.gap });\n self.nodeToRelativeConstraintMapHorizontal.get(nodeIdRight).push({ left: nodeIdLeft, gap: constraint.gap });\n } else {\n var nodeIdTop = nodeToDummyForHorizontalAlignment.has(constraint.top) ? nodeToDummyForHorizontalAlignment.get(constraint.top) : constraint.top;\n var nodeIdBottom = nodeToDummyForHorizontalAlignment.has(constraint.bottom) ? nodeToDummyForHorizontalAlignment.get(constraint.bottom) : constraint.bottom;\n\n if (!self.nodesInRelativeVertical.includes(nodeIdTop)) {\n self.nodesInRelativeVertical.push(nodeIdTop);\n self.nodeToRelativeConstraintMapVertical.set(nodeIdTop, []);\n if (self.dummyToNodeForHorizontalAlignment.has(nodeIdTop)) {\n self.nodeToTempPositionMapVertical.set(nodeIdTop, self.idToNodeMap.get(self.dummyToNodeForHorizontalAlignment.get(nodeIdTop)[0]).getCenterY());\n } else {\n self.nodeToTempPositionMapVertical.set(nodeIdTop, self.idToNodeMap.get(nodeIdTop).getCenterY());\n }\n }\n if (!self.nodesInRelativeVertical.includes(nodeIdBottom)) {\n self.nodesInRelativeVertical.push(nodeIdBottom);\n self.nodeToRelativeConstraintMapVertical.set(nodeIdBottom, []);\n if (self.dummyToNodeForHorizontalAlignment.has(nodeIdBottom)) {\n self.nodeToTempPositionMapVertical.set(nodeIdBottom, self.idToNodeMap.get(self.dummyToNodeForHorizontalAlignment.get(nodeIdBottom)[0]).getCenterY());\n } else {\n self.nodeToTempPositionMapVertical.set(nodeIdBottom, self.idToNodeMap.get(nodeIdBottom).getCenterY());\n }\n }\n self.nodeToRelativeConstraintMapVertical.get(nodeIdTop).push({ bottom: nodeIdBottom, gap: constraint.gap });\n self.nodeToRelativeConstraintMapVertical.get(nodeIdBottom).push({ top: nodeIdTop, gap: constraint.gap });\n }\n });\n } else {\n var subGraphOnHorizontal = new Map(); // subgraph from vertical RP constraints\n var subGraphOnVertical = new Map(); // subgraph from vertical RP constraints\n\n // construct subgraphs from relative placement constraints \n this.constraints.relativePlacementConstraint.forEach(function (constraint) {\n if (constraint.left) {\n var left = nodeToDummyForVerticalAlignment.has(constraint.left) ? nodeToDummyForVerticalAlignment.get(constraint.left) : constraint.left;\n var right = nodeToDummyForVerticalAlignment.has(constraint.right) ? nodeToDummyForVerticalAlignment.get(constraint.right) : constraint.right;\n if (subGraphOnHorizontal.has(left)) {\n subGraphOnHorizontal.get(left).push(right);\n } else {\n subGraphOnHorizontal.set(left, [right]);\n }\n if (subGraphOnHorizontal.has(right)) {\n subGraphOnHorizontal.get(right).push(left);\n } else {\n subGraphOnHorizontal.set(right, [left]);\n }\n } else {\n var top = nodeToDummyForHorizontalAlignment.has(constraint.top) ? nodeToDummyForHorizontalAlignment.get(constraint.top) : constraint.top;\n var bottom = nodeToDummyForHorizontalAlignment.has(constraint.bottom) ? nodeToDummyForHorizontalAlignment.get(constraint.bottom) : constraint.bottom;\n if (subGraphOnVertical.has(top)) {\n subGraphOnVertical.get(top).push(bottom);\n } else {\n subGraphOnVertical.set(top, [bottom]);\n }\n if (subGraphOnVertical.has(bottom)) {\n subGraphOnVertical.get(bottom).push(top);\n } else {\n subGraphOnVertical.set(bottom, [top]);\n }\n }\n });\n\n // function to construct components from a given graph \n // also returns an array that keeps whether each component contains fixed node\n var constructComponents = function constructComponents(graph, fixedNodes) {\n var components = [];\n var isFixed = [];\n var queue = new LinkedList();\n var visited = new Set();\n var count = 0;\n\n graph.forEach(function (value, key) {\n if (!visited.has(key)) {\n components[count] = [];\n isFixed[count] = false;\n var currentNode = key;\n queue.push(currentNode);\n visited.add(currentNode);\n components[count].push(currentNode);\n\n while (queue.length != 0) {\n currentNode = queue.shift();\n if (fixedNodes.has(currentNode)) {\n isFixed[count] = true;\n }\n var neighbors = graph.get(currentNode);\n neighbors.forEach(function (neighbor) {\n if (!visited.has(neighbor)) {\n queue.push(neighbor);\n visited.add(neighbor);\n components[count].push(neighbor);\n }\n });\n }\n count++;\n }\n });\n\n return { components: components, isFixed: isFixed };\n };\n\n var resultOnHorizontal = constructComponents(subGraphOnHorizontal, self.fixedNodesOnHorizontal);\n this.componentsOnHorizontal = resultOnHorizontal.components;\n this.fixedComponentsOnHorizontal = resultOnHorizontal.isFixed;\n var resultOnVertical = constructComponents(subGraphOnVertical, self.fixedNodesOnVertical);\n this.componentsOnVertical = resultOnVertical.components;\n this.fixedComponentsOnVertical = resultOnVertical.isFixed;\n }\n }\n};\n\n// updates node displacements based on constraints\nCoSELayout.prototype.updateDisplacements = function () {\n var self = this;\n if (this.constraints.fixedNodeConstraint) {\n this.constraints.fixedNodeConstraint.forEach(function (nodeData) {\n var fixedNode = self.idToNodeMap.get(nodeData.nodeId);\n fixedNode.displacementX = 0;\n fixedNode.displacementY = 0;\n });\n }\n\n if (this.constraints.alignmentConstraint) {\n if (this.constraints.alignmentConstraint.vertical) {\n var allVerticalAlignments = this.constraints.alignmentConstraint.vertical;\n for (var i = 0; i < allVerticalAlignments.length; i++) {\n var totalDisplacementX = 0;\n for (var j = 0; j < allVerticalAlignments[i].length; j++) {\n if (this.fixedNodeSet.has(allVerticalAlignments[i][j])) {\n totalDisplacementX = 0;\n break;\n }\n totalDisplacementX += this.idToNodeMap.get(allVerticalAlignments[i][j]).displacementX;\n }\n var averageDisplacementX = totalDisplacementX / allVerticalAlignments[i].length;\n for (var j = 0; j < allVerticalAlignments[i].length; j++) {\n this.idToNodeMap.get(allVerticalAlignments[i][j]).displacementX = averageDisplacementX;\n }\n }\n }\n if (this.constraints.alignmentConstraint.horizontal) {\n var allHorizontalAlignments = this.constraints.alignmentConstraint.horizontal;\n for (var i = 0; i < allHorizontalAlignments.length; i++) {\n var totalDisplacementY = 0;\n for (var j = 0; j < allHorizontalAlignments[i].length; j++) {\n if (this.fixedNodeSet.has(allHorizontalAlignments[i][j])) {\n totalDisplacementY = 0;\n break;\n }\n totalDisplacementY += this.idToNodeMap.get(allHorizontalAlignments[i][j]).displacementY;\n }\n var averageDisplacementY = totalDisplacementY / allHorizontalAlignments[i].length;\n for (var j = 0; j < allHorizontalAlignments[i].length; j++) {\n this.idToNodeMap.get(allHorizontalAlignments[i][j]).displacementY = averageDisplacementY;\n }\n }\n }\n }\n\n if (this.constraints.relativePlacementConstraint) {\n\n if (CoSEConstants.RELAX_MOVEMENT_ON_CONSTRAINTS) {\n // shuffle array to randomize node processing order\n if (this.totalIterations % 10 == 0) {\n this.shuffle(this.nodesInRelativeHorizontal);\n this.shuffle(this.nodesInRelativeVertical);\n }\n\n this.nodesInRelativeHorizontal.forEach(function (nodeId) {\n if (!self.fixedNodesOnHorizontal.has(nodeId)) {\n var displacement = 0;\n if (self.dummyToNodeForVerticalAlignment.has(nodeId)) {\n displacement = self.idToNodeMap.get(self.dummyToNodeForVerticalAlignment.get(nodeId)[0]).displacementX;\n } else {\n displacement = self.idToNodeMap.get(nodeId).displacementX;\n }\n self.nodeToRelativeConstraintMapHorizontal.get(nodeId).forEach(function (constraint) {\n if (constraint.right) {\n var diff = self.nodeToTempPositionMapHorizontal.get(constraint.right) - self.nodeToTempPositionMapHorizontal.get(nodeId) - displacement;\n if (diff < constraint.gap) {\n displacement -= constraint.gap - diff;\n }\n } else {\n var diff = self.nodeToTempPositionMapHorizontal.get(nodeId) - self.nodeToTempPositionMapHorizontal.get(constraint.left) + displacement;\n if (diff < constraint.gap) {\n displacement += constraint.gap - diff;\n }\n }\n });\n self.nodeToTempPositionMapHorizontal.set(nodeId, self.nodeToTempPositionMapHorizontal.get(nodeId) + displacement);\n if (self.dummyToNodeForVerticalAlignment.has(nodeId)) {\n self.dummyToNodeForVerticalAlignment.get(nodeId).forEach(function (nodeId) {\n self.idToNodeMap.get(nodeId).displacementX = displacement;\n });\n } else {\n self.idToNodeMap.get(nodeId).displacementX = displacement;\n }\n }\n });\n\n this.nodesInRelativeVertical.forEach(function (nodeId) {\n if (!self.fixedNodesOnHorizontal.has(nodeId)) {\n var displacement = 0;\n if (self.dummyToNodeForHorizontalAlignment.has(nodeId)) {\n displacement = self.idToNodeMap.get(self.dummyToNodeForHorizontalAlignment.get(nodeId)[0]).displacementY;\n } else {\n displacement = self.idToNodeMap.get(nodeId).displacementY;\n }\n self.nodeToRelativeConstraintMapVertical.get(nodeId).forEach(function (constraint) {\n if (constraint.bottom) {\n var diff = self.nodeToTempPositionMapVertical.get(constraint.bottom) - self.nodeToTempPositionMapVertical.get(nodeId) - displacement;\n if (diff < constraint.gap) {\n displacement -= constraint.gap - diff;\n }\n } else {\n var diff = self.nodeToTempPositionMapVertical.get(nodeId) - self.nodeToTempPositionMapVertical.get(constraint.top) + displacement;\n if (diff < constraint.gap) {\n displacement += constraint.gap - diff;\n }\n }\n });\n self.nodeToTempPositionMapVertical.set(nodeId, self.nodeToTempPositionMapVertical.get(nodeId) + displacement);\n if (self.dummyToNodeForHorizontalAlignment.has(nodeId)) {\n self.dummyToNodeForHorizontalAlignment.get(nodeId).forEach(function (nodeId) {\n self.idToNodeMap.get(nodeId).displacementY = displacement;\n });\n } else {\n self.idToNodeMap.get(nodeId).displacementY = displacement;\n }\n }\n });\n } else {\n for (var i = 0; i < this.componentsOnHorizontal.length; i++) {\n var component = this.componentsOnHorizontal[i];\n if (this.fixedComponentsOnHorizontal[i]) {\n for (var j = 0; j < component.length; j++) {\n if (this.dummyToNodeForVerticalAlignment.has(component[j])) {\n this.dummyToNodeForVerticalAlignment.get(component[j]).forEach(function (nodeId) {\n self.idToNodeMap.get(nodeId).displacementX = 0;\n });\n } else {\n this.idToNodeMap.get(component[j]).displacementX = 0;\n }\n }\n } else {\n var sum = 0;\n var count = 0;\n for (var j = 0; j < component.length; j++) {\n if (this.dummyToNodeForVerticalAlignment.has(component[j])) {\n var actualNodes = this.dummyToNodeForVerticalAlignment.get(component[j]);\n sum += actualNodes.length * this.idToNodeMap.get(actualNodes[0]).displacementX;\n count += actualNodes.length;\n } else {\n sum += this.idToNodeMap.get(component[j]).displacementX;\n count++;\n }\n }\n var averageDisplacement = sum / count;\n for (var j = 0; j < component.length; j++) {\n if (this.dummyToNodeForVerticalAlignment.has(component[j])) {\n this.dummyToNodeForVerticalAlignment.get(component[j]).forEach(function (nodeId) {\n self.idToNodeMap.get(nodeId).displacementX = averageDisplacement;\n });\n } else {\n this.idToNodeMap.get(component[j]).displacementX = averageDisplacement;\n }\n }\n }\n }\n\n for (var i = 0; i < this.componentsOnVertical.length; i++) {\n var component = this.componentsOnVertical[i];\n if (this.fixedComponentsOnVertical[i]) {\n for (var j = 0; j < component.length; j++) {\n if (this.dummyToNodeForHorizontalAlignment.has(component[j])) {\n this.dummyToNodeForHorizontalAlignment.get(component[j]).forEach(function (nodeId) {\n self.idToNodeMap.get(nodeId).displacementY = 0;\n });\n } else {\n this.idToNodeMap.get(component[j]).displacementY = 0;\n }\n }\n } else {\n var sum = 0;\n var count = 0;\n for (var j = 0; j < component.length; j++) {\n if (this.dummyToNodeForHorizontalAlignment.has(component[j])) {\n var actualNodes = this.dummyToNodeForHorizontalAlignment.get(component[j]);\n sum += actualNodes.length * this.idToNodeMap.get(actualNodes[0]).displacementY;\n count += actualNodes.length;\n } else {\n sum += this.idToNodeMap.get(component[j]).displacementY;\n count++;\n }\n }\n var averageDisplacement = sum / count;\n for (var j = 0; j < component.length; j++) {\n if (this.dummyToNodeForHorizontalAlignment.has(component[j])) {\n this.dummyToNodeForHorizontalAlignment.get(component[j]).forEach(function (nodeId) {\n self.idToNodeMap.get(nodeId).displacementY = averageDisplacement;\n });\n } else {\n this.idToNodeMap.get(component[j]).displacementY = averageDisplacement;\n }\n }\n }\n }\n }\n }\n};\n\nCoSELayout.prototype.calculateNodesToApplyGravitationTo = function () {\n var nodeList = [];\n var graph;\n\n var graphs = this.graphManager.getGraphs();\n var size = graphs.length;\n var i;\n for (i = 0; i < size; i++) {\n graph = graphs[i];\n\n graph.updateConnected();\n\n if (!graph.isConnected) {\n nodeList = nodeList.concat(graph.getNodes());\n }\n }\n\n return nodeList;\n};\n\nCoSELayout.prototype.createBendpoints = function () {\n var edges = [];\n edges = edges.concat(this.graphManager.getAllEdges());\n var visited = new Set();\n var i;\n for (i = 0; i < edges.length; i++) {\n var edge = edges[i];\n\n if (!visited.has(edge)) {\n var source = edge.getSource();\n var target = edge.getTarget();\n\n if (source == target) {\n edge.getBendpoints().push(new PointD());\n edge.getBendpoints().push(new PointD());\n this.createDummyNodesForBendpoints(edge);\n visited.add(edge);\n } else {\n var edgeList = [];\n\n edgeList = edgeList.concat(source.getEdgeListToNode(target));\n edgeList = edgeList.concat(target.getEdgeListToNode(source));\n\n if (!visited.has(edgeList[0])) {\n if (edgeList.length > 1) {\n var k;\n for (k = 0; k < edgeList.length; k++) {\n var multiEdge = edgeList[k];\n multiEdge.getBendpoints().push(new PointD());\n this.createDummyNodesForBendpoints(multiEdge);\n }\n }\n edgeList.forEach(function (edge) {\n visited.add(edge);\n });\n }\n }\n }\n\n if (visited.size == edges.length) {\n break;\n }\n }\n};\n\nCoSELayout.prototype.positionNodesRadially = function (forest) {\n // We tile the trees to a grid row by row; first tree starts at (0,0)\n var currentStartingPoint = new Point(0, 0);\n var numberOfColumns = Math.ceil(Math.sqrt(forest.length));\n var height = 0;\n var currentY = 0;\n var currentX = 0;\n var point = new PointD(0, 0);\n\n for (var i = 0; i < forest.length; i++) {\n if (i % numberOfColumns == 0) {\n // Start of a new row, make the x coordinate 0, increment the\n // y coordinate with the max height of the previous row\n currentX = 0;\n currentY = height;\n\n if (i != 0) {\n currentY += CoSEConstants.DEFAULT_COMPONENT_SEPERATION;\n }\n\n height = 0;\n }\n\n var tree = forest[i];\n\n // Find the center of the tree\n var centerNode = Layout.findCenterOfTree(tree);\n\n // Set the staring point of the next tree\n currentStartingPoint.x = currentX;\n currentStartingPoint.y = currentY;\n\n // Do a radial layout starting with the center\n point = CoSELayout.radialLayout(tree, centerNode, currentStartingPoint);\n\n if (point.y > height) {\n height = Math.floor(point.y);\n }\n\n currentX = Math.floor(point.x + CoSEConstants.DEFAULT_COMPONENT_SEPERATION);\n }\n\n this.transform(new PointD(LayoutConstants.WORLD_CENTER_X - point.x / 2, LayoutConstants.WORLD_CENTER_Y - point.y / 2));\n};\n\nCoSELayout.radialLayout = function (tree, centerNode, startingPoint) {\n var radialSep = Math.max(this.maxDiagonalInTree(tree), CoSEConstants.DEFAULT_RADIAL_SEPARATION);\n CoSELayout.branchRadialLayout(centerNode, null, 0, 359, 0, radialSep);\n var bounds = LGraph.calculateBounds(tree);\n\n var transform = new Transform();\n transform.setDeviceOrgX(bounds.getMinX());\n transform.setDeviceOrgY(bounds.getMinY());\n transform.setWorldOrgX(startingPoint.x);\n transform.setWorldOrgY(startingPoint.y);\n\n for (var i = 0; i < tree.length; i++) {\n var node = tree[i];\n node.transform(transform);\n }\n\n var bottomRight = new PointD(bounds.getMaxX(), bounds.getMaxY());\n\n return transform.inverseTransformPoint(bottomRight);\n};\n\nCoSELayout.branchRadialLayout = function (node, parentOfNode, startAngle, endAngle, distance, radialSeparation) {\n // First, position this node by finding its angle.\n var halfInterval = (endAngle - startAngle + 1) / 2;\n\n if (halfInterval < 0) {\n halfInterval += 180;\n }\n\n var nodeAngle = (halfInterval + startAngle) % 360;\n var teta = nodeAngle * IGeometry.TWO_PI / 360;\n\n // Make polar to java cordinate conversion.\n var cos_teta = Math.cos(teta);\n var x_ = distance * Math.cos(teta);\n var y_ = distance * Math.sin(teta);\n\n node.setCenter(x_, y_);\n\n // Traverse all neighbors of this node and recursively call this\n // function.\n var neighborEdges = [];\n neighborEdges = neighborEdges.concat(node.getEdges());\n var childCount = neighborEdges.length;\n\n if (parentOfNode != null) {\n childCount--;\n }\n\n var branchCount = 0;\n\n var incEdgesCount = neighborEdges.length;\n var startIndex;\n\n var edges = node.getEdgesBetween(parentOfNode);\n\n // If there are multiple edges, prune them until there remains only one\n // edge.\n while (edges.length > 1) {\n //neighborEdges.remove(edges.remove(0));\n var temp = edges[0];\n edges.splice(0, 1);\n var index = neighborEdges.indexOf(temp);\n if (index >= 0) {\n neighborEdges.splice(index, 1);\n }\n incEdgesCount--;\n childCount--;\n }\n\n if (parentOfNode != null) {\n //assert edges.length == 1;\n startIndex = (neighborEdges.indexOf(edges[0]) + 1) % incEdgesCount;\n } else {\n startIndex = 0;\n }\n\n var stepAngle = Math.abs(endAngle - startAngle) / childCount;\n\n for (var i = startIndex; branchCount != childCount; i = ++i % incEdgesCount) {\n var currentNeighbor = neighborEdges[i].getOtherEnd(node);\n\n // Don't back traverse to root node in current tree.\n if (currentNeighbor == parentOfNode) {\n continue;\n }\n\n var childStartAngle = (startAngle + branchCount * stepAngle) % 360;\n var childEndAngle = (childStartAngle + stepAngle) % 360;\n\n CoSELayout.branchRadialLayout(currentNeighbor, node, childStartAngle, childEndAngle, distance + radialSeparation, radialSeparation);\n\n branchCount++;\n }\n};\n\nCoSELayout.maxDiagonalInTree = function (tree) {\n var maxDiagonal = Integer.MIN_VALUE;\n\n for (var i = 0; i < tree.length; i++) {\n var node = tree[i];\n var diagonal = node.getDiagonal();\n\n if (diagonal > maxDiagonal) {\n maxDiagonal = diagonal;\n }\n }\n\n return maxDiagonal;\n};\n\nCoSELayout.prototype.calcRepulsionRange = function () {\n // formula is 2 x (level + 1) x idealEdgeLength\n return 2 * (this.level + 1) * this.idealEdgeLength;\n};\n\n// Tiling methods\n\n// Group zero degree members whose parents are not to be tiled, create dummy parents where needed and fill memberGroups by their dummp parent id's\nCoSELayout.prototype.groupZeroDegreeMembers = function () {\n var self = this;\n // array of [parent_id x oneDegreeNode_id]\n var tempMemberGroups = {}; // A temporary map of parent node and its zero degree members\n this.memberGroups = {}; // A map of dummy parent node and its zero degree members whose parents are not to be tiled\n this.idToDummyNode = {}; // A map of id to dummy node \n\n var zeroDegree = []; // List of zero degree nodes whose parents are not to be tiled\n var allNodes = this.graphManager.getAllNodes();\n\n // Fill zero degree list\n for (var i = 0; i < allNodes.length; i++) {\n var node = allNodes[i];\n var parent = node.getParent();\n // If a node has zero degree and its parent is not to be tiled if exists add that node to zeroDegres list\n if (this.getNodeDegreeWithChildren(node) === 0 && (parent.id == undefined || !this.getToBeTiled(parent))) {\n zeroDegree.push(node);\n }\n }\n\n // Create a map of parent node and its zero degree members\n for (var i = 0; i < zeroDegree.length; i++) {\n var node = zeroDegree[i]; // Zero degree node itself\n var p_id = node.getParent().id; // Parent id\n\n if (typeof tempMemberGroups[p_id] === \"undefined\") tempMemberGroups[p_id] = [];\n\n tempMemberGroups[p_id] = tempMemberGroups[p_id].concat(node); // Push node to the list belongs to its parent in tempMemberGroups\n }\n\n // If there are at least two nodes at a level, create a dummy compound for them\n Object.keys(tempMemberGroups).forEach(function (p_id) {\n if (tempMemberGroups[p_id].length > 1) {\n var dummyCompoundId = \"DummyCompound_\" + p_id; // The id of dummy compound which will be created soon\n self.memberGroups[dummyCompoundId] = tempMemberGroups[p_id]; // Add dummy compound to memberGroups\n\n var parent = tempMemberGroups[p_id][0].getParent(); // The parent of zero degree nodes will be the parent of new dummy compound\n\n // Create a dummy compound with calculated id\n var dummyCompound = new CoSENode(self.graphManager);\n dummyCompound.id = dummyCompoundId;\n dummyCompound.paddingLeft = parent.paddingLeft || 0;\n dummyCompound.paddingRight = parent.paddingRight || 0;\n dummyCompound.paddingBottom = parent.paddingBottom || 0;\n dummyCompound.paddingTop = parent.paddingTop || 0;\n\n self.idToDummyNode[dummyCompoundId] = dummyCompound;\n\n var dummyParentGraph = self.getGraphManager().add(self.newGraph(), dummyCompound);\n var parentGraph = parent.getChild();\n\n // Add dummy compound to parent the graph\n parentGraph.add(dummyCompound);\n\n // For each zero degree node in this level remove it from its parent graph and add it to the graph of dummy parent\n for (var i = 0; i < tempMemberGroups[p_id].length; i++) {\n var node = tempMemberGroups[p_id][i];\n\n parentGraph.remove(node);\n dummyParentGraph.add(node);\n }\n }\n });\n};\n\nCoSELayout.prototype.clearCompounds = function () {\n var childGraphMap = {};\n var idToNode = {};\n\n // Get compound ordering by finding the inner one first\n this.performDFSOnCompounds();\n\n for (var i = 0; i < this.compoundOrder.length; i++) {\n\n idToNode[this.compoundOrder[i].id] = this.compoundOrder[i];\n childGraphMap[this.compoundOrder[i].id] = [].concat(this.compoundOrder[i].getChild().getNodes());\n\n // Remove children of compounds\n this.graphManager.remove(this.compoundOrder[i].getChild());\n this.compoundOrder[i].child = null;\n }\n\n this.graphManager.resetAllNodes();\n\n // Tile the removed children\n this.tileCompoundMembers(childGraphMap, idToNode);\n};\n\nCoSELayout.prototype.clearZeroDegreeMembers = function () {\n var self = this;\n var tiledZeroDegreePack = this.tiledZeroDegreePack = [];\n\n Object.keys(this.memberGroups).forEach(function (id) {\n var compoundNode = self.idToDummyNode[id]; // Get the dummy compound\n\n tiledZeroDegreePack[id] = self.tileNodes(self.memberGroups[id], compoundNode.paddingLeft + compoundNode.paddingRight);\n\n // Set the width and height of the dummy compound as calculated\n compoundNode.rect.width = tiledZeroDegreePack[id].width;\n compoundNode.rect.height = tiledZeroDegreePack[id].height;\n compoundNode.setCenter(tiledZeroDegreePack[id].centerX, tiledZeroDegreePack[id].centerY);\n\n // compound left and top margings for labels\n // when node labels are included, these values may be set to different values below and are used in tilingPostLayout,\n // otherwise they stay as zero\n compoundNode.labelMarginLeft = 0;\n compoundNode.labelMarginTop = 0;\n\n // Update compound bounds considering its label properties and set label margins for left and top\n if (CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS) {\n\n var width = compoundNode.rect.width;\n var height = compoundNode.rect.height;\n\n if (compoundNode.labelWidth) {\n if (compoundNode.labelPosHorizontal == \"left\") {\n compoundNode.rect.x -= compoundNode.labelWidth;\n compoundNode.setWidth(width + compoundNode.labelWidth);\n compoundNode.labelMarginLeft = compoundNode.labelWidth;\n } else if (compoundNode.labelPosHorizontal == \"center\" && compoundNode.labelWidth > width) {\n compoundNode.rect.x -= (compoundNode.labelWidth - width) / 2;\n compoundNode.setWidth(compoundNode.labelWidth);\n compoundNode.labelMarginLeft = (compoundNode.labelWidth - width) / 2;\n } else if (compoundNode.labelPosHorizontal == \"right\") {\n compoundNode.setWidth(width + compoundNode.labelWidth);\n }\n }\n\n if (compoundNode.labelHeight) {\n if (compoundNode.labelPosVertical == \"top\") {\n compoundNode.rect.y -= compoundNode.labelHeight;\n compoundNode.setHeight(height + compoundNode.labelHeight);\n compoundNode.labelMarginTop = compoundNode.labelHeight;\n } else if (compoundNode.labelPosVertical == \"center\" && compoundNode.labelHeight > height) {\n compoundNode.rect.y -= (compoundNode.labelHeight - height) / 2;\n compoundNode.setHeight(compoundNode.labelHeight);\n compoundNode.labelMarginTop = (compoundNode.labelHeight - height) / 2;\n } else if (compoundNode.labelPosVertical == \"bottom\") {\n compoundNode.setHeight(height + compoundNode.labelHeight);\n }\n }\n }\n });\n};\n\nCoSELayout.prototype.repopulateCompounds = function () {\n for (var i = this.compoundOrder.length - 1; i >= 0; i--) {\n var lCompoundNode = this.compoundOrder[i];\n var id = lCompoundNode.id;\n var horizontalMargin = lCompoundNode.paddingLeft;\n var verticalMargin = lCompoundNode.paddingTop;\n var labelMarginLeft = lCompoundNode.labelMarginLeft;\n var labelMarginTop = lCompoundNode.labelMarginTop;\n\n this.adjustLocations(this.tiledMemberPack[id], lCompoundNode.rect.x, lCompoundNode.rect.y, horizontalMargin, verticalMargin, labelMarginLeft, labelMarginTop);\n }\n};\n\nCoSELayout.prototype.repopulateZeroDegreeMembers = function () {\n var self = this;\n var tiledPack = this.tiledZeroDegreePack;\n\n Object.keys(tiledPack).forEach(function (id) {\n var compoundNode = self.idToDummyNode[id]; // Get the dummy compound by its id\n var horizontalMargin = compoundNode.paddingLeft;\n var verticalMargin = compoundNode.paddingTop;\n var labelMarginLeft = compoundNode.labelMarginLeft;\n var labelMarginTop = compoundNode.labelMarginTop;\n\n // Adjust the positions of nodes wrt its compound\n self.adjustLocations(tiledPack[id], compoundNode.rect.x, compoundNode.rect.y, horizontalMargin, verticalMargin, labelMarginLeft, labelMarginTop);\n });\n};\n\nCoSELayout.prototype.getToBeTiled = function (node) {\n var id = node.id;\n //firstly check the previous results\n if (this.toBeTiled[id] != null) {\n return this.toBeTiled[id];\n }\n\n //only compound nodes are to be tiled\n var childGraph = node.getChild();\n if (childGraph == null) {\n this.toBeTiled[id] = false;\n return false;\n }\n\n var children = childGraph.getNodes(); // Get the children nodes\n\n //a compound node is not to be tiled if all of its compound children are not to be tiled\n for (var i = 0; i < children.length; i++) {\n var theChild = children[i];\n\n if (this.getNodeDegree(theChild) > 0) {\n this.toBeTiled[id] = false;\n return false;\n }\n\n //pass the children not having the compound structure\n if (theChild.getChild() == null) {\n this.toBeTiled[theChild.id] = false;\n continue;\n }\n\n if (!this.getToBeTiled(theChild)) {\n this.toBeTiled[id] = false;\n return false;\n }\n }\n this.toBeTiled[id] = true;\n return true;\n};\n\n// Get degree of a node depending of its edges and independent of its children\nCoSELayout.prototype.getNodeDegree = function (node) {\n var id = node.id;\n var edges = node.getEdges();\n var degree = 0;\n\n // For the edges connected\n for (var i = 0; i < edges.length; i++) {\n var edge = edges[i];\n if (edge.getSource().id !== edge.getTarget().id) {\n degree = degree + 1;\n }\n }\n return degree;\n};\n\n// Get degree of a node with its children\nCoSELayout.prototype.getNodeDegreeWithChildren = function (node) {\n var degree = this.getNodeDegree(node);\n if (node.getChild() == null) {\n return degree;\n }\n var children = node.getChild().getNodes();\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n degree += this.getNodeDegreeWithChildren(child);\n }\n return degree;\n};\n\nCoSELayout.prototype.performDFSOnCompounds = function () {\n this.compoundOrder = [];\n this.fillCompexOrderByDFS(this.graphManager.getRoot().getNodes());\n};\n\nCoSELayout.prototype.fillCompexOrderByDFS = function (children) {\n for (var i = 0; i < children.length; i++) {\n var child = children[i];\n if (child.getChild() != null) {\n this.fillCompexOrderByDFS(child.getChild().getNodes());\n }\n if (this.getToBeTiled(child)) {\n this.compoundOrder.push(child);\n }\n }\n};\n\n/**\n* This method places each zero degree member wrt given (x,y) coordinates (top left).\n*/\nCoSELayout.prototype.adjustLocations = function (organization, x, y, compoundHorizontalMargin, compoundVerticalMargin, compoundLabelMarginLeft, compoundLabelMarginTop) {\n x += compoundHorizontalMargin + compoundLabelMarginLeft;\n y += compoundVerticalMargin + compoundLabelMarginTop;\n\n var left = x;\n\n for (var i = 0; i < organization.rows.length; i++) {\n var row = organization.rows[i];\n x = left;\n var maxHeight = 0;\n\n for (var j = 0; j < row.length; j++) {\n var lnode = row[j];\n\n lnode.rect.x = x; // + lnode.rect.width / 2;\n lnode.rect.y = y; // + lnode.rect.height / 2;\n\n x += lnode.rect.width + organization.horizontalPadding;\n\n if (lnode.rect.height > maxHeight) maxHeight = lnode.rect.height;\n }\n\n y += maxHeight + organization.verticalPadding;\n }\n};\n\nCoSELayout.prototype.tileCompoundMembers = function (childGraphMap, idToNode) {\n var self = this;\n this.tiledMemberPack = [];\n\n Object.keys(childGraphMap).forEach(function (id) {\n // Get the compound node\n var compoundNode = idToNode[id];\n\n self.tiledMemberPack[id] = self.tileNodes(childGraphMap[id], compoundNode.paddingLeft + compoundNode.paddingRight);\n\n compoundNode.rect.width = self.tiledMemberPack[id].width;\n compoundNode.rect.height = self.tiledMemberPack[id].height;\n compoundNode.setCenter(self.tiledMemberPack[id].centerX, self.tiledMemberPack[id].centerY);\n\n // compound left and top margings for labels\n // when node labels are included, these values may be set to different values below and are used in tilingPostLayout,\n // otherwise they stay as zero\n compoundNode.labelMarginLeft = 0;\n compoundNode.labelMarginTop = 0;\n\n // Update compound bounds considering its label properties and set label margins for left and top\n if (CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS) {\n\n var width = compoundNode.rect.width;\n var height = compoundNode.rect.height;\n\n if (compoundNode.labelWidth) {\n if (compoundNode.labelPosHorizontal == \"left\") {\n compoundNode.rect.x -= compoundNode.labelWidth;\n compoundNode.setWidth(width + compoundNode.labelWidth);\n compoundNode.labelMarginLeft = compoundNode.labelWidth;\n } else if (compoundNode.labelPosHorizontal == \"center\" && compoundNode.labelWidth > width) {\n compoundNode.rect.x -= (compoundNode.labelWidth - width) / 2;\n compoundNode.setWidth(compoundNode.labelWidth);\n compoundNode.labelMarginLeft = (compoundNode.labelWidth - width) / 2;\n } else if (compoundNode.labelPosHorizontal == \"right\") {\n compoundNode.setWidth(width + compoundNode.labelWidth);\n }\n }\n\n if (compoundNode.labelHeight) {\n if (compoundNode.labelPosVertical == \"top\") {\n compoundNode.rect.y -= compoundNode.labelHeight;\n compoundNode.setHeight(height + compoundNode.labelHeight);\n compoundNode.labelMarginTop = compoundNode.labelHeight;\n } else if (compoundNode.labelPosVertical == \"center\" && compoundNode.labelHeight > height) {\n compoundNode.rect.y -= (compoundNode.labelHeight - height) / 2;\n compoundNode.setHeight(compoundNode.labelHeight);\n compoundNode.labelMarginTop = (compoundNode.labelHeight - height) / 2;\n } else if (compoundNode.labelPosVertical == \"bottom\") {\n compoundNode.setHeight(height + compoundNode.labelHeight);\n }\n }\n }\n });\n};\n\nCoSELayout.prototype.tileNodes = function (nodes, minWidth) {\n var horizontalOrg = this.tileNodesByFavoringDim(nodes, minWidth, true);\n var verticalOrg = this.tileNodesByFavoringDim(nodes, minWidth, false);\n\n var horizontalRatio = this.getOrgRatio(horizontalOrg);\n var verticalRatio = this.getOrgRatio(verticalOrg);\n var bestOrg;\n\n // the best ratio is the one that is closer to 1 since the ratios are already normalized\n // and the best organization is the one that has the best ratio\n if (verticalRatio < horizontalRatio) {\n bestOrg = verticalOrg;\n } else {\n bestOrg = horizontalOrg;\n }\n\n return bestOrg;\n};\n\n// get the width/height ratio of the organization that is normalized so that it will not be less than 1\nCoSELayout.prototype.getOrgRatio = function (organization) {\n // get dimensions and calculate the initial ratio\n var width = organization.width;\n var height = organization.height;\n var ratio = width / height;\n\n // if the initial ratio is less then 1 then inverse it\n if (ratio < 1) {\n ratio = 1 / ratio;\n }\n\n // return the normalized ratio\n return ratio;\n};\n\n/*\n * Calculates the ideal width for the rows. This method assumes that\n * each node has the same sizes and calculates the ideal row width that\n * approximates a square shaped complex accordingly. However, since nodes would\n * have different sizes some rows would have different sizes and the resulting\n * shape would not be an exact square.\n */\nCoSELayout.prototype.calcIdealRowWidth = function (members, favorHorizontalDim) {\n // To approximate a square shaped complex we need to make complex width equal to complex height.\n // To achieve this we need to solve the following equation system for hc:\n // (x + bx) * hc - bx = (y + by) * vc - by, hc * vc = n\n // where x is the avarage width of the nodes, y is the avarage height of nodes\n // bx and by are the buffer sizes in horizontal and vertical dimensions accordingly,\n // hc and vc are the number of rows in horizontal and vertical dimensions\n // n is number of members.\n\n var verticalPadding = CoSEConstants.TILING_PADDING_VERTICAL;\n var horizontalPadding = CoSEConstants.TILING_PADDING_HORIZONTAL;\n\n // number of members\n var membersSize = members.length;\n\n // sum of the width of all members\n var totalWidth = 0;\n\n // sum of the height of all members\n var totalHeight = 0;\n\n var maxWidth = 0;\n\n // traverse all members to calculate total width and total height and get the maximum members width\n members.forEach(function (node) {\n totalWidth += node.getWidth();\n totalHeight += node.getHeight();\n\n if (node.getWidth() > maxWidth) {\n maxWidth = node.getWidth();\n }\n });\n\n // average width of the members\n var averageWidth = totalWidth / membersSize;\n\n // average height of the members\n var averageHeight = totalHeight / membersSize;\n\n // solving the initial equation system for the hc yields the following second degree equation:\n // hc^2 * (x+bx) + hc * (by - bx) - n * (y + by) = 0\n\n // the delta value to solve the equation above for hc\n var delta = Math.pow(verticalPadding - horizontalPadding, 2) + 4 * (averageWidth + horizontalPadding) * (averageHeight + verticalPadding) * membersSize;\n\n // solve the equation using delta value to calculate the horizontal count\n // that represents the number of nodes in an ideal row\n var horizontalCountDouble = (horizontalPadding - verticalPadding + Math.sqrt(delta)) / (2 * (averageWidth + horizontalPadding));\n // round the calculated horizontal count up or down according to the favored dimension\n var horizontalCount;\n\n if (favorHorizontalDim) {\n horizontalCount = Math.ceil(horizontalCountDouble);\n // if horizontalCount count is not a float value then both of rounding to floor and ceil\n // will yield the same values. Instead of repeating the same calculation try going up\n // while favoring horizontal dimension in such cases\n if (horizontalCount == horizontalCountDouble) {\n horizontalCount++;\n }\n } else {\n horizontalCount = Math.floor(horizontalCountDouble);\n }\n\n // ideal width to be calculated\n var idealWidth = horizontalCount * (averageWidth + horizontalPadding) - horizontalPadding;\n\n // if max width is bigger than calculated ideal width reset ideal width to it\n if (maxWidth > idealWidth) {\n idealWidth = maxWidth;\n }\n\n // add the left-right margins to the ideal row width\n idealWidth += horizontalPadding * 2;\n\n // return the ideal row width1\n return idealWidth;\n};\n\nCoSELayout.prototype.tileNodesByFavoringDim = function (nodes, minWidth, favorHorizontalDim) {\n var verticalPadding = CoSEConstants.TILING_PADDING_VERTICAL;\n var horizontalPadding = CoSEConstants.TILING_PADDING_HORIZONTAL;\n var tilingCompareBy = CoSEConstants.TILING_COMPARE_BY;\n var organization = {\n rows: [],\n rowWidth: [],\n rowHeight: [],\n width: 0,\n height: minWidth, // assume minHeight equals to minWidth\n verticalPadding: verticalPadding,\n horizontalPadding: horizontalPadding,\n centerX: 0,\n centerY: 0\n };\n\n if (tilingCompareBy) {\n organization.idealRowWidth = this.calcIdealRowWidth(nodes, favorHorizontalDim);\n }\n\n var getNodeArea = function getNodeArea(n) {\n return n.rect.width * n.rect.height;\n };\n\n var areaCompareFcn = function areaCompareFcn(n1, n2) {\n return getNodeArea(n2) - getNodeArea(n1);\n };\n\n // Sort the nodes in descending order of their areas\n nodes.sort(function (n1, n2) {\n var cmpBy = areaCompareFcn;\n if (organization.idealRowWidth) {\n cmpBy = tilingCompareBy;\n return cmpBy(n1.id, n2.id);\n }\n return cmpBy(n1, n2);\n });\n\n // Create the organization -> calculate compound center\n var sumCenterX = 0;\n var sumCenterY = 0;\n for (var i = 0; i < nodes.length; i++) {\n var lNode = nodes[i];\n\n sumCenterX += lNode.getCenterX();\n sumCenterY += lNode.getCenterY();\n }\n\n organization.centerX = sumCenterX / nodes.length;\n organization.centerY = sumCenterY / nodes.length;\n\n // Create the organization -> tile members\n for (var i = 0; i < nodes.length; i++) {\n var lNode = nodes[i];\n\n if (organization.rows.length == 0) {\n this.insertNodeToRow(organization, lNode, 0, minWidth);\n } else if (this.canAddHorizontal(organization, lNode.rect.width, lNode.rect.height)) {\n var rowIndex = organization.rows.length - 1;\n if (!organization.idealRowWidth) {\n rowIndex = this.getShortestRowIndex(organization);\n }\n this.insertNodeToRow(organization, lNode, rowIndex, minWidth);\n } else {\n this.insertNodeToRow(organization, lNode, organization.rows.length, minWidth);\n }\n\n this.shiftToLastRow(organization);\n }\n\n return organization;\n};\n\nCoSELayout.prototype.insertNodeToRow = function (organization, node, rowIndex, minWidth) {\n var minCompoundSize = minWidth;\n\n // Add new row if needed\n if (rowIndex == organization.rows.length) {\n var secondDimension = [];\n\n organization.rows.push(secondDimension);\n organization.rowWidth.push(minCompoundSize);\n organization.rowHeight.push(0);\n }\n\n // Update row width\n var w = organization.rowWidth[rowIndex] + node.rect.width;\n\n if (organization.rows[rowIndex].length > 0) {\n w += organization.horizontalPadding;\n }\n\n organization.rowWidth[rowIndex] = w;\n // Update compound width\n if (organization.width < w) {\n organization.width = w;\n }\n\n // Update height\n var h = node.rect.height;\n if (rowIndex > 0) h += organization.verticalPadding;\n\n var extraHeight = 0;\n if (h > organization.rowHeight[rowIndex]) {\n extraHeight = organization.rowHeight[rowIndex];\n organization.rowHeight[rowIndex] = h;\n extraHeight = organization.rowHeight[rowIndex] - extraHeight;\n }\n\n organization.height += extraHeight;\n\n // Insert node\n organization.rows[rowIndex].push(node);\n};\n\n//Scans the rows of an organization and returns the one with the min width\nCoSELayout.prototype.getShortestRowIndex = function (organization) {\n var r = -1;\n var min = Number.MAX_VALUE;\n\n for (var i = 0; i < organization.rows.length; i++) {\n if (organization.rowWidth[i] < min) {\n r = i;\n min = organization.rowWidth[i];\n }\n }\n return r;\n};\n\n//Scans the rows of an organization and returns the one with the max width\nCoSELayout.prototype.getLongestRowIndex = function (organization) {\n var r = -1;\n var max = Number.MIN_VALUE;\n\n for (var i = 0; i < organization.rows.length; i++) {\n\n if (organization.rowWidth[i] > max) {\n r = i;\n max = organization.rowWidth[i];\n }\n }\n\n return r;\n};\n\n/**\n* This method checks whether adding extra width to the organization violates\n* the aspect ratio(1) or not.\n*/\nCoSELayout.prototype.canAddHorizontal = function (organization, extraWidth, extraHeight) {\n\n // if there is an ideal row width specified use it instead of checking the aspect ratio\n if (organization.idealRowWidth) {\n var lastRowIndex = organization.rows.length - 1;\n var lastRowWidth = organization.rowWidth[lastRowIndex];\n\n // check and return if ideal row width will be exceed if the node is added to the row\n return lastRowWidth + extraWidth + organization.horizontalPadding <= organization.idealRowWidth;\n }\n\n var sri = this.getShortestRowIndex(organization);\n\n if (sri < 0) {\n return true;\n }\n\n var min = organization.rowWidth[sri];\n\n if (min + organization.horizontalPadding + extraWidth <= organization.width) return true;\n\n var hDiff = 0;\n\n // Adding to an existing row\n if (organization.rowHeight[sri] < extraHeight) {\n if (sri > 0) hDiff = extraHeight + organization.verticalPadding - organization.rowHeight[sri];\n }\n\n var add_to_row_ratio;\n if (organization.width - min >= extraWidth + organization.horizontalPadding) {\n add_to_row_ratio = (organization.height + hDiff) / (min + extraWidth + organization.horizontalPadding);\n } else {\n add_to_row_ratio = (organization.height + hDiff) / organization.width;\n }\n\n // Adding a new row for this node\n hDiff = extraHeight + organization.verticalPadding;\n var add_new_row_ratio;\n if (organization.width < extraWidth) {\n add_new_row_ratio = (organization.height + hDiff) / extraWidth;\n } else {\n add_new_row_ratio = (organization.height + hDiff) / organization.width;\n }\n\n if (add_new_row_ratio < 1) add_new_row_ratio = 1 / add_new_row_ratio;\n\n if (add_to_row_ratio < 1) add_to_row_ratio = 1 / add_to_row_ratio;\n\n return add_to_row_ratio < add_new_row_ratio;\n};\n\n//If moving the last node from the longest row and adding it to the last\n//row makes the bounding box smaller, do it.\nCoSELayout.prototype.shiftToLastRow = function (organization) {\n var longest = this.getLongestRowIndex(organization);\n var last = organization.rowWidth.length - 1;\n var row = organization.rows[longest];\n var node = row[row.length - 1];\n\n var diff = node.width + organization.horizontalPadding;\n\n // Check if there is enough space on the last row\n if (organization.width - organization.rowWidth[last] > diff && longest != last) {\n // Remove the last element of the longest row\n row.splice(-1, 1);\n\n // Push it to the last row\n organization.rows[last].push(node);\n\n organization.rowWidth[longest] = organization.rowWidth[longest] - diff;\n organization.rowWidth[last] = organization.rowWidth[last] + diff;\n organization.width = organization.rowWidth[instance.getLongestRowIndex(organization)];\n\n // Update heights of the organization\n var maxHeight = Number.MIN_VALUE;\n for (var i = 0; i < row.length; i++) {\n if (row[i].height > maxHeight) maxHeight = row[i].height;\n }\n if (longest > 0) maxHeight += organization.verticalPadding;\n\n var prevTotal = organization.rowHeight[longest] + organization.rowHeight[last];\n\n organization.rowHeight[longest] = maxHeight;\n if (organization.rowHeight[last] < node.height + organization.verticalPadding) organization.rowHeight[last] = node.height + organization.verticalPadding;\n\n var finalTotal = organization.rowHeight[longest] + organization.rowHeight[last];\n organization.height += finalTotal - prevTotal;\n\n this.shiftToLastRow(organization);\n }\n};\n\nCoSELayout.prototype.tilingPreLayout = function () {\n if (CoSEConstants.TILE) {\n // Find zero degree nodes and create a compound for each level\n this.groupZeroDegreeMembers();\n // Tile and clear children of each compound\n this.clearCompounds();\n // Separately tile and clear zero degree nodes for each level\n this.clearZeroDegreeMembers();\n }\n};\n\nCoSELayout.prototype.tilingPostLayout = function () {\n if (CoSEConstants.TILE) {\n this.repopulateZeroDegreeMembers();\n this.repopulateCompounds();\n }\n};\n\n// -----------------------------------------------------------------------------\n// Section: Tree Reduction methods\n// -----------------------------------------------------------------------------\n// Reduce trees \nCoSELayout.prototype.reduceTrees = function () {\n var prunedNodesAll = [];\n var containsLeaf = true;\n var node;\n\n while (containsLeaf) {\n var allNodes = this.graphManager.getAllNodes();\n var prunedNodesInStepTemp = [];\n containsLeaf = false;\n\n for (var i = 0; i < allNodes.length; i++) {\n node = allNodes[i];\n if (node.getEdges().length == 1 && !node.getEdges()[0].isInterGraph && node.getChild() == null) {\n if (CoSEConstants.PURE_INCREMENTAL) {\n var otherEnd = node.getEdges()[0].getOtherEnd(node);\n var relativePosition = new DimensionD(node.getCenterX() - otherEnd.getCenterX(), node.getCenterY() - otherEnd.getCenterY());\n prunedNodesInStepTemp.push([node, node.getEdges()[0], node.getOwner(), relativePosition]);\n } else {\n prunedNodesInStepTemp.push([node, node.getEdges()[0], node.getOwner()]);\n }\n containsLeaf = true;\n }\n }\n if (containsLeaf == true) {\n var prunedNodesInStep = [];\n for (var j = 0; j < prunedNodesInStepTemp.length; j++) {\n if (prunedNodesInStepTemp[j][0].getEdges().length == 1) {\n prunedNodesInStep.push(prunedNodesInStepTemp[j]);\n prunedNodesInStepTemp[j][0].getOwner().remove(prunedNodesInStepTemp[j][0]);\n }\n }\n prunedNodesAll.push(prunedNodesInStep);\n this.graphManager.resetAllNodes();\n this.graphManager.resetAllEdges();\n }\n }\n this.prunedNodesAll = prunedNodesAll;\n};\n\n// Grow tree one step \nCoSELayout.prototype.growTree = function (prunedNodesAll) {\n var lengthOfPrunedNodesInStep = prunedNodesAll.length;\n var prunedNodesInStep = prunedNodesAll[lengthOfPrunedNodesInStep - 1];\n\n var nodeData;\n for (var i = 0; i < prunedNodesInStep.length; i++) {\n nodeData = prunedNodesInStep[i];\n\n this.findPlaceforPrunedNode(nodeData);\n\n nodeData[2].add(nodeData[0]);\n nodeData[2].add(nodeData[1], nodeData[1].source, nodeData[1].target);\n }\n\n prunedNodesAll.splice(prunedNodesAll.length - 1, 1);\n this.graphManager.resetAllNodes();\n this.graphManager.resetAllEdges();\n};\n\n// Find an appropriate position to replace pruned node, this method can be improved\nCoSELayout.prototype.findPlaceforPrunedNode = function (nodeData) {\n\n var gridForPrunedNode;\n var nodeToConnect;\n var prunedNode = nodeData[0];\n if (prunedNode == nodeData[1].source) {\n nodeToConnect = nodeData[1].target;\n } else {\n nodeToConnect = nodeData[1].source;\n }\n\n if (CoSEConstants.PURE_INCREMENTAL) {\n prunedNode.setCenter(nodeToConnect.getCenterX() + nodeData[3].getWidth(), nodeToConnect.getCenterY() + nodeData[3].getHeight());\n } else {\n var startGridX = nodeToConnect.startX;\n var finishGridX = nodeToConnect.finishX;\n var startGridY = nodeToConnect.startY;\n var finishGridY = nodeToConnect.finishY;\n\n var upNodeCount = 0;\n var downNodeCount = 0;\n var rightNodeCount = 0;\n var leftNodeCount = 0;\n var controlRegions = [upNodeCount, rightNodeCount, downNodeCount, leftNodeCount];\n\n if (startGridY > 0) {\n for (var i = startGridX; i <= finishGridX; i++) {\n controlRegions[0] += this.grid[i][startGridY - 1].length + this.grid[i][startGridY].length - 1;\n }\n }\n if (finishGridX < this.grid.length - 1) {\n for (var i = startGridY; i <= finishGridY; i++) {\n controlRegions[1] += this.grid[finishGridX + 1][i].length + this.grid[finishGridX][i].length - 1;\n }\n }\n if (finishGridY < this.grid[0].length - 1) {\n for (var i = startGridX; i <= finishGridX; i++) {\n controlRegions[2] += this.grid[i][finishGridY + 1].length + this.grid[i][finishGridY].length - 1;\n }\n }\n if (startGridX > 0) {\n for (var i = startGridY; i <= finishGridY; i++) {\n controlRegions[3] += this.grid[startGridX - 1][i].length + this.grid[startGridX][i].length - 1;\n }\n }\n var min = Integer.MAX_VALUE;\n var minCount;\n var minIndex;\n for (var j = 0; j < controlRegions.length; j++) {\n if (controlRegions[j] < min) {\n min = controlRegions[j];\n minCount = 1;\n minIndex = j;\n } else if (controlRegions[j] == min) {\n minCount++;\n }\n }\n\n if (minCount == 3 && min == 0) {\n if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[2] == 0) {\n gridForPrunedNode = 1;\n } else if (controlRegions[0] == 0 && controlRegions[1] == 0 && controlRegions[3] == 0) {\n gridForPrunedNode = 0;\n } else if (controlRegions[0] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {\n gridForPrunedNode = 3;\n } else if (controlRegions[1] == 0 && controlRegions[2] == 0 && controlRegions[3] == 0) {\n gridForPrunedNode = 2;\n }\n } else if (minCount == 2 && min == 0) {\n var random = Math.floor(Math.random() * 2);\n if (controlRegions[0] == 0 && controlRegions[1] == 0) {\n ;\n if (random == 0) {\n gridForPrunedNode = 0;\n } else {\n gridForPrunedNode = 1;\n }\n } else if (controlRegions[0] == 0 && controlRegions[2] == 0) {\n if (random == 0) {\n gridForPrunedNode = 0;\n } else {\n gridForPrunedNode = 2;\n }\n } else if (controlRegions[0] == 0 && controlRegions[3] == 0) {\n if (random == 0) {\n gridForPrunedNode = 0;\n } else {\n gridForPrunedNode = 3;\n }\n } else if (controlRegions[1] == 0 && controlRegions[2] == 0) {\n if (random == 0) {\n gridForPrunedNode = 1;\n } else {\n gridForPrunedNode = 2;\n }\n } else if (controlRegions[1] == 0 && controlRegions[3] == 0) {\n if (random == 0) {\n gridForPrunedNode = 1;\n } else {\n gridForPrunedNode = 3;\n }\n } else {\n if (random == 0) {\n gridForPrunedNode = 2;\n } else {\n gridForPrunedNode = 3;\n }\n }\n } else if (minCount == 4 && min == 0) {\n var random = Math.floor(Math.random() * 4);\n gridForPrunedNode = random;\n } else {\n gridForPrunedNode = minIndex;\n }\n\n if (gridForPrunedNode == 0) {\n prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() - nodeToConnect.getHeight() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getHeight() / 2);\n } else if (gridForPrunedNode == 1) {\n prunedNode.setCenter(nodeToConnect.getCenterX() + nodeToConnect.getWidth() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getWidth() / 2, nodeToConnect.getCenterY());\n } else if (gridForPrunedNode == 2) {\n prunedNode.setCenter(nodeToConnect.getCenterX(), nodeToConnect.getCenterY() + nodeToConnect.getHeight() / 2 + FDLayoutConstants.DEFAULT_EDGE_LENGTH + prunedNode.getHeight() / 2);\n } else {\n prunedNode.setCenter(nodeToConnect.getCenterX() - nodeToConnect.getWidth() / 2 - FDLayoutConstants.DEFAULT_EDGE_LENGTH - prunedNode.getWidth() / 2, nodeToConnect.getCenterY());\n }\n }\n};\n\nmodule.exports = CoSELayout;\n\n/***/ }),\n\n/***/ 991:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar FDLayoutNode = __webpack_require__(551).FDLayoutNode;\nvar IMath = __webpack_require__(551).IMath;\n\nfunction CoSENode(gm, loc, size, vNode) {\n FDLayoutNode.call(this, gm, loc, size, vNode);\n}\n\nCoSENode.prototype = Object.create(FDLayoutNode.prototype);\nfor (var prop in FDLayoutNode) {\n CoSENode[prop] = FDLayoutNode[prop];\n}\n\nCoSENode.prototype.calculateDisplacement = function () {\n var layout = this.graphManager.getLayout();\n // this check is for compound nodes that contain fixed nodes\n if (this.getChild() != null && this.fixedNodeWeight) {\n this.displacementX += layout.coolingFactor * (this.springForceX + this.repulsionForceX + this.gravitationForceX) / this.fixedNodeWeight;\n this.displacementY += layout.coolingFactor * (this.springForceY + this.repulsionForceY + this.gravitationForceY) / this.fixedNodeWeight;\n } else {\n this.displacementX += layout.coolingFactor * (this.springForceX + this.repulsionForceX + this.gravitationForceX) / this.noOfChildren;\n this.displacementY += layout.coolingFactor * (this.springForceY + this.repulsionForceY + this.gravitationForceY) / this.noOfChildren;\n }\n\n if (Math.abs(this.displacementX) > layout.coolingFactor * layout.maxNodeDisplacement) {\n this.displacementX = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementX);\n }\n\n if (Math.abs(this.displacementY) > layout.coolingFactor * layout.maxNodeDisplacement) {\n this.displacementY = layout.coolingFactor * layout.maxNodeDisplacement * IMath.sign(this.displacementY);\n }\n\n // non-empty compound node, propogate movement to children as well\n if (this.child && this.child.getNodes().length > 0) {\n this.propogateDisplacementToChildren(this.displacementX, this.displacementY);\n }\n};\n\nCoSENode.prototype.propogateDisplacementToChildren = function (dX, dY) {\n var nodes = this.getChild().getNodes();\n var node;\n for (var i = 0; i < nodes.length; i++) {\n node = nodes[i];\n if (node.getChild() == null) {\n node.displacementX += dX;\n node.displacementY += dY;\n } else {\n node.propogateDisplacementToChildren(dX, dY);\n }\n }\n};\n\nCoSENode.prototype.move = function () {\n var layout = this.graphManager.getLayout();\n\n // a simple node or an empty compound node, move it\n if (this.child == null || this.child.getNodes().length == 0) {\n this.moveBy(this.displacementX, this.displacementY);\n\n layout.totalDisplacement += Math.abs(this.displacementX) + Math.abs(this.displacementY);\n }\n\n this.springForceX = 0;\n this.springForceY = 0;\n this.repulsionForceX = 0;\n this.repulsionForceY = 0;\n this.gravitationForceX = 0;\n this.gravitationForceY = 0;\n this.displacementX = 0;\n this.displacementY = 0;\n};\n\nCoSENode.prototype.setPred1 = function (pred1) {\n this.pred1 = pred1;\n};\n\nCoSENode.prototype.getPred1 = function () {\n return pred1;\n};\n\nCoSENode.prototype.getPred2 = function () {\n return pred2;\n};\n\nCoSENode.prototype.setNext = function (next) {\n this.next = next;\n};\n\nCoSENode.prototype.getNext = function () {\n return next;\n};\n\nCoSENode.prototype.setProcessed = function (processed) {\n this.processed = processed;\n};\n\nCoSENode.prototype.isProcessed = function () {\n return processed;\n};\n\nmodule.exports = CoSENode;\n\n/***/ }),\n\n/***/ 902:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nfunction _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }\n\nvar CoSEConstants = __webpack_require__(806);\nvar LinkedList = __webpack_require__(551).LinkedList;\nvar Matrix = __webpack_require__(551).Matrix;\nvar SVD = __webpack_require__(551).SVD;\n\nfunction ConstraintHandler() {}\n\nConstraintHandler.handleConstraints = function (layout) {\n // let layout = this.graphManager.getLayout();\n\n // get constraints from layout\n var constraints = {};\n constraints.fixedNodeConstraint = layout.constraints.fixedNodeConstraint;\n constraints.alignmentConstraint = layout.constraints.alignmentConstraint;\n constraints.relativePlacementConstraint = layout.constraints.relativePlacementConstraint;\n\n var idToNodeMap = new Map();\n var nodeIndexes = new Map();\n var xCoords = [];\n var yCoords = [];\n\n var allNodes = layout.getAllNodes();\n var index = 0;\n // fill index map and coordinates\n for (var i = 0; i < allNodes.length; i++) {\n var node = allNodes[i];\n if (node.getChild() == null) {\n nodeIndexes.set(node.id, index++);\n xCoords.push(node.getCenterX());\n yCoords.push(node.getCenterY());\n idToNodeMap.set(node.id, node);\n }\n }\n\n // if there exists relative placement constraint without gap value, set it to default \n if (constraints.relativePlacementConstraint) {\n constraints.relativePlacementConstraint.forEach(function (constraint) {\n if (!constraint.gap && constraint.gap != 0) {\n if (constraint.left) {\n constraint.gap = CoSEConstants.DEFAULT_EDGE_LENGTH + idToNodeMap.get(constraint.left).getWidth() / 2 + idToNodeMap.get(constraint.right).getWidth() / 2;\n } else {\n constraint.gap = CoSEConstants.DEFAULT_EDGE_LENGTH + idToNodeMap.get(constraint.top).getHeight() / 2 + idToNodeMap.get(constraint.bottom).getHeight() / 2;\n }\n }\n });\n }\n\n /* auxiliary functions */\n\n // calculate difference between two position objects\n var calculatePositionDiff = function calculatePositionDiff(pos1, pos2) {\n return { x: pos1.x - pos2.x, y: pos1.y - pos2.y };\n };\n\n // calculate average position of the nodes\n var calculateAvgPosition = function calculateAvgPosition(nodeIdSet) {\n var xPosSum = 0;\n var yPosSum = 0;\n nodeIdSet.forEach(function (nodeId) {\n xPosSum += xCoords[nodeIndexes.get(nodeId)];\n yPosSum += yCoords[nodeIndexes.get(nodeId)];\n });\n\n return { x: xPosSum / nodeIdSet.size, y: yPosSum / nodeIdSet.size };\n };\n\n // find an appropriate positioning for the nodes in a given graph according to relative placement constraints\n // this function also takes the fixed nodes and alignment constraints into account\n // graph: dag to be evaluated, direction: \"horizontal\" or \"vertical\", \n // fixedNodes: set of fixed nodes to consider during evaluation, dummyPositions: appropriate coordinates of the dummy nodes \n var findAppropriatePositionForRelativePlacement = function findAppropriatePositionForRelativePlacement(graph, direction, fixedNodes, dummyPositions, componentSources) {\n\n // find union of two sets\n function setUnion(setA, setB) {\n var union = new Set(setA);\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = setB[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var elem = _step.value;\n\n union.add(elem);\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n return union;\n }\n\n // find indegree count for each node\n var inDegrees = new Map();\n\n graph.forEach(function (value, key) {\n inDegrees.set(key, 0);\n });\n graph.forEach(function (value, key) {\n value.forEach(function (adjacent) {\n inDegrees.set(adjacent.id, inDegrees.get(adjacent.id) + 1);\n });\n });\n\n var positionMap = new Map(); // keeps the position for each node\n var pastMap = new Map(); // keeps the predecessors(past) of a node\n var queue = new LinkedList();\n inDegrees.forEach(function (value, key) {\n if (value == 0) {\n queue.push(key);\n if (!fixedNodes) {\n if (direction == \"horizontal\") {\n positionMap.set(key, nodeIndexes.has(key) ? xCoords[nodeIndexes.get(key)] : dummyPositions.get(key));\n } else {\n positionMap.set(key, nodeIndexes.has(key) ? yCoords[nodeIndexes.get(key)] : dummyPositions.get(key));\n }\n }\n } else {\n positionMap.set(key, Number.NEGATIVE_INFINITY);\n }\n if (fixedNodes) {\n pastMap.set(key, new Set([key]));\n }\n });\n\n // align sources of each component in enforcement phase\n if (fixedNodes) {\n componentSources.forEach(function (component) {\n var fixedIds = [];\n component.forEach(function (nodeId) {\n if (fixedNodes.has(nodeId)) {\n fixedIds.push(nodeId);\n }\n });\n if (fixedIds.length > 0) {\n var position = 0;\n fixedIds.forEach(function (fixedId) {\n if (direction == \"horizontal\") {\n positionMap.set(fixedId, nodeIndexes.has(fixedId) ? xCoords[nodeIndexes.get(fixedId)] : dummyPositions.get(fixedId));\n position += positionMap.get(fixedId);\n } else {\n positionMap.set(fixedId, nodeIndexes.has(fixedId) ? yCoords[nodeIndexes.get(fixedId)] : dummyPositions.get(fixedId));\n position += positionMap.get(fixedId);\n }\n });\n position = position / fixedIds.length;\n component.forEach(function (nodeId) {\n if (!fixedNodes.has(nodeId)) {\n positionMap.set(nodeId, position);\n }\n });\n } else {\n var _position = 0;\n component.forEach(function (nodeId) {\n if (direction == \"horizontal\") {\n _position += nodeIndexes.has(nodeId) ? xCoords[nodeIndexes.get(nodeId)] : dummyPositions.get(nodeId);\n } else {\n _position += nodeIndexes.has(nodeId) ? yCoords[nodeIndexes.get(nodeId)] : dummyPositions.get(nodeId);\n }\n });\n _position = _position / component.length;\n component.forEach(function (nodeId) {\n positionMap.set(nodeId, _position);\n });\n }\n });\n }\n\n // calculate positions of the nodes\n\n var _loop = function _loop() {\n var currentNode = queue.shift();\n var neighbors = graph.get(currentNode);\n neighbors.forEach(function (neighbor) {\n if (positionMap.get(neighbor.id) < positionMap.get(currentNode) + neighbor.gap) {\n if (fixedNodes && fixedNodes.has(neighbor.id)) {\n var fixedPosition = void 0;\n if (direction == \"horizontal\") {\n fixedPosition = nodeIndexes.has(neighbor.id) ? xCoords[nodeIndexes.get(neighbor.id)] : dummyPositions.get(neighbor.id);\n } else {\n fixedPosition = nodeIndexes.has(neighbor.id) ? yCoords[nodeIndexes.get(neighbor.id)] : dummyPositions.get(neighbor.id);\n }\n positionMap.set(neighbor.id, fixedPosition); // TODO: may do unnecessary work\n if (fixedPosition < positionMap.get(currentNode) + neighbor.gap) {\n var diff = positionMap.get(currentNode) + neighbor.gap - fixedPosition;\n pastMap.get(currentNode).forEach(function (nodeId) {\n positionMap.set(nodeId, positionMap.get(nodeId) - diff);\n });\n }\n } else {\n positionMap.set(neighbor.id, positionMap.get(currentNode) + neighbor.gap);\n }\n }\n inDegrees.set(neighbor.id, inDegrees.get(neighbor.id) - 1);\n if (inDegrees.get(neighbor.id) == 0) {\n queue.push(neighbor.id);\n }\n if (fixedNodes) {\n pastMap.set(neighbor.id, setUnion(pastMap.get(currentNode), pastMap.get(neighbor.id)));\n }\n });\n };\n\n while (queue.length != 0) {\n _loop();\n }\n\n // readjust position of the nodes after enforcement\n if (fixedNodes) {\n // find indegree count for each node\n var sinkNodes = new Set();\n\n graph.forEach(function (value, key) {\n if (value.length == 0) {\n sinkNodes.add(key);\n }\n });\n\n var _components = [];\n pastMap.forEach(function (value, key) {\n if (sinkNodes.has(key)) {\n var isFixedComponent = false;\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = value[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var nodeId = _step2.value;\n\n if (fixedNodes.has(nodeId)) {\n isFixedComponent = true;\n }\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n if (!isFixedComponent) {\n var isExist = false;\n var existAt = void 0;\n _components.forEach(function (component, index) {\n if (component.has([].concat(_toConsumableArray(value))[0])) {\n isExist = true;\n existAt = index;\n }\n });\n if (!isExist) {\n _components.push(new Set(value));\n } else {\n value.forEach(function (ele) {\n _components[existAt].add(ele);\n });\n }\n }\n }\n });\n\n _components.forEach(function (component, index) {\n var minBefore = Number.POSITIVE_INFINITY;\n var minAfter = Number.POSITIVE_INFINITY;\n var maxBefore = Number.NEGATIVE_INFINITY;\n var maxAfter = Number.NEGATIVE_INFINITY;\n\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = component[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var nodeId = _step3.value;\n\n var posBefore = void 0;\n if (direction == \"horizontal\") {\n posBefore = nodeIndexes.has(nodeId) ? xCoords[nodeIndexes.get(nodeId)] : dummyPositions.get(nodeId);\n } else {\n posBefore = nodeIndexes.has(nodeId) ? yCoords[nodeIndexes.get(nodeId)] : dummyPositions.get(nodeId);\n }\n var posAfter = positionMap.get(nodeId);\n if (posBefore < minBefore) {\n minBefore = posBefore;\n }\n if (posBefore > maxBefore) {\n maxBefore = posBefore;\n }\n if (posAfter < minAfter) {\n minAfter = posAfter;\n }\n if (posAfter > maxAfter) {\n maxAfter = posAfter;\n }\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n\n var diff = (minBefore + maxBefore) / 2 - (minAfter + maxAfter) / 2;\n\n var _iteratorNormalCompletion4 = true;\n var _didIteratorError4 = false;\n var _iteratorError4 = undefined;\n\n try {\n for (var _iterator4 = component[Symbol.iterator](), _step4; !(_iteratorNormalCompletion4 = (_step4 = _iterator4.next()).done); _iteratorNormalCompletion4 = true) {\n var _nodeId = _step4.value;\n\n positionMap.set(_nodeId, positionMap.get(_nodeId) + diff);\n }\n } catch (err) {\n _didIteratorError4 = true;\n _iteratorError4 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion4 && _iterator4.return) {\n _iterator4.return();\n }\n } finally {\n if (_didIteratorError4) {\n throw _iteratorError4;\n }\n }\n }\n });\n }\n\n return positionMap;\n };\n\n // find transformation based on rel. placement constraints if there are both alignment and rel. placement constraints\n // or if there are only rel. placement contraints where the largest component isn't sufficiently large\n var applyReflectionForRelativePlacement = function applyReflectionForRelativePlacement(relativePlacementConstraints) {\n // variables to count votes\n var reflectOnY = 0,\n notReflectOnY = 0;\n var reflectOnX = 0,\n notReflectOnX = 0;\n\n relativePlacementConstraints.forEach(function (constraint) {\n if (constraint.left) {\n xCoords[nodeIndexes.get(constraint.left)] - xCoords[nodeIndexes.get(constraint.right)] >= 0 ? reflectOnY++ : notReflectOnY++;\n } else {\n yCoords[nodeIndexes.get(constraint.top)] - yCoords[nodeIndexes.get(constraint.bottom)] >= 0 ? reflectOnX++ : notReflectOnX++;\n }\n });\n\n if (reflectOnY > notReflectOnY && reflectOnX > notReflectOnX) {\n for (var _i = 0; _i < nodeIndexes.size; _i++) {\n xCoords[_i] = -1 * xCoords[_i];\n yCoords[_i] = -1 * yCoords[_i];\n }\n } else if (reflectOnY > notReflectOnY) {\n for (var _i2 = 0; _i2 < nodeIndexes.size; _i2++) {\n xCoords[_i2] = -1 * xCoords[_i2];\n }\n } else if (reflectOnX > notReflectOnX) {\n for (var _i3 = 0; _i3 < nodeIndexes.size; _i3++) {\n yCoords[_i3] = -1 * yCoords[_i3];\n }\n }\n };\n\n // find weakly connected components in undirected graph\n var findComponents = function findComponents(graph) {\n // find weakly connected components in dag\n var components = [];\n var queue = new LinkedList();\n var visited = new Set();\n var count = 0;\n\n graph.forEach(function (value, key) {\n if (!visited.has(key)) {\n components[count] = [];\n var _currentNode = key;\n queue.push(_currentNode);\n visited.add(_currentNode);\n components[count].push(_currentNode);\n\n while (queue.length != 0) {\n _currentNode = queue.shift();\n var neighbors = graph.get(_currentNode);\n neighbors.forEach(function (neighbor) {\n if (!visited.has(neighbor.id)) {\n queue.push(neighbor.id);\n visited.add(neighbor.id);\n components[count].push(neighbor.id);\n }\n });\n }\n count++;\n }\n });\n return components;\n };\n\n // return undirected version of given dag\n var dagToUndirected = function dagToUndirected(dag) {\n var undirected = new Map();\n\n dag.forEach(function (value, key) {\n undirected.set(key, []);\n });\n\n dag.forEach(function (value, key) {\n value.forEach(function (adjacent) {\n undirected.get(key).push(adjacent);\n undirected.get(adjacent.id).push({ id: key, gap: adjacent.gap, direction: adjacent.direction });\n });\n });\n\n return undirected;\n };\n\n // return reversed (directions inverted) version of given dag\n var dagToReversed = function dagToReversed(dag) {\n var reversed = new Map();\n\n dag.forEach(function (value, key) {\n reversed.set(key, []);\n });\n\n dag.forEach(function (value, key) {\n value.forEach(function (adjacent) {\n reversed.get(adjacent.id).push({ id: key, gap: adjacent.gap, direction: adjacent.direction });\n });\n });\n\n return reversed;\n };\n\n /**** apply transformation to the initial draft layout to better align with constrained nodes ****/\n // solve the Orthogonal Procrustean Problem to rotate and/or reflect initial draft layout\n // here we follow the solution in Chapter 20.2 of Borg, I. & Groenen, P. (2005) Modern Multidimensional Scaling: Theory and Applications \n\n /* construct source and target configurations */\n\n var targetMatrix = []; // A - target configuration\n var sourceMatrix = []; // B - source configuration \n var standardTransformation = false; // false for no transformation, true for standart (Procrustes) transformation (rotation and/or reflection)\n var reflectionType = false; // false/true for reflection check, 'reflectOnX', 'reflectOnY' or 'reflectOnBoth' for reflection type if necessary\n var fixedNodes = new Set();\n var dag = new Map(); // adjacency list to keep directed acyclic graph (dag) that consists of relative placement constraints\n var dagUndirected = new Map(); // undirected version of the dag\n var components = []; // weakly connected components\n\n // fill fixedNodes collection to use later\n if (constraints.fixedNodeConstraint) {\n constraints.fixedNodeConstraint.forEach(function (nodeData) {\n fixedNodes.add(nodeData.nodeId);\n });\n }\n\n // construct dag from relative placement constraints \n if (constraints.relativePlacementConstraint) {\n // construct both directed and undirected version of the dag\n constraints.relativePlacementConstraint.forEach(function (constraint) {\n if (constraint.left) {\n if (dag.has(constraint.left)) {\n dag.get(constraint.left).push({ id: constraint.right, gap: constraint.gap, direction: \"horizontal\" });\n } else {\n dag.set(constraint.left, [{ id: constraint.right, gap: constraint.gap, direction: \"horizontal\" }]);\n }\n if (!dag.has(constraint.right)) {\n dag.set(constraint.right, []);\n }\n } else {\n if (dag.has(constraint.top)) {\n dag.get(constraint.top).push({ id: constraint.bottom, gap: constraint.gap, direction: \"vertical\" });\n } else {\n dag.set(constraint.top, [{ id: constraint.bottom, gap: constraint.gap, direction: \"vertical\" }]);\n }\n if (!dag.has(constraint.bottom)) {\n dag.set(constraint.bottom, []);\n }\n }\n });\n\n dagUndirected = dagToUndirected(dag);\n components = findComponents(dagUndirected);\n }\n\n if (CoSEConstants.TRANSFORM_ON_CONSTRAINT_HANDLING) {\n // first check fixed node constraint\n if (constraints.fixedNodeConstraint && constraints.fixedNodeConstraint.length > 1) {\n constraints.fixedNodeConstraint.forEach(function (nodeData, i) {\n targetMatrix[i] = [nodeData.position.x, nodeData.position.y];\n sourceMatrix[i] = [xCoords[nodeIndexes.get(nodeData.nodeId)], yCoords[nodeIndexes.get(nodeData.nodeId)]];\n });\n standardTransformation = true;\n } else if (constraints.alignmentConstraint) {\n (function () {\n // then check alignment constraint\n var count = 0;\n if (constraints.alignmentConstraint.vertical) {\n var verticalAlign = constraints.alignmentConstraint.vertical;\n\n var _loop2 = function _loop2(_i4) {\n var alignmentSet = new Set();\n verticalAlign[_i4].forEach(function (nodeId) {\n alignmentSet.add(nodeId);\n });\n var intersection = new Set([].concat(_toConsumableArray(alignmentSet)).filter(function (x) {\n return fixedNodes.has(x);\n }));\n var xPos = void 0;\n if (intersection.size > 0) xPos = xCoords[nodeIndexes.get(intersection.values().next().value)];else xPos = calculateAvgPosition(alignmentSet).x;\n\n verticalAlign[_i4].forEach(function (nodeId) {\n targetMatrix[count] = [xPos, yCoords[nodeIndexes.get(nodeId)]];\n sourceMatrix[count] = [xCoords[nodeIndexes.get(nodeId)], yCoords[nodeIndexes.get(nodeId)]];\n count++;\n });\n };\n\n for (var _i4 = 0; _i4 < verticalAlign.length; _i4++) {\n _loop2(_i4);\n }\n standardTransformation = true;\n }\n if (constraints.alignmentConstraint.horizontal) {\n var horizontalAlign = constraints.alignmentConstraint.horizontal;\n\n var _loop3 = function _loop3(_i5) {\n var alignmentSet = new Set();\n horizontalAlign[_i5].forEach(function (nodeId) {\n alignmentSet.add(nodeId);\n });\n var intersection = new Set([].concat(_toConsumableArray(alignmentSet)).filter(function (x) {\n return fixedNodes.has(x);\n }));\n var yPos = void 0;\n if (intersection.size > 0) yPos = xCoords[nodeIndexes.get(intersection.values().next().value)];else yPos = calculateAvgPosition(alignmentSet).y;\n\n horizontalAlign[_i5].forEach(function (nodeId) {\n targetMatrix[count] = [xCoords[nodeIndexes.get(nodeId)], yPos];\n sourceMatrix[count] = [xCoords[nodeIndexes.get(nodeId)], yCoords[nodeIndexes.get(nodeId)]];\n count++;\n });\n };\n\n for (var _i5 = 0; _i5 < horizontalAlign.length; _i5++) {\n _loop3(_i5);\n }\n standardTransformation = true;\n }\n if (constraints.relativePlacementConstraint) {\n reflectionType = true;\n }\n })();\n } else if (constraints.relativePlacementConstraint) {\n // finally check relative placement constraint\n // find largest component in dag\n var largestComponentSize = 0;\n var largestComponentIndex = 0;\n for (var _i6 = 0; _i6 < components.length; _i6++) {\n if (components[_i6].length > largestComponentSize) {\n largestComponentSize = components[_i6].length;\n largestComponentIndex = _i6;\n }\n }\n // if largest component isn't dominant, then take the votes for reflection\n if (largestComponentSize < dagUndirected.size / 2) {\n applyReflectionForRelativePlacement(constraints.relativePlacementConstraint);\n standardTransformation = false;\n reflectionType = false;\n } else {\n // use largest component for transformation\n // construct horizontal and vertical subgraphs in the largest component\n var subGraphOnHorizontal = new Map();\n var subGraphOnVertical = new Map();\n var constraintsInlargestComponent = [];\n\n components[largestComponentIndex].forEach(function (nodeId) {\n dag.get(nodeId).forEach(function (adjacent) {\n if (adjacent.direction == \"horizontal\") {\n if (subGraphOnHorizontal.has(nodeId)) {\n subGraphOnHorizontal.get(nodeId).push(adjacent);\n } else {\n subGraphOnHorizontal.set(nodeId, [adjacent]);\n }\n if (!subGraphOnHorizontal.has(adjacent.id)) {\n subGraphOnHorizontal.set(adjacent.id, []);\n }\n constraintsInlargestComponent.push({ left: nodeId, right: adjacent.id });\n } else {\n if (subGraphOnVertical.has(nodeId)) {\n subGraphOnVertical.get(nodeId).push(adjacent);\n } else {\n subGraphOnVertical.set(nodeId, [adjacent]);\n }\n if (!subGraphOnVertical.has(adjacent.id)) {\n subGraphOnVertical.set(adjacent.id, []);\n }\n constraintsInlargestComponent.push({ top: nodeId, bottom: adjacent.id });\n }\n });\n });\n\n applyReflectionForRelativePlacement(constraintsInlargestComponent);\n reflectionType = false;\n\n // calculate appropriate positioning for subgraphs\n var positionMapHorizontal = findAppropriatePositionForRelativePlacement(subGraphOnHorizontal, \"horizontal\");\n var positionMapVertical = findAppropriatePositionForRelativePlacement(subGraphOnVertical, \"vertical\");\n\n // construct source and target configuration\n components[largestComponentIndex].forEach(function (nodeId, i) {\n sourceMatrix[i] = [xCoords[nodeIndexes.get(nodeId)], yCoords[nodeIndexes.get(nodeId)]];\n targetMatrix[i] = [];\n if (positionMapHorizontal.has(nodeId)) {\n targetMatrix[i][0] = positionMapHorizontal.get(nodeId);\n } else {\n targetMatrix[i][0] = xCoords[nodeIndexes.get(nodeId)];\n }\n if (positionMapVertical.has(nodeId)) {\n targetMatrix[i][1] = positionMapVertical.get(nodeId);\n } else {\n targetMatrix[i][1] = yCoords[nodeIndexes.get(nodeId)];\n }\n });\n\n standardTransformation = true;\n }\n }\n\n // if transformation is required, then calculate and apply transformation matrix\n if (standardTransformation) {\n /* calculate transformation matrix */\n var transformationMatrix = void 0;\n var targetMatrixTranspose = Matrix.transpose(targetMatrix); // A'\n var sourceMatrixTranspose = Matrix.transpose(sourceMatrix); // B'\n\n // centralize transpose matrices\n for (var _i7 = 0; _i7 < targetMatrixTranspose.length; _i7++) {\n targetMatrixTranspose[_i7] = Matrix.multGamma(targetMatrixTranspose[_i7]);\n sourceMatrixTranspose[_i7] = Matrix.multGamma(sourceMatrixTranspose[_i7]);\n }\n\n // do actual calculation for transformation matrix\n var tempMatrix = Matrix.multMat(targetMatrixTranspose, Matrix.transpose(sourceMatrixTranspose)); // tempMatrix = A'B\n var SVDResult = SVD.svd(tempMatrix); // SVD(A'B) = USV', svd function returns U, S and V \n transformationMatrix = Matrix.multMat(SVDResult.V, Matrix.transpose(SVDResult.U)); // transformationMatrix = T = VU'\n\n /* apply found transformation matrix to obtain final draft layout */\n for (var _i8 = 0; _i8 < nodeIndexes.size; _i8++) {\n var temp1 = [xCoords[_i8], yCoords[_i8]];\n var temp2 = [transformationMatrix[0][0], transformationMatrix[1][0]];\n var temp3 = [transformationMatrix[0][1], transformationMatrix[1][1]];\n xCoords[_i8] = Matrix.dotProduct(temp1, temp2);\n yCoords[_i8] = Matrix.dotProduct(temp1, temp3);\n }\n\n // applied only both alignment and rel. placement constraints exist\n if (reflectionType) {\n applyReflectionForRelativePlacement(constraints.relativePlacementConstraint);\n }\n }\n }\n\n if (CoSEConstants.ENFORCE_CONSTRAINTS) {\n /**** enforce constraints on the transformed draft layout ****/\n\n /* first enforce fixed node constraint */\n\n if (constraints.fixedNodeConstraint && constraints.fixedNodeConstraint.length > 0) {\n var translationAmount = { x: 0, y: 0 };\n constraints.fixedNodeConstraint.forEach(function (nodeData, i) {\n var posInTheory = { x: xCoords[nodeIndexes.get(nodeData.nodeId)], y: yCoords[nodeIndexes.get(nodeData.nodeId)] };\n var posDesired = nodeData.position;\n var posDiff = calculatePositionDiff(posDesired, posInTheory);\n translationAmount.x += posDiff.x;\n translationAmount.y += posDiff.y;\n });\n translationAmount.x /= constraints.fixedNodeConstraint.length;\n translationAmount.y /= constraints.fixedNodeConstraint.length;\n\n xCoords.forEach(function (value, i) {\n xCoords[i] += translationAmount.x;\n });\n\n yCoords.forEach(function (value, i) {\n yCoords[i] += translationAmount.y;\n });\n\n constraints.fixedNodeConstraint.forEach(function (nodeData) {\n xCoords[nodeIndexes.get(nodeData.nodeId)] = nodeData.position.x;\n yCoords[nodeIndexes.get(nodeData.nodeId)] = nodeData.position.y;\n });\n }\n\n /* then enforce alignment constraint */\n\n if (constraints.alignmentConstraint) {\n if (constraints.alignmentConstraint.vertical) {\n var xAlign = constraints.alignmentConstraint.vertical;\n\n var _loop4 = function _loop4(_i9) {\n var alignmentSet = new Set();\n xAlign[_i9].forEach(function (nodeId) {\n alignmentSet.add(nodeId);\n });\n var intersection = new Set([].concat(_toConsumableArray(alignmentSet)).filter(function (x) {\n return fixedNodes.has(x);\n }));\n var xPos = void 0;\n if (intersection.size > 0) xPos = xCoords[nodeIndexes.get(intersection.values().next().value)];else xPos = calculateAvgPosition(alignmentSet).x;\n\n alignmentSet.forEach(function (nodeId) {\n if (!fixedNodes.has(nodeId)) xCoords[nodeIndexes.get(nodeId)] = xPos;\n });\n };\n\n for (var _i9 = 0; _i9 < xAlign.length; _i9++) {\n _loop4(_i9);\n }\n }\n if (constraints.alignmentConstraint.horizontal) {\n var yAlign = constraints.alignmentConstraint.horizontal;\n\n var _loop5 = function _loop5(_i10) {\n var alignmentSet = new Set();\n yAlign[_i10].forEach(function (nodeId) {\n alignmentSet.add(nodeId);\n });\n var intersection = new Set([].concat(_toConsumableArray(alignmentSet)).filter(function (x) {\n return fixedNodes.has(x);\n }));\n var yPos = void 0;\n if (intersection.size > 0) yPos = yCoords[nodeIndexes.get(intersection.values().next().value)];else yPos = calculateAvgPosition(alignmentSet).y;\n\n alignmentSet.forEach(function (nodeId) {\n if (!fixedNodes.has(nodeId)) yCoords[nodeIndexes.get(nodeId)] = yPos;\n });\n };\n\n for (var _i10 = 0; _i10 < yAlign.length; _i10++) {\n _loop5(_i10);\n }\n }\n }\n\n /* finally enforce relative placement constraint */\n\n if (constraints.relativePlacementConstraint) {\n (function () {\n var nodeToDummyForVerticalAlignment = new Map();\n var nodeToDummyForHorizontalAlignment = new Map();\n var dummyToNodeForVerticalAlignment = new Map();\n var dummyToNodeForHorizontalAlignment = new Map();\n var dummyPositionsForVerticalAlignment = new Map();\n var dummyPositionsForHorizontalAlignment = new Map();\n var fixedNodesOnHorizontal = new Set();\n var fixedNodesOnVertical = new Set();\n\n // fill maps and sets \n fixedNodes.forEach(function (nodeId) {\n fixedNodesOnHorizontal.add(nodeId);\n fixedNodesOnVertical.add(nodeId);\n });\n\n if (constraints.alignmentConstraint) {\n if (constraints.alignmentConstraint.vertical) {\n var verticalAlignment = constraints.alignmentConstraint.vertical;\n\n var _loop6 = function _loop6(_i11) {\n dummyToNodeForVerticalAlignment.set(\"dummy\" + _i11, []);\n verticalAlignment[_i11].forEach(function (nodeId) {\n nodeToDummyForVerticalAlignment.set(nodeId, \"dummy\" + _i11);\n dummyToNodeForVerticalAlignment.get(\"dummy\" + _i11).push(nodeId);\n if (fixedNodes.has(nodeId)) {\n fixedNodesOnHorizontal.add(\"dummy\" + _i11);\n }\n });\n dummyPositionsForVerticalAlignment.set(\"dummy\" + _i11, xCoords[nodeIndexes.get(verticalAlignment[_i11][0])]);\n };\n\n for (var _i11 = 0; _i11 < verticalAlignment.length; _i11++) {\n _loop6(_i11);\n }\n }\n if (constraints.alignmentConstraint.horizontal) {\n var horizontalAlignment = constraints.alignmentConstraint.horizontal;\n\n var _loop7 = function _loop7(_i12) {\n dummyToNodeForHorizontalAlignment.set(\"dummy\" + _i12, []);\n horizontalAlignment[_i12].forEach(function (nodeId) {\n nodeToDummyForHorizontalAlignment.set(nodeId, \"dummy\" + _i12);\n dummyToNodeForHorizontalAlignment.get(\"dummy\" + _i12).push(nodeId);\n if (fixedNodes.has(nodeId)) {\n fixedNodesOnVertical.add(\"dummy\" + _i12);\n }\n });\n dummyPositionsForHorizontalAlignment.set(\"dummy\" + _i12, yCoords[nodeIndexes.get(horizontalAlignment[_i12][0])]);\n };\n\n for (var _i12 = 0; _i12 < horizontalAlignment.length; _i12++) {\n _loop7(_i12);\n }\n }\n }\n\n // construct horizontal and vertical dags (subgraphs) from overall dag\n var dagOnHorizontal = new Map();\n var dagOnVertical = new Map();\n\n var _loop8 = function _loop8(nodeId) {\n dag.get(nodeId).forEach(function (adjacent) {\n var sourceId = void 0;\n var targetNode = void 0;\n if (adjacent[\"direction\"] == \"horizontal\") {\n sourceId = nodeToDummyForVerticalAlignment.get(nodeId) ? nodeToDummyForVerticalAlignment.get(nodeId) : nodeId;\n if (nodeToDummyForVerticalAlignment.get(adjacent.id)) {\n targetNode = { id: nodeToDummyForVerticalAlignment.get(adjacent.id), gap: adjacent.gap, direction: adjacent.direction };\n } else {\n targetNode = adjacent;\n }\n if (dagOnHorizontal.has(sourceId)) {\n dagOnHorizontal.get(sourceId).push(targetNode);\n } else {\n dagOnHorizontal.set(sourceId, [targetNode]);\n }\n if (!dagOnHorizontal.has(targetNode.id)) {\n dagOnHorizontal.set(targetNode.id, []);\n }\n } else {\n sourceId = nodeToDummyForHorizontalAlignment.get(nodeId) ? nodeToDummyForHorizontalAlignment.get(nodeId) : nodeId;\n if (nodeToDummyForHorizontalAlignment.get(adjacent.id)) {\n targetNode = { id: nodeToDummyForHorizontalAlignment.get(adjacent.id), gap: adjacent.gap, direction: adjacent.direction };\n } else {\n targetNode = adjacent;\n }\n if (dagOnVertical.has(sourceId)) {\n dagOnVertical.get(sourceId).push(targetNode);\n } else {\n dagOnVertical.set(sourceId, [targetNode]);\n }\n if (!dagOnVertical.has(targetNode.id)) {\n dagOnVertical.set(targetNode.id, []);\n }\n }\n });\n };\n\n var _iteratorNormalCompletion5 = true;\n var _didIteratorError5 = false;\n var _iteratorError5 = undefined;\n\n try {\n for (var _iterator5 = dag.keys()[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {\n var nodeId = _step5.value;\n\n _loop8(nodeId);\n }\n\n // find source nodes of each component in horizontal and vertical dags\n } catch (err) {\n _didIteratorError5 = true;\n _iteratorError5 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion5 && _iterator5.return) {\n _iterator5.return();\n }\n } finally {\n if (_didIteratorError5) {\n throw _iteratorError5;\n }\n }\n }\n\n var undirectedOnHorizontal = dagToUndirected(dagOnHorizontal);\n var undirectedOnVertical = dagToUndirected(dagOnVertical);\n var componentsOnHorizontal = findComponents(undirectedOnHorizontal);\n var componentsOnVertical = findComponents(undirectedOnVertical);\n var reversedDagOnHorizontal = dagToReversed(dagOnHorizontal);\n var reversedDagOnVertical = dagToReversed(dagOnVertical);\n var componentSourcesOnHorizontal = [];\n var componentSourcesOnVertical = [];\n\n componentsOnHorizontal.forEach(function (component, index) {\n componentSourcesOnHorizontal[index] = [];\n component.forEach(function (nodeId) {\n if (reversedDagOnHorizontal.get(nodeId).length == 0) {\n componentSourcesOnHorizontal[index].push(nodeId);\n }\n });\n });\n\n componentsOnVertical.forEach(function (component, index) {\n componentSourcesOnVertical[index] = [];\n component.forEach(function (nodeId) {\n if (reversedDagOnVertical.get(nodeId).length == 0) {\n componentSourcesOnVertical[index].push(nodeId);\n }\n });\n });\n\n // calculate appropriate positioning for subgraphs\n var positionMapHorizontal = findAppropriatePositionForRelativePlacement(dagOnHorizontal, \"horizontal\", fixedNodesOnHorizontal, dummyPositionsForVerticalAlignment, componentSourcesOnHorizontal);\n var positionMapVertical = findAppropriatePositionForRelativePlacement(dagOnVertical, \"vertical\", fixedNodesOnVertical, dummyPositionsForHorizontalAlignment, componentSourcesOnVertical);\n\n // update positions of the nodes based on relative placement constraints\n\n var _loop9 = function _loop9(key) {\n if (dummyToNodeForVerticalAlignment.get(key)) {\n dummyToNodeForVerticalAlignment.get(key).forEach(function (nodeId) {\n xCoords[nodeIndexes.get(nodeId)] = positionMapHorizontal.get(key);\n });\n } else {\n xCoords[nodeIndexes.get(key)] = positionMapHorizontal.get(key);\n }\n };\n\n var _iteratorNormalCompletion6 = true;\n var _didIteratorError6 = false;\n var _iteratorError6 = undefined;\n\n try {\n for (var _iterator6 = positionMapHorizontal.keys()[Symbol.iterator](), _step6; !(_iteratorNormalCompletion6 = (_step6 = _iterator6.next()).done); _iteratorNormalCompletion6 = true) {\n var key = _step6.value;\n\n _loop9(key);\n }\n } catch (err) {\n _didIteratorError6 = true;\n _iteratorError6 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion6 && _iterator6.return) {\n _iterator6.return();\n }\n } finally {\n if (_didIteratorError6) {\n throw _iteratorError6;\n }\n }\n }\n\n var _loop10 = function _loop10(key) {\n if (dummyToNodeForHorizontalAlignment.get(key)) {\n dummyToNodeForHorizontalAlignment.get(key).forEach(function (nodeId) {\n yCoords[nodeIndexes.get(nodeId)] = positionMapVertical.get(key);\n });\n } else {\n yCoords[nodeIndexes.get(key)] = positionMapVertical.get(key);\n }\n };\n\n var _iteratorNormalCompletion7 = true;\n var _didIteratorError7 = false;\n var _iteratorError7 = undefined;\n\n try {\n for (var _iterator7 = positionMapVertical.keys()[Symbol.iterator](), _step7; !(_iteratorNormalCompletion7 = (_step7 = _iterator7.next()).done); _iteratorNormalCompletion7 = true) {\n var key = _step7.value;\n\n _loop10(key);\n }\n } catch (err) {\n _didIteratorError7 = true;\n _iteratorError7 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion7 && _iterator7.return) {\n _iterator7.return();\n }\n } finally {\n if (_didIteratorError7) {\n throw _iteratorError7;\n }\n }\n }\n })();\n }\n }\n\n // assign new coordinates to nodes after constraint handling\n for (var _i13 = 0; _i13 < allNodes.length; _i13++) {\n var _node = allNodes[_i13];\n if (_node.getChild() == null) {\n _node.setCenter(xCoords[nodeIndexes.get(_node.id)], yCoords[nodeIndexes.get(_node.id)]);\n }\n }\n};\n\nmodule.exports = ConstraintHandler;\n\n/***/ }),\n\n/***/ 551:\n/***/ ((module) => {\n\nmodule.exports = __WEBPACK_EXTERNAL_MODULE__551__;\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \t\tif (cachedModule !== undefined) {\n/******/ \t\t\treturn cachedModule.exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \t// This entry module is referenced by other modules so it can't be inlined\n/******/ \tvar __webpack_exports__ = __webpack_require__(45);\n/******/ \t\n/******/ \treturn __webpack_exports__;\n/******/ })()\n;\n});", "(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"cose-base\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"cose-base\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"cytoscapeFcose\"] = factory(require(\"cose-base\"));\n\telse\n\t\troot[\"cytoscapeFcose\"] = factory(root[\"coseBase\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE__140__) {\nreturn /******/ (() => { // webpackBootstrap\n/******/ \t\"use strict\";\n/******/ \tvar __webpack_modules__ = ({\n\n/***/ 658:\n/***/ ((module) => {\n\n\n\n// Simple, internal Object.assign() polyfill for options objects etc.\n\nmodule.exports = Object.assign != null ? Object.assign.bind(Object) : function (tgt) {\n for (var _len = arguments.length, srcs = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n srcs[_key - 1] = arguments[_key];\n }\n\n srcs.forEach(function (src) {\n Object.keys(src).forEach(function (k) {\n return tgt[k] = src[k];\n });\n });\n\n return tgt;\n};\n\n/***/ }),\n\n/***/ 548:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i[\"return\"]) _i[\"return\"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError(\"Invalid attempt to destructure non-iterable instance\"); } }; }();\n\n/*\n * Auxiliary functions\n */\n\nvar LinkedList = __webpack_require__(140).layoutBase.LinkedList;\n\nvar auxiliary = {};\n\n// get the top most nodes\nauxiliary.getTopMostNodes = function (nodes) {\n var nodesMap = {};\n for (var i = 0; i < nodes.length; i++) {\n nodesMap[nodes[i].id()] = true;\n }\n var roots = nodes.filter(function (ele, i) {\n if (typeof ele === \"number\") {\n ele = i;\n }\n var parent = ele.parent()[0];\n while (parent != null) {\n if (nodesMap[parent.id()]) {\n return false;\n }\n parent = parent.parent()[0];\n }\n return true;\n });\n\n return roots;\n};\n\n// find disconnected components and create dummy nodes that connect them\nauxiliary.connectComponents = function (cy, eles, topMostNodes, dummyNodes) {\n var queue = new LinkedList();\n var visited = new Set();\n var visitedTopMostNodes = [];\n var currentNeighbor = void 0;\n var minDegreeNode = void 0;\n var minDegree = void 0;\n\n var isConnected = false;\n var count = 1;\n var nodesConnectedToDummy = [];\n var components = [];\n\n var _loop = function _loop() {\n var cmpt = cy.collection();\n components.push(cmpt);\n\n var currentNode = topMostNodes[0];\n var childrenOfCurrentNode = cy.collection();\n childrenOfCurrentNode.merge(currentNode).merge(currentNode.descendants().intersection(eles));\n visitedTopMostNodes.push(currentNode);\n\n childrenOfCurrentNode.forEach(function (node) {\n queue.push(node);\n visited.add(node);\n cmpt.merge(node);\n });\n\n var _loop2 = function _loop2() {\n currentNode = queue.shift();\n\n // Traverse all neighbors of this node\n var neighborNodes = cy.collection();\n currentNode.neighborhood().nodes().forEach(function (node) {\n if (eles.intersection(currentNode.edgesWith(node)).length > 0) {\n neighborNodes.merge(node);\n }\n });\n\n for (var i = 0; i < neighborNodes.length; i++) {\n var neighborNode = neighborNodes[i];\n currentNeighbor = topMostNodes.intersection(neighborNode.union(neighborNode.ancestors()));\n if (currentNeighbor != null && !visited.has(currentNeighbor[0])) {\n var childrenOfNeighbor = currentNeighbor.union(currentNeighbor.descendants());\n\n childrenOfNeighbor.forEach(function (node) {\n queue.push(node);\n visited.add(node);\n cmpt.merge(node);\n if (topMostNodes.has(node)) {\n visitedTopMostNodes.push(node);\n }\n });\n }\n }\n };\n\n while (queue.length != 0) {\n _loop2();\n }\n\n cmpt.forEach(function (node) {\n eles.intersection(node.connectedEdges()).forEach(function (e) {\n // connectedEdges() usually cached\n if (cmpt.has(e.source()) && cmpt.has(e.target())) {\n // has() is cheap\n cmpt.merge(e);\n }\n });\n });\n\n if (visitedTopMostNodes.length == topMostNodes.length) {\n isConnected = true;\n }\n\n if (!isConnected || isConnected && count > 1) {\n minDegreeNode = visitedTopMostNodes[0];\n minDegree = minDegreeNode.connectedEdges().length;\n visitedTopMostNodes.forEach(function (node) {\n if (node.connectedEdges().length < minDegree) {\n minDegree = node.connectedEdges().length;\n minDegreeNode = node;\n }\n });\n nodesConnectedToDummy.push(minDegreeNode.id());\n // TO DO: Check efficiency of this part\n var temp = cy.collection();\n temp.merge(visitedTopMostNodes[0]);\n visitedTopMostNodes.forEach(function (node) {\n temp.merge(node);\n });\n visitedTopMostNodes = [];\n topMostNodes = topMostNodes.difference(temp);\n count++;\n }\n };\n\n do {\n _loop();\n } while (!isConnected);\n\n if (dummyNodes) {\n if (nodesConnectedToDummy.length > 0) {\n dummyNodes.set('dummy' + (dummyNodes.size + 1), nodesConnectedToDummy);\n }\n }\n return components;\n};\n\n// relocates componentResult to originalCenter if there is no fixedNodeConstraint\nauxiliary.relocateComponent = function (originalCenter, componentResult, options) {\n if (!options.fixedNodeConstraint) {\n var minXCoord = Number.POSITIVE_INFINITY;\n var maxXCoord = Number.NEGATIVE_INFINITY;\n var minYCoord = Number.POSITIVE_INFINITY;\n var maxYCoord = Number.NEGATIVE_INFINITY;\n if (options.quality == \"draft\") {\n // calculate current bounding box\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = componentResult.nodeIndexes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var _ref = _step.value;\n\n var _ref2 = _slicedToArray(_ref, 2);\n\n var key = _ref2[0];\n var value = _ref2[1];\n\n var cyNode = options.cy.getElementById(key);\n if (cyNode) {\n var nodeBB = cyNode.boundingBox();\n var leftX = componentResult.xCoords[value] - nodeBB.w / 2;\n var rightX = componentResult.xCoords[value] + nodeBB.w / 2;\n var topY = componentResult.yCoords[value] - nodeBB.h / 2;\n var bottomY = componentResult.yCoords[value] + nodeBB.h / 2;\n\n if (leftX < minXCoord) minXCoord = leftX;\n if (rightX > maxXCoord) maxXCoord = rightX;\n if (topY < minYCoord) minYCoord = topY;\n if (bottomY > maxYCoord) maxYCoord = bottomY;\n }\n }\n // find difference between current and original center\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n var diffOnX = originalCenter.x - (maxXCoord + minXCoord) / 2;\n var diffOnY = originalCenter.y - (maxYCoord + minYCoord) / 2;\n // move component to original center\n componentResult.xCoords = componentResult.xCoords.map(function (x) {\n return x + diffOnX;\n });\n componentResult.yCoords = componentResult.yCoords.map(function (y) {\n return y + diffOnY;\n });\n } else {\n // calculate current bounding box\n Object.keys(componentResult).forEach(function (item) {\n var node = componentResult[item];\n var leftX = node.getRect().x;\n var rightX = node.getRect().x + node.getRect().width;\n var topY = node.getRect().y;\n var bottomY = node.getRect().y + node.getRect().height;\n\n if (leftX < minXCoord) minXCoord = leftX;\n if (rightX > maxXCoord) maxXCoord = rightX;\n if (topY < minYCoord) minYCoord = topY;\n if (bottomY > maxYCoord) maxYCoord = bottomY;\n });\n // find difference between current and original center\n var _diffOnX = originalCenter.x - (maxXCoord + minXCoord) / 2;\n var _diffOnY = originalCenter.y - (maxYCoord + minYCoord) / 2;\n // move component to original center\n Object.keys(componentResult).forEach(function (item) {\n var node = componentResult[item];\n node.setCenter(node.getCenterX() + _diffOnX, node.getCenterY() + _diffOnY);\n });\n }\n }\n};\n\nauxiliary.calcBoundingBox = function (parentNode, xCoords, yCoords, nodeIndexes) {\n // calculate bounds\n var left = Number.MAX_SAFE_INTEGER;\n var right = Number.MIN_SAFE_INTEGER;\n var top = Number.MAX_SAFE_INTEGER;\n var bottom = Number.MIN_SAFE_INTEGER;\n var nodeLeft = void 0;\n var nodeRight = void 0;\n var nodeTop = void 0;\n var nodeBottom = void 0;\n\n var nodes = parentNode.descendants().not(\":parent\");\n var s = nodes.length;\n for (var i = 0; i < s; i++) {\n var node = nodes[i];\n\n nodeLeft = xCoords[nodeIndexes.get(node.id())] - node.width() / 2;\n nodeRight = xCoords[nodeIndexes.get(node.id())] + node.width() / 2;\n nodeTop = yCoords[nodeIndexes.get(node.id())] - node.height() / 2;\n nodeBottom = yCoords[nodeIndexes.get(node.id())] + node.height() / 2;\n\n if (left > nodeLeft) {\n left = nodeLeft;\n }\n\n if (right < nodeRight) {\n right = nodeRight;\n }\n\n if (top > nodeTop) {\n top = nodeTop;\n }\n\n if (bottom < nodeBottom) {\n bottom = nodeBottom;\n }\n }\n\n var boundingBox = {};\n boundingBox.topLeftX = left;\n boundingBox.topLeftY = top;\n boundingBox.width = right - left;\n boundingBox.height = bottom - top;\n return boundingBox;\n};\n\n// This function finds and returns parent nodes whose all children are hidden\nauxiliary.calcParentsWithoutChildren = function (cy, eles) {\n var parentsWithoutChildren = cy.collection();\n eles.nodes(':parent').forEach(function (parent) {\n var check = false;\n parent.children().forEach(function (child) {\n if (child.css('display') != 'none') {\n check = true;\n }\n });\n if (!check) {\n parentsWithoutChildren.merge(parent);\n }\n });\n\n return parentsWithoutChildren;\n};\n\nmodule.exports = auxiliary;\n\n/***/ }),\n\n/***/ 816:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\n/**\n The implementation of the postprocessing part that applies CoSE layout over the spectral layout\n*/\n\nvar aux = __webpack_require__(548);\nvar CoSELayout = __webpack_require__(140).CoSELayout;\nvar CoSENode = __webpack_require__(140).CoSENode;\nvar PointD = __webpack_require__(140).layoutBase.PointD;\nvar DimensionD = __webpack_require__(140).layoutBase.DimensionD;\nvar LayoutConstants = __webpack_require__(140).layoutBase.LayoutConstants;\nvar FDLayoutConstants = __webpack_require__(140).layoutBase.FDLayoutConstants;\nvar CoSEConstants = __webpack_require__(140).CoSEConstants;\n\n// main function that cose layout is processed\nvar coseLayout = function coseLayout(options, spectralResult) {\n\n var cy = options.cy;\n var eles = options.eles;\n var nodes = eles.nodes();\n var edges = eles.edges();\n\n var nodeIndexes = void 0;\n var xCoords = void 0;\n var yCoords = void 0;\n var idToLNode = {};\n\n if (options.randomize) {\n nodeIndexes = spectralResult[\"nodeIndexes\"];\n xCoords = spectralResult[\"xCoords\"];\n yCoords = spectralResult[\"yCoords\"];\n }\n\n var isFn = function isFn(fn) {\n return typeof fn === 'function';\n };\n\n var optFn = function optFn(opt, ele) {\n if (isFn(opt)) {\n return opt(ele);\n } else {\n return opt;\n }\n };\n\n /**** Postprocessing functions ****/\n\n var parentsWithoutChildren = aux.calcParentsWithoutChildren(cy, eles);\n\n // transfer cytoscape nodes to cose nodes\n var processChildrenList = function processChildrenList(parent, children, layout, options) {\n var size = children.length;\n for (var i = 0; i < size; i++) {\n var theChild = children[i];\n var children_of_children = null;\n if (theChild.intersection(parentsWithoutChildren).length == 0) {\n children_of_children = theChild.children();\n }\n var theNode = void 0;\n\n var dimensions = theChild.layoutDimensions({\n nodeDimensionsIncludeLabels: options.nodeDimensionsIncludeLabels\n });\n\n if (theChild.outerWidth() != null && theChild.outerHeight() != null) {\n if (options.randomize) {\n if (!theChild.isParent()) {\n theNode = parent.add(new CoSENode(layout.graphManager, new PointD(xCoords[nodeIndexes.get(theChild.id())] - dimensions.w / 2, yCoords[nodeIndexes.get(theChild.id())] - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));\n } else {\n var parentInfo = aux.calcBoundingBox(theChild, xCoords, yCoords, nodeIndexes);\n if (theChild.intersection(parentsWithoutChildren).length == 0) {\n theNode = parent.add(new CoSENode(layout.graphManager, new PointD(parentInfo.topLeftX, parentInfo.topLeftY), new DimensionD(parentInfo.width, parentInfo.height)));\n } else {\n // for the parentsWithoutChildren\n theNode = parent.add(new CoSENode(layout.graphManager, new PointD(parentInfo.topLeftX, parentInfo.topLeftY), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));\n }\n }\n } else {\n theNode = parent.add(new CoSENode(layout.graphManager, new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));\n }\n } else {\n theNode = parent.add(new CoSENode(this.graphManager));\n }\n // Attach id to the layout node and repulsion value\n theNode.id = theChild.data(\"id\");\n theNode.nodeRepulsion = optFn(options.nodeRepulsion, theChild);\n // Attach the paddings of cy node to layout node\n theNode.paddingLeft = parseInt(theChild.css('padding'));\n theNode.paddingTop = parseInt(theChild.css('padding'));\n theNode.paddingRight = parseInt(theChild.css('padding'));\n theNode.paddingBottom = parseInt(theChild.css('padding'));\n\n //Attach the label properties to both compound and simple nodes if labels will be included in node dimensions\n //These properties will be used while updating bounds of compounds during iterations or tiling\n //and will be used for simple nodes while transferring final positions to cytoscape\n if (options.nodeDimensionsIncludeLabels) {\n theNode.labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false, includeOverlays: false }).w;\n theNode.labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false, includeOverlays: false }).h;\n theNode.labelPosVertical = theChild.css(\"text-valign\");\n theNode.labelPosHorizontal = theChild.css(\"text-halign\");\n }\n\n // Map the layout node\n idToLNode[theChild.data(\"id\")] = theNode;\n\n if (isNaN(theNode.rect.x)) {\n theNode.rect.x = 0;\n }\n\n if (isNaN(theNode.rect.y)) {\n theNode.rect.y = 0;\n }\n\n if (children_of_children != null && children_of_children.length > 0) {\n var theNewGraph = void 0;\n theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode);\n processChildrenList(theNewGraph, children_of_children, layout, options);\n }\n }\n };\n\n // transfer cytoscape edges to cose edges\n var processEdges = function processEdges(layout, gm, edges) {\n var idealLengthTotal = 0;\n var edgeCount = 0;\n for (var i = 0; i < edges.length; i++) {\n var edge = edges[i];\n var sourceNode = idToLNode[edge.data(\"source\")];\n var targetNode = idToLNode[edge.data(\"target\")];\n if (sourceNode && targetNode && sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) {\n var e1 = gm.add(layout.newEdge(), sourceNode, targetNode);\n e1.id = edge.id();\n e1.idealLength = optFn(options.idealEdgeLength, edge);\n e1.edgeElasticity = optFn(options.edgeElasticity, edge);\n idealLengthTotal += e1.idealLength;\n edgeCount++;\n }\n }\n // we need to update the ideal edge length constant with the avg. ideal length value after processing edges\n // in case there is no edge, use other options\n if (options.idealEdgeLength != null) {\n if (edgeCount > 0) CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = idealLengthTotal / edgeCount;else if (!isFn(options.idealEdgeLength)) // in case there is no edge, but option gives a value to use\n CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength;else // in case there is no edge and we cannot get a value from option (because it's a function)\n CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = 50;\n // we need to update these constant values based on the ideal edge length constant\n CoSEConstants.MIN_REPULSION_DIST = FDLayoutConstants.MIN_REPULSION_DIST = FDLayoutConstants.DEFAULT_EDGE_LENGTH / 10.0;\n CoSEConstants.DEFAULT_RADIAL_SEPARATION = FDLayoutConstants.DEFAULT_EDGE_LENGTH;\n }\n };\n\n // transfer cytoscape constraints to cose layout\n var processConstraints = function processConstraints(layout, options) {\n // get nodes to be fixed\n if (options.fixedNodeConstraint) {\n layout.constraints[\"fixedNodeConstraint\"] = options.fixedNodeConstraint;\n }\n // get nodes to be aligned\n if (options.alignmentConstraint) {\n layout.constraints[\"alignmentConstraint\"] = options.alignmentConstraint;\n }\n // get nodes to be relatively placed\n if (options.relativePlacementConstraint) {\n layout.constraints[\"relativePlacementConstraint\"] = options.relativePlacementConstraint;\n }\n };\n\n /**** Apply postprocessing ****/\n if (options.nestingFactor != null) CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor;\n if (options.gravity != null) CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity;\n if (options.numIter != null) CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter;\n if (options.gravityRange != null) CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange;\n if (options.gravityCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound;\n if (options.gravityRangeCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound;\n if (options.initialEnergyOnIncremental != null) CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental;\n\n if (options.tilingCompareBy != null) CoSEConstants.TILING_COMPARE_BY = options.tilingCompareBy;\n\n if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 0;\n\n CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels;\n CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = !options.randomize;\n CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate;\n CoSEConstants.TILE = options.tile;\n CoSEConstants.TILING_PADDING_VERTICAL = typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical;\n CoSEConstants.TILING_PADDING_HORIZONTAL = typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal;\n\n CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = true;\n CoSEConstants.PURE_INCREMENTAL = !options.randomize;\n LayoutConstants.DEFAULT_UNIFORM_LEAF_NODE_SIZES = options.uniformNodeDimensions;\n\n // This part is for debug/demo purpose\n if (options.step == \"transformed\") {\n CoSEConstants.TRANSFORM_ON_CONSTRAINT_HANDLING = true;\n CoSEConstants.ENFORCE_CONSTRAINTS = false;\n CoSEConstants.APPLY_LAYOUT = false;\n }\n if (options.step == \"enforced\") {\n CoSEConstants.TRANSFORM_ON_CONSTRAINT_HANDLING = false;\n CoSEConstants.ENFORCE_CONSTRAINTS = true;\n CoSEConstants.APPLY_LAYOUT = false;\n }\n if (options.step == \"cose\") {\n CoSEConstants.TRANSFORM_ON_CONSTRAINT_HANDLING = false;\n CoSEConstants.ENFORCE_CONSTRAINTS = false;\n CoSEConstants.APPLY_LAYOUT = true;\n }\n if (options.step == \"all\") {\n if (options.randomize) CoSEConstants.TRANSFORM_ON_CONSTRAINT_HANDLING = true;else CoSEConstants.TRANSFORM_ON_CONSTRAINT_HANDLING = false;\n CoSEConstants.ENFORCE_CONSTRAINTS = true;\n CoSEConstants.APPLY_LAYOUT = true;\n }\n\n if (options.fixedNodeConstraint || options.alignmentConstraint || options.relativePlacementConstraint) {\n CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = false;\n } else {\n CoSEConstants.TREE_REDUCTION_ON_INCREMENTAL = true;\n }\n\n var coseLayout = new CoSELayout();\n var gm = coseLayout.newGraphManager();\n\n processChildrenList(gm.addRoot(), aux.getTopMostNodes(nodes), coseLayout, options);\n processEdges(coseLayout, gm, edges);\n processConstraints(coseLayout, options);\n\n coseLayout.runLayout();\n\n return idToLNode;\n};\n\nmodule.exports = { coseLayout: coseLayout };\n\n/***/ }),\n\n/***/ 212:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (\"value\" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();\n\nfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\n/**\n The implementation of the fcose layout algorithm\n*/\n\nvar assign = __webpack_require__(658);\nvar aux = __webpack_require__(548);\n\nvar _require = __webpack_require__(657),\n spectralLayout = _require.spectralLayout;\n\nvar _require2 = __webpack_require__(816),\n coseLayout = _require2.coseLayout;\n\nvar defaults = Object.freeze({\n\n // 'draft', 'default' or 'proof' \n // - 'draft' only applies spectral layout \n // - 'default' improves the quality with subsequent CoSE layout (fast cooling rate)\n // - 'proof' improves the quality with subsequent CoSE layout (slow cooling rate) \n quality: \"default\",\n // Use random node positions at beginning of layout\n // if this is set to false, then quality option must be \"proof\"\n randomize: true,\n // Whether or not to animate the layout\n animate: true,\n // Duration of animation in ms, if enabled\n animationDuration: 1000,\n // Easing of animation, if enabled\n animationEasing: undefined,\n // Fit the viewport to the repositioned nodes\n fit: true,\n // Padding around layout\n padding: 30,\n // Whether to include labels in node dimensions. Valid in \"proof\" quality\n nodeDimensionsIncludeLabels: false,\n // Whether or not simple nodes (non-compound nodes) are of uniform dimensions\n uniformNodeDimensions: false,\n // Whether to pack disconnected components - valid only if randomize: true\n packComponents: true,\n // Layout step - all, transformed, enforced, cose - for debug purpose only\n step: \"all\",\n\n /* spectral layout options */\n\n // False for random, true for greedy\n samplingType: true,\n // Sample size to construct distance matrix\n sampleSize: 25,\n // Separation amount between nodes\n nodeSeparation: 75,\n // Power iteration tolerance\n piTol: 0.0000001,\n\n /* CoSE layout options */\n\n // Node repulsion (non overlapping) multiplier\n nodeRepulsion: function nodeRepulsion(node) {\n return 4500;\n },\n // Ideal edge (non nested) length\n idealEdgeLength: function idealEdgeLength(edge) {\n return 50;\n },\n // Divisor to compute edge forces\n edgeElasticity: function edgeElasticity(edge) {\n return 0.45;\n },\n // Nesting factor (multiplier) to compute ideal edge length for nested edges\n nestingFactor: 0.1,\n // Gravity force (constant)\n gravity: 0.25,\n // Maximum number of iterations to perform\n numIter: 2500,\n // For enabling tiling\n tile: true,\n // The function that specifies the criteria for comparing nodes while sorting them during tiling operation.\n // Takes the node id as a parameter and the default tiling operation is perfomed when this option is not set.\n tilingCompareBy: undefined,\n // Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)\n tilingPaddingVertical: 10,\n // Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function)\n tilingPaddingHorizontal: 10,\n // Gravity range (constant) for compounds\n gravityRangeCompound: 1.5,\n // Gravity force (constant) for compounds\n gravityCompound: 1.0,\n // Gravity range (constant)\n gravityRange: 3.8,\n // Initial cooling factor for incremental layout \n initialEnergyOnIncremental: 0.3,\n\n /* constraint options */\n\n // Fix required nodes to predefined positions\n // [{nodeId: 'n1', position: {x: 100, y: 200}, {...}]\n fixedNodeConstraint: undefined,\n // Align required nodes in vertical/horizontal direction\n // {vertical: [['n1', 'n2')], ['n3', 'n4']], horizontal: ['n2', 'n4']}\n alignmentConstraint: undefined,\n // Place two nodes relatively in vertical/horizontal direction \n // [{top: 'n1', bottom: 'n2', gap: 100}, {left: 'n3', right: 'n4', gap: 75}]\n relativePlacementConstraint: undefined,\n\n /* layout event callbacks */\n ready: function ready() {}, // on layoutready\n stop: function stop() {} // on layoutstop\n});\n\nvar Layout = function () {\n function Layout(options) {\n _classCallCheck(this, Layout);\n\n this.options = assign({}, defaults, options);\n }\n\n _createClass(Layout, [{\n key: 'run',\n value: function run() {\n var layout = this;\n var options = this.options;\n var cy = options.cy;\n var eles = options.eles;\n\n var spectralResult = [];\n var xCoords = void 0;\n var yCoords = void 0;\n var coseResult = [];\n var components = void 0;\n var componentCenters = [];\n\n // basic validity check for constraint inputs \n if (options.fixedNodeConstraint && (!Array.isArray(options.fixedNodeConstraint) || options.fixedNodeConstraint.length == 0)) {\n options.fixedNodeConstraint = undefined;\n }\n\n if (options.alignmentConstraint) {\n if (options.alignmentConstraint.vertical && (!Array.isArray(options.alignmentConstraint.vertical) || options.alignmentConstraint.vertical.length == 0)) {\n options.alignmentConstraint.vertical = undefined;\n }\n if (options.alignmentConstraint.horizontal && (!Array.isArray(options.alignmentConstraint.horizontal) || options.alignmentConstraint.horizontal.length == 0)) {\n options.alignmentConstraint.horizontal = undefined;\n }\n }\n\n if (options.relativePlacementConstraint && (!Array.isArray(options.relativePlacementConstraint) || options.relativePlacementConstraint.length == 0)) {\n options.relativePlacementConstraint = undefined;\n }\n\n // if any constraint exists, set some options\n var constraintExist = options.fixedNodeConstraint || options.alignmentConstraint || options.relativePlacementConstraint;\n if (constraintExist) {\n // constraints work with these options\n options.tile = false;\n options.packComponents = false;\n }\n\n // decide component packing is enabled or not\n var layUtil = void 0;\n var packingEnabled = false;\n if (cy.layoutUtilities && options.packComponents) {\n layUtil = cy.layoutUtilities(\"get\");\n if (!layUtil) layUtil = cy.layoutUtilities();\n packingEnabled = true;\n }\n\n if (eles.nodes().length > 0) {\n // if packing is not enabled, perform layout on the whole graph\n if (!packingEnabled) {\n // store component center\n var boundingBox = options.eles.boundingBox();\n componentCenters.push({ x: boundingBox.x1 + boundingBox.w / 2, y: boundingBox.y1 + boundingBox.h / 2 });\n // apply spectral layout\n if (options.randomize) {\n var result = spectralLayout(options);\n spectralResult.push(result);\n }\n // apply cose layout as postprocessing\n if (options.quality == \"default\" || options.quality == \"proof\") {\n coseResult.push(coseLayout(options, spectralResult[0]));\n aux.relocateComponent(componentCenters[0], coseResult[0], options); // relocate center to original position\n } else {\n aux.relocateComponent(componentCenters[0], spectralResult[0], options); // relocate center to original position\n }\n } else {\n // packing is enabled\n var topMostNodes = aux.getTopMostNodes(options.eles.nodes());\n components = aux.connectComponents(cy, options.eles, topMostNodes);\n // store component centers\n components.forEach(function (component) {\n var boundingBox = component.boundingBox();\n componentCenters.push({ x: boundingBox.x1 + boundingBox.w / 2, y: boundingBox.y1 + boundingBox.h / 2 });\n });\n\n //send each component to spectral layout if randomized\n if (options.randomize) {\n components.forEach(function (component) {\n options.eles = component;\n spectralResult.push(spectralLayout(options));\n });\n }\n\n if (options.quality == \"default\" || options.quality == \"proof\") {\n var toBeTiledNodes = cy.collection();\n if (options.tile) {\n // behave nodes to be tiled as one component\n var nodeIndexes = new Map();\n var _xCoords = [];\n var _yCoords = [];\n var count = 0;\n var tempSpectralResult = { nodeIndexes: nodeIndexes, xCoords: _xCoords, yCoords: _yCoords };\n var indexesToBeDeleted = [];\n components.forEach(function (component, index) {\n if (component.edges().length == 0) {\n component.nodes().forEach(function (node, i) {\n toBeTiledNodes.merge(component.nodes()[i]);\n if (!node.isParent()) {\n tempSpectralResult.nodeIndexes.set(component.nodes()[i].id(), count++);\n tempSpectralResult.xCoords.push(component.nodes()[0].position().x);\n tempSpectralResult.yCoords.push(component.nodes()[0].position().y);\n }\n });\n indexesToBeDeleted.push(index);\n }\n });\n if (toBeTiledNodes.length > 1) {\n var _boundingBox = toBeTiledNodes.boundingBox();\n componentCenters.push({ x: _boundingBox.x1 + _boundingBox.w / 2, y: _boundingBox.y1 + _boundingBox.h / 2 });\n components.push(toBeTiledNodes);\n spectralResult.push(tempSpectralResult);\n for (var i = indexesToBeDeleted.length - 1; i >= 0; i--) {\n components.splice(indexesToBeDeleted[i], 1);\n spectralResult.splice(indexesToBeDeleted[i], 1);\n componentCenters.splice(indexesToBeDeleted[i], 1);\n };\n }\n }\n components.forEach(function (component, index) {\n // send each component to cose layout\n options.eles = component;\n coseResult.push(coseLayout(options, spectralResult[index]));\n aux.relocateComponent(componentCenters[index], coseResult[index], options); // relocate center to original position\n });\n } else {\n components.forEach(function (component, index) {\n aux.relocateComponent(componentCenters[index], spectralResult[index], options); // relocate center to original position\n });\n }\n\n // packing\n var componentsEvaluated = new Set();\n if (components.length > 1) {\n var subgraphs = [];\n var hiddenEles = eles.filter(function (ele) {\n return ele.css('display') == 'none';\n });\n components.forEach(function (component, index) {\n var nodeIndexes = void 0;\n if (options.quality == \"draft\") {\n nodeIndexes = spectralResult[index].nodeIndexes;\n }\n\n if (component.nodes().not(hiddenEles).length > 0) {\n var subgraph = {};\n subgraph.edges = [];\n subgraph.nodes = [];\n var nodeIndex = void 0;\n component.nodes().not(hiddenEles).forEach(function (node) {\n if (options.quality == \"draft\") {\n if (!node.isParent()) {\n nodeIndex = nodeIndexes.get(node.id());\n subgraph.nodes.push({ x: spectralResult[index].xCoords[nodeIndex] - node.boundingbox().w / 2, y: spectralResult[index].yCoords[nodeIndex] - node.boundingbox().h / 2, width: node.boundingbox().w, height: node.boundingbox().h });\n } else {\n var parentInfo = aux.calcBoundingBox(node, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);\n subgraph.nodes.push({ x: parentInfo.topLeftX, y: parentInfo.topLeftY, width: parentInfo.width, height: parentInfo.height });\n }\n } else {\n if (coseResult[index][node.id()]) {\n subgraph.nodes.push({ x: coseResult[index][node.id()].getLeft(), y: coseResult[index][node.id()].getTop(), width: coseResult[index][node.id()].getWidth(), height: coseResult[index][node.id()].getHeight() });\n }\n }\n });\n component.edges().forEach(function (edge) {\n var source = edge.source();\n var target = edge.target();\n if (source.css(\"display\") != \"none\" && target.css(\"display\") != \"none\") {\n if (options.quality == \"draft\") {\n var sourceNodeIndex = nodeIndexes.get(source.id());\n var targetNodeIndex = nodeIndexes.get(target.id());\n var sourceCenter = [];\n var targetCenter = [];\n if (source.isParent()) {\n var parentInfo = aux.calcBoundingBox(source, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);\n sourceCenter.push(parentInfo.topLeftX + parentInfo.width / 2);\n sourceCenter.push(parentInfo.topLeftY + parentInfo.height / 2);\n } else {\n sourceCenter.push(spectralResult[index].xCoords[sourceNodeIndex]);\n sourceCenter.push(spectralResult[index].yCoords[sourceNodeIndex]);\n }\n if (target.isParent()) {\n var _parentInfo = aux.calcBoundingBox(target, spectralResult[index].xCoords, spectralResult[index].yCoords, nodeIndexes);\n targetCenter.push(_parentInfo.topLeftX + _parentInfo.width / 2);\n targetCenter.push(_parentInfo.topLeftY + _parentInfo.height / 2);\n } else {\n targetCenter.push(spectralResult[index].xCoords[targetNodeIndex]);\n targetCenter.push(spectralResult[index].yCoords[targetNodeIndex]);\n }\n subgraph.edges.push({ startX: sourceCenter[0], startY: sourceCenter[1], endX: targetCenter[0], endY: targetCenter[1] });\n } else {\n if (coseResult[index][source.id()] && coseResult[index][target.id()]) {\n subgraph.edges.push({ startX: coseResult[index][source.id()].getCenterX(), startY: coseResult[index][source.id()].getCenterY(), endX: coseResult[index][target.id()].getCenterX(), endY: coseResult[index][target.id()].getCenterY() });\n }\n }\n }\n });\n if (subgraph.nodes.length > 0) {\n subgraphs.push(subgraph);\n componentsEvaluated.add(index);\n }\n }\n });\n var shiftResult = layUtil.packComponents(subgraphs, options.randomize).shifts;\n if (options.quality == \"draft\") {\n spectralResult.forEach(function (result, index) {\n var newXCoords = result.xCoords.map(function (x) {\n return x + shiftResult[index].dx;\n });\n var newYCoords = result.yCoords.map(function (y) {\n return y + shiftResult[index].dy;\n });\n result.xCoords = newXCoords;\n result.yCoords = newYCoords;\n });\n } else {\n var _count = 0;\n componentsEvaluated.forEach(function (index) {\n Object.keys(coseResult[index]).forEach(function (item) {\n var nodeRectangle = coseResult[index][item];\n nodeRectangle.setCenter(nodeRectangle.getCenterX() + shiftResult[_count].dx, nodeRectangle.getCenterY() + shiftResult[_count].dy);\n });\n _count++;\n });\n }\n }\n }\n }\n\n // get each element's calculated position\n var getPositions = function getPositions(ele, i) {\n if (options.quality == \"default\" || options.quality == \"proof\") {\n if (typeof ele === \"number\") {\n ele = i;\n }\n var pos = void 0;\n var node = void 0;\n var theId = ele.data('id');\n coseResult.forEach(function (result) {\n if (theId in result) {\n pos = { x: result[theId].getRect().getCenterX(), y: result[theId].getRect().getCenterY() };\n node = result[theId];\n }\n });\n if (options.nodeDimensionsIncludeLabels) {\n if (node.labelWidth) {\n if (node.labelPosHorizontal == \"left\") {\n pos.x += node.labelWidth / 2;\n } else if (node.labelPosHorizontal == \"right\") {\n pos.x -= node.labelWidth / 2;\n }\n }\n if (node.labelHeight) {\n if (node.labelPosVertical == \"top\") {\n pos.y += node.labelHeight / 2;\n } else if (node.labelPosVertical == \"bottom\") {\n pos.y -= node.labelHeight / 2;\n }\n }\n }\n if (pos == undefined) pos = { x: ele.position(\"x\"), y: ele.position(\"y\") };\n return {\n x: pos.x,\n y: pos.y\n };\n } else {\n var _pos = void 0;\n spectralResult.forEach(function (result) {\n var index = result.nodeIndexes.get(ele.id());\n if (index != undefined) {\n _pos = { x: result.xCoords[index], y: result.yCoords[index] };\n }\n });\n if (_pos == undefined) _pos = { x: ele.position(\"x\"), y: ele.position(\"y\") };\n return {\n x: _pos.x,\n y: _pos.y\n };\n }\n };\n\n // quality = \"draft\" and randomize = false are contradictive so in that case positions don't change\n if (options.quality == \"default\" || options.quality == \"proof\" || options.randomize) {\n // transfer calculated positions to nodes (positions of only simple nodes are evaluated, compounds are positioned automatically)\n var parentsWithoutChildren = aux.calcParentsWithoutChildren(cy, eles);\n var _hiddenEles = eles.filter(function (ele) {\n return ele.css('display') == 'none';\n });\n options.eles = eles.not(_hiddenEles);\n\n eles.nodes().not(\":parent\").not(_hiddenEles).layoutPositions(layout, options, getPositions);\n\n if (parentsWithoutChildren.length > 0) {\n parentsWithoutChildren.forEach(function (ele) {\n ele.position(getPositions(ele));\n });\n }\n } else {\n console.log(\"If randomize option is set to false, then quality option must be 'default' or 'proof'.\");\n }\n }\n }]);\n\n return Layout;\n}();\n\nmodule.exports = Layout;\n\n/***/ }),\n\n/***/ 657:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\n/**\n The implementation of the spectral layout that is the first part of the fcose layout algorithm\n*/\n\nvar aux = __webpack_require__(548);\nvar Matrix = __webpack_require__(140).layoutBase.Matrix;\nvar SVD = __webpack_require__(140).layoutBase.SVD;\n\n// main function that spectral layout is processed\nvar spectralLayout = function spectralLayout(options) {\n\n var cy = options.cy;\n var eles = options.eles;\n var nodes = eles.nodes();\n var parentNodes = eles.nodes(\":parent\");\n\n var dummyNodes = new Map(); // map to keep dummy nodes and their neighbors\n var nodeIndexes = new Map(); // map to keep indexes to nodes\n var parentChildMap = new Map(); // mapping btw. compound and its representative node \n var allNodesNeighborhood = []; // array to keep neighborhood of all nodes\n var xCoords = [];\n var yCoords = [];\n\n var samplesColumn = []; // sampled vertices\n var minDistancesColumn = [];\n var C = []; // column sampling matrix\n var PHI = []; // intersection of column and row sampling matrices \n var INV = []; // inverse of PHI \n\n var firstSample = void 0; // the first sampled node\n var nodeSize = void 0;\n\n var infinity = 100000000;\n var small = 0.000000001;\n\n var piTol = options.piTol;\n var samplingType = options.samplingType; // false for random, true for greedy\n var nodeSeparation = options.nodeSeparation;\n var sampleSize = void 0;\n\n /**** Spectral-preprocessing functions ****/\n\n /**** Spectral layout functions ****/\n\n // determine which columns to be sampled\n var randomSampleCR = function randomSampleCR() {\n var sample = 0;\n var count = 0;\n var flag = false;\n\n while (count < sampleSize) {\n sample = Math.floor(Math.random() * nodeSize);\n\n flag = false;\n for (var i = 0; i < count; i++) {\n if (samplesColumn[i] == sample) {\n flag = true;\n break;\n }\n }\n\n if (!flag) {\n samplesColumn[count] = sample;\n count++;\n } else {\n continue;\n }\n }\n };\n\n // takes the index of the node(pivot) to initiate BFS as a parameter\n var BFS = function BFS(pivot, index, samplingMethod) {\n var path = []; // the front of the path\n var front = 0; // the back of the path\n var back = 0;\n var current = 0;\n var temp = void 0;\n var distance = [];\n\n var max_dist = 0; // the furthest node to be returned\n var max_ind = 1;\n\n for (var i = 0; i < nodeSize; i++) {\n distance[i] = infinity;\n }\n\n path[back] = pivot;\n distance[pivot] = 0;\n\n while (back >= front) {\n current = path[front++];\n var neighbors = allNodesNeighborhood[current];\n for (var _i = 0; _i < neighbors.length; _i++) {\n temp = nodeIndexes.get(neighbors[_i]);\n if (distance[temp] == infinity) {\n distance[temp] = distance[current] + 1;\n path[++back] = temp;\n }\n }\n C[current][index] = distance[current] * nodeSeparation;\n }\n\n if (samplingMethod) {\n for (var _i2 = 0; _i2 < nodeSize; _i2++) {\n if (C[_i2][index] < minDistancesColumn[_i2]) minDistancesColumn[_i2] = C[_i2][index];\n }\n\n for (var _i3 = 0; _i3 < nodeSize; _i3++) {\n if (minDistancesColumn[_i3] > max_dist) {\n max_dist = minDistancesColumn[_i3];\n max_ind = _i3;\n }\n }\n }\n return max_ind;\n };\n\n // apply BFS to all nodes or selected samples\n var allBFS = function allBFS(samplingMethod) {\n\n var sample = void 0;\n\n if (!samplingMethod) {\n randomSampleCR();\n\n // call BFS\n for (var i = 0; i < sampleSize; i++) {\n BFS(samplesColumn[i], i, samplingMethod, false);\n }\n } else {\n sample = Math.floor(Math.random() * nodeSize);\n firstSample = sample;\n\n for (var _i4 = 0; _i4 < nodeSize; _i4++) {\n minDistancesColumn[_i4] = infinity;\n }\n\n for (var _i5 = 0; _i5 < sampleSize; _i5++) {\n samplesColumn[_i5] = sample;\n sample = BFS(sample, _i5, samplingMethod);\n }\n }\n\n // form the squared distances for C\n for (var _i6 = 0; _i6 < nodeSize; _i6++) {\n for (var j = 0; j < sampleSize; j++) {\n C[_i6][j] *= C[_i6][j];\n }\n }\n\n // form PHI\n for (var _i7 = 0; _i7 < sampleSize; _i7++) {\n PHI[_i7] = [];\n }\n\n for (var _i8 = 0; _i8 < sampleSize; _i8++) {\n for (var _j = 0; _j < sampleSize; _j++) {\n PHI[_i8][_j] = C[samplesColumn[_j]][_i8];\n }\n }\n };\n\n // perform the SVD algorithm and apply a regularization step\n var sample = function sample() {\n\n var SVDResult = SVD.svd(PHI);\n\n var a_q = SVDResult.S;\n var a_u = SVDResult.U;\n var a_v = SVDResult.V;\n\n var max_s = a_q[0] * a_q[0] * a_q[0];\n\n var a_Sig = [];\n\n // regularization\n for (var i = 0; i < sampleSize; i++) {\n a_Sig[i] = [];\n for (var j = 0; j < sampleSize; j++) {\n a_Sig[i][j] = 0;\n if (i == j) {\n a_Sig[i][j] = a_q[i] / (a_q[i] * a_q[i] + max_s / (a_q[i] * a_q[i]));\n }\n }\n }\n\n INV = Matrix.multMat(Matrix.multMat(a_v, a_Sig), Matrix.transpose(a_u));\n };\n\n // calculate final coordinates \n var powerIteration = function powerIteration() {\n // two largest eigenvalues\n var theta1 = void 0;\n var theta2 = void 0;\n\n // initial guesses for eigenvectors\n var Y1 = [];\n var Y2 = [];\n\n var V1 = [];\n var V2 = [];\n\n for (var i = 0; i < nodeSize; i++) {\n Y1[i] = Math.random();\n Y2[i] = Math.random();\n }\n\n Y1 = Matrix.normalize(Y1);\n Y2 = Matrix.normalize(Y2);\n\n var count = 0;\n // to keep track of the improvement ratio in power iteration\n var current = small;\n var previous = small;\n\n var temp = void 0;\n\n while (true) {\n count++;\n\n for (var _i9 = 0; _i9 < nodeSize; _i9++) {\n V1[_i9] = Y1[_i9];\n }\n\n Y1 = Matrix.multGamma(Matrix.multL(Matrix.multGamma(V1), C, INV));\n theta1 = Matrix.dotProduct(V1, Y1);\n Y1 = Matrix.normalize(Y1);\n\n current = Matrix.dotProduct(V1, Y1);\n\n temp = Math.abs(current / previous);\n\n if (temp <= 1 + piTol && temp >= 1) {\n break;\n }\n\n previous = current;\n }\n\n for (var _i10 = 0; _i10 < nodeSize; _i10++) {\n V1[_i10] = Y1[_i10];\n }\n\n count = 0;\n previous = small;\n while (true) {\n count++;\n\n for (var _i11 = 0; _i11 < nodeSize; _i11++) {\n V2[_i11] = Y2[_i11];\n }\n\n V2 = Matrix.minusOp(V2, Matrix.multCons(V1, Matrix.dotProduct(V1, V2)));\n Y2 = Matrix.multGamma(Matrix.multL(Matrix.multGamma(V2), C, INV));\n theta2 = Matrix.dotProduct(V2, Y2);\n Y2 = Matrix.normalize(Y2);\n\n current = Matrix.dotProduct(V2, Y2);\n\n temp = Math.abs(current / previous);\n\n if (temp <= 1 + piTol && temp >= 1) {\n break;\n }\n\n previous = current;\n }\n\n for (var _i12 = 0; _i12 < nodeSize; _i12++) {\n V2[_i12] = Y2[_i12];\n }\n\n // theta1 now contains dominant eigenvalue\n // theta2 now contains the second-largest eigenvalue\n // V1 now contains theta1's eigenvector\n // V2 now contains theta2's eigenvector\n\n //populate the two vectors\n xCoords = Matrix.multCons(V1, Math.sqrt(Math.abs(theta1)));\n yCoords = Matrix.multCons(V2, Math.sqrt(Math.abs(theta2)));\n };\n\n /**** Preparation for spectral layout (Preprocessing) ****/\n\n // connect disconnected components (first top level, then inside of each compound node)\n aux.connectComponents(cy, eles, aux.getTopMostNodes(nodes), dummyNodes);\n\n parentNodes.forEach(function (ele) {\n aux.connectComponents(cy, eles, aux.getTopMostNodes(ele.descendants().intersection(eles)), dummyNodes);\n });\n\n // assign indexes to nodes (first real, then dummy nodes)\n var index = 0;\n for (var i = 0; i < nodes.length; i++) {\n if (!nodes[i].isParent()) {\n nodeIndexes.set(nodes[i].id(), index++);\n }\n }\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = dummyNodes.keys()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var key = _step.value;\n\n nodeIndexes.set(key, index++);\n }\n\n // instantiate the neighborhood matrix\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n for (var _i13 = 0; _i13 < nodeIndexes.size; _i13++) {\n allNodesNeighborhood[_i13] = [];\n }\n\n // form a parent-child map to keep representative node of each compound node \n parentNodes.forEach(function (ele) {\n var children = ele.children().intersection(eles);\n\n // let random = 0;\n while (children.nodes(\":childless\").length == 0) {\n // random = Math.floor(Math.random() * children.nodes().length); // if all children are compound then proceed randomly\n children = children.nodes()[0].children().intersection(eles);\n }\n // select the representative node - we can apply different methods here\n // random = Math.floor(Math.random() * children.nodes(\":childless\").length);\n var index = 0;\n var min = children.nodes(\":childless\")[0].connectedEdges().length;\n children.nodes(\":childless\").forEach(function (ele2, i) {\n if (ele2.connectedEdges().length < min) {\n min = ele2.connectedEdges().length;\n index = i;\n }\n });\n parentChildMap.set(ele.id(), children.nodes(\":childless\")[index].id());\n });\n\n // add neighborhood relations (first real, then dummy nodes)\n nodes.forEach(function (ele) {\n var eleIndex = void 0;\n\n if (ele.isParent()) eleIndex = nodeIndexes.get(parentChildMap.get(ele.id()));else eleIndex = nodeIndexes.get(ele.id());\n\n ele.neighborhood().nodes().forEach(function (node) {\n if (eles.intersection(ele.edgesWith(node)).length > 0) {\n if (node.isParent()) allNodesNeighborhood[eleIndex].push(parentChildMap.get(node.id()));else allNodesNeighborhood[eleIndex].push(node.id());\n }\n });\n });\n\n var _loop = function _loop(_key) {\n var eleIndex = nodeIndexes.get(_key);\n var disconnectedId = void 0;\n dummyNodes.get(_key).forEach(function (id) {\n if (cy.getElementById(id).isParent()) disconnectedId = parentChildMap.get(id);else disconnectedId = id;\n\n allNodesNeighborhood[eleIndex].push(disconnectedId);\n allNodesNeighborhood[nodeIndexes.get(disconnectedId)].push(_key);\n });\n };\n\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = dummyNodes.keys()[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var _key = _step2.value;\n\n _loop(_key);\n }\n\n // nodeSize now only considers the size of transformed graph\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n nodeSize = nodeIndexes.size;\n\n var spectralResult = void 0;\n\n // If number of nodes in transformed graph is 1 or 2, either SVD or powerIteration causes problem\n // So skip spectral and layout the graph with cose\n if (nodeSize > 2) {\n // if # of nodes in transformed graph is smaller than sample size,\n // then use # of nodes as sample size\n sampleSize = nodeSize < options.sampleSize ? nodeSize : options.sampleSize;\n\n // instantiates the partial matrices that will be used in spectral layout\n for (var _i14 = 0; _i14 < nodeSize; _i14++) {\n C[_i14] = [];\n }\n for (var _i15 = 0; _i15 < sampleSize; _i15++) {\n INV[_i15] = [];\n }\n\n /**** Apply spectral layout ****/\n\n if (options.quality == \"draft\" || options.step == \"all\") {\n allBFS(samplingType);\n sample();\n powerIteration();\n\n spectralResult = { nodeIndexes: nodeIndexes, xCoords: xCoords, yCoords: yCoords };\n } else {\n nodeIndexes.forEach(function (value, key) {\n xCoords.push(cy.getElementById(key).position(\"x\"));\n yCoords.push(cy.getElementById(key).position(\"y\"));\n });\n spectralResult = { nodeIndexes: nodeIndexes, xCoords: xCoords, yCoords: yCoords };\n }\n return spectralResult;\n } else {\n var iterator = nodeIndexes.keys();\n var firstNode = cy.getElementById(iterator.next().value);\n var firstNodePos = firstNode.position();\n var firstNodeWidth = firstNode.outerWidth();\n xCoords.push(firstNodePos.x);\n yCoords.push(firstNodePos.y);\n if (nodeSize == 2) {\n var secondNode = cy.getElementById(iterator.next().value);\n var secondNodeWidth = secondNode.outerWidth();\n xCoords.push(firstNodePos.x + firstNodeWidth / 2 + secondNodeWidth / 2 + options.idealEdgeLength);\n yCoords.push(firstNodePos.y);\n }\n\n spectralResult = { nodeIndexes: nodeIndexes, xCoords: xCoords, yCoords: yCoords };\n return spectralResult;\n }\n};\n\nmodule.exports = { spectralLayout: spectralLayout };\n\n/***/ }),\n\n/***/ 579:\n/***/ ((module, __unused_webpack_exports, __webpack_require__) => {\n\n\n\nvar impl = __webpack_require__(212);\n\n// registers the extension on a cytoscape lib ref\nvar register = function register(cytoscape) {\n if (!cytoscape) {\n return;\n } // can't register if cytoscape unspecified\n\n cytoscape('layout', 'fcose', impl); // register with cytoscape.js\n};\n\nif (typeof cytoscape !== 'undefined') {\n // expose to global cytoscape (i.e. window.cytoscape)\n register(cytoscape);\n}\n\nmodule.exports = register;\n\n/***/ }),\n\n/***/ 140:\n/***/ ((module) => {\n\nmodule.exports = __WEBPACK_EXTERNAL_MODULE__140__;\n\n/***/ })\n\n/******/ \t});\n/************************************************************************/\n/******/ \t// The module cache\n/******/ \tvar __webpack_module_cache__ = {};\n/******/ \t\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/ \t\t// Check if module is in cache\n/******/ \t\tvar cachedModule = __webpack_module_cache__[moduleId];\n/******/ \t\tif (cachedModule !== undefined) {\n/******/ \t\t\treturn cachedModule.exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = __webpack_module_cache__[moduleId] = {\n/******/ \t\t\t// no module.id needed\n/******/ \t\t\t// no module.loaded needed\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/ \t\n/******/ \t\t// Execute the module function\n/******/ \t\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n/******/ \t\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/ \t\n/************************************************************************/\n/******/ \t\n/******/ \t// startup\n/******/ \t// Load entry module and return exports\n/******/ \t// This entry module is referenced by other modules so it can't be inlined\n/******/ \tvar __webpack_exports__ = __webpack_require__(579);\n/******/ \t\n/******/ \treturn __webpack_exports__;\n/******/ })()\n;\n});", "import {\n getIconSVG,\n registerIconPacks,\n unknownIcon\n} from \"./chunk-CUPH5FGA.mjs\";\nimport {\n createText\n} from \"./chunk-5N55DQE6.mjs\";\nimport {\n populateCommonDb\n} from \"./chunk-OQCM5LHU.mjs\";\nimport {\n ImperativeState\n} from \"./chunk-2RYQ3QTB.mjs\";\nimport \"./chunk-2EDTWDYI.mjs\";\nimport {\n selectSvgElement\n} from \"./chunk-F2XFN3BY.mjs\";\nimport {\n __name,\n clear,\n defaultConfig_default,\n getAccDescription,\n getAccTitle,\n getConfig2 as getConfig,\n getDiagramTitle,\n log,\n setAccDescription,\n setAccTitle,\n setDiagramTitle,\n setupGraphViewbox\n} from \"./chunk-IIKMQLIC.mjs\";\n\n// src/diagrams/architecture/architectureParser.ts\nimport { parse } from \"@mermaid-js/parser\";\n\n// src/diagrams/architecture/architectureTypes.ts\nvar ArchitectureDirectionName = {\n L: \"left\",\n R: \"right\",\n T: \"top\",\n B: \"bottom\"\n};\nvar ArchitectureDirectionArrow = {\n L: /* @__PURE__ */ __name((scale) => `${scale},${scale / 2} 0,${scale} 0,0`, \"L\"),\n R: /* @__PURE__ */ __name((scale) => `0,${scale / 2} ${scale},0 ${scale},${scale}`, \"R\"),\n T: /* @__PURE__ */ __name((scale) => `0,0 ${scale},0 ${scale / 2},${scale}`, \"T\"),\n B: /* @__PURE__ */ __name((scale) => `${scale / 2},0 ${scale},${scale} 0,${scale}`, \"B\")\n};\nvar ArchitectureDirectionArrowShift = {\n L: /* @__PURE__ */ __name((orig, arrowSize) => orig - arrowSize + 2, \"L\"),\n R: /* @__PURE__ */ __name((orig, _arrowSize) => orig - 2, \"R\"),\n T: /* @__PURE__ */ __name((orig, arrowSize) => orig - arrowSize + 2, \"T\"),\n B: /* @__PURE__ */ __name((orig, _arrowSize) => orig - 2, \"B\")\n};\nvar getOppositeArchitectureDirection = /* @__PURE__ */ __name(function(x) {\n if (isArchitectureDirectionX(x)) {\n return x === \"L\" ? \"R\" : \"L\";\n } else {\n return x === \"T\" ? \"B\" : \"T\";\n }\n}, \"getOppositeArchitectureDirection\");\nvar isArchitectureDirection = /* @__PURE__ */ __name(function(x) {\n const temp = x;\n return temp === \"L\" || temp === \"R\" || temp === \"T\" || temp === \"B\";\n}, \"isArchitectureDirection\");\nvar isArchitectureDirectionX = /* @__PURE__ */ __name(function(x) {\n const temp = x;\n return temp === \"L\" || temp === \"R\";\n}, \"isArchitectureDirectionX\");\nvar isArchitectureDirectionY = /* @__PURE__ */ __name(function(x) {\n const temp = x;\n return temp === \"T\" || temp === \"B\";\n}, \"isArchitectureDirectionY\");\nvar isArchitectureDirectionXY = /* @__PURE__ */ __name(function(a, b) {\n const aX_bY = isArchitectureDirectionX(a) && isArchitectureDirectionY(b);\n const aY_bX = isArchitectureDirectionY(a) && isArchitectureDirectionX(b);\n return aX_bY || aY_bX;\n}, \"isArchitectureDirectionXY\");\nvar isArchitecturePairXY = /* @__PURE__ */ __name(function(pair) {\n const lhs = pair[0];\n const rhs = pair[1];\n const aX_bY = isArchitectureDirectionX(lhs) && isArchitectureDirectionY(rhs);\n const aY_bX = isArchitectureDirectionY(lhs) && isArchitectureDirectionX(rhs);\n return aX_bY || aY_bX;\n}, \"isArchitecturePairXY\");\nvar isValidArchitectureDirectionPair = /* @__PURE__ */ __name(function(x) {\n return x !== \"LL\" && x !== \"RR\" && x !== \"TT\" && x !== \"BB\";\n}, \"isValidArchitectureDirectionPair\");\nvar getArchitectureDirectionPair = /* @__PURE__ */ __name(function(sourceDir, targetDir) {\n const pair = `${sourceDir}${targetDir}`;\n return isValidArchitectureDirectionPair(pair) ? pair : void 0;\n}, \"getArchitectureDirectionPair\");\nvar shiftPositionByArchitectureDirectionPair = /* @__PURE__ */ __name(function([x, y], pair) {\n const lhs = pair[0];\n const rhs = pair[1];\n if (isArchitectureDirectionX(lhs)) {\n if (isArchitectureDirectionY(rhs)) {\n return [x + (lhs === \"L\" ? -1 : 1), y + (rhs === \"T\" ? 1 : -1)];\n } else {\n return [x + (lhs === \"L\" ? -1 : 1), y];\n }\n } else {\n if (isArchitectureDirectionX(rhs)) {\n return [x + (rhs === \"L\" ? 1 : -1), y + (lhs === \"T\" ? 1 : -1)];\n } else {\n return [x, y + (lhs === \"T\" ? 1 : -1)];\n }\n }\n}, \"shiftPositionByArchitectureDirectionPair\");\nvar getArchitectureDirectionXYFactors = /* @__PURE__ */ __name(function(pair) {\n if (pair === \"LT\" || pair === \"TL\") {\n return [1, 1];\n } else if (pair === \"BL\" || pair === \"LB\") {\n return [1, -1];\n } else if (pair === \"BR\" || pair === \"RB\") {\n return [-1, -1];\n } else {\n return [-1, 1];\n }\n}, \"getArchitectureDirectionXYFactors\");\nvar isArchitectureService = /* @__PURE__ */ __name(function(x) {\n const temp = x;\n return temp.type === \"service\";\n}, \"isArchitectureService\");\nvar isArchitectureJunction = /* @__PURE__ */ __name(function(x) {\n const temp = x;\n return temp.type === \"junction\";\n}, \"isArchitectureJunction\");\nvar edgeData = /* @__PURE__ */ __name((edge) => {\n return edge.data();\n}, \"edgeData\");\nvar nodeData = /* @__PURE__ */ __name((node) => {\n return node.data();\n}, \"nodeData\");\n\n// src/diagrams/architecture/architectureDb.ts\nvar DEFAULT_ARCHITECTURE_CONFIG = defaultConfig_default.architecture;\nvar state = new ImperativeState(() => ({\n nodes: {},\n groups: {},\n edges: [],\n registeredIds: {},\n config: DEFAULT_ARCHITECTURE_CONFIG,\n dataStructures: void 0,\n elements: {}\n}));\nvar clear2 = /* @__PURE__ */ __name(() => {\n state.reset();\n clear();\n}, \"clear\");\nvar addService = /* @__PURE__ */ __name(function({\n id,\n icon,\n in: parent,\n title,\n iconText\n}) {\n if (state.records.registeredIds[id] !== void 0) {\n throw new Error(\n `The service id [${id}] is already in use by another ${state.records.registeredIds[id]}`\n );\n }\n if (parent !== void 0) {\n if (id === parent) {\n throw new Error(`The service [${id}] cannot be placed within itself`);\n }\n if (state.records.registeredIds[parent] === void 0) {\n throw new Error(\n `The service [${id}]'s parent does not exist. Please make sure the parent is created before this service`\n );\n }\n if (state.records.registeredIds[parent] === \"node\") {\n throw new Error(`The service [${id}]'s parent is not a group`);\n }\n }\n state.records.registeredIds[id] = \"node\";\n state.records.nodes[id] = {\n id,\n type: \"service\",\n icon,\n iconText,\n title,\n edges: [],\n in: parent\n };\n}, \"addService\");\nvar getServices = /* @__PURE__ */ __name(() => Object.values(state.records.nodes).filter(isArchitectureService), \"getServices\");\nvar addJunction = /* @__PURE__ */ __name(function({ id, in: parent }) {\n state.records.registeredIds[id] = \"node\";\n state.records.nodes[id] = {\n id,\n type: \"junction\",\n edges: [],\n in: parent\n };\n}, \"addJunction\");\nvar getJunctions = /* @__PURE__ */ __name(() => Object.values(state.records.nodes).filter(isArchitectureJunction), \"getJunctions\");\nvar getNodes = /* @__PURE__ */ __name(() => Object.values(state.records.nodes), \"getNodes\");\nvar getNode = /* @__PURE__ */ __name((id) => state.records.nodes[id], \"getNode\");\nvar addGroup = /* @__PURE__ */ __name(function({ id, icon, in: parent, title }) {\n if (state.records.registeredIds[id] !== void 0) {\n throw new Error(\n `The group id [${id}] is already in use by another ${state.records.registeredIds[id]}`\n );\n }\n if (parent !== void 0) {\n if (id === parent) {\n throw new Error(`The group [${id}] cannot be placed within itself`);\n }\n if (state.records.registeredIds[parent] === void 0) {\n throw new Error(\n `The group [${id}]'s parent does not exist. Please make sure the parent is created before this group`\n );\n }\n if (state.records.registeredIds[parent] === \"node\") {\n throw new Error(`The group [${id}]'s parent is not a group`);\n }\n }\n state.records.registeredIds[id] = \"group\";\n state.records.groups[id] = {\n id,\n icon,\n title,\n in: parent\n };\n}, \"addGroup\");\nvar getGroups = /* @__PURE__ */ __name(() => {\n return Object.values(state.records.groups);\n}, \"getGroups\");\nvar addEdge = /* @__PURE__ */ __name(function({\n lhsId,\n rhsId,\n lhsDir,\n rhsDir,\n lhsInto,\n rhsInto,\n lhsGroup,\n rhsGroup,\n title\n}) {\n if (!isArchitectureDirection(lhsDir)) {\n throw new Error(\n `Invalid direction given for left hand side of edge ${lhsId}--${rhsId}. Expected (L,R,T,B) got ${lhsDir}`\n );\n }\n if (!isArchitectureDirection(rhsDir)) {\n throw new Error(\n `Invalid direction given for right hand side of edge ${lhsId}--${rhsId}. Expected (L,R,T,B) got ${rhsDir}`\n );\n }\n if (state.records.nodes[lhsId] === void 0 && state.records.groups[lhsId] === void 0) {\n throw new Error(\n `The left-hand id [${lhsId}] does not yet exist. Please create the service/group before declaring an edge to it.`\n );\n }\n if (state.records.nodes[rhsId] === void 0 && state.records.groups[lhsId] === void 0) {\n throw new Error(\n `The right-hand id [${rhsId}] does not yet exist. Please create the service/group before declaring an edge to it.`\n );\n }\n const lhsGroupId = state.records.nodes[lhsId].in;\n const rhsGroupId = state.records.nodes[rhsId].in;\n if (lhsGroup && lhsGroupId && rhsGroupId && lhsGroupId == rhsGroupId) {\n throw new Error(\n `The left-hand id [${lhsId}] is modified to traverse the group boundary, but the edge does not pass through two groups.`\n );\n }\n if (rhsGroup && lhsGroupId && rhsGroupId && lhsGroupId == rhsGroupId) {\n throw new Error(\n `The right-hand id [${rhsId}] is modified to traverse the group boundary, but the edge does not pass through two groups.`\n );\n }\n const edge = {\n lhsId,\n lhsDir,\n lhsInto,\n lhsGroup,\n rhsId,\n rhsDir,\n rhsInto,\n rhsGroup,\n title\n };\n state.records.edges.push(edge);\n if (state.records.nodes[lhsId] && state.records.nodes[rhsId]) {\n state.records.nodes[lhsId].edges.push(state.records.edges[state.records.edges.length - 1]);\n state.records.nodes[rhsId].edges.push(state.records.edges[state.records.edges.length - 1]);\n }\n}, \"addEdge\");\nvar getEdges = /* @__PURE__ */ __name(() => state.records.edges, \"getEdges\");\nvar getDataStructures = /* @__PURE__ */ __name(() => {\n if (state.records.dataStructures === void 0) {\n const adjList = Object.entries(state.records.nodes).reduce((prevOuter, [id, service]) => {\n prevOuter[id] = service.edges.reduce((prevInner, edge) => {\n if (edge.lhsId === id) {\n const pair = getArchitectureDirectionPair(edge.lhsDir, edge.rhsDir);\n if (pair) {\n prevInner[pair] = edge.rhsId;\n }\n } else {\n const pair = getArchitectureDirectionPair(edge.rhsDir, edge.lhsDir);\n if (pair) {\n prevInner[pair] = edge.lhsId;\n }\n }\n return prevInner;\n }, {});\n return prevOuter;\n }, {});\n const firstId = Object.keys(adjList)[0];\n const visited = { [firstId]: 1 };\n const notVisited = Object.keys(adjList).reduce(\n (prev, id) => id === firstId ? prev : { ...prev, [id]: 1 },\n {}\n );\n const BFS = /* @__PURE__ */ __name((startingId) => {\n const spatialMap = { [startingId]: [0, 0] };\n const queue = [startingId];\n while (queue.length > 0) {\n const id = queue.shift();\n if (id) {\n visited[id] = 1;\n delete notVisited[id];\n const adj = adjList[id];\n const [posX, posY] = spatialMap[id];\n Object.entries(adj).forEach(([dir, rhsId]) => {\n if (!visited[rhsId]) {\n spatialMap[rhsId] = shiftPositionByArchitectureDirectionPair(\n [posX, posY],\n dir\n );\n queue.push(rhsId);\n }\n });\n }\n }\n return spatialMap;\n }, \"BFS\");\n const spatialMaps = [BFS(firstId)];\n while (Object.keys(notVisited).length > 0) {\n spatialMaps.push(BFS(Object.keys(notVisited)[0]));\n }\n state.records.dataStructures = {\n adjList,\n spatialMaps\n };\n }\n return state.records.dataStructures;\n}, \"getDataStructures\");\nvar setElementForId = /* @__PURE__ */ __name((id, element) => {\n state.records.elements[id] = element;\n}, \"setElementForId\");\nvar getElementById = /* @__PURE__ */ __name((id) => state.records.elements[id], \"getElementById\");\nvar db = {\n clear: clear2,\n setDiagramTitle,\n getDiagramTitle,\n setAccTitle,\n getAccTitle,\n setAccDescription,\n getAccDescription,\n addService,\n getServices,\n addJunction,\n getJunctions,\n getNodes,\n getNode,\n addGroup,\n getGroups,\n addEdge,\n getEdges,\n setElementForId,\n getElementById,\n getDataStructures\n};\nfunction getConfigField(field) {\n const arch = getConfig().architecture;\n if (arch?.[field]) {\n return arch[field];\n }\n return DEFAULT_ARCHITECTURE_CONFIG[field];\n}\n__name(getConfigField, \"getConfigField\");\n\n// src/diagrams/architecture/architectureParser.ts\nvar populateDb = /* @__PURE__ */ __name((ast, db2) => {\n populateCommonDb(ast, db2);\n ast.groups.map(db2.addGroup);\n ast.services.map((service) => db2.addService({ ...service, type: \"service\" }));\n ast.junctions.map((service) => db2.addJunction({ ...service, type: \"junction\" }));\n ast.edges.map(db2.addEdge);\n}, \"populateDb\");\nvar parser = {\n parse: /* @__PURE__ */ __name(async (input) => {\n const ast = await parse(\"architecture\", input);\n log.debug(ast);\n populateDb(ast, db);\n }, \"parse\")\n};\n\n// src/diagrams/architecture/architectureStyles.ts\nvar getStyles = /* @__PURE__ */ __name((options) => `\n .edge {\n stroke-width: ${options.archEdgeWidth};\n stroke: ${options.archEdgeColor};\n fill: none;\n }\n\n .arrow {\n fill: ${options.archEdgeArrowColor};\n }\n\n .node-bkg {\n fill: none;\n stroke: ${options.archGroupBorderColor};\n stroke-width: ${options.archGroupBorderWidth};\n stroke-dasharray: 8;\n }\n .node-icon-text {\n display: flex; \n align-items: center;\n }\n \n .node-icon-text > div {\n color: #fff;\n margin: 1px;\n height: fit-content;\n text-align: center;\n overflow: hidden;\n display: -webkit-box;\n -webkit-box-orient: vertical;\n }\n`, \"getStyles\");\nvar architectureStyles_default = getStyles;\n\n// src/diagrams/architecture/architectureRenderer.ts\nimport cytoscape from \"cytoscape\";\nimport fcose from \"cytoscape-fcose\";\nimport { select } from \"d3\";\n\n// src/diagrams/architecture/architectureIcons.ts\nvar wrapIcon = /* @__PURE__ */ __name((icon) => {\n return `${icon}`;\n}, \"wrapIcon\");\nvar architectureIcons = {\n prefix: \"mermaid-architecture\",\n height: 80,\n width: 80,\n icons: {\n database: {\n body: wrapIcon(\n ''\n )\n },\n server: {\n body: wrapIcon(\n ''\n )\n },\n disk: {\n body: wrapIcon(\n ''\n )\n },\n internet: {\n body: wrapIcon(\n ''\n )\n },\n cloud: {\n body: wrapIcon(\n ''\n )\n },\n unknown: unknownIcon,\n blank: {\n body: wrapIcon(\"\")\n }\n }\n};\n\n// src/diagrams/architecture/svgDraw.ts\nvar drawEdges = /* @__PURE__ */ __name(async function(edgesEl, cy) {\n const padding = getConfigField(\"padding\");\n const iconSize = getConfigField(\"iconSize\");\n const halfIconSize = iconSize / 2;\n const arrowSize = iconSize / 6;\n const halfArrowSize = arrowSize / 2;\n await Promise.all(\n cy.edges().map(async (edge) => {\n const {\n source,\n sourceDir,\n sourceArrow,\n sourceGroup,\n target,\n targetDir,\n targetArrow,\n targetGroup,\n label\n } = edgeData(edge);\n let { x: startX, y: startY } = edge[0].sourceEndpoint();\n const { x: midX, y: midY } = edge[0].midpoint();\n let { x: endX, y: endY } = edge[0].targetEndpoint();\n const groupEdgeShift = padding + 4;\n if (sourceGroup) {\n if (isArchitectureDirectionX(sourceDir)) {\n startX += sourceDir === \"L\" ? -groupEdgeShift : groupEdgeShift;\n } else {\n startY += sourceDir === \"T\" ? -groupEdgeShift : groupEdgeShift + 18;\n }\n }\n if (targetGroup) {\n if (isArchitectureDirectionX(targetDir)) {\n endX += targetDir === \"L\" ? -groupEdgeShift : groupEdgeShift;\n } else {\n endY += targetDir === \"T\" ? -groupEdgeShift : groupEdgeShift + 18;\n }\n }\n if (!sourceGroup && db.getNode(source)?.type === \"junction\") {\n if (isArchitectureDirectionX(sourceDir)) {\n startX += sourceDir === \"L\" ? halfIconSize : -halfIconSize;\n } else {\n startY += sourceDir === \"T\" ? halfIconSize : -halfIconSize;\n }\n }\n if (!targetGroup && db.getNode(target)?.type === \"junction\") {\n if (isArchitectureDirectionX(targetDir)) {\n endX += targetDir === \"L\" ? halfIconSize : -halfIconSize;\n } else {\n endY += targetDir === \"T\" ? halfIconSize : -halfIconSize;\n }\n }\n if (edge[0]._private.rscratch) {\n const g = edgesEl.insert(\"g\");\n g.insert(\"path\").attr(\"d\", `M ${startX},${startY} L ${midX},${midY} L${endX},${endY} `).attr(\"class\", \"edge\");\n if (sourceArrow) {\n const xShift = isArchitectureDirectionX(sourceDir) ? ArchitectureDirectionArrowShift[sourceDir](startX, arrowSize) : startX - halfArrowSize;\n const yShift = isArchitectureDirectionY(sourceDir) ? ArchitectureDirectionArrowShift[sourceDir](startY, arrowSize) : startY - halfArrowSize;\n g.insert(\"polygon\").attr(\"points\", ArchitectureDirectionArrow[sourceDir](arrowSize)).attr(\"transform\", `translate(${xShift},${yShift})`).attr(\"class\", \"arrow\");\n }\n if (targetArrow) {\n const xShift = isArchitectureDirectionX(targetDir) ? ArchitectureDirectionArrowShift[targetDir](endX, arrowSize) : endX - halfArrowSize;\n const yShift = isArchitectureDirectionY(targetDir) ? ArchitectureDirectionArrowShift[targetDir](endY, arrowSize) : endY - halfArrowSize;\n g.insert(\"polygon\").attr(\"points\", ArchitectureDirectionArrow[targetDir](arrowSize)).attr(\"transform\", `translate(${xShift},${yShift})`).attr(\"class\", \"arrow\");\n }\n if (label) {\n const axis = !isArchitectureDirectionXY(sourceDir, targetDir) ? isArchitectureDirectionX(sourceDir) ? \"X\" : \"Y\" : \"XY\";\n let width = 0;\n if (axis === \"X\") {\n width = Math.abs(startX - endX);\n } else if (axis === \"Y\") {\n width = Math.abs(startY - endY) / 1.5;\n } else {\n width = Math.abs(startX - endX) / 2;\n }\n const textElem = g.append(\"g\");\n await createText(\n textElem,\n label,\n {\n useHtmlLabels: false,\n width,\n classes: \"architecture-service-label\"\n },\n getConfig()\n );\n textElem.attr(\"dy\", \"1em\").attr(\"alignment-baseline\", \"middle\").attr(\"dominant-baseline\", \"middle\").attr(\"text-anchor\", \"middle\");\n if (axis === \"X\") {\n textElem.attr(\"transform\", \"translate(\" + midX + \", \" + midY + \")\");\n } else if (axis === \"Y\") {\n textElem.attr(\"transform\", \"translate(\" + midX + \", \" + midY + \") rotate(-90)\");\n } else if (axis === \"XY\") {\n const pair = getArchitectureDirectionPair(sourceDir, targetDir);\n if (pair && isArchitecturePairXY(pair)) {\n const bboxOrig = textElem.node().getBoundingClientRect();\n const [x, y] = getArchitectureDirectionXYFactors(pair);\n textElem.attr(\"dominant-baseline\", \"auto\").attr(\"transform\", `rotate(${-1 * x * y * 45})`);\n const bboxNew = textElem.node().getBoundingClientRect();\n textElem.attr(\n \"transform\",\n `\n translate(${midX}, ${midY - bboxOrig.height / 2})\n translate(${x * bboxNew.width / 2}, ${y * bboxNew.height / 2})\n rotate(${-1 * x * y * 45}, 0, ${bboxOrig.height / 2})\n `\n );\n }\n }\n }\n }\n })\n );\n}, \"drawEdges\");\nvar drawGroups = /* @__PURE__ */ __name(async function(groupsEl, cy) {\n const padding = getConfigField(\"padding\");\n const groupIconSize = padding * 0.75;\n const fontSize = getConfigField(\"fontSize\");\n const iconSize = getConfigField(\"iconSize\");\n const halfIconSize = iconSize / 2;\n await Promise.all(\n cy.nodes().map(async (node) => {\n const data = nodeData(node);\n if (data.type === \"group\") {\n const { h, w, x1, y1 } = node.boundingBox();\n groupsEl.append(\"rect\").attr(\"x\", x1 + halfIconSize).attr(\"y\", y1 + halfIconSize).attr(\"width\", w).attr(\"height\", h).attr(\"class\", \"node-bkg\");\n const groupLabelContainer = groupsEl.append(\"g\");\n let shiftedX1 = x1;\n let shiftedY1 = y1;\n if (data.icon) {\n const bkgElem = groupLabelContainer.append(\"g\");\n bkgElem.html(\n `${await getIconSVG(data.icon, { height: groupIconSize, width: groupIconSize, fallbackPrefix: architectureIcons.prefix })}`\n );\n bkgElem.attr(\n \"transform\",\n \"translate(\" + (shiftedX1 + halfIconSize + 1) + \", \" + (shiftedY1 + halfIconSize + 1) + \")\"\n );\n shiftedX1 += groupIconSize;\n shiftedY1 += fontSize / 2 - 1 - 2;\n }\n if (data.label) {\n const textElem = groupLabelContainer.append(\"g\");\n await createText(\n textElem,\n data.label,\n {\n useHtmlLabels: false,\n width: w,\n classes: \"architecture-service-label\"\n },\n getConfig()\n );\n textElem.attr(\"dy\", \"1em\").attr(\"alignment-baseline\", \"middle\").attr(\"dominant-baseline\", \"start\").attr(\"text-anchor\", \"start\");\n textElem.attr(\n \"transform\",\n \"translate(\" + (shiftedX1 + halfIconSize + 4) + \", \" + (shiftedY1 + halfIconSize + 2) + \")\"\n );\n }\n }\n })\n );\n}, \"drawGroups\");\nvar drawServices = /* @__PURE__ */ __name(async function(db2, elem, services) {\n for (const service of services) {\n const serviceElem = elem.append(\"g\");\n const iconSize = getConfigField(\"iconSize\");\n if (service.title) {\n const textElem = serviceElem.append(\"g\");\n await createText(\n textElem,\n service.title,\n {\n useHtmlLabels: false,\n width: iconSize * 1.5,\n classes: \"architecture-service-label\"\n },\n getConfig()\n );\n textElem.attr(\"dy\", \"1em\").attr(\"alignment-baseline\", \"middle\").attr(\"dominant-baseline\", \"middle\").attr(\"text-anchor\", \"middle\");\n textElem.attr(\"transform\", \"translate(\" + iconSize / 2 + \", \" + iconSize + \")\");\n }\n const bkgElem = serviceElem.append(\"g\");\n if (service.icon) {\n bkgElem.html(\n `${await getIconSVG(service.icon, { height: iconSize, width: iconSize, fallbackPrefix: architectureIcons.prefix })}`\n );\n } else if (service.iconText) {\n bkgElem.html(\n `${await getIconSVG(\"blank\", { height: iconSize, width: iconSize, fallbackPrefix: architectureIcons.prefix })}`\n );\n const textElemContainer = bkgElem.append(\"g\");\n const fo = textElemContainer.append(\"foreignObject\").attr(\"width\", iconSize).attr(\"height\", iconSize);\n const divElem = fo.append(\"div\").attr(\"class\", \"node-icon-text\").attr(\"style\", `height: ${iconSize}px;`).append(\"div\").html(service.iconText);\n const fontSize = parseInt(\n window.getComputedStyle(divElem.node(), null).getPropertyValue(\"font-size\").replace(/\\D/g, \"\")\n ) ?? 16;\n divElem.attr(\"style\", `-webkit-line-clamp: ${Math.floor((iconSize - 2) / fontSize)};`);\n } else {\n bkgElem.append(\"path\").attr(\"class\", \"node-bkg\").attr(\"id\", \"node-\" + service.id).attr(\n \"d\",\n `M0 ${iconSize} v${-iconSize} q0,-5 5,-5 h${iconSize} q5,0 5,5 v${iconSize} H0 Z`\n );\n }\n serviceElem.attr(\"class\", \"architecture-service\");\n const { width, height } = serviceElem._groups[0][0].getBBox();\n service.width = width;\n service.height = height;\n db2.setElementForId(service.id, serviceElem);\n }\n return 0;\n}, \"drawServices\");\nvar drawJunctions = /* @__PURE__ */ __name(function(db2, elem, junctions) {\n junctions.forEach((junction) => {\n const junctionElem = elem.append(\"g\");\n const iconSize = getConfigField(\"iconSize\");\n const bkgElem = junctionElem.append(\"g\");\n bkgElem.append(\"rect\").attr(\"id\", \"node-\" + junction.id).attr(\"fill-opacity\", \"0\").attr(\"width\", iconSize).attr(\"height\", iconSize);\n junctionElem.attr(\"class\", \"architecture-junction\");\n const { width, height } = junctionElem._groups[0][0].getBBox();\n junctionElem.width = width;\n junctionElem.height = height;\n db2.setElementForId(junction.id, junctionElem);\n });\n}, \"drawJunctions\");\n\n// src/diagrams/architecture/architectureRenderer.ts\nregisterIconPacks([\n {\n name: architectureIcons.prefix,\n icons: architectureIcons\n }\n]);\ncytoscape.use(fcose);\nfunction addServices(services, cy) {\n services.forEach((service) => {\n cy.add({\n group: \"nodes\",\n data: {\n type: \"service\",\n id: service.id,\n icon: service.icon,\n label: service.title,\n parent: service.in,\n width: getConfigField(\"iconSize\"),\n height: getConfigField(\"iconSize\")\n },\n classes: \"node-service\"\n });\n });\n}\n__name(addServices, \"addServices\");\nfunction addJunctions(junctions, cy) {\n junctions.forEach((junction) => {\n cy.add({\n group: \"nodes\",\n data: {\n type: \"junction\",\n id: junction.id,\n parent: junction.in,\n width: getConfigField(\"iconSize\"),\n height: getConfigField(\"iconSize\")\n },\n classes: \"node-junction\"\n });\n });\n}\n__name(addJunctions, \"addJunctions\");\nfunction positionNodes(db2, cy) {\n cy.nodes().map((node) => {\n const data = nodeData(node);\n if (data.type === \"group\") {\n return;\n }\n data.x = node.position().x;\n data.y = node.position().y;\n const nodeElem = db2.getElementById(data.id);\n nodeElem.attr(\"transform\", \"translate(\" + (data.x || 0) + \",\" + (data.y || 0) + \")\");\n });\n}\n__name(positionNodes, \"positionNodes\");\nfunction addGroups(groups, cy) {\n groups.forEach((group) => {\n cy.add({\n group: \"nodes\",\n data: {\n type: \"group\",\n id: group.id,\n icon: group.icon,\n label: group.title,\n parent: group.in\n },\n classes: \"node-group\"\n });\n });\n}\n__name(addGroups, \"addGroups\");\nfunction addEdges(edges, cy) {\n edges.forEach((parsedEdge) => {\n const { lhsId, rhsId, lhsInto, lhsGroup, rhsInto, lhsDir, rhsDir, rhsGroup, title } = parsedEdge;\n const edgeType = isArchitectureDirectionXY(parsedEdge.lhsDir, parsedEdge.rhsDir) ? \"segments\" : \"straight\";\n const edge = {\n id: `${lhsId}-${rhsId}`,\n label: title,\n source: lhsId,\n sourceDir: lhsDir,\n sourceArrow: lhsInto,\n sourceGroup: lhsGroup,\n sourceEndpoint: lhsDir === \"L\" ? \"0 50%\" : lhsDir === \"R\" ? \"100% 50%\" : lhsDir === \"T\" ? \"50% 0\" : \"50% 100%\",\n target: rhsId,\n targetDir: rhsDir,\n targetArrow: rhsInto,\n targetGroup: rhsGroup,\n targetEndpoint: rhsDir === \"L\" ? \"0 50%\" : rhsDir === \"R\" ? \"100% 50%\" : rhsDir === \"T\" ? \"50% 0\" : \"50% 100%\"\n };\n cy.add({\n group: \"edges\",\n data: edge,\n classes: edgeType\n });\n });\n}\n__name(addEdges, \"addEdges\");\nfunction getAlignments(spatialMaps) {\n const alignments = spatialMaps.map((spatialMap) => {\n const horizontalAlignments = {};\n const verticalAlignments = {};\n Object.entries(spatialMap).forEach(([id, [x, y]]) => {\n if (!horizontalAlignments[y]) {\n horizontalAlignments[y] = [];\n }\n if (!verticalAlignments[x]) {\n verticalAlignments[x] = [];\n }\n horizontalAlignments[y].push(id);\n verticalAlignments[x].push(id);\n });\n return {\n horiz: Object.values(horizontalAlignments).filter((arr) => arr.length > 1),\n vert: Object.values(verticalAlignments).filter((arr) => arr.length > 1)\n };\n });\n const [horizontal, vertical] = alignments.reduce(\n ([prevHoriz, prevVert], { horiz, vert }) => {\n return [\n [...prevHoriz, ...horiz],\n [...prevVert, ...vert]\n ];\n },\n [[], []]\n );\n return {\n horizontal,\n vertical\n };\n}\n__name(getAlignments, \"getAlignments\");\nfunction getRelativeConstraints(spatialMaps) {\n const relativeConstraints = [];\n const posToStr = /* @__PURE__ */ __name((pos) => `${pos[0]},${pos[1]}`, \"posToStr\");\n const strToPos = /* @__PURE__ */ __name((pos) => pos.split(\",\").map((p) => parseInt(p)), \"strToPos\");\n spatialMaps.forEach((spatialMap) => {\n const invSpatialMap = Object.fromEntries(\n Object.entries(spatialMap).map(([id, pos]) => [posToStr(pos), id])\n );\n const queue = [posToStr([0, 0])];\n const visited = {};\n const directions = {\n L: [-1, 0],\n R: [1, 0],\n T: [0, 1],\n B: [0, -1]\n };\n while (queue.length > 0) {\n const curr = queue.shift();\n if (curr) {\n visited[curr] = 1;\n const currId = invSpatialMap[curr];\n if (currId) {\n const currPos = strToPos(curr);\n Object.entries(directions).forEach(([dir, shift]) => {\n const newPos = posToStr([currPos[0] + shift[0], currPos[1] + shift[1]]);\n const newId = invSpatialMap[newPos];\n if (newId && !visited[newPos]) {\n queue.push(newPos);\n relativeConstraints.push({\n [ArchitectureDirectionName[dir]]: newId,\n [ArchitectureDirectionName[getOppositeArchitectureDirection(dir)]]: currId,\n gap: 1.5 * getConfigField(\"iconSize\")\n });\n }\n });\n }\n }\n }\n });\n return relativeConstraints;\n}\n__name(getRelativeConstraints, \"getRelativeConstraints\");\nfunction layoutArchitecture(services, junctions, groups, edges, { spatialMaps }) {\n return new Promise((resolve) => {\n const renderEl = select(\"body\").append(\"div\").attr(\"id\", \"cy\").attr(\"style\", \"display:none\");\n const cy = cytoscape({\n container: document.getElementById(\"cy\"),\n style: [\n {\n selector: \"edge\",\n style: {\n \"curve-style\": \"straight\",\n label: \"data(label)\",\n \"source-endpoint\": \"data(sourceEndpoint)\",\n \"target-endpoint\": \"data(targetEndpoint)\"\n }\n },\n {\n selector: \"edge.segments\",\n style: {\n \"curve-style\": \"segments\",\n \"segment-weights\": \"0\",\n \"segment-distances\": [0.5],\n // @ts-ignore Incorrect library types\n \"edge-distances\": \"endpoints\",\n \"source-endpoint\": \"data(sourceEndpoint)\",\n \"target-endpoint\": \"data(targetEndpoint)\"\n }\n },\n {\n selector: \"node\",\n style: {\n // @ts-ignore Incorrect library types\n \"compound-sizing-wrt-labels\": \"include\"\n }\n },\n {\n selector: \"node[label]\",\n style: {\n \"text-valign\": \"bottom\",\n \"text-halign\": \"center\",\n \"font-size\": `${getConfigField(\"fontSize\")}px`\n }\n },\n {\n selector: \".node-service\",\n style: {\n label: \"data(label)\",\n width: \"data(width)\",\n height: \"data(height)\"\n }\n },\n {\n selector: \".node-junction\",\n style: {\n width: \"data(width)\",\n height: \"data(height)\"\n }\n },\n {\n selector: \".node-group\",\n style: {\n // @ts-ignore Incorrect library types\n padding: `${getConfigField(\"padding\")}px`\n }\n }\n ]\n });\n renderEl.remove();\n addGroups(groups, cy);\n addServices(services, cy);\n addJunctions(junctions, cy);\n addEdges(edges, cy);\n const alignmentConstraint = getAlignments(spatialMaps);\n const relativePlacementConstraint = getRelativeConstraints(spatialMaps);\n const layout = cy.layout({\n name: \"fcose\",\n quality: \"proof\",\n styleEnabled: false,\n animate: false,\n nodeDimensionsIncludeLabels: false,\n // Adjust the edge parameters if it passes through the border of a group\n // Hacky fix for: https://github.com/iVis-at-Bilkent/cytoscape.js-fcose/issues/67\n idealEdgeLength(edge) {\n const [nodeA, nodeB] = edge.connectedNodes();\n const { parent: parentA } = nodeData(nodeA);\n const { parent: parentB } = nodeData(nodeB);\n const elasticity = parentA === parentB ? 1.5 * getConfigField(\"iconSize\") : 0.5 * getConfigField(\"iconSize\");\n return elasticity;\n },\n edgeElasticity(edge) {\n const [nodeA, nodeB] = edge.connectedNodes();\n const { parent: parentA } = nodeData(nodeA);\n const { parent: parentB } = nodeData(nodeB);\n const elasticity = parentA === parentB ? 0.45 : 1e-3;\n return elasticity;\n },\n alignmentConstraint,\n relativePlacementConstraint\n });\n layout.one(\"layoutstop\", () => {\n function getSegmentWeights(source, target, pointX, pointY) {\n let W, D;\n const { x: sX, y: sY } = source;\n const { x: tX, y: tY } = target;\n D = (pointY - sY + (sX - pointX) * (sY - tY) / (sX - tX)) / Math.sqrt(1 + Math.pow((sY - tY) / (sX - tX), 2));\n W = Math.sqrt(Math.pow(pointY - sY, 2) + Math.pow(pointX - sX, 2) - Math.pow(D, 2));\n const distAB = Math.sqrt(Math.pow(tX - sX, 2) + Math.pow(tY - sY, 2));\n W = W / distAB;\n let delta1 = (tX - sX) * (pointY - sY) - (tY - sY) * (pointX - sX);\n switch (true) {\n case delta1 >= 0:\n delta1 = 1;\n break;\n case delta1 < 0:\n delta1 = -1;\n break;\n }\n let delta2 = (tX - sX) * (pointX - sX) + (tY - sY) * (pointY - sY);\n switch (true) {\n case delta2 >= 0:\n delta2 = 1;\n break;\n case delta2 < 0:\n delta2 = -1;\n break;\n }\n D = Math.abs(D) * delta1;\n W = W * delta2;\n return {\n distances: D,\n weights: W\n };\n }\n __name(getSegmentWeights, \"getSegmentWeights\");\n cy.startBatch();\n for (const edge of Object.values(cy.edges())) {\n if (edge.data?.()) {\n const { x: sX, y: sY } = edge.source().position();\n const { x: tX, y: tY } = edge.target().position();\n if (sX !== tX && sY !== tY) {\n const sEP = edge.sourceEndpoint();\n const tEP = edge.targetEndpoint();\n const { sourceDir } = edgeData(edge);\n const [pointX, pointY] = isArchitectureDirectionY(sourceDir) ? [sEP.x, tEP.y] : [tEP.x, sEP.y];\n const { weights, distances } = getSegmentWeights(sEP, tEP, pointX, pointY);\n edge.style(\"segment-distances\", distances);\n edge.style(\"segment-weights\", weights);\n }\n }\n }\n cy.endBatch();\n layout.run();\n });\n layout.run();\n cy.ready((e) => {\n log.info(\"Ready\", e);\n resolve(cy);\n });\n });\n}\n__name(layoutArchitecture, \"layoutArchitecture\");\nvar draw = /* @__PURE__ */ __name(async (text, id, _version, diagObj) => {\n const db2 = diagObj.db;\n const services = db2.getServices();\n const junctions = db2.getJunctions();\n const groups = db2.getGroups();\n const edges = db2.getEdges();\n const ds = db2.getDataStructures();\n const svg = selectSvgElement(id);\n const edgesElem = svg.append(\"g\");\n edgesElem.attr(\"class\", \"architecture-edges\");\n const servicesElem = svg.append(\"g\");\n servicesElem.attr(\"class\", \"architecture-services\");\n const groupElem = svg.append(\"g\");\n groupElem.attr(\"class\", \"architecture-groups\");\n await drawServices(db2, servicesElem, services);\n drawJunctions(db2, servicesElem, junctions);\n const cy = await layoutArchitecture(services, junctions, groups, edges, ds);\n await drawEdges(edgesElem, cy);\n await drawGroups(groupElem, cy);\n positionNodes(db2, cy);\n setupGraphViewbox(void 0, svg, getConfigField(\"padding\"), getConfigField(\"useMaxWidth\"));\n}, \"draw\");\nvar renderer = { draw };\n\n// src/diagrams/architecture/architectureDiagram.ts\nvar diagram = {\n parser,\n db,\n renderer,\n styles: architectureStyles_default\n};\nexport {\n diagram\n};\n", "/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** `Object#toString` result references. */\nvar symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred invocation.\n */\nvar now = function() {\n return root.Date.now();\n};\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide `options` to indicate whether `func` should be invoked on the\n * leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent\n * calls to the debounced function return the result of the last `func`\n * invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until to the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n result = wait - timeSinceLastCall;\n\n return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastInvokeTime = 0;\n lastArgs = lastCallTime = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = typeof value.valueOf == 'function' ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = debounce;\n", "/*!\nTurbo 8.0.6\nCopyright \u00A9 2024 37signals LLC\n */\n/**\n * The MIT License (MIT)\n *\n * Copyright (c) 2019 Javan Makhmali\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n * THE SOFTWARE.\n */\n\n(function (prototype) {\n if (typeof prototype.requestSubmit == \"function\") return\n\n prototype.requestSubmit = function (submitter) {\n if (submitter) {\n validateSubmitter(submitter, this);\n submitter.click();\n } else {\n submitter = document.createElement(\"input\");\n submitter.type = \"submit\";\n submitter.hidden = true;\n this.appendChild(submitter);\n submitter.click();\n this.removeChild(submitter);\n }\n };\n\n function validateSubmitter(submitter, form) {\n submitter instanceof HTMLElement || raise(TypeError, \"parameter 1 is not of type 'HTMLElement'\");\n submitter.type == \"submit\" || raise(TypeError, \"The specified element is not a submit button\");\n submitter.form == form ||\n raise(DOMException, \"The specified element is not owned by this form element\", \"NotFoundError\");\n }\n\n function raise(errorConstructor, message, name) {\n throw new errorConstructor(\"Failed to execute 'requestSubmit' on 'HTMLFormElement': \" + message + \".\", name)\n }\n})(HTMLFormElement.prototype);\n\nconst submittersByForm = new WeakMap();\n\nfunction findSubmitterFromClickTarget(target) {\n const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;\n const candidate = element ? element.closest(\"input, button\") : null;\n return candidate?.type == \"submit\" ? candidate : null\n}\n\nfunction clickCaptured(event) {\n const submitter = findSubmitterFromClickTarget(event.target);\n\n if (submitter && submitter.form) {\n submittersByForm.set(submitter.form, submitter);\n }\n}\n\n(function () {\n if (\"submitter\" in Event.prototype) return\n\n let prototype = window.Event.prototype;\n // Certain versions of Safari 15 have a bug where they won't\n // populate the submitter. This hurts TurboDrive's enable/disable detection.\n // See https://bugs.webkit.org/show_bug.cgi?id=229660\n if (\"SubmitEvent\" in window) {\n const prototypeOfSubmitEvent = window.SubmitEvent.prototype;\n\n if (/Apple Computer/.test(navigator.vendor) && !(\"submitter\" in prototypeOfSubmitEvent)) {\n prototype = prototypeOfSubmitEvent;\n } else {\n return // polyfill not needed\n }\n }\n\n addEventListener(\"click\", clickCaptured, true);\n\n Object.defineProperty(prototype, \"submitter\", {\n get() {\n if (this.type == \"submit\" && this.target instanceof HTMLFormElement) {\n return submittersByForm.get(this.target)\n }\n }\n });\n})();\n\nconst FrameLoadingStyle = {\n eager: \"eager\",\n lazy: \"lazy\"\n};\n\n/**\n * Contains a fragment of HTML which is updated based on navigation within\n * it (e.g. via links or form submissions).\n *\n * @customElement turbo-frame\n * @example\n * \n * \n * Show all expanded messages in this frame.\n * \n *\n *
\n * Show response from this form within this frame.\n *
\n *
\n */\nclass FrameElement extends HTMLElement {\n static delegateConstructor = undefined\n\n loaded = Promise.resolve()\n\n static get observedAttributes() {\n return [\"disabled\", \"loading\", \"src\"]\n }\n\n constructor() {\n super();\n this.delegate = new FrameElement.delegateConstructor(this);\n }\n\n connectedCallback() {\n this.delegate.connect();\n }\n\n disconnectedCallback() {\n this.delegate.disconnect();\n }\n\n reload() {\n return this.delegate.sourceURLReloaded()\n }\n\n attributeChangedCallback(name) {\n if (name == \"loading\") {\n this.delegate.loadingStyleChanged();\n } else if (name == \"src\") {\n this.delegate.sourceURLChanged();\n } else if (name == \"disabled\") {\n this.delegate.disabledChanged();\n }\n }\n\n /**\n * Gets the URL to lazily load source HTML from\n */\n get src() {\n return this.getAttribute(\"src\")\n }\n\n /**\n * Sets the URL to lazily load source HTML from\n */\n set src(value) {\n if (value) {\n this.setAttribute(\"src\", value);\n } else {\n this.removeAttribute(\"src\");\n }\n }\n\n /**\n * Gets the refresh mode for the frame.\n */\n get refresh() {\n return this.getAttribute(\"refresh\")\n }\n\n /**\n * Sets the refresh mode for the frame.\n */\n set refresh(value) {\n if (value) {\n this.setAttribute(\"refresh\", value);\n } else {\n this.removeAttribute(\"refresh\");\n }\n }\n\n get shouldReloadWithMorph() {\n return this.src && this.refresh === \"morph\"\n }\n\n /**\n * Determines if the element is loading\n */\n get loading() {\n return frameLoadingStyleFromString(this.getAttribute(\"loading\") || \"\")\n }\n\n /**\n * Sets the value of if the element is loading\n */\n set loading(value) {\n if (value) {\n this.setAttribute(\"loading\", value);\n } else {\n this.removeAttribute(\"loading\");\n }\n }\n\n /**\n * Gets the disabled state of the frame.\n *\n * If disabled, no requests will be intercepted by the frame.\n */\n get disabled() {\n return this.hasAttribute(\"disabled\")\n }\n\n /**\n * Sets the disabled state of the frame.\n *\n * If disabled, no requests will be intercepted by the frame.\n */\n set disabled(value) {\n if (value) {\n this.setAttribute(\"disabled\", \"\");\n } else {\n this.removeAttribute(\"disabled\");\n }\n }\n\n /**\n * Gets the autoscroll state of the frame.\n *\n * If true, the frame will be scrolled into view automatically on update.\n */\n get autoscroll() {\n return this.hasAttribute(\"autoscroll\")\n }\n\n /**\n * Sets the autoscroll state of the frame.\n *\n * If true, the frame will be scrolled into view automatically on update.\n */\n set autoscroll(value) {\n if (value) {\n this.setAttribute(\"autoscroll\", \"\");\n } else {\n this.removeAttribute(\"autoscroll\");\n }\n }\n\n /**\n * Determines if the element has finished loading\n */\n get complete() {\n return !this.delegate.isLoading\n }\n\n /**\n * Gets the active state of the frame.\n *\n * If inactive, source changes will not be observed.\n */\n get isActive() {\n return this.ownerDocument === document && !this.isPreview\n }\n\n /**\n * Sets the active state of the frame.\n *\n * If inactive, source changes will not be observed.\n */\n get isPreview() {\n return this.ownerDocument?.documentElement?.hasAttribute(\"data-turbo-preview\")\n }\n}\n\nfunction frameLoadingStyleFromString(style) {\n switch (style.toLowerCase()) {\n case \"lazy\":\n return FrameLoadingStyle.lazy\n default:\n return FrameLoadingStyle.eager\n }\n}\n\nconst drive = {\n enabled: true,\n progressBarDelay: 500,\n unvisitableExtensions: new Set(\n [\n \".7z\", \".aac\", \".apk\", \".avi\", \".bmp\", \".bz2\", \".css\", \".csv\", \".deb\", \".dmg\", \".doc\",\n \".docx\", \".exe\", \".gif\", \".gz\", \".heic\", \".heif\", \".ico\", \".iso\", \".jpeg\", \".jpg\",\n \".js\", \".json\", \".m4a\", \".mkv\", \".mov\", \".mp3\", \".mp4\", \".mpeg\", \".mpg\", \".msi\",\n \".ogg\", \".ogv\", \".pdf\", \".pkg\", \".png\", \".ppt\", \".pptx\", \".rar\", \".rtf\",\n \".svg\", \".tar\", \".tif\", \".tiff\", \".txt\", \".wav\", \".webm\", \".webp\", \".wma\", \".wmv\",\n \".xls\", \".xlsx\", \".xml\", \".zip\"\n ]\n )\n};\n\nfunction activateScriptElement(element) {\n if (element.getAttribute(\"data-turbo-eval\") == \"false\") {\n return element\n } else {\n const createdScriptElement = document.createElement(\"script\");\n const cspNonce = getMetaContent(\"csp-nonce\");\n if (cspNonce) {\n createdScriptElement.nonce = cspNonce;\n }\n createdScriptElement.textContent = element.textContent;\n createdScriptElement.async = false;\n copyElementAttributes(createdScriptElement, element);\n return createdScriptElement\n }\n}\n\nfunction copyElementAttributes(destinationElement, sourceElement) {\n for (const { name, value } of sourceElement.attributes) {\n destinationElement.setAttribute(name, value);\n }\n}\n\nfunction createDocumentFragment(html) {\n const template = document.createElement(\"template\");\n template.innerHTML = html;\n return template.content\n}\n\nfunction dispatch(eventName, { target, cancelable, detail } = {}) {\n const event = new CustomEvent(eventName, {\n cancelable,\n bubbles: true,\n composed: true,\n detail\n });\n\n if (target && target.isConnected) {\n target.dispatchEvent(event);\n } else {\n document.documentElement.dispatchEvent(event);\n }\n\n return event\n}\n\nfunction cancelEvent(event) {\n event.preventDefault();\n event.stopImmediatePropagation();\n}\n\nfunction nextRepaint() {\n if (document.visibilityState === \"hidden\") {\n return nextEventLoopTick()\n } else {\n return nextAnimationFrame()\n }\n}\n\nfunction nextAnimationFrame() {\n return new Promise((resolve) => requestAnimationFrame(() => resolve()))\n}\n\nfunction nextEventLoopTick() {\n return new Promise((resolve) => setTimeout(() => resolve(), 0))\n}\n\nfunction nextMicrotask() {\n return Promise.resolve()\n}\n\nfunction parseHTMLDocument(html = \"\") {\n return new DOMParser().parseFromString(html, \"text/html\")\n}\n\nfunction unindent(strings, ...values) {\n const lines = interpolate(strings, values).replace(/^\\n/, \"\").split(\"\\n\");\n const match = lines[0].match(/^\\s+/);\n const indent = match ? match[0].length : 0;\n return lines.map((line) => line.slice(indent)).join(\"\\n\")\n}\n\nfunction interpolate(strings, values) {\n return strings.reduce((result, string, i) => {\n const value = values[i] == undefined ? \"\" : values[i];\n return result + string + value\n }, \"\")\n}\n\nfunction uuid() {\n return Array.from({ length: 36 })\n .map((_, i) => {\n if (i == 8 || i == 13 || i == 18 || i == 23) {\n return \"-\"\n } else if (i == 14) {\n return \"4\"\n } else if (i == 19) {\n return (Math.floor(Math.random() * 4) + 8).toString(16)\n } else {\n return Math.floor(Math.random() * 15).toString(16)\n }\n })\n .join(\"\")\n}\n\nfunction getAttribute(attributeName, ...elements) {\n for (const value of elements.map((element) => element?.getAttribute(attributeName))) {\n if (typeof value == \"string\") return value\n }\n\n return null\n}\n\nfunction hasAttribute(attributeName, ...elements) {\n return elements.some((element) => element && element.hasAttribute(attributeName))\n}\n\nfunction markAsBusy(...elements) {\n for (const element of elements) {\n if (element.localName == \"turbo-frame\") {\n element.setAttribute(\"busy\", \"\");\n }\n element.setAttribute(\"aria-busy\", \"true\");\n }\n}\n\nfunction clearBusyState(...elements) {\n for (const element of elements) {\n if (element.localName == \"turbo-frame\") {\n element.removeAttribute(\"busy\");\n }\n\n element.removeAttribute(\"aria-busy\");\n }\n}\n\nfunction waitForLoad(element, timeoutInMilliseconds = 2000) {\n return new Promise((resolve) => {\n const onComplete = () => {\n element.removeEventListener(\"error\", onComplete);\n element.removeEventListener(\"load\", onComplete);\n resolve();\n };\n\n element.addEventListener(\"load\", onComplete, { once: true });\n element.addEventListener(\"error\", onComplete, { once: true });\n setTimeout(resolve, timeoutInMilliseconds);\n })\n}\n\nfunction getHistoryMethodForAction(action) {\n switch (action) {\n case \"replace\":\n return history.replaceState\n case \"advance\":\n case \"restore\":\n return history.pushState\n }\n}\n\nfunction isAction(action) {\n return action == \"advance\" || action == \"replace\" || action == \"restore\"\n}\n\nfunction getVisitAction(...elements) {\n const action = getAttribute(\"data-turbo-action\", ...elements);\n\n return isAction(action) ? action : null\n}\n\nfunction getMetaElement(name) {\n return document.querySelector(`meta[name=\"${name}\"]`)\n}\n\nfunction getMetaContent(name) {\n const element = getMetaElement(name);\n return element && element.content\n}\n\nfunction setMetaContent(name, content) {\n let element = getMetaElement(name);\n\n if (!element) {\n element = document.createElement(\"meta\");\n element.setAttribute(\"name\", name);\n\n document.head.appendChild(element);\n }\n\n element.setAttribute(\"content\", content);\n\n return element\n}\n\nfunction findClosestRecursively(element, selector) {\n if (element instanceof Element) {\n return (\n element.closest(selector) || findClosestRecursively(element.assignedSlot || element.getRootNode()?.host, selector)\n )\n }\n}\n\nfunction elementIsFocusable(element) {\n const inertDisabledOrHidden = \"[inert], :disabled, [hidden], details:not([open]), dialog:not([open])\";\n\n return !!element && element.closest(inertDisabledOrHidden) == null && typeof element.focus == \"function\"\n}\n\nfunction queryAutofocusableElement(elementOrDocumentFragment) {\n return Array.from(elementOrDocumentFragment.querySelectorAll(\"[autofocus]\")).find(elementIsFocusable)\n}\n\nasync function around(callback, reader) {\n const before = reader();\n\n callback();\n\n await nextAnimationFrame();\n\n const after = reader();\n\n return [before, after]\n}\n\nfunction doesNotTargetIFrame(name) {\n if (name === \"_blank\") {\n return false\n } else if (name) {\n for (const element of document.getElementsByName(name)) {\n if (element instanceof HTMLIFrameElement) return false\n }\n\n return true\n } else {\n return true\n }\n}\n\nfunction findLinkFromClickTarget(target) {\n return findClosestRecursively(target, \"a[href]:not([target^=_]):not([download])\")\n}\n\nfunction getLocationForLink(link) {\n return expandURL(link.getAttribute(\"href\") || \"\")\n}\n\nfunction debounce(fn, delay) {\n let timeoutId = null;\n\n return (...args) => {\n const callback = () => fn.apply(this, args);\n clearTimeout(timeoutId);\n timeoutId = setTimeout(callback, delay);\n }\n}\n\nconst submitter = {\n \"aria-disabled\": {\n beforeSubmit: submitter => {\n submitter.setAttribute(\"aria-disabled\", \"true\");\n submitter.addEventListener(\"click\", cancelEvent);\n },\n\n afterSubmit: submitter => {\n submitter.removeAttribute(\"aria-disabled\");\n submitter.removeEventListener(\"click\", cancelEvent);\n }\n },\n\n \"disabled\": {\n beforeSubmit: submitter => submitter.disabled = true,\n afterSubmit: submitter => submitter.disabled = false\n }\n};\n\nclass Config {\n #submitter = null\n\n constructor(config) {\n Object.assign(this, config);\n }\n\n get submitter() {\n return this.#submitter\n }\n\n set submitter(value) {\n this.#submitter = submitter[value] || value;\n }\n}\n\nconst forms = new Config({\n mode: \"on\",\n submitter: \"disabled\"\n});\n\nconst config = {\n drive,\n forms\n};\n\nfunction expandURL(locatable) {\n return new URL(locatable.toString(), document.baseURI)\n}\n\nfunction getAnchor(url) {\n let anchorMatch;\n if (url.hash) {\n return url.hash.slice(1)\n // eslint-disable-next-line no-cond-assign\n } else if ((anchorMatch = url.href.match(/#(.*)$/))) {\n return anchorMatch[1]\n }\n}\n\nfunction getAction$1(form, submitter) {\n const action = submitter?.getAttribute(\"formaction\") || form.getAttribute(\"action\") || form.action;\n\n return expandURL(action)\n}\n\nfunction getExtension(url) {\n return (getLastPathComponent(url).match(/\\.[^.]*$/) || [])[0] || \"\"\n}\n\nfunction isPrefixedBy(baseURL, url) {\n const prefix = getPrefix(url);\n return baseURL.href === expandURL(prefix).href || baseURL.href.startsWith(prefix)\n}\n\nfunction locationIsVisitable(location, rootLocation) {\n return isPrefixedBy(location, rootLocation) && !config.drive.unvisitableExtensions.has(getExtension(location))\n}\n\nfunction getRequestURL(url) {\n const anchor = getAnchor(url);\n return anchor != null ? url.href.slice(0, -(anchor.length + 1)) : url.href\n}\n\nfunction toCacheKey(url) {\n return getRequestURL(url)\n}\n\nfunction urlsAreEqual(left, right) {\n return expandURL(left).href == expandURL(right).href\n}\n\nfunction getPathComponents(url) {\n return url.pathname.split(\"/\").slice(1)\n}\n\nfunction getLastPathComponent(url) {\n return getPathComponents(url).slice(-1)[0]\n}\n\nfunction getPrefix(url) {\n return addTrailingSlash(url.origin + url.pathname)\n}\n\nfunction addTrailingSlash(value) {\n return value.endsWith(\"/\") ? value : value + \"/\"\n}\n\nclass FetchResponse {\n constructor(response) {\n this.response = response;\n }\n\n get succeeded() {\n return this.response.ok\n }\n\n get failed() {\n return !this.succeeded\n }\n\n get clientError() {\n return this.statusCode >= 400 && this.statusCode <= 499\n }\n\n get serverError() {\n return this.statusCode >= 500 && this.statusCode <= 599\n }\n\n get redirected() {\n return this.response.redirected\n }\n\n get location() {\n return expandURL(this.response.url)\n }\n\n get isHTML() {\n return this.contentType && this.contentType.match(/^(?:text\\/([^\\s;,]+\\b)?html|application\\/xhtml\\+xml)\\b/)\n }\n\n get statusCode() {\n return this.response.status\n }\n\n get contentType() {\n return this.header(\"Content-Type\")\n }\n\n get responseText() {\n return this.response.clone().text()\n }\n\n get responseHTML() {\n if (this.isHTML) {\n return this.response.clone().text()\n } else {\n return Promise.resolve(undefined)\n }\n }\n\n header(name) {\n return this.response.headers.get(name)\n }\n}\n\nclass LimitedSet extends Set {\n constructor(maxSize) {\n super();\n this.maxSize = maxSize;\n }\n\n add(value) {\n if (this.size >= this.maxSize) {\n const iterator = this.values();\n const oldestValue = iterator.next().value;\n this.delete(oldestValue);\n }\n super.add(value);\n }\n}\n\nconst recentRequests = new LimitedSet(20);\n\nconst nativeFetch = window.fetch;\n\nfunction fetchWithTurboHeaders(url, options = {}) {\n const modifiedHeaders = new Headers(options.headers || {});\n const requestUID = uuid();\n recentRequests.add(requestUID);\n modifiedHeaders.append(\"X-Turbo-Request-Id\", requestUID);\n\n return nativeFetch(url, {\n ...options,\n headers: modifiedHeaders\n })\n}\n\nfunction fetchMethodFromString(method) {\n switch (method.toLowerCase()) {\n case \"get\":\n return FetchMethod.get\n case \"post\":\n return FetchMethod.post\n case \"put\":\n return FetchMethod.put\n case \"patch\":\n return FetchMethod.patch\n case \"delete\":\n return FetchMethod.delete\n }\n}\n\nconst FetchMethod = {\n get: \"get\",\n post: \"post\",\n put: \"put\",\n patch: \"patch\",\n delete: \"delete\"\n};\n\nfunction fetchEnctypeFromString(encoding) {\n switch (encoding.toLowerCase()) {\n case FetchEnctype.multipart:\n return FetchEnctype.multipart\n case FetchEnctype.plain:\n return FetchEnctype.plain\n default:\n return FetchEnctype.urlEncoded\n }\n}\n\nconst FetchEnctype = {\n urlEncoded: \"application/x-www-form-urlencoded\",\n multipart: \"multipart/form-data\",\n plain: \"text/plain\"\n};\n\nclass FetchRequest {\n abortController = new AbortController()\n #resolveRequestPromise = (_value) => {}\n\n constructor(delegate, method, location, requestBody = new URLSearchParams(), target = null, enctype = FetchEnctype.urlEncoded) {\n const [url, body] = buildResourceAndBody(expandURL(location), method, requestBody, enctype);\n\n this.delegate = delegate;\n this.url = url;\n this.target = target;\n this.fetchOptions = {\n credentials: \"same-origin\",\n redirect: \"follow\",\n method: method.toUpperCase(),\n headers: { ...this.defaultHeaders },\n body: body,\n signal: this.abortSignal,\n referrer: this.delegate.referrer?.href\n };\n this.enctype = enctype;\n }\n\n get method() {\n return this.fetchOptions.method\n }\n\n set method(value) {\n const fetchBody = this.isSafe ? this.url.searchParams : this.fetchOptions.body || new FormData();\n const fetchMethod = fetchMethodFromString(value) || FetchMethod.get;\n\n this.url.search = \"\";\n\n const [url, body] = buildResourceAndBody(this.url, fetchMethod, fetchBody, this.enctype);\n\n this.url = url;\n this.fetchOptions.body = body;\n this.fetchOptions.method = fetchMethod.toUpperCase();\n }\n\n get headers() {\n return this.fetchOptions.headers\n }\n\n set headers(value) {\n this.fetchOptions.headers = value;\n }\n\n get body() {\n if (this.isSafe) {\n return this.url.searchParams\n } else {\n return this.fetchOptions.body\n }\n }\n\n set body(value) {\n this.fetchOptions.body = value;\n }\n\n get location() {\n return this.url\n }\n\n get params() {\n return this.url.searchParams\n }\n\n get entries() {\n return this.body ? Array.from(this.body.entries()) : []\n }\n\n cancel() {\n this.abortController.abort();\n }\n\n async perform() {\n const { fetchOptions } = this;\n this.delegate.prepareRequest(this);\n const event = await this.#allowRequestToBeIntercepted(fetchOptions);\n try {\n this.delegate.requestStarted(this);\n\n if (event.detail.fetchRequest) {\n this.response = event.detail.fetchRequest.response;\n } else {\n this.response = fetchWithTurboHeaders(this.url.href, fetchOptions);\n }\n\n const response = await this.response;\n return await this.receive(response)\n } catch (error) {\n if (error.name !== \"AbortError\") {\n if (this.#willDelegateErrorHandling(error)) {\n this.delegate.requestErrored(this, error);\n }\n throw error\n }\n } finally {\n this.delegate.requestFinished(this);\n }\n }\n\n async receive(response) {\n const fetchResponse = new FetchResponse(response);\n const event = dispatch(\"turbo:before-fetch-response\", {\n cancelable: true,\n detail: { fetchResponse },\n target: this.target\n });\n if (event.defaultPrevented) {\n this.delegate.requestPreventedHandlingResponse(this, fetchResponse);\n } else if (fetchResponse.succeeded) {\n this.delegate.requestSucceededWithResponse(this, fetchResponse);\n } else {\n this.delegate.requestFailedWithResponse(this, fetchResponse);\n }\n return fetchResponse\n }\n\n get defaultHeaders() {\n return {\n Accept: \"text/html, application/xhtml+xml\"\n }\n }\n\n get isSafe() {\n return isSafe(this.method)\n }\n\n get abortSignal() {\n return this.abortController.signal\n }\n\n acceptResponseType(mimeType) {\n this.headers[\"Accept\"] = [mimeType, this.headers[\"Accept\"]].join(\", \");\n }\n\n async #allowRequestToBeIntercepted(fetchOptions) {\n const requestInterception = new Promise((resolve) => (this.#resolveRequestPromise = resolve));\n const event = dispatch(\"turbo:before-fetch-request\", {\n cancelable: true,\n detail: {\n fetchOptions,\n url: this.url,\n resume: this.#resolveRequestPromise\n },\n target: this.target\n });\n this.url = event.detail.url;\n if (event.defaultPrevented) await requestInterception;\n\n return event\n }\n\n #willDelegateErrorHandling(error) {\n const event = dispatch(\"turbo:fetch-request-error\", {\n target: this.target,\n cancelable: true,\n detail: { request: this, error: error }\n });\n\n return !event.defaultPrevented\n }\n}\n\nfunction isSafe(fetchMethod) {\n return fetchMethodFromString(fetchMethod) == FetchMethod.get\n}\n\nfunction buildResourceAndBody(resource, method, requestBody, enctype) {\n const searchParams =\n Array.from(requestBody).length > 0 ? new URLSearchParams(entriesExcludingFiles(requestBody)) : resource.searchParams;\n\n if (isSafe(method)) {\n return [mergeIntoURLSearchParams(resource, searchParams), null]\n } else if (enctype == FetchEnctype.urlEncoded) {\n return [resource, searchParams]\n } else {\n return [resource, requestBody]\n }\n}\n\nfunction entriesExcludingFiles(requestBody) {\n const entries = [];\n\n for (const [name, value] of requestBody) {\n if (value instanceof File) continue\n else entries.push([name, value]);\n }\n\n return entries\n}\n\nfunction mergeIntoURLSearchParams(url, requestBody) {\n const searchParams = new URLSearchParams(entriesExcludingFiles(requestBody));\n\n url.search = searchParams.toString();\n\n return url\n}\n\nclass AppearanceObserver {\n started = false\n\n constructor(delegate, element) {\n this.delegate = delegate;\n this.element = element;\n this.intersectionObserver = new IntersectionObserver(this.intersect);\n }\n\n start() {\n if (!this.started) {\n this.started = true;\n this.intersectionObserver.observe(this.element);\n }\n }\n\n stop() {\n if (this.started) {\n this.started = false;\n this.intersectionObserver.unobserve(this.element);\n }\n }\n\n intersect = (entries) => {\n const lastEntry = entries.slice(-1)[0];\n if (lastEntry?.isIntersecting) {\n this.delegate.elementAppearedInViewport(this.element);\n }\n }\n}\n\nclass StreamMessage {\n static contentType = \"text/vnd.turbo-stream.html\"\n\n static wrap(message) {\n if (typeof message == \"string\") {\n return new this(createDocumentFragment(message))\n } else {\n return message\n }\n }\n\n constructor(fragment) {\n this.fragment = importStreamElements(fragment);\n }\n}\n\nfunction importStreamElements(fragment) {\n for (const element of fragment.querySelectorAll(\"turbo-stream\")) {\n const streamElement = document.importNode(element, true);\n\n for (const inertScriptElement of streamElement.templateElement.content.querySelectorAll(\"script\")) {\n inertScriptElement.replaceWith(activateScriptElement(inertScriptElement));\n }\n\n element.replaceWith(streamElement);\n }\n\n return fragment\n}\n\nconst PREFETCH_DELAY = 100;\n\nclass PrefetchCache {\n #prefetchTimeout = null\n #prefetched = null\n\n get(url) {\n if (this.#prefetched && this.#prefetched.url === url && this.#prefetched.expire > Date.now()) {\n return this.#prefetched.request\n }\n }\n\n setLater(url, request, ttl) {\n this.clear();\n\n this.#prefetchTimeout = setTimeout(() => {\n request.perform();\n this.set(url, request, ttl);\n this.#prefetchTimeout = null;\n }, PREFETCH_DELAY);\n }\n\n set(url, request, ttl) {\n this.#prefetched = { url, request, expire: new Date(new Date().getTime() + ttl) };\n }\n\n clear() {\n if (this.#prefetchTimeout) clearTimeout(this.#prefetchTimeout);\n this.#prefetched = null;\n }\n}\n\nconst cacheTtl = 10 * 1000;\nconst prefetchCache = new PrefetchCache();\n\nconst FormSubmissionState = {\n initialized: \"initialized\",\n requesting: \"requesting\",\n waiting: \"waiting\",\n receiving: \"receiving\",\n stopping: \"stopping\",\n stopped: \"stopped\"\n};\n\nclass FormSubmission {\n state = FormSubmissionState.initialized\n\n static confirmMethod(message) {\n return Promise.resolve(confirm(message))\n }\n\n constructor(delegate, formElement, submitter, mustRedirect = false) {\n const method = getMethod(formElement, submitter);\n const action = getAction(getFormAction(formElement, submitter), method);\n const body = buildFormData(formElement, submitter);\n const enctype = getEnctype(formElement, submitter);\n\n this.delegate = delegate;\n this.formElement = formElement;\n this.submitter = submitter;\n this.fetchRequest = new FetchRequest(this, method, action, body, formElement, enctype);\n this.mustRedirect = mustRedirect;\n }\n\n get method() {\n return this.fetchRequest.method\n }\n\n set method(value) {\n this.fetchRequest.method = value;\n }\n\n get action() {\n return this.fetchRequest.url.toString()\n }\n\n set action(value) {\n this.fetchRequest.url = expandURL(value);\n }\n\n get body() {\n return this.fetchRequest.body\n }\n\n get enctype() {\n return this.fetchRequest.enctype\n }\n\n get isSafe() {\n return this.fetchRequest.isSafe\n }\n\n get location() {\n return this.fetchRequest.url\n }\n\n // The submission process\n\n async start() {\n const { initialized, requesting } = FormSubmissionState;\n const confirmationMessage = getAttribute(\"data-turbo-confirm\", this.submitter, this.formElement);\n\n if (typeof confirmationMessage === \"string\") {\n const confirmMethod = typeof config.forms.confirm === \"function\" ?\n config.forms.confirm :\n FormSubmission.confirmMethod;\n\n const answer = await confirmMethod(confirmationMessage, this.formElement, this.submitter);\n if (!answer) {\n return\n }\n }\n\n if (this.state == initialized) {\n this.state = requesting;\n return this.fetchRequest.perform()\n }\n }\n\n stop() {\n const { stopping, stopped } = FormSubmissionState;\n if (this.state != stopping && this.state != stopped) {\n this.state = stopping;\n this.fetchRequest.cancel();\n return true\n }\n }\n\n // Fetch request delegate\n\n prepareRequest(request) {\n if (!request.isSafe) {\n const token = getCookieValue(getMetaContent(\"csrf-param\")) || getMetaContent(\"csrf-token\");\n if (token) {\n request.headers[\"X-CSRF-Token\"] = token;\n }\n }\n\n if (this.requestAcceptsTurboStreamResponse(request)) {\n request.acceptResponseType(StreamMessage.contentType);\n }\n }\n\n requestStarted(_request) {\n this.state = FormSubmissionState.waiting;\n if (this.submitter) config.forms.submitter.beforeSubmit(this.submitter);\n this.setSubmitsWith();\n markAsBusy(this.formElement);\n dispatch(\"turbo:submit-start\", {\n target: this.formElement,\n detail: { formSubmission: this }\n });\n this.delegate.formSubmissionStarted(this);\n }\n\n requestPreventedHandlingResponse(request, response) {\n prefetchCache.clear();\n\n this.result = { success: response.succeeded, fetchResponse: response };\n }\n\n requestSucceededWithResponse(request, response) {\n if (response.clientError || response.serverError) {\n this.delegate.formSubmissionFailedWithResponse(this, response);\n return\n }\n\n prefetchCache.clear();\n\n if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) {\n const error = new Error(\"Form responses must redirect to another location\");\n this.delegate.formSubmissionErrored(this, error);\n } else {\n this.state = FormSubmissionState.receiving;\n this.result = { success: true, fetchResponse: response };\n this.delegate.formSubmissionSucceededWithResponse(this, response);\n }\n }\n\n requestFailedWithResponse(request, response) {\n this.result = { success: false, fetchResponse: response };\n this.delegate.formSubmissionFailedWithResponse(this, response);\n }\n\n requestErrored(request, error) {\n this.result = { success: false, error };\n this.delegate.formSubmissionErrored(this, error);\n }\n\n requestFinished(_request) {\n this.state = FormSubmissionState.stopped;\n if (this.submitter) config.forms.submitter.afterSubmit(this.submitter);\n this.resetSubmitterText();\n clearBusyState(this.formElement);\n dispatch(\"turbo:submit-end\", {\n target: this.formElement,\n detail: { formSubmission: this, ...this.result }\n });\n this.delegate.formSubmissionFinished(this);\n }\n\n // Private\n\n setSubmitsWith() {\n if (!this.submitter || !this.submitsWith) return\n\n if (this.submitter.matches(\"button\")) {\n this.originalSubmitText = this.submitter.innerHTML;\n this.submitter.innerHTML = this.submitsWith;\n } else if (this.submitter.matches(\"input\")) {\n const input = this.submitter;\n this.originalSubmitText = input.value;\n input.value = this.submitsWith;\n }\n }\n\n resetSubmitterText() {\n if (!this.submitter || !this.originalSubmitText) return\n\n if (this.submitter.matches(\"button\")) {\n this.submitter.innerHTML = this.originalSubmitText;\n } else if (this.submitter.matches(\"input\")) {\n const input = this.submitter;\n input.value = this.originalSubmitText;\n }\n }\n\n requestMustRedirect(request) {\n return !request.isSafe && this.mustRedirect\n }\n\n requestAcceptsTurboStreamResponse(request) {\n return !request.isSafe || hasAttribute(\"data-turbo-stream\", this.submitter, this.formElement)\n }\n\n get submitsWith() {\n return this.submitter?.getAttribute(\"data-turbo-submits-with\")\n }\n}\n\nfunction buildFormData(formElement, submitter) {\n const formData = new FormData(formElement);\n const name = submitter?.getAttribute(\"name\");\n const value = submitter?.getAttribute(\"value\");\n\n if (name) {\n formData.append(name, value || \"\");\n }\n\n return formData\n}\n\nfunction getCookieValue(cookieName) {\n if (cookieName != null) {\n const cookies = document.cookie ? document.cookie.split(\"; \") : [];\n const cookie = cookies.find((cookie) => cookie.startsWith(cookieName));\n if (cookie) {\n const value = cookie.split(\"=\").slice(1).join(\"=\");\n return value ? decodeURIComponent(value) : undefined\n }\n }\n}\n\nfunction responseSucceededWithoutRedirect(response) {\n return response.statusCode == 200 && !response.redirected\n}\n\nfunction getFormAction(formElement, submitter) {\n const formElementAction = typeof formElement.action === \"string\" ? formElement.action : null;\n\n if (submitter?.hasAttribute(\"formaction\")) {\n return submitter.getAttribute(\"formaction\") || \"\"\n } else {\n return formElement.getAttribute(\"action\") || formElementAction || \"\"\n }\n}\n\nfunction getAction(formAction, fetchMethod) {\n const action = expandURL(formAction);\n\n if (isSafe(fetchMethod)) {\n action.search = \"\";\n }\n\n return action\n}\n\nfunction getMethod(formElement, submitter) {\n const method = submitter?.getAttribute(\"formmethod\") || formElement.getAttribute(\"method\") || \"\";\n return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get\n}\n\nfunction getEnctype(formElement, submitter) {\n return fetchEnctypeFromString(submitter?.getAttribute(\"formenctype\") || formElement.enctype)\n}\n\nclass Snapshot {\n constructor(element) {\n this.element = element;\n }\n\n get activeElement() {\n return this.element.ownerDocument.activeElement\n }\n\n get children() {\n return [...this.element.children]\n }\n\n hasAnchor(anchor) {\n return this.getElementForAnchor(anchor) != null\n }\n\n getElementForAnchor(anchor) {\n return anchor ? this.element.querySelector(`[id='${anchor}'], a[name='${anchor}']`) : null\n }\n\n get isConnected() {\n return this.element.isConnected\n }\n\n get firstAutofocusableElement() {\n return queryAutofocusableElement(this.element)\n }\n\n get permanentElements() {\n return queryPermanentElementsAll(this.element)\n }\n\n getPermanentElementById(id) {\n return getPermanentElementById(this.element, id)\n }\n\n getPermanentElementMapForSnapshot(snapshot) {\n const permanentElementMap = {};\n\n for (const currentPermanentElement of this.permanentElements) {\n const { id } = currentPermanentElement;\n const newPermanentElement = snapshot.getPermanentElementById(id);\n if (newPermanentElement) {\n permanentElementMap[id] = [currentPermanentElement, newPermanentElement];\n }\n }\n\n return permanentElementMap\n }\n}\n\nfunction getPermanentElementById(node, id) {\n return node.querySelector(`#${id}[data-turbo-permanent]`)\n}\n\nfunction queryPermanentElementsAll(node) {\n return node.querySelectorAll(\"[id][data-turbo-permanent]\")\n}\n\nclass FormSubmitObserver {\n started = false\n\n constructor(delegate, eventTarget) {\n this.delegate = delegate;\n this.eventTarget = eventTarget;\n }\n\n start() {\n if (!this.started) {\n this.eventTarget.addEventListener(\"submit\", this.submitCaptured, true);\n this.started = true;\n }\n }\n\n stop() {\n if (this.started) {\n this.eventTarget.removeEventListener(\"submit\", this.submitCaptured, true);\n this.started = false;\n }\n }\n\n submitCaptured = () => {\n this.eventTarget.removeEventListener(\"submit\", this.submitBubbled, false);\n this.eventTarget.addEventListener(\"submit\", this.submitBubbled, false);\n }\n\n submitBubbled = (event) => {\n if (!event.defaultPrevented) {\n const form = event.target instanceof HTMLFormElement ? event.target : undefined;\n const submitter = event.submitter || undefined;\n\n if (\n form &&\n submissionDoesNotDismissDialog(form, submitter) &&\n submissionDoesNotTargetIFrame(form, submitter) &&\n this.delegate.willSubmitForm(form, submitter)\n ) {\n event.preventDefault();\n event.stopImmediatePropagation();\n this.delegate.formSubmitted(form, submitter);\n }\n }\n }\n}\n\nfunction submissionDoesNotDismissDialog(form, submitter) {\n const method = submitter?.getAttribute(\"formmethod\") || form.getAttribute(\"method\");\n\n return method != \"dialog\"\n}\n\nfunction submissionDoesNotTargetIFrame(form, submitter) {\n const target = submitter?.getAttribute(\"formtarget\") || form.getAttribute(\"target\");\n\n return doesNotTargetIFrame(target)\n}\n\nclass View {\n #resolveRenderPromise = (_value) => {}\n #resolveInterceptionPromise = (_value) => {}\n\n constructor(delegate, element) {\n this.delegate = delegate;\n this.element = element;\n }\n\n // Scrolling\n\n scrollToAnchor(anchor) {\n const element = this.snapshot.getElementForAnchor(anchor);\n if (element) {\n this.scrollToElement(element);\n this.focusElement(element);\n } else {\n this.scrollToPosition({ x: 0, y: 0 });\n }\n }\n\n scrollToAnchorFromLocation(location) {\n this.scrollToAnchor(getAnchor(location));\n }\n\n scrollToElement(element) {\n element.scrollIntoView();\n }\n\n focusElement(element) {\n if (element instanceof HTMLElement) {\n if (element.hasAttribute(\"tabindex\")) {\n element.focus();\n } else {\n element.setAttribute(\"tabindex\", \"-1\");\n element.focus();\n element.removeAttribute(\"tabindex\");\n }\n }\n }\n\n scrollToPosition({ x, y }) {\n this.scrollRoot.scrollTo(x, y);\n }\n\n scrollToTop() {\n this.scrollToPosition({ x: 0, y: 0 });\n }\n\n get scrollRoot() {\n return window\n }\n\n // Rendering\n\n async render(renderer) {\n const { isPreview, shouldRender, willRender, newSnapshot: snapshot } = renderer;\n\n // A workaround to ignore tracked element mismatch reloads when performing\n // a promoted Visit from a frame navigation\n const shouldInvalidate = willRender;\n\n if (shouldRender) {\n try {\n this.renderPromise = new Promise((resolve) => (this.#resolveRenderPromise = resolve));\n this.renderer = renderer;\n await this.prepareToRenderSnapshot(renderer);\n\n const renderInterception = new Promise((resolve) => (this.#resolveInterceptionPromise = resolve));\n const options = { resume: this.#resolveInterceptionPromise, render: this.renderer.renderElement, renderMethod: this.renderer.renderMethod };\n const immediateRender = this.delegate.allowsImmediateRender(snapshot, options);\n if (!immediateRender) await renderInterception;\n\n await this.renderSnapshot(renderer);\n this.delegate.viewRenderedSnapshot(snapshot, isPreview, this.renderer.renderMethod);\n this.delegate.preloadOnLoadLinksForView(this.element);\n this.finishRenderingSnapshot(renderer);\n } finally {\n delete this.renderer;\n this.#resolveRenderPromise(undefined);\n delete this.renderPromise;\n }\n } else if (shouldInvalidate) {\n this.invalidate(renderer.reloadReason);\n }\n }\n\n invalidate(reason) {\n this.delegate.viewInvalidated(reason);\n }\n\n async prepareToRenderSnapshot(renderer) {\n this.markAsPreview(renderer.isPreview);\n await renderer.prepareToRender();\n }\n\n markAsPreview(isPreview) {\n if (isPreview) {\n this.element.setAttribute(\"data-turbo-preview\", \"\");\n } else {\n this.element.removeAttribute(\"data-turbo-preview\");\n }\n }\n\n markVisitDirection(direction) {\n this.element.setAttribute(\"data-turbo-visit-direction\", direction);\n }\n\n unmarkVisitDirection() {\n this.element.removeAttribute(\"data-turbo-visit-direction\");\n }\n\n async renderSnapshot(renderer) {\n await renderer.render();\n }\n\n finishRenderingSnapshot(renderer) {\n renderer.finishRendering();\n }\n}\n\nclass FrameView extends View {\n missing() {\n this.element.innerHTML = `Content missing`;\n }\n\n get snapshot() {\n return new Snapshot(this.element)\n }\n}\n\nclass LinkInterceptor {\n constructor(delegate, element) {\n this.delegate = delegate;\n this.element = element;\n }\n\n start() {\n this.element.addEventListener(\"click\", this.clickBubbled);\n document.addEventListener(\"turbo:click\", this.linkClicked);\n document.addEventListener(\"turbo:before-visit\", this.willVisit);\n }\n\n stop() {\n this.element.removeEventListener(\"click\", this.clickBubbled);\n document.removeEventListener(\"turbo:click\", this.linkClicked);\n document.removeEventListener(\"turbo:before-visit\", this.willVisit);\n }\n\n clickBubbled = (event) => {\n if (this.clickEventIsSignificant(event)) {\n this.clickEvent = event;\n } else {\n delete this.clickEvent;\n }\n }\n\n linkClicked = (event) => {\n if (this.clickEvent && this.clickEventIsSignificant(event)) {\n if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url, event.detail.originalEvent)) {\n this.clickEvent.preventDefault();\n event.preventDefault();\n this.delegate.linkClickIntercepted(event.target, event.detail.url, event.detail.originalEvent);\n }\n }\n delete this.clickEvent;\n }\n\n willVisit = (_event) => {\n delete this.clickEvent;\n }\n\n clickEventIsSignificant(event) {\n const target = event.composed ? event.target?.parentElement : event.target;\n const element = findLinkFromClickTarget(target) || target;\n\n return element instanceof Element && element.closest(\"turbo-frame, html\") == this.element\n }\n}\n\nclass LinkClickObserver {\n started = false\n\n constructor(delegate, eventTarget) {\n this.delegate = delegate;\n this.eventTarget = eventTarget;\n }\n\n start() {\n if (!this.started) {\n this.eventTarget.addEventListener(\"click\", this.clickCaptured, true);\n this.started = true;\n }\n }\n\n stop() {\n if (this.started) {\n this.eventTarget.removeEventListener(\"click\", this.clickCaptured, true);\n this.started = false;\n }\n }\n\n clickCaptured = () => {\n this.eventTarget.removeEventListener(\"click\", this.clickBubbled, false);\n this.eventTarget.addEventListener(\"click\", this.clickBubbled, false);\n }\n\n clickBubbled = (event) => {\n if (event instanceof MouseEvent && this.clickEventIsSignificant(event)) {\n const target = (event.composedPath && event.composedPath()[0]) || event.target;\n const link = findLinkFromClickTarget(target);\n if (link && doesNotTargetIFrame(link.target)) {\n const location = getLocationForLink(link);\n if (this.delegate.willFollowLinkToLocation(link, location, event)) {\n event.preventDefault();\n this.delegate.followedLinkToLocation(link, location);\n }\n }\n }\n }\n\n clickEventIsSignificant(event) {\n return !(\n (event.target && event.target.isContentEditable) ||\n event.defaultPrevented ||\n event.which > 1 ||\n event.altKey ||\n event.ctrlKey ||\n event.metaKey ||\n event.shiftKey\n )\n }\n}\n\nclass FormLinkClickObserver {\n constructor(delegate, element) {\n this.delegate = delegate;\n this.linkInterceptor = new LinkClickObserver(this, element);\n }\n\n start() {\n this.linkInterceptor.start();\n }\n\n stop() {\n this.linkInterceptor.stop();\n }\n\n // Link hover observer delegate\n\n canPrefetchRequestToLocation(link, location) {\n return false\n }\n\n prefetchAndCacheRequestToLocation(link, location) {\n return\n }\n\n // Link click observer delegate\n\n willFollowLinkToLocation(link, location, originalEvent) {\n return (\n this.delegate.willSubmitFormLinkToLocation(link, location, originalEvent) &&\n (link.hasAttribute(\"data-turbo-method\") || link.hasAttribute(\"data-turbo-stream\"))\n )\n }\n\n followedLinkToLocation(link, location) {\n const form = document.createElement(\"form\");\n\n const type = \"hidden\";\n for (const [name, value] of location.searchParams) {\n form.append(Object.assign(document.createElement(\"input\"), { type, name, value }));\n }\n\n const action = Object.assign(location, { search: \"\" });\n form.setAttribute(\"data-turbo\", \"true\");\n form.setAttribute(\"action\", action.href);\n form.setAttribute(\"hidden\", \"\");\n\n const method = link.getAttribute(\"data-turbo-method\");\n if (method) form.setAttribute(\"method\", method);\n\n const turboFrame = link.getAttribute(\"data-turbo-frame\");\n if (turboFrame) form.setAttribute(\"data-turbo-frame\", turboFrame);\n\n const turboAction = getVisitAction(link);\n if (turboAction) form.setAttribute(\"data-turbo-action\", turboAction);\n\n const turboConfirm = link.getAttribute(\"data-turbo-confirm\");\n if (turboConfirm) form.setAttribute(\"data-turbo-confirm\", turboConfirm);\n\n const turboStream = link.hasAttribute(\"data-turbo-stream\");\n if (turboStream) form.setAttribute(\"data-turbo-stream\", \"\");\n\n this.delegate.submittedFormLinkToLocation(link, location, form);\n\n document.body.appendChild(form);\n form.addEventListener(\"turbo:submit-end\", () => form.remove(), { once: true });\n requestAnimationFrame(() => form.requestSubmit());\n }\n}\n\nclass Bardo {\n static async preservingPermanentElements(delegate, permanentElementMap, callback) {\n const bardo = new this(delegate, permanentElementMap);\n bardo.enter();\n await callback();\n bardo.leave();\n }\n\n constructor(delegate, permanentElementMap) {\n this.delegate = delegate;\n this.permanentElementMap = permanentElementMap;\n }\n\n enter() {\n for (const id in this.permanentElementMap) {\n const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id];\n this.delegate.enteringBardo(currentPermanentElement, newPermanentElement);\n this.replaceNewPermanentElementWithPlaceholder(newPermanentElement);\n }\n }\n\n leave() {\n for (const id in this.permanentElementMap) {\n const [currentPermanentElement] = this.permanentElementMap[id];\n this.replaceCurrentPermanentElementWithClone(currentPermanentElement);\n this.replacePlaceholderWithPermanentElement(currentPermanentElement);\n this.delegate.leavingBardo(currentPermanentElement);\n }\n }\n\n replaceNewPermanentElementWithPlaceholder(permanentElement) {\n const placeholder = createPlaceholderForPermanentElement(permanentElement);\n permanentElement.replaceWith(placeholder);\n }\n\n replaceCurrentPermanentElementWithClone(permanentElement) {\n const clone = permanentElement.cloneNode(true);\n permanentElement.replaceWith(clone);\n }\n\n replacePlaceholderWithPermanentElement(permanentElement) {\n const placeholder = this.getPlaceholderById(permanentElement.id);\n placeholder?.replaceWith(permanentElement);\n }\n\n getPlaceholderById(id) {\n return this.placeholders.find((element) => element.content == id)\n }\n\n get placeholders() {\n return [...document.querySelectorAll(\"meta[name=turbo-permanent-placeholder][content]\")]\n }\n}\n\nfunction createPlaceholderForPermanentElement(permanentElement) {\n const element = document.createElement(\"meta\");\n element.setAttribute(\"name\", \"turbo-permanent-placeholder\");\n element.setAttribute(\"content\", permanentElement.id);\n return element\n}\n\nclass Renderer {\n #activeElement = null\n\n constructor(currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {\n this.currentSnapshot = currentSnapshot;\n this.newSnapshot = newSnapshot;\n this.isPreview = isPreview;\n this.willRender = willRender;\n this.renderElement = renderElement;\n this.promise = new Promise((resolve, reject) => (this.resolvingFunctions = { resolve, reject }));\n }\n\n get shouldRender() {\n return true\n }\n\n get shouldAutofocus() {\n return true\n }\n\n get reloadReason() {\n return\n }\n\n prepareToRender() {\n return\n }\n\n render() {\n // Abstract method\n }\n\n finishRendering() {\n if (this.resolvingFunctions) {\n this.resolvingFunctions.resolve();\n delete this.resolvingFunctions;\n }\n }\n\n async preservingPermanentElements(callback) {\n await Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);\n }\n\n focusFirstAutofocusableElement() {\n if (this.shouldAutofocus) {\n const element = this.connectedSnapshot.firstAutofocusableElement;\n if (element) {\n element.focus();\n }\n }\n }\n\n // Bardo delegate\n\n enteringBardo(currentPermanentElement) {\n if (this.#activeElement) return\n\n if (currentPermanentElement.contains(this.currentSnapshot.activeElement)) {\n this.#activeElement = this.currentSnapshot.activeElement;\n }\n }\n\n leavingBardo(currentPermanentElement) {\n if (currentPermanentElement.contains(this.#activeElement) && this.#activeElement instanceof HTMLElement) {\n this.#activeElement.focus();\n\n this.#activeElement = null;\n }\n }\n\n get connectedSnapshot() {\n return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot\n }\n\n get currentElement() {\n return this.currentSnapshot.element\n }\n\n get newElement() {\n return this.newSnapshot.element\n }\n\n get permanentElementMap() {\n return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot)\n }\n\n get renderMethod() {\n return \"replace\"\n }\n}\n\nclass FrameRenderer extends Renderer {\n static renderElement(currentElement, newElement) {\n const destinationRange = document.createRange();\n destinationRange.selectNodeContents(currentElement);\n destinationRange.deleteContents();\n\n const frameElement = newElement;\n const sourceRange = frameElement.ownerDocument?.createRange();\n if (sourceRange) {\n sourceRange.selectNodeContents(frameElement);\n currentElement.appendChild(sourceRange.extractContents());\n }\n }\n\n constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {\n super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender);\n this.delegate = delegate;\n }\n\n get shouldRender() {\n return true\n }\n\n async render() {\n await nextRepaint();\n this.preservingPermanentElements(() => {\n this.loadFrameElement();\n });\n this.scrollFrameIntoView();\n await nextRepaint();\n this.focusFirstAutofocusableElement();\n await nextRepaint();\n this.activateScriptElements();\n }\n\n loadFrameElement() {\n this.delegate.willRenderFrame(this.currentElement, this.newElement);\n this.renderElement(this.currentElement, this.newElement);\n }\n\n scrollFrameIntoView() {\n if (this.currentElement.autoscroll || this.newElement.autoscroll) {\n const element = this.currentElement.firstElementChild;\n const block = readScrollLogicalPosition(this.currentElement.getAttribute(\"data-autoscroll-block\"), \"end\");\n const behavior = readScrollBehavior(this.currentElement.getAttribute(\"data-autoscroll-behavior\"), \"auto\");\n\n if (element) {\n element.scrollIntoView({ block, behavior });\n return true\n }\n }\n return false\n }\n\n activateScriptElements() {\n for (const inertScriptElement of this.newScriptElements) {\n const activatedScriptElement = activateScriptElement(inertScriptElement);\n inertScriptElement.replaceWith(activatedScriptElement);\n }\n }\n\n get newScriptElements() {\n return this.currentElement.querySelectorAll(\"script\")\n }\n}\n\nfunction readScrollLogicalPosition(value, defaultValue) {\n if (value == \"end\" || value == \"start\" || value == \"center\" || value == \"nearest\") {\n return value\n } else {\n return defaultValue\n }\n}\n\nfunction readScrollBehavior(value, defaultValue) {\n if (value == \"auto\" || value == \"smooth\") {\n return value\n } else {\n return defaultValue\n }\n}\n\n// base IIFE to define idiomorph\nvar Idiomorph = (function () {\n\n //=============================================================================\n // AND NOW IT BEGINS...\n //=============================================================================\n let EMPTY_SET = new Set();\n\n // default configuration values, updatable by users now\n let defaults = {\n morphStyle: \"outerHTML\",\n callbacks : {\n beforeNodeAdded: noOp,\n afterNodeAdded: noOp,\n beforeNodeMorphed: noOp,\n afterNodeMorphed: noOp,\n beforeNodeRemoved: noOp,\n afterNodeRemoved: noOp,\n beforeAttributeUpdated: noOp,\n\n },\n head: {\n style: 'merge',\n shouldPreserve: function (elt) {\n return elt.getAttribute(\"im-preserve\") === \"true\";\n },\n shouldReAppend: function (elt) {\n return elt.getAttribute(\"im-re-append\") === \"true\";\n },\n shouldRemove: noOp,\n afterHeadMorphed: noOp,\n }\n };\n\n //=============================================================================\n // Core Morphing Algorithm - morph, morphNormalizedContent, morphOldNodeTo, morphChildren\n //=============================================================================\n function morph(oldNode, newContent, config = {}) {\n\n if (oldNode instanceof Document) {\n oldNode = oldNode.documentElement;\n }\n\n if (typeof newContent === 'string') {\n newContent = parseContent(newContent);\n }\n\n let normalizedContent = normalizeContent(newContent);\n\n let ctx = createMorphContext(oldNode, normalizedContent, config);\n\n return morphNormalizedContent(oldNode, normalizedContent, ctx);\n }\n\n function morphNormalizedContent(oldNode, normalizedNewContent, ctx) {\n if (ctx.head.block) {\n let oldHead = oldNode.querySelector('head');\n let newHead = normalizedNewContent.querySelector('head');\n if (oldHead && newHead) {\n let promises = handleHeadElement(newHead, oldHead, ctx);\n // when head promises resolve, call morph again, ignoring the head tag\n Promise.all(promises).then(function () {\n morphNormalizedContent(oldNode, normalizedNewContent, Object.assign(ctx, {\n head: {\n block: false,\n ignore: true\n }\n }));\n });\n return;\n }\n }\n\n if (ctx.morphStyle === \"innerHTML\") {\n\n // innerHTML, so we are only updating the children\n morphChildren(normalizedNewContent, oldNode, ctx);\n return oldNode.children;\n\n } else if (ctx.morphStyle === \"outerHTML\" || ctx.morphStyle == null) {\n // otherwise find the best element match in the new content, morph that, and merge its siblings\n // into either side of the best match\n let bestMatch = findBestNodeMatch(normalizedNewContent, oldNode, ctx);\n\n // stash the siblings that will need to be inserted on either side of the best match\n let previousSibling = bestMatch?.previousSibling;\n let nextSibling = bestMatch?.nextSibling;\n\n // morph it\n let morphedNode = morphOldNodeTo(oldNode, bestMatch, ctx);\n\n if (bestMatch) {\n // if there was a best match, merge the siblings in too and return the\n // whole bunch\n return insertSiblings(previousSibling, morphedNode, nextSibling);\n } else {\n // otherwise nothing was added to the DOM\n return []\n }\n } else {\n throw \"Do not understand how to morph style \" + ctx.morphStyle;\n }\n }\n\n\n /**\n * @param possibleActiveElement\n * @param ctx\n * @returns {boolean}\n */\n function ignoreValueOfActiveElement(possibleActiveElement, ctx) {\n return ctx.ignoreActiveValue && possibleActiveElement === document.activeElement && possibleActiveElement !== document.body;\n }\n\n /**\n * @param oldNode root node to merge content into\n * @param newContent new content to merge\n * @param ctx the merge context\n * @returns {Element} the element that ended up in the DOM\n */\n function morphOldNodeTo(oldNode, newContent, ctx) {\n if (ctx.ignoreActive && oldNode === document.activeElement) ; else if (newContent == null) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n\n oldNode.remove();\n ctx.callbacks.afterNodeRemoved(oldNode);\n return null;\n } else if (!isSoftMatch(oldNode, newContent)) {\n if (ctx.callbacks.beforeNodeRemoved(oldNode) === false) return oldNode;\n if (ctx.callbacks.beforeNodeAdded(newContent) === false) return oldNode;\n\n oldNode.parentElement.replaceChild(newContent, oldNode);\n ctx.callbacks.afterNodeAdded(newContent);\n ctx.callbacks.afterNodeRemoved(oldNode);\n return newContent;\n } else {\n if (ctx.callbacks.beforeNodeMorphed(oldNode, newContent) === false) return oldNode;\n\n if (oldNode instanceof HTMLHeadElement && ctx.head.ignore) ; else if (oldNode instanceof HTMLHeadElement && ctx.head.style !== \"morph\") {\n handleHeadElement(newContent, oldNode, ctx);\n } else {\n syncNodeFrom(newContent, oldNode, ctx);\n if (!ignoreValueOfActiveElement(oldNode, ctx)) {\n morphChildren(newContent, oldNode, ctx);\n }\n }\n ctx.callbacks.afterNodeMorphed(oldNode, newContent);\n return oldNode;\n }\n }\n\n /**\n * This is the core algorithm for matching up children. The idea is to use id sets to try to match up\n * nodes as faithfully as possible. We greedily match, which allows us to keep the algorithm fast, but\n * by using id sets, we are able to better match up with content deeper in the DOM.\n *\n * Basic algorithm is, for each node in the new content:\n *\n * - if we have reached the end of the old parent, append the new content\n * - if the new content has an id set match with the current insertion point, morph\n * - search for an id set match\n * - if id set match found, morph\n * - otherwise search for a \"soft\" match\n * - if a soft match is found, morph\n * - otherwise, prepend the new node before the current insertion point\n *\n * The two search algorithms terminate if competing node matches appear to outweigh what can be achieved\n * with the current node. See findIdSetMatch() and findSoftMatch() for details.\n *\n * @param {Element} newParent the parent element of the new content\n * @param {Element } oldParent the old content that we are merging the new content into\n * @param ctx the merge context\n */\n function morphChildren(newParent, oldParent, ctx) {\n\n let nextNewChild = newParent.firstChild;\n let insertionPoint = oldParent.firstChild;\n let newChild;\n\n // run through all the new content\n while (nextNewChild) {\n\n newChild = nextNewChild;\n nextNewChild = newChild.nextSibling;\n\n // if we are at the end of the exiting parent's children, just append\n if (insertionPoint == null) {\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.appendChild(newChild);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // if the current node has an id set match then morph\n if (isIdSetMatch(newChild, insertionPoint, ctx)) {\n morphOldNodeTo(insertionPoint, newChild, ctx);\n insertionPoint = insertionPoint.nextSibling;\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // otherwise search forward in the existing old children for an id set match\n let idSetMatch = findIdSetMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a potential match, remove the nodes until that point and morph\n if (idSetMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, idSetMatch, ctx);\n morphOldNodeTo(idSetMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // no id set match found, so scan forward for a soft match for the current node\n let softMatch = findSoftMatch(newParent, oldParent, newChild, insertionPoint, ctx);\n\n // if we found a soft match for the current node, morph\n if (softMatch) {\n insertionPoint = removeNodesBetween(insertionPoint, softMatch, ctx);\n morphOldNodeTo(softMatch, newChild, ctx);\n removeIdsFromConsideration(ctx, newChild);\n continue;\n }\n\n // abandon all hope of morphing, just insert the new child before the insertion point\n // and move on\n if (ctx.callbacks.beforeNodeAdded(newChild) === false) return;\n\n oldParent.insertBefore(newChild, insertionPoint);\n ctx.callbacks.afterNodeAdded(newChild);\n removeIdsFromConsideration(ctx, newChild);\n }\n\n // remove any remaining old nodes that didn't match up with new content\n while (insertionPoint !== null) {\n\n let tempNode = insertionPoint;\n insertionPoint = insertionPoint.nextSibling;\n removeNode(tempNode, ctx);\n }\n }\n\n //=============================================================================\n // Attribute Syncing Code\n //=============================================================================\n\n /**\n * @param attr {String} the attribute to be mutated\n * @param to {Element} the element that is going to be updated\n * @param updateType {(\"update\"|\"remove\")}\n * @param ctx the merge context\n * @returns {boolean} true if the attribute should be ignored, false otherwise\n */\n function ignoreAttribute(attr, to, updateType, ctx) {\n if(attr === 'value' && ctx.ignoreActiveValue && to === document.activeElement){\n return true;\n }\n return ctx.callbacks.beforeAttributeUpdated(attr, to, updateType) === false;\n }\n\n /**\n * syncs a given node with another node, copying over all attributes and\n * inner element state from the 'from' node to the 'to' node\n *\n * @param {Element} from the element to copy attributes & state from\n * @param {Element} to the element to copy attributes & state to\n * @param ctx the merge context\n */\n function syncNodeFrom(from, to, ctx) {\n let type = from.nodeType;\n\n // if is an element type, sync the attributes from the\n // new node into the new node\n if (type === 1 /* element type */) {\n const fromAttributes = from.attributes;\n const toAttributes = to.attributes;\n for (const fromAttribute of fromAttributes) {\n if (ignoreAttribute(fromAttribute.name, to, 'update', ctx)) {\n continue;\n }\n if (to.getAttribute(fromAttribute.name) !== fromAttribute.value) {\n to.setAttribute(fromAttribute.name, fromAttribute.value);\n }\n }\n // iterate backwards to avoid skipping over items when a delete occurs\n for (let i = toAttributes.length - 1; 0 <= i; i--) {\n const toAttribute = toAttributes[i];\n if (ignoreAttribute(toAttribute.name, to, 'remove', ctx)) {\n continue;\n }\n if (!from.hasAttribute(toAttribute.name)) {\n to.removeAttribute(toAttribute.name);\n }\n }\n }\n\n // sync text nodes\n if (type === 8 /* comment */ || type === 3 /* text */) {\n if (to.nodeValue !== from.nodeValue) {\n to.nodeValue = from.nodeValue;\n }\n }\n\n if (!ignoreValueOfActiveElement(to, ctx)) {\n // sync input values\n syncInputValue(from, to, ctx);\n }\n }\n\n /**\n * @param from {Element} element to sync the value from\n * @param to {Element} element to sync the value to\n * @param attributeName {String} the attribute name\n * @param ctx the merge context\n */\n function syncBooleanAttribute(from, to, attributeName, ctx) {\n if (from[attributeName] !== to[attributeName]) {\n let ignoreUpdate = ignoreAttribute(attributeName, to, 'update', ctx);\n if (!ignoreUpdate) {\n to[attributeName] = from[attributeName];\n }\n if (from[attributeName]) {\n if (!ignoreUpdate) {\n to.setAttribute(attributeName, from[attributeName]);\n }\n } else {\n if (!ignoreAttribute(attributeName, to, 'remove', ctx)) {\n to.removeAttribute(attributeName);\n }\n }\n }\n }\n\n /**\n * NB: many bothans died to bring us information:\n *\n * https://github.com/patrick-steele-idem/morphdom/blob/master/src/specialElHandlers.js\n * https://github.com/choojs/nanomorph/blob/master/lib/morph.jsL113\n *\n * @param from {Element} the element to sync the input value from\n * @param to {Element} the element to sync the input value to\n * @param ctx the merge context\n */\n function syncInputValue(from, to, ctx) {\n if (from instanceof HTMLInputElement &&\n to instanceof HTMLInputElement &&\n from.type !== 'file') {\n\n let fromValue = from.value;\n let toValue = to.value;\n\n // sync boolean attributes\n syncBooleanAttribute(from, to, 'checked', ctx);\n syncBooleanAttribute(from, to, 'disabled', ctx);\n\n if (!from.hasAttribute('value')) {\n if (!ignoreAttribute('value', to, 'remove', ctx)) {\n to.value = '';\n to.removeAttribute('value');\n }\n } else if (fromValue !== toValue) {\n if (!ignoreAttribute('value', to, 'update', ctx)) {\n to.setAttribute('value', fromValue);\n to.value = fromValue;\n }\n }\n } else if (from instanceof HTMLOptionElement) {\n syncBooleanAttribute(from, to, 'selected', ctx);\n } else if (from instanceof HTMLTextAreaElement && to instanceof HTMLTextAreaElement) {\n let fromValue = from.value;\n let toValue = to.value;\n if (ignoreAttribute('value', to, 'update', ctx)) {\n return;\n }\n if (fromValue !== toValue) {\n to.value = fromValue;\n }\n if (to.firstChild && to.firstChild.nodeValue !== fromValue) {\n to.firstChild.nodeValue = fromValue;\n }\n }\n }\n\n //=============================================================================\n // the HEAD tag can be handled specially, either w/ a 'merge' or 'append' style\n //=============================================================================\n function handleHeadElement(newHeadTag, currentHead, ctx) {\n\n let added = [];\n let removed = [];\n let preserved = [];\n let nodesToAppend = [];\n\n let headMergeStyle = ctx.head.style;\n\n // put all new head elements into a Map, by their outerHTML\n let srcToNewHeadNodes = new Map();\n for (const newHeadChild of newHeadTag.children) {\n srcToNewHeadNodes.set(newHeadChild.outerHTML, newHeadChild);\n }\n\n // for each elt in the current head\n for (const currentHeadElt of currentHead.children) {\n\n // If the current head element is in the map\n let inNewContent = srcToNewHeadNodes.has(currentHeadElt.outerHTML);\n let isReAppended = ctx.head.shouldReAppend(currentHeadElt);\n let isPreserved = ctx.head.shouldPreserve(currentHeadElt);\n if (inNewContent || isPreserved) {\n if (isReAppended) {\n // remove the current version and let the new version replace it and re-execute\n removed.push(currentHeadElt);\n } else {\n // this element already exists and should not be re-appended, so remove it from\n // the new content map, preserving it in the DOM\n srcToNewHeadNodes.delete(currentHeadElt.outerHTML);\n preserved.push(currentHeadElt);\n }\n } else {\n if (headMergeStyle === \"append\") {\n // we are appending and this existing element is not new content\n // so if and only if it is marked for re-append do we do anything\n if (isReAppended) {\n removed.push(currentHeadElt);\n nodesToAppend.push(currentHeadElt);\n }\n } else {\n // if this is a merge, we remove this content since it is not in the new head\n if (ctx.head.shouldRemove(currentHeadElt) !== false) {\n removed.push(currentHeadElt);\n }\n }\n }\n }\n\n // Push the remaining new head elements in the Map into the\n // nodes to append to the head tag\n nodesToAppend.push(...srcToNewHeadNodes.values());\n\n let promises = [];\n for (const newNode of nodesToAppend) {\n let newElt = document.createRange().createContextualFragment(newNode.outerHTML).firstChild;\n if (ctx.callbacks.beforeNodeAdded(newElt) !== false) {\n if (newElt.href || newElt.src) {\n let resolve = null;\n let promise = new Promise(function (_resolve) {\n resolve = _resolve;\n });\n newElt.addEventListener('load', function () {\n resolve();\n });\n promises.push(promise);\n }\n currentHead.appendChild(newElt);\n ctx.callbacks.afterNodeAdded(newElt);\n added.push(newElt);\n }\n }\n\n // remove all removed elements, after we have appended the new elements to avoid\n // additional network requests for things like style sheets\n for (const removedElement of removed) {\n if (ctx.callbacks.beforeNodeRemoved(removedElement) !== false) {\n currentHead.removeChild(removedElement);\n ctx.callbacks.afterNodeRemoved(removedElement);\n }\n }\n\n ctx.head.afterHeadMorphed(currentHead, {added: added, kept: preserved, removed: removed});\n return promises;\n }\n\n function noOp() {\n }\n\n /*\n Deep merges the config object and the Idiomoroph.defaults object to\n produce a final configuration object\n */\n function mergeDefaults(config) {\n let finalConfig = {};\n // copy top level stuff into final config\n Object.assign(finalConfig, defaults);\n Object.assign(finalConfig, config);\n\n // copy callbacks into final config (do this to deep merge the callbacks)\n finalConfig.callbacks = {};\n Object.assign(finalConfig.callbacks, defaults.callbacks);\n Object.assign(finalConfig.callbacks, config.callbacks);\n\n // copy head config into final config (do this to deep merge the head)\n finalConfig.head = {};\n Object.assign(finalConfig.head, defaults.head);\n Object.assign(finalConfig.head, config.head);\n return finalConfig;\n }\n\n function createMorphContext(oldNode, newContent, config) {\n config = mergeDefaults(config);\n return {\n target: oldNode,\n newContent: newContent,\n config: config,\n morphStyle: config.morphStyle,\n ignoreActive: config.ignoreActive,\n ignoreActiveValue: config.ignoreActiveValue,\n idMap: createIdMap(oldNode, newContent),\n deadIds: new Set(),\n callbacks: config.callbacks,\n head: config.head\n }\n }\n\n function isIdSetMatch(node1, node2, ctx) {\n if (node1 == null || node2 == null) {\n return false;\n }\n if (node1.nodeType === node2.nodeType && node1.tagName === node2.tagName) {\n if (node1.id !== \"\" && node1.id === node2.id) {\n return true;\n } else {\n return getIdIntersectionCount(ctx, node1, node2) > 0;\n }\n }\n return false;\n }\n\n function isSoftMatch(node1, node2) {\n if (node1 == null || node2 == null) {\n return false;\n }\n return node1.nodeType === node2.nodeType && node1.tagName === node2.tagName\n }\n\n function removeNodesBetween(startInclusive, endExclusive, ctx) {\n while (startInclusive !== endExclusive) {\n let tempNode = startInclusive;\n startInclusive = startInclusive.nextSibling;\n removeNode(tempNode, ctx);\n }\n removeIdsFromConsideration(ctx, endExclusive);\n return endExclusive.nextSibling;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential id match\n // for the newChild. We stop if we find a potential id match for the new child OR\n // if the number of potential id matches we are discarding is greater than the\n // potential id matches for the new child\n //=============================================================================\n function findIdSetMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n // max id matches we are willing to discard in our search\n let newChildPotentialIdCount = getIdIntersectionCount(ctx, newChild, oldParent);\n\n let potentialMatch = null;\n\n // only search forward if there is a possibility of an id match\n if (newChildPotentialIdCount > 0) {\n let potentialMatch = insertionPoint;\n // if there is a possibility of an id match, scan forward\n // keep track of the potential id match count we are discarding (the\n // newChildPotentialIdCount must be greater than this to make it likely\n // worth it)\n let otherMatchCount = 0;\n while (potentialMatch != null) {\n\n // If we have an id match, return the current potential match\n if (isIdSetMatch(newChild, potentialMatch, ctx)) {\n return potentialMatch;\n }\n\n // computer the other potential matches of this new content\n otherMatchCount += getIdIntersectionCount(ctx, potentialMatch, newContent);\n if (otherMatchCount > newChildPotentialIdCount) {\n // if we have more potential id matches in _other_ content, we\n // do not have a good candidate for an id match, so return null\n return null;\n }\n\n // advanced to the next old content child\n potentialMatch = potentialMatch.nextSibling;\n }\n }\n return potentialMatch;\n }\n\n //=============================================================================\n // Scans forward from the insertionPoint in the old parent looking for a potential soft match\n // for the newChild. We stop if we find a potential soft match for the new child OR\n // if we find a potential id match in the old parents children OR if we find two\n // potential soft matches for the next two pieces of new content\n //=============================================================================\n function findSoftMatch(newContent, oldParent, newChild, insertionPoint, ctx) {\n\n let potentialSoftMatch = insertionPoint;\n let nextSibling = newChild.nextSibling;\n let siblingSoftMatchCount = 0;\n\n while (potentialSoftMatch != null) {\n\n if (getIdIntersectionCount(ctx, potentialSoftMatch, newContent) > 0) {\n // the current potential soft match has a potential id set match with the remaining new\n // content so bail out of looking\n return null;\n }\n\n // if we have a soft match with the current node, return it\n if (isSoftMatch(newChild, potentialSoftMatch)) {\n return potentialSoftMatch;\n }\n\n if (isSoftMatch(nextSibling, potentialSoftMatch)) {\n // the next new node has a soft match with this node, so\n // increment the count of future soft matches\n siblingSoftMatchCount++;\n nextSibling = nextSibling.nextSibling;\n\n // If there are two future soft matches, bail to allow the siblings to soft match\n // so that we don't consume future soft matches for the sake of the current node\n if (siblingSoftMatchCount >= 2) {\n return null;\n }\n }\n\n // advanced to the next old content child\n potentialSoftMatch = potentialSoftMatch.nextSibling;\n }\n\n return potentialSoftMatch;\n }\n\n function parseContent(newContent) {\n let parser = new DOMParser();\n\n // remove svgs to avoid false-positive matches on head, etc.\n let contentWithSvgsRemoved = newContent.replace(/]*>|>)([\\s\\S]*?)<\\/svg>/gim, '');\n\n // if the newContent contains a html, head or body tag, we can simply parse it w/o wrapping\n if (contentWithSvgsRemoved.match(/<\\/html>/) || contentWithSvgsRemoved.match(/<\\/head>/) || contentWithSvgsRemoved.match(/<\\/body>/)) {\n let content = parser.parseFromString(newContent, \"text/html\");\n // if it is a full HTML document, return the document itself as the parent container\n if (contentWithSvgsRemoved.match(/<\\/html>/)) {\n content.generatedByIdiomorph = true;\n return content;\n } else {\n // otherwise return the html element as the parent container\n let htmlElement = content.firstChild;\n if (htmlElement) {\n htmlElement.generatedByIdiomorph = true;\n return htmlElement;\n } else {\n return null;\n }\n }\n } else {\n // if it is partial HTML, wrap it in a template tag to provide a parent element and also to help\n // deal with touchy tags like tr, tbody, etc.\n let responseDoc = parser.parseFromString(\"\", \"text/html\");\n let content = responseDoc.body.querySelector('template').content;\n content.generatedByIdiomorph = true;\n return content\n }\n }\n\n function normalizeContent(newContent) {\n if (newContent == null) {\n // noinspection UnnecessaryLocalVariableJS\n const dummyParent = document.createElement('div');\n return dummyParent;\n } else if (newContent.generatedByIdiomorph) {\n // the template tag created by idiomorph parsing can serve as a dummy parent\n return newContent;\n } else if (newContent instanceof Node) {\n // a single node is added as a child to a dummy parent\n const dummyParent = document.createElement('div');\n dummyParent.append(newContent);\n return dummyParent;\n } else {\n // all nodes in the array or HTMLElement collection are consolidated under\n // a single dummy parent element\n const dummyParent = document.createElement('div');\n for (const elt of [...newContent]) {\n dummyParent.append(elt);\n }\n return dummyParent;\n }\n }\n\n function insertSiblings(previousSibling, morphedNode, nextSibling) {\n let stack = [];\n let added = [];\n while (previousSibling != null) {\n stack.push(previousSibling);\n previousSibling = previousSibling.previousSibling;\n }\n while (stack.length > 0) {\n let node = stack.pop();\n added.push(node); // push added preceding siblings on in order and insert\n morphedNode.parentElement.insertBefore(node, morphedNode);\n }\n added.push(morphedNode);\n while (nextSibling != null) {\n stack.push(nextSibling);\n added.push(nextSibling); // here we are going in order, so push on as we scan, rather than add\n nextSibling = nextSibling.nextSibling;\n }\n while (stack.length > 0) {\n morphedNode.parentElement.insertBefore(stack.pop(), morphedNode.nextSibling);\n }\n return added;\n }\n\n function findBestNodeMatch(newContent, oldNode, ctx) {\n let currentElement;\n currentElement = newContent.firstChild;\n let bestElement = currentElement;\n let score = 0;\n while (currentElement) {\n let newScore = scoreElement(currentElement, oldNode, ctx);\n if (newScore > score) {\n bestElement = currentElement;\n score = newScore;\n }\n currentElement = currentElement.nextSibling;\n }\n return bestElement;\n }\n\n function scoreElement(node1, node2, ctx) {\n if (isSoftMatch(node1, node2)) {\n return .5 + getIdIntersectionCount(ctx, node1, node2);\n }\n return 0;\n }\n\n function removeNode(tempNode, ctx) {\n removeIdsFromConsideration(ctx, tempNode);\n if (ctx.callbacks.beforeNodeRemoved(tempNode) === false) return;\n\n tempNode.remove();\n ctx.callbacks.afterNodeRemoved(tempNode);\n }\n\n //=============================================================================\n // ID Set Functions\n //=============================================================================\n\n function isIdInConsideration(ctx, id) {\n return !ctx.deadIds.has(id);\n }\n\n function idIsWithinNode(ctx, id, targetNode) {\n let idSet = ctx.idMap.get(targetNode) || EMPTY_SET;\n return idSet.has(id);\n }\n\n function removeIdsFromConsideration(ctx, node) {\n let idSet = ctx.idMap.get(node) || EMPTY_SET;\n for (const id of idSet) {\n ctx.deadIds.add(id);\n }\n }\n\n function getIdIntersectionCount(ctx, node1, node2) {\n let sourceSet = ctx.idMap.get(node1) || EMPTY_SET;\n let matchCount = 0;\n for (const id of sourceSet) {\n // a potential match is an id in the source and potentialIdsSet, but\n // that has not already been merged into the DOM\n if (isIdInConsideration(ctx, id) && idIsWithinNode(ctx, id, node2)) {\n ++matchCount;\n }\n }\n return matchCount;\n }\n\n /**\n * A bottom up algorithm that finds all elements with ids inside of the node\n * argument and populates id sets for those nodes and all their parents, generating\n * a set of ids contained within all nodes for the entire hierarchy in the DOM\n *\n * @param node {Element}\n * @param {Map>} idMap\n */\n function populateIdMapForNode(node, idMap) {\n let nodeParent = node.parentElement;\n // find all elements with an id property\n let idElements = node.querySelectorAll('[id]');\n for (const elt of idElements) {\n let current = elt;\n // walk up the parent hierarchy of that element, adding the id\n // of element to the parent's id set\n while (current !== nodeParent && current != null) {\n let idSet = idMap.get(current);\n // if the id set doesn't exist, create it and insert it in the map\n if (idSet == null) {\n idSet = new Set();\n idMap.set(current, idSet);\n }\n idSet.add(elt.id);\n current = current.parentElement;\n }\n }\n }\n\n /**\n * This function computes a map of nodes to all ids contained within that node (inclusive of the\n * node). This map can be used to ask if two nodes have intersecting sets of ids, which allows\n * for a looser definition of \"matching\" than tradition id matching, and allows child nodes\n * to contribute to a parent nodes matching.\n *\n * @param {Element} oldContent the old content that will be morphed\n * @param {Element} newContent the new content to morph to\n * @returns {Map>} a map of nodes to id sets for the\n */\n function createIdMap(oldContent, newContent) {\n let idMap = new Map();\n populateIdMapForNode(oldContent, idMap);\n populateIdMapForNode(newContent, idMap);\n return idMap;\n }\n\n //=============================================================================\n // This is what ends up becoming the Idiomorph global object\n //=============================================================================\n return {\n morph,\n defaults\n }\n })();\n\nfunction morphElements(currentElement, newElement, { callbacks, ...options } = {}) {\n Idiomorph.morph(currentElement, newElement, {\n ...options,\n callbacks: new DefaultIdiomorphCallbacks(callbacks)\n });\n}\n\nfunction morphChildren(currentElement, newElement) {\n morphElements(currentElement, newElement.children, {\n morphStyle: \"innerHTML\"\n });\n}\n\nclass DefaultIdiomorphCallbacks {\n #beforeNodeMorphed\n\n constructor({ beforeNodeMorphed } = {}) {\n this.#beforeNodeMorphed = beforeNodeMorphed || (() => true);\n }\n\n beforeNodeAdded = (node) => {\n return !(node.id && node.hasAttribute(\"data-turbo-permanent\") && document.getElementById(node.id))\n }\n\n beforeNodeMorphed = (currentElement, newElement) => {\n if (currentElement instanceof Element) {\n if (!currentElement.hasAttribute(\"data-turbo-permanent\") && this.#beforeNodeMorphed(currentElement, newElement)) {\n const event = dispatch(\"turbo:before-morph-element\", {\n cancelable: true,\n target: currentElement,\n detail: { currentElement, newElement }\n });\n\n return !event.defaultPrevented\n } else {\n return false\n }\n }\n }\n\n beforeAttributeUpdated = (attributeName, target, mutationType) => {\n const event = dispatch(\"turbo:before-morph-attribute\", {\n cancelable: true,\n target,\n detail: { attributeName, mutationType }\n });\n\n return !event.defaultPrevented\n }\n\n beforeNodeRemoved = (node) => {\n return this.beforeNodeMorphed(node)\n }\n\n afterNodeMorphed = (currentElement, newElement) => {\n if (currentElement instanceof Element) {\n dispatch(\"turbo:morph-element\", {\n target: currentElement,\n detail: { currentElement, newElement }\n });\n }\n }\n}\n\nclass MorphingFrameRenderer extends FrameRenderer {\n static renderElement(currentElement, newElement) {\n dispatch(\"turbo:before-frame-morph\", {\n target: currentElement,\n detail: { currentElement, newElement }\n });\n\n morphChildren(currentElement, newElement);\n }\n}\n\nclass ProgressBar {\n static animationDuration = 300 /*ms*/\n\n static get defaultCSS() {\n return unindent`\n .turbo-progress-bar {\n position: fixed;\n display: block;\n top: 0;\n left: 0;\n height: 3px;\n background: #0076ff;\n z-index: 2147483647;\n transition:\n width ${ProgressBar.animationDuration}ms ease-out,\n opacity ${ProgressBar.animationDuration / 2}ms ${ProgressBar.animationDuration / 2}ms ease-in;\n transform: translate3d(0, 0, 0);\n }\n `\n }\n\n hiding = false\n value = 0\n visible = false\n\n constructor() {\n this.stylesheetElement = this.createStylesheetElement();\n this.progressElement = this.createProgressElement();\n this.installStylesheetElement();\n this.setValue(0);\n }\n\n show() {\n if (!this.visible) {\n this.visible = true;\n this.installProgressElement();\n this.startTrickling();\n }\n }\n\n hide() {\n if (this.visible && !this.hiding) {\n this.hiding = true;\n this.fadeProgressElement(() => {\n this.uninstallProgressElement();\n this.stopTrickling();\n this.visible = false;\n this.hiding = false;\n });\n }\n }\n\n setValue(value) {\n this.value = value;\n this.refresh();\n }\n\n // Private\n\n installStylesheetElement() {\n document.head.insertBefore(this.stylesheetElement, document.head.firstChild);\n }\n\n installProgressElement() {\n this.progressElement.style.width = \"0\";\n this.progressElement.style.opacity = \"1\";\n document.documentElement.insertBefore(this.progressElement, document.body);\n this.refresh();\n }\n\n fadeProgressElement(callback) {\n this.progressElement.style.opacity = \"0\";\n setTimeout(callback, ProgressBar.animationDuration * 1.5);\n }\n\n uninstallProgressElement() {\n if (this.progressElement.parentNode) {\n document.documentElement.removeChild(this.progressElement);\n }\n }\n\n startTrickling() {\n if (!this.trickleInterval) {\n this.trickleInterval = window.setInterval(this.trickle, ProgressBar.animationDuration);\n }\n }\n\n stopTrickling() {\n window.clearInterval(this.trickleInterval);\n delete this.trickleInterval;\n }\n\n trickle = () => {\n this.setValue(this.value + Math.random() / 100);\n }\n\n refresh() {\n requestAnimationFrame(() => {\n this.progressElement.style.width = `${10 + this.value * 90}%`;\n });\n }\n\n createStylesheetElement() {\n const element = document.createElement(\"style\");\n element.type = \"text/css\";\n element.textContent = ProgressBar.defaultCSS;\n if (this.cspNonce) {\n element.nonce = this.cspNonce;\n }\n return element\n }\n\n createProgressElement() {\n const element = document.createElement(\"div\");\n element.className = \"turbo-progress-bar\";\n return element\n }\n\n get cspNonce() {\n return getMetaContent(\"csp-nonce\")\n }\n}\n\nclass HeadSnapshot extends Snapshot {\n detailsByOuterHTML = this.children\n .filter((element) => !elementIsNoscript(element))\n .map((element) => elementWithoutNonce(element))\n .reduce((result, element) => {\n const { outerHTML } = element;\n const details =\n outerHTML in result\n ? result[outerHTML]\n : {\n type: elementType(element),\n tracked: elementIsTracked(element),\n elements: []\n };\n return {\n ...result,\n [outerHTML]: {\n ...details,\n elements: [...details.elements, element]\n }\n }\n }, {})\n\n get trackedElementSignature() {\n return Object.keys(this.detailsByOuterHTML)\n .filter((outerHTML) => this.detailsByOuterHTML[outerHTML].tracked)\n .join(\"\")\n }\n\n getScriptElementsNotInSnapshot(snapshot) {\n return this.getElementsMatchingTypeNotInSnapshot(\"script\", snapshot)\n }\n\n getStylesheetElementsNotInSnapshot(snapshot) {\n return this.getElementsMatchingTypeNotInSnapshot(\"stylesheet\", snapshot)\n }\n\n getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) {\n return Object.keys(this.detailsByOuterHTML)\n .filter((outerHTML) => !(outerHTML in snapshot.detailsByOuterHTML))\n .map((outerHTML) => this.detailsByOuterHTML[outerHTML])\n .filter(({ type }) => type == matchedType)\n .map(({ elements: [element] }) => element)\n }\n\n get provisionalElements() {\n return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {\n const { type, tracked, elements } = this.detailsByOuterHTML[outerHTML];\n if (type == null && !tracked) {\n return [...result, ...elements]\n } else if (elements.length > 1) {\n return [...result, ...elements.slice(1)]\n } else {\n return result\n }\n }, [])\n }\n\n getMetaValue(name) {\n const element = this.findMetaElementByName(name);\n return element ? element.getAttribute(\"content\") : null\n }\n\n findMetaElementByName(name) {\n return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {\n const {\n elements: [element]\n } = this.detailsByOuterHTML[outerHTML];\n return elementIsMetaElementWithName(element, name) ? element : result\n }, undefined | undefined)\n }\n}\n\nfunction elementType(element) {\n if (elementIsScript(element)) {\n return \"script\"\n } else if (elementIsStylesheet(element)) {\n return \"stylesheet\"\n }\n}\n\nfunction elementIsTracked(element) {\n return element.getAttribute(\"data-turbo-track\") == \"reload\"\n}\n\nfunction elementIsScript(element) {\n const tagName = element.localName;\n return tagName == \"script\"\n}\n\nfunction elementIsNoscript(element) {\n const tagName = element.localName;\n return tagName == \"noscript\"\n}\n\nfunction elementIsStylesheet(element) {\n const tagName = element.localName;\n return tagName == \"style\" || (tagName == \"link\" && element.getAttribute(\"rel\") == \"stylesheet\")\n}\n\nfunction elementIsMetaElementWithName(element, name) {\n const tagName = element.localName;\n return tagName == \"meta\" && element.getAttribute(\"name\") == name\n}\n\nfunction elementWithoutNonce(element) {\n if (element.hasAttribute(\"nonce\")) {\n element.setAttribute(\"nonce\", \"\");\n }\n\n return element\n}\n\nclass PageSnapshot extends Snapshot {\n static fromHTMLString(html = \"\") {\n return this.fromDocument(parseHTMLDocument(html))\n }\n\n static fromElement(element) {\n return this.fromDocument(element.ownerDocument)\n }\n\n static fromDocument({ documentElement, body, head }) {\n return new this(documentElement, body, new HeadSnapshot(head))\n }\n\n constructor(documentElement, body, headSnapshot) {\n super(body);\n this.documentElement = documentElement;\n this.headSnapshot = headSnapshot;\n }\n\n clone() {\n const clonedElement = this.element.cloneNode(true);\n\n const selectElements = this.element.querySelectorAll(\"select\");\n const clonedSelectElements = clonedElement.querySelectorAll(\"select\");\n\n for (const [index, source] of selectElements.entries()) {\n const clone = clonedSelectElements[index];\n for (const option of clone.selectedOptions) option.selected = false;\n for (const option of source.selectedOptions) clone.options[option.index].selected = true;\n }\n\n for (const clonedPasswordInput of clonedElement.querySelectorAll('input[type=\"password\"]')) {\n clonedPasswordInput.value = \"\";\n }\n\n return new PageSnapshot(this.documentElement, clonedElement, this.headSnapshot)\n }\n\n get lang() {\n return this.documentElement.getAttribute(\"lang\")\n }\n\n get headElement() {\n return this.headSnapshot.element\n }\n\n get rootLocation() {\n const root = this.getSetting(\"root\") ?? \"/\";\n return expandURL(root)\n }\n\n get cacheControlValue() {\n return this.getSetting(\"cache-control\")\n }\n\n get isPreviewable() {\n return this.cacheControlValue != \"no-preview\"\n }\n\n get isCacheable() {\n return this.cacheControlValue != \"no-cache\"\n }\n\n get isVisitable() {\n return this.getSetting(\"visit-control\") != \"reload\"\n }\n\n get prefersViewTransitions() {\n return this.headSnapshot.getMetaValue(\"view-transition\") === \"same-origin\"\n }\n\n get shouldMorphPage() {\n return this.getSetting(\"refresh-method\") === \"morph\"\n }\n\n get shouldPreserveScrollPosition() {\n return this.getSetting(\"refresh-scroll\") === \"preserve\"\n }\n\n // Private\n\n getSetting(name) {\n return this.headSnapshot.getMetaValue(`turbo-${name}`)\n }\n}\n\nclass ViewTransitioner {\n #viewTransitionStarted = false\n #lastOperation = Promise.resolve()\n\n renderChange(useViewTransition, render) {\n if (useViewTransition && this.viewTransitionsAvailable && !this.#viewTransitionStarted) {\n this.#viewTransitionStarted = true;\n this.#lastOperation = this.#lastOperation.then(async () => {\n await document.startViewTransition(render).finished;\n });\n } else {\n this.#lastOperation = this.#lastOperation.then(render);\n }\n\n return this.#lastOperation\n }\n\n get viewTransitionsAvailable() {\n return document.startViewTransition\n }\n}\n\nconst defaultOptions = {\n action: \"advance\",\n historyChanged: false,\n visitCachedSnapshot: () => {},\n willRender: true,\n updateHistory: true,\n shouldCacheSnapshot: true,\n acceptsStreamResponse: false\n};\n\nconst TimingMetric = {\n visitStart: \"visitStart\",\n requestStart: \"requestStart\",\n requestEnd: \"requestEnd\",\n visitEnd: \"visitEnd\"\n};\n\nconst VisitState = {\n initialized: \"initialized\",\n started: \"started\",\n canceled: \"canceled\",\n failed: \"failed\",\n completed: \"completed\"\n};\n\nconst SystemStatusCode = {\n networkFailure: 0,\n timeoutFailure: -1,\n contentTypeMismatch: -2\n};\n\nconst Direction = {\n advance: \"forward\",\n restore: \"back\",\n replace: \"none\"\n};\n\nclass Visit {\n identifier = uuid() // Required by turbo-ios\n timingMetrics = {}\n\n followedRedirect = false\n historyChanged = false\n scrolled = false\n shouldCacheSnapshot = true\n acceptsStreamResponse = false\n snapshotCached = false\n state = VisitState.initialized\n viewTransitioner = new ViewTransitioner()\n\n constructor(delegate, location, restorationIdentifier, options = {}) {\n this.delegate = delegate;\n this.location = location;\n this.restorationIdentifier = restorationIdentifier || uuid();\n\n const {\n action,\n historyChanged,\n referrer,\n snapshot,\n snapshotHTML,\n response,\n visitCachedSnapshot,\n willRender,\n updateHistory,\n shouldCacheSnapshot,\n acceptsStreamResponse,\n direction\n } = {\n ...defaultOptions,\n ...options\n };\n this.action = action;\n this.historyChanged = historyChanged;\n this.referrer = referrer;\n this.snapshot = snapshot;\n this.snapshotHTML = snapshotHTML;\n this.response = response;\n this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action);\n this.isPageRefresh = this.view.isPageRefresh(this);\n this.visitCachedSnapshot = visitCachedSnapshot;\n this.willRender = willRender;\n this.updateHistory = updateHistory;\n this.scrolled = !willRender;\n this.shouldCacheSnapshot = shouldCacheSnapshot;\n this.acceptsStreamResponse = acceptsStreamResponse;\n this.direction = direction || Direction[action];\n }\n\n get adapter() {\n return this.delegate.adapter\n }\n\n get view() {\n return this.delegate.view\n }\n\n get history() {\n return this.delegate.history\n }\n\n get restorationData() {\n return this.history.getRestorationDataForIdentifier(this.restorationIdentifier)\n }\n\n get silent() {\n return this.isSamePage\n }\n\n start() {\n if (this.state == VisitState.initialized) {\n this.recordTimingMetric(TimingMetric.visitStart);\n this.state = VisitState.started;\n this.adapter.visitStarted(this);\n this.delegate.visitStarted(this);\n }\n }\n\n cancel() {\n if (this.state == VisitState.started) {\n if (this.request) {\n this.request.cancel();\n }\n this.cancelRender();\n this.state = VisitState.canceled;\n }\n }\n\n complete() {\n if (this.state == VisitState.started) {\n this.recordTimingMetric(TimingMetric.visitEnd);\n this.adapter.visitCompleted(this);\n this.state = VisitState.completed;\n this.followRedirect();\n\n if (!this.followedRedirect) {\n this.delegate.visitCompleted(this);\n }\n }\n }\n\n fail() {\n if (this.state == VisitState.started) {\n this.state = VisitState.failed;\n this.adapter.visitFailed(this);\n this.delegate.visitCompleted(this);\n }\n }\n\n changeHistory() {\n if (!this.historyChanged && this.updateHistory) {\n const actionForHistory = this.location.href === this.referrer?.href ? \"replace\" : this.action;\n const method = getHistoryMethodForAction(actionForHistory);\n this.history.update(method, this.location, this.restorationIdentifier);\n this.historyChanged = true;\n }\n }\n\n issueRequest() {\n if (this.hasPreloadedResponse()) {\n this.simulateRequest();\n } else if (this.shouldIssueRequest() && !this.request) {\n this.request = new FetchRequest(this, FetchMethod.get, this.location);\n this.request.perform();\n }\n }\n\n simulateRequest() {\n if (this.response) {\n this.startRequest();\n this.recordResponse();\n this.finishRequest();\n }\n }\n\n startRequest() {\n this.recordTimingMetric(TimingMetric.requestStart);\n this.adapter.visitRequestStarted(this);\n }\n\n recordResponse(response = this.response) {\n this.response = response;\n if (response) {\n const { statusCode } = response;\n if (isSuccessful(statusCode)) {\n this.adapter.visitRequestCompleted(this);\n } else {\n this.adapter.visitRequestFailedWithStatusCode(this, statusCode);\n }\n }\n }\n\n finishRequest() {\n this.recordTimingMetric(TimingMetric.requestEnd);\n this.adapter.visitRequestFinished(this);\n }\n\n loadResponse() {\n if (this.response) {\n const { statusCode, responseHTML } = this.response;\n this.render(async () => {\n if (this.shouldCacheSnapshot) this.cacheSnapshot();\n if (this.view.renderPromise) await this.view.renderPromise;\n\n if (isSuccessful(statusCode) && responseHTML != null) {\n const snapshot = PageSnapshot.fromHTMLString(responseHTML);\n await this.renderPageSnapshot(snapshot, false);\n\n this.adapter.visitRendered(this);\n this.complete();\n } else {\n await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this);\n this.adapter.visitRendered(this);\n this.fail();\n }\n });\n }\n }\n\n getCachedSnapshot() {\n const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot();\n\n if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) {\n if (this.action == \"restore\" || snapshot.isPreviewable) {\n return snapshot\n }\n }\n }\n\n getPreloadedSnapshot() {\n if (this.snapshotHTML) {\n return PageSnapshot.fromHTMLString(this.snapshotHTML)\n }\n }\n\n hasCachedSnapshot() {\n return this.getCachedSnapshot() != null\n }\n\n loadCachedSnapshot() {\n const snapshot = this.getCachedSnapshot();\n if (snapshot) {\n const isPreview = this.shouldIssueRequest();\n this.render(async () => {\n this.cacheSnapshot();\n if (this.isSamePage || this.isPageRefresh) {\n this.adapter.visitRendered(this);\n } else {\n if (this.view.renderPromise) await this.view.renderPromise;\n\n await this.renderPageSnapshot(snapshot, isPreview);\n\n this.adapter.visitRendered(this);\n if (!isPreview) {\n this.complete();\n }\n }\n });\n }\n }\n\n followRedirect() {\n if (this.redirectedToLocation && !this.followedRedirect && this.response?.redirected) {\n this.adapter.visitProposedToLocation(this.redirectedToLocation, {\n action: \"replace\",\n response: this.response,\n shouldCacheSnapshot: false,\n willRender: false\n });\n this.followedRedirect = true;\n }\n }\n\n goToSamePageAnchor() {\n if (this.isSamePage) {\n this.render(async () => {\n this.cacheSnapshot();\n this.performScroll();\n this.changeHistory();\n this.adapter.visitRendered(this);\n });\n }\n }\n\n // Fetch request delegate\n\n prepareRequest(request) {\n if (this.acceptsStreamResponse) {\n request.acceptResponseType(StreamMessage.contentType);\n }\n }\n\n requestStarted() {\n this.startRequest();\n }\n\n requestPreventedHandlingResponse(_request, _response) {}\n\n async requestSucceededWithResponse(request, response) {\n const responseHTML = await response.responseHTML;\n const { redirected, statusCode } = response;\n if (responseHTML == undefined) {\n this.recordResponse({\n statusCode: SystemStatusCode.contentTypeMismatch,\n redirected\n });\n } else {\n this.redirectedToLocation = response.redirected ? response.location : undefined;\n this.recordResponse({ statusCode: statusCode, responseHTML, redirected });\n }\n }\n\n async requestFailedWithResponse(request, response) {\n const responseHTML = await response.responseHTML;\n const { redirected, statusCode } = response;\n if (responseHTML == undefined) {\n this.recordResponse({\n statusCode: SystemStatusCode.contentTypeMismatch,\n redirected\n });\n } else {\n this.recordResponse({ statusCode: statusCode, responseHTML, redirected });\n }\n }\n\n requestErrored(_request, _error) {\n this.recordResponse({\n statusCode: SystemStatusCode.networkFailure,\n redirected: false\n });\n }\n\n requestFinished() {\n this.finishRequest();\n }\n\n // Scrolling\n\n performScroll() {\n if (!this.scrolled && !this.view.forceReloaded && !this.view.shouldPreserveScrollPosition(this)) {\n if (this.action == \"restore\") {\n this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop();\n } else {\n this.scrollToAnchor() || this.view.scrollToTop();\n }\n if (this.isSamePage) {\n this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation, this.location);\n }\n\n this.scrolled = true;\n }\n }\n\n scrollToRestoredPosition() {\n const { scrollPosition } = this.restorationData;\n if (scrollPosition) {\n this.view.scrollToPosition(scrollPosition);\n return true\n }\n }\n\n scrollToAnchor() {\n const anchor = getAnchor(this.location);\n if (anchor != null) {\n this.view.scrollToAnchor(anchor);\n return true\n }\n }\n\n // Instrumentation\n\n recordTimingMetric(metric) {\n this.timingMetrics[metric] = new Date().getTime();\n }\n\n getTimingMetrics() {\n return { ...this.timingMetrics }\n }\n\n // Private\n\n getHistoryMethodForAction(action) {\n switch (action) {\n case \"replace\":\n return history.replaceState\n case \"advance\":\n case \"restore\":\n return history.pushState\n }\n }\n\n hasPreloadedResponse() {\n return typeof this.response == \"object\"\n }\n\n shouldIssueRequest() {\n if (this.isSamePage) {\n return false\n } else if (this.action == \"restore\") {\n return !this.hasCachedSnapshot()\n } else {\n return this.willRender\n }\n }\n\n cacheSnapshot() {\n if (!this.snapshotCached) {\n this.view.cacheSnapshot(this.snapshot).then((snapshot) => snapshot && this.visitCachedSnapshot(snapshot));\n this.snapshotCached = true;\n }\n }\n\n async render(callback) {\n this.cancelRender();\n await new Promise((resolve) => {\n this.frame =\n document.visibilityState === \"hidden\" ? setTimeout(() => resolve(), 0) : requestAnimationFrame(() => resolve());\n });\n await callback();\n delete this.frame;\n }\n\n async renderPageSnapshot(snapshot, isPreview) {\n await this.viewTransitioner.renderChange(this.view.shouldTransitionTo(snapshot), async () => {\n await this.view.renderPage(snapshot, isPreview, this.willRender, this);\n this.performScroll();\n });\n }\n\n cancelRender() {\n if (this.frame) {\n cancelAnimationFrame(this.frame);\n delete this.frame;\n }\n }\n}\n\nfunction isSuccessful(statusCode) {\n return statusCode >= 200 && statusCode < 300\n}\n\nclass BrowserAdapter {\n progressBar = new ProgressBar()\n\n constructor(session) {\n this.session = session;\n }\n\n visitProposedToLocation(location, options) {\n if (locationIsVisitable(location, this.navigator.rootLocation)) {\n this.navigator.startVisit(location, options?.restorationIdentifier || uuid(), options);\n } else {\n window.location.href = location.toString();\n }\n }\n\n visitStarted(visit) {\n this.location = visit.location;\n visit.loadCachedSnapshot();\n visit.issueRequest();\n visit.goToSamePageAnchor();\n }\n\n visitRequestStarted(visit) {\n this.progressBar.setValue(0);\n if (visit.hasCachedSnapshot() || visit.action != \"restore\") {\n this.showVisitProgressBarAfterDelay();\n } else {\n this.showProgressBar();\n }\n }\n\n visitRequestCompleted(visit) {\n visit.loadResponse();\n }\n\n visitRequestFailedWithStatusCode(visit, statusCode) {\n switch (statusCode) {\n case SystemStatusCode.networkFailure:\n case SystemStatusCode.timeoutFailure:\n case SystemStatusCode.contentTypeMismatch:\n return this.reload({\n reason: \"request_failed\",\n context: {\n statusCode\n }\n })\n default:\n return visit.loadResponse()\n }\n }\n\n visitRequestFinished(_visit) {}\n\n visitCompleted(_visit) {\n this.progressBar.setValue(1);\n this.hideVisitProgressBar();\n }\n\n pageInvalidated(reason) {\n this.reload(reason);\n }\n\n visitFailed(_visit) {\n this.progressBar.setValue(1);\n this.hideVisitProgressBar();\n }\n\n visitRendered(_visit) {}\n\n // Form Submission Delegate\n\n formSubmissionStarted(_formSubmission) {\n this.progressBar.setValue(0);\n this.showFormProgressBarAfterDelay();\n }\n\n formSubmissionFinished(_formSubmission) {\n this.progressBar.setValue(1);\n this.hideFormProgressBar();\n }\n\n // Private\n\n showVisitProgressBarAfterDelay() {\n this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);\n }\n\n hideVisitProgressBar() {\n this.progressBar.hide();\n if (this.visitProgressBarTimeout != null) {\n window.clearTimeout(this.visitProgressBarTimeout);\n delete this.visitProgressBarTimeout;\n }\n }\n\n showFormProgressBarAfterDelay() {\n if (this.formProgressBarTimeout == null) {\n this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);\n }\n }\n\n hideFormProgressBar() {\n this.progressBar.hide();\n if (this.formProgressBarTimeout != null) {\n window.clearTimeout(this.formProgressBarTimeout);\n delete this.formProgressBarTimeout;\n }\n }\n\n showProgressBar = () => {\n this.progressBar.show();\n }\n\n reload(reason) {\n dispatch(\"turbo:reload\", { detail: reason });\n\n window.location.href = this.location?.toString() || window.location.href;\n }\n\n get navigator() {\n return this.session.navigator\n }\n}\n\nclass CacheObserver {\n selector = \"[data-turbo-temporary]\"\n deprecatedSelector = \"[data-turbo-cache=false]\"\n\n started = false\n\n start() {\n if (!this.started) {\n this.started = true;\n addEventListener(\"turbo:before-cache\", this.removeTemporaryElements, false);\n }\n }\n\n stop() {\n if (this.started) {\n this.started = false;\n removeEventListener(\"turbo:before-cache\", this.removeTemporaryElements, false);\n }\n }\n\n removeTemporaryElements = (_event) => {\n for (const element of this.temporaryElements) {\n element.remove();\n }\n }\n\n get temporaryElements() {\n return [...document.querySelectorAll(this.selector), ...this.temporaryElementsWithDeprecation]\n }\n\n get temporaryElementsWithDeprecation() {\n const elements = document.querySelectorAll(this.deprecatedSelector);\n\n if (elements.length) {\n console.warn(\n `The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`\n );\n }\n\n return [...elements]\n }\n}\n\nclass FrameRedirector {\n constructor(session, element) {\n this.session = session;\n this.element = element;\n this.linkInterceptor = new LinkInterceptor(this, element);\n this.formSubmitObserver = new FormSubmitObserver(this, element);\n }\n\n start() {\n this.linkInterceptor.start();\n this.formSubmitObserver.start();\n }\n\n stop() {\n this.linkInterceptor.stop();\n this.formSubmitObserver.stop();\n }\n\n // Link interceptor delegate\n\n shouldInterceptLinkClick(element, _location, _event) {\n return this.#shouldRedirect(element)\n }\n\n linkClickIntercepted(element, url, event) {\n const frame = this.#findFrameElement(element);\n if (frame) {\n frame.delegate.linkClickIntercepted(element, url, event);\n }\n }\n\n // Form submit observer delegate\n\n willSubmitForm(element, submitter) {\n return (\n element.closest(\"turbo-frame\") == null &&\n this.#shouldSubmit(element, submitter) &&\n this.#shouldRedirect(element, submitter)\n )\n }\n\n formSubmitted(element, submitter) {\n const frame = this.#findFrameElement(element, submitter);\n if (frame) {\n frame.delegate.formSubmitted(element, submitter);\n }\n }\n\n #shouldSubmit(form, submitter) {\n const action = getAction$1(form, submitter);\n const meta = this.element.ownerDocument.querySelector(`meta[name=\"turbo-root\"]`);\n const rootLocation = expandURL(meta?.content ?? \"/\");\n\n return this.#shouldRedirect(form, submitter) && locationIsVisitable(action, rootLocation)\n }\n\n #shouldRedirect(element, submitter) {\n const isNavigatable =\n element instanceof HTMLFormElement\n ? this.session.submissionIsNavigatable(element, submitter)\n : this.session.elementIsNavigatable(element);\n\n if (isNavigatable) {\n const frame = this.#findFrameElement(element, submitter);\n return frame ? frame != element.closest(\"turbo-frame\") : false\n } else {\n return false\n }\n }\n\n #findFrameElement(element, submitter) {\n const id = submitter?.getAttribute(\"data-turbo-frame\") || element.getAttribute(\"data-turbo-frame\");\n if (id && id != \"_top\") {\n const frame = this.element.querySelector(`#${id}:not([disabled])`);\n if (frame instanceof FrameElement) {\n return frame\n }\n }\n }\n}\n\nclass History {\n location\n restorationIdentifier = uuid()\n restorationData = {}\n started = false\n pageLoaded = false\n currentIndex = 0\n\n constructor(delegate) {\n this.delegate = delegate;\n }\n\n start() {\n if (!this.started) {\n addEventListener(\"popstate\", this.onPopState, false);\n addEventListener(\"load\", this.onPageLoad, false);\n this.currentIndex = history.state?.turbo?.restorationIndex || 0;\n this.started = true;\n this.replace(new URL(window.location.href));\n }\n }\n\n stop() {\n if (this.started) {\n removeEventListener(\"popstate\", this.onPopState, false);\n removeEventListener(\"load\", this.onPageLoad, false);\n this.started = false;\n }\n }\n\n push(location, restorationIdentifier) {\n this.update(history.pushState, location, restorationIdentifier);\n }\n\n replace(location, restorationIdentifier) {\n this.update(history.replaceState, location, restorationIdentifier);\n }\n\n update(method, location, restorationIdentifier = uuid()) {\n if (method === history.pushState) ++this.currentIndex;\n\n const state = { turbo: { restorationIdentifier, restorationIndex: this.currentIndex } };\n method.call(history, state, \"\", location.href);\n this.location = location;\n this.restorationIdentifier = restorationIdentifier;\n }\n\n // Restoration data\n\n getRestorationDataForIdentifier(restorationIdentifier) {\n return this.restorationData[restorationIdentifier] || {}\n }\n\n updateRestorationData(additionalData) {\n const { restorationIdentifier } = this;\n const restorationData = this.restorationData[restorationIdentifier];\n this.restorationData[restorationIdentifier] = {\n ...restorationData,\n ...additionalData\n };\n }\n\n // Scroll restoration\n\n assumeControlOfScrollRestoration() {\n if (!this.previousScrollRestoration) {\n this.previousScrollRestoration = history.scrollRestoration ?? \"auto\";\n history.scrollRestoration = \"manual\";\n }\n }\n\n relinquishControlOfScrollRestoration() {\n if (this.previousScrollRestoration) {\n history.scrollRestoration = this.previousScrollRestoration;\n delete this.previousScrollRestoration;\n }\n }\n\n // Event handlers\n\n onPopState = (event) => {\n if (this.shouldHandlePopState()) {\n const { turbo } = event.state || {};\n if (turbo) {\n this.location = new URL(window.location.href);\n const { restorationIdentifier, restorationIndex } = turbo;\n this.restorationIdentifier = restorationIdentifier;\n const direction = restorationIndex > this.currentIndex ? \"forward\" : \"back\";\n this.delegate.historyPoppedToLocationWithRestorationIdentifierAndDirection(this.location, restorationIdentifier, direction);\n this.currentIndex = restorationIndex;\n }\n }\n }\n\n onPageLoad = async (_event) => {\n await nextMicrotask();\n this.pageLoaded = true;\n }\n\n // Private\n\n shouldHandlePopState() {\n // Safari dispatches a popstate event after window's load event, ignore it\n return this.pageIsLoaded()\n }\n\n pageIsLoaded() {\n return this.pageLoaded || document.readyState == \"complete\"\n }\n}\n\nclass LinkPrefetchObserver {\n started = false\n #prefetchedLink = null\n\n constructor(delegate, eventTarget) {\n this.delegate = delegate;\n this.eventTarget = eventTarget;\n }\n\n start() {\n if (this.started) return\n\n if (this.eventTarget.readyState === \"loading\") {\n this.eventTarget.addEventListener(\"DOMContentLoaded\", this.#enable, { once: true });\n } else {\n this.#enable();\n }\n }\n\n stop() {\n if (!this.started) return\n\n this.eventTarget.removeEventListener(\"mouseenter\", this.#tryToPrefetchRequest, {\n capture: true,\n passive: true\n });\n this.eventTarget.removeEventListener(\"mouseleave\", this.#cancelRequestIfObsolete, {\n capture: true,\n passive: true\n });\n\n this.eventTarget.removeEventListener(\"turbo:before-fetch-request\", this.#tryToUsePrefetchedRequest, true);\n this.started = false;\n }\n\n #enable = () => {\n this.eventTarget.addEventListener(\"mouseenter\", this.#tryToPrefetchRequest, {\n capture: true,\n passive: true\n });\n this.eventTarget.addEventListener(\"mouseleave\", this.#cancelRequestIfObsolete, {\n capture: true,\n passive: true\n });\n\n this.eventTarget.addEventListener(\"turbo:before-fetch-request\", this.#tryToUsePrefetchedRequest, true);\n this.started = true;\n }\n\n #tryToPrefetchRequest = (event) => {\n if (getMetaContent(\"turbo-prefetch\") === \"false\") return\n\n const target = event.target;\n const isLink = target.matches && target.matches(\"a[href]:not([target^=_]):not([download])\");\n\n if (isLink && this.#isPrefetchable(target)) {\n const link = target;\n const location = getLocationForLink(link);\n\n if (this.delegate.canPrefetchRequestToLocation(link, location)) {\n this.#prefetchedLink = link;\n\n const fetchRequest = new FetchRequest(\n this,\n FetchMethod.get,\n location,\n new URLSearchParams(),\n target\n );\n\n prefetchCache.setLater(location.toString(), fetchRequest, this.#cacheTtl);\n }\n }\n }\n\n #cancelRequestIfObsolete = (event) => {\n if (event.target === this.#prefetchedLink) this.#cancelPrefetchRequest();\n }\n\n #cancelPrefetchRequest = () => {\n prefetchCache.clear();\n this.#prefetchedLink = null;\n }\n\n #tryToUsePrefetchedRequest = (event) => {\n if (event.target.tagName !== \"FORM\" && event.detail.fetchOptions.method === \"GET\") {\n const cached = prefetchCache.get(event.detail.url.toString());\n\n if (cached) {\n // User clicked link, use cache response\n event.detail.fetchRequest = cached;\n }\n\n prefetchCache.clear();\n }\n }\n\n prepareRequest(request) {\n const link = request.target;\n\n request.headers[\"X-Sec-Purpose\"] = \"prefetch\";\n\n const turboFrame = link.closest(\"turbo-frame\");\n const turboFrameTarget = link.getAttribute(\"data-turbo-frame\") || turboFrame?.getAttribute(\"target\") || turboFrame?.id;\n\n if (turboFrameTarget && turboFrameTarget !== \"_top\") {\n request.headers[\"Turbo-Frame\"] = turboFrameTarget;\n }\n }\n\n // Fetch request interface\n\n requestSucceededWithResponse() {}\n\n requestStarted(fetchRequest) {}\n\n requestErrored(fetchRequest) {}\n\n requestFinished(fetchRequest) {}\n\n requestPreventedHandlingResponse(fetchRequest, fetchResponse) {}\n\n requestFailedWithResponse(fetchRequest, fetchResponse) {}\n\n get #cacheTtl() {\n return Number(getMetaContent(\"turbo-prefetch-cache-time\")) || cacheTtl\n }\n\n #isPrefetchable(link) {\n const href = link.getAttribute(\"href\");\n\n if (!href) return false\n\n if (unfetchableLink(link)) return false\n if (linkToTheSamePage(link)) return false\n if (linkOptsOut(link)) return false\n if (nonSafeLink(link)) return false\n if (eventPrevented(link)) return false\n\n return true\n }\n}\n\nconst unfetchableLink = (link) => {\n return link.origin !== document.location.origin || ![\"http:\", \"https:\"].includes(link.protocol) || link.hasAttribute(\"target\")\n};\n\nconst linkToTheSamePage = (link) => {\n return (link.pathname + link.search === document.location.pathname + document.location.search) || link.href.startsWith(\"#\")\n};\n\nconst linkOptsOut = (link) => {\n if (link.getAttribute(\"data-turbo-prefetch\") === \"false\") return true\n if (link.getAttribute(\"data-turbo\") === \"false\") return true\n\n const turboPrefetchParent = findClosestRecursively(link, \"[data-turbo-prefetch]\");\n if (turboPrefetchParent && turboPrefetchParent.getAttribute(\"data-turbo-prefetch\") === \"false\") return true\n\n return false\n};\n\nconst nonSafeLink = (link) => {\n const turboMethod = link.getAttribute(\"data-turbo-method\");\n if (turboMethod && turboMethod.toLowerCase() !== \"get\") return true\n\n if (isUJS(link)) return true\n if (link.hasAttribute(\"data-turbo-confirm\")) return true\n if (link.hasAttribute(\"data-turbo-stream\")) return true\n\n return false\n};\n\nconst isUJS = (link) => {\n return link.hasAttribute(\"data-remote\") || link.hasAttribute(\"data-behavior\") || link.hasAttribute(\"data-confirm\") || link.hasAttribute(\"data-method\")\n};\n\nconst eventPrevented = (link) => {\n const event = dispatch(\"turbo:before-prefetch\", { target: link, cancelable: true });\n return event.defaultPrevented\n};\n\nclass Navigator {\n constructor(delegate) {\n this.delegate = delegate;\n }\n\n proposeVisit(location, options = {}) {\n if (this.delegate.allowsVisitingLocationWithAction(location, options.action)) {\n this.delegate.visitProposedToLocation(location, options);\n }\n }\n\n startVisit(locatable, restorationIdentifier, options = {}) {\n this.stop();\n this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, {\n referrer: this.location,\n ...options\n });\n this.currentVisit.start();\n }\n\n submitForm(form, submitter) {\n this.stop();\n this.formSubmission = new FormSubmission(this, form, submitter, true);\n\n this.formSubmission.start();\n }\n\n stop() {\n if (this.formSubmission) {\n this.formSubmission.stop();\n delete this.formSubmission;\n }\n\n if (this.currentVisit) {\n this.currentVisit.cancel();\n delete this.currentVisit;\n }\n }\n\n get adapter() {\n return this.delegate.adapter\n }\n\n get view() {\n return this.delegate.view\n }\n\n get rootLocation() {\n return this.view.snapshot.rootLocation\n }\n\n get history() {\n return this.delegate.history\n }\n\n // Form submission delegate\n\n formSubmissionStarted(formSubmission) {\n // Not all adapters implement formSubmissionStarted\n if (typeof this.adapter.formSubmissionStarted === \"function\") {\n this.adapter.formSubmissionStarted(formSubmission);\n }\n }\n\n async formSubmissionSucceededWithResponse(formSubmission, fetchResponse) {\n if (formSubmission == this.formSubmission) {\n const responseHTML = await fetchResponse.responseHTML;\n if (responseHTML) {\n const shouldCacheSnapshot = formSubmission.isSafe;\n if (!shouldCacheSnapshot) {\n this.view.clearSnapshotCache();\n }\n\n const { statusCode, redirected } = fetchResponse;\n const action = this.#getActionForFormSubmission(formSubmission, fetchResponse);\n const visitOptions = {\n action,\n shouldCacheSnapshot,\n response: { statusCode, responseHTML, redirected }\n };\n this.proposeVisit(fetchResponse.location, visitOptions);\n }\n }\n }\n\n async formSubmissionFailedWithResponse(formSubmission, fetchResponse) {\n const responseHTML = await fetchResponse.responseHTML;\n\n if (responseHTML) {\n const snapshot = PageSnapshot.fromHTMLString(responseHTML);\n if (fetchResponse.serverError) {\n await this.view.renderError(snapshot, this.currentVisit);\n } else {\n await this.view.renderPage(snapshot, false, true, this.currentVisit);\n }\n if(!snapshot.shouldPreserveScrollPosition) {\n this.view.scrollToTop();\n }\n this.view.clearSnapshotCache();\n }\n }\n\n formSubmissionErrored(formSubmission, error) {\n console.error(error);\n }\n\n formSubmissionFinished(formSubmission) {\n // Not all adapters implement formSubmissionFinished\n if (typeof this.adapter.formSubmissionFinished === \"function\") {\n this.adapter.formSubmissionFinished(formSubmission);\n }\n }\n\n // Visit delegate\n\n visitStarted(visit) {\n this.delegate.visitStarted(visit);\n }\n\n visitCompleted(visit) {\n this.delegate.visitCompleted(visit);\n delete this.currentVisit;\n }\n\n locationWithActionIsSamePage(location, action) {\n const anchor = getAnchor(location);\n const currentAnchor = getAnchor(this.view.lastRenderedLocation);\n const isRestorationToTop = action === \"restore\" && typeof anchor === \"undefined\";\n\n return (\n action !== \"replace\" &&\n getRequestURL(location) === getRequestURL(this.view.lastRenderedLocation) &&\n (isRestorationToTop || (anchor != null && anchor !== currentAnchor))\n )\n }\n\n visitScrolledToSamePageLocation(oldURL, newURL) {\n this.delegate.visitScrolledToSamePageLocation(oldURL, newURL);\n }\n\n // Visits\n\n get location() {\n return this.history.location\n }\n\n get restorationIdentifier() {\n return this.history.restorationIdentifier\n }\n\n #getActionForFormSubmission(formSubmission, fetchResponse) {\n const { submitter, formElement } = formSubmission;\n return getVisitAction(submitter, formElement) || this.#getDefaultAction(fetchResponse)\n }\n\n #getDefaultAction(fetchResponse) {\n const sameLocationRedirect = fetchResponse.redirected && fetchResponse.location.href === this.location?.href;\n return sameLocationRedirect ? \"replace\" : \"advance\"\n }\n}\n\nconst PageStage = {\n initial: 0,\n loading: 1,\n interactive: 2,\n complete: 3\n};\n\nclass PageObserver {\n stage = PageStage.initial\n started = false\n\n constructor(delegate) {\n this.delegate = delegate;\n }\n\n start() {\n if (!this.started) {\n if (this.stage == PageStage.initial) {\n this.stage = PageStage.loading;\n }\n document.addEventListener(\"readystatechange\", this.interpretReadyState, false);\n addEventListener(\"pagehide\", this.pageWillUnload, false);\n this.started = true;\n }\n }\n\n stop() {\n if (this.started) {\n document.removeEventListener(\"readystatechange\", this.interpretReadyState, false);\n removeEventListener(\"pagehide\", this.pageWillUnload, false);\n this.started = false;\n }\n }\n\n interpretReadyState = () => {\n const { readyState } = this;\n if (readyState == \"interactive\") {\n this.pageIsInteractive();\n } else if (readyState == \"complete\") {\n this.pageIsComplete();\n }\n }\n\n pageIsInteractive() {\n if (this.stage == PageStage.loading) {\n this.stage = PageStage.interactive;\n this.delegate.pageBecameInteractive();\n }\n }\n\n pageIsComplete() {\n this.pageIsInteractive();\n if (this.stage == PageStage.interactive) {\n this.stage = PageStage.complete;\n this.delegate.pageLoaded();\n }\n }\n\n pageWillUnload = () => {\n this.delegate.pageWillUnload();\n }\n\n get readyState() {\n return document.readyState\n }\n}\n\nclass ScrollObserver {\n started = false\n\n constructor(delegate) {\n this.delegate = delegate;\n }\n\n start() {\n if (!this.started) {\n addEventListener(\"scroll\", this.onScroll, false);\n this.onScroll();\n this.started = true;\n }\n }\n\n stop() {\n if (this.started) {\n removeEventListener(\"scroll\", this.onScroll, false);\n this.started = false;\n }\n }\n\n onScroll = () => {\n this.updatePosition({ x: window.pageXOffset, y: window.pageYOffset });\n }\n\n // Private\n\n updatePosition(position) {\n this.delegate.scrollPositionChanged(position);\n }\n}\n\nclass StreamMessageRenderer {\n render({ fragment }) {\n Bardo.preservingPermanentElements(this, getPermanentElementMapForFragment(fragment), () => {\n withAutofocusFromFragment(fragment, () => {\n withPreservedFocus(() => {\n document.documentElement.appendChild(fragment);\n });\n });\n });\n }\n\n // Bardo delegate\n\n enteringBardo(currentPermanentElement, newPermanentElement) {\n newPermanentElement.replaceWith(currentPermanentElement.cloneNode(true));\n }\n\n leavingBardo() {}\n}\n\nfunction getPermanentElementMapForFragment(fragment) {\n const permanentElementsInDocument = queryPermanentElementsAll(document.documentElement);\n const permanentElementMap = {};\n for (const permanentElementInDocument of permanentElementsInDocument) {\n const { id } = permanentElementInDocument;\n\n for (const streamElement of fragment.querySelectorAll(\"turbo-stream\")) {\n const elementInStream = getPermanentElementById(streamElement.templateElement.content, id);\n\n if (elementInStream) {\n permanentElementMap[id] = [permanentElementInDocument, elementInStream];\n }\n }\n }\n\n return permanentElementMap\n}\n\nasync function withAutofocusFromFragment(fragment, callback) {\n const generatedID = `turbo-stream-autofocus-${uuid()}`;\n const turboStreams = fragment.querySelectorAll(\"turbo-stream\");\n const elementWithAutofocus = firstAutofocusableElementInStreams(turboStreams);\n let willAutofocusId = null;\n\n if (elementWithAutofocus) {\n if (elementWithAutofocus.id) {\n willAutofocusId = elementWithAutofocus.id;\n } else {\n willAutofocusId = generatedID;\n }\n\n elementWithAutofocus.id = willAutofocusId;\n }\n\n callback();\n await nextRepaint();\n\n const hasNoActiveElement = document.activeElement == null || document.activeElement == document.body;\n\n if (hasNoActiveElement && willAutofocusId) {\n const elementToAutofocus = document.getElementById(willAutofocusId);\n\n if (elementIsFocusable(elementToAutofocus)) {\n elementToAutofocus.focus();\n }\n if (elementToAutofocus && elementToAutofocus.id == generatedID) {\n elementToAutofocus.removeAttribute(\"id\");\n }\n }\n}\n\nasync function withPreservedFocus(callback) {\n const [activeElementBeforeRender, activeElementAfterRender] = await around(callback, () => document.activeElement);\n\n const restoreFocusTo = activeElementBeforeRender && activeElementBeforeRender.id;\n\n if (restoreFocusTo) {\n const elementToFocus = document.getElementById(restoreFocusTo);\n\n if (elementIsFocusable(elementToFocus) && elementToFocus != activeElementAfterRender) {\n elementToFocus.focus();\n }\n }\n}\n\nfunction firstAutofocusableElementInStreams(nodeListOfStreamElements) {\n for (const streamElement of nodeListOfStreamElements) {\n const elementWithAutofocus = queryAutofocusableElement(streamElement.templateElement.content);\n\n if (elementWithAutofocus) return elementWithAutofocus\n }\n\n return null\n}\n\nclass StreamObserver {\n sources = new Set()\n #started = false\n\n constructor(delegate) {\n this.delegate = delegate;\n }\n\n start() {\n if (!this.#started) {\n this.#started = true;\n addEventListener(\"turbo:before-fetch-response\", this.inspectFetchResponse, false);\n }\n }\n\n stop() {\n if (this.#started) {\n this.#started = false;\n removeEventListener(\"turbo:before-fetch-response\", this.inspectFetchResponse, false);\n }\n }\n\n connectStreamSource(source) {\n if (!this.streamSourceIsConnected(source)) {\n this.sources.add(source);\n source.addEventListener(\"message\", this.receiveMessageEvent, false);\n }\n }\n\n disconnectStreamSource(source) {\n if (this.streamSourceIsConnected(source)) {\n this.sources.delete(source);\n source.removeEventListener(\"message\", this.receiveMessageEvent, false);\n }\n }\n\n streamSourceIsConnected(source) {\n return this.sources.has(source)\n }\n\n inspectFetchResponse = (event) => {\n const response = fetchResponseFromEvent(event);\n if (response && fetchResponseIsStream(response)) {\n event.preventDefault();\n this.receiveMessageResponse(response);\n }\n }\n\n receiveMessageEvent = (event) => {\n if (this.#started && typeof event.data == \"string\") {\n this.receiveMessageHTML(event.data);\n }\n }\n\n async receiveMessageResponse(response) {\n const html = await response.responseHTML;\n if (html) {\n this.receiveMessageHTML(html);\n }\n }\n\n receiveMessageHTML(html) {\n this.delegate.receivedMessageFromStream(StreamMessage.wrap(html));\n }\n}\n\nfunction fetchResponseFromEvent(event) {\n const fetchResponse = event.detail?.fetchResponse;\n if (fetchResponse instanceof FetchResponse) {\n return fetchResponse\n }\n}\n\nfunction fetchResponseIsStream(response) {\n const contentType = response.contentType ?? \"\";\n return contentType.startsWith(StreamMessage.contentType)\n}\n\nclass ErrorRenderer extends Renderer {\n static renderElement(currentElement, newElement) {\n const { documentElement, body } = document;\n\n documentElement.replaceChild(newElement, body);\n }\n\n async render() {\n this.replaceHeadAndBody();\n this.activateScriptElements();\n }\n\n replaceHeadAndBody() {\n const { documentElement, head } = document;\n documentElement.replaceChild(this.newHead, head);\n this.renderElement(this.currentElement, this.newElement);\n }\n\n activateScriptElements() {\n for (const replaceableElement of this.scriptElements) {\n const parentNode = replaceableElement.parentNode;\n if (parentNode) {\n const element = activateScriptElement(replaceableElement);\n parentNode.replaceChild(element, replaceableElement);\n }\n }\n }\n\n get newHead() {\n return this.newSnapshot.headSnapshot.element\n }\n\n get scriptElements() {\n return document.documentElement.querySelectorAll(\"script\")\n }\n}\n\nclass PageRenderer extends Renderer {\n static renderElement(currentElement, newElement) {\n if (document.body && newElement instanceof HTMLBodyElement) {\n document.body.replaceWith(newElement);\n } else {\n document.documentElement.appendChild(newElement);\n }\n }\n\n get shouldRender() {\n return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical\n }\n\n get reloadReason() {\n if (!this.newSnapshot.isVisitable) {\n return {\n reason: \"turbo_visit_control_is_reload\"\n }\n }\n\n if (!this.trackedElementsAreIdentical) {\n return {\n reason: \"tracked_element_mismatch\"\n }\n }\n }\n\n async prepareToRender() {\n this.#setLanguage();\n await this.mergeHead();\n }\n\n async render() {\n if (this.willRender) {\n await this.replaceBody();\n }\n }\n\n finishRendering() {\n super.finishRendering();\n if (!this.isPreview) {\n this.focusFirstAutofocusableElement();\n }\n }\n\n get currentHeadSnapshot() {\n return this.currentSnapshot.headSnapshot\n }\n\n get newHeadSnapshot() {\n return this.newSnapshot.headSnapshot\n }\n\n get newElement() {\n return this.newSnapshot.element\n }\n\n #setLanguage() {\n const { documentElement } = this.currentSnapshot;\n const { lang } = this.newSnapshot;\n\n if (lang) {\n documentElement.setAttribute(\"lang\", lang);\n } else {\n documentElement.removeAttribute(\"lang\");\n }\n }\n\n async mergeHead() {\n const mergedHeadElements = this.mergeProvisionalElements();\n const newStylesheetElements = this.copyNewHeadStylesheetElements();\n this.copyNewHeadScriptElements();\n\n await mergedHeadElements;\n await newStylesheetElements;\n\n if (this.willRender) {\n this.removeUnusedDynamicStylesheetElements();\n }\n }\n\n async replaceBody() {\n await this.preservingPermanentElements(async () => {\n this.activateNewBody();\n await this.assignNewBody();\n });\n }\n\n get trackedElementsAreIdentical() {\n return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature\n }\n\n async copyNewHeadStylesheetElements() {\n const loadingElements = [];\n\n for (const element of this.newHeadStylesheetElements) {\n loadingElements.push(waitForLoad(element));\n\n document.head.appendChild(element);\n }\n\n await Promise.all(loadingElements);\n }\n\n copyNewHeadScriptElements() {\n for (const element of this.newHeadScriptElements) {\n document.head.appendChild(activateScriptElement(element));\n }\n }\n\n removeUnusedDynamicStylesheetElements() {\n for (const element of this.unusedDynamicStylesheetElements) {\n document.head.removeChild(element);\n }\n }\n\n async mergeProvisionalElements() {\n const newHeadElements = [...this.newHeadProvisionalElements];\n\n for (const element of this.currentHeadProvisionalElements) {\n if (!this.isCurrentElementInElementList(element, newHeadElements)) {\n document.head.removeChild(element);\n }\n }\n\n for (const element of newHeadElements) {\n document.head.appendChild(element);\n }\n }\n\n isCurrentElementInElementList(element, elementList) {\n for (const [index, newElement] of elementList.entries()) {\n // if title element...\n if (element.tagName == \"TITLE\") {\n if (newElement.tagName != \"TITLE\") {\n continue\n }\n if (element.innerHTML == newElement.innerHTML) {\n elementList.splice(index, 1);\n return true\n }\n }\n\n // if any other element...\n if (newElement.isEqualNode(element)) {\n elementList.splice(index, 1);\n return true\n }\n }\n\n return false\n }\n\n removeCurrentHeadProvisionalElements() {\n for (const element of this.currentHeadProvisionalElements) {\n document.head.removeChild(element);\n }\n }\n\n copyNewHeadProvisionalElements() {\n for (const element of this.newHeadProvisionalElements) {\n document.head.appendChild(element);\n }\n }\n\n activateNewBody() {\n document.adoptNode(this.newElement);\n this.activateNewBodyScriptElements();\n }\n\n activateNewBodyScriptElements() {\n for (const inertScriptElement of this.newBodyScriptElements) {\n const activatedScriptElement = activateScriptElement(inertScriptElement);\n inertScriptElement.replaceWith(activatedScriptElement);\n }\n }\n\n async assignNewBody() {\n await this.renderElement(this.currentElement, this.newElement);\n }\n\n get unusedDynamicStylesheetElements() {\n return this.oldHeadStylesheetElements.filter((element) => {\n return element.getAttribute(\"data-turbo-track\") === \"dynamic\"\n })\n }\n\n get oldHeadStylesheetElements() {\n return this.currentHeadSnapshot.getStylesheetElementsNotInSnapshot(this.newHeadSnapshot)\n }\n\n get newHeadStylesheetElements() {\n return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot)\n }\n\n get newHeadScriptElements() {\n return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot)\n }\n\n get currentHeadProvisionalElements() {\n return this.currentHeadSnapshot.provisionalElements\n }\n\n get newHeadProvisionalElements() {\n return this.newHeadSnapshot.provisionalElements\n }\n\n get newBodyScriptElements() {\n return this.newElement.querySelectorAll(\"script\")\n }\n}\n\nclass MorphingPageRenderer extends PageRenderer {\n static renderElement(currentElement, newElement) {\n morphElements(currentElement, newElement, {\n callbacks: {\n beforeNodeMorphed: element => !canRefreshFrame(element)\n }\n });\n\n for (const frame of currentElement.querySelectorAll(\"turbo-frame\")) {\n if (canRefreshFrame(frame)) frame.reload();\n }\n\n dispatch(\"turbo:morph\", { detail: { currentElement, newElement } });\n }\n\n async preservingPermanentElements(callback) {\n return await callback()\n }\n\n get renderMethod() {\n return \"morph\"\n }\n\n get shouldAutofocus() {\n return false\n }\n}\n\nfunction canRefreshFrame(frame) {\n return frame instanceof FrameElement &&\n frame.src &&\n frame.refresh === \"morph\" &&\n !frame.closest(\"[data-turbo-permanent]\")\n}\n\nclass SnapshotCache {\n keys = []\n snapshots = {}\n\n constructor(size) {\n this.size = size;\n }\n\n has(location) {\n return toCacheKey(location) in this.snapshots\n }\n\n get(location) {\n if (this.has(location)) {\n const snapshot = this.read(location);\n this.touch(location);\n return snapshot\n }\n }\n\n put(location, snapshot) {\n this.write(location, snapshot);\n this.touch(location);\n return snapshot\n }\n\n clear() {\n this.snapshots = {};\n }\n\n // Private\n\n read(location) {\n return this.snapshots[toCacheKey(location)]\n }\n\n write(location, snapshot) {\n this.snapshots[toCacheKey(location)] = snapshot;\n }\n\n touch(location) {\n const key = toCacheKey(location);\n const index = this.keys.indexOf(key);\n if (index > -1) this.keys.splice(index, 1);\n this.keys.unshift(key);\n this.trim();\n }\n\n trim() {\n for (const key of this.keys.splice(this.size)) {\n delete this.snapshots[key];\n }\n }\n}\n\nclass PageView extends View {\n snapshotCache = new SnapshotCache(10)\n lastRenderedLocation = new URL(location.href)\n forceReloaded = false\n\n shouldTransitionTo(newSnapshot) {\n return this.snapshot.prefersViewTransitions && newSnapshot.prefersViewTransitions\n }\n\n renderPage(snapshot, isPreview = false, willRender = true, visit) {\n const shouldMorphPage = this.isPageRefresh(visit) && this.snapshot.shouldMorphPage;\n const rendererClass = shouldMorphPage ? MorphingPageRenderer : PageRenderer;\n\n const renderer = new rendererClass(this.snapshot, snapshot, rendererClass.renderElement, isPreview, willRender);\n\n if (!renderer.shouldRender) {\n this.forceReloaded = true;\n } else {\n visit?.changeHistory();\n }\n\n return this.render(renderer)\n }\n\n renderError(snapshot, visit) {\n visit?.changeHistory();\n const renderer = new ErrorRenderer(this.snapshot, snapshot, ErrorRenderer.renderElement, false);\n return this.render(renderer)\n }\n\n clearSnapshotCache() {\n this.snapshotCache.clear();\n }\n\n async cacheSnapshot(snapshot = this.snapshot) {\n if (snapshot.isCacheable) {\n this.delegate.viewWillCacheSnapshot();\n const { lastRenderedLocation: location } = this;\n await nextEventLoopTick();\n const cachedSnapshot = snapshot.clone();\n this.snapshotCache.put(location, cachedSnapshot);\n return cachedSnapshot\n }\n }\n\n getCachedSnapshotForLocation(location) {\n return this.snapshotCache.get(location)\n }\n\n isPageRefresh(visit) {\n return !visit || (this.lastRenderedLocation.pathname === visit.location.pathname && visit.action === \"replace\")\n }\n\n shouldPreserveScrollPosition(visit) {\n return this.isPageRefresh(visit) && this.snapshot.shouldPreserveScrollPosition\n }\n\n get snapshot() {\n return PageSnapshot.fromElement(this.element)\n }\n}\n\nclass Preloader {\n selector = \"a[data-turbo-preload]\"\n\n constructor(delegate, snapshotCache) {\n this.delegate = delegate;\n this.snapshotCache = snapshotCache;\n }\n\n start() {\n if (document.readyState === \"loading\") {\n document.addEventListener(\"DOMContentLoaded\", this.#preloadAll);\n } else {\n this.preloadOnLoadLinksForView(document.body);\n }\n }\n\n stop() {\n document.removeEventListener(\"DOMContentLoaded\", this.#preloadAll);\n }\n\n preloadOnLoadLinksForView(element) {\n for (const link of element.querySelectorAll(this.selector)) {\n if (this.delegate.shouldPreloadLink(link)) {\n this.preloadURL(link);\n }\n }\n }\n\n async preloadURL(link) {\n const location = new URL(link.href);\n\n if (this.snapshotCache.has(location)) {\n return\n }\n\n const fetchRequest = new FetchRequest(this, FetchMethod.get, location, new URLSearchParams(), link);\n await fetchRequest.perform();\n }\n\n // Fetch request delegate\n\n prepareRequest(fetchRequest) {\n fetchRequest.headers[\"X-Sec-Purpose\"] = \"prefetch\";\n }\n\n async requestSucceededWithResponse(fetchRequest, fetchResponse) {\n try {\n const responseHTML = await fetchResponse.responseHTML;\n const snapshot = PageSnapshot.fromHTMLString(responseHTML);\n\n this.snapshotCache.put(fetchRequest.url, snapshot);\n } catch (_) {\n // If we cannot preload that is ok!\n }\n }\n\n requestStarted(fetchRequest) {}\n\n requestErrored(fetchRequest) {}\n\n requestFinished(fetchRequest) {}\n\n requestPreventedHandlingResponse(fetchRequest, fetchResponse) {}\n\n requestFailedWithResponse(fetchRequest, fetchResponse) {}\n\n #preloadAll = () => {\n this.preloadOnLoadLinksForView(document.body);\n }\n}\n\nclass Cache {\n constructor(session) {\n this.session = session;\n }\n\n clear() {\n this.session.clearCache();\n }\n\n resetCacheControl() {\n this.#setCacheControl(\"\");\n }\n\n exemptPageFromCache() {\n this.#setCacheControl(\"no-cache\");\n }\n\n exemptPageFromPreview() {\n this.#setCacheControl(\"no-preview\");\n }\n\n #setCacheControl(value) {\n setMetaContent(\"turbo-cache-control\", value);\n }\n}\n\nclass Session {\n navigator = new Navigator(this)\n history = new History(this)\n view = new PageView(this, document.documentElement)\n adapter = new BrowserAdapter(this)\n\n pageObserver = new PageObserver(this)\n cacheObserver = new CacheObserver()\n linkPrefetchObserver = new LinkPrefetchObserver(this, document)\n linkClickObserver = new LinkClickObserver(this, window)\n formSubmitObserver = new FormSubmitObserver(this, document)\n scrollObserver = new ScrollObserver(this)\n streamObserver = new StreamObserver(this)\n formLinkClickObserver = new FormLinkClickObserver(this, document.documentElement)\n frameRedirector = new FrameRedirector(this, document.documentElement)\n streamMessageRenderer = new StreamMessageRenderer()\n cache = new Cache(this)\n\n enabled = true\n started = false\n #pageRefreshDebouncePeriod = 150\n\n constructor(recentRequests) {\n this.recentRequests = recentRequests;\n this.preloader = new Preloader(this, this.view.snapshotCache);\n this.debouncedRefresh = this.refresh;\n this.pageRefreshDebouncePeriod = this.pageRefreshDebouncePeriod;\n }\n\n start() {\n if (!this.started) {\n this.pageObserver.start();\n this.cacheObserver.start();\n this.linkPrefetchObserver.start();\n this.formLinkClickObserver.start();\n this.linkClickObserver.start();\n this.formSubmitObserver.start();\n this.scrollObserver.start();\n this.streamObserver.start();\n this.frameRedirector.start();\n this.history.start();\n this.preloader.start();\n this.started = true;\n this.enabled = true;\n }\n }\n\n disable() {\n this.enabled = false;\n }\n\n stop() {\n if (this.started) {\n this.pageObserver.stop();\n this.cacheObserver.stop();\n this.linkPrefetchObserver.stop();\n this.formLinkClickObserver.stop();\n this.linkClickObserver.stop();\n this.formSubmitObserver.stop();\n this.scrollObserver.stop();\n this.streamObserver.stop();\n this.frameRedirector.stop();\n this.history.stop();\n this.preloader.stop();\n this.started = false;\n }\n }\n\n registerAdapter(adapter) {\n this.adapter = adapter;\n }\n\n visit(location, options = {}) {\n const frameElement = options.frame ? document.getElementById(options.frame) : null;\n\n if (frameElement instanceof FrameElement) {\n const action = options.action || getVisitAction(frameElement);\n\n frameElement.delegate.proposeVisitIfNavigatedWithAction(frameElement, action);\n frameElement.src = location.toString();\n } else {\n this.navigator.proposeVisit(expandURL(location), options);\n }\n }\n\n refresh(url, requestId) {\n const isRecentRequest = requestId && this.recentRequests.has(requestId);\n if (!isRecentRequest && !this.navigator.currentVisit) {\n this.visit(url, { action: \"replace\", shouldCacheSnapshot: false });\n }\n }\n\n connectStreamSource(source) {\n this.streamObserver.connectStreamSource(source);\n }\n\n disconnectStreamSource(source) {\n this.streamObserver.disconnectStreamSource(source);\n }\n\n renderStreamMessage(message) {\n this.streamMessageRenderer.render(StreamMessage.wrap(message));\n }\n\n clearCache() {\n this.view.clearSnapshotCache();\n }\n\n setProgressBarDelay(delay) {\n console.warn(\n \"Please replace `session.setProgressBarDelay(delay)` with `session.progressBarDelay = delay`. The function is deprecated and will be removed in a future version of Turbo.`\"\n );\n\n this.progressBarDelay = delay;\n }\n\n set progressBarDelay(delay) {\n config.drive.progressBarDelay = delay;\n }\n\n get progressBarDelay() {\n return config.drive.progressBarDelay\n }\n\n set drive(value) {\n config.drive.enabled = value;\n }\n\n get drive() {\n return config.drive.enabled\n }\n\n set formMode(value) {\n config.forms.mode = value;\n }\n\n get formMode() {\n return config.forms.mode\n }\n\n get location() {\n return this.history.location\n }\n\n get restorationIdentifier() {\n return this.history.restorationIdentifier\n }\n\n get pageRefreshDebouncePeriod() {\n return this.#pageRefreshDebouncePeriod\n }\n\n set pageRefreshDebouncePeriod(value) {\n this.refresh = debounce(this.debouncedRefresh.bind(this), value);\n this.#pageRefreshDebouncePeriod = value;\n }\n\n // Preloader delegate\n\n shouldPreloadLink(element) {\n const isUnsafe = element.hasAttribute(\"data-turbo-method\");\n const isStream = element.hasAttribute(\"data-turbo-stream\");\n const frameTarget = element.getAttribute(\"data-turbo-frame\");\n const frame = frameTarget == \"_top\" ?\n null :\n document.getElementById(frameTarget) || findClosestRecursively(element, \"turbo-frame:not([disabled])\");\n\n if (isUnsafe || isStream || frame instanceof FrameElement) {\n return false\n } else {\n const location = new URL(element.href);\n\n return this.elementIsNavigatable(element) && locationIsVisitable(location, this.snapshot.rootLocation)\n }\n }\n\n // History delegate\n\n historyPoppedToLocationWithRestorationIdentifierAndDirection(location, restorationIdentifier, direction) {\n if (this.enabled) {\n this.navigator.startVisit(location, restorationIdentifier, {\n action: \"restore\",\n historyChanged: true,\n direction\n });\n } else {\n this.adapter.pageInvalidated({\n reason: \"turbo_disabled\"\n });\n }\n }\n\n // Scroll observer delegate\n\n scrollPositionChanged(position) {\n this.history.updateRestorationData({ scrollPosition: position });\n }\n\n // Form click observer delegate\n\n willSubmitFormLinkToLocation(link, location) {\n return this.elementIsNavigatable(link) && locationIsVisitable(location, this.snapshot.rootLocation)\n }\n\n submittedFormLinkToLocation() {}\n\n // Link hover observer delegate\n\n canPrefetchRequestToLocation(link, location) {\n return (\n this.elementIsNavigatable(link) &&\n locationIsVisitable(location, this.snapshot.rootLocation)\n )\n }\n\n // Link click observer delegate\n\n willFollowLinkToLocation(link, location, event) {\n return (\n this.elementIsNavigatable(link) &&\n locationIsVisitable(location, this.snapshot.rootLocation) &&\n this.applicationAllowsFollowingLinkToLocation(link, location, event)\n )\n }\n\n followedLinkToLocation(link, location) {\n const action = this.getActionForLink(link);\n const acceptsStreamResponse = link.hasAttribute(\"data-turbo-stream\");\n\n this.visit(location.href, { action, acceptsStreamResponse });\n }\n\n // Navigator delegate\n\n allowsVisitingLocationWithAction(location, action) {\n return this.locationWithActionIsSamePage(location, action) || this.applicationAllowsVisitingLocation(location)\n }\n\n visitProposedToLocation(location, options) {\n extendURLWithDeprecatedProperties(location);\n this.adapter.visitProposedToLocation(location, options);\n }\n\n // Visit delegate\n\n visitStarted(visit) {\n if (!visit.acceptsStreamResponse) {\n markAsBusy(document.documentElement);\n this.view.markVisitDirection(visit.direction);\n }\n extendURLWithDeprecatedProperties(visit.location);\n if (!visit.silent) {\n this.notifyApplicationAfterVisitingLocation(visit.location, visit.action);\n }\n }\n\n visitCompleted(visit) {\n this.view.unmarkVisitDirection();\n clearBusyState(document.documentElement);\n this.notifyApplicationAfterPageLoad(visit.getTimingMetrics());\n }\n\n locationWithActionIsSamePage(location, action) {\n return this.navigator.locationWithActionIsSamePage(location, action)\n }\n\n visitScrolledToSamePageLocation(oldURL, newURL) {\n this.notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL);\n }\n\n // Form submit observer delegate\n\n willSubmitForm(form, submitter) {\n const action = getAction$1(form, submitter);\n\n return (\n this.submissionIsNavigatable(form, submitter) &&\n locationIsVisitable(expandURL(action), this.snapshot.rootLocation)\n )\n }\n\n formSubmitted(form, submitter) {\n this.navigator.submitForm(form, submitter);\n }\n\n // Page observer delegate\n\n pageBecameInteractive() {\n this.view.lastRenderedLocation = this.location;\n this.notifyApplicationAfterPageLoad();\n }\n\n pageLoaded() {\n this.history.assumeControlOfScrollRestoration();\n }\n\n pageWillUnload() {\n this.history.relinquishControlOfScrollRestoration();\n }\n\n // Stream observer delegate\n\n receivedMessageFromStream(message) {\n this.renderStreamMessage(message);\n }\n\n // Page view delegate\n\n viewWillCacheSnapshot() {\n if (!this.navigator.currentVisit?.silent) {\n this.notifyApplicationBeforeCachingSnapshot();\n }\n }\n\n allowsImmediateRender({ element }, options) {\n const event = this.notifyApplicationBeforeRender(element, options);\n const {\n defaultPrevented,\n detail: { render }\n } = event;\n\n if (this.view.renderer && render) {\n this.view.renderer.renderElement = render;\n }\n\n return !defaultPrevented\n }\n\n viewRenderedSnapshot(_snapshot, _isPreview, renderMethod) {\n this.view.lastRenderedLocation = this.history.location;\n this.notifyApplicationAfterRender(renderMethod);\n }\n\n preloadOnLoadLinksForView(element) {\n this.preloader.preloadOnLoadLinksForView(element);\n }\n\n viewInvalidated(reason) {\n this.adapter.pageInvalidated(reason);\n }\n\n // Frame element\n\n frameLoaded(frame) {\n this.notifyApplicationAfterFrameLoad(frame);\n }\n\n frameRendered(fetchResponse, frame) {\n this.notifyApplicationAfterFrameRender(fetchResponse, frame);\n }\n\n // Application events\n\n applicationAllowsFollowingLinkToLocation(link, location, ev) {\n const event = this.notifyApplicationAfterClickingLinkToLocation(link, location, ev);\n return !event.defaultPrevented\n }\n\n applicationAllowsVisitingLocation(location) {\n const event = this.notifyApplicationBeforeVisitingLocation(location);\n return !event.defaultPrevented\n }\n\n notifyApplicationAfterClickingLinkToLocation(link, location, event) {\n return dispatch(\"turbo:click\", {\n target: link,\n detail: { url: location.href, originalEvent: event },\n cancelable: true\n })\n }\n\n notifyApplicationBeforeVisitingLocation(location) {\n return dispatch(\"turbo:before-visit\", {\n detail: { url: location.href },\n cancelable: true\n })\n }\n\n notifyApplicationAfterVisitingLocation(location, action) {\n return dispatch(\"turbo:visit\", { detail: { url: location.href, action } })\n }\n\n notifyApplicationBeforeCachingSnapshot() {\n return dispatch(\"turbo:before-cache\")\n }\n\n notifyApplicationBeforeRender(newBody, options) {\n return dispatch(\"turbo:before-render\", {\n detail: { newBody, ...options },\n cancelable: true\n })\n }\n\n notifyApplicationAfterRender(renderMethod) {\n return dispatch(\"turbo:render\", { detail: { renderMethod } })\n }\n\n notifyApplicationAfterPageLoad(timing = {}) {\n return dispatch(\"turbo:load\", {\n detail: { url: this.location.href, timing }\n })\n }\n\n notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL) {\n dispatchEvent(\n new HashChangeEvent(\"hashchange\", {\n oldURL: oldURL.toString(),\n newURL: newURL.toString()\n })\n );\n }\n\n notifyApplicationAfterFrameLoad(frame) {\n return dispatch(\"turbo:frame-load\", { target: frame })\n }\n\n notifyApplicationAfterFrameRender(fetchResponse, frame) {\n return dispatch(\"turbo:frame-render\", {\n detail: { fetchResponse },\n target: frame,\n cancelable: true\n })\n }\n\n // Helpers\n\n submissionIsNavigatable(form, submitter) {\n if (config.forms.mode == \"off\") {\n return false\n } else {\n const submitterIsNavigatable = submitter ? this.elementIsNavigatable(submitter) : true;\n\n if (config.forms.mode == \"optin\") {\n return submitterIsNavigatable && form.closest('[data-turbo=\"true\"]') != null\n } else {\n return submitterIsNavigatable && this.elementIsNavigatable(form)\n }\n }\n }\n\n elementIsNavigatable(element) {\n const container = findClosestRecursively(element, \"[data-turbo]\");\n const withinFrame = findClosestRecursively(element, \"turbo-frame\");\n\n // Check if Drive is enabled on the session or we're within a Frame.\n if (config.drive.enabled || withinFrame) {\n // Element is navigatable by default, unless `data-turbo=\"false\"`.\n if (container) {\n return container.getAttribute(\"data-turbo\") != \"false\"\n } else {\n return true\n }\n } else {\n // Element isn't navigatable by default, unless `data-turbo=\"true\"`.\n if (container) {\n return container.getAttribute(\"data-turbo\") == \"true\"\n } else {\n return false\n }\n }\n }\n\n // Private\n\n getActionForLink(link) {\n return getVisitAction(link) || \"advance\"\n }\n\n get snapshot() {\n return this.view.snapshot\n }\n}\n\n// Older versions of the Turbo Native adapters referenced the\n// `Location#absoluteURL` property in their implementations of\n// the `Adapter#visitProposedToLocation()` and `#visitStarted()`\n// methods. The Location class has since been removed in favor\n// of the DOM URL API, and accordingly all Adapter methods now\n// receive URL objects.\n//\n// We alias #absoluteURL to #toString() here to avoid crashing\n// older adapters which do not expect URL objects. We should\n// consider removing this support at some point in the future.\n\nfunction extendURLWithDeprecatedProperties(url) {\n Object.defineProperties(url, deprecatedLocationPropertyDescriptors);\n}\n\nconst deprecatedLocationPropertyDescriptors = {\n absoluteURL: {\n get() {\n return this.toString()\n }\n }\n};\n\nconst session = new Session(recentRequests);\nconst { cache, navigator: navigator$1 } = session;\n\n/**\n * Starts the main session.\n * This initialises any necessary observers such as those to monitor\n * link interactions.\n */\nfunction start() {\n session.start();\n}\n\n/**\n * Registers an adapter for the main session.\n *\n * @param adapter Adapter to register\n */\nfunction registerAdapter(adapter) {\n session.registerAdapter(adapter);\n}\n\n/**\n * Performs an application visit to the given location.\n *\n * @param location Location to visit (a URL or path)\n * @param options Options to apply\n * @param options.action Type of history navigation to apply (\"restore\",\n * \"replace\" or \"advance\")\n * @param options.historyChanged Specifies whether the browser history has\n * already been changed for this visit or not\n * @param options.referrer Specifies the referrer of this visit such that\n * navigations to the same page will not result in a new history entry.\n * @param options.snapshotHTML Cached snapshot to render\n * @param options.response Response of the specified location\n */\nfunction visit(location, options) {\n session.visit(location, options);\n}\n\n/**\n * Connects a stream source to the main session.\n *\n * @param source Stream source to connect\n */\nfunction connectStreamSource(source) {\n session.connectStreamSource(source);\n}\n\n/**\n * Disconnects a stream source from the main session.\n *\n * @param source Stream source to disconnect\n */\nfunction disconnectStreamSource(source) {\n session.disconnectStreamSource(source);\n}\n\n/**\n * Renders a stream message to the main session by appending it to the\n * current document.\n *\n * @param message Message to render\n */\nfunction renderStreamMessage(message) {\n session.renderStreamMessage(message);\n}\n\n/**\n * Removes all entries from the Turbo Drive page cache.\n * Call this when state has changed on the server that may affect cached pages.\n *\n * @deprecated since version 7.2.0 in favor of `Turbo.cache.clear()`\n */\nfunction clearCache() {\n console.warn(\n \"Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`\"\n );\n session.clearCache();\n}\n\n/**\n * Sets the delay after which the progress bar will appear during navigation.\n *\n * The progress bar appears after 500ms by default.\n *\n * Note that this method has no effect when used with the iOS or Android\n * adapters.\n *\n * @param delay Time to delay in milliseconds\n */\nfunction setProgressBarDelay(delay) {\n console.warn(\n \"Please replace `Turbo.setProgressBarDelay(delay)` with `Turbo.config.drive.progressBarDelay = delay`. The top-level function is deprecated and will be removed in a future version of Turbo.`\"\n );\n config.drive.progressBarDelay = delay;\n}\n\nfunction setConfirmMethod(confirmMethod) {\n console.warn(\n \"Please replace `Turbo.setConfirmMethod(confirmMethod)` with `Turbo.config.forms.confirm = confirmMethod`. The top-level function is deprecated and will be removed in a future version of Turbo.`\"\n );\n config.forms.confirm = confirmMethod;\n}\n\nfunction setFormMode(mode) {\n console.warn(\n \"Please replace `Turbo.setFormMode(mode)` with `Turbo.config.forms.mode = mode`. The top-level function is deprecated and will be removed in a future version of Turbo.`\"\n );\n config.forms.mode = mode;\n}\n\nvar Turbo = /*#__PURE__*/Object.freeze({\n __proto__: null,\n navigator: navigator$1,\n session: session,\n cache: cache,\n PageRenderer: PageRenderer,\n PageSnapshot: PageSnapshot,\n FrameRenderer: FrameRenderer,\n fetch: fetchWithTurboHeaders,\n config: config,\n start: start,\n registerAdapter: registerAdapter,\n visit: visit,\n connectStreamSource: connectStreamSource,\n disconnectStreamSource: disconnectStreamSource,\n renderStreamMessage: renderStreamMessage,\n clearCache: clearCache,\n setProgressBarDelay: setProgressBarDelay,\n setConfirmMethod: setConfirmMethod,\n setFormMode: setFormMode\n});\n\nclass TurboFrameMissingError extends Error {}\n\nclass FrameController {\n fetchResponseLoaded = (_fetchResponse) => Promise.resolve()\n #currentFetchRequest = null\n #resolveVisitPromise = () => {}\n #connected = false\n #hasBeenLoaded = false\n #ignoredAttributes = new Set()\n action = null\n\n constructor(element) {\n this.element = element;\n this.view = new FrameView(this, this.element);\n this.appearanceObserver = new AppearanceObserver(this, this.element);\n this.formLinkClickObserver = new FormLinkClickObserver(this, this.element);\n this.linkInterceptor = new LinkInterceptor(this, this.element);\n this.restorationIdentifier = uuid();\n this.formSubmitObserver = new FormSubmitObserver(this, this.element);\n }\n\n // Frame delegate\n\n connect() {\n if (!this.#connected) {\n this.#connected = true;\n if (this.loadingStyle == FrameLoadingStyle.lazy) {\n this.appearanceObserver.start();\n } else {\n this.#loadSourceURL();\n }\n this.formLinkClickObserver.start();\n this.linkInterceptor.start();\n this.formSubmitObserver.start();\n }\n }\n\n disconnect() {\n if (this.#connected) {\n this.#connected = false;\n this.appearanceObserver.stop();\n this.formLinkClickObserver.stop();\n this.linkInterceptor.stop();\n this.formSubmitObserver.stop();\n }\n }\n\n disabledChanged() {\n if (this.loadingStyle == FrameLoadingStyle.eager) {\n this.#loadSourceURL();\n }\n }\n\n sourceURLChanged() {\n if (this.#isIgnoringChangesTo(\"src\")) return\n\n if (this.element.isConnected) {\n this.complete = false;\n }\n\n if (this.loadingStyle == FrameLoadingStyle.eager || this.#hasBeenLoaded) {\n this.#loadSourceURL();\n }\n }\n\n sourceURLReloaded() {\n if (this.element.shouldReloadWithMorph) {\n this.element.addEventListener(\"turbo:before-frame-render\", ({ detail }) => {\n detail.render = MorphingFrameRenderer.renderElement;\n }, { once: true });\n }\n\n const { src } = this.element;\n this.element.removeAttribute(\"complete\");\n this.element.src = null;\n this.element.src = src;\n return this.element.loaded\n }\n\n loadingStyleChanged() {\n if (this.loadingStyle == FrameLoadingStyle.lazy) {\n this.appearanceObserver.start();\n } else {\n this.appearanceObserver.stop();\n this.#loadSourceURL();\n }\n }\n\n async #loadSourceURL() {\n if (this.enabled && this.isActive && !this.complete && this.sourceURL) {\n this.element.loaded = this.#visit(expandURL(this.sourceURL));\n this.appearanceObserver.stop();\n await this.element.loaded;\n this.#hasBeenLoaded = true;\n }\n }\n\n async loadResponse(fetchResponse) {\n if (fetchResponse.redirected || (fetchResponse.succeeded && fetchResponse.isHTML)) {\n this.sourceURL = fetchResponse.response.url;\n }\n\n try {\n const html = await fetchResponse.responseHTML;\n if (html) {\n const document = parseHTMLDocument(html);\n const pageSnapshot = PageSnapshot.fromDocument(document);\n\n if (pageSnapshot.isVisitable) {\n await this.#loadFrameResponse(fetchResponse, document);\n } else {\n await this.#handleUnvisitableFrameResponse(fetchResponse);\n }\n }\n } finally {\n this.fetchResponseLoaded = () => Promise.resolve();\n }\n }\n\n // Appearance observer delegate\n\n elementAppearedInViewport(element) {\n this.proposeVisitIfNavigatedWithAction(element, getVisitAction(element));\n this.#loadSourceURL();\n }\n\n // Form link click observer delegate\n\n willSubmitFormLinkToLocation(link) {\n return this.#shouldInterceptNavigation(link)\n }\n\n submittedFormLinkToLocation(link, _location, form) {\n const frame = this.#findFrameElement(link);\n if (frame) form.setAttribute(\"data-turbo-frame\", frame.id);\n }\n\n // Link interceptor delegate\n\n shouldInterceptLinkClick(element, _location, _event) {\n return this.#shouldInterceptNavigation(element)\n }\n\n linkClickIntercepted(element, location) {\n this.#navigateFrame(element, location);\n }\n\n // Form submit observer delegate\n\n willSubmitForm(element, submitter) {\n return element.closest(\"turbo-frame\") == this.element && this.#shouldInterceptNavigation(element, submitter)\n }\n\n formSubmitted(element, submitter) {\n if (this.formSubmission) {\n this.formSubmission.stop();\n }\n\n this.formSubmission = new FormSubmission(this, element, submitter);\n const { fetchRequest } = this.formSubmission;\n this.prepareRequest(fetchRequest);\n this.formSubmission.start();\n }\n\n // Fetch request delegate\n\n prepareRequest(request) {\n request.headers[\"Turbo-Frame\"] = this.id;\n\n if (this.currentNavigationElement?.hasAttribute(\"data-turbo-stream\")) {\n request.acceptResponseType(StreamMessage.contentType);\n }\n }\n\n requestStarted(_request) {\n markAsBusy(this.element);\n }\n\n requestPreventedHandlingResponse(_request, _response) {\n this.#resolveVisitPromise();\n }\n\n async requestSucceededWithResponse(request, response) {\n await this.loadResponse(response);\n this.#resolveVisitPromise();\n }\n\n async requestFailedWithResponse(request, response) {\n await this.loadResponse(response);\n this.#resolveVisitPromise();\n }\n\n requestErrored(request, error) {\n console.error(error);\n this.#resolveVisitPromise();\n }\n\n requestFinished(_request) {\n clearBusyState(this.element);\n }\n\n // Form submission delegate\n\n formSubmissionStarted({ formElement }) {\n markAsBusy(formElement, this.#findFrameElement(formElement));\n }\n\n formSubmissionSucceededWithResponse(formSubmission, response) {\n const frame = this.#findFrameElement(formSubmission.formElement, formSubmission.submitter);\n\n frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(formSubmission.submitter, formSubmission.formElement, frame));\n frame.delegate.loadResponse(response);\n\n if (!formSubmission.isSafe) {\n session.clearCache();\n }\n }\n\n formSubmissionFailedWithResponse(formSubmission, fetchResponse) {\n this.element.delegate.loadResponse(fetchResponse);\n session.clearCache();\n }\n\n formSubmissionErrored(formSubmission, error) {\n console.error(error);\n }\n\n formSubmissionFinished({ formElement }) {\n clearBusyState(formElement, this.#findFrameElement(formElement));\n }\n\n // View delegate\n\n allowsImmediateRender({ element: newFrame }, options) {\n const event = dispatch(\"turbo:before-frame-render\", {\n target: this.element,\n detail: { newFrame, ...options },\n cancelable: true\n });\n\n const {\n defaultPrevented,\n detail: { render }\n } = event;\n\n if (this.view.renderer && render) {\n this.view.renderer.renderElement = render;\n }\n\n return !defaultPrevented\n }\n\n viewRenderedSnapshot(_snapshot, _isPreview, _renderMethod) {}\n\n preloadOnLoadLinksForView(element) {\n session.preloadOnLoadLinksForView(element);\n }\n\n viewInvalidated() {}\n\n // Frame renderer delegate\n\n willRenderFrame(currentElement, _newElement) {\n this.previousFrameElement = currentElement.cloneNode(true);\n }\n\n visitCachedSnapshot = ({ element }) => {\n const frame = element.querySelector(\"#\" + this.element.id);\n\n if (frame && this.previousFrameElement) {\n frame.replaceChildren(...this.previousFrameElement.children);\n }\n\n delete this.previousFrameElement;\n }\n\n // Private\n\n async #loadFrameResponse(fetchResponse, document) {\n const newFrameElement = await this.extractForeignFrameElement(document.body);\n\n if (newFrameElement) {\n const snapshot = new Snapshot(newFrameElement);\n const renderer = new FrameRenderer(this, this.view.snapshot, snapshot, FrameRenderer.renderElement, false, false);\n\n if (this.view.renderPromise) await this.view.renderPromise;\n this.changeHistory();\n\n await this.view.render(renderer);\n this.complete = true;\n session.frameRendered(fetchResponse, this.element);\n session.frameLoaded(this.element);\n await this.fetchResponseLoaded(fetchResponse);\n } else if (this.#willHandleFrameMissingFromResponse(fetchResponse)) {\n this.#handleFrameMissingFromResponse(fetchResponse);\n }\n }\n\n async #visit(url) {\n const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element);\n\n this.#currentFetchRequest?.cancel();\n this.#currentFetchRequest = request;\n\n return new Promise((resolve) => {\n this.#resolveVisitPromise = () => {\n this.#resolveVisitPromise = () => {};\n this.#currentFetchRequest = null;\n resolve();\n };\n request.perform();\n })\n }\n\n #navigateFrame(element, url, submitter) {\n const frame = this.#findFrameElement(element, submitter);\n\n frame.delegate.proposeVisitIfNavigatedWithAction(frame, getVisitAction(submitter, element, frame));\n\n this.#withCurrentNavigationElement(element, () => {\n frame.src = url;\n });\n }\n\n proposeVisitIfNavigatedWithAction(frame, action = null) {\n this.action = action;\n\n if (this.action) {\n const pageSnapshot = PageSnapshot.fromElement(frame).clone();\n const { visitCachedSnapshot } = frame.delegate;\n\n frame.delegate.fetchResponseLoaded = async (fetchResponse) => {\n if (frame.src) {\n const { statusCode, redirected } = fetchResponse;\n const responseHTML = await fetchResponse.responseHTML;\n const response = { statusCode, redirected, responseHTML };\n const options = {\n response,\n visitCachedSnapshot,\n willRender: false,\n updateHistory: false,\n restorationIdentifier: this.restorationIdentifier,\n snapshot: pageSnapshot\n };\n\n if (this.action) options.action = this.action;\n\n session.visit(frame.src, options);\n }\n };\n }\n }\n\n changeHistory() {\n if (this.action) {\n const method = getHistoryMethodForAction(this.action);\n session.history.update(method, expandURL(this.element.src || \"\"), this.restorationIdentifier);\n }\n }\n\n async #handleUnvisitableFrameResponse(fetchResponse) {\n console.warn(\n `The response (${fetchResponse.statusCode}) from is performing a full page visit due to turbo-visit-control.`\n );\n\n await this.#visitResponse(fetchResponse.response);\n }\n\n #willHandleFrameMissingFromResponse(fetchResponse) {\n this.element.setAttribute(\"complete\", \"\");\n\n const response = fetchResponse.response;\n const visit = async (url, options) => {\n if (url instanceof Response) {\n this.#visitResponse(url);\n } else {\n session.visit(url, options);\n }\n };\n\n const event = dispatch(\"turbo:frame-missing\", {\n target: this.element,\n detail: { response, visit },\n cancelable: true\n });\n\n return !event.defaultPrevented\n }\n\n #handleFrameMissingFromResponse(fetchResponse) {\n this.view.missing();\n this.#throwFrameMissingError(fetchResponse);\n }\n\n #throwFrameMissingError(fetchResponse) {\n const message = `The response (${fetchResponse.statusCode}) did not contain the expected and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`;\n throw new TurboFrameMissingError(message)\n }\n\n async #visitResponse(response) {\n const wrapped = new FetchResponse(response);\n const responseHTML = await wrapped.responseHTML;\n const { location, redirected, statusCode } = wrapped;\n\n return session.visit(location, { response: { redirected, statusCode, responseHTML } })\n }\n\n #findFrameElement(element, submitter) {\n const id = getAttribute(\"data-turbo-frame\", submitter, element) || this.element.getAttribute(\"target\");\n return getFrameElementById(id) ?? this.element\n }\n\n async extractForeignFrameElement(container) {\n let element;\n const id = CSS.escape(this.id);\n\n try {\n element = activateElement(container.querySelector(`turbo-frame#${id}`), this.sourceURL);\n if (element) {\n return element\n }\n\n element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.sourceURL);\n if (element) {\n await element.loaded;\n return await this.extractForeignFrameElement(element)\n }\n } catch (error) {\n console.error(error);\n return new FrameElement()\n }\n\n return null\n }\n\n #formActionIsVisitable(form, submitter) {\n const action = getAction$1(form, submitter);\n\n return locationIsVisitable(expandURL(action), this.rootLocation)\n }\n\n #shouldInterceptNavigation(element, submitter) {\n const id = getAttribute(\"data-turbo-frame\", submitter, element) || this.element.getAttribute(\"target\");\n\n if (element instanceof HTMLFormElement && !this.#formActionIsVisitable(element, submitter)) {\n return false\n }\n\n if (!this.enabled || id == \"_top\") {\n return false\n }\n\n if (id) {\n const frameElement = getFrameElementById(id);\n if (frameElement) {\n return !frameElement.disabled\n }\n }\n\n if (!session.elementIsNavigatable(element)) {\n return false\n }\n\n if (submitter && !session.elementIsNavigatable(submitter)) {\n return false\n }\n\n return true\n }\n\n // Computed properties\n\n get id() {\n return this.element.id\n }\n\n get enabled() {\n return !this.element.disabled\n }\n\n get sourceURL() {\n if (this.element.src) {\n return this.element.src\n }\n }\n\n set sourceURL(sourceURL) {\n this.#ignoringChangesToAttribute(\"src\", () => {\n this.element.src = sourceURL ?? null;\n });\n }\n\n get loadingStyle() {\n return this.element.loading\n }\n\n get isLoading() {\n return this.formSubmission !== undefined || this.#resolveVisitPromise() !== undefined\n }\n\n get complete() {\n return this.element.hasAttribute(\"complete\")\n }\n\n set complete(value) {\n if (value) {\n this.element.setAttribute(\"complete\", \"\");\n } else {\n this.element.removeAttribute(\"complete\");\n }\n }\n\n get isActive() {\n return this.element.isActive && this.#connected\n }\n\n get rootLocation() {\n const meta = this.element.ownerDocument.querySelector(`meta[name=\"turbo-root\"]`);\n const root = meta?.content ?? \"/\";\n return expandURL(root)\n }\n\n #isIgnoringChangesTo(attributeName) {\n return this.#ignoredAttributes.has(attributeName)\n }\n\n #ignoringChangesToAttribute(attributeName, callback) {\n this.#ignoredAttributes.add(attributeName);\n callback();\n this.#ignoredAttributes.delete(attributeName);\n }\n\n #withCurrentNavigationElement(element, callback) {\n this.currentNavigationElement = element;\n callback();\n delete this.currentNavigationElement;\n }\n}\n\nfunction getFrameElementById(id) {\n if (id != null) {\n const element = document.getElementById(id);\n if (element instanceof FrameElement) {\n return element\n }\n }\n}\n\nfunction activateElement(element, currentURL) {\n if (element) {\n const src = element.getAttribute(\"src\");\n if (src != null && currentURL != null && urlsAreEqual(src, currentURL)) {\n throw new Error(`Matching element has a source URL which references itself`)\n }\n if (element.ownerDocument !== document) {\n element = document.importNode(element, true);\n }\n\n if (element instanceof FrameElement) {\n element.connectedCallback();\n element.disconnectedCallback();\n return element\n }\n }\n}\n\nconst StreamActions = {\n after() {\n this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e.nextSibling));\n },\n\n append() {\n this.removeDuplicateTargetChildren();\n this.targetElements.forEach((e) => e.append(this.templateContent));\n },\n\n before() {\n this.targetElements.forEach((e) => e.parentElement?.insertBefore(this.templateContent, e));\n },\n\n prepend() {\n this.removeDuplicateTargetChildren();\n this.targetElements.forEach((e) => e.prepend(this.templateContent));\n },\n\n remove() {\n this.targetElements.forEach((e) => e.remove());\n },\n\n replace() {\n const method = this.getAttribute(\"method\");\n\n this.targetElements.forEach((targetElement) => {\n if (method === \"morph\") {\n morphElements(targetElement, this.templateContent);\n } else {\n targetElement.replaceWith(this.templateContent);\n }\n });\n },\n\n update() {\n const method = this.getAttribute(\"method\");\n\n this.targetElements.forEach((targetElement) => {\n if (method === \"morph\") {\n morphChildren(targetElement, this.templateContent);\n } else {\n targetElement.innerHTML = \"\";\n targetElement.append(this.templateContent);\n }\n });\n },\n\n refresh() {\n session.refresh(this.baseURI, this.requestId);\n }\n};\n\n//