diff --git a/assets/customIcon/SVG/gps_signal_high.svg b/assets/customIcon/SVG/gps_signal_high.svg
new file mode 100644
index 0000000..f218fb8
--- /dev/null
+++ b/assets/customIcon/SVG/gps_signal_high.svg
@@ -0,0 +1,262 @@
+
\ No newline at end of file
diff --git a/assets/customIcon/SVG/gps_signal_low.svg b/assets/customIcon/SVG/gps_signal_low.svg
new file mode 100644
index 0000000..366fade
--- /dev/null
+++ b/assets/customIcon/SVG/gps_signal_low.svg
@@ -0,0 +1,330 @@
+
\ No newline at end of file
diff --git a/assets/customIcon/SVG/gps_signal_middle.svg b/assets/customIcon/SVG/gps_signal_middle.svg
new file mode 100644
index 0000000..d7ec422
--- /dev/null
+++ b/assets/customIcon/SVG/gps_signal_middle.svg
@@ -0,0 +1,223 @@
+
\ No newline at end of file
diff --git a/assets/customIcon/gps_signal.psd b/assets/customIcon/gps_signal.psd
new file mode 100644
index 0000000..f769c9f
Binary files /dev/null and b/assets/customIcon/gps_signal.psd differ
diff --git a/assets/customIcon/gps_signal_high.png b/assets/customIcon/gps_signal_high.png
new file mode 100644
index 0000000..b2ea965
Binary files /dev/null and b/assets/customIcon/gps_signal_high.png differ
diff --git a/assets/customIcon/gps_signal_low.png b/assets/customIcon/gps_signal_low.png
new file mode 100644
index 0000000..104c76f
Binary files /dev/null and b/assets/customIcon/gps_signal_low.png differ
diff --git a/assets/customIcon/gps_signal_middle.png b/assets/customIcon/gps_signal_middle.png
new file mode 100644
index 0000000..e206146
Binary files /dev/null and b/assets/customIcon/gps_signal_middle.png differ
diff --git a/assets/customIcon/icomoon-old/Read Me.txt b/assets/customIcon/icomoon-old/Read Me.txt
new file mode 100644
index 0000000..723a49e
--- /dev/null
+++ b/assets/customIcon/icomoon-old/Read Me.txt
@@ -0,0 +1,7 @@
+Open *demo.html* to see a list of all the glyphs in your font along with their codes/ligatures.
+
+To use the generated font in desktop programs, you can install the TTF font. In order to copy the character associated with each icon, refer to the text box at the bottom right corner of each glyph in demo.html. The character inside this text box may be invisible; but it can still be copied. See this guide for more info: https://icomoon.io/docs/#local-fonts
+
+You won't need any of the files located under the *demo-files* directory when including the generated font in your own projects.
+
+You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection.
diff --git a/assets/customIcon/icomoon-old/demo-files/demo.css b/assets/customIcon/icomoon-old/demo-files/demo.css
new file mode 100644
index 0000000..39b8991
--- /dev/null
+++ b/assets/customIcon/icomoon-old/demo-files/demo.css
@@ -0,0 +1,152 @@
+body {
+ padding: 0;
+ margin: 0;
+ font-family: sans-serif;
+ font-size: 1em;
+ line-height: 1.5;
+ color: #555;
+ background: #fff;
+}
+h1 {
+ font-size: 1.5em;
+ font-weight: normal;
+}
+small {
+ font-size: .66666667em;
+}
+a {
+ color: #e74c3c;
+ text-decoration: none;
+}
+a:hover, a:focus {
+ box-shadow: 0 1px #e74c3c;
+}
+.bshadow0, input {
+ box-shadow: inset 0 -2px #e7e7e7;
+}
+input:hover {
+ box-shadow: inset 0 -2px #ccc;
+}
+input, fieldset {
+ font-family: sans-serif;
+ font-size: 1em;
+ margin: 0;
+ padding: 0;
+ border: 0;
+}
+input {
+ color: inherit;
+ line-height: 1.5;
+ height: 1.5em;
+ padding: .25em 0;
+}
+input:focus {
+ outline: none;
+ box-shadow: inset 0 -2px #449fdb;
+}
+.glyph {
+ font-size: 16px;
+ width: 15em;
+ padding-bottom: 1em;
+ margin-right: 4em;
+ margin-bottom: 1em;
+ float: left;
+ overflow: hidden;
+}
+.liga {
+ width: 80%;
+ width: calc(100% - 2.5em);
+}
+.talign-right {
+ text-align: right;
+}
+.talign-center {
+ text-align: center;
+}
+.bgc1 {
+ background: #f1f1f1;
+}
+.fgc1 {
+ color: #999;
+}
+.fgc0 {
+ color: #000;
+}
+p {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+.mvm {
+ margin-top: .75em;
+ margin-bottom: .75em;
+}
+.mtn {
+ margin-top: 0;
+}
+.mtl, .mal {
+ margin-top: 1.5em;
+}
+.mbl, .mal {
+ margin-bottom: 1.5em;
+}
+.mal, .mhl {
+ margin-left: 1.5em;
+ margin-right: 1.5em;
+}
+.mhmm {
+ margin-left: 1em;
+ margin-right: 1em;
+}
+.mls {
+ margin-left: .25em;
+}
+.ptl {
+ padding-top: 1.5em;
+}
+.pbs, .pvs {
+ padding-bottom: .25em;
+}
+.pvs, .pts {
+ padding-top: .25em;
+}
+.unit {
+ float: left;
+}
+.unitRight {
+ float: right;
+}
+.size1of2 {
+ width: 50%;
+}
+.size1of1 {
+ width: 100%;
+}
+.clearfix:before, .clearfix:after {
+ content: " ";
+ display: table;
+}
+.clearfix:after {
+ clear: both;
+}
+.hidden-true {
+ display: none;
+}
+.textbox0 {
+ width: 3em;
+ background: #f1f1f1;
+ padding: .25em .5em;
+ line-height: 1.5;
+ height: 1.5em;
+}
+#testDrive {
+ display: block;
+ padding-top: 24px;
+ line-height: 1.5;
+}
+.fs0 {
+ font-size: 16px;
+}
+.fs1 {
+ font-size: 32px;
+}
+
diff --git a/assets/customIcon/icomoon-old/demo-files/demo.js b/assets/customIcon/icomoon-old/demo-files/demo.js
new file mode 100644
index 0000000..6f45f1c
--- /dev/null
+++ b/assets/customIcon/icomoon-old/demo-files/demo.js
@@ -0,0 +1,30 @@
+if (!('boxShadow' in document.body.style)) {
+ document.body.setAttribute('class', 'noBoxShadow');
+}
+
+document.body.addEventListener("click", function(e) {
+ var target = e.target;
+ if (target.tagName === "INPUT" &&
+ target.getAttribute('class').indexOf('liga') === -1) {
+ target.select();
+ }
+});
+
+(function() {
+ var fontSize = document.getElementById('fontSize'),
+ testDrive = document.getElementById('testDrive'),
+ testText = document.getElementById('testText');
+ function updateTest() {
+ testDrive.innerHTML = testText.value || String.fromCharCode(160);
+ if (window.icomoonLiga) {
+ window.icomoonLiga(testDrive);
+ }
+ }
+ function updateSize() {
+ testDrive.style.fontSize = fontSize.value + 'px';
+ }
+ fontSize.addEventListener('change', updateSize, false);
+ testText.addEventListener('input', updateTest, false);
+ testText.addEventListener('change', updateTest, false);
+ updateSize();
+}());
diff --git a/assets/customIcon/icomoon-old/demo.html b/assets/customIcon/icomoon-old/demo.html
new file mode 100644
index 0000000..edf3669
--- /dev/null
+++ b/assets/customIcon/icomoon-old/demo.html
@@ -0,0 +1,80 @@
+
+
+
+
+ IcoMoon Demo
+
+
+
+
+
+
+
Font Name: icomoon (Glyphs: 3)
+
+
+
Grid Size: Unknown
+
+
+
+
+
+
+
+
Font Test Drive
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/customIcon/icomoon-old/fonts/icomoon.eot b/assets/customIcon/icomoon-old/fonts/icomoon.eot
new file mode 100644
index 0000000..74b0f40
Binary files /dev/null and b/assets/customIcon/icomoon-old/fonts/icomoon.eot differ
diff --git a/assets/customIcon/icomoon-old/fonts/icomoon.svg b/assets/customIcon/icomoon-old/fonts/icomoon.svg
new file mode 100644
index 0000000..02cb400
--- /dev/null
+++ b/assets/customIcon/icomoon-old/fonts/icomoon.svg
@@ -0,0 +1,39 @@
+
+
+
\ No newline at end of file
diff --git a/assets/customIcon/icomoon-old/fonts/icomoon.woff b/assets/customIcon/icomoon-old/fonts/icomoon.woff
new file mode 100644
index 0000000..351d4f9
Binary files /dev/null and b/assets/customIcon/icomoon-old/fonts/icomoon.woff differ
diff --git a/assets/customIcon/icomoon-old/selection.json b/assets/customIcon/icomoon-old/selection.json
new file mode 100644
index 0000000..ceea3de
--- /dev/null
+++ b/assets/customIcon/icomoon-old/selection.json
@@ -0,0 +1 @@
+{"IcoMoonType":"selection","icons":[{"icon":{"paths":["M476.771 35.229c199.666-13.278 355.46 61.878 467.376 225.468 108.605 206.743 88.252 399.332-61.064 577.761-127.939 124.994-280.599 169.618-457.982 133.872-231.133-67.546-353.261-221.776-366.385-462.679 9.428-217.043 114.333-366.572 314.716-448.587 34.697-10.24 69.143-18.852 103.339-25.835z","M504.954 218.422c110.963-8.694 205.688 25.752 284.183 103.339 4.721 17.168-1.541 28.129-18.789 32.881-30.823-26.775-64.489-49.478-100.991-68.11-81.37-34.44-162.788-34.44-244.257 0-35.044 21.006-68.708 43.709-100.991 68.11-11.273-4.217-18.319-12.046-21.138-23.486 29.204-38.979 66.782-67.945 112.734-86.899 29.725-10.931 59.477-19.542 89.248-25.835z","M514.349 302.972c80.403-7.114 148.513 17.937 204.33 75.156 6.247 23.475-2.367 33.652-25.835 30.532-96.19-87.544-193.264-89.11-291.229-4.697-18.12 11.933-30.646 8.019-37.578-11.743 2.069-12.747 8.332-22.925 18.789-30.532 39.091-31.31 82.932-50.882 131.523-58.716z","M260.697 453.284c184.765-0.783 369.523 0 554.275 2.349 26.431 4.496 44.436 19.371 54.018 44.624 4.462 91.056 2.894 181.873-4.697 272.44-9.131 15.191-22.443 25.365-39.927 30.532-191.023 3.133-382.043 3.133-573.064 0-26.722-3.227-43.163-18.098-49.321-44.624-3.132-84.55-3.132-169.101 0-253.651 8.958-30.138 28.53-47.362 58.716-51.67z","M237.211 467.376c197.291-0.783 394.574 0 591.853 2.349 15.294 7.455 25.473 19.198 30.532 35.229 3.133 84.55 3.133 169.101 0 253.651-6.017 17.554-17.76 29.297-35.229 35.229-192.587 3.133-385.174 3.133-577.761 0-17.469-5.933-29.212-17.676-35.229-35.229-3.132-86.115-3.132-172.234 0-258.349 7.828-11.724 16.439-22.683 25.835-32.881z","M345.248 519.046c28.354-0.658 56.537 0.907 84.55 4.697 0 14.092 0 28.183 0 42.275-4.942 0.7-9.639-0.080-14.092-2.349-12.498-31.307-34.419-40.702-65.761-28.183-25.779 24.083-36.739 53.835-32.881 89.248-3.754 35.765 7.207 65.513 32.881 89.248 49.484 5.209 65.924-15.928 49.321-63.413-4.239-5.641-9.72-9.559-16.44-11.743 20.355-3.133 40.71-3.133 61.064 0-5.643 4.242-9.558 9.719-11.743 16.44-1.566 23.486-3.132 46.972-4.697 70.459-1.566 1.564-3.132 3.133-4.697 4.697-6.167-5.040-13.213-8.173-21.138-9.394-77.32 18.3-116.464-13.016-117.431-93.945-1.181-48.762 19.174-84.776 61.064-108.037z","M472.073 523.743c30.471-5.421 61.788-6.205 93.945-2.349 45.267 6.67 61.708 32.505 49.321 77.505-5.482 18.005-17.225 29.748-35.229 35.229-19.977 0.939-39.551 3.288-58.716 7.046-3.133 21.922-3.133 43.839 0 65.761 5.702 7.276 12.748 12.753 21.138 16.44-23.486 3.133-46.972 3.133-70.459 0 5.068-4.491 10.545-8.403 16.44-11.743 3.133-57.931 3.133-115.867 0-173.798-4.88-5.684-10.362-10.381-16.44-14.092z","M692.844 519.046c27.066-1.649 53.68 0.7 79.853 7.046-4.434 12.772-5.998 26.079-4.697 39.927-4.697 0-9.394 0-14.092 0-7.765-33.707-28.118-43.886-61.064-30.532-18.939 21.626-17.375 41.979 4.697 61.064 22.326 11.546 43.464 24.858 63.413 39.927 24.599 57.264 5.81 88.581-56.367 93.945-17.925-3.791-35.934-6.924-54.018-9.394-0.77-12.622 0.014-25.149 2.349-37.578 1.945-2.147 4.293-3.716 7.046-4.697 6.656 15.285 17.615 27.028 32.881 35.229 43.637 7.619 60.078-10.386 49.321-54.018-22.984-18.277-47.254-34.717-72.807-49.321-24.567-39.56-16.741-70.092 23.486-91.596z","M519.046 533.138c58.077-5.369 79.214 19.681 63.413 75.156-17.779 16.271-38.917 22.537-63.413 18.789 0-31.317 0-62.628 0-93.945z"],"attrs":[{"fill":"rgb(255, 254, 11)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(0, 0, 0)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(254, 255, 0)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(3, 3, 3)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(254, 255, 0)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_middle"],"colorPermutations":{"1101010111111415721312215821312221254255012552541112556537133315551":[{"f":9},{"f":0},{"f":1},{"f":4},{"f":8},{"f":2},{"f":3},{"f":2},{"f":8}]}},"attrs":[{"fill":"rgb(255, 254, 11)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(0, 0, 0)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(254, 255, 0)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(3, 3, 3)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(254, 255, 0)"}],"properties":{"order":2,"id":2,"name":"gps_signal_middle","prevSize":32,"code":59648,"codes":[59648,59649,59650,59651,59652,59653,59654,59655,59656]},"setIdx":0,"setId":2,"iconIdx":0},{"icon":{"paths":["M472.073 16.44c-62.2 9.509-121.698 29.081-178.495 58.716-183.411 111.384-267.179 275.005-251.303 490.862 33.091 203.748 146.608 340.752 340.55 411.009 213.466 56.080 392.746 2.062 537.835-162.055 123.012-171.919 138.667-353.547 46.972-544.881-113.96-181.861-279.148-266.412-495.56-253.651zM669.358 340.55c-67.809-41.065-139.837-48.111-216.073-21.138-25.823 10.547-49.309 24.639-70.459 42.275-14.050 10.059-19.531 23.368-16.44 39.927 3.777 6.128 9.257 9.259 16.44 9.394 24.303-17.197 49.355-33.637 75.156-49.321 62.177-27.915 123.242-25.567 183.193 7.046-26.619 28.183-53.234 56.367-79.853 84.55-100.22-0.783-200.428 0-300.624 2.349-30.974 2.785-50.545 19.226-58.716 49.321-3.132 84.55-3.132 169.101 0 253.651 5.542 11.086 11.023 22.044 16.44 32.881-6.072 8.436-13.118 16.267-21.138 23.486-117.899-133.054-150.78-284.93-98.642-455.633 79.099-195.473 224.714-298.813 436.844-310.018 117.098 2.714 218.089 43.424 302.972 122.128-54.901 58.031-111.268 114.398-169.101 169.101zM260.697 805.578c187.896 0.784 375.785 0 563.67-2.349 26.244-6.384 41.12-22.824 44.624-49.321 3.133-84.55 3.133-169.101 0-253.651-9.582-25.252-27.587-40.128-54.018-44.624-67.307-2.348-134.637-3.131-201.982-2.349 18.789-21.921 39.142-42.275 61.064-61.064 9.254 13.214 21.781 18.694 37.578 16.44 14.026-18.322 10.898-33.196-9.394-44.624 53.135-56.268 107.938-111.070 164.404-164.404 57.809 59.207 96.171 129.666 115.083 211.376 34.623 240.701-56.973 413.715-274.789 519.046-142.665 52.083-280.449 41.12-413.358-32.881-24.842-17.004-48.328-35.793-70.459-56.367 11.913-12.706 24.439-24.449 37.578-35.229zM542.532 472.073c-17.225 15.656-34.445 31.317-51.67 46.972-6.449-0.737-12.715 0.047-18.789 2.349 2.555 3.368 5.688 5.717 9.394 7.046-50.104 53.234-101.774 104.904-155.009 155.009-14.272-44.69-11.923-88.534 7.046-131.523 32.897-33.454 60.297-29.541 82.202 11.743 4.453 2.269 9.15 3.049 14.092 2.349 0-14.092 0-28.183 0-42.275-90.584-23.622-139.122 10.822-145.615 103.339 3.54 15.393 5.889 31.049 7.046 46.972 1.991 11.861 7.471 21.255 16.44 28.183-25.052 28.183-51.67 54.803-79.853 79.853-6.123-6.985-11.603-14.815-16.44-23.486-3.132-86.115-3.132-172.234 0-258.349 6.848-11.555 15.459-21.734 25.835-30.532 102.575-3.896 204.349-3.113 305.321 2.349zM598.899 467.376c76.739-0.783 153.459 0 230.165 2.349 9.977 5.27 18.587 12.316 25.835 21.138 7.647 88.942 9.216 178.19 4.697 267.743-6.017 17.554-17.76 29.297-35.229 35.229-184.752 2.349-369.51 3.133-554.275 2.349 21.921-25.050 45.407-48.537 70.459-70.459 20.407 4.105 40.762 2.541 61.064-4.697 7.925 1.221 14.971 4.354 21.138 9.394 6.026-24.224 9.157-49.274 9.394-75.156 2.185-6.722 6.1-12.199 11.743-16.44-4.453-2.269-9.15-3.049-14.092-2.349 18.789-21.922 39.144-42.275 61.064-61.064 0.78 45.432 0 90.84-2.349 136.22-5.895 3.34-11.372 7.253-16.44 11.743 23.486 3.133 46.972 3.133 70.459 0-8.389-3.687-15.435-9.164-21.138-16.44-3.133-21.922-3.133-43.839 0-65.761 19.165-3.758 38.738-6.106 58.716-7.046 33.999-17.168 45.742-44.567 35.229-82.202-15.665-24.379-38.372-35.342-68.11-32.881 15.656-18.789 32.881-36.014 51.67-51.67zM533.138 533.138c42.172-0.892 60.176 19.461 54.018 61.064-1.625 11.029-7.107 19.639-16.44 25.835-16.722 5.81-33.947 8.159-51.67 7.046 0-26.619 0-53.234 0-79.853 3.133-6.261 7.83-10.959 14.092-14.092zM401.615 664.661c7.172 39.809-10.052 57.034-51.67 51.67 15.657-18.789 32.881-36.014 51.67-51.67z","M669.358 340.55c-7.83 10.96-17.225 20.355-28.183 28.183-59.951-32.613-121.015-34.961-183.193-7.046-25.801 15.684-50.853 32.124-75.156 49.321-7.184-0.135-12.664-3.267-16.44-9.394-3.090-16.559 2.39-29.868 16.44-39.927 21.15-17.636 44.636-31.728 70.459-42.275 76.236-26.973 148.264-19.928 216.073 21.138z","M702.239 364.037c20.292 11.427 23.42 26.302 9.394 44.624-15.797 2.254-28.324-3.227-37.578-16.44 7.83-10.96 17.225-20.355 28.183-28.183z","M561.321 453.284c-4.697 7.829-10.959 14.092-18.789 18.789-100.973-5.462-202.746-6.245-305.321-2.349-10.376 8.798-18.987 18.977-25.835 30.532-3.132 86.115-3.132 172.234 0 258.349 4.837 8.671 10.317 16.501 16.44 23.486-1.566 4.697-4.697 7.83-9.394 9.394-5.418-10.837-10.898-21.795-16.44-32.881-3.132-84.55-3.132-169.101 0-253.651 8.17-30.095 27.742-46.537 58.716-49.321 100.196-2.349 200.404-3.131 300.624-2.349z","M612.991 453.284c67.344-0.783 134.675 0 201.982 2.349 26.431 4.496 44.436 19.371 54.018 44.624 3.133 84.55 3.133 169.101 0 253.651-3.504 26.497-18.38 42.938-44.624 49.321-187.885 2.349-375.773 3.133-563.67 2.349 1.566-4.697 4.697-7.83 9.394-9.394 184.765 0.784 369.523 0 554.275-2.349 17.469-5.933 29.212-17.676 35.229-35.229 4.519-89.553 2.95-178.801-4.697-267.743-7.248-8.821-15.858-15.867-25.835-21.138-76.706-2.348-153.426-3.131-230.165-2.349 3.133-6.263 7.83-10.96 14.092-14.092z","M326.459 683.45c-4.697 7.83-10.96 14.092-18.789 18.789-8.969-6.928-14.45-16.323-16.44-28.183-1.157-15.924-3.506-31.58-7.046-46.972 6.493-92.517 55.031-126.962 145.615-103.339 0 14.092 0 28.183 0 42.275-4.942 0.7-9.639-0.080-14.092-2.349-21.905-41.284-49.305-45.197-82.202-11.743-18.969 42.989-21.318 86.833-7.046 131.523z","M490.862 519.046c-1.564 4.697-4.697 7.83-9.394 9.394-3.706-1.329-6.839-3.678-9.394-7.046 6.074-2.302 12.34-3.086 18.789-2.349z","M547.229 519.046c29.738-2.461 52.445 8.502 68.11 32.881 10.512 37.634-1.231 65.033-35.229 82.202-19.977 0.939-39.551 3.288-58.716 7.046-3.133 21.922-3.133 43.839 0 65.761 5.702 7.276 12.748 12.753 21.138 16.44-23.486 3.133-46.972 3.133-70.459 0 5.068-4.491 10.545-8.403 16.44-11.743 2.349-45.38 3.128-90.788 2.349-136.22 7.83-10.959 17.225-20.353 28.183-28.183 0 26.619 0 53.234 0 79.853 17.723 1.113 34.948-1.235 51.67-7.046 9.333-6.196 14.815-14.806 16.44-25.835 6.158-41.604-11.846-61.957-54.018-61.064 3.133-6.261 7.83-10.959 14.092-14.092z","M692.844 519.046c27.066-1.649 53.68 0.7 79.853 7.046-4.434 12.772-5.998 26.079-4.697 39.927-4.697 0-9.394 0-14.092 0-7.765-33.707-28.118-43.886-61.064-30.532-18.939 21.626-17.375 41.979 4.697 61.064 22.326 11.546 43.464 24.858 63.413 39.927 24.599 57.264 5.81 88.581-56.367 93.945-17.925-3.791-35.934-6.924-54.018-9.394-0.77-12.622 0.014-25.149 2.349-37.578 1.945-2.147 4.293-3.716 7.046-4.697 6.656 15.285 17.615 27.028 32.881 35.229 43.637 7.619 60.078-10.386 49.321-54.018-22.984-18.277-47.254-34.717-72.807-49.321-24.567-39.56-16.741-70.092 23.486-91.596z","M429.798 636.477c4.942-0.7 9.639 0.080 14.092 2.349-5.643 4.242-9.558 9.719-11.743 16.44-0.237 25.882-3.369 50.932-9.394 75.156-6.167-5.040-13.213-8.173-21.138-9.394-20.302 7.238-40.657 8.803-61.064 4.697 1.566-4.697 4.697-7.83 9.394-9.394 41.618 5.364 58.841-11.861 51.67-51.67 7.829-10.959 17.223-20.353 28.183-28.183z"],"attrs":[{"fill":"rgb(255, 65, 37)"},{"fill":"rgb(0, 0, 0)"},{"fill":"rgb(0, 0, 0)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(3, 3, 3)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(3, 3, 3)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(2, 2, 2)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_low"],"colorPermutations":{"1101010111111415721312215821312221254255012552541112556537133315551":[{"f":10},{"f":1},{"f":1},{"f":5},{"f":3},{"f":2},{"f":4},{"f":3},{"f":2},{"f":2}]}},"attrs":[{"fill":"rgb(255, 65, 37)"},{"fill":"rgb(0, 0, 0)"},{"fill":"rgb(0, 0, 0)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(3, 3, 3)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(3, 3, 3)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(2, 2, 2)"}],"properties":{"order":3,"id":1,"name":"gps_signal_low","prevSize":32,"code":59657,"codes":[59657,59658,59659,59660,59661,59662,59663,59664,59665,59666]},"setIdx":0,"setId":2,"iconIdx":1},{"icon":{"paths":["M476.771 30.532c203.992-13.476 361.35 64.811 472.073 234.862 84.55 161.272 84.55 322.546 0 483.817-130.461 195.927-311.305 268.734-542.532 218.422-195.946-64.418-311.029-198.29-345.248-401.615-15.798-232.312 80.496-399.065 288.881-500.257 41.888-15.544 84.163-27.287 126.826-35.229z","M519.046 119.78c131.297-2.777 241.683 42.629 331.156 136.22 3.119 23.469-7.055 32.081-30.532 25.835-147.423-132.183-308.694-150.972-483.817-56.367-22.969 13.877-43.324 31.1-61.064 51.67-30.235 15.35-41.978 6.738-35.229-25.835 77.581-77.549 170.743-121.39 279.486-131.523z","M504.954 218.422c110.963-8.694 205.688 25.752 284.183 103.339 4.721 17.168-1.541 28.129-18.789 32.881-30.823-26.775-64.489-49.478-100.991-68.11-81.37-34.44-162.788-34.44-244.257 0-35.044 21.006-68.708 43.709-100.991 68.11-11.273-4.217-18.319-12.046-21.138-23.486 29.204-38.979 66.782-67.945 112.734-86.899 29.725-10.931 59.477-19.542 89.248-25.835z","M514.349 302.972c80.403-7.114 148.513 17.937 204.33 75.156 6.247 23.475-2.367 33.652-25.835 30.532-96.19-87.544-193.264-89.11-291.229-4.697-18.12 11.933-30.646 8.019-37.578-11.743 2.069-12.747 8.332-22.925 18.789-30.532 39.091-31.31 82.932-50.882 131.523-58.716z","M260.697 453.284c184.765-0.783 369.523 0 554.275 2.349 26.431 4.496 44.436 19.371 54.018 44.624 4.462 91.056 2.894 181.873-4.697 272.44-9.131 15.191-22.443 25.365-39.927 30.532-191.023 3.133-382.043 3.133-573.064 0-26.722-3.227-43.163-18.098-49.321-44.624-3.132-84.55-3.132-169.101 0-253.651 8.958-30.138 28.53-47.362 58.716-51.67z","M237.211 467.376c197.291-0.783 394.574 0 591.853 2.349 15.294 7.455 25.473 19.198 30.532 35.229 3.133 84.55 3.133 169.101 0 253.651-6.017 17.554-17.76 29.297-35.229 35.229-192.587 3.133-385.174 3.133-577.761 0-17.469-5.933-29.212-17.676-35.229-35.229-3.132-86.115-3.132-172.234 0-258.349 7.828-11.724 16.439-22.683 25.835-32.881z","M345.248 519.046c28.354-0.658 56.537 0.907 84.55 4.697 0 14.092 0 28.183 0 42.275-4.942 0.7-9.639-0.080-14.092-2.349-12.498-31.307-34.419-40.702-65.761-28.183-25.779 24.083-36.739 53.835-32.881 89.248-3.754 35.765 7.207 65.513 32.881 89.248 49.484 5.209 65.924-15.928 49.321-63.413-4.239-5.641-9.72-9.559-16.44-11.743 20.355-3.133 40.71-3.133 61.064 0-5.643 4.242-9.558 9.719-11.743 16.44-1.566 23.486-3.132 46.972-4.697 70.459-1.566 1.564-3.132 3.133-4.697 4.697-6.167-5.040-13.213-8.173-21.138-9.394-77.32 18.3-116.464-13.016-117.431-93.945-1.181-48.762 19.174-84.776 61.064-108.037z","M472.073 523.743c30.471-5.421 61.788-6.205 93.945-2.349 45.267 6.67 61.708 32.505 49.321 77.505-5.482 18.005-17.225 29.748-35.229 35.229-19.977 0.939-39.551 3.288-58.716 7.046-3.133 21.922-3.133 43.839 0 65.761 5.702 7.276 12.748 12.753 21.138 16.44-23.486 3.133-46.972 3.133-70.459 0 5.068-4.491 10.545-8.403 16.44-11.743 3.133-57.931 3.133-115.867 0-173.798-4.88-5.684-10.362-10.381-16.44-14.092z","M692.844 519.046c27.066-1.649 53.68 0.7 79.853 7.046-4.434 12.772-5.998 26.079-4.697 39.927-4.697 0-9.394 0-14.092 0-7.765-33.707-28.118-43.886-61.064-30.532-18.939 21.626-17.375 41.979 4.697 61.064 22.326 11.546 43.464 24.858 63.413 39.927 24.599 57.264 5.81 88.581-56.367 93.945-17.925-3.791-35.934-6.924-54.018-9.394-0.77-12.622 0.014-25.149 2.349-37.578 1.945-2.147 4.293-3.716 7.046-4.697 6.656 15.285 17.615 27.028 32.881 35.229 43.637 7.619 60.078-10.386 49.321-54.018-22.984-18.277-47.254-34.717-72.807-49.321-24.567-39.56-16.741-70.092 23.486-91.596z","M519.046 533.138c58.077-5.369 79.214 19.681 63.413 75.156-17.779 16.271-38.917 22.537-63.413 18.789 0-31.317 0-62.628 0-93.945z"],"attrs":[{"fill":"rgb(22, 158, 213)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(0, 0, 0)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(14, 157, 213)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(3, 3, 3)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(14, 157, 213)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_high"],"colorPermutations":{"1101010111111415721312215821312221254255012552541112556537133315551":[{"f":7},{"f":0},{"f":0},{"f":1},{"f":4},{"f":6},{"f":2},{"f":3},{"f":2},{"f":6}]}},"attrs":[{"fill":"rgb(22, 158, 213)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(0, 0, 0)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(14, 157, 213)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(3, 3, 3)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(14, 157, 213)"}],"properties":{"order":4,"id":0,"name":"gps_signal_high","prevSize":32,"code":59667,"codes":[59667,59668,59669,59670,59671,59672,59673,59674,59675,59676]},"setIdx":0,"setId":2,"iconIdx":2}],"height":1024,"metadata":{"name":"icomoon"},"preferences":{"showGlyphs":true,"showQuickUse":true,"showQuickUse2":true,"showSVGs":true,"fontPref":{"prefix":"icon-","metadata":{"fontFamily":"icomoon"},"metrics":{"emSize":1024,"baseline":6.25,"whitespace":50},"embed":false},"imagePref":{"prefix":"icon-","png":true,"useClassSelector":true,"color":0,"bgColor":16777215,"classSelector":".icon"},"historySize":50,"showCodes":false,"gridSize":16,"showLiga":true}}
\ No newline at end of file
diff --git a/assets/customIcon/icomoon-old/style.css b/assets/customIcon/icomoon-old/style.css
new file mode 100644
index 0000000..20b696c
--- /dev/null
+++ b/assets/customIcon/icomoon-old/style.css
@@ -0,0 +1,169 @@
+@font-face {
+ font-family: 'icomoon';
+ src: url('fonts/icomoon.eot?tueyzw');
+ src: url('fonts/icomoon.eot?tueyzw#iefix') format('embedded-opentype'),
+ url('fonts/icomoon.ttf?tueyzw') format('truetype'),
+ url('fonts/icomoon.woff?tueyzw') format('woff'),
+ url('fonts/icomoon.svg?tueyzw#icomoon') format('svg');
+ font-weight: normal;
+ font-style: normal;
+ font-display: block;
+}
+
+[class^="icon-"], [class*=" icon-"] {
+ /* use !important to prevent issues with browser extensions that change fonts */
+ font-family: 'icomoon' !important;
+ speak: never;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-gps_signal_middle .path1:before {
+ content: "\e900";
+ color: rgb(255, 254, 11);
+}
+.icon-gps_signal_middle .path2:before {
+ content: "\e901";
+ margin-left: -1.0458984375em;
+ color: rgb(1, 1, 1);
+}
+.icon-gps_signal_middle .path3:before {
+ content: "\e902";
+ margin-left: -1.0458984375em;
+ color: rgb(0, 0, 0);
+}
+.icon-gps_signal_middle .path4:before {
+ content: "\e903";
+ margin-left: -1.0458984375em;
+ color: rgb(5, 5, 5);
+}
+.icon-gps_signal_middle .path5:before {
+ content: "\e904";
+ margin-left: -1.0458984375em;
+ color: rgb(254, 255, 0);
+}
+.icon-gps_signal_middle .path6:before {
+ content: "\e905";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_middle .path7:before {
+ content: "\e906";
+ margin-left: -1.0458984375em;
+ color: rgb(3, 3, 3);
+}
+.icon-gps_signal_middle .path8:before {
+ content: "\e907";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_middle .path9:before {
+ content: "\e908";
+ margin-left: -1.0458984375em;
+ color: rgb(254, 255, 0);
+}
+.icon-gps_signal_low .path1:before {
+ content: "\e909";
+ color: rgb(255, 65, 37);
+}
+.icon-gps_signal_low .path2:before {
+ content: "\e90a";
+ margin-left: -1.0458984375em;
+ color: rgb(0, 0, 0);
+}
+.icon-gps_signal_low .path3:before {
+ content: "\e90b";
+ margin-left: -1.0458984375em;
+ color: rgb(0, 0, 0);
+}
+.icon-gps_signal_low .path4:before {
+ content: "\e90c";
+ margin-left: -1.0458984375em;
+ color: rgb(10, 10, 10);
+}
+.icon-gps_signal_low .path5:before {
+ content: "\e90d";
+ margin-left: -1.0458984375em;
+ color: rgb(3, 3, 3);
+}
+.icon-gps_signal_low .path6:before {
+ content: "\e90e";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_low .path7:before {
+ content: "\e90f";
+ margin-left: -1.0458984375em;
+ color: rgb(5, 5, 5);
+}
+.icon-gps_signal_low .path8:before {
+ content: "\e910";
+ margin-left: -1.0458984375em;
+ color: rgb(3, 3, 3);
+}
+.icon-gps_signal_low .path9:before {
+ content: "\e911";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_low .path10:before {
+ content: "\e912";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_high .path1:before {
+ content: "\e913";
+ color: rgb(22, 158, 213);
+}
+.icon-gps_signal_high .path2:before {
+ content: "\e914";
+ margin-left: -1.0458984375em;
+ color: rgb(1, 1, 1);
+}
+.icon-gps_signal_high .path3:before {
+ content: "\e915";
+ margin-left: -1.0458984375em;
+ color: rgb(1, 1, 1);
+}
+.icon-gps_signal_high .path4:before {
+ content: "\e916";
+ margin-left: -1.0458984375em;
+ color: rgb(0, 0, 0);
+}
+.icon-gps_signal_high .path5:before {
+ content: "\e917";
+ margin-left: -1.0458984375em;
+ color: rgb(5, 5, 5);
+}
+.icon-gps_signal_high .path6:before {
+ content: "\e918";
+ margin-left: -1.0458984375em;
+ color: rgb(14, 157, 213);
+}
+.icon-gps_signal_high .path7:before {
+ content: "\e919";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_high .path8:before {
+ content: "\e91a";
+ margin-left: -1.0458984375em;
+ color: rgb(3, 3, 3);
+}
+.icon-gps_signal_high .path9:before {
+ content: "\e91b";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_high .path10:before {
+ content: "\e91c";
+ margin-left: -1.0458984375em;
+ color: rgb(14, 157, 213);
+}
diff --git a/assets/customIcon/icomoon.zip b/assets/customIcon/icomoon.zip
new file mode 100644
index 0000000..f09032b
Binary files /dev/null and b/assets/customIcon/icomoon.zip differ
diff --git a/assets/customIcon/icomoon/Read Me.txt b/assets/customIcon/icomoon/Read Me.txt
new file mode 100644
index 0000000..723a49e
--- /dev/null
+++ b/assets/customIcon/icomoon/Read Me.txt
@@ -0,0 +1,7 @@
+Open *demo.html* to see a list of all the glyphs in your font along with their codes/ligatures.
+
+To use the generated font in desktop programs, you can install the TTF font. In order to copy the character associated with each icon, refer to the text box at the bottom right corner of each glyph in demo.html. The character inside this text box may be invisible; but it can still be copied. See this guide for more info: https://icomoon.io/docs/#local-fonts
+
+You won't need any of the files located under the *demo-files* directory when including the generated font in your own projects.
+
+You can import *selection.json* back to the IcoMoon app using the *Import Icons* button (or via Main Menu → Manage Projects) to retrieve your icon selection.
diff --git a/assets/customIcon/icomoon/demo-files/demo.css b/assets/customIcon/icomoon/demo-files/demo.css
new file mode 100644
index 0000000..39b8991
--- /dev/null
+++ b/assets/customIcon/icomoon/demo-files/demo.css
@@ -0,0 +1,152 @@
+body {
+ padding: 0;
+ margin: 0;
+ font-family: sans-serif;
+ font-size: 1em;
+ line-height: 1.5;
+ color: #555;
+ background: #fff;
+}
+h1 {
+ font-size: 1.5em;
+ font-weight: normal;
+}
+small {
+ font-size: .66666667em;
+}
+a {
+ color: #e74c3c;
+ text-decoration: none;
+}
+a:hover, a:focus {
+ box-shadow: 0 1px #e74c3c;
+}
+.bshadow0, input {
+ box-shadow: inset 0 -2px #e7e7e7;
+}
+input:hover {
+ box-shadow: inset 0 -2px #ccc;
+}
+input, fieldset {
+ font-family: sans-serif;
+ font-size: 1em;
+ margin: 0;
+ padding: 0;
+ border: 0;
+}
+input {
+ color: inherit;
+ line-height: 1.5;
+ height: 1.5em;
+ padding: .25em 0;
+}
+input:focus {
+ outline: none;
+ box-shadow: inset 0 -2px #449fdb;
+}
+.glyph {
+ font-size: 16px;
+ width: 15em;
+ padding-bottom: 1em;
+ margin-right: 4em;
+ margin-bottom: 1em;
+ float: left;
+ overflow: hidden;
+}
+.liga {
+ width: 80%;
+ width: calc(100% - 2.5em);
+}
+.talign-right {
+ text-align: right;
+}
+.talign-center {
+ text-align: center;
+}
+.bgc1 {
+ background: #f1f1f1;
+}
+.fgc1 {
+ color: #999;
+}
+.fgc0 {
+ color: #000;
+}
+p {
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+.mvm {
+ margin-top: .75em;
+ margin-bottom: .75em;
+}
+.mtn {
+ margin-top: 0;
+}
+.mtl, .mal {
+ margin-top: 1.5em;
+}
+.mbl, .mal {
+ margin-bottom: 1.5em;
+}
+.mal, .mhl {
+ margin-left: 1.5em;
+ margin-right: 1.5em;
+}
+.mhmm {
+ margin-left: 1em;
+ margin-right: 1em;
+}
+.mls {
+ margin-left: .25em;
+}
+.ptl {
+ padding-top: 1.5em;
+}
+.pbs, .pvs {
+ padding-bottom: .25em;
+}
+.pvs, .pts {
+ padding-top: .25em;
+}
+.unit {
+ float: left;
+}
+.unitRight {
+ float: right;
+}
+.size1of2 {
+ width: 50%;
+}
+.size1of1 {
+ width: 100%;
+}
+.clearfix:before, .clearfix:after {
+ content: " ";
+ display: table;
+}
+.clearfix:after {
+ clear: both;
+}
+.hidden-true {
+ display: none;
+}
+.textbox0 {
+ width: 3em;
+ background: #f1f1f1;
+ padding: .25em .5em;
+ line-height: 1.5;
+ height: 1.5em;
+}
+#testDrive {
+ display: block;
+ padding-top: 24px;
+ line-height: 1.5;
+}
+.fs0 {
+ font-size: 16px;
+}
+.fs1 {
+ font-size: 32px;
+}
+
diff --git a/assets/customIcon/icomoon/demo-files/demo.js b/assets/customIcon/icomoon/demo-files/demo.js
new file mode 100644
index 0000000..6f45f1c
--- /dev/null
+++ b/assets/customIcon/icomoon/demo-files/demo.js
@@ -0,0 +1,30 @@
+if (!('boxShadow' in document.body.style)) {
+ document.body.setAttribute('class', 'noBoxShadow');
+}
+
+document.body.addEventListener("click", function(e) {
+ var target = e.target;
+ if (target.tagName === "INPUT" &&
+ target.getAttribute('class').indexOf('liga') === -1) {
+ target.select();
+ }
+});
+
+(function() {
+ var fontSize = document.getElementById('fontSize'),
+ testDrive = document.getElementById('testDrive'),
+ testText = document.getElementById('testText');
+ function updateTest() {
+ testDrive.innerHTML = testText.value || String.fromCharCode(160);
+ if (window.icomoonLiga) {
+ window.icomoonLiga(testDrive);
+ }
+ }
+ function updateSize() {
+ testDrive.style.fontSize = fontSize.value + 'px';
+ }
+ fontSize.addEventListener('change', updateSize, false);
+ testText.addEventListener('input', updateTest, false);
+ testText.addEventListener('change', updateTest, false);
+ updateSize();
+}());
diff --git a/assets/customIcon/icomoon/demo.html b/assets/customIcon/icomoon/demo.html
new file mode 100644
index 0000000..81d22fa
--- /dev/null
+++ b/assets/customIcon/icomoon/demo.html
@@ -0,0 +1,80 @@
+
+
+
+
+ IcoMoon Demo
+
+
+
+
+
+
+
Font Name: icomoon (Glyphs: 3)
+
+
+
Grid Size: Unknown
+
+
+
+
+
+
+
+
Font Test Drive
+
+
+
+
+
+
+
+
+
+
+
diff --git a/assets/customIcon/icomoon/fonts/icomoon.eot b/assets/customIcon/icomoon/fonts/icomoon.eot
new file mode 100644
index 0000000..ef25f06
Binary files /dev/null and b/assets/customIcon/icomoon/fonts/icomoon.eot differ
diff --git a/assets/customIcon/icomoon/fonts/icomoon.svg b/assets/customIcon/icomoon/fonts/icomoon.svg
new file mode 100644
index 0000000..aeaaed4
--- /dev/null
+++ b/assets/customIcon/icomoon/fonts/icomoon.svg
@@ -0,0 +1,50 @@
+
+
+
\ No newline at end of file
diff --git a/assets/customIcon/icomoon/fonts/icomoon.ttf b/assets/customIcon/icomoon/fonts/icomoon.ttf
new file mode 100644
index 0000000..f2e8bb4
Binary files /dev/null and b/assets/customIcon/icomoon/fonts/icomoon.ttf differ
diff --git a/assets/customIcon/icomoon/fonts/icomoon.woff b/assets/customIcon/icomoon/fonts/icomoon.woff
new file mode 100644
index 0000000..4ed8b4e
Binary files /dev/null and b/assets/customIcon/icomoon/fonts/icomoon.woff differ
diff --git a/assets/customIcon/icomoon/selection.json b/assets/customIcon/icomoon/selection.json
new file mode 100644
index 0000000..de89dcd
--- /dev/null
+++ b/assets/customIcon/icomoon/selection.json
@@ -0,0 +1 @@
+{"IcoMoonType":"selection","icons":[{"icon":{"paths":["M4.697 371.083c0-123.694 0-245.040 0-366.385 356.991-0 713.982-0 1070.972-0 0 341.333 0 682.667 0 1024-356.991 0-713.982 0-1070.972 0-0-218.422-0-436.844-0-657.615zM54.676 595.488c8.121 29.927 13.467 60.954 24.814 89.603 73.114 184.603 210.166 292.309 405.758 315.852 266.402 32.066 503.041-151.136 541.779-416.589 26.568-182.062-36.314-334.611-177.010-450.896-110.474-91.306-241.173-124.942-383.508-103.957-127.29 18.767-232.431 79.646-312.212 180.371-88.664 111.94-121.433 240.139-99.62 385.616z","M54.001 593.523c-21.138-143.512 11.63-271.711 100.295-383.651 79.781-100.726 184.922-161.605 312.212-180.371 142.335-20.985 273.035 12.651 383.508 103.957 140.696 116.285 203.578 268.833 177.010 450.896-38.737 265.453-275.376 448.655-541.779 416.589-195.592-23.543-332.644-131.249-405.758-315.852-11.347-28.649-16.693-59.676-25.488-91.568zM493.216 582.955c0 0-1.199 1.237-4.108 3.501-15.138 15.638-30.275 31.276-47.497 49.623-6.517 6.27-13.034 12.539-22.199 19.893-20.165 20.664-40.33 41.329-62.409 64.715-4.767 4.63-9.535 9.261-17.027 14.967-17.098 17.578-34.196 35.156-53.412 55.506-3.397 3.166-6.794 6.333-12.766 10.681-15.251 15.398-30.503 30.797-45.735 46.176 161.781 159.584 456.337 177.301 643.164-16.003 193.416-200.12 149.585-488.401 5.346-626.396-56.661 54.941-113.278 109.839-171.898 167.468-9.587 9.377-19.174 18.754-31.401 29.287-17.031 17.498-34.062 34.995-53.17 55.23-4.967 4.743-9.934 9.485-17.489 15.395-18.525 19.010-37.051 38.020-57.67 59.748-6.536 6.316-13.073 12.632-21.576 19.475-1.581 2.108-3.163 4.216-6.521 9.011-6.080 5.961-12.16 11.922-20.487 18.182-1.455 0.761-2.314 1.951-2.211 3.625 0 0 0.034 0.37-0.935-0.085zM457.349 571.913c0 0-0.712 0.977 2.256-1.469 31.315-31.739 62.63-63.477 97.020-96.279 4.189-4.859 8.378-9.717 15.274-15.85 25.278-25.754 50.555-51.508 78.782-78.569 8.838-9.388 17.677-18.776 29.227-29.44 57.003-56.719 114.006-113.437 173.154-172.291-127.777-109.386-271.643-148.812-430.725-105.427-177.884 48.513-292.038 167.261-331.848 348.107-33.559 152.449 8.712 287.734 114.173 407.397 13.331-16.326 24.48-29.98 38.474-44.797 3.774-2.991 7.548-5.982 14.040-10.238 18.934-19.42 37.868-38.839 59.863-59.322 4.17-4.831 8.339-9.662 15.251-15.732 41.798-42.129 83.596-84.258 125.060-126.090z","M647.731 381.052c-25.278 25.754-50.555 51.508-78.41 76.23-85.383-1.219-168.198-2.262-250.989-1.289-54.246 0.638-104.545 39.561-115.433 92.715-6.635 32.394-3.208 66.74-5.864 100.084-4.093 51.377 6.421 97.585 43.256 135.665-11.149 13.654-22.298 27.308-35.629 43.635-105.46-119.663-147.732-254.948-114.173-407.397 39.81-180.846 153.964-299.594 331.848-348.107 159.081-43.385 302.948-3.959 430.725 105.427-59.149 58.854-116.151 115.572-175.322 171.472-52.719-33.54-106.686-44.272-167.197-35.86-49.736 6.914-90.483 28.306-128.083 58.454-11.706 9.386-24.523 22.034-10.979 38.809 12.334 15.278 25.445 6.171 35.552-3.391 47.505-44.942 103.381-65.857 167.97-54.371 25.104 4.464 48.535 18.337 72.729 27.924z","M706.678 370.357c56.617-54.898 113.234-109.796 169.895-164.737 144.239 137.995 188.070 426.275-5.346 626.396-186.827 193.303-481.382 175.587-643.164 16.003 15.232-15.379 30.484-30.777 48.077-45.472 16.687 3.827 31.019 9.601 45.377 9.666 148.48 0.671 296.967 0.883 445.447 0.224 69.745-0.309 124.21-55.525 125.408-125.287 0.577-33.594 0.331-67.208 0.085-100.81-0.56-76.639-54.843-130.298-131.996-130.73-46.094-0.258-92.187-0.496-138.281-0.743 17.031-17.498 34.062-34.995 53.601-52.013 6.812 3.35 10.774 7.623 15.497 8.774 7.82 1.905 21.142 5.075 23.229 1.883 4.929-7.54 6.615-18.719 5.65-28.014-0.567-5.454-8.732-10.12-13.479-15.14z","M288.683 788.389c17.098-17.578 34.196-35.156 54.055-52.173 25.691 0.936 49.255 4.88 71.414 0.931 43.88-7.82 43.56-9.622 43.559-53.704-0-12.444 1.298-25.097-0.649-37.229-0.782-4.871-8.698-8.597-13.367-12.844 15.138-15.638 30.275-31.276 47.258-47.226 1.845-0.312 3.424-1.259 3.58 1.081 0.156 51.265 0.156 100.191 0.156 149.031 10.116 0 17.547 0 26.374 0 0-12.799 0-24.391 0-35.982 0-12.228 0-24.456 0-35.717 22.424-2.396 42.894-2.377 62.18-7.144 31.628-7.817 48.024-32.983 47.054-66.477-0.906-31.284-17.309-50.117-50.913-57.192-10.573-2.226-21.551-2.53-32.344-3.714 18.525-19.010 37.051-38.020 58.45-56.409 55.319 0.696 107.77 0.285 160.207 0.974 60.482 0.795 106.686 46.886 107.85 107.17 0.605 31.3 0.184 62.62 0.12 93.931-0.152 73.981-44.235 118.075-118.264 118.112-138.552 0.068-277.104 0.207-415.655-0.22-17.027-0.052-34.044-3.385-51.065-5.197zM685.514 536.493c-9.389 11.917-22.983 22.491-27.307 36.027-9.514 29.78 6.364 55.983 37.202 65.543 19.283 5.977 39.588 8.571 59.224 13.52 14.668 3.697 25.308 11.705 25.972 28.854 0.681 17.589-8.526 28.124-23.865 33.383-8.692 2.98-18.715 5.807-27.408 4.348-24.887-4.178-49.4-10.58-78.679-17.143 5.071 9.826 7.662 24.504 15.266 27.874 29.575 13.11 61.062 18.449 93.416 8.941 29.759-8.745 48.729-31.477 48.58-58.593-0.153-27.827-15.741-45.238-49.196-53.785-15.864-4.053-32.090-6.666-48.039-10.411-17.044-4.002-31.058-15.2-27.148-32.21 2.68-11.657 15.84-25.504 27.342-29.37 14.379-4.833 32.251-2.436 47.889 0.59 13.633 2.638 26.26 10.48 39.331 16.022 1.731-1.056 3.462-2.112 5.193-3.168-4.75-9.855-7.118-25.43-14.664-28.573-32.18-13.401-65.977-19.331-103.108-1.85z","M553.549 475.228c-31.315 31.739-62.63 63.477-95.517 94.277 4.048-19.731-3.166-30.462-22.079-34.436-11.364-2.388-22.431-6.401-33.866-8.2-45.115-7.097-87.371 11.223-106.921 45.699-22.276 39.283-18.799 104.031 7.602 135.059 2.749 3.23 7.425 4.821 11.207 7.172-18.934 19.42-37.868 38.839-58.357 57.246-21.783-25.020-39.474-50.197-39.474-83.5 0.001-36.655-0.838-73.334 0.222-109.958 1.634-56.438 47.027-102.894 103.262-103.688 77.956-1.101 155.944 0.109 233.919 0.329z","M287.624 789.775c18.081 0.427 35.098 3.759 52.124 3.812 138.55 0.427 277.103 0.289 415.655 0.22 74.029-0.037 118.112-44.131 118.264-118.112 0.064-31.311 0.485-62.632-0.12-93.931-1.164-60.285-47.368-106.376-107.85-107.17-52.437-0.689-104.888-0.278-158.913-1.557 3.386-5.947 8.354-10.689 14.359-16.801 47.132-1.122 93.226-0.884 139.32-0.626 77.153 0.432 131.437 54.090 131.996 130.73 0.245 33.602 0.492 67.216-0.085 100.81-1.198 69.762-55.663 124.978-125.408 125.287-148.48 0.659-296.967 0.447-445.447-0.224-14.358-0.065-28.691-5.839-44.090-10.257 2.342-4.461 5.739-7.628 10.196-12.179z","M649.206 380.399c-25.668-8.934-49.099-22.807-74.203-27.271-64.589-11.486-120.465 9.429-167.97 54.371-10.107 9.562-23.218 18.669-35.552 3.391-13.543-16.775-0.727-29.423 10.979-38.809 37.6-30.148 78.346-51.54 128.083-58.454 60.511-8.412 114.478 2.32 165.841 36.498-8.027 10.846-16.865 20.234-27.178 30.275z","M457.684 571.617c-41.798 42.129-83.596 84.258-127.487 125.542-26.108-30.178-27.734-63.581-17.936-98.031 8.9-31.292 33.578-51.725 65.771-48.569 26.979 2.645 53.133 13.717 79.652 21.058z","M555.087 474.696c-79.512 0.311-157.501-0.898-235.457 0.203-56.235 0.794-101.629 47.25-103.262 103.688-1.060 36.624-0.222 73.304-0.222 109.958-0.001 33.303 17.69 58.48 38.115 84.132-3.578 4.636-7.352 7.627-12.548 11.199-38.258-37.499-48.771-83.707-44.678-135.084 2.656-33.344-0.771-67.69 5.864-100.084 10.887-53.154 61.187-92.077 115.433-92.715 82.792-0.973 165.607 0.070 249.637 1.926-2.965 6.528-7.154 11.386-12.881 16.777z","M545.992 531.388c11.84-0.175 22.818 0.129 33.391 2.355 33.604 7.075 50.007 25.908 50.913 57.192 0.97 33.494-15.425 58.66-47.054 66.477-19.286 4.767-39.756 4.748-62.18 7.144 0 11.261 0 23.489 0 35.717 0 11.592 0 23.183 0 35.982-8.826 0-16.258 0-26.374 0 0-48.84 0-97.766-0.001-149.426-0.001-2.734-0.505-3.42-0.505-3.42s-0.034-0.37 1.059-0.011c1.85-1.188 2.607-2.735 3.365-4.282 6.080-5.961 12.16-11.922 20.248-17.625 2.008 25.676 2.008 51.094 2.008 77.932 17.043-0.788 31.148-0.143 44.792-2.347 26.442-4.272 39.396-20.134 38.472-44.438-0.849-22.312-15.605-35.775-42.153-38.187-12.196-1.108-24.425-1.849-36.638-2.756 6.536-6.316 13.073-12.632 20.656-20.308z","M457.516 571.765c-26.352-7.489-52.505-18.561-79.484-21.206-32.194-3.157-56.871 17.277-65.771 48.569-9.799 34.449-8.172 67.852 16.564 98.65-3.448 6.296-7.618 11.127-13.318 16.489-5.312-1.82-9.989-3.41-12.737-6.64-26.401-31.028-29.878-95.776-7.602-135.059 19.55-34.476 61.806-52.796 106.921-45.699 11.434 1.799 22.502 5.812 33.866 8.2 18.913 3.974 26.127 14.705 20.595 35.66 0.088 2.163 0.8 1.185 0.968 1.037z","M524.353 551.959c13.198 0.644 25.427 1.385 37.622 2.493 26.548 2.411 41.304 15.875 42.153 38.187 0.924 24.304-12.030 40.166-38.472 44.438-13.644 2.204-27.749 1.559-44.792 2.347 0-26.838 0-52.255-1.119-79.275 0.462-3.71 2.043-5.818 4.608-8.19z","M442.653 634.725c5.711 2.892 13.627 6.618 14.409 11.489 1.947 12.132 0.649 24.785 0.649 37.229 0.001 44.083 0.322 45.885-43.559 53.704-22.158 3.949-45.723 0.005-70.051-1.469 3.368-5.73 8.136-10.36 15.853-16.702 19.909-2.381 37.037-1.881 53.745-4.292 6.746-0.974 18.282-9.024 17.833-12.635-1.964-15.793 11.32-35.329-9.472-47.16 6.517-6.27 13.034-12.539 20.593-20.164z","M420.736 655.43c22.116 11.289 8.832 30.825 10.796 46.618 0.449 3.61-11.087 11.661-17.833 12.635-16.708 2.411-33.836 1.911-52.788 2.931 18.172-20.313 38.337-40.978 59.825-62.184z","M705.677 371.722c5.749 3.655 13.914 8.32 14.481 13.775 0.965 9.296-0.721 20.474-5.65 28.014-2.087 3.192-15.409 0.021-23.229-1.883-4.723-1.15-8.685-5.423-14.177-9.351 8.399-10.435 17.986-19.812 28.575-30.555z","M497.484 579.266c0.366 1.398-0.391 2.945-2.425 4.106-1.012-2.006-0.153-3.196 2.425-4.106z","M493.7 583.183c0.484 0.227 0.988 0.913 0.833 1.308s-1.735 1.341-2.125 0.521c-0.39-0.82 0.808-2.057 1.292-1.829z","M687.197 535.787c35.449-16.776 69.246-10.846 101.426 2.555 7.546 3.142 9.914 18.717 14.664 28.573-1.731 1.056-3.462 2.112-5.193 3.168-13.071-5.543-25.698-13.385-39.331-16.022-15.639-3.026-33.51-5.423-47.889-0.59-11.501 3.866-24.662 17.713-27.342 29.37-3.91 17.009 10.104 28.208 27.148 32.21 15.949 3.745 32.176 6.358 48.039 10.411 33.454 8.548 49.042 25.958 49.196 53.785 0.149 27.116-18.82 49.848-48.58 58.593-32.354 9.507-63.842 4.168-93.416-8.941-7.604-3.37-10.195-18.049-15.266-27.874 29.28 6.563 53.793 12.965 78.679 17.143 8.693 1.459 18.716-1.368 27.408-4.348 15.339-5.259 24.545-15.794 23.865-33.383-0.664-17.149-11.304-25.157-25.972-28.854-19.636-4.949-39.941-7.543-59.224-13.52-30.839-9.56-46.717-35.762-37.202-65.543 4.324-13.535 17.918-24.109 28.99-36.732z"],"attrs":[{"fill":"rgb(255, 253, 253)"},{"fill":"rgb(255, 37, 4)"},{"fill":"rgb(255, 253, 253)"},{"fill":"rgb(255, 252, 252)"},{"fill":"rgb(251, 251, 251)"},{"fill":"rgb(252, 250, 250)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(250, 248, 248)"},{"fill":"rgb(6, 6, 6)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(12, 12, 12)"},{"fill":"rgb(251, 251, 251)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(250, 238, 238)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(113, 106, 106)"},{"fill":"rgb(113, 106, 106)"},{"fill":"rgb(12, 12, 12)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_low"]},"attrs":[{"fill":"rgb(255, 253, 253)"},{"fill":"rgb(255, 37, 4)"},{"fill":"rgb(255, 253, 253)"},{"fill":"rgb(255, 252, 252)"},{"fill":"rgb(251, 251, 251)"},{"fill":"rgb(252, 250, 250)"},{"fill":"rgb(5, 5, 5)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(250, 248, 248)"},{"fill":"rgb(6, 6, 6)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(12, 12, 12)"},{"fill":"rgb(251, 251, 251)"},{"fill":"rgb(10, 10, 10)"},{"fill":"rgb(250, 238, 238)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(113, 106, 106)"},{"fill":"rgb(113, 106, 106)"},{"fill":"rgb(12, 12, 12)"}],"properties":{"order":2,"id":2,"name":"gps_signal_low","prevSize":32,"code":59648,"codes":[59648,59649,59650,59651,59652,59653,59654,59655,59656,59657,59658,59659,59660,59661,59662,59663,59664,59665,59666]},"setIdx":0,"setId":0,"iconIdx":0},{"icon":{"paths":["M601.248 1028.697c-200.416 0-398.483 0-596.55 0-0-341.333-0-682.667-0-1024 356.991-0 713.982-0 1070.972-0 0 341.333 0 682.666 0 1024-157.358 0-314.716 0-474.422 0zM992.795 670.585c26.319-76.179 33.921-154.172 18.963-233.408-47.787-253.137-266.071-416.098-522.563-391.022-277.053 27.086-471.494 299.456-412.78 571.963 40.134 186.274 229.787 382.491 455.627 363.915 38.042-3.129 77.887 4.194 114.39-4.212 168.807-38.872 283.272-142.1 346.364-307.236z","M992.239 672.346c-62.537 163.374-177.001 266.603-345.809 305.475-36.502 8.406-76.348 1.083-114.39 4.212-225.84 18.576-415.492-177.641-455.627-363.915-58.714-272.507 135.727-544.877 412.78-571.963 256.493-25.076 474.776 137.885 522.563 391.022 14.958 79.236 7.356 157.229-19.519 235.17zM664.661 812.673c34.442-0.014 68.894 0.519 103.322-0.157 68.659-1.348 123.080-55.748 124.381-124.386 0.682-35.994 0.692-72.023-0.003-108.016-1.326-68.636-55.819-123.928-124.405-124.27-148.722-0.741-297.452-0.743-446.174 0.001-68.563 0.343-123.086 55.742-124.408 124.298-0.634 32.864-0.22 65.75-0.12 98.626 0.245 80.241 53.727 133.784 133.948 133.873 109.587 0.121 219.175 0.031 333.459 0.031zM682.018 249.234c-58.826-19.859-118.173-30.421-180.832-19.534-68.359 11.877-127.277 40.675-177.552 87.976-10.499 9.878-22.386 19.995-6.634 34.441 13.496 12.377 25.599 7.537 37.361-4.155 89.111-88.585 230.179-104.762 339.503-45.382 25.276 13.729 47.029 33.919 70.515 50.983 10.067 7.314 20.821 8.483 29.222-1.699 8.968-10.869 5.112-20.28-4.318-30.329-29.478-31.414-65.62-52.506-107.267-72.301zM643.5 331.137c-28.682-7.041-57.115-18.587-86.096-20.186-60.451-3.335-115.995 13.125-163.652 53.267-26.11 21.993-34.912 35.592-22.149 46.667 22.561 19.577 33.74-3.52 47.501-15.060 37.726-31.635 82.827-48.181 130.31-46.809 53.545 1.548 101.016 25.184 141.615 61.611 5.127 4.6 16.988 1.697 25.729 2.27 0.367-10.311 5.19-25.976 0.338-30.014-22.038-18.339-46.802-33.401-73.596-51.747z","M662.312 812.673c-111.936-0-221.523 0.091-331.111-0.031-80.221-0.089-133.702-53.632-133.948-133.873-0.1-32.876-0.514-65.762 0.12-98.626 1.322-68.556 55.846-123.955 124.408-124.298 148.722-0.745 297.452-0.743 446.174-0.001 68.586 0.342 123.079 55.634 124.405 124.27 0.695 35.994 0.685 72.022 0.003 108.016-1.301 68.638-55.722 123.038-124.381 124.386-34.428 0.676-68.881 0.143-105.671 0.157zM368.775 793.819c130.586-0.001 261.173 0.164 391.759-0.071 67.376-0.121 112.735-45.978 113.104-113.691 0.179-32.841 0.547-65.694-0.096-98.524-1.159-59.195-46.848-106.465-105.64-106.775-148.567-0.785-297.144-0.749-445.711-0.025-57.945 0.282-104.202 46.517-105.834 104.128-1.040 36.722-0.916 73.515-0.024 110.244 1.173 48.284 33.133 89.407 80.327 100.115 21.711 4.926 44.915 3.271 72.114 4.599z","M683.667 250.093c39.997 18.936 76.139 40.028 105.617 71.442 9.43 10.049 13.285 19.46 4.318 30.329-8.401 10.182-19.155 9.012-29.222 1.699-23.486-17.063-45.239-37.254-70.515-50.983-109.325-59.38-250.392-43.203-339.503 45.382-11.762 11.692-23.865 16.532-37.361 4.155-15.752-14.446-3.865-24.563 6.634-34.441 50.274-47.301 109.193-76.099 177.552-87.976 62.658-10.887 122.006-0.326 182.481 20.393z","M645.005 332.189c25.288 17.293 50.053 32.356 72.090 50.695 4.853 4.038 0.030 19.703-0.338 30.014-8.741-0.573-20.601 2.331-25.729-2.27-40.6-36.427-88.071-60.063-141.615-61.611-47.484-1.373-92.584 15.174-130.31 46.809-13.761 11.54-24.94 34.636-47.501 15.060-12.763-11.075-3.961-24.674 22.149-46.667 47.658-40.143 103.201-56.602 163.652-53.267 28.982 1.599 57.415 13.145 87.602 21.238z","M366.439 793.819c-24.863-1.329-48.067 0.327-69.778-4.599-47.194-10.708-79.155-51.831-80.327-100.115-0.892-36.73-1.016-73.522 0.024-110.244 1.632-57.611 47.889-103.846 105.834-104.128 148.568-0.724 297.144-0.76 445.711 0.025 58.792 0.31 104.481 47.581 105.64 106.775 0.642 32.83 0.275 65.683 0.096 98.524-0.369 67.713-45.728 113.57-113.104 113.691-130.586 0.235-261.173 0.070-394.095 0.071zM410.844 657.647c6.827 0.309 13.654 0.619 22.056 1 0 14.41 0.614 27.571-0.338 40.618-0.327 4.485-3.472 10.549-7.185 12.728-40.471 23.743-102.254 0.921-113.308-44.194-5.174-21.115-4.564-45.116-0.526-66.677 6.082-32.478 33.028-52.991 66.314-50.82 26.181 1.708 51.959 9.592 78.275 14.804 5.308-16.108-3.216-24.293-20.19-29.897-58.040-19.164-113.328-6.091-138.535 34.017-26.323 41.883-21.286 111.849 11.512 144.489 36.008 35.836 89.26 35.018 139.289 12.143 3.876-1.772 8.115-7.772 8.234-11.92 0.748-26.179 0.379-52.389 0.379-78.263-27.606 0-52.162 0-77.875 0 0.878 8.232 1.576 14.768 2.345 21.973 9.523 0 17.283 0 29.554 0zM657.369 573.207c-1.997 41.811 9.834 57.724 50.995 67.96 17.323 4.308 35.697 5.977 51.802 12.971 8.886 3.859 18.649 15.769 19.638 24.952 1.019 9.461-5.876 22.55-13.498 29.368-7.288 6.519-20.319 10.495-30.202 9.485-26.452-2.705-52.568-8.684-81.127-13.773 1.527 5.9 0.893 18.391 6.62 23.030 27.401 22.194 96.867 19.471 124.106-3.414 16.705-14.035 24.667-31.973 20.79-54.121-3.782-21.604-17.421-34.603-37.705-40.392-17.18-4.903-34.768-8.413-52.239-12.252-20.136-4.424-36.857-13.551-34.112-36.974 2.673-22.812 21.442-31.392 41.201-29.732 24.914 2.094 49.415 9.105 74.859 14.146 5.42-15.393 0.070-27.113-21.212-30.435-11.497-1.795-22.617-6.101-34.125-7.704-38.083-5.303-68.182 10.241-85.791 46.885zM621.648 561.187c-33.585-44.783-81.323-26.053-124.295-30.444 0 70.19 0 137.675 0 205.577 8.016 0 14.624 0 23.448 0 0-24.832 0-48.61 0-72.033 97.387-10.277 124.705-37.339 100.847-103.1z","M408.589 657.647c-10.016 0-17.776 0-27.299 0-0.769-7.204-1.466-13.74-2.345-21.973 25.713 0 50.269 0 77.875 0 0 25.874 0.369 52.085-0.379 78.263-0.118 4.148-4.358 10.148-8.234 11.92-50.029 22.875-103.28 23.693-139.289-12.143-32.798-32.641-37.836-102.606-11.512-144.489 25.207-40.108 80.495-53.181 138.535-34.017 16.974 5.605 25.498 13.789 20.19 29.897-26.315-5.212-52.093-13.096-78.275-14.804-33.286-2.171-60.232 18.342-66.314 50.82-4.038 21.56-4.648 45.561 0.526 66.677 11.054 45.115 72.837 67.938 113.308 44.194 3.714-2.179 6.858-8.243 7.185-12.728 0.952-13.047 0.338-26.208 0.338-40.618-8.402-0.381-15.229-0.69-24.311-1z","M657.702 571.307c17.275-34.745 47.374-50.289 85.457-44.986 11.509 1.603 22.628 5.909 34.125 7.704 21.282 3.322 26.632 15.042 21.212 30.435-25.444-5.041-49.944-12.052-74.859-14.146-19.759-1.66-38.528 6.92-41.201 29.732-2.745 23.423 13.976 32.549 34.112 36.974 17.471 3.839 35.059 7.348 52.239 12.252 20.284 5.789 33.923 18.788 37.705 40.392 3.877 22.148-4.085 40.086-20.79 54.121-27.239 22.885-96.705 25.608-124.106 3.414-5.727-4.639-5.093-17.13-6.62-23.030 28.558 5.089 54.675 11.068 81.127 13.773 9.883 1.011 22.914-2.966 30.202-9.485 7.622-6.818 14.516-19.906 13.498-29.368-0.989-9.183-10.752-21.093-19.638-24.952-16.105-6.994-34.478-8.663-51.802-12.971-41.16-10.236-52.992-26.149-50.661-69.859z","M622.778 562.655c22.728 64.292-4.59 91.354-101.976 101.631 0 23.423 0 47.201 0 72.033-8.824 0-15.432 0-23.448 0 0-67.902 0-135.386 0-205.577 42.971 4.391 90.71-14.339 125.424 31.912zM604.49 587.095c-12.204-31.237-39.004-40.681-82.929-29.447 0 26.401 0 52.698 0 78.832 58.152 8.154 79.432-3.716 82.929-49.386z","M604.637 588.908c-3.644 43.857-24.924 55.727-83.076 47.573 0-26.134 0-52.432 0-78.832 43.925-11.234 70.725-1.79 83.076 31.26z"],"attrs":[{"fill":"rgb(255, 255, 254)"},{"fill":"rgb(255, 255, 1)"},{"fill":"rgb(6, 6, 0)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(251, 251, 0)"},{"fill":"rgb(11, 11, 4)"},{"fill":"rgb(13, 13, 4)"},{"fill":"rgb(11, 11, 4)"},{"fill":"rgb(251, 251, 0)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_middle"]},"attrs":[{"fill":"rgb(255, 255, 254)"},{"fill":"rgb(255, 255, 1)"},{"fill":"rgb(6, 6, 0)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(251, 251, 0)"},{"fill":"rgb(11, 11, 4)"},{"fill":"rgb(13, 13, 4)"},{"fill":"rgb(11, 11, 4)"},{"fill":"rgb(251, 251, 0)"}],"properties":{"order":3,"id":1,"name":"gps_signal_middle","prevSize":32,"code":59667,"codes":[59667,59668,59669,59670,59671,59672,59673,59674,59675,59676]},"setIdx":0,"setId":0,"iconIdx":1},{"icon":{"paths":["M634.128 1028.697c-211.376 0-420.404 0-629.431 0-0-341.333-0-682.667-0-1024 356.991-0 713.982-0 1070.972-0 0 341.333 0 682.666 0 1024-146.398 0-292.795 0-441.541 0zM1018.959 501.469c-2.949-21.188-6.17-42.343-8.797-63.572-7.842-63.369-29.651-122.3-64.221-175.103-52.965-80.9-122.179-144.268-212.401-183.329-93.652-40.546-190.908-50.996-289.73-30.777-107.563 22.007-197.921 76.162-268.048 162.18-91.023 111.65-127.203 239.557-104.177 380.846 18.831 115.543 74.43 213.335 166.396 288.16 104.879 85.331 223.578 123.823 359.421 107.232 127.561-15.579 230.911-75.57 312.898-171.565 75.519-88.421 105.49-194.946 108.657-314.073z","M1019.106 503.618c-3.315 116.979-33.286 223.503-108.805 311.924-81.987 95.995-185.338 155.986-312.898 171.565-135.842 16.591-254.542-21.901-359.421-107.232-91.966-74.825-147.566-172.617-166.396-288.16-23.027-141.289 13.153-269.197 104.177-380.846 70.127-86.018 160.485-140.173 268.048-162.18 98.822-20.219 196.077-9.769 289.73 30.777 90.221 39.061 159.436 102.428 212.401 183.329 34.569 52.803 56.378 111.734 64.221 175.103 2.627 21.228 5.847 42.383 8.944 65.72zM799.743 807.979c62.703-22.243 92.613-64.375 92.766-130.838 0.074-32.063 0.444-64.135-0.102-96.189-1.189-69.756-55.905-124.893-125.817-125.173-147.803-0.59-295.611-0.59-443.413-0-69.904 0.279-124.673 55.467-125.831 125.172-0.533 32.055-0.164 64.126-0.096 96.189 0.174 82.015 53.086 135.436 134.513 135.5 141.549 0.11 283.097 0.132 424.645-0.139 13.163-0.025 26.322-2.415 43.334-4.522zM845.943 290.783c19.664-10.476 16.044-24.67 4.691-38.181-6.827-8.124-16.424-13.898-24.667-20.858-102.658-86.687-220.311-118.998-352.495-95.284-83.844 15.042-156.91 52.061-217.902 112.387-11.64 11.513-17.353 25.465-7.901 36.833 10.802 12.99 25.375 4.53 36.919-4.494 1.834-1.434 3.342-3.283 5.018-4.923 60.514-59.235 134.53-92.844 217.163-101.47 109.754-11.457 209.174 18.078 293.803 91.941 11.899 10.386 27.653 16.356 45.371 24.049zM775.039 307.636c-78.335-64.668-166.752-92.678-268.706-78.131-71.31 10.174-131.594 40.482-183.638 89.055-10.127 9.451-20.415 19.409-6.217 33.024 13.592 13.034 25.731 7.147 37.973-3.565 13.894-12.158 27.903-24.545 43.376-34.475 61.476-39.454 128.107-52.37 200.921-41.953 56.244 8.047 104.338 30.4 146.366 67.287 13.962 12.254 29.686 30.189 46.735 14.515 19.369-17.807-2.919-30.777-16.81-45.756zM399.999 413.2c4.109-3.525 8.218-7.050 12.327-10.576 55.468-47.602 118.517-67.82 188.788-42.195 32.254 11.762 60.401 34.606 90.859 51.624 5.929 3.313 16.294 6.3 20.4 3.423 5.732-4.015 9.759-13.546 10.223-20.983 0.345-5.545-4.97-12.755-9.708-17.108-71.283-65.488-154.002-84.582-245.127-52.948-31.757 11.024-60.431 32.244-88.491 51.721-7.438 5.163-7.376 21.133-10.757 32.141 9.337 1.91 18.674 3.821 31.487 4.902z","M797.817 808.386c-15.087 1.699-28.245 4.090-41.408 4.115-141.548 0.271-283.097 0.249-424.645 0.139-81.427-0.063-134.339-53.485-134.513-135.5-0.068-32.063-0.437-64.134 0.096-96.189 1.159-69.705 55.927-124.893 125.831-125.172 147.803-0.59 295.611-0.59 443.413 0 69.912 0.279 124.629 55.417 125.817 125.173 0.546 32.054 0.176 64.126 0.102 96.189-0.153 66.463-30.063 108.596-94.692 131.246zM462.679 793.82c100.986-0.005 201.975 0.427 302.958-0.18 60.49-0.363 106.842-46.898 107.908-107.238 0.608-34.434 0.52-68.894 0.025-103.332-0.887-61.658-47.25-108.284-109.092-108.475-146.39-0.453-292.783-0.452-439.173-0.001-61.838 0.191-108.207 46.807-109.117 108.458-0.496 33.655-0.422 67.327-0.021 100.984 0.751 63.060 47.040 109.14 110.297 109.701 43.836 0.389 87.678 0.079 136.214 0.082z","M844.068 290.944c-15.844-7.853-31.597-13.823-43.497-24.209-84.628-73.863-184.049-103.398-293.803-91.941-82.633 8.626-156.65 42.235-217.163 101.47-1.675 1.64-3.184 3.489-5.018 4.923-11.544 9.024-26.117 17.485-36.919 4.494-9.453-11.368-3.739-25.32 7.901-36.833 60.992-60.327 134.058-97.345 217.902-112.387 132.184-23.715 249.838 8.597 352.495 95.284 8.242 6.96 17.84 12.734 24.667 20.858 11.353 13.51 14.973 27.705-6.565 38.341z","M776.248 308.845c12.682 13.769 34.97 26.74 15.6 44.547-17.049 15.674-32.774-2.26-46.735-14.515-42.028-36.887-90.122-59.24-146.366-67.287-72.815-10.418-139.446 2.499-200.921 41.953-15.472 9.93-29.482 22.317-43.376 34.475-12.242 10.712-24.38 16.599-37.973 3.565-14.197-13.615-3.909-23.572 6.217-33.024 52.044-48.573 112.328-78.88 183.638-89.055 101.954-14.546 190.371 13.463 269.916 79.34z","M398.261 413.615c-11.075-1.496-20.412-3.406-29.749-5.317 3.381-11.008 3.319-26.978 10.757-32.141 28.060-19.476 56.734-40.696 88.491-51.721 91.125-31.634 173.844-12.54 245.127 52.948 4.738 4.353 10.054 11.563 9.708 17.108-0.463 7.438-4.491 16.968-10.223 20.983-4.106 2.876-14.471-0.111-20.4-3.423-30.457-17.017-58.605-39.862-90.859-51.624-70.271-25.626-133.319-5.407-188.788 42.195-4.109 3.526-8.218 7.051-14.065 10.991z","M460.33 793.82c-46.188-0.003-90.030 0.307-133.865-0.082-63.258-0.561-109.546-46.641-110.297-109.701-0.401-33.657-0.475-67.329 0.021-100.984 0.909-61.651 47.278-108.267 109.117-108.458 146.39-0.451 292.783-0.452 439.173 0.001 61.841 0.191 108.205 46.817 109.092 108.475 0.495 34.438 0.584 68.898-0.025 103.332-1.066 60.34-47.418 106.875-107.908 107.238-100.983 0.607-201.972 0.174-305.307 0.18zM340.633 734.174c35.799 14.349 70.394 7.23 104.144-6.899 5.113-2.141 11.149-9.453 11.386-14.62 1.171-25.462 0.532-51.008 0.532-76.842-27.198 0-51.657 0-75.875 0 0 7.697 0 13.674 0 22.485 17.769 0 34.459 0 52.007 0 0 14.544 1.262 26.438-0.504 37.863-0.961 6.217-5.759 14.609-11.061 16.943-38.518 16.957-84.093 3.123-102.989-30.044-21.968-38.559-13.994-97.141 18.296-119.752 10.837-7.589 26.101-13.677 38.802-12.783 26.576 1.871 52.794 8.84 80.39 13.943 4.744-12.517 0.763-23.549-16.791-27.935-10.55-2.636-21.136-5.176-31.792-7.328-55.339-11.175-102.859 12.441-119.261 60.624-15.491 45.51-9.434 119.357 52.716 144.345zM661.318 562.453c-12.57 40.998 1.507 66.808 42.796 77.559 18.777 4.889 38.636 6.857 56.313 14.213 8.794 3.66 18.328 16.050 19.211 25.287 0.905 9.46-6.123 22.435-13.802 29.166-7.362 6.452-20.389 10.329-30.272 9.265-26.437-2.848-52.522-8.954-81.688-14.305 2.368 7.142 2.569 19.328 8.532 23.757 27.572 20.48 90.308 19.552 118.496-0.039 18.721-13.012 28.751-30.903 26.118-54.048-2.676-23.529-16.679-38.243-39.23-44.283-19.539-5.233-39.435-9.122-59.019-14.2-15.932-4.132-26.398-14.267-26.752-31.326-0.367-17.68 11.667-26.503 26.824-31.211 6.559-2.037 14.138-3.582 20.689-2.35 22.963 4.317 45.681 9.94 71.626 15.771-2.892-8.827-3.314-22.748-8.993-25.396-36.951-17.233-99.421-26.774-130.849 22.141zM623.879 624.249c14.226-41.402 3.962-76.291-30.808-85.39-30.58-8.002-63.426-7.345-95.358-10.52 0 73.371 0 140.308 0 207.64 8.016 0 14.555 0 23.827 0 0-25.128 0-48.859 0-72.994 39.077-1.297 77.422 2.354 102.339-38.736z","M338.867 733.605c-60.385-24.419-66.442-98.266-50.95-143.776 16.401-48.183 63.922-71.799 119.261-60.624 10.657 2.152 21.243 4.692 31.792 7.328 17.554 4.386 21.535 15.418 16.791 27.935-27.596-5.103-53.814-12.071-80.39-13.943-12.701-0.894-27.964 5.194-38.802 12.783-32.29 22.611-40.264 81.194-18.296 119.752 18.897 33.168 64.471 47.001 102.989 30.044 5.302-2.334 10.1-10.726 11.061-16.943 1.766-11.425 0.504-23.319 0.504-37.863-17.548 0-34.239 0-52.007 0 0-8.811 0-14.788 0-22.485 24.218 0 48.676 0 75.875 0 0 25.834 0.639 51.38-0.532 76.842-0.238 5.167-6.273 12.479-11.386 14.62-33.75 14.129-68.344 21.248-105.909 6.329z","M662.091 560.759c30.656-47.221 93.125-37.68 130.076-20.448 5.679 2.648 6.101 16.569 8.993 25.396-25.945-5.831-48.663-11.454-71.626-15.771-6.551-1.232-14.13 0.312-20.689 2.35-15.157 4.708-27.191 13.531-26.824 31.211 0.354 17.060 10.82 27.195 26.752 31.326 19.584 5.079 39.48 8.967 59.019 14.2 22.551 6.040 36.554 20.754 39.23 44.283 2.633 23.145-7.397 41.036-26.118 54.048-28.188 19.592-90.924 20.519-118.496 0.039-5.963-4.429-6.164-16.614-8.532-23.757 29.166 5.351 55.252 11.457 81.688 14.305 9.883 1.065 22.911-2.812 30.272-9.265 7.68-6.731 14.707-19.706 13.802-29.166-0.883-9.236-10.418-21.627-19.211-25.287-17.677-7.356-37.536-9.324-56.313-14.213-41.289-10.751-55.366-36.561-42.024-79.253z","M622.875 625.792c-23.913 39.547-62.258 35.895-101.335 37.193 0 24.135 0 47.866 0 72.994-9.272 0-15.811 0-23.827 0 0-67.332 0-134.269 0-207.64 31.933 3.176 64.779 2.518 95.358 10.52 34.77 9.099 45.034 43.987 29.804 86.933zM571.737 555.427c-16.744 0-33.488 0-49.651 0 0 28.983 0 55.24 0 81.277 50.406 6.214 72.301-1.84 80.559-28.949 7.077-23.233-1.362-39.302-30.908-52.328z","M573.663 555.832c27.62 12.621 36.059 28.689 28.982 51.922-8.258 27.108-30.152 35.162-80.559 28.949 0-26.037 0-52.294 0-81.277 16.163 0 32.907 0 51.576 0.406z"],"attrs":[{"fill":"rgb(254, 255, 255)"},{"fill":"rgb(70, 248, 5)"},{"fill":"rgb(2, 5, 0)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(69, 244, 5)"},{"fill":"rgb(6, 11, 4)"},{"fill":"rgb(6, 12, 4)"},{"fill":"rgb(5, 11, 4)"},{"fill":"rgb(69, 244, 5)"}],"width":1071,"isMulticolor":true,"isMulticolor2":false,"grid":0,"tags":["gps_signal_high"]},"attrs":[{"fill":"rgb(254, 255, 255)"},{"fill":"rgb(70, 248, 5)"},{"fill":"rgb(2, 5, 0)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(2, 2, 2)"},{"fill":"rgb(1, 1, 1)"},{"fill":"rgb(69, 244, 5)"},{"fill":"rgb(6, 11, 4)"},{"fill":"rgb(6, 12, 4)"},{"fill":"rgb(5, 11, 4)"},{"fill":"rgb(69, 244, 5)"}],"properties":{"order":4,"id":0,"name":"gps_signal_high","prevSize":32,"code":59677,"codes":[59677,59678,59679,59680,59681,59682,59683,59684,59685,59686,59687]},"setIdx":0,"setId":0,"iconIdx":2}],"height":1024,"metadata":{"name":"icomoon"},"preferences":{"showGlyphs":true,"showCodes":true,"showQuickUse":true,"showQuickUse2":true,"showSVGs":true,"fontPref":{"prefix":"icon-","metadata":{"fontFamily":"icomoon"},"metrics":{"emSize":1024,"baseline":6.25,"whitespace":50},"embed":false},"imagePref":{"prefix":"icon-","png":true,"useClassSelector":true,"color":0,"bgColor":16777215},"historySize":50}}
\ No newline at end of file
diff --git a/assets/customIcon/icomoon/style.css b/assets/customIcon/icomoon/style.css
new file mode 100644
index 0000000..181312b
--- /dev/null
+++ b/assets/customIcon/icomoon/style.css
@@ -0,0 +1,224 @@
+@font-face {
+ font-family: 'icomoon';
+ src: url('fonts/icomoon.eot?eq8f84');
+ src: url('fonts/icomoon.eot?eq8f84#iefix') format('embedded-opentype'),
+ url('fonts/icomoon.ttf?eq8f84') format('truetype'),
+ url('fonts/icomoon.woff?eq8f84') format('woff'),
+ url('fonts/icomoon.svg?eq8f84#icomoon') format('svg');
+ font-weight: normal;
+ font-style: normal;
+ font-display: block;
+}
+
+[class^="icon-"], [class*=" icon-"] {
+ /* use !important to prevent issues with browser extensions that change fonts */
+ font-family: 'icomoon' !important;
+ speak: never;
+ font-style: normal;
+ font-weight: normal;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+
+ /* Better Font Rendering =========== */
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.icon-gps_signal_low .path1:before {
+ content: "\e900";
+ color: rgb(255, 253, 253);
+}
+.icon-gps_signal_low .path2:before {
+ content: "\e901";
+ margin-left: -1.0458984375em;
+ color: rgb(255, 37, 4);
+}
+.icon-gps_signal_low .path3:before {
+ content: "\e902";
+ margin-left: -1.0458984375em;
+ color: rgb(255, 253, 253);
+}
+.icon-gps_signal_low .path4:before {
+ content: "\e903";
+ margin-left: -1.0458984375em;
+ color: rgb(255, 252, 252);
+}
+.icon-gps_signal_low .path5:before {
+ content: "\e904";
+ margin-left: -1.0458984375em;
+ color: rgb(251, 251, 251);
+}
+.icon-gps_signal_low .path6:before {
+ content: "\e905";
+ margin-left: -1.0458984375em;
+ color: rgb(252, 250, 250);
+}
+.icon-gps_signal_low .path7:before {
+ content: "\e906";
+ margin-left: -1.0458984375em;
+ color: rgb(5, 5, 5);
+}
+.icon-gps_signal_low .path8:before {
+ content: "\e907";
+ margin-left: -1.0458984375em;
+ color: rgb(1, 1, 1);
+}
+.icon-gps_signal_low .path9:before {
+ content: "\e908";
+ margin-left: -1.0458984375em;
+ color: rgb(250, 248, 248);
+}
+.icon-gps_signal_low .path10:before {
+ content: "\e909";
+ margin-left: -1.0458984375em;
+ color: rgb(6, 6, 6);
+}
+.icon-gps_signal_low .path11:before {
+ content: "\e90a";
+ margin-left: -1.0458984375em;
+ color: rgb(10, 10, 10);
+}
+.icon-gps_signal_low .path12:before {
+ content: "\e90b";
+ margin-left: -1.0458984375em;
+ color: rgb(12, 12, 12);
+}
+.icon-gps_signal_low .path13:before {
+ content: "\e90c";
+ margin-left: -1.0458984375em;
+ color: rgb(251, 251, 251);
+}
+.icon-gps_signal_low .path14:before {
+ content: "\e90d";
+ margin-left: -1.0458984375em;
+ color: rgb(10, 10, 10);
+}
+.icon-gps_signal_low .path15:before {
+ content: "\e90e";
+ margin-left: -1.0458984375em;
+ color: rgb(250, 238, 238);
+}
+.icon-gps_signal_low .path16:before {
+ content: "\e90f";
+ margin-left: -1.0458984375em;
+ color: rgb(1, 1, 1);
+}
+.icon-gps_signal_low .path17:before {
+ content: "\e910";
+ margin-left: -1.0458984375em;
+ color: rgb(113, 106, 106);
+}
+.icon-gps_signal_low .path18:before {
+ content: "\e911";
+ margin-left: -1.0458984375em;
+ color: rgb(113, 106, 106);
+}
+.icon-gps_signal_low .path19:before {
+ content: "\e912";
+ margin-left: -1.0458984375em;
+ color: rgb(12, 12, 12);
+}
+.icon-gps_signal_middle .path1:before {
+ content: "\e913";
+ color: rgb(255, 255, 254);
+}
+.icon-gps_signal_middle .path2:before {
+ content: "\e914";
+ margin-left: -1.0458984375em;
+ color: rgb(255, 255, 1);
+}
+.icon-gps_signal_middle .path3:before {
+ content: "\e915";
+ margin-left: -1.0458984375em;
+ color: rgb(6, 6, 0);
+}
+.icon-gps_signal_middle .path4:before {
+ content: "\e916";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_middle .path5:before {
+ content: "\e917";
+ margin-left: -1.0458984375em;
+ color: rgb(1, 1, 1);
+}
+.icon-gps_signal_middle .path6:before {
+ content: "\e918";
+ margin-left: -1.0458984375em;
+ color: rgb(251, 251, 0);
+}
+.icon-gps_signal_middle .path7:before {
+ content: "\e919";
+ margin-left: -1.0458984375em;
+ color: rgb(11, 11, 4);
+}
+.icon-gps_signal_middle .path8:before {
+ content: "\e91a";
+ margin-left: -1.0458984375em;
+ color: rgb(13, 13, 4);
+}
+.icon-gps_signal_middle .path9:before {
+ content: "\e91b";
+ margin-left: -1.0458984375em;
+ color: rgb(11, 11, 4);
+}
+.icon-gps_signal_middle .path10:before {
+ content: "\e91c";
+ margin-left: -1.0458984375em;
+ color: rgb(251, 251, 0);
+}
+.icon-gps_signal_high .path1:before {
+ content: "\e91d";
+ color: rgb(254, 255, 255);
+}
+.icon-gps_signal_high .path2:before {
+ content: "\e91e";
+ margin-left: -1.0458984375em;
+ color: rgb(70, 248, 5);
+}
+.icon-gps_signal_high .path3:before {
+ content: "\e91f";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 5, 0);
+}
+.icon-gps_signal_high .path4:before {
+ content: "\e920";
+ margin-left: -1.0458984375em;
+ color: rgb(1, 1, 1);
+}
+.icon-gps_signal_high .path5:before {
+ content: "\e921";
+ margin-left: -1.0458984375em;
+ color: rgb(2, 2, 2);
+}
+.icon-gps_signal_high .path6:before {
+ content: "\e922";
+ margin-left: -1.0458984375em;
+ color: rgb(1, 1, 1);
+}
+.icon-gps_signal_high .path7:before {
+ content: "\e923";
+ margin-left: -1.0458984375em;
+ color: rgb(69, 244, 5);
+}
+.icon-gps_signal_high .path8:before {
+ content: "\e924";
+ margin-left: -1.0458984375em;
+ color: rgb(6, 11, 4);
+}
+.icon-gps_signal_high .path9:before {
+ content: "\e925";
+ margin-left: -1.0458984375em;
+ color: rgb(6, 12, 4);
+}
+.icon-gps_signal_high .path10:before {
+ content: "\e926";
+ margin-left: -1.0458984375em;
+ color: rgb(5, 11, 4);
+}
+.icon-gps_signal_high .path11:before {
+ content: "\e927";
+ margin-left: -1.0458984375em;
+ color: rgb(69, 244, 5);
+}
diff --git a/assets/fonts/icomoon.ttf b/assets/fonts/icomoon.ttf
new file mode 100644
index 0000000..f2e8bb4
Binary files /dev/null and b/assets/fonts/icomoon.ttf differ
diff --git a/lib/data/location_data.dart b/lib/data/location_data.dart
index 608819d..a7e8d6f 100644
--- a/lib/data/location_data.dart
+++ b/lib/data/location_data.dart
@@ -1,4 +1,5 @@
// ignore: non_constant_identifier_names
+// 不要
String location_line_date = """
{
"type": "FeatureCollection",
diff --git a/lib/main.dart b/lib/main.dart
index 51ceaae..e6e50da 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,6 +1,12 @@
+import 'dart:async';
+//import 'dart:convert';
+//import 'dart:developer';
import 'package:flutter/material.dart';
import 'package:flutter_map_tile_caching/flutter_map_tile_caching.dart';
import 'package:get/get.dart';
+//import 'package:vm_service/vm_service.dart';
+//import 'package:dart_vm_info/dart_vm_info.dart';
+
import 'package:rogapp/pages/destination/destination_controller.dart';
import 'package:rogapp/pages/index/index_binding.dart';
import 'package:rogapp/routes/app_pages.dart';
@@ -66,6 +72,8 @@ void main() async {
ErrorService.reportError(details.exception, details.stack ?? StackTrace.current, deviceInfo);
};
+ // startMemoryMonitoring(); // 2024-4-8 Akira: メモリ使用量のチェックを開始 See #2810
+
runZonedGuarded(() {
runApp(const ProviderScope(child: MyApp()));
}, (error, stackTrace) {
@@ -75,6 +83,72 @@ void main() async {
//runApp(const MyApp());
}
+// メモリ使用量の解説:https://qiita.com/hukusuke1007/items/e4e987836412e9bc73b9
+
+/*
+// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810
+// startMemoryMonitoring関数が5分ごとに呼び出され、メモリ使用量をチェックします。
+// メモリ使用量が閾値(ここでは500MB)を超えた場合、エラーメッセージとスタックトレースをレポートします。
+//
+void startMemoryMonitoring() {
+ const threshold = 500 * 1024 * 1024; // 500MB
+
+ // メモリ使用量情報を取得
+ final memoryUsage = MemoryUsage.fromJson(DartVMInfo.getAllocationProfile());
+
+ if (memoryUsage.heapUsage > threshold) {
+ final now = DateTime.now().toIso8601String();
+ final message = 'High memory usage detected at $now: ${memoryUsage.heapUsage} bytes';
+ print(message);
+ reportError(message, StackTrace.current);
+ showMemoryWarningDialog();
+ }
+
+ Timer(const Duration(minutes: 5), startMemoryMonitoring);
+}
+
+class MemoryUsage {
+ final int heapUsage;
+
+ MemoryUsage({required this.heapUsage});
+
+ factory MemoryUsage.fromJson(Map json) {
+ return MemoryUsage(
+ heapUsage: json['heapUsage'] as int,
+ );
+ }
+}
+*/
+
+// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810
+// reportError関数でエラーレポートを送信します。具体的な実装は、利用するエラー報告サービスによって異なります。
+void reportError(String message, StackTrace stackTrace) async {
+ // エラーレポートの送信処理を実装
+ // 例: SentryやFirebase Crashlyticsなどのエラー報告サービスを利用
+ print("ReportError : ${message} . stacktrace : ${stackTrace}");
+}
+
+// 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810
+// showMemoryWarningDialog関数で、メモリ使用量が高い場合にユーザーに警告ダイアログを表示します。
+//
+void showMemoryWarningDialog() {
+ if (Get.context != null) {
+ showDialog(
+ context: Get.context!,
+ builder: (context) => AlertDialog(
+ title: const Text('メモリ使用量の警告'),
+ content: const Text('アプリのメモリ使用量が高くなっています。アプリを再起動することをお勧めします。'),
+ actions: [
+ TextButton(
+ onPressed: () => Navigator.of(context).pop(),
+ child: const Text('OK'),
+ ),
+ ],
+ ),
+ );
+ }
+}
+
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
diff --git a/lib/model/auth_user.dart b/lib/model/auth_user.dart
index bd71551..c77922e 100644
--- a/lib/model/auth_user.dart
+++ b/lib/model/auth_user.dart
@@ -1,3 +1,6 @@
+// プロパティの型がString?やint?などのオプショナル型になっています。
+// これらのプロパティが常に値を持つことが保証されている場合は、非オプショナル型を使用することで、不要なnullチェックを回避できます。
+//
class AuthUser {
AuthUser();
diff --git a/lib/model/destination.dart b/lib/model/destination.dart
index 951f55e..89e2147 100644
--- a/lib/model/destination.dart
+++ b/lib/model/destination.dart
@@ -1,3 +1,6 @@
+// プロパティの型がString?やint?などのオプショナル型になっています。
+// これらのプロパティが常に値を持つことが保証されている場合は、非オプショナル型を使用することで、不要なnullチェックを回避できます。
+//
class Destination {
String? name;
String? address;
diff --git a/lib/pages/camera/camera_page.dart b/lib/pages/camera/camera_page.dart
index 3558781..8e015b5 100644
--- a/lib/pages/camera/camera_page.dart
+++ b/lib/pages/camera/camera_page.dart
@@ -31,6 +31,8 @@ String getTagText(bool isRecept, String? tags) {
return "";
}
+// 要修正:画像の読み込みエラーが発生した場合のエラーハンドリングが不十分です。エラーメッセージを表示するなどの処理を追加してください。
+//
Image getDisplayImage(Destination destination) {
String serverUrl = ConstValues.currentServer();
@@ -104,6 +106,8 @@ class CameraPage extends StatelessWidget {
Timer? timer;
+ // 要修正:エラーハンドリングが不十分です。例外が発生した場合の処理を追加することをお勧めします。
+ //
Widget getAction(BuildContext context) {
//print("----cccheckin is --- ${dbDest?.checkedin} ----");
if (manulaCheckin == true) {
@@ -431,6 +435,8 @@ class BuyPointCamera extends StatelessWidget {
height: 370,
decoration: BoxDecoration(
image: DecorationImage(
+ // 要修正:getReceiptImage関数の戻り値がnullの場合のエラーハンドリングが不十分です。適切なデフォルト画像を表示するなどの処理を追加してください。
+ //
image: getReceiptImage(), fit: BoxFit.cover)),
),
),
diff --git a/lib/pages/changepassword/change_password_page_controller.dart b/lib/pages/changepassword/change_password_page_controller.dart
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/pages/destination/destination_controller.dart b/lib/pages/destination/destination_controller.dart
index b146bdf..e11d067 100644
--- a/lib/pages/destination/destination_controller.dart
+++ b/lib/pages/destination/destination_controller.dart
@@ -33,6 +33,8 @@ import 'package:shared_preferences/shared_preferences.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
+import 'package:geolocator/geolocator.dart';
+
// 目的地に関連する状態管理とロジックを担当するクラスです。
//
class DestinationController extends GetxController {
@@ -44,6 +46,8 @@ class DestinationController extends GetxController {
List destinations = [].obs; // 目的地のリストを保持するObservable変数です。
double currentLat = 0.0; // 現在の緯度と経度を保持する変数です。
double currentLon = 0.0;
+ double lastValidLat = 0.0; // 最後に中・強信号で拾ったGPS位置。ロゲ開始を屋内でやったら 0 のままなので、屋外で行うこと。
+ double lastValidLon = 0.0;
DateTime lastGPSCollectedTime = DateTime.now(); // 最後にGPSデータが収集された時刻を保持する変数です。
bool shouldShowBottomSheet = true; // ボトムシートを表示すべきかどうかを示すフラグです。
@@ -75,6 +79,7 @@ class DestinationController extends GetxController {
var travelMode = 0.obs; // 移動モードを保持するReactive変数です。
bool skipGps = false; // GPSをスキップするかどうかを示すフラグです。
+ bool okToUseGPS = false; // 最新のGPS情報を使用して良いかを示すフラグ。
Map matrix = {}; // 行列データを保持する変数です。
@@ -199,6 +204,10 @@ class DestinationController extends GetxController {
// 目的地がデータベースに存在しない場合は、新しい目的地としてデータベースに挿入します。
// 目的地に応じて、チェックイン、ゴール、買い物ポイントの処理を行います。
//
+ // 2024-4-8 akira: GPS信号が弱い場合でも、最後に取得した位置情報を使用してチェックインやゴールの処理を続行できるようになります。また、チェックインやゴールの処理では、GPS信号の精度チェックを緩和することで、GPS信号が弱い場合でもボタンを押せるようになります。
+ //
+ // 要検討:エラーが発生した場合のエラーハンドリングを追加し、適切なメッセージを表示することを検討してください。
+ //
Future startTimer(Destination d, double distance) async {
//print("=== passed dest is ${d.location_id} ${d.checkedin} ====");
skipGps = true;
@@ -240,6 +249,31 @@ class DestinationController extends GetxController {
// comment out by Akira, 2024-4-5
// skipGps = false;
// return;
+ // GPS信号が弱い場合、最後に取得した高いまたは中程度の位置情報を使用
+ if (okToUseGPS) {
+ double lastValidDistance = Geolocator.distanceBetween(
+ lastValidLat, lastValidLon,
+ d.lat!, d.lon!
+ );
+ /*
+ double lastValidDistance = distance.as(
+ LengthUnit.Meter,
+ LatLng(lastValidLat, lastValidLon),
+ LatLng(d.lat!, d.lon!),
+ );
+ */
+
+ if (checkinRadious >= lastValidDistance || checkinRadious == -1) {
+ indexController.currentDestinationFeature.clear();
+ indexController.currentDestinationFeature.add(d);
+ } else {
+ skipGps = false;
+ return;
+ }
+ } else {
+ skipGps = false;
+ return;
+ }
}
if (isPhotoShoot.value == true) {
@@ -407,10 +441,10 @@ class DestinationController extends GetxController {
context: Get.context!,
isScrollControlled: true,
builder: ((context) => CameraPage(
- buyPointPhoto: true,
- destination: d,
- dbDest: ds.first,
- ))).whenComplete(() {
+ destination: d,
+ buyPointPhoto: true,
+ dbDest: ds.first,
+ ))).whenComplete(() {
shouldShowBottomSheet = true;
skipGps = false;
rogainingCounted.value = true;
@@ -641,13 +675,14 @@ class DestinationController extends GetxController {
});
} else {
Get.snackbar(
- "始まっていません",
- "ロゲ開始ボタンをタップして、ロゲイニングを始める必要があります",
- icon: const Icon(Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
- snackPosition: SnackPosition.TOP,
- duration: const Duration(seconds: 3),
- backgroundColor: Colors.yellow,
- );
+ "ロゲが始まっていません",
+ "ロゲ開始ボタンをタップして、ロゲイニングを始める必要があります",
+ icon: const Icon(
+ Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
+ snackPosition: SnackPosition.TOP,
+ duration: const Duration(seconds: 3),
+ backgroundColor: Colors.yellow,
+ );
}
}
}
@@ -680,6 +715,9 @@ class DestinationController extends GetxController {
// 目的地のリストを走査し、現在位置がチェックイン半径内にある場合は、チェックインの処理を行います。
// GPSデータの送信を開始します。
//
+ // 2024-4-8 Akira : See 2809
+ // checkForCheckinメソッドの再帰呼び出しをunawaitedで囲んで、非同期処理の結果を待たずに先に進むようにしました。また、再帰呼び出しの前に一定時間待機するようにしました。
+ //
Future checkForCheckin() async {
//print("--- Start of checkForCheckin function ---");
dbService.updateDatabase();
@@ -705,15 +743,16 @@ class DestinationController extends GetxController {
});
if (gps_push_started == false) {
- pushGPStoServer();
+ unawaited( pushGPStoServer() );
}
//print("--- 123 ---- $skip_gps----");
} catch (e) {
- //print("An error occurred: $e");
- await checkForCheckin();
+ print("An error occurred: $e");
+ // await checkForCheckin();
} finally {
+ await Future.delayed(const Duration(seconds: 5)); // 一定時間待機してから再帰呼び出し
//print("--- End of checkForCheckin function, calling recursively ---");
- await checkForCheckin();
+ unawaited( checkForCheckin() );
}
}
@@ -772,6 +811,8 @@ class DestinationController extends GetxController {
// 買い物ポイントを作成する関数です。 指定された目的地に対して買い物ポイントの処理を行います。
//
+ // 買い物ポイントの作成に失敗した場合のエラーハンドリングを追加することを検討してください。
+ //
Future makeBuyPoint(Destination destination, String imageurl) async {
DatabaseHelper db = DatabaseHelper.instance;
await db.updateBuyPoint(destination, imageurl);
@@ -804,6 +845,8 @@ class DestinationController extends GetxController {
// チェックインを行う関数です。 指定された目的地に対してチェックインの処理を行います。
//
+ // 要検討:チェックインのリクエストが失敗した場合のエラーハンドリングを追加することをお勧めします。
+ //
Future makeCheckin(
Destination destination, bool action, String imageurl) async {
// print("~~~~ calling checkin function ~~~~");
@@ -873,6 +916,9 @@ class DestinationController extends GetxController {
@override
void onInit() async {
super.onInit();
+
+ // 要検討:エラーメッセージを表示するなどの適切な処理を追加することを検討してください。
+ //
locationController.locationMarkerPositionStream.listen(
(locationMarkerPosition) {
if (locationMarkerPosition != null) {
@@ -896,9 +942,49 @@ class DestinationController extends GetxController {
// 現在位置とスタート地点との距離を計算します。
// 現在位置と前回の位置情報との距離と時間差を確認し、一定の条件を満たす場合はGPSデータをデータベースに追加します。
//
+ // 要検討:GPSデータの追加に失敗した場合のエラーハンドリングを追加することをお勧めします。
+ //
void handleLocationUpdate(LocationMarkerPosition? position) async {
try {
- if (position != null) {
+ final DestinationController destinationController = Get.find();
+ final signalStrength = destinationController.getGpsSignalStrength();
+ okToUseGPS = false;
+ double prevLat = lastValidLat; // 一つ前の位置情報を記録
+ double prevLon = lastValidLon;
+
+ if (position!=null && (signalStrength == 'high' || signalStrength == 'medium')) {
+ // 信号強度が高いまたは中程度の場合、現在の位置情報を更新
+ currentLat = position.latitude;
+ currentLon = position.longitude;
+ lastValidLat = position.latitude;
+ lastValidLon = position.longitude;
+ okToUseGPS = true;
+ } else {
+ // 信号強度が低い場合、最後に取得した高いまたは中程度の位置情報を使用
+ // 但し、最初から高精度のものがない場合、どうするか?
+ //
+ if (lastValidLat != 0.0 && lastValidLon != 0.0) {
+ currentLat = lastValidLat;
+ currentLon = lastValidLon;
+ okToUseGPS = true;
+ } else {
+ // GPSの届く場所に行って、信号を拾ってください。とメッセージを出す。
+ position = null;
+ print("GPSの届く場所に行って、信号を拾ってください。");
+ Get.snackbar(
+ "GPS信号を正確に拾えていません",
+ "空が大きく見えるところへ行ってGPS信号を拾ってください。",
+ icon: const Icon(
+ Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
+ snackPosition: SnackPosition.TOP,
+ duration: const Duration(seconds: 3),
+ backgroundColor: Colors.yellow,
+ );
+ }
+ }
+
+ if (okToUseGPS && position!=null) {
+ // スタート位置から150m離れたら、ready_for_goal
if (distanceToStart() >= 150) {
ready_for_goal = true;
}
@@ -907,10 +993,11 @@ class DestinationController extends GetxController {
double distanceToDest = distance.as(
LengthUnit.Meter,
LatLng(position.latitude, position.longitude),
- LatLng(currentLat, currentLon));
+ LatLng(prevLat, prevLon)
+ );
- Duration difference =
- lastGPSCollectedTime.difference(DateTime.now()).abs();
+ Duration difference = lastGPSCollectedTime.difference(DateTime.now()).abs();
+ // 最後にGPS信号を取得した時刻から10秒以上経過、かつ10m以上経過(普通に歩くスピード)
if (difference.inSeconds >= 10 || distanceToDest >= 10) {
// print(
// "^^^^^^^^ GPS data collected ${DateFormat('kk:mm:ss \n EEE d MMM').format(DateTime.now())}, ^^^ ${position.latitude}, ${position.longitude}");
@@ -931,10 +1018,10 @@ class DestinationController extends GetxController {
currentLon = position.longitude;
}
*/
- if (position != null) {
+ if (okToUseGPS) {
// 位置情報が取得できた場合、精度に関わらず最後の位置情報を更新
- currentLat = position.latitude;
- currentLon = position.longitude;
+ //currentLat = position.latitude;
+ //currentLon = position.longitude;
}
}
}
@@ -1020,25 +1107,32 @@ class DestinationController extends GetxController {
if (token != null && token.isNotEmpty) {
await indexController.loadUserDetailsForToken(token);
fixMapBound(token);
- return;
+ }else {
+ Get.toNamed(AppPages.LOGIN)!.then((value) {
+ if (indexController.currentUser.isNotEmpty) {
+ final tk = indexController.currentUser[0]["token"];
+ fixMapBound(tk);
+ } else {
+ Get.toNamed(AppPages.TRAVEL);
+ PerfectureService.getSubExt("9").then((value) {
+ if (value != null) {
+ LatLngBounds bnds = LatLngBounds(
+ LatLng(value[1], value[0]), LatLng(value[3], value[2]));
+ indexController.mapController
+ .fitBounds(bnds); //.centerZoomFitBounds(bnds);
+ }
+ });
+ }
+ });
}
- Get.toNamed(AppPages.LOGIN)!.then((value) {
- if (indexController.currentUser.isNotEmpty) {
- final tk = indexController.currentUser[0]["token"];
- fixMapBound(tk);
- } else {
- Get.toNamed(AppPages.TRAVEL);
- PerfectureService.getSubExt("9").then((value) {
- if (value != null) {
- LatLngBounds bnds = LatLngBounds(
- LatLng(value[1], value[0]), LatLng(value[3], value[2]));
- indexController.mapController
- .fitBounds(bnds); //.centerZoomFitBounds(bnds);
- }
- });
+ // 地図のイベントリスナーを設定
+ indexController.mapController.mapEventStream.listen((MapEvent mapEvent) {
+ if (mapEvent is MapEventMoveEnd) {
+ indexController.loadLocationsBound();
}
});
+
super.onReady();
}
@@ -1106,7 +1200,7 @@ class DestinationController extends GetxController {
print("center is ${currentLon}, ${currentLon}");
return true;
}());
- // Akira
+ // Akira ... 状況によって呼ぶか呼ばないか
if (currentLat != 0 || currentLon != 0) {
indexController.mapController.move(LatLng(currentLat, currentLon), 17.0);
}
@@ -1236,22 +1330,36 @@ class DestinationController extends GetxController {
// 目的地の選択状態を切り替える関数です。
//
void toggleSelection(Destination dest) async {
- DatabaseHelper db = DatabaseHelper.instance;
- await db.toggleSelecttion(dest);
- destinations.clear();
- db.getDestinations().then((value) {
- destinationCount.value = 0;
- currentSelectedDestinations.clear();
- for (Destination d in value) {
- //print("------ destination controller populating destination-------- ${d.checkedin}-------- :::::");
- //print("-----populated----- ${d.toMap()}");
- if (d.selected!) {
- currentSelectedDestinations.add(d);
+ try {
+ DatabaseHelper db = DatabaseHelper.instance;
+ await db.toggleSelecttion(dest);
+ destinations.clear();
+ db.getDestinations().then((value) {
+ destinationCount.value = 0;
+ currentSelectedDestinations.clear();
+ for (Destination d in value) {
+ //print("------ destination controller populating destination-------- ${d.checkedin}-------- :::::");
+ //print("-----populated----- ${d.toMap()}");
+ if (d.selected!) {
+ currentSelectedDestinations.add(d);
+ }
+ destinations.add(d);
}
- destinations.add(d);
- }
- destinationCount.value = destinations.length;
- });
+ destinationCount.value = destinations.length;
+ });
+ } catch( e ){
+ print('Error in toggleSelection: $e');
+ Get.snackbar(
+ "画面切り替えでエラー",
+ "画面の切り替えができませんでした",
+ icon: const Icon(
+ Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
+ snackPosition: SnackPosition.TOP,
+ duration: const Duration(seconds: 3),
+ backgroundColor: Colors.yellow,
+ );
+
+ }
}
// ダイアログを表示する関数です。
diff --git a/lib/pages/destination/destination_page.dart b/lib/pages/destination/destination_page.dart
deleted file mode 100644
index 7b7928f..0000000
--- a/lib/pages/destination/destination_page.dart
+++ /dev/null
@@ -1,252 +0,0 @@
-// import 'package:flutter/material.dart';
-// import 'package:geolocator/geolocator.dart';
-// import 'package:get/get.dart';
-// import 'package:latlong2/latlong.dart';
-// import 'package:rogapp/pages/destination/destination_controller.dart';
-// import 'package:rogapp/pages/destination_map/destination_map_page.dart';
-// import 'package:rogapp/pages/drawer/drawer_page.dart';
-// import 'package:rogapp/pages/index/index_controller.dart';
-// import 'package:rogapp/routes/app_pages.dart';
-// import 'package:rogapp/widgets/destination_widget.dart';
-
-// class XDestnationPage extends StatelessWidget {
-// XDestnationPage({Key? key}) : super(key: key);
-
-// final DestinationController destinationController =
-// Get.find();
-
-// final IndexController indexController = Get.find();
-
-// final List _items = List.generate(50, (int index) => index);
-
-// Future showCurrentPosition() async {
-// LocationPermission permission = await Geolocator.checkPermission();
-// if (permission != LocationPermission.whileInUse ||
-// permission != LocationPermission.always) {
-// permission = await Geolocator.requestPermission();
-// }
-// Position position = await Geolocator.getCurrentPosition(
-// desiredAccuracy: LocationAccuracy.high,
-// forceAndroidLocationManager: true);
-// indexController.rogMapController
-// .move(LatLng(position.latitude, position.longitude), 14);
-// }
-
-// Image getImage(int index) {
-// if (destinationController.destinations[index].photos == null ||
-// destinationController.destinations[index].photos == "") {
-// return const Image(image: AssetImage('assets/images/empty_image.png'));
-// } else {
-// return Image(
-// image:
-// NetworkImage(destinationController.destinations[index].photos!));
-// }
-// }
-
-// Widget getRoutingImage(int route) {
-// switch (route) {
-// case 0:
-// return const Image(
-// image: AssetImage('assets/images/p4_9_man.png'),
-// width: 35.0,
-// );
-// case 1:
-// return const Image(
-// image: AssetImage('assets/images/p4_8_car.png'),
-// width: 35.0,
-// );
-// case 2:
-// return const Image(
-// image: AssetImage('assets/images/p4_10_train.png'),
-// width: 35.0,
-// );
-// default:
-// return const Image(
-// image: AssetImage('assets/images/p4_9_man.png'),
-// width: 35.0,
-// );
-// }
-// }
-
-// @override
-// Widget build(BuildContext context) {
-// return WillPopScope(
-// onWillPop: () async {
-// indexController.switchPage(AppPages.INITIAL);
-// return false;
-// },
-// child: Scaffold(
-// drawer: DrawerPage(),
-// bottomNavigationBar: BottomAppBar(
-// child: Row(
-// mainAxisAlignment: MainAxisAlignment.spaceBetween,
-// children: [
-// Padding(
-// padding: const EdgeInsets.only(left: 13.0),
-// child: InkWell(
-// child: Obx((() => getRoutingImage(
-// destinationController.travelMode.value))),
-// onTap: () {
-// Get.bottomSheet(
-// Obx(
-// () => ListView(
-// children: [
-// Padding(
-// padding: const EdgeInsets.only(
-// top: 30.0, bottom: 30),
-// child: Center(
-// child: Text(
-// "select_travel_mode".tr,
-// style: const TextStyle(
-// fontSize: 22.0,
-// color: Colors.red,
-// fontWeight: FontWeight.bold),
-// ),
-// ),
-// ),
-// ListTile(
-// selected:
-// destinationController.travelMode.value ==
-// 0
-// ? true
-// : false,
-// selectedTileColor: Colors.amber.shade200,
-// leading: const Image(
-// image: AssetImage(
-// 'assets/images/p4_9_man.png'),
-// ),
-// title: Text("walking".tr),
-// onTap: () {
-// destinationController.travelMode.value = 0;
-// destinationController
-// .populateDestinations();
-// Get.back();
-// },
-// ),
-// ListTile(
-// selected:
-// destinationController.travelMode.value ==
-// 1
-// ? true
-// : false,
-// selectedTileColor: Colors.amber.shade200,
-// leading: const Image(
-// image: AssetImage(
-// 'assets/images/p4_8_car.png'),
-// ),
-// title: Text("driving".tr),
-// onTap: () {
-// destinationController.travelMode.value = 1;
-// destinationController
-// .populateDestinations();
-// Get.back();
-// },
-// ),
-// // ListTile(
-// // selected: destinationController.travelMode == 2 ? true : false,
-// // selectedTileColor: Colors.amber.shade200,
-// // leading: Image(image: AssetImage('assets/images/p4_10_train.png'),),
-// // title: Text("transit".tr),
-// // onTap:(){
-// // destinationController.travelMode.value = 2;
-// // destinationController.PopulateDestinations();
-// // Get.back();
-// // },
-// // ),
-// ],
-// ),
-// ),
-// isScrollControlled: false,
-// backgroundColor: Colors.white,
-// );
-// //destinationController.PopulateDestinations();
-// }),
-// ),
-// IconButton(
-// icon: const Icon(
-// Icons.travel_explore,
-// size: 35,
-// ),
-// onPressed: () {
-// indexController.switchPage(AppPages.INITIAL);
-// }),
-// ],
-// ),
-// ),
-// floatingActionButton: FloatingActionButton(
-// onPressed: () {
-// //print("######");
-// indexController.toggleDestinationMode();
-// },
-// tooltip: 'Increment',
-// elevation: 4.0,
-// child: Obx(() => indexController.desinationMode.value == 1
-// ? const Image(image: AssetImage('assets/images/list2.png'))
-// : const Image(image: AssetImage('assets/images/map.png'))),
-// ),
-// floatingActionButtonLocation:
-// FloatingActionButtonLocation.centerDocked,
-// appBar: AppBar(
-// automaticallyImplyLeading: true,
-// title: Text("app_title".tr),
-// actions: [
-// InkWell(
-// onTap: () {
-// Get.toNamed(AppPages.CAMERA_PAGE);
-// },
-// child: destinationController.isInRog.value == true
-// ? Image.asset(
-// "assets/images/basic-walking.gif",
-// height: 10.0,
-// )
-// : destinationController.isAtGoal.value == true
-// ? IconButton(
-// onPressed: () {
-// Get.toNamed(AppPages.CAMERA_PAGE);
-// },
-// icon: const Icon(Icons.assistant_photo),
-// )
-// : IconButton(
-// onPressed: () {
-// Get.toNamed(AppPages.CAMERA_PAGE);
-// },
-// icon: const Icon(Icons.accessibility),
-// ),
-// ),
-// // Obx(() =>
-// // Text(indexController.connectionStatusName.value)
-// // ),
-// Obx(
-// () => ToggleButtons(
-// disabledColor: Colors.grey.shade200,
-// selectedColor: Colors.red,
-// onPressed: (int index) {
-// destinationController.isGpsSelected.value =
-// !destinationController.isGpsSelected.value;
-// if (destinationController.isGpsSelected.value) {
-// destinationController.chekcs = 0;
-// destinationController.skipGps = false;
-// //destinationController.resetRogaining();
-// }
-// },
-// isSelected: [destinationController.isGpsSelected.value],
-// children: const [
-// Icon(
-// Icons.explore,
-// size: 35.0,
-// )
-// ],
-// ),
-// ),
-// // IconButton(onPressed: (){
-// // showCurrentPosition();
-// // },
-// // icon: Icon(Icons.location_on_outlined))
-// ],
-// ),
-// body: Obx(() => indexController.desinationMode.value == 0
-// ? DestinationWidget()
-// : DestinationMapPage())),
-// );
-// }
-// }
diff --git a/lib/pages/destination_map/destination_map_controller.dart b/lib/pages/destination_map/destination_map_controller.dart
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/pages/destination_map/destination_map_page.dart b/lib/pages/destination_map/destination_map_page.dart
index 75c9b05..1fd0941 100644
--- a/lib/pages/destination_map/destination_map_page.dart
+++ b/lib/pages/destination_map/destination_map_page.dart
@@ -34,6 +34,8 @@ class DestinationMapPage extends StatelessWidget {
return pts;
}
+ // 要検討:マーカーのタップイベントを処理する際に、エラーハンドリングが不十分です。例外が発生した場合の処理を追加することをお勧めします。
+ //
List? getMarkers() {
List pts = [];
int index = -1;
@@ -123,6 +125,8 @@ class DestinationMapPage extends StatelessWidget {
)));
}
+ // 要検討:MapOptionsのboundsプロパティにハードコードされた座標が使用されています。これを動的に設定できるようにすることを検討してください。
+ //
FlutterMap travelMap() {
return FlutterMap(
mapController: indexController.rogMapController,
diff --git a/lib/pages/drawer/drawer_binding.dart b/lib/pages/drawer/drawer_binding.dart
deleted file mode 100644
index e69de29..0000000
diff --git a/lib/pages/drawer/drawer_page.dart b/lib/pages/drawer/drawer_page.dart
index ef33299..e8f1c61 100644
--- a/lib/pages/drawer/drawer_page.dart
+++ b/lib/pages/drawer/drawer_page.dart
@@ -11,6 +11,8 @@ class DrawerPage extends StatelessWidget {
final IndexController indexController = Get.find();
+ // 要検討:URLの起動に失敗した場合のエラーハンドリングが不十分です。適切なエラーメッセージを表示するなどの処理を追加してください。
+ //
void _launchURL(url) async {
if (!await launchUrl(url)) throw 'Could not launch $url';
}
@@ -90,6 +92,8 @@ class DrawerPage extends StatelessWidget {
leading: const Icon(Icons.password),
title: const Text("リセット"),
onTap: () {
+ // 要検討:リセット操作の確認メッセージをローカライズすることを検討してください。
+ //
Get.defaultDialog(
title: "よろしいですか、リセットしますか?",
middleText: "これにより、すべてのゲーム データが削除され、すべての状態が削除されます",
@@ -132,6 +136,8 @@ class DrawerPage extends StatelessWidget {
),
indexController.currentUser.isNotEmpty
? ListTile(
+ // 要検討:アカウント削除のリクエストが失敗した場合のエラーハンドリングを追加することをお勧めします。
+ //
leading: const Icon(Icons.delete_forever),
title: Text("ユーザーデータを削除する".tr),
onTap: () {
diff --git a/lib/pages/gps/gps_page.dart b/lib/pages/gps/gps_page.dart
index 838f07f..6cbb459 100644
--- a/lib/pages/gps/gps_page.dart
+++ b/lib/pages/gps/gps_page.dart
@@ -31,6 +31,8 @@ class _GpsPageState extends State {
loadGpsData();
}
+ // 要検討:GPSデータの読み込みに失敗した場合のエラーハンドリングが不十分です。適切なエラーメッセージを表示するなどの処理を追加してください。
+ //
void loadGpsData() async {
final team_name = indexController.currentUser[0]["user"]['team_name'];
final event_code = indexController.currentUser[0]["user"]["event_code"];
@@ -41,6 +43,8 @@ class _GpsPageState extends State {
//print("--- gps data ${data} ----");
}
+ // 要検討:マーカーの形状を決定する際に、マジックナンバーが使用されています。定数を使用するなどして、コードの可読性を向上させることを検討してください。
+ //
Widget getMarkerShape(GpsData i) {
return Row(
mainAxisAlignment: MainAxisAlignment.start,
diff --git a/lib/pages/history/history_page.dart b/lib/pages/history/history_page.dart
index 1e0e6d2..31ca1c7 100644
--- a/lib/pages/history/history_page.dart
+++ b/lib/pages/history/history_page.dart
@@ -24,6 +24,8 @@ class _HistoryPageState extends State {
child: Column(
children: [
FutureBuilder(
+ // 要検討:スナップショットのエラーハンドリングが行われていますが、具体的なエラーメッセージを表示するようにすることをお勧めします。
+ //
future: db.getDestinations(),
builder: (BuildContext context,
AsyncSnapshot> snapshot) {
@@ -49,6 +51,7 @@ class _HistoryPageState extends State {
return Padding(
padding: const EdgeInsets.all(8.0),
child: CustomWidget(
+ // 要検討:画像のサイズがハードコードされています。画像のサイズを動的に設定できるようにすることを検討してください。
title: dests[index].name!,
subtitle:
"${dests[index].sub_loc_id} : ${dests[index].name}",
diff --git a/lib/pages/home/home_page.dart b/lib/pages/home/home_page.dart
index 779b2ee..3ab42bb 100644
--- a/lib/pages/home/home_page.dart
+++ b/lib/pages/home/home_page.dart
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rogapp/pages/search/search_page.dart';
+// 要検討:SearchPageへのナビゲーションにNavigator.pushを使用していますが、一貫性のためにGet.toやGet.toNamedを使用することを検討してください。
+//
class HomePage extends GetView{
const HomePage({Key? key}) : super(key: key);
diff --git a/lib/pages/index/index_controller.dart b/lib/pages/index/index_controller.dart
index e27f8ee..33e6bc3 100644
--- a/lib/pages/index/index_controller.dart
+++ b/lib/pages/index/index_controller.dart
@@ -166,6 +166,8 @@ class IndexController extends GetxController {
return LatLngBounds(LatLng(x1!, y1!), LatLng(x0!, y0!));
}
+ // 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。
+ //
void login(String email, String password, BuildContext context) {
AuthService.login(email, password).then((value) {
print("------- logged in user details ######## $value ###### --------");
@@ -189,6 +191,8 @@ class IndexController extends GetxController {
});
}
+ // 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。
+ //
void changePassword(
String oldpassword, String newpassword, BuildContext context) {
String token = currentUser[0]['token'];
@@ -230,6 +234,8 @@ class IndexController extends GetxController {
cats.clear();
}
+ // 要検討:エラーハンドリングが行われていますが、エラーメッセージをローカライズすることを検討してください。
+ //
void register(String email, String password, BuildContext context) {
AuthService.register(email, password).then((value) {
if (value.isNotEmpty) {
@@ -345,14 +351,20 @@ class IndexController extends GetxController {
// 2024-04-03 Akira .. Update the code . See ticket 2800.
//
+ // 2024-4-8 Akira : See 2809
+ // IndexControllerクラスでは、Future.delayedの呼び出しをunawaitedで囲んで、非同期処理の結果を待たずに先に進むようにしました。これにより、メモリリークを防ぐことができます
+ //
+ // 要検討:Future.delayedを使用して非同期処理を待たずに先に進むようにしていますが、これによってメモリリークが発生する可能性があります。非同期処理の結果を適切に処理することを検討してください。
+ //
void loadLocationsBound() async {
if (isCustomAreaSelected.value == true) {
return;
}
// Akira 追加:2024-4-6 #2800
- await waitForMapControllerReady(); // MapControllerの初期化が完了するまで待機
+ //await waitForMapControllerReady(); // MapControllerの初期化が完了するまで待機
// Akira 追加:2024-4-6 #2800
+ // ==> remove 2024-4-8
locations.clear();
String cat = currentCat.isNotEmpty ? currentCat[0] : "";
@@ -375,22 +387,25 @@ class IndexController extends GetxController {
isLoading.value = true; // ローディング状態をtrueに設定
- Future.delayed(const Duration(seconds: 1), () async {
+// unawaited( Future.delayed(const Duration(seconds: 1), () async {
+// remove
//print("bounds --- (${bounds.southWest.latitude},${bounds.southWest.longitude}),(${bounds.northWest.latitude},${bounds.northWest.longitude}),(${bounds.northEast.latitude},${bounds.northEast.longitude}),(${bounds.southEast.latitude},${bounds.southEast.longitude})");
- var value = await LocationService.loadLocationsBound(
- bounds.southWest.latitude,
- bounds.southWest.longitude,
- bounds.northWest.latitude,
- bounds.northWest.longitude,
- bounds.northEast.latitude,
- bounds.northEast.longitude,
- bounds.southEast.latitude,
- bounds.southEast.longitude,
- cat
- );
- if ( value == null ) {
+ // 要検討:APIからのレスポンスがnullの場合のエラーハンドリングが不十分です。適切なエラーメッセージを表示するなどの処理を追加してください。
+ try {
+ final value = await LocationService.loadLocationsBound(
+ bounds.southWest.latitude,
+ bounds.southWest.longitude,
+ bounds.northWest.latitude,
+ bounds.northWest.longitude,
+ bounds.northEast.latitude,
+ bounds.northEast.longitude,
+ bounds.southEast.latitude,
+ bounds.southEast.longitude,
+ cat
+ );
+ if (value == null) {
// APIからのレスポンスがnullの場合
print("LocationService.loadLocationsBound からの回答がnullのため、マップをリロード");
//DestinationController destinationController = Get.find(); // 追加
@@ -399,32 +414,41 @@ class IndexController extends GetxController {
// destinationController.fixMapBound(tk); // 追加
//} // 追加
return;
- }
- isLoading.value = false; // ローディング状態をfalseに設定
-
- if (value!=null && value.features.isEmpty) {
+ }
+ isLoading.value = false; // ローディング状態をfalseに設定
+
+ if (value != null && value.features.isEmpty) {
if (showPopup == false) {
return;
}
Get.snackbar(
"Too many Points",
"please zoom in",
- icon: const Icon(Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
+ icon: const Icon(
+ Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
snackPosition: SnackPosition.TOP,
duration: const Duration(seconds: 3),
backgroundColor: Colors.yellow,
);
showPopup = false;
}
- if (value!=null && value.features.isNotEmpty) {
+ if (value != null && value.features.isNotEmpty) {
locations.add(value);
}
-
- });
+ } catch ( e) {
+ print("Error in loadLocationsBound: $e");
+ // エラーが発生した場合のリトライ処理や適切なエラーメッセージの表示を行う
+ // 例えば、一定時間後に再度loadLocationsBound()を呼び出すなど
+
+
+ }));
}
//===Akira 追加:2024-4-6 #2800
+ // 要検討:MapControllerの初期化が完了するまで待機していますが、タイムアウトを設定することを検討してください。
+ // 初期化に時間がかかりすぎる場合、ユーザーにわかりやすいメッセージを表示するようにしてください。
+ //
Future waitForMapControllerReady() async {
if (!isMapControllerReady.value) {
await Future.doWhile(() async {
diff --git a/lib/pages/index/index_page.dart b/lib/pages/index/index_page.dart
index 2bd588a..f08f17b 100644
--- a/lib/pages/index/index_page.dart
+++ b/lib/pages/index/index_page.dart
@@ -22,6 +22,9 @@ import 'package:rogapp/utils/location_controller.dart';
// 全体的に、index_page.dartはアプリのメインページの構造を定義し、他のコンポーネントやページへの橋渡しを行っているファイルです。
//
+// 要検討:GPSデータの表示アイコンをタップした際のエラーハンドリングを追加することをお勧めします。
+// MapWidgetとListWidgetの切り替えにObxを使用していますが、パフォーマンスを考慮して、必要な場合にのみウィジェットを再構築するようにしてください。
+// DestinationControllerのisSimulationModeを使用してGPS信号の強弱をシミュレーションしていますが、本番環境では適切に実際のGPS信号を使用するようにしてください。
// IndexPageクラスは、GetViewを継承したStatelessWidgetです。このクラスは、アプリのメインページを表すウィジェットです。
//
diff --git a/lib/pages/landing/landing_page.dart b/lib/pages/landing/landing_page.dart
index 67127f8..b18eef3 100644
--- a/lib/pages/landing/landing_page.dart
+++ b/lib/pages/landing/landing_page.dart
@@ -2,6 +2,9 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rogapp/routes/app_pages.dart';
+// 要検討:ログインボタンとサインアップボタンの配色を見直すことを検討してください。現在の配色では、ボタンの役割がわかりにくい可能性があります。
+// ボタンのテキストをローカライズすることを検討してください。
+//
class LandingPage extends StatefulWidget {
const LandingPage({ Key? key }) : super(key: key);
diff --git a/lib/pages/loading/loading_page.dart b/lib/pages/loading/loading_page.dart
index 82951e1..e4721d7 100644
--- a/lib/pages/loading/loading_page.dart
+++ b/lib/pages/loading/loading_page.dart
@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
class LoadingPage extends StatelessWidget {
const LoadingPage({Key? key}) : super(key: key);
+ // 要検討:ローディングインジケーターの値を固定値(0.8)にしていますが、実際のローディング進捗に合わせて動的に変更することを検討してください。
+ //
@override
Widget build(BuildContext context) {
return Container(
diff --git a/lib/pages/login/login_page.dart b/lib/pages/login/login_page.dart
index 50a1538..07b2b52 100644
--- a/lib/pages/login/login_page.dart
+++ b/lib/pages/login/login_page.dart
@@ -3,6 +3,10 @@ import 'package:get/get.dart';
import 'package:rogapp/pages/index/index_controller.dart';
import 'package:rogapp/routes/app_pages.dart';
+// 要検討:ログインボタンとサインアップボタンの配色を見直すことを検討してください。現在の配色では、ボタンの役割がわかりにくい可能性があります。
+// エラーメッセージをローカライズすることを検討してください。
+// ログイン処理中にエラーが発生した場合のエラーハンドリングを追加することをお勧めします。
+//
class LoginPage extends StatelessWidget {
final IndexController indexController = Get.find();
diff --git a/lib/pages/login_popup/login_popup_page.dart b/lib/pages/login_popup/login_popup_page.dart
index fa2fea0..5f50fe1 100644
--- a/lib/pages/login_popup/login_popup_page.dart
+++ b/lib/pages/login_popup/login_popup_page.dart
@@ -3,6 +3,10 @@ import 'package:get/get.dart';
import 'package:rogapp/pages/index/index_controller.dart';
import 'package:rogapp/routes/app_pages.dart';
+// 要検討:ログインボタンとサインアップボタンの配色を見直すことを検討してください。現在の配色では、ボタンの役割がわかりにくい可能性があります。
+// エラーメッセージをローカライズすることを検討してください。
+// ポップアップを閉じるボタンを追加することを検討してください。
+//
class LoginPopupPage extends StatelessWidget {
LoginPopupPage({Key? key}) : super(key: key);
diff --git a/lib/pages/permission/permission.dart b/lib/pages/permission/permission.dart
index fd692a6..d104f8d 100644
--- a/lib/pages/permission/permission.dart
+++ b/lib/pages/permission/permission.dart
@@ -70,6 +70,8 @@ class _PermissionHandlerScreenState extends State {
));
}
+ // 要検討:位置情報の許可が拒否された場合、適切なエラーメッセージを表示することを検討してください。
+ //
Future requestPermission() async {
PermissionStatus permission = await Permission.location.status;
if (permission == PermissionStatus.permanentlyDenied) {
@@ -93,6 +95,8 @@ class _PermissionHandlerScreenState extends State {
);
}
+ // 要検討:ユーザーが位置情報の許可を拒否し続けた場合の対処方法を明確にすることをお勧めします。
+ //
void showPermanentAlert() {
showDialog(
context: context,
diff --git a/lib/services/auth_service.dart b/lib/services/auth_service.dart
index 72f058f..ddd5b36 100644
--- a/lib/services/auth_service.dart
+++ b/lib/services/auth_service.dart
@@ -1,6 +1,8 @@
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:rogapp/model/auth_user.dart';
+import 'package:get/get.dart';
+import 'package:flutter/material.dart';
import '../utils/const.dart';
@@ -90,16 +92,35 @@ class AuthService {
String url = '$serverUrl/api/login/';
//print('++++++++$url');
//String url = 'http://localhost:8100/api/login/';
- final http.Response response = await http.post(
- Uri.parse(url),
- headers: {
- 'Content-Type': 'application/json; charset=UTF-8',
- },
- body: jsonEncode({'email': email, 'password': password}),
- );
+ try {
+ final http.Response response = await http.post(
+ Uri.parse(url),
+ headers: {
+ 'Content-Type': 'application/json; charset=UTF-8',
+ },
+ body: jsonEncode(
+ {'email': email, 'password': password}),
+ );
- if (response.statusCode == 200) {
- cats = json.decode(utf8.decode(response.bodyBytes));
+ if (response.statusCode == 200) {
+ cats = json.decode(utf8.decode(response.bodyBytes));
+ } else {
+ print('Login failed with status code: ${response.statusCode}');
+ cats = {};
+ }
+ } catch( e ){
+ print('Error in login: $e');
+ Get.snackbar("通信エラーがおきました", "サーバーと通信できませんでした");
+ Get.snackbar(
+ "通信エラーがおきました",
+ "サーバーと通信できませんでした",
+ icon: const Icon(
+ Icons.assistant_photo_outlined, size: 40.0, color: Colors.blue),
+ snackPosition: SnackPosition.TOP,
+ duration: const Duration(seconds: 3),
+ backgroundColor: Colors.yellow,
+ );
+ cats = {};
}
return cats;
}
diff --git a/lib/services/device_info_service.dart b/lib/services/device_info_service.dart
index aa7b24d..dcbb325 100644
--- a/lib/services/device_info_service.dart
+++ b/lib/services/device_info_service.dart
@@ -1,5 +1,5 @@
import 'dart:io';
-//import 'package:device_info/device_info.dart';
+import 'package:device_info_plus/device_info_plus.dart';
import 'package:flutter/foundation.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:device_info_plus/device_info_plus.dart';
diff --git a/lib/services/error_service.dart b/lib/services/error_service.dart
index c432769..3c3a9ba 100644
--- a/lib/services/error_service.dart
+++ b/lib/services/error_service.dart
@@ -9,7 +9,7 @@ class ErrorService {
final String errorMessage = error.toString();
final String stackTraceString = stackTrace.toString();
final String estimatedCause = _estimateErrorCause(errorMessage);
- // final String deviceInfo = await _getDeviceInfo();
+ //final String deviceInfo = await _getDeviceInfo();
final Uri url = Uri.parse('https://rogaining.sumasen.net/report-error');
final response = await http.post(
@@ -44,5 +44,17 @@ class ErrorService {
return '不明なエラー';
}
}
+
+ /*
+ // 2024-4-8 Akira: メモリ使用量のチェックのため追加 See #2810
+ //
+ static void reportMemoryError(String message, StackTrace stackTrace) async {
+ final errorDetails = FlutterErrorDetails(
+ exception: Exception(message),
+ stack: stackTrace,
+ );
+ await reportError(errorDetails.exception, errorDetails.stack ?? StackTrace.current, deviceInfo);
+ }
+ */
}
diff --git a/lib/services/external_service.dart b/lib/services/external_service.dart
index a3b1905..c0d8c1d 100644
--- a/lib/services/external_service.dart
+++ b/lib/services/external_service.dart
@@ -114,64 +114,69 @@ class ExternalService {
//print("~~~~ before calling api 1 ~~~~");
- final http.Response response = await http.post(
- Uri.parse(url1),
- headers: {
- 'Content-Type': 'application/json; charset=UTF-8',
- 'Authorization': 'Token $token'
- },
- // 'id', 'user', 'goalimage', 'goaltime', 'team_name', 'event_code','cp_number'
- body: jsonEncode({
- 'user': userId.toString(),
- 'team_name': teamname,
- 'event_code': eventcode,
- 'checkinimage': im1_64,
- 'checkintime': checkinTime,
- 'cp_number': cp.toString()
- }),
- );
-
- res = json.decode(utf8.decode(response.bodyBytes));
- //print("~~~~ api1 result $res ~~~~");
- //print("-----@@@@@ checkin $_res -----");
-
- if (response.statusCode == 201) {
- //print("~~~~ image from api1 ${res["checkinimage"].toString()} ~~~~");
- //print('---- toekn is ${token} -----');
- //print("~~~~ token is $token ~~~~");
- //print("~~~~ before callling api2 ~~~~");
- final http.Response response2 = await http.post(
- Uri.parse(url),
+ try {
+ final http.Response response = await http.post(
+ Uri.parse(url1),
headers: {
'Content-Type': 'application/json; charset=UTF-8',
+ 'Authorization': 'Token $token'
},
+ // 'id', 'user', 'goalimage', 'goaltime', 'team_name', 'event_code','cp_number'
body: jsonEncode({
+ 'user': userId.toString(),
+ 'team_name': teamname,
+ 'event_code': eventcode,
+ 'checkinimage': im1_64,
+ 'checkintime': checkinTime,
+ 'cp_number': cp.toString()
+ }),
+ );
+
+ res = json.decode(utf8.decode(response.bodyBytes));
+ //print("~~~~ api1 result $res ~~~~");
+ //print("-----@@@@@ checkin $_res -----");
+
+ if (response.statusCode == 201) {
+ //print("~~~~ image from api1 ${res["checkinimage"].toString()} ~~~~");
+ //print('---- toekn is ${token} -----');
+ //print("~~~~ token is $token ~~~~");
+ //print("~~~~ before callling api2 ~~~~");
+ final http.Response response2 = await http.post(
+ Uri.parse(url),
+ headers: {
+ 'Content-Type': 'application/json; charset=UTF-8',
+ },
+ body: jsonEncode({
+ 'team_name': teamname,
+ 'cp_number': cp.toString(),
+ 'event_code': eventcode,
+ 'image': res["checkinimage"].toString().replaceAll(
+ 'http://localhost:8100', 'http://rogaining.sumasen.net')
+ }),
+ );
+ var vv = jsonEncode({
'team_name': teamname,
'cp_number': cp.toString(),
'event_code': eventcode,
'image': res["checkinimage"].toString().replaceAll(
'http://localhost:8100', 'http://rogaining.sumasen.net')
- }),
- );
- var vv = jsonEncode({
- 'team_name': teamname,
- 'cp_number': cp.toString(),
- 'event_code': eventcode,
- 'image': res["checkinimage"].toString().replaceAll(
- 'http://localhost:8100', 'http://rogaining.sumasen.net')
- });
- //print("~~~~ api 2 values $vv ~~~~");
- //print("--json-- $vv");
- //print("--- checnin response ${response2.statusCode}----");
- if (response2.statusCode == 200) {
- res = json.decode(utf8.decode(response2.bodyBytes));
- //print('----checkin res _res : $res ----');
- if (res["status"] == "ERROR") {
- Get.snackbar("エラーがおきました", res["detail"]);
+ });
+ //print("~~~~ api 2 values $vv ~~~~");
+ //print("--json-- $vv");
+ //print("--- checnin response ${response2.statusCode}----");
+ if (response2.statusCode == 200) {
+ res = json.decode(utf8.decode(response2.bodyBytes));
+ //print('----checkin res _res : $res ----');
+ if (res["status"] == "ERROR") {
+ Get.snackbar("エラーがおきました", res["detail"]);
+ }
}
+ } else {
+ Get.snackbar("サーバーエラーがおきました", "サーバーと通信できませんでした");
}
- } else {
- Get.snackbar("エラーがおきました", "サーバーに更新できませんでした");
+ } catch( e ) {
+ print('Error in makeCheckpoint: $e');
+ Get.snackbar("通信エラーがおきました", "サーバーと通信できませんでした");
}
}
} else {
diff --git a/lib/utils/location_controller.dart b/lib/utils/location_controller.dart
index 8108f88..4c2efe3 100644
--- a/lib/utils/location_controller.dart
+++ b/lib/utils/location_controller.dart
@@ -77,6 +77,9 @@ class LocationController extends GetxController {
// エラーが発生した場合は、locationMarkerPositionStreamControllerにエラーを追加します。
// ストリームが一時停止中の場合は、ストリームを再開します。
//
+ // 2024-4-8 Akira : See 2809
+ // stopPositionStreamメソッドを追加して、既存のストリームをキャンセルするようにしました。また、ストリームが完了したらnullに設定し、エラー発生時にストリームをキャンセルするようにしました。
+ //
void startPositionStream() async {
// Check for location service and permissions before starting the stream
bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
@@ -161,8 +164,7 @@ class LocationController extends GetxController {
await positionStream?.cancel();
- positionStream =
- Geolocator.getPositionStream(locationSettings: locationOptions).listen(
+ positionStream = Geolocator.getPositionStream(locationSettings: locationOptions).listen(
(Position? position) {
if (position != null) {
final LocationMarkerPosition locationMarkerPosition =
@@ -170,14 +172,18 @@ class LocationController extends GetxController {
latitude: position.latitude,
longitude: position.longitude,
accuracy: position.accuracy);
- locationMarkerPositionStreamController.add(locationMarkerPosition);
- } else {
- locationMarkerPositionStreamController.add(null);
- }
- },
- onError: (e) {
- locationMarkerPositionStreamController.addError(e);
- },
+ locationMarkerPositionStreamController.add(locationMarkerPosition);
+ } else {
+ locationMarkerPositionStreamController.add(null);
+ }
+ },
+ onError: (e) {
+ locationMarkerPositionStreamController.addError(e);
+ },
+ onDone: () {
+ positionStream = null; // ストリームが完了したらnullに設定
+ },
+ cancelOnError: true // エラー発生時にストリームをキャンセル
);
// Resume stream if it was paused previously
@@ -192,10 +198,14 @@ class LocationController extends GetxController {
// positionStreamが存在する場合、ストリームを一時停止します。
// isStreamPausedフラグをtrueに設定します。
//
- void stopPositionStream() {
+ void stopPositionStream() async {
if (positionStream != null) {
- positionStream!.pause();
- isStreamPaused = true;
+ // updated Akira 2024-4-8
+ await positionStream!.cancel();
+ positionStream = null;
+
+ //positionStream!.pause();
+ //isStreamPaused = true;
}
}
diff --git a/lib/widgets/custom_icons.dart b/lib/widgets/custom_icons.dart
new file mode 100644
index 0000000..26d9333
--- /dev/null
+++ b/lib/widgets/custom_icons.dart
@@ -0,0 +1,9 @@
+import 'package:flutter/material.dart';
+
+class CustomIcons {
+ static const _fontFamily = 'CustomIcons';
+
+ static const IconData gps_signal_low = IconData(0xe900, fontFamily: _fontFamily);
+ static const IconData gps_signal_middle = IconData(0xe913, fontFamily: _fontFamily);
+ static const IconData gps_signal_high = IconData(0xe91d, fontFamily: _fontFamily);
+}
diff --git a/lib/widgets/gps_status.dart b/lib/widgets/gps_status.dart
index 68a79dc..c27f522 100644
--- a/lib/widgets/gps_status.dart
+++ b/lib/widgets/gps_status.dart
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:rogapp/widgets/GameState/Colors.dart';
import 'package:rogapp/pages/destination/destination_controller.dart';
-//import 'package:rogapp/widgets/custom_icons.dart';
+import 'package:rogapp/widgets/custom_icons.dart';
enum GPSStatus { high, middle, low }
@@ -30,19 +30,19 @@ class GpsSignalStrengthIndicator extends StatelessWidget {
case 'high':
backgroundColor = Colors.green;
iconData = Icons.signal_cellular_alt;
- //iconData = CustomIcons.gps_signal_high_0;
+ // iconData = CustomIcons.gps_signal_high;
text = 'GPS 強';
break;
case 'medium':
backgroundColor = Colors.orange;
iconData = Icons.signal_cellular_alt_2_bar;
- //iconData = CustomIcons.gps_signal_middle_0;
+ // iconData = CustomIcons.gps_signal_middle;
text = 'GPS 中';
break;
default:
backgroundColor = Colors.grey; // Fallback color
iconData = Icons.signal_cellular_connected_no_internet_4_bar;
- //iconData = CustomIcons.gps_signal_low_0;
+ // iconData = CustomIcons.gps_signal_low;
text = 'GPS 弱';
}
diff --git a/lib/widgets/map_widget.dart b/lib/widgets/map_widget.dart
index bc83327..20c1896 100644
--- a/lib/widgets/map_widget.dart
+++ b/lib/widgets/map_widget.dart
@@ -18,6 +18,21 @@ import 'package:rogapp/widgets/bottom_sheet_new.dart';
import 'package:rogapp/widgets/current_position_widget.dart';
import 'package:rogapp/widgets/game_state_view.dart';
+// map_widget.dartファイルは、アプリ内の地図表示を担当するウィジェットを定義しています。以下に、主要な部分を解説します。
+// 地図表示に関連する主要な機能を提供しています。以下のような機能が含まれています。
+//
+// 地図の表示と操作
+// マーカーの表示とカスタマイズ
+// ルートの表示
+// 現在位置の表示
+// アイドル状態の処理
+// ローディングインジケーターの表示
+// ゲーム状態の表示
+// 現在位置ボタンの表示
+
+
+// StatefulWidgetを継承したクラスで、地図表示のメインウィジェットです。
+//
class MapWidget extends StatefulWidget {
MapWidget({Key? key}) : super(key: key);
@@ -25,16 +40,23 @@ class MapWidget extends StatefulWidget {
State createState() => _MapWidgetState();
}
+// MapWidgetの状態を管理するクラスです。
+//
class _MapWidgetState extends State {
final IndexController indexController = Get.find();
-
+ // IndexControllerのインスタンスを保持します。
final DestinationController destinationController =
Get.find();
+ // DestinationControllerのインスタンスを保持します。
final LocationController locationController = Get.find();
+ // LocationControllerのインスタンスを保持します。
- StreamSubscription? subscription;
- Timer? _timer;
+ StreamSubscription? subscription; // 地図イベントの購読を保持します。
+ Timer? _timer; // アイドル状態のタイマーを保持します。
+ // 地図上のマーカーのUIを生成するメソッドです。
+ // GeoJSONFeatureを受け取り、マーカーのUIを返します。
+ //
Widget getMarkerShape(GeoJSONFeature i, BuildContext context) {
GeoJSONMultiPoint p = i.geometry as GeoJSONMultiPoint;
//print("lat is ${p.geoSerie!.geoPoints[0].latitude} and lon is ${p.geoSerie!.geoPoints[0].longitude}");
@@ -155,6 +177,9 @@ class _MapWidgetState extends State {
);
}
+ // ルートポイントをLatLngのリストに変換するメソッドです。
+ // IndexControllerのroutePointsからLatLngのリストを生成しています。
+ //
List? getPoints() {
//print("##### --- route point ${indexController.routePoints.length}");
List pts = [];
@@ -165,21 +190,31 @@ class _MapWidgetState extends State {
return pts;
}
+ // ウィジェットの初期化時に呼び出されるメソッドです。
+ // _startIdleTimerメソッドを呼び出して、アイドル状態のタイマーを開始します。
+ //
@override
void initState() {
super.initState();
- _startIdleTimer();
+ _startIdleTimer(); // _startIdleTimerメソッドを呼び出してアイドル状態のタイマーを開始しています。
}
+ // アイドル状態のタイマーを開始するメソッドです。
+ // 一定時間後に_centerMapOnUserメソッドを呼び出すようにタイマーを設定しています。
+ //
void _startIdleTimer() {
_timer = Timer(const Duration(milliseconds: (1000 * 10)), _centerMapOnUser);
}
+ // アイドル状態のタイマーをリセットするメソッドです。
+ //
void _resetTimer() {
_timer?.cancel();
_startIdleTimer();
}
+ // 地図をユーザーの現在位置に中央揃えするメソッドです。
+ //
void _centerMapOnUser() {
assert(() {
print("showBottomSheet ${destinationController.shouldShowBottomSheet}");
@@ -192,6 +227,13 @@ class _MapWidgetState extends State {
//}
}
+ // ウィジェットのUIを構築するメソッドです。
+ // FlutterMapウィジェットを使用して地図を表示します。
+ // layersプロパティに、ベースレイヤー、ルートレイヤー、現在位置レイヤー、マーカーレイヤーを設定します。
+ // PopupControllerを使用して、ポップアップの制御を行います。
+ // IndexControllerのisLoading変数に基づいて、ローディングインジケーターを表示します。
+ // GameStateWidgetとCurrentPositionウィジェットを重ねて表示します。
+ //
@override
Widget build(BuildContext context) {
// print(
@@ -200,18 +242,22 @@ class _MapWidgetState extends State {
final PopupController popupController = PopupController();
return Stack(
children: [
+ // IndexControllerのisLoading変数に基づいて、ローディングインジケーターを表示します。
+ // isLoadingがtrueの場合はCircularProgressIndicatorを表示し、falseの場合は地図を表示します。
Obx(() => indexController.isLoading.value == true
? const Padding(
padding: EdgeInsets.only(top: 60.0),
child: CircularProgressIndicator(),
)
: FlutterMap(
+ // 地図の表示を担当
mapController: indexController.mapController,
options: MapOptions(
+ // 地図の初期設定(最大ズームレベル、初期位置、ズームレベルなど)を行っています。
maxZoom: 18.4,
onMapReady: () {
- // print("Map controller ready!!"); ... working corretly
- indexController.isMapControllerReady.value = true; // Added Akira,2024-4-6 for #2800
+ // print("Map controller ready!!"); ... working corretly
+ indexController.isMapControllerReady.value = true; // Added Akira,2024-4-6 for #2800
subscription = indexController.mapController.mapEventStream
.listen((MapEvent mapEvent) {
@@ -235,6 +281,7 @@ class _MapWidgetState extends State {
InteractiveFlag.pinchZoom | InteractiveFlag.drag,
onPositionChanged: (MapPosition pos, hasGesture) {
+ // 地図の位置が変更された際の処理を行います。
//print("map position changed ${pos.center!.latitude}");
if (hasGesture) {
_resetTimer();
@@ -249,9 +296,10 @@ class _MapWidgetState extends State {
Obx(
() => indexController.routePointLenght > 0
? PolylineLayer(
+ // ルートの表示を担当
polylines: [
Polyline(
- points: getPoints()!,
+ points: getPoints()!, // ルートのポイントを設定しています。
strokeWidth: 6.0,
color: Colors.indigo),
],
@@ -259,11 +307,14 @@ class _MapWidgetState extends State {
: Container(),
),
CurrentLocationLayer(
+ // 現在位置の表示を担当
positionStream: locationController
.locationMarkerPositionStreamController.stream,
+ // locationMarkerPositionStreamController.streamを設定して、現在位置の更新を監視しています。
alignDirectionOnUpdate: AlignOnUpdate.never,
turnOnHeadingUpdate: TurnOnHeadingUpdate.never,
style: const LocationMarkerStyle(
+ // styleプロパティで、現在位置のマーカーのスタイルを設定しています。
marker: DefaultLocationMarker(
child: Icon(
Icons.navigation,
@@ -277,6 +328,7 @@ class _MapWidgetState extends State {
indexController.locations.isNotEmpty &&
indexController.locations[0].features.isNotEmpty
? MarkerLayer(
+ // マーカーの表示を担当
markers:
indexController.locations[0].features.map((i) {
//print("i si ${i.properties!['location_id']}");
@@ -293,13 +345,29 @@ class _MapWidgetState extends State {
point: LatLng(
p.coordinates[0][1], p.coordinates[0][0]),
child: getMarkerShape(i, context));
+ // マーカーのUIを生成しています。
+ // マーカーのアイコン、ラベル、色などをカスタマイズしています。
}).toList(),
)
: const Center(child: CircularProgressIndicator()),
],
)),
const Positioned(top: 0, left: 0, child: GameStateWidget()),
- const Positioned(bottom: 10, right: 10, child: CurrentPosition())
+ // ゲーム状態の表示を担当。ゲームの状態(開始、終了など)を表示するカスタムウィジェットです。
+ const Positioned(bottom: 10, right: 10, child: CurrentPosition()),
+ // 現在位置ボタンの表示を担当。現在位置に移動するためのボタンを表示するカスタムウィジェットです。
+ StreamBuilder(
+ stream: locationController.locationMarkerPositionStream,
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ print("Display current marker");
+ } else {
+ print("Not display current marker");
+ }
+ return Container();
+ },
+ )
+
// const Positioned(
// bottom: 10,
// left: 0,
diff --git a/pubspec.yaml b/pubspec.yaml
index 5c79059..c128997 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -135,6 +135,12 @@ flutter:
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
+
+ fonts:
+ - family: CustomIcons
+ fonts:
+ - asset: assets/fonts/icomoon.ttf
+
# fonts:
# - family: Schyler
# fonts: