qwc2 2026.5.28 → 2026.6.3

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.
Files changed (39) hide show
  1. package/components/QtDesignerForm.js +18 -1
  2. package/components/StandardApp.js +2 -2
  3. package/components/ThemeList.js +6 -1
  4. package/components/map3d/Map3D.js +10 -6
  5. package/components/map3d/utils/FirstPersonControls3D.js +14 -12
  6. package/components/style/SearchBox.css +0 -4
  7. package/components/style/ThemeList.css +8 -0
  8. package/package.json +1 -1
  9. package/plugins/BackgroundSwitcher.js +1 -1
  10. package/plugins/Bookmark.js +7 -2
  11. package/plugins/Editing.js +2 -1
  12. package/plugins/map3d/BottomBar3D.js +90 -13
  13. package/plugins/map3d/LayerTree3D.js +10 -3
  14. package/plugins/map3d/TopBar3D.js +1 -1
  15. package/plugins/map3d/style/BottomBar3D.css +6 -0
  16. package/plugins/style/OverviewMap.css +3 -0
  17. package/static/translations/bg-BG.json +1 -0
  18. package/static/translations/ca-ES.json +1 -0
  19. package/static/translations/cs-CZ.json +1 -0
  20. package/static/translations/de-CH.json +1 -0
  21. package/static/translations/de-DE.json +1 -0
  22. package/static/translations/en-US.json +1 -0
  23. package/static/translations/es-ES.json +1 -0
  24. package/static/translations/fi-FI.json +1 -0
  25. package/static/translations/fr-FR.json +1 -0
  26. package/static/translations/hu-HU.json +1 -0
  27. package/static/translations/it-IT.json +1 -0
  28. package/static/translations/ja-JP.json +1 -0
  29. package/static/translations/nl-NL.json +1 -0
  30. package/static/translations/no-NO.json +1 -0
  31. package/static/translations/pl-PL.json +1 -0
  32. package/static/translations/pt-BR.json +1 -0
  33. package/static/translations/pt-PT.json +1 -0
  34. package/static/translations/ro-RO.json +1 -0
  35. package/static/translations/ru-RU.json +1 -0
  36. package/static/translations/sv-SE.json +1 -0
  37. package/static/translations/tr-TR.json +1 -0
  38. package/static/translations/tsconfig.json +1 -0
  39. package/static/translations/uk-UA.json +1 -0
@@ -273,7 +273,24 @@ var QtDesignerForm = /*#__PURE__*/function (_React$Component) {
273
273
  } else {
274
274
  elname = nametransform(widget.name);
275
275
  }
276
- if (widget["class"] === "QLabel") {
276
+ if (widget.component) {
277
+ return /*#__PURE__*/React.createElement(widget.component, {
278
+ addRelationRecord: _this.props.addRelationRecord,
279
+ editConfigs: _this.props.editConfigs,
280
+ feature: _this.props.feature,
281
+ inputConstraints: inputConstraints,
282
+ mapPrefix: _this.props.mapPrefix,
283
+ name: elname,
284
+ onChange: function onChange(val) {
285
+ return updateField(widget.name, val);
286
+ },
287
+ readOnly: _this.props.readOnly,
288
+ removeRelationRecord: _this.props.removeRelationRecord,
289
+ reorderRelationRecord: _this.props.reorderRelationRecord,
290
+ updateRelationField: _this.props.updateRelationField,
291
+ widget: widget
292
+ });
293
+ } else if (widget["class"] === "QLabel") {
277
294
  if (widget.name.startsWith("img__")) {
278
295
  var _feature$properties$w2, _feature$properties2;
279
296
  value = (_feature$properties$w2 = (_feature$properties2 = feature.properties) === null || _feature$properties2 === void 0 ? void 0 : _feature$properties2[widget.name.split("__")[1]]) !== null && _feature$properties$w2 !== void 0 ? _feature$properties$w2 : widget.property.text;
@@ -265,7 +265,7 @@ var StandardApp = /*#__PURE__*/function (_React$Component2) {
265
265
  return res;
266
266
  }, {});
267
267
  ConfigUtils.loadConfiguration(configParams).then(function (config) {
268
- var _window$QWC2PluginCon, _window$QWC2PluginCon2, _window$QWC2PluginCon3, _ref5, _this2$props$appConfi, _this2$props$appConfi2, _this2$props$appConfi3;
268
+ var _window$QWC2PluginCon, _window$QWC2PluginCon2, _window$QWC2PluginCon3, _ref5, _ref6, _this2$props$appConfi, _this2$props$appConfi2, _this2$props$appConfi3;
269
269
  // Merge common config into mobile/desktop config, merge config from appConfig
270
270
  var renameTaskButtons = function renameTaskButtons(res, entry) {
271
271
  var _entry$cfg$task, _entry$cfg;
@@ -318,7 +318,7 @@ var StandardApp = /*#__PURE__*/function (_React$Component2) {
318
318
  });
319
319
 
320
320
  // Load locale
321
- var lang = (_ref5 = (_this2$props$appConfi = (_this2$props$appConfi2 = (_this2$props$appConfi3 = _this2.props.appConfig).getDefaultLocale) === null || _this2$props$appConfi2 === void 0 ? void 0 : _this2$props$appConfi2.call(_this2$props$appConfi3)) !== null && _this2$props$appConfi !== void 0 ? _this2$props$appConfi : initialParams.lang) !== null && _ref5 !== void 0 ? _ref5 : navigator.language;
321
+ var lang = (_ref5 = (_ref6 = (_this2$props$appConfi = (_this2$props$appConfi2 = (_this2$props$appConfi3 = _this2.props.appConfig).getDefaultLocale) === null || _this2$props$appConfi2 === void 0 ? void 0 : _this2$props$appConfi2.call(_this2$props$appConfi3)) !== null && _this2$props$appConfi !== void 0 ? _this2$props$appConfi : initialParams.lang) !== null && _ref6 !== void 0 ? _ref6 : config.defaultLocale) !== null && _ref5 !== void 0 ? _ref5 : navigator.language;
322
322
  LocaleUtils.loadLocale(lang, _this2.props.appConfig.defaultLocaleData).then(function (localeData) {
323
323
  StandardApp.store.dispatch(changeLocale(localeData, _this2.props.appConfig.defaultLocaleData));
324
324
  _this2.setState({
@@ -216,7 +216,12 @@ var ThemeList = /*#__PURE__*/function (_React$Component) {
216
216
  className: "theme-item-restricted-overlay"
217
217
  }, /*#__PURE__*/React.createElement(Icon, {
218
218
  icon: "lock"
219
- })), isEmpty(matches) ? null : /*#__PURE__*/React.createElement("div", {
219
+ })), item.hasRestrictedContent ? /*#__PURE__*/React.createElement("div", {
220
+ className: "theme-item-restricted-content",
221
+ title: LocaleUtils.tr("themeswitcher.restrictedcontent")
222
+ }, /*#__PURE__*/React.createElement(Icon, {
223
+ icon: "lock"
224
+ })) : null, isEmpty(matches) ? null : /*#__PURE__*/React.createElement("div", {
220
225
  className: "theme-item-filterinfo-overlay"
221
226
  }, matches.map(function (match) {
222
227
  return /*#__PURE__*/React.createElement("div", {
@@ -586,7 +586,9 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
586
586
  objectTree[child] = _objectSpread(_objectSpread({}, objectTree[child]), {}, {
587
587
  visibility: false
588
588
  });
589
- _this2.objectMap[child].visible = false;
589
+ if (_this2.objectMap[child]) {
590
+ _this2.objectMap[child].visible = false;
591
+ }
590
592
  }
591
593
  });
592
594
  }
@@ -625,10 +627,12 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
625
627
  }
626
628
  var child = objectTree[nodeId];
627
629
  var newVisible = visibility && child.visibility && child.opacity > 0;
628
- var changed = newVisible !== _this2.objectMap[child.objectId].visible;
629
- _this2.objectMap[child.objectId].visible = newVisible;
630
- if (changed) {
631
- _this2.instance.notifyChange(_this2.objectMap[child.objectId]);
630
+ if (_this2.objectMap[child.objectId]) {
631
+ var changed = newVisible !== _this2.objectMap[child.objectId].visible;
632
+ _this2.objectMap[child.objectId].visible = newVisible;
633
+ if (changed) {
634
+ _this2.instance.notifyChange(_this2.objectMap[child.objectId]);
635
+ }
632
636
  }
633
637
  }
634
638
  });
@@ -803,7 +807,7 @@ var Map3D = /*#__PURE__*/function (_React$Component2) {
803
807
  // Collect baselayers
804
808
  var externalLayers = {};
805
809
  var baseLayers = ThemeUtils.createThemeBackgroundLayers(_this2.props.theme.map3d.basemaps || [], _this2.props.themes, null, externalLayers);
806
- baseLayers.push({
810
+ baseLayers.unshift({
807
811
  type: "blank",
808
812
  name: "",
809
813
  title: LocaleUtils.tr("bgswitcher.nobg")
@@ -347,19 +347,21 @@ var FirstPersonControls3D = /*#__PURE__*/function (_Controls) {
347
347
  this.target.y += step * dir.y;
348
348
 
349
349
  // Project overstep onto wall
350
- var tangent = new Vector2(-inter.normal.y, inter.normal.x).normalize();
351
- var slidestep = tangent.dot(dir) * overstep;
352
- if (slidestep < 0) {
353
- tangent.negate();
354
- slidestep *= -1;
350
+ if (inter.normal) {
351
+ var tangent = new Vector2(-inter.normal.y, inter.normal.x).normalize();
352
+ var slidestep = tangent.dot(dir) * overstep;
353
+ if (slidestep < 0) {
354
+ tangent.negate();
355
+ slidestep *= -1;
356
+ }
357
+ raycaster.set(this.target, new Vector3(tangent.x, tangent.y, 0));
358
+ var slideInter = raycaster.intersectObjects(this.sceneContext.collisionObjects, true)[0];
359
+ if (slideInter && slideInter.distance - wallBuffer < slidestep) {
360
+ slidestep = slideInter.distance - wallBuffer;
361
+ }
362
+ this.target.x += slidestep * tangent.x;
363
+ this.target.y += slidestep * tangent.y;
355
364
  }
356
- raycaster.set(this.target, new Vector3(tangent.x, tangent.y, 0));
357
- var slideInter = raycaster.intersectObjects(this.sceneContext.collisionObjects, true)[0];
358
- if (slideInter && slideInter.distance - wallBuffer < slidestep) {
359
- slidestep = slideInter.distance - wallBuffer;
360
- }
361
- this.target.x += slidestep * tangent.x;
362
- this.target.y += slidestep * tangent.y;
363
365
  } else {
364
366
  this.target.x += step * dir.x;
365
367
  this.target.y += step * dir.y;
@@ -1,10 +1,6 @@
1
1
  div.SearchBox {
2
2
  position: relative;
3
3
  display: flex;
4
- height: 2em;
5
- background-color: var(--input-bg-color);
6
- color: var(--text-color);
7
- border-radius: var(--border-radius);
8
4
  }
9
5
 
10
6
  div.searchbox-field {
@@ -200,3 +200,11 @@ div.ThemeList div.theme-item-restricted-overlay {
200
200
  justify-content: center;
201
201
  font-size: 400%;
202
202
  }
203
+
204
+ div.ThemeList div.theme-item-restricted-content {
205
+ position: absolute;
206
+ right: 0;
207
+ top: 0;
208
+ opacity: .5;
209
+ padding: 0.25em;
210
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "qwc2",
3
- "version": "2026.05.28",
3
+ "version": "2026.06.03",
4
4
  "description": "QGIS Web Client",
5
5
  "author": "Sourcepole AG",
6
6
  "license": "BSD-2-Clause",
@@ -395,7 +395,7 @@ var selector = function selector(state) {
395
395
  var backgroundLayers = Object.values(state.layers.flat.filter(function (layer) {
396
396
  return layer.role === LayerRole.BACKGROUND;
397
397
  }).reduce(function (res, l) {
398
- return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, l.group || l.name, l.group ? [].concat(_toConsumableArray(res[l.group] || []), [l]) : l));
398
+ return _objectSpread(_objectSpread({}, res), {}, _defineProperty({}, "_" + (l.group || l.name), l.group ? [].concat(_toConsumableArray(res["_" + l.group] || []), [l]) : l));
399
399
  }, {}));
400
400
  return {
401
401
  backgroundLayers: backgroundLayers
@@ -76,6 +76,11 @@ var Bookmark = /*#__PURE__*/function (_React$Component) {
76
76
  });
77
77
  }
78
78
  });
79
+ _defineProperty(_this, "bookmarkDoubleClicked", function (ev, bookmark) {
80
+ if (!_this.state.renameBookmark) {
81
+ _this.open(bookmark.key, false);
82
+ }
83
+ });
79
84
  _defineProperty(_this, "updateBookmarkName", function (text) {
80
85
  _this.setState({
81
86
  busy: true
@@ -284,8 +289,8 @@ var Bookmark = /*#__PURE__*/function (_React$Component) {
284
289
  onClick: function onClick(ev) {
285
290
  return _this2.bookmarkClicked(ev, bookmark);
286
291
  },
287
- onDoubleClick: function onDoubleClick() {
288
- return _this2.open(bookmark.key, false);
292
+ onDoubleClick: function onDoubleClick(ev) {
293
+ return _this2.bookmarkDoubleClicked(ev, bookmark);
289
294
  },
290
295
  title: lastUpdateTitle + ": " + bookmark.date
291
296
  }, _this2.state.renameBookmark === bookmark.key ? /*#__PURE__*/React.createElement(InputContainer, null, /*#__PURE__*/React.createElement(TextInput, {
@@ -392,7 +392,8 @@ var Editing = /*#__PURE__*/function (_React$Component) {
392
392
  value = !['0', 'false'].includes(String(value).toLowerCase());
393
393
  } else if (field.type === 'date') {
394
394
  if (typeof value === 'string') {
395
- value = dateParser.fromString(value).toISOString();
395
+ var _dateParser$fromStrin, _dateParser$fromStrin2, _dateParser$fromStrin3;
396
+ value = (_dateParser$fromStrin = (_dateParser$fromStrin2 = dateParser.fromString(value)) === null || _dateParser$fromStrin2 === void 0 || (_dateParser$fromStrin3 = _dateParser$fromStrin2.toISOString) === null || _dateParser$fromStrin3 === void 0 ? void 0 : _dateParser$fromStrin3.call(_dateParser$fromStrin2)) !== null && _dateParser$fromStrin !== void 0 ? _dateParser$fromStrin : null;
396
397
  }
397
398
  } else if (field.type === 'list') {
398
399
  // Not supported
@@ -23,8 +23,11 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
23
23
  import React from 'react';
24
24
  import { connect } from 'react-redux';
25
25
  import PropTypes from 'prop-types';
26
- import { setBottombarHeight } from '../../actions/windows';
26
+ import { ViewMode } from '../../actions/display';
27
+ import { openExternalUrl, setBottombarHeight } from '../../actions/windows';
28
+ import ConfigUtils from '../../utils/ConfigUtils';
27
29
  import CoordinatesUtils from '../../utils/CoordinatesUtils';
30
+ import LocaleUtils from '../../utils/LocaleUtils';
28
31
  import './style/BottomBar3D.css';
29
32
 
30
33
  /**
@@ -42,6 +45,28 @@ var BottomBar3D = /*#__PURE__*/function (_React$Component) {
42
45
  cursorPosition: null,
43
46
  progress: 0
44
47
  });
48
+ _defineProperty(_this, "renderLink", function (entry) {
49
+ var _entry$labelMsgId;
50
+ return /*#__PURE__*/React.createElement("a", {
51
+ href: entry.url,
52
+ key: (_entry$labelMsgId = entry.labelMsgId) !== null && _entry$labelMsgId !== void 0 ? _entry$labelMsgId : entry.label,
53
+ onClick: function onClick(ev) {
54
+ return _this.openUrl(ev, entry.url, entry.urlTarget, entry.labelMsgId ? LocaleUtils.tr(entry.labelMsgId) : entry.label, entry.icon);
55
+ }
56
+ }, /*#__PURE__*/React.createElement("span", {
57
+ className: "extra_label"
58
+ }, entry.labelMsgId ? LocaleUtils.tr(entry.labelMsgId) : entry.label));
59
+ });
60
+ _defineProperty(_this, "openUrl", function (ev, url, target, title, icon) {
61
+ if (target === "iframe") {
62
+ target = ":iframedialog:externallinkiframe";
63
+ }
64
+ _this.props.openExternalUrl(url, target, {
65
+ title: title,
66
+ icon: icon
67
+ });
68
+ ev.preventDefault();
69
+ });
45
70
  _defineProperty(_this, "scheduleGetCursorPosition", function (ev) {
46
71
  var rect = ev.currentTarget.getBoundingClientRect();
47
72
  var x = (ev.clientX - rect.left) / rect.width * 2 - 1;
@@ -87,6 +112,47 @@ var BottomBar3D = /*#__PURE__*/function (_React$Component) {
87
112
  }, {
88
113
  key: "render",
89
114
  value: function render() {
115
+ var _ConfigUtils$getPlugi, _ConfigUtils$getPlugi2;
116
+ if (this.props.fullscreen) {
117
+ return null;
118
+ }
119
+ var bottomBarConfig = (_ConfigUtils$getPlugi = (_ConfigUtils$getPlugi2 = ConfigUtils.getPluginConfig("BottomBar")) === null || _ConfigUtils$getPlugi2 === void 0 ? void 0 : _ConfigUtils$getPlugi2.cfg) !== null && _ConfigUtils$getPlugi !== void 0 ? _ConfigUtils$getPlugi : {};
120
+ var leftBottomLinks = (bottomBarConfig.additionalBottomBarLinks || []).filter(function (entry) {
121
+ return entry.side === "left";
122
+ }).map(this.renderLink);
123
+ var rightBottomLinks = (bottomBarConfig.additionalBottomBarLinks || []).filter(function (entry) {
124
+ return entry.side !== "left";
125
+ }).map(this.renderLink);
126
+ if (bottomBarConfig.viewertitleUrl) {
127
+ var entry = {
128
+ url: bottomBarConfig.viewertitleUrl,
129
+ urlTarget: bottomBarConfig.viewertitleUrlTarget,
130
+ label: LocaleUtils.tr("bottombar.viewertitle_label"),
131
+ icon: bottomBarConfig.viewertitleUrlIcon
132
+ };
133
+ rightBottomLinks.push(this.renderLink(entry));
134
+ }
135
+ if (bottomBarConfig.termsUrl) {
136
+ var _entry = {
137
+ url: bottomBarConfig.termsUrl,
138
+ urlTarget: bottomBarConfig.termsUrlTarget,
139
+ label: LocaleUtils.tr("bottombar.terms_label"),
140
+ icon: bottomBarConfig.termsUrlIcon
141
+ };
142
+ rightBottomLinks.push(this.renderLink(_entry));
143
+ }
144
+ var position = null;
145
+ var projection = null;
146
+ if (this.props.displayCoordinates) {
147
+ position = /*#__PURE__*/React.createElement("div", {
148
+ className: "map3d-bottombar-position"
149
+ }, (this.state.cursorPosition || []).map(function (x) {
150
+ return x.toFixed(0);
151
+ }).join(" "));
152
+ projection = /*#__PURE__*/React.createElement("div", {
153
+ className: "map3d-bottombar-projection"
154
+ }, this.props.sceneContext.mapCrs ? CoordinatesUtils.getAvailableCRS()[this.props.sceneContext.mapCrs].label : "");
155
+ }
90
156
  return /*#__PURE__*/React.createElement("div", {
91
157
  className: "map3d-bottombar",
92
158
  ref: this.storeHeight
@@ -99,26 +165,37 @@ var BottomBar3D = /*#__PURE__*/function (_React$Component) {
99
165
  }
100
166
  }), /*#__PURE__*/React.createElement("div", {
101
167
  className: "map3d-bottombar-progress-label"
102
- }, this.state.progress)), /*#__PURE__*/React.createElement("div", {
168
+ }, this.state.progress)), this.props.viewMode === ViewMode._3DFullscreen ? /*#__PURE__*/React.createElement("span", {
169
+ className: "bottombar-links"
170
+ }, leftBottomLinks) : null, /*#__PURE__*/React.createElement("div", {
103
171
  className: "map3d-bottombar-spacer"
104
- }), /*#__PURE__*/React.createElement("div", {
105
- className: "map3d-bottombar-position"
106
- }, (this.state.cursorPosition || []).map(function (x) {
107
- return x.toFixed(0);
108
- }).join(" ")), /*#__PURE__*/React.createElement("div", {
109
- className: "map3d-bottombar-projection"
110
- }, this.props.sceneContext.mapCrs ? CoordinatesUtils.getAvailableCRS()[this.props.sceneContext.mapCrs].label : ""), /*#__PURE__*/React.createElement("div", {
172
+ }), position, projection, /*#__PURE__*/React.createElement("div", {
111
173
  className: "map3d-bottombar-spacer"
112
- }));
174
+ }), this.props.viewMode === ViewMode._3DFullscreen ? /*#__PURE__*/React.createElement("span", {
175
+ className: "bottombar-links"
176
+ }, rightBottomLinks) : null);
113
177
  }
114
178
  }]);
115
179
  }(React.Component);
116
180
  _defineProperty(BottomBar3D, "propTypes", {
181
+ /** Whether to display the coordinates in the bottom bar. */
182
+ displayCoordinates: PropTypes.bool,
183
+ fullscreen: PropTypes.bool,
184
+ openExternalUrl: PropTypes.func,
117
185
  sceneContext: PropTypes.object,
118
- setBottombarHeight: PropTypes.func
186
+ setBottombarHeight: PropTypes.func,
187
+ viewMode: PropTypes.number
188
+ });
189
+ _defineProperty(BottomBar3D, "defaultProps", {
190
+ displayCoordinates: true
119
191
  });
120
- export default connect(function () {
121
- return {};
192
+ export default connect(function (state) {
193
+ var _state$display, _state$display2;
194
+ return {
195
+ fullscreen: (_state$display = state.display) === null || _state$display === void 0 ? void 0 : _state$display.fullscreen,
196
+ viewMode: (_state$display2 = state.display) === null || _state$display2 === void 0 ? void 0 : _state$display2.viewMode
197
+ };
122
198
  }, {
199
+ openExternalUrl: openExternalUrl,
123
200
  setBottombarHeight: setBottombarHeight
124
201
  })(BottomBar3D);
@@ -341,8 +341,9 @@ var LayerTree3D = /*#__PURE__*/function (_React$Component) {
341
341
  return /*#__PURE__*/React.createElement(SideBar, {
342
342
  icon: "layers",
343
343
  id: "LayerTree3D",
344
+ side: this.props.side,
344
345
  title: LocaleUtils.tr("appmenu.items.LayerTree3D"),
345
- width: "20em"
346
+ width: this.state.sidebarwidth || this.props.width
346
347
  }, function () {
347
348
  return {
348
349
  body: _this2.renderBody()
@@ -357,10 +358,16 @@ _defineProperty(LayerTree3D, "propTypes", {
357
358
  /** Base URL of imported tile sets. */
358
359
  importedTilesBaseUrl: PropTypes.string,
359
360
  sceneContext: PropTypes.object,
360
- setCurrentTask: PropTypes.func
361
+ setCurrentTask: PropTypes.func,
362
+ /** The side of the application on which to display the sidebar. */
363
+ side: PropTypes.string,
364
+ /** The initial width of the layertree, as a CSS width string. */
365
+ width: PropTypes.string
361
366
  });
362
367
  _defineProperty(LayerTree3D, "defaultProps", {
363
- importedTilesBaseUrl: ':/'
368
+ importedTilesBaseUrl: ':/',
369
+ side: 'right',
370
+ width: '25em'
364
371
  });
365
372
  export default connect(function (state) {
366
373
  return {};
@@ -39,7 +39,7 @@ import LocaleUtils from '../../utils/LocaleUtils';
39
39
  import ThemeUtils from '../../utils/ThemeUtils';
40
40
 
41
41
  /**
42
- * Bottom bar of the 3D map, including the search bar, tool bar and menu.
42
+ * Top bar of the 3D map, including the search bar, tool bar and menu.
43
43
  */
44
44
  var TopBar3D = /*#__PURE__*/function (_React$Component) {
45
45
  function TopBar3D() {
@@ -64,4 +64,10 @@ div.map3d-bottombar-projection {
64
64
  background-color: var(--input-bg-color);
65
65
  padding: 0.25em 0.5em;
66
66
  height: 2em;
67
+ }
68
+
69
+ div.map3d-bottombar span.bottombar-links > a:not(:first-child) {
70
+ border-left: 1px solid var(--panel-text-color);
71
+ margin-left: 0.5em;
72
+ padding-left: 0.5em;
67
73
  }
@@ -2,6 +2,9 @@
2
2
  #BottomBar span.bottombar-links {
3
3
  margin-right: 3em;
4
4
  }
5
+ div.map3d-bottombar span.bottombar-links {
6
+ margin-right: 3em;
7
+ }
5
8
 
6
9
  div.overview-map {
7
10
  position: absolute;
@@ -813,6 +813,7 @@
813
813
  "title": "Заглавие"
814
814
  },
815
815
  "openintab": "Отваряне в раздел",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Нямате право да разглеждате темата или не сте влезли в системата"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Títol"
814
814
  },
815
815
  "openintab": "Obrir en pestaña",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Vostè no te permisos per veure el tema o no està connectat"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Název"
814
814
  },
815
815
  "openintab": "Otevřít v novém okně",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": ""
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Titel"
814
814
  },
815
815
  "openintab": "In Tab öffnen",
816
+ "restrictedcontent": "Theme mit Inhalten, die auf authentifizierte Benutzer beschränkt sind",
816
817
  "restrictedthemeinfo": "Sie sind nicht berechtigt oder sind nicht angemeldet"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Titel"
814
814
  },
815
815
  "openintab": "In Tab öffnen",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Sie sind nicht berechtigt oder sind nicht angemeldet"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Title"
814
814
  },
815
815
  "openintab": "Open in Tab",
816
+ "restrictedcontent": "Theme with content restricted to logged-in users",
816
817
  "restrictedthemeinfo": "You are not permitted to view the theme or not logged in"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Título"
814
814
  },
815
815
  "openintab": "Abrir en pestaña",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Ud. no tiene permitido ver el tema o no está conectado"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Otsikko"
814
814
  },
815
815
  "openintab": "Avaa välilehdellä",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Teeman tarkasteluun ei ole oikeuksia tai et ole kirjautunut sisään"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Titre"
814
814
  },
815
815
  "openintab": "Ouvrir dans l'onglet",
816
+ "restrictedcontent": "Thème avec contenu réservé aux utilisateurs authentifiés",
816
817
  "restrictedthemeinfo": "Vous n'êtes pas autorisé à voir le thème ou vous n'êtes pas connecté"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": ""
814
814
  },
815
815
  "openintab": "",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": ""
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Titolo"
814
814
  },
815
815
  "openintab": "Apri in nuova scheda",
816
+ "restrictedcontent": "Tema con contenuti riservati agli utenti autenticati",
816
817
  "restrictedthemeinfo": "Non sei autorizzato a visualizzare il tema oppure non hai effettuato il login"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "タイトル"
814
814
  },
815
815
  "openintab": "タブで開く",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "テーマを閲覧する権限がありません。ログインして下さい。"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Titel"
814
814
  },
815
815
  "openintab": "Openen in tabblad",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Je hebt geen toestemming om de kaart te bekijken of bent niet ingelogd"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Tittel"
814
814
  },
815
815
  "openintab": "Åpne i nytt vindu",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": ""
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": ""
814
814
  },
815
815
  "openintab": "",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": ""
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Título"
814
814
  },
815
815
  "openintab": "Aberto em separador",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Não está autorizado a ver o tema ou a iniciar sessão"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Título"
814
814
  },
815
815
  "openintab": "Abrir em Aba",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Não está autorizado a ver o tema ou não iniciou sessão"
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Titlu"
814
814
  },
815
815
  "openintab": "Deschide în pagină nouă",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Nu aveți permisiunea de a accesa tema sau nu sunteți logat."
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": ""
814
814
  },
815
815
  "openintab": "",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": ""
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": ""
814
814
  },
815
815
  "openintab": "",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": ""
817
818
  },
818
819
  "timemanager": {
@@ -813,6 +813,7 @@
813
813
  "title": "Başlık"
814
814
  },
815
815
  "openintab": "Sekmede aç",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": "Bu temayı görmeye yetkiniz yok"
817
818
  },
818
819
  "timemanager": {
@@ -694,6 +694,7 @@
694
694
  "themeswitcher.match.keywords",
695
695
  "themeswitcher.match.title",
696
696
  "themeswitcher.openintab",
697
+ "themeswitcher.restrictedcontent",
697
698
  "themeswitcher.restrictedthemeinfo",
698
699
  "timemanager.animationinterval",
699
700
  "timemanager.classify",
@@ -813,6 +813,7 @@
813
813
  "title": ""
814
814
  },
815
815
  "openintab": "",
816
+ "restrictedcontent": "",
816
817
  "restrictedthemeinfo": ""
817
818
  },
818
819
  "timemanager": {