pyDiffTools 0.1.30__tar.gz → 0.1.32__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pydifftools-0.1.30 → pydifftools-0.1.32}/MANIFEST.in +2 -0
- {pydifftools-0.1.30/pyDiffTools.egg-info → pydifftools-0.1.32}/PKG-INFO +10 -1
- {pydifftools-0.1.30 → pydifftools-0.1.32}/README.rst +9 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32/pyDiffTools.egg-info}/PKG-INFO +10 -1
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pyDiffTools.egg-info/SOURCES.txt +3 -0
- pydifftools-0.1.32/pydifftools/flowchart/comparison.py +330 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/flowchart/graph.py +19 -19
- pydifftools-0.1.32/pydifftools/flowchart/svg-pan-zoom.min.js +30 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/flowchart/watch_graph.py +228 -231
- pydifftools-0.1.32/pydifftools/flowchart/wgrph_view.js +212 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/git_gd_history.py +34 -16
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pyproject.toml +5 -1
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_git_gd_history.py +2 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/LICENSE.md +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/_quarto.yml +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/__version__.txt +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/1a724af72b16f5a9e607e12b1c721645/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/1b28fc9daac9081847e5161b2c546f8a/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/231f64eee282fa225d1104935cf80a24/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/26e56f6b0ff54851a45145157f2f0dc4/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/311fabd7029ffd050d056e2f316eb50f/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/57da2021e5b156ac3adf01398201c723/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/62b24ea7da75011d92b0f8924faa208d/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/7f1b20d69d889514ab5d1cc92e3cb14f/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/86f74c8c54a87ff892d9b15dd714e8f0/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/88893b4234eac2945d9d6cb2e277f186/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/9a40046ada6f582ee34af00fbdbfb417/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/a1bf4d270d0641ff41faf1d7cce3439a/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/a3789f7d9585a781f2a1c60ce95ff10d/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/be46ecba858d39ad5f0c46902ddf1c02/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/d0cbc57a12f2ccce710a5afd04cc05e7/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/d3e12d320b14228f701231ae32ddd7dd/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/eb434f61555438d020a6970a5dbf9ee8/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/f6b0e73aa7fa029134665d4dde57e096/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/f719a6e4ff09873cb0ffb06ec9d232f9/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/executed/feeee244a7ce3d60e1a227eb604df823/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/.jupyter_cache/global.db +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/example.qmd +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/example.tex +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/index.qmd +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/.jupyter_cache/__version__.txt +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/.jupyter_cache/executed/ca90e4df5f4f0583df6554156a68dc7f/base.ipynb +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/.jupyter_cache/global.db +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/end_vs_he_sketch.jpg +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/independent.qmd +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/index.qmd +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/tasks.qmd +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/test_include.qmd +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/subproject1/tryforerror.qmd +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/example_notebook/project1/test_include.qmd +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pyDiffTools.egg-info/dependency_links.txt +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pyDiffTools.egg-info/entry_points.txt +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pyDiffTools.egg-info/requires.txt +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pyDiffTools.egg-info/top_level.txt +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/__init__.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/browser_lifecycle.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/check_numbers.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/command_line.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/command_registry.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/comment_functions.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/comment_tags.lua +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/comment_tags_margin.lua +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/comment_tags_no_comments.lua +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/comment_toggle.js +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/comments.css +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/continuous.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/copy_files.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/diff-doc.js +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/doc_contents.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/flowchart/__init__.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/flowchart/dot_to_yaml.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/forward_search.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/git_gd.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/git_gd_image.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/git_gd_qt.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/html_comments.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/html_uncomments.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/log_example.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/match_spaces.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/notebook/__init__.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/notebook/display.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/notebook/fast_build.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/notebook/tex_to_qmd.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/onewordify.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/onewordify_undo.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/outline.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/rearrange_tex.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/searchacro.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/separate_comments.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/split_conflict.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/unseparate_comments.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/update_check.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/wrap_sentences.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/pydifftools/xml2xlsx.vbs +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/setup.cfg +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_browser_lifecycle.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_check_single_use.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_command_line_help.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_continuous_shutdown.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_forward_search.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_git_gd_image.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_git_gd_qt.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_rrng.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_tex_to_qmd.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_update_check.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_wrap_check.py +0 -0
- {pydifftools-0.1.30 → pydifftools-0.1.32}/tests/test_wrapping.py +0 -0
|
@@ -8,4 +8,6 @@ include pydifftools/comment_tags.lua
|
|
|
8
8
|
include pydifftools/comment_tags_margin.lua
|
|
9
9
|
include pydifftools/comment_tags_no_comments.lua
|
|
10
10
|
include pydifftools/comment_toggle.js
|
|
11
|
+
include pydifftools/flowchart/svg-pan-zoom.min.js
|
|
12
|
+
include pydifftools/flowchart/wgrph_view.js
|
|
11
13
|
recursive-include example_notebook *
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyDiffTools
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.32
|
|
4
4
|
Summary: Diff tools
|
|
5
5
|
Author: J M Franck
|
|
6
6
|
License: Copyright (c) 2015, jmfranck
|
|
@@ -101,6 +101,15 @@ included are (listed in order of fun/utility):
|
|
|
101
101
|
refreshed as you edit the file. This wraps the former
|
|
102
102
|
``flowchart/watch_graph.py`` script so all of its functionality is now
|
|
103
103
|
available through the main ``pydifft`` entry point.
|
|
104
|
+
Add ``--diff-base HEAD`` (or a branch, tag, commit, or quoted reflog
|
|
105
|
+
reference) to compare against that Git snapshot throughout the preview
|
|
106
|
+
session. Additions are green, deletions are red and struck through, and
|
|
107
|
+
unchanged content is muted. Renames share one box; date, status, and
|
|
108
|
+
dependency changes are annotated. Navigation, filters, and reloads retain
|
|
109
|
+
the baseline, whose reference and commit appear below the graph.
|
|
110
|
+
Comparison uses the same repository-relative YAML path; a file absent
|
|
111
|
+
from the revision is treated as an empty plan. Historical file renames
|
|
112
|
+
are not followed, and comparison markup is never written to YAML.
|
|
104
113
|
- `pydifft tex2qmd file.tex` converts LaTeX sources to Quarto markdown.
|
|
105
114
|
The converter preserves custom observation blocks and errata tags while
|
|
106
115
|
translating verbatim/python environments into fenced code blocks so the
|
|
@@ -46,6 +46,15 @@ included are (listed in order of fun/utility):
|
|
|
46
46
|
refreshed as you edit the file. This wraps the former
|
|
47
47
|
``flowchart/watch_graph.py`` script so all of its functionality is now
|
|
48
48
|
available through the main ``pydifft`` entry point.
|
|
49
|
+
Add ``--diff-base HEAD`` (or a branch, tag, commit, or quoted reflog
|
|
50
|
+
reference) to compare against that Git snapshot throughout the preview
|
|
51
|
+
session. Additions are green, deletions are red and struck through, and
|
|
52
|
+
unchanged content is muted. Renames share one box; date, status, and
|
|
53
|
+
dependency changes are annotated. Navigation, filters, and reloads retain
|
|
54
|
+
the baseline, whose reference and commit appear below the graph.
|
|
55
|
+
Comparison uses the same repository-relative YAML path; a file absent
|
|
56
|
+
from the revision is treated as an empty plan. Historical file renames
|
|
57
|
+
are not followed, and comparison markup is never written to YAML.
|
|
49
58
|
- `pydifft tex2qmd file.tex` converts LaTeX sources to Quarto markdown.
|
|
50
59
|
The converter preserves custom observation blocks and errata tags while
|
|
51
60
|
translating verbatim/python environments into fenced code blocks so the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyDiffTools
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.32
|
|
4
4
|
Summary: Diff tools
|
|
5
5
|
Author: J M Franck
|
|
6
6
|
License: Copyright (c) 2015, jmfranck
|
|
@@ -101,6 +101,15 @@ included are (listed in order of fun/utility):
|
|
|
101
101
|
refreshed as you edit the file. This wraps the former
|
|
102
102
|
``flowchart/watch_graph.py`` script so all of its functionality is now
|
|
103
103
|
available through the main ``pydifft`` entry point.
|
|
104
|
+
Add ``--diff-base HEAD`` (or a branch, tag, commit, or quoted reflog
|
|
105
|
+
reference) to compare against that Git snapshot throughout the preview
|
|
106
|
+
session. Additions are green, deletions are red and struck through, and
|
|
107
|
+
unchanged content is muted. Renames share one box; date, status, and
|
|
108
|
+
dependency changes are annotated. Navigation, filters, and reloads retain
|
|
109
|
+
the baseline, whose reference and commit appear below the graph.
|
|
110
|
+
Comparison uses the same repository-relative YAML path; a file absent
|
|
111
|
+
from the revision is treated as an empty plan. Historical file renames
|
|
112
|
+
are not followed, and comparison markup is never written to YAML.
|
|
104
113
|
- `pydifft tex2qmd file.tex` converts LaTeX sources to Quarto markdown.
|
|
105
114
|
The converter preserves custom observation blocks and errata tags while
|
|
106
115
|
translating verbatim/python environments into fenced code blocks so the
|
|
@@ -80,9 +80,12 @@ pydifftools/update_check.py
|
|
|
80
80
|
pydifftools/wrap_sentences.py
|
|
81
81
|
pydifftools/xml2xlsx.vbs
|
|
82
82
|
pydifftools/flowchart/__init__.py
|
|
83
|
+
pydifftools/flowchart/comparison.py
|
|
83
84
|
pydifftools/flowchart/dot_to_yaml.py
|
|
84
85
|
pydifftools/flowchart/graph.py
|
|
86
|
+
pydifftools/flowchart/svg-pan-zoom.min.js
|
|
85
87
|
pydifftools/flowchart/watch_graph.py
|
|
88
|
+
pydifftools/flowchart/wgrph_view.js
|
|
86
89
|
pydifftools/notebook/__init__.py
|
|
87
90
|
pydifftools/notebook/display.py
|
|
88
91
|
pydifftools/notebook/fast_build.py
|
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
"""An immutable Git snapshot and a disposable plan comparison render model."""
|
|
2
|
+
|
|
3
|
+
from copy import deepcopy
|
|
4
|
+
from difflib import SequenceMatcher
|
|
5
|
+
import html
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import re
|
|
8
|
+
import subprocess
|
|
9
|
+
import tempfile
|
|
10
|
+
|
|
11
|
+
from .graph import (
|
|
12
|
+
_filter_nodes_for_dot,
|
|
13
|
+
_format_label,
|
|
14
|
+
_normalize_graph_dates,
|
|
15
|
+
_node_text_with_due,
|
|
16
|
+
load_graph_yaml,
|
|
17
|
+
trace_ancestors,
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PlanComparison:
|
|
22
|
+
def __init__(self, path, revision):
|
|
23
|
+
path = Path(path).resolve()
|
|
24
|
+
try:
|
|
25
|
+
root = Path(
|
|
26
|
+
subprocess.check_output(
|
|
27
|
+
[
|
|
28
|
+
"git",
|
|
29
|
+
"-C",
|
|
30
|
+
str(path.parent),
|
|
31
|
+
"rev-parse",
|
|
32
|
+
"--show-toplevel",
|
|
33
|
+
],
|
|
34
|
+
text=True,
|
|
35
|
+
stderr=subprocess.PIPE,
|
|
36
|
+
).strip()
|
|
37
|
+
).resolve()
|
|
38
|
+
relative = path.relative_to(root).as_posix()
|
|
39
|
+
self.commit = subprocess.check_output(
|
|
40
|
+
[
|
|
41
|
+
"git",
|
|
42
|
+
"-C",
|
|
43
|
+
str(root),
|
|
44
|
+
"rev-parse",
|
|
45
|
+
"--verify",
|
|
46
|
+
"--end-of-options",
|
|
47
|
+
f"{revision}^{{commit}}",
|
|
48
|
+
],
|
|
49
|
+
text=True,
|
|
50
|
+
stderr=subprocess.PIPE,
|
|
51
|
+
).strip()
|
|
52
|
+
listing = subprocess.check_output(
|
|
53
|
+
[
|
|
54
|
+
"git",
|
|
55
|
+
"-C",
|
|
56
|
+
str(root),
|
|
57
|
+
"ls-tree",
|
|
58
|
+
self.commit,
|
|
59
|
+
"--",
|
|
60
|
+
relative,
|
|
61
|
+
],
|
|
62
|
+
stderr=subprocess.PIPE,
|
|
63
|
+
)
|
|
64
|
+
self.reference = revision
|
|
65
|
+
self.data = {"nodes": {}}
|
|
66
|
+
if listing:
|
|
67
|
+
content = subprocess.check_output(
|
|
68
|
+
[
|
|
69
|
+
"git",
|
|
70
|
+
"-C",
|
|
71
|
+
str(root),
|
|
72
|
+
"show",
|
|
73
|
+
f"{self.commit}:{relative}",
|
|
74
|
+
],
|
|
75
|
+
stderr=subprocess.PIPE,
|
|
76
|
+
)
|
|
77
|
+
with tempfile.NamedTemporaryFile(suffix=".yaml") as snapshot:
|
|
78
|
+
snapshot.write(content)
|
|
79
|
+
snapshot.flush()
|
|
80
|
+
self.data = load_graph_yaml(snapshot.name)
|
|
81
|
+
_normalize_graph_dates(self.data)
|
|
82
|
+
except Exception as exc:
|
|
83
|
+
detail = getattr(exc, "stderr", None) or str(exc)
|
|
84
|
+
if isinstance(detail, bytes):
|
|
85
|
+
detail = detail.decode(errors="replace")
|
|
86
|
+
raise ValueError(
|
|
87
|
+
f"Cannot compare {path} against Git revision {revision!r}: "
|
|
88
|
+
f"{detail}"
|
|
89
|
+
) from exc
|
|
90
|
+
|
|
91
|
+
def correspondence(self, current):
|
|
92
|
+
old = self.data["nodes"]
|
|
93
|
+
new = current["nodes"]
|
|
94
|
+
matches = {name: name for name in old.keys() & new.keys()}
|
|
95
|
+
old_text = {
|
|
96
|
+
k: " ".join(str(v.get("text", "")).split()) for k, v in old.items()
|
|
97
|
+
}
|
|
98
|
+
new_text = {
|
|
99
|
+
k: " ".join(str(v.get("text", "")).split()) for k, v in new.items()
|
|
100
|
+
}
|
|
101
|
+
# {{{ Match unique exact content before conservative edited renames
|
|
102
|
+
remaining_old = set(old) - matches.keys()
|
|
103
|
+
remaining_new = set(new) - set(matches.values())
|
|
104
|
+
for name in sorted(remaining_old):
|
|
105
|
+
candidates = [
|
|
106
|
+
k for k in remaining_new if new_text[k] == old_text[name]
|
|
107
|
+
]
|
|
108
|
+
peers = [k for k in remaining_old if old_text[k] == old_text[name]]
|
|
109
|
+
if len(candidates) == len(peers) == 1:
|
|
110
|
+
matches[name] = candidates[0]
|
|
111
|
+
remaining_old -= matches.keys()
|
|
112
|
+
remaining_new -= set(matches.values())
|
|
113
|
+
scores = {}
|
|
114
|
+
for a in remaining_old:
|
|
115
|
+
for b in remaining_new:
|
|
116
|
+
scores[a, b] = SequenceMatcher(
|
|
117
|
+
None, old_text[a], new_text[b], autojunk=False
|
|
118
|
+
).ratio()
|
|
119
|
+
anchors = dict(matches)
|
|
120
|
+
for (a, b), score in sorted(scores.items()):
|
|
121
|
+
if score < 0.9:
|
|
122
|
+
continue
|
|
123
|
+
alternatives = [
|
|
124
|
+
v
|
|
125
|
+
for (x, y), v in scores.items()
|
|
126
|
+
if (x == a or y == b) and (x, y) != (a, b)
|
|
127
|
+
]
|
|
128
|
+
if alternatives and score - max(alternatives) < 0.1 - 1e-9:
|
|
129
|
+
continue
|
|
130
|
+
agrees = True
|
|
131
|
+
evidence = False
|
|
132
|
+
for relation in ("parents", "children"):
|
|
133
|
+
left = {
|
|
134
|
+
anchors[k]
|
|
135
|
+
for k in old[a].get(relation, [])
|
|
136
|
+
if k in anchors
|
|
137
|
+
}
|
|
138
|
+
right = set(new[b].get(relation, [])) & set(anchors.values())
|
|
139
|
+
evidence |= bool(left or right)
|
|
140
|
+
agrees &= left == right
|
|
141
|
+
if agrees and evidence:
|
|
142
|
+
matches[a] = b
|
|
143
|
+
# }}}
|
|
144
|
+
return matches
|
|
145
|
+
|
|
146
|
+
def label(self, before, after, width):
|
|
147
|
+
"""Diff visible words while retaining the current label's markup."""
|
|
148
|
+
deleting = bool(before) and not after
|
|
149
|
+
if deleting:
|
|
150
|
+
after = before
|
|
151
|
+
old = _format_label(before or "", width)[1:-1]
|
|
152
|
+
new = _format_label(after or "", width)[1:-1]
|
|
153
|
+
old_words = re.findall(r"[^\s<>]+", re.sub(r"<[^>]*>", " ", old))
|
|
154
|
+
pieces = re.findall(r"<[^>]*>|\s+|[^\s<]+", new)
|
|
155
|
+
positions = [
|
|
156
|
+
i
|
|
157
|
+
for i, part in enumerate(pieces)
|
|
158
|
+
if not part.startswith("<") and not part.isspace()
|
|
159
|
+
]
|
|
160
|
+
words = [pieces[i] for i in positions]
|
|
161
|
+
for op, a, b, c, d in SequenceMatcher(
|
|
162
|
+
None, old_words, words, autojunk=False
|
|
163
|
+
).get_opcodes():
|
|
164
|
+
for index in range(c, d):
|
|
165
|
+
color = "#16803c" if op in ("insert", "replace") else "#888888"
|
|
166
|
+
pos = positions[index]
|
|
167
|
+
if deleting:
|
|
168
|
+
pieces[pos] = "<s>" + pieces[pos] + "</s>"
|
|
169
|
+
color = "#c62828"
|
|
170
|
+
pieces[pos] = f'<font color="{color}">{pieces[pos]}</font>'
|
|
171
|
+
if op in ("delete", "replace"):
|
|
172
|
+
removed = " ".join(old_words[a:b])
|
|
173
|
+
removed = f'<font color="#c62828"><s>{removed}</s></font> '
|
|
174
|
+
if c < len(positions):
|
|
175
|
+
pieces[positions[c]] = removed + pieces[positions[c]]
|
|
176
|
+
else:
|
|
177
|
+
pieces.append(removed)
|
|
178
|
+
return "".join(pieces)
|
|
179
|
+
|
|
180
|
+
def render(self, current, width, target=None, completed=False):
|
|
181
|
+
matches = self.correspondence(current)
|
|
182
|
+
old = self.data["nodes"]
|
|
183
|
+
new = current["nodes"]
|
|
184
|
+
reverse = {b: a for a, b in matches.items()}
|
|
185
|
+
if target is not None:
|
|
186
|
+
candidates = set(old) | set(new)
|
|
187
|
+
if target not in candidates:
|
|
188
|
+
candidates = [
|
|
189
|
+
k for k in candidates if k.lower() == target.lower()
|
|
190
|
+
]
|
|
191
|
+
if len(candidates) != 1:
|
|
192
|
+
raise ValueError(
|
|
193
|
+
f"Task {target!r} not found or ambiguous."
|
|
194
|
+
)
|
|
195
|
+
target = candidates[0]
|
|
196
|
+
visible = []
|
|
197
|
+
views = []
|
|
198
|
+
for graph, focus in (
|
|
199
|
+
(current, matches.get(target, target)),
|
|
200
|
+
(self.data, reverse.get(target, target)),
|
|
201
|
+
):
|
|
202
|
+
if target is not None:
|
|
203
|
+
names = [focus] + trace_ancestors(graph, focus)
|
|
204
|
+
view = _filter_nodes_for_dot(graph, names)
|
|
205
|
+
elif completed:
|
|
206
|
+
view = _filter_nodes_for_dot(graph, graph["nodes"], True)
|
|
207
|
+
else:
|
|
208
|
+
view = graph
|
|
209
|
+
visible.append(set(view["nodes"]))
|
|
210
|
+
views.append(view)
|
|
211
|
+
names = visible[0] | {matches.get(k, k) for k in visible[1]}
|
|
212
|
+
model = {"nodes": {}, "styles": deepcopy(current.get("styles", {}))}
|
|
213
|
+
model["styles"] = {
|
|
214
|
+
**deepcopy(self.data.get("styles", {})),
|
|
215
|
+
**model["styles"],
|
|
216
|
+
}
|
|
217
|
+
self.node_states = {}
|
|
218
|
+
self.edge_states = {}
|
|
219
|
+
for name in sorted(names):
|
|
220
|
+
previous = reverse.get(name, name if name in old else None)
|
|
221
|
+
node = deepcopy(new[name] if name in new else old[name])
|
|
222
|
+
before = old.get(previous, {})
|
|
223
|
+
after = new.get(name, {})
|
|
224
|
+
state = "same"
|
|
225
|
+
if name not in new:
|
|
226
|
+
state = "removed"
|
|
227
|
+
elif previous is None:
|
|
228
|
+
state = "added"
|
|
229
|
+
body = self.label(
|
|
230
|
+
before.get("text", ""), after.get("text", ""), width
|
|
231
|
+
)
|
|
232
|
+
if state in ("added", "removed"):
|
|
233
|
+
node["_comparison_status"] = (
|
|
234
|
+
"added" if state == "added" else "deleted"
|
|
235
|
+
)
|
|
236
|
+
if previous is not None and previous != name:
|
|
237
|
+
body = (
|
|
238
|
+
f'<font color="#c62828"><s>{html.escape(previous)}</s>'
|
|
239
|
+
"</font><br/>" + body
|
|
240
|
+
)
|
|
241
|
+
state = "changed"
|
|
242
|
+
# {{{ Explicit metadata changes, including date-only view edges
|
|
243
|
+
for key in ("due", "orig_due", "style", "parents", "children"):
|
|
244
|
+
left = before.get(key, "")
|
|
245
|
+
right = after.get(key, "")
|
|
246
|
+
if key in ("parents", "children"):
|
|
247
|
+
equal = {matches.get(k, k) for k in left} == set(right)
|
|
248
|
+
else:
|
|
249
|
+
equal = left == right
|
|
250
|
+
if equal:
|
|
251
|
+
if key == "due" and right:
|
|
252
|
+
dated = dict(after)
|
|
253
|
+
dated.pop("text", None)
|
|
254
|
+
body += (
|
|
255
|
+
"<br/>"
|
|
256
|
+
+ _format_label(_node_text_with_due(dated), width)[
|
|
257
|
+
1:-1
|
|
258
|
+
]
|
|
259
|
+
)
|
|
260
|
+
continue
|
|
261
|
+
body += "<br/>" + self.label(
|
|
262
|
+
html.escape(f"{key}: {left or '(none)'}"),
|
|
263
|
+
html.escape(f"{key}: {right or '(none)'}"),
|
|
264
|
+
width,
|
|
265
|
+
)
|
|
266
|
+
# }}}
|
|
267
|
+
if state == "same" and body.count("#16803c") + body.count(
|
|
268
|
+
"#c62828"
|
|
269
|
+
):
|
|
270
|
+
state = "changed"
|
|
271
|
+
node["_comparison_label"] = body
|
|
272
|
+
node["children"] = []
|
|
273
|
+
node["parents"] = []
|
|
274
|
+
model["nodes"][name] = node
|
|
275
|
+
self.node_states[name] = state
|
|
276
|
+
edges = []
|
|
277
|
+
for graph, mapping in ((self.data, matches), (current, {})):
|
|
278
|
+
edges.append(
|
|
279
|
+
{
|
|
280
|
+
(mapping.get(a, a), mapping.get(b, b))
|
|
281
|
+
for a, node in graph["nodes"].items()
|
|
282
|
+
for b in node.get("children", [])
|
|
283
|
+
}
|
|
284
|
+
)
|
|
285
|
+
visible_edges = {
|
|
286
|
+
(mapping.get(a, a), mapping.get(b, b))
|
|
287
|
+
for graph, mapping in ((views[1], matches), (views[0], {}))
|
|
288
|
+
for a, node in graph["nodes"].items()
|
|
289
|
+
for b in node.get("children", [])
|
|
290
|
+
}
|
|
291
|
+
for a, b in sorted(visible_edges):
|
|
292
|
+
if a not in names or b not in names:
|
|
293
|
+
continue
|
|
294
|
+
model["nodes"][a]["children"].append(b)
|
|
295
|
+
model["nodes"][b]["parents"].append(a)
|
|
296
|
+
self.edge_states[f"{a}->{b}"] = (
|
|
297
|
+
"same"
|
|
298
|
+
if (a, b) in edges[0] & edges[1]
|
|
299
|
+
else "added" if (a, b) in edges[1] else "removed"
|
|
300
|
+
)
|
|
301
|
+
return model
|
|
302
|
+
|
|
303
|
+
def style_svg(self, root, namespace):
|
|
304
|
+
for group in root.iter(f"{namespace}g"):
|
|
305
|
+
kind = group.get("class")
|
|
306
|
+
if kind not in ("node", "edge"):
|
|
307
|
+
continue
|
|
308
|
+
title = group.find(f"{namespace}title")
|
|
309
|
+
states = self.node_states if kind == "node" else self.edge_states
|
|
310
|
+
state = states.get(title.text if title is not None else "", "same")
|
|
311
|
+
color = {"added": "#16803c", "removed": "#c62828"}.get(
|
|
312
|
+
state, "#888888"
|
|
313
|
+
)
|
|
314
|
+
for item in group.iter():
|
|
315
|
+
tag = item.tag.split("}")[-1]
|
|
316
|
+
if tag in ("polygon", "path", "ellipse", "rect"):
|
|
317
|
+
item.set("stroke", color)
|
|
318
|
+
if kind == "node" and item.get("fill") != "none":
|
|
319
|
+
item.set("fill", "#f5f5f5")
|
|
320
|
+
if kind == "edge" and tag == "polygon":
|
|
321
|
+
item.set("fill", color)
|
|
322
|
+
if state == "removed":
|
|
323
|
+
item.set("stroke-dasharray", "5,3")
|
|
324
|
+
elif tag == "text":
|
|
325
|
+
if state in ("added", "removed"):
|
|
326
|
+
item.set("fill", color)
|
|
327
|
+
elif item.get("fill") not in ("#16803c", "#c62828"):
|
|
328
|
+
item.set("fill", "#888888")
|
|
329
|
+
if state == "removed":
|
|
330
|
+
item.set("text-decoration", "line-through")
|
|
@@ -42,15 +42,11 @@ def _str_presenter(dumper, data: str):
|
|
|
42
42
|
return dumper.represent_scalar("tag:yaml.org,2002:str", data)
|
|
43
43
|
|
|
44
44
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
dumper.add_representer(str, _str_presenter)
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
_register_block_str_presenter()
|
|
45
|
+
# {{{ Register multiline strings with each YAML dumper
|
|
46
|
+
for dumper in (yaml.Dumper, yaml.SafeDumper, IndentDumper):
|
|
47
|
+
if getattr(dumper, "yaml_representers", None) is not None:
|
|
48
|
+
dumper.add_representer(str, _str_presenter)
|
|
49
|
+
# }}}
|
|
54
50
|
|
|
55
51
|
|
|
56
52
|
class EmptyGraphYamlError(ValueError):
|
|
@@ -428,12 +424,6 @@ def endpoint_projects(data):
|
|
|
428
424
|
return projects
|
|
429
425
|
|
|
430
426
|
|
|
431
|
-
def _node_label(text, wrap_width=55):
|
|
432
|
-
if text is None:
|
|
433
|
-
return ""
|
|
434
|
-
return _format_label(text, wrap_width)
|
|
435
|
-
|
|
436
|
-
|
|
437
427
|
def _normalize_graph_dates(data):
|
|
438
428
|
# Normalize due dates to mm/dd/yy so the YAML is consistent across years.
|
|
439
429
|
if "nodes" not in data:
|
|
@@ -482,11 +472,16 @@ def _append_node(
|
|
|
482
472
|
if parent_due is None or not str(parent_due).strip():
|
|
483
473
|
depends_on_undated_parent = True
|
|
484
474
|
break
|
|
485
|
-
label =
|
|
486
|
-
_node_text_with_due(node, depends_on_undated_parent), wrap_width
|
|
475
|
+
label = _format_label(
|
|
476
|
+
_node_text_with_due(node, depends_on_undated_parent) or "", wrap_width
|
|
487
477
|
)
|
|
478
|
+
if "_comparison_label" in node:
|
|
479
|
+
label = "<" + node["_comparison_label"] + ">"
|
|
480
|
+
status = node.get("_comparison_status")
|
|
481
|
+
status_prefix = f"<b>{status}:</b> " if status else ""
|
|
488
482
|
task_link_line = (
|
|
489
|
-
f'<font point-size="9">
|
|
483
|
+
f'<font point-size="9">{status_prefix}'
|
|
484
|
+
f"__WGRPH_TASK_LINK__:{node_name}</font>"
|
|
490
485
|
)
|
|
491
486
|
if label:
|
|
492
487
|
label = "<" + task_link_line + '<br align="left"/>' + label[1:]
|
|
@@ -734,6 +729,7 @@ def write_dot_from_yaml(
|
|
|
734
729
|
filter_task=None,
|
|
735
730
|
filter_completed=False,
|
|
736
731
|
resolve_due_date_conflict=None,
|
|
732
|
+
comparison=None,
|
|
737
733
|
):
|
|
738
734
|
data = load_graph_yaml(str(yaml_path), old_data=old_data)
|
|
739
735
|
_normalize_graph_dates(data)
|
|
@@ -847,7 +843,11 @@ def write_dot_from_yaml(
|
|
|
847
843
|
adjust_due_after_parents(name)
|
|
848
844
|
# }}}
|
|
849
845
|
data_for_dot = data
|
|
850
|
-
if
|
|
846
|
+
if comparison is not None:
|
|
847
|
+
data_for_dot = comparison.render(
|
|
848
|
+
data, wrap_width, filter_task, filter_completed
|
|
849
|
+
)
|
|
850
|
+
elif filter_task is not None:
|
|
851
851
|
# Limit the rendered graph to incomplete ancestors of the target task.
|
|
852
852
|
if "nodes" not in data or filter_task not in data["nodes"]:
|
|
853
853
|
matches = [
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Vendored unmodified from svg-pan-zoom 3.6.2 (BSD 2-Clause license):
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2009-2010 Andrea Leofreddi <a.leofreddi@vleo.net>
|
|
5
|
+
* All rights reserved.
|
|
6
|
+
*
|
|
7
|
+
* Redistribution and use in source and binary forms, with or without modification,
|
|
8
|
+
* are permitted provided that the following conditions are met:
|
|
9
|
+
*
|
|
10
|
+
* * Redistributions of source code must retain the above copyright notice, this
|
|
11
|
+
* list of conditions and the following disclaimer.
|
|
12
|
+
*
|
|
13
|
+
* * Redistributions in binary form must reproduce the above copyright notice, this
|
|
14
|
+
* list of conditions and the following disclaimer in the documentation and/or
|
|
15
|
+
* other materials provided with the distribution.
|
|
16
|
+
*
|
|
17
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
18
|
+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
19
|
+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
20
|
+
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
|
|
21
|
+
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
22
|
+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
23
|
+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
|
24
|
+
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
25
|
+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
26
|
+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
27
|
+
*/
|
|
28
|
+
// svg-pan-zoom v3.6.2
|
|
29
|
+
// https://github.com/bumbu/svg-pan-zoom
|
|
30
|
+
!function s(r,a,l){function u(e,t){if(!a[e]){if(!r[e]){var o="function"==typeof require&&require;if(!t&&o)return o(e,!0);if(h)return h(e,!0);var n=new Error("Cannot find module '"+e+"'");throw n.code="MODULE_NOT_FOUND",n}var i=a[e]={exports:{}};r[e][0].call(i.exports,function(t){return u(r[e][1][t]||t)},i,i.exports,s,r,a,l)}return a[e].exports}for(var h="function"==typeof require&&require,t=0;t<l.length;t++)u(l[t]);return u}({1:[function(t,e,o){var s=t("./svg-utilities");e.exports={enable:function(t){var e=t.svg.querySelector("defs");if(e||(e=document.createElementNS(s.svgNS,"defs"),t.svg.appendChild(e)),!e.querySelector("style#svg-pan-zoom-controls-styles")){var o=document.createElementNS(s.svgNS,"style");o.setAttribute("id","svg-pan-zoom-controls-styles"),o.setAttribute("type","text/css"),o.textContent=".svg-pan-zoom-control { cursor: pointer; fill: black; fill-opacity: 0.333; } .svg-pan-zoom-control:hover { fill-opacity: 0.8; } .svg-pan-zoom-control-background { fill: white; fill-opacity: 0.5; } .svg-pan-zoom-control-background { fill-opacity: 0.8; }",e.appendChild(o)}var n=document.createElementNS(s.svgNS,"g");n.setAttribute("id","svg-pan-zoom-controls"),n.setAttribute("transform","translate("+(t.width-70)+" "+(t.height-76)+") scale(0.75)"),n.setAttribute("class","svg-pan-zoom-control"),n.appendChild(this._createZoomIn(t)),n.appendChild(this._createZoomReset(t)),n.appendChild(this._createZoomOut(t)),t.svg.appendChild(n),t.controlIcons=n},_createZoomIn:function(t){var e=document.createElementNS(s.svgNS,"g");e.setAttribute("id","svg-pan-zoom-zoom-in"),e.setAttribute("transform","translate(30.5 5) scale(0.015)"),e.setAttribute("class","svg-pan-zoom-control"),e.addEventListener("click",function(){t.getPublicInstance().zoomIn()},!1),e.addEventListener("touchstart",function(){t.getPublicInstance().zoomIn()},!1);var o=document.createElementNS(s.svgNS,"rect");o.setAttribute("x","0"),o.setAttribute("y","0"),o.setAttribute("width","1500"),o.setAttribute("height","1400"),o.setAttribute("class","svg-pan-zoom-control-background"),e.appendChild(o);var n=document.createElementNS(s.svgNS,"path");return n.setAttribute("d","M1280 576v128q0 26 -19 45t-45 19h-320v320q0 26 -19 45t-45 19h-128q-26 0 -45 -19t-19 -45v-320h-320q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h320v-320q0 -26 19 -45t45 -19h128q26 0 45 19t19 45v320h320q26 0 45 19t19 45zM1536 1120v-960 q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5t84.5 -203.5z"),n.setAttribute("class","svg-pan-zoom-control-element"),e.appendChild(n),e},_createZoomReset:function(t){var e=document.createElementNS(s.svgNS,"g");e.setAttribute("id","svg-pan-zoom-reset-pan-zoom"),e.setAttribute("transform","translate(5 35) scale(0.4)"),e.setAttribute("class","svg-pan-zoom-control"),e.addEventListener("click",function(){t.getPublicInstance().reset()},!1),e.addEventListener("touchstart",function(){t.getPublicInstance().reset()},!1);var o=document.createElementNS(s.svgNS,"rect");o.setAttribute("x","2"),o.setAttribute("y","2"),o.setAttribute("width","182"),o.setAttribute("height","58"),o.setAttribute("class","svg-pan-zoom-control-background"),e.appendChild(o);var n=document.createElementNS(s.svgNS,"path");n.setAttribute("d","M33.051,20.632c-0.742-0.406-1.854-0.609-3.338-0.609h-7.969v9.281h7.769c1.543,0,2.701-0.188,3.473-0.562c1.365-0.656,2.048-1.953,2.048-3.891C35.032,22.757,34.372,21.351,33.051,20.632z"),n.setAttribute("class","svg-pan-zoom-control-element"),e.appendChild(n);var i=document.createElementNS(s.svgNS,"path");return i.setAttribute("d","M170.231,0.5H15.847C7.102,0.5,0.5,5.708,0.5,11.84v38.861C0.5,56.833,7.102,61.5,15.847,61.5h154.384c8.745,0,15.269-4.667,15.269-10.798V11.84C185.5,5.708,178.976,0.5,170.231,0.5z M42.837,48.569h-7.969c-0.219-0.766-0.375-1.383-0.469-1.852c-0.188-0.969-0.289-1.961-0.305-2.977l-0.047-3.211c-0.03-2.203-0.41-3.672-1.142-4.406c-0.732-0.734-2.103-1.102-4.113-1.102h-7.05v13.547h-7.055V14.022h16.524c2.361,0.047,4.178,0.344,5.45,0.891c1.272,0.547,2.351,1.352,3.234,2.414c0.731,0.875,1.31,1.844,1.737,2.906s0.64,2.273,0.64,3.633c0,1.641-0.414,3.254-1.242,4.84s-2.195,2.707-4.102,3.363c1.594,0.641,2.723,1.551,3.387,2.73s0.996,2.98,0.996,5.402v2.32c0,1.578,0.063,2.648,0.19,3.211c0.19,0.891,0.635,1.547,1.333,1.969V48.569z M75.579,48.569h-26.18V14.022h25.336v6.117H56.454v7.336h16.781v6H56.454v8.883h19.125V48.569z M104.497,46.331c-2.44,2.086-5.887,3.129-10.34,3.129c-4.548,0-8.125-1.027-10.731-3.082s-3.909-4.879-3.909-8.473h6.891c0.224,1.578,0.662,2.758,1.316,3.539c1.196,1.422,3.246,2.133,6.15,2.133c1.739,0,3.151-0.188,4.236-0.562c2.058-0.719,3.087-2.055,3.087-4.008c0-1.141-0.504-2.023-1.512-2.648c-1.008-0.609-2.607-1.148-4.796-1.617l-3.74-0.82c-3.676-0.812-6.201-1.695-7.576-2.648c-2.328-1.594-3.492-4.086-3.492-7.477c0-3.094,1.139-5.664,3.417-7.711s5.623-3.07,10.036-3.07c3.685,0,6.829,0.965,9.431,2.895c2.602,1.93,3.966,4.73,4.093,8.402h-6.938c-0.128-2.078-1.057-3.555-2.787-4.43c-1.154-0.578-2.587-0.867-4.301-0.867c-1.907,0-3.428,0.375-4.565,1.125c-1.138,0.75-1.706,1.797-1.706,3.141c0,1.234,0.561,2.156,1.682,2.766c0.721,0.406,2.25,0.883,4.589,1.43l6.063,1.43c2.657,0.625,4.648,1.461,5.975,2.508c2.059,1.625,3.089,3.977,3.089,7.055C108.157,41.624,106.937,44.245,104.497,46.331z M139.61,48.569h-26.18V14.022h25.336v6.117h-18.281v7.336h16.781v6h-16.781v8.883h19.125V48.569z M170.337,20.14h-10.336v28.43h-7.266V20.14h-10.383v-6.117h27.984V20.14z"),i.setAttribute("class","svg-pan-zoom-control-element"),e.appendChild(i),e},_createZoomOut:function(t){var e=document.createElementNS(s.svgNS,"g");e.setAttribute("id","svg-pan-zoom-zoom-out"),e.setAttribute("transform","translate(30.5 70) scale(0.015)"),e.setAttribute("class","svg-pan-zoom-control"),e.addEventListener("click",function(){t.getPublicInstance().zoomOut()},!1),e.addEventListener("touchstart",function(){t.getPublicInstance().zoomOut()},!1);var o=document.createElementNS(s.svgNS,"rect");o.setAttribute("x","0"),o.setAttribute("y","0"),o.setAttribute("width","1500"),o.setAttribute("height","1400"),o.setAttribute("class","svg-pan-zoom-control-background"),e.appendChild(o);var n=document.createElementNS(s.svgNS,"path");return n.setAttribute("d","M1280 576v128q0 26 -19 45t-45 19h-896q-26 0 -45 -19t-19 -45v-128q0 -26 19 -45t45 -19h896q26 0 45 19t19 45zM1536 1120v-960q0 -119 -84.5 -203.5t-203.5 -84.5h-960q-119 0 -203.5 84.5t-84.5 203.5v960q0 119 84.5 203.5t203.5 84.5h960q119 0 203.5 -84.5 t84.5 -203.5z"),n.setAttribute("class","svg-pan-zoom-control-element"),e.appendChild(n),e},disable:function(t){t.controlIcons&&(t.controlIcons.parentNode.removeChild(t.controlIcons),t.controlIcons=null)}}},{"./svg-utilities":5}],2:[function(t,e,o){function n(t,e){this.init(t,e)}var i=t("./svg-utilities"),r=t("./utilities");n.prototype.init=function(t,e){this.viewport=t,this.options=e,this.originalState={zoom:1,x:0,y:0},this.activeState={zoom:1,x:0,y:0},this.updateCTMCached=r.proxy(this.updateCTM,this),this.requestAnimationFrame=r.createRequestAnimationFrame(this.options.refreshRate),this.viewBox={x:0,y:0,width:0,height:0},this.cacheViewBox();var o=this.processCTM();this.setCTM(o),this.updateCTM()},n.prototype.cacheViewBox=function(){var t=this.options.svg.getAttribute("viewBox");if(t){var e=t.split(/[\s\,]/).filter(function(t){return t}).map(parseFloat);this.viewBox.x=e[0],this.viewBox.y=e[1],this.viewBox.width=e[2],this.viewBox.height=e[3];var o=Math.min(this.options.width/this.viewBox.width,this.options.height/this.viewBox.height);this.activeState.zoom=o,this.activeState.x=(this.options.width-this.viewBox.width*o)/2,this.activeState.y=(this.options.height-this.viewBox.height*o)/2,this.updateCTMOnNextFrame(),this.options.svg.removeAttribute("viewBox")}else this.simpleViewBoxCache()},n.prototype.simpleViewBoxCache=function(){var t=this.viewport.getBBox();this.viewBox.x=t.x,this.viewBox.y=t.y,this.viewBox.width=t.width,this.viewBox.height=t.height},n.prototype.getViewBox=function(){return r.extend({},this.viewBox)},n.prototype.processCTM=function(){var t,e=this.getCTM();(this.options.fit||this.options.contain)&&(t=this.options.fit?Math.min(this.options.width/this.viewBox.width,this.options.height/this.viewBox.height):Math.max(this.options.width/this.viewBox.width,this.options.height/this.viewBox.height),e.a=t,e.d=t,e.e=-this.viewBox.x*t,e.f=-this.viewBox.y*t);if(this.options.center){var o=.5*(this.options.width-(this.viewBox.width+2*this.viewBox.x)*e.a),n=.5*(this.options.height-(this.viewBox.height+2*this.viewBox.y)*e.a);e.e=o,e.f=n}return this.originalState.zoom=e.a,this.originalState.x=e.e,this.originalState.y=e.f,e},n.prototype.getOriginalState=function(){return r.extend({},this.originalState)},n.prototype.getState=function(){return r.extend({},this.activeState)},n.prototype.getZoom=function(){return this.activeState.zoom},n.prototype.getRelativeZoom=function(){return this.activeState.zoom/this.originalState.zoom},n.prototype.computeRelativeZoom=function(t){return t/this.originalState.zoom},n.prototype.getPan=function(){return{x:this.activeState.x,y:this.activeState.y}},n.prototype.getCTM=function(){var t=this.options.svg.createSVGMatrix();return t.a=this.activeState.zoom,t.b=0,t.c=0,t.d=this.activeState.zoom,t.e=this.activeState.x,t.f=this.activeState.y,t},n.prototype.setCTM=function(t){var e=this.isZoomDifferent(t),o=this.isPanDifferent(t);if(e||o){if(e&&(!1===this.options.beforeZoom(this.getRelativeZoom(),this.computeRelativeZoom(t.a))?(t.a=t.d=this.activeState.zoom,e=!1):(this.updateCache(t),this.options.onZoom(this.getRelativeZoom()))),o){var n=this.options.beforePan(this.getPan(),{x:t.e,y:t.f}),i=!1,s=!1;!1===n?(t.e=this.getPan().x,t.f=this.getPan().y,i=s=!0):r.isObject(n)&&(!1===n.x?(t.e=this.getPan().x,i=!0):r.isNumber(n.x)&&(t.e=n.x),!1===n.y?(t.f=this.getPan().y,s=!0):r.isNumber(n.y)&&(t.f=n.y)),i&&s||!this.isPanDifferent(t)?o=!1:(this.updateCache(t),this.options.onPan(this.getPan()))}(e||o)&&this.updateCTMOnNextFrame()}},n.prototype.isZoomDifferent=function(t){return this.activeState.zoom!==t.a},n.prototype.isPanDifferent=function(t){return this.activeState.x!==t.e||this.activeState.y!==t.f},n.prototype.updateCache=function(t){this.activeState.zoom=t.a,this.activeState.x=t.e,this.activeState.y=t.f},n.prototype.pendingUpdate=!1,n.prototype.updateCTMOnNextFrame=function(){this.pendingUpdate||(this.pendingUpdate=!0,this.requestAnimationFrame.call(window,this.updateCTMCached))},n.prototype.updateCTM=function(){var t=this.getCTM();i.setCTM(this.viewport,t,this.defs),this.pendingUpdate=!1,this.options.onUpdatedCTM&&this.options.onUpdatedCTM(t)},e.exports=function(t,e){return new n(t,e)}},{"./svg-utilities":5,"./utilities":7}],3:[function(t,e,o){var n,i=t("./svg-pan-zoom.js");n=window,document,"function"==typeof define&&define.amd?define("svg-pan-zoom",function(){return i}):void 0!==e&&e.exports&&(e.exports=i,n.svgPanZoom=i)},{"./svg-pan-zoom.js":4}],4:[function(t,e,o){function i(t,e){this.init(t,e)}var n=t("./uniwheel"),s=t("./control-icons"),r=t("./utilities"),a=t("./svg-utilities"),l=t("./shadow-viewport"),u={viewportSelector:".svg-pan-zoom_viewport",panEnabled:!0,controlIconsEnabled:!1,zoomEnabled:!0,dblClickZoomEnabled:!0,mouseWheelZoomEnabled:!0,preventMouseEventsDefault:!0,zoomScaleSensitivity:.1,minZoom:.5,maxZoom:10,fit:!0,contain:!1,center:!0,refreshRate:"auto",beforeZoom:null,onZoom:null,beforePan:null,onPan:null,customEventsHandler:null,eventsListenerElement:null,onUpdatedCTM:null},h={passive:!0};i.prototype.init=function(t,e){var o=this;this.svg=t,this.defs=t.querySelector("defs"),a.setupSvgAttributes(this.svg),this.options=r.extend(r.extend({},u),e),this.state="none";var n=a.getBoundingClientRectNormalized(t);this.width=n.width,this.height=n.height,this.viewport=l(a.getOrCreateViewport(this.svg,this.options.viewportSelector),{svg:this.svg,width:this.width,height:this.height,fit:this.options.fit,contain:this.options.contain,center:this.options.center,refreshRate:this.options.refreshRate,beforeZoom:function(t,e){if(o.viewport&&o.options.beforeZoom)return o.options.beforeZoom(t,e)},onZoom:function(t){if(o.viewport&&o.options.onZoom)return o.options.onZoom(t)},beforePan:function(t,e){if(o.viewport&&o.options.beforePan)return o.options.beforePan(t,e)},onPan:function(t){if(o.viewport&&o.options.onPan)return o.options.onPan(t)},onUpdatedCTM:function(t){if(o.viewport&&o.options.onUpdatedCTM)return o.options.onUpdatedCTM(t)}});var i=this.getPublicInstance();i.setBeforeZoom(this.options.beforeZoom),i.setOnZoom(this.options.onZoom),i.setBeforePan(this.options.beforePan),i.setOnPan(this.options.onPan),i.setOnUpdatedCTM(this.options.onUpdatedCTM),this.options.controlIconsEnabled&&s.enable(this),this.lastMouseWheelEventTime=Date.now(),this.setupHandlers()},i.prototype.setupHandlers=function(){var o=this,n=null;if(this.eventListeners={mousedown:function(t){var e=o.handleMouseDown(t,n);return n=t,e},touchstart:function(t){var e=o.handleMouseDown(t,n);return n=t,e},mouseup:function(t){return o.handleMouseUp(t)},touchend:function(t){return o.handleMouseUp(t)},mousemove:function(t){return o.handleMouseMove(t)},touchmove:function(t){return o.handleMouseMove(t)},mouseleave:function(t){return o.handleMouseUp(t)},touchleave:function(t){return o.handleMouseUp(t)},touchcancel:function(t){return o.handleMouseUp(t)}},null!=this.options.customEventsHandler){this.options.customEventsHandler.init({svgElement:this.svg,eventsListenerElement:this.options.eventsListenerElement,instance:this.getPublicInstance()});var t=this.options.customEventsHandler.haltEventListeners;if(t&&t.length)for(var e=t.length-1;0<=e;e--)this.eventListeners.hasOwnProperty(t[e])&&delete this.eventListeners[t[e]]}for(var i in this.eventListeners)(this.options.eventsListenerElement||this.svg).addEventListener(i,this.eventListeners[i],!this.options.preventMouseEventsDefault&&h);this.options.mouseWheelZoomEnabled&&(this.options.mouseWheelZoomEnabled=!1,this.enableMouseWheelZoom())},i.prototype.enableMouseWheelZoom=function(){if(!this.options.mouseWheelZoomEnabled){var e=this;this.wheelListener=function(t){return e.handleMouseWheel(t)};var t=!this.options.preventMouseEventsDefault;n.on(this.options.eventsListenerElement||this.svg,this.wheelListener,t),this.options.mouseWheelZoomEnabled=!0}},i.prototype.disableMouseWheelZoom=function(){if(this.options.mouseWheelZoomEnabled){var t=!this.options.preventMouseEventsDefault;n.off(this.options.eventsListenerElement||this.svg,this.wheelListener,t),this.options.mouseWheelZoomEnabled=!1}},i.prototype.handleMouseWheel=function(t){if(this.options.zoomEnabled&&"none"===this.state){this.options.preventMouseEventsDefault&&(t.preventDefault?t.preventDefault():t.returnValue=!1);var e=t.deltaY||1,o=Date.now()-this.lastMouseWheelEventTime,n=3+Math.max(0,30-o);this.lastMouseWheelEventTime=Date.now(),"deltaMode"in t&&0===t.deltaMode&&t.wheelDelta&&(e=0===t.deltaY?0:Math.abs(t.wheelDelta)/t.deltaY),e=-.3<e&&e<.3?e:(0<e?1:-1)*Math.log(Math.abs(e)+10)/n;var i=this.svg.getScreenCTM().inverse(),s=a.getEventPoint(t,this.svg).matrixTransform(i),r=Math.pow(1+this.options.zoomScaleSensitivity,-1*e);this.zoomAtPoint(r,s)}},i.prototype.zoomAtPoint=function(t,e,o){var n=this.viewport.getOriginalState();o?(t=Math.max(this.options.minZoom*n.zoom,Math.min(this.options.maxZoom*n.zoom,t)),t/=this.getZoom()):this.getZoom()*t<this.options.minZoom*n.zoom?t=this.options.minZoom*n.zoom/this.getZoom():this.getZoom()*t>this.options.maxZoom*n.zoom&&(t=this.options.maxZoom*n.zoom/this.getZoom());var i=this.viewport.getCTM(),s=e.matrixTransform(i.inverse()),r=this.svg.createSVGMatrix().translate(s.x,s.y).scale(t).translate(-s.x,-s.y),a=i.multiply(r);a.a!==i.a&&this.viewport.setCTM(a)},i.prototype.zoom=function(t,e){this.zoomAtPoint(t,a.getSvgCenterPoint(this.svg,this.width,this.height),e)},i.prototype.publicZoom=function(t,e){e&&(t=this.computeFromRelativeZoom(t)),this.zoom(t,e)},i.prototype.publicZoomAtPoint=function(t,e,o){if(o&&(t=this.computeFromRelativeZoom(t)),"SVGPoint"!==r.getType(e)){if(!("x"in e&&"y"in e))throw new Error("Given point is invalid");e=a.createSVGPoint(this.svg,e.x,e.y)}this.zoomAtPoint(t,e,o)},i.prototype.getZoom=function(){return this.viewport.getZoom()},i.prototype.getRelativeZoom=function(){return this.viewport.getRelativeZoom()},i.prototype.computeFromRelativeZoom=function(t){return t*this.viewport.getOriginalState().zoom},i.prototype.resetZoom=function(){var t=this.viewport.getOriginalState();this.zoom(t.zoom,!0)},i.prototype.resetPan=function(){this.pan(this.viewport.getOriginalState())},i.prototype.reset=function(){this.resetZoom(),this.resetPan()},i.prototype.handleDblClick=function(t){var e;if((this.options.preventMouseEventsDefault&&(t.preventDefault?t.preventDefault():t.returnValue=!1),this.options.controlIconsEnabled)&&-1<(t.target.getAttribute("class")||"").indexOf("svg-pan-zoom-control"))return!1;e=t.shiftKey?1/(2*(1+this.options.zoomScaleSensitivity)):2*(1+this.options.zoomScaleSensitivity);var o=a.getEventPoint(t,this.svg).matrixTransform(this.svg.getScreenCTM().inverse());this.zoomAtPoint(e,o)},i.prototype.handleMouseDown=function(t,e){this.options.preventMouseEventsDefault&&(t.preventDefault?t.preventDefault():t.returnValue=!1),r.mouseAndTouchNormalize(t,this.svg),this.options.dblClickZoomEnabled&&r.isDblClick(t,e)?this.handleDblClick(t):(this.state="pan",this.firstEventCTM=this.viewport.getCTM(),this.stateOrigin=a.getEventPoint(t,this.svg).matrixTransform(this.firstEventCTM.inverse()))},i.prototype.handleMouseMove=function(t){if(this.options.preventMouseEventsDefault&&(t.preventDefault?t.preventDefault():t.returnValue=!1),"pan"===this.state&&this.options.panEnabled){var e=a.getEventPoint(t,this.svg).matrixTransform(this.firstEventCTM.inverse()),o=this.firstEventCTM.translate(e.x-this.stateOrigin.x,e.y-this.stateOrigin.y);this.viewport.setCTM(o)}},i.prototype.handleMouseUp=function(t){this.options.preventMouseEventsDefault&&(t.preventDefault?t.preventDefault():t.returnValue=!1),"pan"===this.state&&(this.state="none")},i.prototype.fit=function(){var t=this.viewport.getViewBox(),e=Math.min(this.width/t.width,this.height/t.height);this.zoom(e,!0)},i.prototype.contain=function(){var t=this.viewport.getViewBox(),e=Math.max(this.width/t.width,this.height/t.height);this.zoom(e,!0)},i.prototype.center=function(){var t=this.viewport.getViewBox(),e=.5*(this.width-(t.width+2*t.x)*this.getZoom()),o=.5*(this.height-(t.height+2*t.y)*this.getZoom());this.getPublicInstance().pan({x:e,y:o})},i.prototype.updateBBox=function(){this.viewport.simpleViewBoxCache()},i.prototype.pan=function(t){var e=this.viewport.getCTM();e.e=t.x,e.f=t.y,this.viewport.setCTM(e)},i.prototype.panBy=function(t){var e=this.viewport.getCTM();e.e+=t.x,e.f+=t.y,this.viewport.setCTM(e)},i.prototype.getPan=function(){var t=this.viewport.getState();return{x:t.x,y:t.y}},i.prototype.resize=function(){var t=a.getBoundingClientRectNormalized(this.svg);this.width=t.width,this.height=t.height;var e=this.viewport;e.options.width=this.width,e.options.height=this.height,e.processCTM(),this.options.controlIconsEnabled&&(this.getPublicInstance().disableControlIcons(),this.getPublicInstance().enableControlIcons())},i.prototype.destroy=function(){var e=this;for(var t in this.beforeZoom=null,this.onZoom=null,this.beforePan=null,this.onPan=null,(this.onUpdatedCTM=null)!=this.options.customEventsHandler&&this.options.customEventsHandler.destroy({svgElement:this.svg,eventsListenerElement:this.options.eventsListenerElement,instance:this.getPublicInstance()}),this.eventListeners)(this.options.eventsListenerElement||this.svg).removeEventListener(t,this.eventListeners[t],!this.options.preventMouseEventsDefault&&h);this.disableMouseWheelZoom(),this.getPublicInstance().disableControlIcons(),this.reset(),c=c.filter(function(t){return t.svg!==e.svg}),delete this.options,delete this.viewport,delete this.publicInstance,delete this.pi,this.getPublicInstance=function(){return null}},i.prototype.getPublicInstance=function(){var o=this;return this.publicInstance||(this.publicInstance=this.pi={enablePan:function(){return o.options.panEnabled=!0,o.pi},disablePan:function(){return o.options.panEnabled=!1,o.pi},isPanEnabled:function(){return!!o.options.panEnabled},pan:function(t){return o.pan(t),o.pi},panBy:function(t){return o.panBy(t),o.pi},getPan:function(){return o.getPan()},setBeforePan:function(t){return o.options.beforePan=null===t?null:r.proxy(t,o.publicInstance),o.pi},setOnPan:function(t){return o.options.onPan=null===t?null:r.proxy(t,o.publicInstance),o.pi},enableZoom:function(){return o.options.zoomEnabled=!0,o.pi},disableZoom:function(){return o.options.zoomEnabled=!1,o.pi},isZoomEnabled:function(){return!!o.options.zoomEnabled},enableControlIcons:function(){return o.options.controlIconsEnabled||(o.options.controlIconsEnabled=!0,s.enable(o)),o.pi},disableControlIcons:function(){return o.options.controlIconsEnabled&&(o.options.controlIconsEnabled=!1,s.disable(o)),o.pi},isControlIconsEnabled:function(){return!!o.options.controlIconsEnabled},enableDblClickZoom:function(){return o.options.dblClickZoomEnabled=!0,o.pi},disableDblClickZoom:function(){return o.options.dblClickZoomEnabled=!1,o.pi},isDblClickZoomEnabled:function(){return!!o.options.dblClickZoomEnabled},enableMouseWheelZoom:function(){return o.enableMouseWheelZoom(),o.pi},disableMouseWheelZoom:function(){return o.disableMouseWheelZoom(),o.pi},isMouseWheelZoomEnabled:function(){return!!o.options.mouseWheelZoomEnabled},setZoomScaleSensitivity:function(t){return o.options.zoomScaleSensitivity=t,o.pi},setMinZoom:function(t){return o.options.minZoom=t,o.pi},setMaxZoom:function(t){return o.options.maxZoom=t,o.pi},setBeforeZoom:function(t){return o.options.beforeZoom=null===t?null:r.proxy(t,o.publicInstance),o.pi},setOnZoom:function(t){return o.options.onZoom=null===t?null:r.proxy(t,o.publicInstance),o.pi},zoom:function(t){return o.publicZoom(t,!0),o.pi},zoomBy:function(t){return o.publicZoom(t,!1),o.pi},zoomAtPoint:function(t,e){return o.publicZoomAtPoint(t,e,!0),o.pi},zoomAtPointBy:function(t,e){return o.publicZoomAtPoint(t,e,!1),o.pi},zoomIn:function(){return this.zoomBy(1+o.options.zoomScaleSensitivity),o.pi},zoomOut:function(){return this.zoomBy(1/(1+o.options.zoomScaleSensitivity)),o.pi},getZoom:function(){return o.getRelativeZoom()},setOnUpdatedCTM:function(t){return o.options.onUpdatedCTM=null===t?null:r.proxy(t,o.publicInstance),o.pi},resetZoom:function(){return o.resetZoom(),o.pi},resetPan:function(){return o.resetPan(),o.pi},reset:function(){return o.reset(),o.pi},fit:function(){return o.fit(),o.pi},contain:function(){return o.contain(),o.pi},center:function(){return o.center(),o.pi},updateBBox:function(){return o.updateBBox(),o.pi},resize:function(){return o.resize(),o.pi},getSizes:function(){return{width:o.width,height:o.height,realZoom:o.getZoom(),viewBox:o.viewport.getViewBox()}},destroy:function(){return o.destroy(),o.pi}}),this.publicInstance};var c=[];e.exports=function(t,e){var o=r.getSvg(t);if(null===o)return null;for(var n=c.length-1;0<=n;n--)if(c[n].svg===o)return c[n].instance.getPublicInstance();return c.push({svg:o,instance:new i(o,e)}),c[c.length-1].instance.getPublicInstance()}},{"./control-icons":1,"./shadow-viewport":2,"./svg-utilities":5,"./uniwheel":6,"./utilities":7}],5:[function(t,e,o){var l=t("./utilities"),s="unknown";document.documentMode&&(s="ie"),e.exports={svgNS:"http://www.w3.org/2000/svg",xmlNS:"http://www.w3.org/XML/1998/namespace",xmlnsNS:"http://www.w3.org/2000/xmlns/",xlinkNS:"http://www.w3.org/1999/xlink",evNS:"http://www.w3.org/2001/xml-events",getBoundingClientRectNormalized:function(t){if(t.clientWidth&&t.clientHeight)return{width:t.clientWidth,height:t.clientHeight};if(t.getBoundingClientRect())return t.getBoundingClientRect();throw new Error("Cannot get BoundingClientRect for SVG.")},getOrCreateViewport:function(t,e){var o=null;if(!(o=l.isElement(e)?e:t.querySelector(e))){var n=Array.prototype.slice.call(t.childNodes||t.children).filter(function(t){return"defs"!==t.nodeName&&"#text"!==t.nodeName});1===n.length&&"g"===n[0].nodeName&&null===n[0].getAttribute("transform")&&(o=n[0])}if(!o){var i="viewport-"+(new Date).toISOString().replace(/\D/g,"");(o=document.createElementNS(this.svgNS,"g")).setAttribute("id",i);var s=t.childNodes||t.children;if(s&&0<s.length)for(var r=s.length;0<r;r--)"defs"!==s[s.length-r].nodeName&&o.appendChild(s[s.length-r]);t.appendChild(o)}var a=[];return o.getAttribute("class")&&(a=o.getAttribute("class").split(" ")),~a.indexOf("svg-pan-zoom_viewport")||(a.push("svg-pan-zoom_viewport"),o.setAttribute("class",a.join(" "))),o},setupSvgAttributes:function(t){if(t.setAttribute("xmlns",this.svgNS),t.setAttributeNS(this.xmlnsNS,"xmlns:xlink",this.xlinkNS),t.setAttributeNS(this.xmlnsNS,"xmlns:ev",this.evNS),null!==t.parentNode){var e=t.getAttribute("style")||"";-1===e.toLowerCase().indexOf("overflow")&&t.setAttribute("style","overflow: hidden; "+e)}},internetExplorerRedisplayInterval:300,refreshDefsGlobal:l.throttle(function(){for(var t=document.querySelectorAll("defs"),e=t.length,o=0;o<e;o++){var n=t[o];n.parentNode.insertBefore(n,n)}},this?this.internetExplorerRedisplayInterval:null),setCTM:function(t,e,o){var n=this,i="matrix("+e.a+","+e.b+","+e.c+","+e.d+","+e.e+","+e.f+")";t.setAttributeNS(null,"transform",i),"transform"in t.style?t.style.transform=i:"-ms-transform"in t.style?t.style["-ms-transform"]=i:"-webkit-transform"in t.style&&(t.style["-webkit-transform"]=i),"ie"===s&&o&&(o.parentNode.insertBefore(o,o),window.setTimeout(function(){n.refreshDefsGlobal()},n.internetExplorerRedisplayInterval))},getEventPoint:function(t,e){var o=e.createSVGPoint();return l.mouseAndTouchNormalize(t,e),o.x=t.clientX,o.y=t.clientY,o},getSvgCenterPoint:function(t,e,o){return this.createSVGPoint(t,e/2,o/2)},createSVGPoint:function(t,e,o){var n=t.createSVGPoint();return n.x=e,n.y=o,n}}},{"./utilities":7}],6:[function(t,e,o){function s(t,o){function e(t){var e={originalEvent:t=t||window.event,target:t.target||t.srcElement,type:"wheel",deltaMode:"MozMousePixelScroll"==t.type?0:1,deltaX:0,delatZ:0,preventDefault:function(){t.preventDefault?t.preventDefault():t.returnValue=!1}};return"mousewheel"==l?(e.deltaY=-.025*t.wheelDelta,t.wheelDeltaX&&(e.deltaX=-.025*t.wheelDeltaX)):e.deltaY=t.detail,o(e)}return h.push({element:t,fn:e}),e}function n(t,e,o,n){var i;i="wheel"===l?o:s(t,o),t[r](u+e,i,n?c:p)}function i(t,e,o,n){var i;i="wheel"===l?o:function(t){for(var e=0;e<h.length;e++)if(h[e].element===t)return h[e].fn;return function(){}}(t),t[a](u+e,i,n?c:p),function(t){for(var e=0;e<h.length;e++)if(h[e].element===t)return h.splice(e,1)}(t)}var r,a,l,u,h,c,p;e.exports=(h=[],p={passive:!(c={passive:!(u="")})},window.addEventListener?(r="addEventListener",a="removeEventListener"):(r="attachEvent",a="detachEvent",u="on"),l="onwheel"in document.createElement("div")?"wheel":void 0!==document.onmousewheel?"mousewheel":"DOMMouseScroll",{on:function(t,e,o){n(t,l,e,o),"DOMMouseScroll"==l&&n(t,"MozMousePixelScroll",e,o)},off:function(t,e,o){i(t,l,e,o),"DOMMouseScroll"==l&&i(t,"MozMousePixelScroll",e,o)}})},{}],7:[function(t,e,o){function n(e){return function(t){window.setTimeout(t,e)}}e.exports={extend:function(t,e){for(var o in t=t||{},e)this.isObject(e[o])?t[o]=this.extend(t[o],e[o]):t[o]=e[o];return t},isElement:function(t){return t instanceof HTMLElement||t instanceof SVGElement||t instanceof SVGSVGElement||t&&"object"==typeof t&&null!==t&&1===t.nodeType&&"string"==typeof t.nodeName},isObject:function(t){return"[object Object]"===Object.prototype.toString.call(t)},isNumber:function(t){return!isNaN(parseFloat(t))&&isFinite(t)},getSvg:function(t){var e,o;if(this.isElement(t))e=t;else{if(!("string"==typeof t||t instanceof String))throw new Error("Provided selector is not an HTML object nor String");if(!(e=document.querySelector(t)))throw new Error("Provided selector did not find any elements. Selector: "+t)}if("svg"===e.tagName.toLowerCase())o=e;else if("object"===e.tagName.toLowerCase())o=e.contentDocument.documentElement;else{if("embed"!==e.tagName.toLowerCase())throw"img"===e.tagName.toLowerCase()?new Error('Cannot script an SVG in an "img" element. Please use an "object" element or an in-line SVG.'):new Error("Cannot get SVG.");o=e.getSVGDocument().documentElement}return o},proxy:function(t,e){return function(){return t.apply(e,arguments)}},getType:function(t){return Object.prototype.toString.apply(t).replace(/^\[object\s/,"").replace(/\]$/,"")},mouseAndTouchNormalize:function(t,e){if(void 0===t.clientX||null===t.clientX)if(t.clientX=0,void(t.clientY=0)!==t.touches&&t.touches.length){if(void 0!==t.touches[0].clientX)t.clientX=t.touches[0].clientX,t.clientY=t.touches[0].clientY;else if(void 0!==t.touches[0].pageX){var o=e.getBoundingClientRect();t.clientX=t.touches[0].pageX-o.left,t.clientY=t.touches[0].pageY-o.top}}else void 0!==t.originalEvent&&void 0!==t.originalEvent.clientX&&(t.clientX=t.originalEvent.clientX,t.clientY=t.originalEvent.clientY)},isDblClick:function(t,e){if(2===t.detail)return!0;if(null==e)return!1;var o=t.timeStamp-e.timeStamp,n=Math.sqrt(Math.pow(t.clientX-e.clientX,2)+Math.pow(t.clientY-e.clientY,2));return o<250&&n<10},now:Date.now||function(){return(new Date).getTime()},throttle:function(o,n,i){var s,r,a,l=this,u=null,h=0;i=i||{};function c(){h=!1===i.leading?0:l.now(),u=null,a=o.apply(s,r),u||(s=r=null)}return function(){var t=l.now();h||!1!==i.leading||(h=t);var e=n-(t-h);return s=this,r=arguments,e<=0||n<e?(clearTimeout(u),u=null,h=t,a=o.apply(s,r),u||(s=r=null)):u||!1===i.trailing||(u=setTimeout(c,e)),a}},createRequestAnimationFrame:function(t){var e=null;return"auto"!==t&&t<60&&1<t&&(e=Math.floor(1e3/t)),null===e?window.requestAnimationFrame||n(33):n(e)}}},{}]},{},[3]);
|