@open-pioneer/printing 0.1.0
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.
- package/CHANGELOG.md +24 -0
- package/LICENSE +202 -0
- package/Printing.d.ts +15 -0
- package/Printing.js +116 -0
- package/Printing.js.map +1 -0
- package/PrintingController.d.ts +26 -0
- package/PrintingController.js +117 -0
- package/PrintingController.js.map +1 -0
- package/PrintingServiceImpl.d.ts +30 -0
- package/PrintingServiceImpl.js +144 -0
- package/PrintingServiceImpl.js.map +1 -0
- package/README.md +75 -0
- package/_virtual/_virtual-pioneer-module_react-hooks.js +8 -0
- package/_virtual/_virtual-pioneer-module_react-hooks.js.map +1 -0
- package/i18n/de.yaml +8 -0
- package/i18n/en.yaml +8 -0
- package/index.d.ts +47 -0
- package/index.js +2 -0
- package/index.js.map +1 -0
- package/package.json +76 -0
- package/services.d.ts +1 -0
- package/services.js +2 -0
- package/services.js.map +1 -0
- package/styles.css +25 -0
- package/styles.css.map +1 -0
- package/utils.d.ts +4 -0
- package/utils.js +22 -0
- package/utils.js.map +1 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# @open-pioneer/printing
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 9334e81: Update to OpenLayers 9
|
|
8
|
+
- a0d8882: Initial release
|
|
9
|
+
|
|
10
|
+
### Patch Changes
|
|
11
|
+
|
|
12
|
+
- a2a6c63: Provide an API for exporting the map into a canvas / png.
|
|
13
|
+
- 1a8ad89: Update package.json metadata
|
|
14
|
+
- 6162979: Update versions of core packages
|
|
15
|
+
- Updated dependencies [1a8ad89]
|
|
16
|
+
- Updated dependencies [a11bf72]
|
|
17
|
+
- Updated dependencies [fc6bf82]
|
|
18
|
+
- Updated dependencies [a0d8882]
|
|
19
|
+
- Updated dependencies [6162979]
|
|
20
|
+
- Updated dependencies [9334e81]
|
|
21
|
+
- Updated dependencies [ac7fdd1]
|
|
22
|
+
- Updated dependencies [13ea342]
|
|
23
|
+
- @open-pioneer/react-utils@0.2.2
|
|
24
|
+
- @open-pioneer/map@0.4.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
package/Printing.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CommonComponentProps } from "@open-pioneer/react-utils";
|
|
2
|
+
import { FC } from "react";
|
|
3
|
+
/**
|
|
4
|
+
* This is special property for the Printing.
|
|
5
|
+
*/
|
|
6
|
+
export interface PrintingProps extends CommonComponentProps {
|
|
7
|
+
/**
|
|
8
|
+
* The id of the map.
|
|
9
|
+
*/
|
|
10
|
+
mapId: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The `Printing` component can be used to download the current map view as a printable file.
|
|
14
|
+
*/
|
|
15
|
+
export declare const Printing: FC<PrintingProps>;
|
package/Printing.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { Box, FormControl, HStack, FormLabel, Input, Select, Button } from '@open-pioneer/chakra-integration';
|
|
3
|
+
import { createLogger } from '@open-pioneer/core';
|
|
4
|
+
import { useMapModel } from '@open-pioneer/map';
|
|
5
|
+
import { useCommonComponentProps } from '@open-pioneer/react-utils';
|
|
6
|
+
import { useIntl, useService } from './_virtual/_virtual-pioneer-module_react-hooks.js';
|
|
7
|
+
import { useState, useEffect } from 'react';
|
|
8
|
+
import { PrintingController } from './PrintingController.js';
|
|
9
|
+
|
|
10
|
+
const LOG = createLogger("printing");
|
|
11
|
+
const Printing = (props) => {
|
|
12
|
+
const intl = useIntl();
|
|
13
|
+
const { mapId } = props;
|
|
14
|
+
const { containerProps } = useCommonComponentProps("printing", props);
|
|
15
|
+
const [selectedFileFormat, setSelectedFileFormat] = useState("pdf");
|
|
16
|
+
const [title, setTitle] = useState("");
|
|
17
|
+
const [running, setRunning] = useState(false);
|
|
18
|
+
const printingService = useService("printing.PrintingService");
|
|
19
|
+
const notifier = useService("notifier.NotificationService");
|
|
20
|
+
const { map } = useMapModel(mapId);
|
|
21
|
+
const controller = useController(map, intl, printingService);
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
controller?.setFileFormat(selectedFileFormat);
|
|
24
|
+
}, [controller, selectedFileFormat]);
|
|
25
|
+
useEffect(() => {
|
|
26
|
+
controller?.setTitle(title);
|
|
27
|
+
}, [controller, title]);
|
|
28
|
+
function changeFileFormat(fileFormat) {
|
|
29
|
+
if (fileFormat === "png" || fileFormat === "pdf") {
|
|
30
|
+
setSelectedFileFormat(fileFormat);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function exportMap() {
|
|
34
|
+
if (running || !controller) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
setRunning(true);
|
|
38
|
+
controller.handleMapExport().catch((error) => {
|
|
39
|
+
const errorMessage = intl.formatMessage({ id: "printingFailed" });
|
|
40
|
+
notifier.notify({
|
|
41
|
+
level: "error",
|
|
42
|
+
message: errorMessage
|
|
43
|
+
});
|
|
44
|
+
LOG.error("Failed to print the map", error);
|
|
45
|
+
}).finally(() => {
|
|
46
|
+
setRunning(false);
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
return /* @__PURE__ */ jsxs(Box, { ...containerProps, children: [
|
|
50
|
+
/* @__PURE__ */ jsxs(FormControl, { mb: 4, alignItems: "center", children: [
|
|
51
|
+
/* @__PURE__ */ jsxs(HStack, { mb: 2, children: [
|
|
52
|
+
/* @__PURE__ */ jsx(FormLabel, { minWidth: "82", mb: 1, children: intl.formatMessage({ id: "title" }) }),
|
|
53
|
+
/* @__PURE__ */ jsx(
|
|
54
|
+
Input,
|
|
55
|
+
{
|
|
56
|
+
placeholder: intl.formatMessage({ id: "input.placeholder" }),
|
|
57
|
+
value: title,
|
|
58
|
+
onChange: (event) => {
|
|
59
|
+
setTitle(event.target.value);
|
|
60
|
+
},
|
|
61
|
+
isRequired: true,
|
|
62
|
+
autoFocus: true
|
|
63
|
+
}
|
|
64
|
+
)
|
|
65
|
+
] }),
|
|
66
|
+
/* @__PURE__ */ jsxs(HStack, { mb: 2, children: [
|
|
67
|
+
/* @__PURE__ */ jsx(FormLabel, { minWidth: "82", mb: 1, children: intl.formatMessage({ id: "fileFormat" }) }),
|
|
68
|
+
/* @__PURE__ */ jsxs(
|
|
69
|
+
Select,
|
|
70
|
+
{
|
|
71
|
+
value: selectedFileFormat,
|
|
72
|
+
onChange: (e) => changeFileFormat(e.target.value),
|
|
73
|
+
className: "printing-select",
|
|
74
|
+
children: [
|
|
75
|
+
/* @__PURE__ */ jsx("option", { value: "png", children: "PNG" }),
|
|
76
|
+
/* @__PURE__ */ jsx("option", { value: "pdf", children: "PDF" })
|
|
77
|
+
]
|
|
78
|
+
}
|
|
79
|
+
)
|
|
80
|
+
] })
|
|
81
|
+
] }),
|
|
82
|
+
/* @__PURE__ */ jsx(
|
|
83
|
+
Button,
|
|
84
|
+
{
|
|
85
|
+
isLoading: running,
|
|
86
|
+
loadingText: intl.formatMessage({ id: "printingMap" }),
|
|
87
|
+
disabled: running,
|
|
88
|
+
padding: 2,
|
|
89
|
+
className: "printing-export-button",
|
|
90
|
+
onClick: exportMap,
|
|
91
|
+
width: "100%",
|
|
92
|
+
children: intl.formatMessage({ id: "export" })
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
] });
|
|
96
|
+
};
|
|
97
|
+
function useController(map, intl, printingService) {
|
|
98
|
+
const [controller, setController] = useState(void 0);
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
if (!map) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const controller2 = new PrintingController(map.olMap, printingService, {
|
|
104
|
+
overlayText: intl.formatMessage({ id: "printingMap" })
|
|
105
|
+
});
|
|
106
|
+
setController(controller2);
|
|
107
|
+
return () => {
|
|
108
|
+
controller2.destroy();
|
|
109
|
+
setController(void 0);
|
|
110
|
+
};
|
|
111
|
+
}, [map, intl, printingService]);
|
|
112
|
+
return controller;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { Printing };
|
|
116
|
+
//# sourceMappingURL=Printing.js.map
|
package/Printing.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Printing.js","sources":["Printing.tsx"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport {\n Box,\n Button,\n FormControl,\n FormLabel,\n HStack,\n Input,\n Select\n} from \"@open-pioneer/chakra-integration\";\nimport { createLogger } from \"@open-pioneer/core\";\nimport { MapModel, useMapModel } from \"@open-pioneer/map\";\nimport { NotificationService } from \"@open-pioneer/notifier\";\nimport { CommonComponentProps, useCommonComponentProps } from \"@open-pioneer/react-utils\";\nimport { PackageIntl } from \"@open-pioneer/runtime\";\nimport { useIntl, useService } from \"open-pioneer:react-hooks\";\nimport { FC, useEffect, useState } from \"react\";\nimport { FileFormatType, PrintingController } from \"./PrintingController\";\nimport { PrintingService } from \"./index\";\n\nconst LOG = createLogger(\"printing\");\n\n/**\n * This is special property for the Printing.\n */\nexport interface PrintingProps extends CommonComponentProps {\n /**\n * The id of the map.\n */\n mapId: string;\n}\n\n/**\n * The `Printing` component can be used to download the current map view as a printable file.\n */\nexport const Printing: FC<PrintingProps> = (props) => {\n const intl = useIntl();\n\n const { mapId } = props;\n const { containerProps } = useCommonComponentProps(\"printing\", props);\n const [selectedFileFormat, setSelectedFileFormat] = useState<FileFormatType>(\"pdf\");\n const [title, setTitle] = useState<string>(\"\");\n const [running, setRunning] = useState<boolean>(false);\n\n const printingService = useService<PrintingService>(\"printing.PrintingService\");\n const notifier = useService<NotificationService>(\"notifier.NotificationService\");\n\n const { map } = useMapModel(mapId);\n\n const controller = useController(map, intl, printingService);\n\n useEffect(() => {\n controller?.setFileFormat(selectedFileFormat);\n }, [controller, selectedFileFormat]);\n\n useEffect(() => {\n controller?.setTitle(title);\n }, [controller, title]);\n\n function changeFileFormat(fileFormat: string) {\n if (fileFormat === \"png\" || fileFormat === \"pdf\") {\n setSelectedFileFormat(fileFormat);\n }\n }\n\n function exportMap() {\n if (running || !controller) {\n return;\n }\n\n setRunning(true);\n controller\n .handleMapExport()\n .catch((error) => {\n const errorMessage = intl.formatMessage({ id: \"printingFailed\" });\n notifier.notify({\n level: \"error\",\n message: errorMessage\n });\n LOG.error(\"Failed to print the map\", error);\n })\n .finally(() => {\n setRunning(false);\n });\n }\n\n return (\n <Box {...containerProps}>\n <FormControl mb={4} alignItems=\"center\">\n <HStack mb={2}>\n <FormLabel minWidth=\"82\" mb={1}>\n {intl.formatMessage({ id: \"title\" })}\n </FormLabel>\n <Input\n placeholder={intl.formatMessage({ id: \"input.placeholder\" })}\n value={title}\n onChange={(event) => {\n setTitle(event.target.value);\n }}\n isRequired\n autoFocus // eslint-disable-line jsx-a11y/no-autofocus\n />\n </HStack>\n <HStack mb={2}>\n <FormLabel minWidth=\"82\" mb={1}>\n {intl.formatMessage({ id: \"fileFormat\" })}\n </FormLabel>\n <Select\n value={selectedFileFormat}\n onChange={(e) => changeFileFormat(e.target.value)}\n className=\"printing-select\"\n >\n <option value={\"png\"}>PNG</option>\n <option value={\"pdf\"}>PDF</option>\n </Select>\n </HStack>\n </FormControl>\n <Button\n isLoading={running}\n loadingText={intl.formatMessage({ id: \"printingMap\" })}\n disabled={running}\n padding={2}\n className=\"printing-export-button\"\n onClick={exportMap}\n width=\"100%\"\n >\n {intl.formatMessage({ id: \"export\" })}\n </Button>\n </Box>\n );\n};\n\n/**\n * Create a PrintingController instance to export the map view.\n */\nfunction useController(\n map: MapModel | undefined,\n intl: PackageIntl,\n printingService: PrintingService\n) {\n const [controller, setController] = useState<PrintingController | undefined>(undefined);\n\n useEffect(() => {\n if (!map) {\n return;\n }\n\n const controller = new PrintingController(map.olMap, printingService, {\n overlayText: intl.formatMessage({ id: \"printingMap\" })\n });\n setController(controller);\n\n return () => {\n controller.destroy();\n setController(undefined);\n };\n }, [map, intl, printingService]);\n return controller;\n}\n"],"names":["controller"],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import OlMap from "ol/Map";
|
|
2
|
+
import { PrintingService } from "./index";
|
|
3
|
+
export type FileFormatType = "png" | "pdf";
|
|
4
|
+
export declare class PrintingController {
|
|
5
|
+
private olMap;
|
|
6
|
+
private title;
|
|
7
|
+
private fileFormat;
|
|
8
|
+
private i18n;
|
|
9
|
+
private printingService;
|
|
10
|
+
private printMap;
|
|
11
|
+
private overlay;
|
|
12
|
+
constructor(olMap: OlMap, printingService: PrintingService, i18n: I18n);
|
|
13
|
+
destroy(): void;
|
|
14
|
+
setTitle(title: string): void;
|
|
15
|
+
setFileFormat(format: FileFormatType): void;
|
|
16
|
+
handleMapExport(): Promise<void>;
|
|
17
|
+
private begin;
|
|
18
|
+
private reset;
|
|
19
|
+
private getTitleAndFileName;
|
|
20
|
+
private exportMapInPNG;
|
|
21
|
+
private exportMapInPDF;
|
|
22
|
+
}
|
|
23
|
+
interface I18n {
|
|
24
|
+
overlayText: string;
|
|
25
|
+
}
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { createBlockUserOverlay, canvasToPng } from './utils.js';
|
|
2
|
+
|
|
3
|
+
const DEFAULT_FILE_NAME = "map";
|
|
4
|
+
class PrintingController {
|
|
5
|
+
olMap;
|
|
6
|
+
title = "";
|
|
7
|
+
fileFormat = "pdf";
|
|
8
|
+
i18n;
|
|
9
|
+
printingService;
|
|
10
|
+
printMap = void 0;
|
|
11
|
+
overlay = void 0;
|
|
12
|
+
constructor(olMap, printingService, i18n) {
|
|
13
|
+
this.olMap = olMap;
|
|
14
|
+
this.printingService = printingService;
|
|
15
|
+
this.i18n = i18n;
|
|
16
|
+
}
|
|
17
|
+
destroy() {
|
|
18
|
+
this.reset();
|
|
19
|
+
}
|
|
20
|
+
setTitle(title) {
|
|
21
|
+
this.title = title;
|
|
22
|
+
}
|
|
23
|
+
setFileFormat(format) {
|
|
24
|
+
this.fileFormat = format;
|
|
25
|
+
}
|
|
26
|
+
async handleMapExport() {
|
|
27
|
+
if (!this.olMap || !this.fileFormat) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
this.begin();
|
|
32
|
+
this.printMap = await this.printingService.printMap(this.olMap, {
|
|
33
|
+
blockUserInteraction: false
|
|
34
|
+
});
|
|
35
|
+
const canvas = this.printMap.getCanvas();
|
|
36
|
+
if (canvas) {
|
|
37
|
+
this.fileFormat == "png" ? await this.exportMapInPNG(canvas) : await this.exportMapInPDF(canvas);
|
|
38
|
+
} else {
|
|
39
|
+
throw new Error("Canvas export failed");
|
|
40
|
+
}
|
|
41
|
+
} finally {
|
|
42
|
+
this.reset();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
begin() {
|
|
46
|
+
const container = this.olMap.getTargetElement();
|
|
47
|
+
if (container) {
|
|
48
|
+
this.overlay = createBlockUserOverlay(container, this.i18n.overlayText);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
reset() {
|
|
52
|
+
this.overlay?.destroy();
|
|
53
|
+
this.overlay = void 0;
|
|
54
|
+
}
|
|
55
|
+
getTitleAndFileName() {
|
|
56
|
+
const titleValue = this.title || "";
|
|
57
|
+
const fileName = this.title || DEFAULT_FILE_NAME;
|
|
58
|
+
return { title: titleValue, fileName };
|
|
59
|
+
}
|
|
60
|
+
async exportMapInPNG(mapCanvas) {
|
|
61
|
+
const containerCanvas = document.createElement("canvas");
|
|
62
|
+
containerCanvas.width = mapCanvas.width;
|
|
63
|
+
containerCanvas.height = mapCanvas.height + 50;
|
|
64
|
+
containerCanvas.style.backgroundColor = "#fff";
|
|
65
|
+
const context = containerCanvas.getContext("2d");
|
|
66
|
+
if (!context) {
|
|
67
|
+
throw new Error("2d canvas rendering context not available");
|
|
68
|
+
}
|
|
69
|
+
const { title, fileName } = this.getTitleAndFileName();
|
|
70
|
+
context.fillStyle = "#fff";
|
|
71
|
+
context.fillRect(0, 0, containerCanvas.width, containerCanvas.height);
|
|
72
|
+
context.font = "20px bold sans-serif";
|
|
73
|
+
context.textAlign = "center";
|
|
74
|
+
context.fillStyle = "#000";
|
|
75
|
+
const x = containerCanvas.width / 2;
|
|
76
|
+
context.fillText(title, x, 20);
|
|
77
|
+
context.drawImage(mapCanvas, 0, 50);
|
|
78
|
+
const link = document.createElement("a");
|
|
79
|
+
link.setAttribute("download", fileName + ".png");
|
|
80
|
+
const dataURL = canvasToPng(containerCanvas);
|
|
81
|
+
if (!dataURL) {
|
|
82
|
+
throw new Error("Failed to get image data URL");
|
|
83
|
+
}
|
|
84
|
+
link.href = dataURL;
|
|
85
|
+
link.click();
|
|
86
|
+
}
|
|
87
|
+
async exportMapInPDF(canvas) {
|
|
88
|
+
const { jsPDF } = await import('jspdf');
|
|
89
|
+
const pdf = new jsPDF({
|
|
90
|
+
orientation: "landscape",
|
|
91
|
+
unit: "mm",
|
|
92
|
+
format: "a4"
|
|
93
|
+
});
|
|
94
|
+
const pageWidth = pdf.internal.pageSize.getWidth();
|
|
95
|
+
const pageHeight = pdf.internal.pageSize.getHeight();
|
|
96
|
+
const titleOffset = 15;
|
|
97
|
+
const mapOffset = 20;
|
|
98
|
+
const mapPageHeight = pageHeight - mapOffset;
|
|
99
|
+
pdf.setFontSize(20);
|
|
100
|
+
const { title, fileName } = this.getTitleAndFileName();
|
|
101
|
+
pdf.text(title, pageWidth / 2, titleOffset, { align: "center" });
|
|
102
|
+
const imageAspectRatio = canvas.width / canvas.height;
|
|
103
|
+
let targetImageHeight = mapPageHeight;
|
|
104
|
+
let targetImageWidth = targetImageHeight * imageAspectRatio;
|
|
105
|
+
if (targetImageWidth >= pageWidth) {
|
|
106
|
+
targetImageWidth = pageWidth;
|
|
107
|
+
targetImageHeight = targetImageWidth / imageAspectRatio;
|
|
108
|
+
}
|
|
109
|
+
const imageX = (pageWidth - targetImageWidth) / 2;
|
|
110
|
+
const imageY = mapOffset + (mapPageHeight - targetImageHeight) / 2;
|
|
111
|
+
pdf.addImage(canvas, "", imageX, imageY, targetImageWidth, targetImageHeight);
|
|
112
|
+
pdf.save(fileName + ".pdf");
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export { PrintingController };
|
|
117
|
+
//# sourceMappingURL=PrintingController.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrintingController.js","sources":["PrintingController.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport OlMap from \"ol/Map\";\nimport { PrintingService, PrintResult } from \"./index\";\nimport { canvasToPng, createBlockUserOverlay } from \"./utils\";\nimport { Resource } from \"@open-pioneer/core\";\n\nexport type FileFormatType = \"png\" | \"pdf\";\n\nconst DEFAULT_FILE_NAME = \"map\";\n\nexport class PrintingController {\n private olMap: OlMap;\n private title: string = \"\";\n private fileFormat: FileFormatType = \"pdf\";\n private i18n: I18n;\n\n private printingService: PrintingService;\n\n private printMap: PrintResult | undefined = undefined;\n private overlay: Resource | undefined = undefined;\n\n constructor(olMap: OlMap, printingService: PrintingService, i18n: I18n) {\n this.olMap = olMap;\n this.printingService = printingService;\n this.i18n = i18n;\n }\n\n destroy() {\n this.reset();\n }\n\n setTitle(title: string) {\n this.title = title;\n }\n\n setFileFormat(format: FileFormatType) {\n this.fileFormat = format;\n }\n\n async handleMapExport() {\n if (!this.olMap || !this.fileFormat) {\n return;\n }\n\n try {\n this.begin();\n this.printMap = await this.printingService.printMap(this.olMap, {\n blockUserInteraction: false\n });\n const canvas = this.printMap.getCanvas();\n if (canvas) {\n this.fileFormat == \"png\"\n ? await this.exportMapInPNG(canvas)\n : await this.exportMapInPDF(canvas);\n } else {\n throw new Error(\"Canvas export failed\");\n }\n } finally {\n this.reset();\n }\n }\n\n private begin() {\n const container = this.olMap.getTargetElement();\n if (container) {\n this.overlay = createBlockUserOverlay(container, this.i18n.overlayText);\n }\n }\n\n private reset() {\n this.overlay?.destroy();\n this.overlay = undefined;\n }\n\n private getTitleAndFileName() {\n const titleValue = this.title || \"\";\n const fileName = this.title || DEFAULT_FILE_NAME;\n return { title: titleValue, fileName: fileName };\n }\n\n private async exportMapInPNG(mapCanvas: HTMLCanvasElement) {\n const containerCanvas = document.createElement(\"canvas\");\n containerCanvas.width = mapCanvas.width;\n containerCanvas.height = mapCanvas.height + 50;\n containerCanvas.style.backgroundColor = \"#fff\";\n\n const context = containerCanvas.getContext(\"2d\");\n if (!context) {\n throw new Error(\"2d canvas rendering context not available\");\n }\n\n const { title, fileName } = this.getTitleAndFileName();\n\n context.fillStyle = \"#fff\"; // background color for background rect\n context.fillRect(0, 0, containerCanvas.width, containerCanvas.height); //draw background rect\n context.font = 20 + \"px bold sans-serif\";\n context.textAlign = \"center\";\n context.fillStyle = \"#000\"; // text color\n\n const x = containerCanvas.width / 2; //align text to center\n context.fillText(title, x, 20);\n context.drawImage(mapCanvas, 0, 50);\n\n const link = document.createElement(\"a\");\n link.setAttribute(\"download\", fileName + \".png\");\n\n const dataURL = canvasToPng(containerCanvas);\n if (!dataURL) {\n throw new Error(\"Failed to get image data URL\");\n }\n\n link.href = dataURL;\n link.click();\n }\n\n private async exportMapInPDF(canvas: HTMLCanvasElement) {\n // Landscape map export.\n // Lazy load pdfjs as well.\n const { jsPDF } = await import(\"jspdf\");\n const pdf = new jsPDF({\n orientation: \"landscape\",\n unit: \"mm\",\n format: \"a4\"\n });\n\n // Simple layout: 50 pixels for the header and\n // the remaining space can be used by the map export.\n const pageWidth = pdf.internal.pageSize.getWidth();\n const pageHeight = pdf.internal.pageSize.getHeight();\n const titleOffset = 15;\n const mapOffset = 20;\n const mapPageHeight = pageHeight - mapOffset;\n\n // Render title\n pdf.setFontSize(20);\n const { title, fileName } = this.getTitleAndFileName();\n pdf.text(title, pageWidth / 2, titleOffset, { align: \"center\" });\n\n // Resize image while keeping aspect ratio\n const imageAspectRatio = canvas.width / canvas.height;\n let targetImageHeight = mapPageHeight;\n let targetImageWidth = targetImageHeight * imageAspectRatio;\n if (targetImageWidth >= pageWidth) {\n targetImageWidth = pageWidth;\n targetImageHeight = targetImageWidth / imageAspectRatio;\n }\n\n // Center image\n const imageX = (pageWidth - targetImageWidth) / 2;\n const imageY = mapOffset + (mapPageHeight - targetImageHeight) / 2;\n\n pdf.addImage(canvas, \"\", imageX, imageY, targetImageWidth, targetImageHeight);\n pdf.save(fileName + \".pdf\");\n }\n}\n\ninterface I18n {\n overlayText: string;\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PrintingOptions, PrintingService, PrintResult } from "./index";
|
|
2
|
+
import OlMap from "ol/Map";
|
|
3
|
+
import { ServiceOptions } from "@open-pioneer/runtime";
|
|
4
|
+
export declare class PrintingServiceImpl implements PrintingService {
|
|
5
|
+
private defaultOverlayText;
|
|
6
|
+
constructor(options: ServiceOptions);
|
|
7
|
+
printMap(olMap: OlMap, options?: PrintingOptions): Promise<PrintResultImpl>;
|
|
8
|
+
}
|
|
9
|
+
export declare class PrintJob {
|
|
10
|
+
private olMap;
|
|
11
|
+
private blockUserInteraction;
|
|
12
|
+
private overlayText;
|
|
13
|
+
private running;
|
|
14
|
+
private drawInformation;
|
|
15
|
+
private scaleLine;
|
|
16
|
+
private overlay;
|
|
17
|
+
constructor(olMap: OlMap, options: Required<PrintingOptions>);
|
|
18
|
+
printMap(): Promise<PrintResultImpl>;
|
|
19
|
+
private beginExport;
|
|
20
|
+
private addScaleLine;
|
|
21
|
+
private printToCanvas;
|
|
22
|
+
private reset;
|
|
23
|
+
}
|
|
24
|
+
declare class PrintResultImpl implements PrintResult {
|
|
25
|
+
private canvas;
|
|
26
|
+
constructor(canvas: HTMLCanvasElement);
|
|
27
|
+
getCanvas(): HTMLCanvasElement;
|
|
28
|
+
getPNGDataURL(quality?: number): string;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import Draw from 'ol/interaction/Draw';
|
|
2
|
+
import { ScaleLine } from 'ol/control';
|
|
3
|
+
import { createManualPromise } from '@open-pioneer/core';
|
|
4
|
+
import { createBlockUserOverlay, canvasToPng, PRINTING_HIDE_CLASS } from './utils.js';
|
|
5
|
+
|
|
6
|
+
class PrintingServiceImpl {
|
|
7
|
+
defaultOverlayText;
|
|
8
|
+
constructor(options) {
|
|
9
|
+
this.defaultOverlayText = options.intl.formatMessage({
|
|
10
|
+
id: "printingMap"
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
async printMap(olMap, options) {
|
|
14
|
+
const job = new PrintJob(olMap, {
|
|
15
|
+
blockUserInteraction: true,
|
|
16
|
+
overlayText: this.defaultOverlayText,
|
|
17
|
+
...options
|
|
18
|
+
});
|
|
19
|
+
return await job.printMap();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
class PrintJob {
|
|
23
|
+
olMap;
|
|
24
|
+
blockUserInteraction = false;
|
|
25
|
+
overlayText;
|
|
26
|
+
running = false;
|
|
27
|
+
drawInformation = [];
|
|
28
|
+
scaleLine = void 0;
|
|
29
|
+
overlay = void 0;
|
|
30
|
+
constructor(olMap, options) {
|
|
31
|
+
this.olMap = olMap;
|
|
32
|
+
this.blockUserInteraction = options.blockUserInteraction;
|
|
33
|
+
this.overlayText = options.overlayText;
|
|
34
|
+
}
|
|
35
|
+
async printMap() {
|
|
36
|
+
if (this.running) {
|
|
37
|
+
throw new Error("Printing already running.");
|
|
38
|
+
}
|
|
39
|
+
try {
|
|
40
|
+
await this.beginExport();
|
|
41
|
+
const canvas = await this.printToCanvas(this.olMap.getViewport());
|
|
42
|
+
if (canvas) {
|
|
43
|
+
return new PrintResultImpl(canvas);
|
|
44
|
+
} else {
|
|
45
|
+
throw new Error("Canvas export failed");
|
|
46
|
+
}
|
|
47
|
+
} finally {
|
|
48
|
+
this.reset();
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async beginExport() {
|
|
52
|
+
this.running = true;
|
|
53
|
+
const interactions = this.olMap.getInteractions().getArray().filter((interaction) => {
|
|
54
|
+
return interaction.getActive() && interaction instanceof Draw;
|
|
55
|
+
});
|
|
56
|
+
this.drawInformation = [];
|
|
57
|
+
interactions?.forEach((interaction) => {
|
|
58
|
+
const draw = interaction;
|
|
59
|
+
const previousStyle = draw.getOverlay().getStyle();
|
|
60
|
+
draw.getOverlay().setStyle(null);
|
|
61
|
+
this.drawInformation?.push({
|
|
62
|
+
draw,
|
|
63
|
+
style: previousStyle
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
if (this.blockUserInteraction) {
|
|
67
|
+
const container = this.olMap?.getTargetElement();
|
|
68
|
+
if (container) {
|
|
69
|
+
this.overlay = createBlockUserOverlay(container, this.overlayText);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
await this.addScaleLine();
|
|
73
|
+
}
|
|
74
|
+
async addScaleLine() {
|
|
75
|
+
this.scaleLine = new ScaleLine({
|
|
76
|
+
className: "printing-scale-bar ol-scale-bar",
|
|
77
|
+
bar: true,
|
|
78
|
+
text: true,
|
|
79
|
+
minWidth: 125
|
|
80
|
+
});
|
|
81
|
+
const renderPromise = createManualPromise();
|
|
82
|
+
const timeout = setTimeout(() => {
|
|
83
|
+
renderPromise.reject(new Error("Scale line did not render"));
|
|
84
|
+
}, 3e3);
|
|
85
|
+
const oldRender = this.scaleLine.render;
|
|
86
|
+
this.scaleLine.render = (...args) => {
|
|
87
|
+
oldRender.apply(this.scaleLine, args);
|
|
88
|
+
renderPromise.resolve();
|
|
89
|
+
};
|
|
90
|
+
this.olMap?.addControl(this.scaleLine);
|
|
91
|
+
try {
|
|
92
|
+
await renderPromise.promise;
|
|
93
|
+
await new Promise((resolve) => {
|
|
94
|
+
requestAnimationFrame(resolve);
|
|
95
|
+
});
|
|
96
|
+
} finally {
|
|
97
|
+
clearTimeout(timeout);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async printToCanvas(element) {
|
|
101
|
+
const exportOptions = {
|
|
102
|
+
useCORS: true,
|
|
103
|
+
ignoreElements: function(element2) {
|
|
104
|
+
if (element2.classList && typeof element2.classList === "object") {
|
|
105
|
+
const classList = element2.classList;
|
|
106
|
+
return classList.contains("map-anchors") || classList.contains(PRINTING_HIDE_CLASS);
|
|
107
|
+
}
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
const html2canvas = (await import('html2canvas')).default;
|
|
112
|
+
const canvas = await html2canvas(element, exportOptions);
|
|
113
|
+
return canvas;
|
|
114
|
+
}
|
|
115
|
+
reset() {
|
|
116
|
+
if (this.scaleLine) {
|
|
117
|
+
this.olMap?.removeControl(this.scaleLine);
|
|
118
|
+
this.scaleLine = void 0;
|
|
119
|
+
}
|
|
120
|
+
if (this.overlay) {
|
|
121
|
+
this.overlay.destroy();
|
|
122
|
+
this.overlay = void 0;
|
|
123
|
+
}
|
|
124
|
+
this.running = false;
|
|
125
|
+
this.drawInformation?.length && this.drawInformation.forEach((drawInfo) => {
|
|
126
|
+
drawInfo.draw.getOverlay().setStyle(drawInfo.style);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
class PrintResultImpl {
|
|
131
|
+
canvas;
|
|
132
|
+
constructor(canvas) {
|
|
133
|
+
this.canvas = canvas;
|
|
134
|
+
}
|
|
135
|
+
getCanvas() {
|
|
136
|
+
return this.canvas;
|
|
137
|
+
}
|
|
138
|
+
getPNGDataURL(quality) {
|
|
139
|
+
return canvasToPng(this.canvas, quality);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export { PrintJob, PrintingServiceImpl };
|
|
144
|
+
//# sourceMappingURL=PrintingServiceImpl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PrintingServiceImpl.js","sources":["PrintingServiceImpl.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport type { PrintingOptions, PrintingService, PrintResult } from \"./index\";\nimport OlMap from \"ol/Map\";\nimport Draw from \"ol/interaction/Draw\";\nimport { StyleLike } from \"ol/style/Style\";\nimport { ScaleLine } from \"ol/control\";\nimport { Interaction } from \"ol/interaction\";\nimport { createManualPromise, Resource } from \"@open-pioneer/core\";\nimport { Options } from \"html2canvas\";\nimport { canvasToPng, createBlockUserOverlay, PRINTING_HIDE_CLASS } from \"./utils\";\nimport { ServiceOptions } from \"@open-pioneer/runtime\";\n\nexport class PrintingServiceImpl implements PrintingService {\n private defaultOverlayText: string;\n\n constructor(options: ServiceOptions) {\n this.defaultOverlayText = options.intl.formatMessage({\n id: \"printingMap\"\n });\n }\n\n async printMap(olMap: OlMap, options?: PrintingOptions): Promise<PrintResultImpl> {\n const job = new PrintJob(olMap, {\n blockUserInteraction: true,\n overlayText: this.defaultOverlayText,\n ...options\n });\n return await job.printMap();\n }\n}\n\n// Exported just for test (mocking)\nexport class PrintJob {\n private olMap: OlMap;\n private blockUserInteraction: boolean = false;\n private overlayText: string;\n\n private running = false;\n private drawInformation: { draw: Draw; style: StyleLike | null | undefined }[] | undefined = [];\n private scaleLine: ScaleLine | undefined = undefined;\n private overlay: Resource | undefined = undefined;\n\n constructor(olMap: OlMap, options: Required<PrintingOptions>) {\n this.olMap = olMap;\n this.blockUserInteraction = options.blockUserInteraction;\n this.overlayText = options.overlayText;\n }\n\n async printMap(): Promise<PrintResultImpl> {\n if (this.running) {\n throw new Error(\"Printing already running.\");\n }\n\n try {\n await this.beginExport();\n\n const canvas = await this.printToCanvas(this.olMap.getViewport());\n if (canvas) {\n return new PrintResultImpl(canvas);\n } else {\n throw new Error(\"Canvas export failed\");\n }\n } finally {\n // Always remove scale bar\n this.reset();\n }\n }\n\n private async beginExport() {\n this.running = true;\n\n /** hides active draw interactions while printing (set feature style to null ) */\n const interactions = this.olMap\n .getInteractions()\n .getArray()\n .filter((interaction: Interaction) => {\n return interaction.getActive() && interaction instanceof Draw;\n });\n this.drawInformation = [];\n interactions?.forEach((interaction) => {\n const draw = interaction as Draw;\n const previousStyle = draw.getOverlay().getStyle();\n draw.getOverlay().setStyle(null);\n this.drawInformation?.push({\n draw: draw,\n style: previousStyle\n });\n });\n\n if (this.blockUserInteraction) {\n const container = this.olMap?.getTargetElement();\n if (container) {\n this.overlay = createBlockUserOverlay(container, this.overlayText);\n }\n }\n await this.addScaleLine();\n }\n\n private async addScaleLine() {\n this.scaleLine = new ScaleLine({\n className: \"printing-scale-bar ol-scale-bar\",\n bar: true,\n text: true,\n minWidth: 125\n });\n\n const renderPromise = createManualPromise<void>();\n\n // We expect the scale line to be rendered by the open layers map.\n // This is a sanity check that throws an error when that either doesn't happen\n // or if it takes an extremely large time.\n const timeout = setTimeout(() => {\n renderPromise.reject(new Error(\"Scale line did not render\"));\n }, 3000);\n\n const oldRender = this.scaleLine.render;\n this.scaleLine.render = (...args) => {\n oldRender.apply(this.scaleLine, args);\n renderPromise.resolve();\n };\n this.olMap?.addControl(this.scaleLine);\n\n try {\n // Wait until render (+ one additional frame just to be sure).\n await renderPromise.promise;\n await new Promise((resolve) => {\n requestAnimationFrame(resolve);\n });\n } finally {\n clearTimeout(timeout);\n }\n }\n\n private async printToCanvas(element: HTMLElement): Promise<HTMLCanvasElement> {\n // export options for html2canvas.\n const exportOptions: Partial<Options> = {\n useCORS: true,\n ignoreElements: function (element: Element) {\n if (element.classList && typeof element.classList === \"object\") {\n const classList = element.classList;\n return (\n classList.contains(\"map-anchors\") || classList.contains(PRINTING_HIDE_CLASS)\n );\n }\n return false;\n }\n };\n\n // Lazy load html2canvas: it is a large dependency (a few hundred KiB) that is only\n // required when actually printed. This speeds up the initial page load.\n const html2canvas = (await import(\"html2canvas\")).default;\n const canvas = await html2canvas(element, exportOptions);\n\n return canvas;\n }\n\n private reset() {\n if (this.scaleLine) {\n this.olMap?.removeControl(this.scaleLine);\n this.scaleLine = undefined;\n }\n if (this.overlay) {\n this.overlay.destroy();\n this.overlay = undefined;\n }\n\n this.running = false;\n\n /** show active draw interactions after printing (reset feature style to its previous style ) */\n this.drawInformation?.length &&\n this.drawInformation.forEach((drawInfo) => {\n drawInfo.draw.getOverlay().setStyle(drawInfo.style);\n });\n }\n}\n\nclass PrintResultImpl implements PrintResult {\n private canvas: HTMLCanvasElement;\n\n constructor(canvas: HTMLCanvasElement) {\n this.canvas = canvas;\n }\n getCanvas(): HTMLCanvasElement {\n return this.canvas;\n }\n\n getPNGDataURL(quality?: number): string {\n return canvasToPng(this.canvas, quality);\n }\n}\n"],"names":["element"],"mappings":"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"}
|
package/README.md
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# @open-pioneer/printing
|
|
2
|
+
|
|
3
|
+
This package provides a UI component and an API to export the current map view as a printable file.
|
|
4
|
+
|
|
5
|
+
The UI allows users to enter a title, switch between the printing file formats, and trigger the export.
|
|
6
|
+
|
|
7
|
+
The supported file formats are PDF and PNG.
|
|
8
|
+
If file format is PNG, the current map canvas is exported as an image.
|
|
9
|
+
If file format is PDF, the map is printed as a DIN A4 landscape PDF file, preserving the current map scale and showing the current map center in the middle of the exported map image.
|
|
10
|
+
|
|
11
|
+
The package also provides a printing service that creates an image of the map as a canvas element or a data URL for a PNG image.
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
### UI Component
|
|
16
|
+
|
|
17
|
+
To integrate the printing in your app, insert the following snippet and reference a map ID:
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
<Printing mapId="map_id" />
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Printing Service
|
|
24
|
+
|
|
25
|
+
To use the printing service, inject it as following:
|
|
26
|
+
|
|
27
|
+
```js
|
|
28
|
+
// build.config.mjs
|
|
29
|
+
import { defineBuildConfig } from "@open-pioneer/build-support";
|
|
30
|
+
|
|
31
|
+
export default defineBuildConfig({
|
|
32
|
+
ui: {
|
|
33
|
+
references: ["printing.PrintingService"]
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
```tsx
|
|
39
|
+
const printingService = useService<PrintingService>("printing.PrintingService");
|
|
40
|
+
|
|
41
|
+
// Triggers printing and waits for the result.
|
|
42
|
+
const printResult = await printingService.printMap(map);
|
|
43
|
+
|
|
44
|
+
// An HTMLCanvasElement containing an image of the map
|
|
45
|
+
const canvas = printResult.getCanvas();
|
|
46
|
+
|
|
47
|
+
// For convenience, an image encoded as PNG (i.e. `data:image/png;base64,...`)
|
|
48
|
+
const dataURL = printResult.getPNGDataURL();
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
It is configurable whether to add an overlay element above the map or not.
|
|
52
|
+
The default overlay blocks user interactions while the map is printing.
|
|
53
|
+
The text content of the overlay can be overwritten by configuring a custom text.
|
|
54
|
+
|
|
55
|
+
Example:
|
|
56
|
+
|
|
57
|
+
```tsx
|
|
58
|
+
const printResult = await printingService.printMap(map, {
|
|
59
|
+
blockUserInteraction: true,
|
|
60
|
+
overlayText: "custom text"
|
|
61
|
+
});
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Printed elements
|
|
65
|
+
|
|
66
|
+
The printed map contains all map elements, visible layers, scale-bar and a title. If the user does not enter a title, the map is printed without title.
|
|
67
|
+
To prevent custom elements from showing in the printed map, add the classname `printing-hide` to the elements.
|
|
68
|
+
|
|
69
|
+
## Known issues
|
|
70
|
+
|
|
71
|
+
- Printing to PNG may not work on Safari / Chrome on iOS (see <https://github.com/open-pioneer/trails-openlayers-base-packages/issues/294>)
|
|
72
|
+
|
|
73
|
+
## License
|
|
74
|
+
|
|
75
|
+
Apache-2.0 (see `LICENSE` file)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { useServiceInternal, useIntlInternal } from '@open-pioneer/runtime/react-integration';
|
|
2
|
+
|
|
3
|
+
const PACKAGE_NAME = "@open-pioneer/printing";
|
|
4
|
+
const useService = /*@__PURE__*/ useServiceInternal.bind(undefined, PACKAGE_NAME);
|
|
5
|
+
const useIntl = /*@__PURE__*/ useIntlInternal.bind(undefined, PACKAGE_NAME);
|
|
6
|
+
|
|
7
|
+
export { useIntl, useService };
|
|
8
|
+
//# sourceMappingURL=_virtual-pioneer-module_react-hooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_virtual-pioneer-module_react-hooks.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
|
package/i18n/de.yaml
ADDED
package/i18n/en.yaml
ADDED
package/index.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { DeclaredService } from "@open-pioneer/runtime";
|
|
2
|
+
import OlMap from "ol/Map";
|
|
3
|
+
/**
|
|
4
|
+
* Options supported when printing the map.
|
|
5
|
+
*/
|
|
6
|
+
export interface PrintingOptions {
|
|
7
|
+
/**
|
|
8
|
+
* When this is true (the default), an overlay will be added above the map
|
|
9
|
+
* to block user interactions.
|
|
10
|
+
*
|
|
11
|
+
* It is recommended to block user interaction (in some way) while the map is printing
|
|
12
|
+
* to avoid inconsistencies.
|
|
13
|
+
*/
|
|
14
|
+
blockUserInteraction?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* This option can be used to customize the text content of the overlay (if enabled).
|
|
17
|
+
*/
|
|
18
|
+
overlayText?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* The printing service provides an image of a map as a canvas element or a data URL for a PNG image.
|
|
22
|
+
*
|
|
23
|
+
* Inject an instance of this service by referencing the interface name `"printing.PrintingService"`.
|
|
24
|
+
*/
|
|
25
|
+
export interface PrintingService extends DeclaredService<"printing.PrintingService"> {
|
|
26
|
+
/**
|
|
27
|
+
* Starts a map print operation on the specified map.
|
|
28
|
+
*
|
|
29
|
+
* The promise resolves with the resulting map image or with any error that occurred
|
|
30
|
+
* while printing the map.
|
|
31
|
+
*/
|
|
32
|
+
printMap(olMap: OlMap, options?: PrintingOptions): Promise<PrintResult>;
|
|
33
|
+
}
|
|
34
|
+
/** The result of a print operation. */
|
|
35
|
+
export interface PrintResult {
|
|
36
|
+
/** Returns a canvas element that contains the result of the map print. */
|
|
37
|
+
getCanvas(): HTMLCanvasElement;
|
|
38
|
+
/**
|
|
39
|
+
* Returns a data URL (i.e. `data:...`) that contains a PNG image.
|
|
40
|
+
*
|
|
41
|
+
* Use `quality` (between 0 and 1, defaults to 0.8) to control the image size / compression.
|
|
42
|
+
*
|
|
43
|
+
* See also <https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL>.
|
|
44
|
+
*/
|
|
45
|
+
getPNGDataURL(quality?: number): string;
|
|
46
|
+
}
|
|
47
|
+
export { Printing, type PrintingProps } from "./Printing";
|
package/index.js
ADDED
package/index.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "module",
|
|
3
|
+
"name": "@open-pioneer/printing",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"description": "This package provides a UI component to export the current map view as a printable file.",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"open-pioneer-trails"
|
|
8
|
+
],
|
|
9
|
+
"homepage": "https://github.com/open-pioneer",
|
|
10
|
+
"license": "Apache-2.0",
|
|
11
|
+
"repository": {
|
|
12
|
+
"type": "git",
|
|
13
|
+
"url": "https://github.com/open-pioneer/trails-openlayers-base-packages",
|
|
14
|
+
"directory": "src/packages/printing"
|
|
15
|
+
},
|
|
16
|
+
"peerDependencies": {
|
|
17
|
+
"@open-pioneer/chakra-integration": "^1.1.1",
|
|
18
|
+
"@open-pioneer/runtime": "^2.1.2",
|
|
19
|
+
"@open-pioneer/core": "^1.2.1",
|
|
20
|
+
"@open-pioneer/notifier": "^0.3.1",
|
|
21
|
+
"ol": "^9.0.0",
|
|
22
|
+
"react": "^18.2.0",
|
|
23
|
+
"classnames": "^2.3.2",
|
|
24
|
+
"html2canvas": "^1.4.1",
|
|
25
|
+
"jspdf": "^2.5.1",
|
|
26
|
+
"@open-pioneer/map": "^0.4.0",
|
|
27
|
+
"@open-pioneer/react-utils": "^0.2.2"
|
|
28
|
+
},
|
|
29
|
+
"exports": {
|
|
30
|
+
"./package.json": "./package.json",
|
|
31
|
+
".": {
|
|
32
|
+
"import": "./index.js",
|
|
33
|
+
"types": "./index.d.ts"
|
|
34
|
+
},
|
|
35
|
+
"./services": {
|
|
36
|
+
"import": "./services.js",
|
|
37
|
+
"types": "./services.d.ts"
|
|
38
|
+
},
|
|
39
|
+
"./styles.css": "./styles.css"
|
|
40
|
+
},
|
|
41
|
+
"openPioneerFramework": {
|
|
42
|
+
"styles": "./styles.css",
|
|
43
|
+
"services": [
|
|
44
|
+
{
|
|
45
|
+
"serviceName": "PrintingServiceImpl",
|
|
46
|
+
"provides": [
|
|
47
|
+
{
|
|
48
|
+
"interfaceName": "printing.PrintingService"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"references": []
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"servicesModule": "./services",
|
|
55
|
+
"i18n": {
|
|
56
|
+
"languages": [
|
|
57
|
+
"en",
|
|
58
|
+
"de"
|
|
59
|
+
]
|
|
60
|
+
},
|
|
61
|
+
"ui": {
|
|
62
|
+
"references": [
|
|
63
|
+
{
|
|
64
|
+
"type": "unique",
|
|
65
|
+
"interfaceName": "notifier.NotificationService"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"type": "unique",
|
|
69
|
+
"interfaceName": "printing.PrintingService"
|
|
70
|
+
}
|
|
71
|
+
]
|
|
72
|
+
},
|
|
73
|
+
"properties": [],
|
|
74
|
+
"packageFormatVersion": "1.0.0"
|
|
75
|
+
}
|
|
76
|
+
}
|
package/services.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { PrintingServiceImpl } from "./PrintingServiceImpl";
|
package/services.js
ADDED
package/services.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
|
package/styles.css
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
.printing-overlay {
|
|
2
|
+
/* container uses position relative, so this absolute positioning works */
|
|
3
|
+
position: absolute;
|
|
4
|
+
inset: 0;
|
|
5
|
+
z-index: 10000;
|
|
6
|
+
|
|
7
|
+
/* non-interactive: the overlay is "in front" of the map and blocks events */
|
|
8
|
+
user-select: none;
|
|
9
|
+
pointer-events: all;
|
|
10
|
+
cursor: wait;
|
|
11
|
+
|
|
12
|
+
display: flex;
|
|
13
|
+
flex-direction: row;
|
|
14
|
+
align-items: center;
|
|
15
|
+
justify-content: center;
|
|
16
|
+
background-color: rgba(180, 180, 180, 0.8);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.printing-overlay-status {
|
|
20
|
+
flex: 1 1 auto;
|
|
21
|
+
font-size: 1.5em;
|
|
22
|
+
text-align: center;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/*# sourceMappingURL=styles.css.map */
|
package/styles.css.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["styles.css"],"names":[],"mappings":"AAAA;IACI,yEAAyE;IACzE,kBAAkB;IAClB,QAAQ;IACR,cAAc;;IAEd,4EAA4E;IAC5E,iBAAiB;IACjB,mBAAmB;IACnB,YAAY;;IAEZ,aAAa;IACb,mBAAmB;IACnB,mBAAmB;IACnB,uBAAuB;IACvB,0CAA0C;AAC9C;;AAEA;IACI,cAAc;IACd,gBAAgB;IAChB,kBAAkB;AACtB","file":"styles.css","sourcesContent":[".printing-overlay {\n /* container uses position relative, so this absolute positioning works */\n position: absolute;\n inset: 0;\n z-index: 10000;\n\n /* non-interactive: the overlay is \"in front\" of the map and blocks events */\n user-select: none;\n pointer-events: all;\n cursor: wait;\n\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: center;\n background-color: rgba(180, 180, 180, 0.8);\n}\n\n.printing-overlay-status {\n flex: 1 1 auto;\n font-size: 1.5em;\n text-align: center;\n}\n"]}
|
package/utils.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { Resource } from "@open-pioneer/core";
|
|
2
|
+
export declare const PRINTING_HIDE_CLASS = "printing-hide";
|
|
3
|
+
export declare function canvasToPng(canvas: HTMLCanvasElement, quality?: number): string;
|
|
4
|
+
export declare function createBlockUserOverlay(container: HTMLElement, text: string): Resource;
|
package/utils.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const DEFAULT_QUALITY = 0.8;
|
|
2
|
+
const PRINTING_HIDE_CLASS = "printing-hide";
|
|
3
|
+
function canvasToPng(canvas, quality) {
|
|
4
|
+
return canvas.toDataURL("image/png", quality ?? DEFAULT_QUALITY);
|
|
5
|
+
}
|
|
6
|
+
function createBlockUserOverlay(container, text) {
|
|
7
|
+
const overlay = document.createElement("div");
|
|
8
|
+
overlay.classList.add("printing-overlay", PRINTING_HIDE_CLASS);
|
|
9
|
+
container.appendChild(overlay);
|
|
10
|
+
const message = document.createElement("div");
|
|
11
|
+
message.classList.add("printing-overlay-status");
|
|
12
|
+
message.textContent = text;
|
|
13
|
+
overlay.appendChild(message);
|
|
14
|
+
return {
|
|
15
|
+
destroy() {
|
|
16
|
+
overlay.remove();
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { PRINTING_HIDE_CLASS, canvasToPng, createBlockUserOverlay };
|
|
22
|
+
//# sourceMappingURL=utils.js.map
|
package/utils.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["utils.ts"],"sourcesContent":["// SPDX-FileCopyrightText: 2023 Open Pioneer project (https://github.com/open-pioneer)\n// SPDX-License-Identifier: Apache-2.0\nimport { Resource } from \"@open-pioneer/core\";\n\nconst DEFAULT_QUALITY = 0.8;\n\nexport const PRINTING_HIDE_CLASS = \"printing-hide\";\n\nexport function canvasToPng(canvas: HTMLCanvasElement, quality?: number) {\n return canvas.toDataURL(\"image/png\", quality ?? DEFAULT_QUALITY);\n}\n\nexport function createBlockUserOverlay(container: HTMLElement, text: string): Resource {\n const overlay = document.createElement(\"div\");\n overlay.classList.add(\"printing-overlay\", PRINTING_HIDE_CLASS);\n container.appendChild(overlay);\n\n const message = document.createElement(\"div\");\n message.classList.add(\"printing-overlay-status\");\n message.textContent = text;\n overlay.appendChild(message);\n\n return {\n destroy() {\n overlay.remove();\n }\n };\n}\n"],"names":[],"mappings":"AAIA,MAAM,eAAkB,GAAA,GAAA,CAAA;AAEjB,MAAM,mBAAsB,GAAA,gBAAA;AAEnB,SAAA,WAAA,CAAY,QAA2B,OAAkB,EAAA;AACrE,EAAA,OAAO,MAAO,CAAA,SAAA,CAAU,WAAa,EAAA,OAAA,IAAW,eAAe,CAAA,CAAA;AACnE,CAAA;AAEgB,SAAA,sBAAA,CAAuB,WAAwB,IAAwB,EAAA;AACnF,EAAM,MAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,KAAK,CAAA,CAAA;AAC5C,EAAQ,OAAA,CAAA,SAAA,CAAU,GAAI,CAAA,kBAAA,EAAoB,mBAAmB,CAAA,CAAA;AAC7D,EAAA,SAAA,CAAU,YAAY,OAAO,CAAA,CAAA;AAE7B,EAAM,MAAA,OAAA,GAAU,QAAS,CAAA,aAAA,CAAc,KAAK,CAAA,CAAA;AAC5C,EAAQ,OAAA,CAAA,SAAA,CAAU,IAAI,yBAAyB,CAAA,CAAA;AAC/C,EAAA,OAAA,CAAQ,WAAc,GAAA,IAAA,CAAA;AACtB,EAAA,OAAA,CAAQ,YAAY,OAAO,CAAA,CAAA;AAE3B,EAAO,OAAA;AAAA,IACH,OAAU,GAAA;AACN,MAAA,OAAA,CAAQ,MAAO,EAAA,CAAA;AAAA,KACnB;AAAA,GACJ,CAAA;AACJ;;;;"}
|