diff --git a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap index 3c60f41c2..4b4269831 100644 --- a/__tests__/components/viewers/__snapshots__/nearby-view.js.snap +++ b/__tests__/components/viewers/__snapshots__/nearby-view.js.snap @@ -45,7 +45,7 @@ exports[`components > viewers > nearby view renders nothing on a blank page 1`] className="nearby-view base-color-bg" >
viewers > nearby view renders nothing on a blank page 1`] } >
    viewers > nearby view renders proper scooter dates 1`] = ` className="nearby-view base-color-bg" >
    viewers > nearby view renders proper scooter dates 1`] = ` } >
      viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
      viewers > nearby view renders proper scooter dates 1`] = ` >

      Roosevelt Station - Bay 2 @@ -10030,7 +10030,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

      viewers > nearby view renders proper scooter dates 1`] = `

      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
      • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = `

          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

        1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = `

            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

          1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = `

              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

              viewers > nearby view renders proper scooter dates 1`] = ` >

              Roosevelt @@ -16849,7 +16849,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

              viewers > nearby view renders proper scooter dates 1`] = `

              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
              • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = `

                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = `

                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                      viewers > nearby view renders proper scooter dates 1`] = ` >

                      Roosevelt Station - Bay 1 @@ -26336,7 +26336,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                      viewers > nearby view renders proper scooter dates 1`] = `

                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                        viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                      • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = `

                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                        1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = `

                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                          1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = `

                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="988" > viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                viewers > nearby view renders proper scooter dates 1`] = ` >

                                Roosevelt Station Bay 5 - Bay 5 @@ -35850,7 +35850,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                viewers > nearby view renders proper scooter dates 1`] = `

                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                  viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                • viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = `

                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = `

                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="984" > viewers > nearby view renders proper scooter dates 1`] = `

                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = `

                                        viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                        viewers > nearby view renders proper scooter dates 1`] = ` >

                                        Roosevelt @@ -43656,7 +43656,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                        viewers > nearby view renders proper scooter dates 1`] = `

                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                          viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                        • viewers > nearby view renders proper scooter dates 1`] = ` title="1 Line" > viewers > nearby view renders proper scooter dates 1`] = `

                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                            viewers > nearby view renders proper scooter dates 1`] = ` >

                                            Roosevelt Station - Bay 3 @@ -51198,7 +51198,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                            viewers > nearby view renders proper scooter dates 1`] = `

                                            viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                              viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                            • viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = `

                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="67" > viewers > nearby view renders proper scooter dates 1`] = `

                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                1. viewers > nearby view renders proper scooter dates 1`] = ` title="522" > viewers > nearby view renders proper scooter dates 1`] = `

                                                    viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                  1. viewers > nearby view renders proper scooter dates 1`] = ` title="73" > viewers > nearby view renders proper scooter dates 1`] = `

                                                      viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                    1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = `

                                                        viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                      1. viewers > nearby view renders proper scooter dates 1`] = ` title="322" > viewers > nearby view renders proper scooter dates 1`] = `

                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = `

                                                          viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                          viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          NE 65th St & 14th Ave NE @@ -62309,7 +62309,7 @@ exports[`components > viewers > nearby view renders proper scooter dates 1`] = ` >

                                                          viewers > nearby view renders proper scooter dates 1`] = `

                                                          viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` size="0.9em" > viewers > nearby view renders proper scooter dates 1`] = ` >
                                                            viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >
                                                          • viewers > nearby view renders proper scooter dates 1`] = ` title="45" > viewers > nearby view renders proper scooter dates 1`] = `

                                                              viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                            1. viewers > nearby view renders proper scooter dates 1`] = ` title="62" > viewers > nearby view renders proper scooter dates 1`] = `

                                                                viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` roundedTop={false} >

                                                              1. viewers > nearby view renders proper scooter dates 1`] = ` title="79" > viewers > nearby view renders proper scooter dates 1`] = `

                                                                  viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.realtime" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` iconViewBox="0 0 448 512" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > nearby view renders proper scooter dates 1`] = ` title="components.StopTimeCell.scheduled" > viewers > nearby view renders proper scooter dates 1`] = ` > viewers > stop viewer should render with initial stop id a > viewers > stop viewer should render with initial stop id a

                                                          aoi', () => { + describe('getDefaultQuery', () => { + it('initializes numItineraries from config', () => { + const config = { + modes: { + numItineraries: 5 + } + } + expect(getDefaultQuery(config).numItineraries).toBe(5) + + expect(getDefaultQuery({}).numItineraries).toBe(3) + }) + }) +}) diff --git a/__tests__/util/pattern-viewer.ts b/__tests__/util/pattern-viewer.ts deleted file mode 100644 index 79b3957f7..000000000 --- a/__tests__/util/pattern-viewer.ts +++ /dev/null @@ -1,68 +0,0 @@ -import '../test-utils/mock-window-url' -import { extractMainHeadsigns } from '../../lib/util/pattern-viewer' - -function createStops(ids) { - return ids.map((id) => ({ - id, - name: id - })) -} - -function editHeadsign(pattern) { - pattern.headsign = `${pattern.headsign} (${pattern.lastStop})` -} - -describe('util > pattern-viewer', () => { - describe('extractMainHeadsigns', () => { - it('should retain the essential patterns', () => { - // Consider the following patterns P1, P2, P3 of the same route with the same headsigns: - // Stops S1 S2 S3 S4 S5 S6 S7 --> direction of travel - // P1: o--o--o--o--o - // P2: o--o-----o--o - // P3: o--o--o - // - // P3 should be removed because it is a subset of P1. - // P1 and P2 should be kept. - // Patterns are assumed in descending length order because - // pre-sorting happened before extractMainHeadsigns is invoked (key order matters). - const headsign = 'Everett via Lynnwood' - const route = '512' - const patterns = { - P1: { - headsign, - id: 'P1', - name: 'P1 Pattern name', - patternGeometry: { - length: 1404, - points: 'p1-points' - }, - stops: createStops(['S1', 'S2', 'S3', 'S4', 'S5']) - }, - P2: { - headsign, - id: 'P2', - name: 'P2 Pattern name', - patternGeometry: { - length: 1072, - points: 'p2-points' - }, - stops: createStops(['S3', 'S4', 'S6', 'S7']) - }, - P3: { - headsign, - id: 'P3', - name: 'P3 Pattern name', - patternGeometry: { - length: 987, - points: 'p3-points' - }, - stops: createStops(['S3', 'S4', 'S5']) - } - } - const headsignData = extractMainHeadsigns(patterns, route, editHeadsign) - expect(headsignData.length).toBe(2) - expect(headsignData[0].headsign).toBe(headsign) - expect(headsignData[1].headsign).toBe(`${headsign} (S7)`) - }) - }) -}) diff --git a/a11y/a11y.test.js b/a11y/a11y.test.js index 255b0c23a..65dd8c492 100644 --- a/a11y/a11y.test.js +++ b/a11y/a11y.test.js @@ -94,7 +94,7 @@ routes.forEach((route) => { test('Mocked Main Trip planner page should pass Axe Tests', async () => { await runAxeTestOnPath( - '/?ui_activeSearch=0qoydlnut&ui_activeItinerary=0&fromPlace=1900%20Main%20Street%2C%20Houston%2C%20TX%2C%20USA%3A%3A29.750144%2C-95.370998&toPlace=800%20Congress%2C%20Houston%2C%20TX%2C%20USA%3A%3A29.76263%2C-95.362178&date=2021-08-04&time=08%3A14&arriveBy=false&mode=WALK%2CBUS%2CTRAM&walkSpeed=1.34&numItineraries=3' + '/?ui_activeSearch=0qoydlnut&ui_activeItinerary=0&fromPlace=1900%20Main%20Street%2C%20Houston%2C%20TX%2C%20USA%3A%3A29.750144%2C-95.370998&toPlace=800%20Congress%2C%20Houston%2C%20TX%2C%20USA%3A%3A29.76263%2C-95.362178&date=2021-08-04&time=08%3A14&arriveBy=false&mode=WALK%2CBUS%2CTRAM&showIntermediateStops=true&maxWalkDistance=1207&optimize=QUICK&walkSpeed=1.34&ignoreRealtimeUpdates=true&numItineraries=3&otherThanPreferredRoutesPenalty=900' ) }) diff --git a/a11y/mocks/plan.json b/a11y/mocks/plan.json index 4c288bf1b..946b9518f 100644 --- a/a11y/mocks/plan.json +++ b/a11y/mocks/plan.json @@ -1 +1 @@ -{"requestParameters":{"date":"2021-08-04","walkSpeed":"1.34","fromPlace":"1900 Main Street, Houston, TX, USA::29.750144,-95.370998","numItineraries":"3","mode":"WALK,BUS,TRAM","arriveBy":"false","toPlace":"800 Congress, Houston, TX, USA::29.76263,-95.362178","time":"08:14"},"plan":{"date":1628082840000,"from":{"name":"1900 Main Street, Houston, TX, USA","lon":-95.370998,"lat":29.750144,"orig":"1900 Main Street, Houston, TX, USA","vertexType":"NORMAL"},"to":{"name":"800 Congress, Houston, TX, USA","lon":-95.362178,"lat":29.76263,"orig":"800 Congress, Houston, TX, USA","vertexType":"NORMAL"},"itineraries":[{"duration":392,"startTime":1628083300000,"endTime":1628083692000,"walkTime":210,"transitTime":180,"waitingTime":2,"walkDistance":259.1391641774315,"walkLimitExceeded":false,"elevationLost":0.0,"elevationGained":0.0,"transfers":0,"fare":{"fare":{"regular":{"currency":{"symbol":"$","currency":"USD","defaultFractionDigits":2,"currencyCode":"USD"},"cents":125}},"details":{}},"legs":[{"startTime":1628083300000,"endTime":1628083379000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":88.17900000000003,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"1900 Main Street, Houston, TX, USA","lon":-95.370998,"lat":29.750144,"departure":1628083300000,"orig":"1900 Main Street, Houston, TX, USA","vertexType":"NORMAL"},"to":{"name":"Travis St @ St Joseph Pkwy","stopId":"Houston:624","stopCode":"624","lon":-95.371177,"lat":29.750596,"arrival":1628083379000,"departure":1628083380000,"stopIndex":101,"stopSequence":102,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"kqqtDvcbeQw@m@GLCBADCDABCDCFEHCBCFABHF","length":14},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":79.0,"intermediateStops":[],"steps":[{"distance":81.20200000000003,"relativeDirection":"DEPART","streetName":"sidewalk","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":true,"lon":-95.37099129880164,"lat":29.750140100302744,"elevation":[]},{"distance":6.977,"relativeDirection":"LEFT","streetName":"sidewalk","absoluteDirection":"SOUTHWEST","stayOn":true,"area":false,"bogusName":true,"lon":-95.37113400000001,"lat":29.750646500000002,"elevation":[]}]},{"startTime":1628083380000,"endTime":1628083560000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":1423.885970658207,"pathway":false,"mode":"BUS","route":"082","agencyName":"Metropolitan Transit Authority of Harris County","agencyUrl":"http://www.ridemetro.org","agencyTimeZoneOffset":-18000000,"routeColor":"004080","routeType":3,"routeId":"Houston:41336","routeTextColor":"FFFFFF","interlineWithPreviousLeg":false,"tripShortName":"WHEIMER","tripBlockId":"1062305","headsign":"DOWNTOWN","agencyId":"HOU","tripId":"Houston:9129562","serviceDate":"20210804","from":{"name":"Travis St @ St Joseph Pkwy","stopId":"Houston:624","stopCode":"624","lon":-95.371177,"lat":29.750596,"arrival":1628083379000,"departure":1628083380000,"stopIndex":101,"stopSequence":102,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"Travis St @ Prairie St","stopId":"Houston:667","stopCode":"667","lon":-95.362814,"lat":29.761145,"arrival":1628083560000,"departure":1628083561000,"stopIndex":106,"stopSequence":107,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"mtqtDhebeQWSyCwBsCuBuCwB{BcBYSsCsB_CcBSQwCyB}BaBSQwCsBsCuBaCgBSMsCyB{CwBiCiB","length":20},"interStopGeometry":[{"points":"mtqtDhebeQWSyCwBsCuBuCwB{BcB","length":6},{"points":"egrtDjvaeQYSsCsB_CcB","length":4},{"points":"sprtD~naeQSQwCyB}BaB","length":4},{"points":"}yrtDpgaeQSQwCsBsCuBaCgB","length":5},{"points":"_hstDl|`eQSMsCyB{CwBiCiB","length":5}],"alerts":[{"alertDescriptionText":"","alertUrl":"https://www.ridemetro.org/Pages/Coronavirus.aspx","effectiveStartDate":1625842020000,"alertHeaderText":"Federal law requires anyone on the METRO system to wear a face mask. This includes rail stations, transit centers and bus stops. Exemptions are available for children under the age of two and for those with a disability defined by the ADA."}],"routeShortName":"082","routeLongName":"WESTHEIMER","rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":true,"duration":180.0,"intermediateStops":[{"name":"Travis St @ Bell St","stopId":"Houston:628","stopCode":"628","lon":-95.368804,"lat":29.753604,"arrival":1628083431000,"departure":1628083431000,"stopIndex":102,"stopSequence":103,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Polk St","stopId":"Houston:685","stopCode":"685","lon":-95.367596,"lat":29.755096,"arrival":1628083456000,"departure":1628083456000,"stopIndex":103,"stopSequence":104,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Lamar St","stopId":"Houston:661","stopCode":"661","lon":-95.366423,"lat":29.756601,"arrival":1628083481000,"departure":1628083481000,"stopIndex":104,"stopSequence":105,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Rusk St","stopId":"Houston:664","stopCode":"664","lon":-95.364659,"lat":29.758853,"arrival":1628083519000,"departure":1628083519000,"stopIndex":105,"stopSequence":106,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"}],"steps":[]},{"startTime":1628083561000,"endTime":1628083692000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":170.893,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"Travis St @ Prairie St","stopId":"Houston:667","stopCode":"667","lon":-95.362814,"lat":29.761145,"arrival":1628083560000,"departure":1628083561000,"stopIndex":106,"stopSequence":107,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"800 Congress, Houston, TX, USA","lon":-95.362178,"lat":29.76263,"arrival":1628083692000,"orig":"800 Congress, Houston, TX, USA","vertexType":"NORMAL"},"legGeometry":{"points":"kvstD`q`eQSOgAw@y@m@IGMIKIcAu@","length":8},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":131.0,"intermediateStops":[],"steps":[{"distance":170.893,"relativeDirection":"DEPART","streetName":"Travis Street","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":false,"lon":-95.36288624616279,"lat":29.761188019319103,"elevation":[]}]}],"tooSloped":false},{"duration":515,"startTime":1628083218000,"endTime":1628083733000,"walkTime":156,"transitTime":357,"waitingTime":2,"walkDistance":182.0511194004663,"walkLimitExceeded":false,"elevationLost":0.0,"elevationGained":0.0,"transfers":0,"fare":{"fare":{"regular":{"currency":{"symbol":"$","currency":"USD","defaultFractionDigits":2,"currencyCode":"USD"},"cents":200}},"details":{}},"legs":[{"startTime":1628083218000,"endTime":1628083319000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":111.22700000000003,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"1900 Main Street, Houston, TX, USA","lon":-95.370998,"lat":29.750144,"departure":1628083218000,"orig":"1900 Main Street, Houston, TX, USA","vertexType":"NORMAL"},"to":{"name":"St Joseph Pkwy @ Travis St","stopId":"Houston:310","stopCode":"310","lon":-95.370944,"lat":29.750747,"arrival":1628083319000,"departure":1628083320000,"stopIndex":8,"stopSequence":9,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"kqqtDvcbeQw@m@GLCBADCDABCDCFEHCBCFABOMOMFK","length":16},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":101.0,"intermediateStops":[],"steps":[{"distance":81.20200000000003,"relativeDirection":"DEPART","streetName":"sidewalk","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":true,"lon":-95.37099129880164,"lat":29.750140100302744,"elevation":[]},{"distance":30.025,"relativeDirection":"UTURN_RIGHT","streetName":"sidewalk","absoluteDirection":"SOUTHEAST","stayOn":true,"area":false,"bogusName":true,"lon":-95.37099780000001,"lat":29.750805200000002,"elevation":[]}]},{"startTime":1628083320000,"endTime":1628083677000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":1524.458915954146,"pathway":false,"mode":"BUS","route":"249","agencyName":"Metropolitan Transit Authority of Harris County","agencyUrl":"http://www.ridemetro.org","agencyTimeZoneOffset":-18000000,"routeColor":"004080","routeType":3,"routeId":"Houston:41364","routeTextColor":"FFFFFF","interlineWithPreviousLeg":false,"tripShortName":"BAY AREA","tripBlockId":"1062867","headsign":"DOWNTOWN / VIA EASTWOOD TC","agencyId":"HOU","tripId":"Houston:9135066","serviceDate":"20210804","from":{"name":"St Joseph Pkwy @ Travis St","stopId":"Houston:310","stopCode":"310","lon":-95.370944,"lat":29.750747,"arrival":1628083319000,"departure":1628083320000,"stopIndex":8,"stopSequence":9,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"Travis St @ Preston St","stopId":"Houston:630","stopCode":"630","lon":-95.362244,"lat":29.761898,"arrival":1628083677000,"departure":1628083678000,"stopIndex":15,"stopSequence":16,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"utqtDxcbeQOZyCwBsCuByBaB[UuCwB{BaBWQsCuB}BcBYUqCsBcCcBSOsCuBaCgBSMsCyB_CaB[U_DyB}BeB","length":23},"interStopGeometry":[{"points":"utqtDxcbeQOZyCwBsCuByBaB","length":5},{"points":"mbrtDdzaeQ[UuCwB{BaB","length":4},{"points":"{krtDtraeQWQsCuB}BcB","length":4},{"points":"eurtDhkaeQYUqCsBcCcB","length":4},{"points":"u~rtDzcaeQSOsCuBaCgB","length":4},{"points":"_hstDl|`eQSMsCyB_CaB","length":4},{"points":"gqstDbu`eQ[U_DyB}BeB","length":4}],"alerts":[{"alertDescriptionText":"","alertUrl":"https://www.ridemetro.org/Pages/Coronavirus.aspx","effectiveStartDate":1625842020000,"alertHeaderText":"Federal law requires anyone on the METRO system to wear a face mask. This includes rail stations, transit centers and bus stops. Exemptions are available for children under the age of two and for those with a disability defined by the ADA."}],"routeShortName":"249","routeLongName":"MONROE/FUQUA/EL DORADO/BAY AREA P&R","rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":true,"duration":357.0,"intermediateStops":[{"name":"Travis St @ Leeland St","stopId":"Houston:627","stopCode":"627","lon":-95.369404,"lat":29.752841,"arrival":1628083389000,"departure":1628083389000,"stopIndex":9,"stopSequence":10,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Clay St","stopId":"Houston:629","stopCode":"629","lon":-95.36821,"lat":29.754346,"arrival":1628083435000,"departure":1628083435000,"stopIndex":10,"stopSequence":11,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Dallas St","stopId":"Houston:660","stopCode":"660","lon":-95.367027,"lat":29.755835,"arrival":1628083480000,"departure":1628083480000,"stopIndex":11,"stopSequence":12,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Mc Kinney St","stopId":"Houston:662","stopCode":"662","lon":-95.365814,"lat":29.757345,"arrival":1628083526000,"departure":1628083526000,"stopIndex":12,"stopSequence":13,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Rusk St","stopId":"Houston:664","stopCode":"664","lon":-95.364659,"lat":29.758853,"arrival":1628083572000,"departure":1628083572000,"stopIndex":13,"stopSequence":14,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Texas Ave","stopId":"Houston:666","stopCode":"666","lon":-95.363472,"lat":29.760325,"arrival":1628083620000,"departure":1628083620000,"stopIndex":14,"stopSequence":15,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"}],"steps":[]},{"startTime":1628083678000,"endTime":1628083733000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":70.72300000000001,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"Travis St @ Preston St","stopId":"Houston:630","stopCode":"630","lon":-95.362244,"lat":29.761898,"arrival":1628083677000,"departure":1628083678000,"stopIndex":15,"stopSequence":16,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"800 Congress, Houston, TX, USA","lon":-95.362178,"lat":29.76263,"arrival":1628083733000,"orig":"800 Congress, Houston, TX, USA","vertexType":"NORMAL"},"legGeometry":{"points":"a{stDjm`eQIGMIKIcAu@","length":5},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":55.0,"intermediateStops":[],"steps":[{"distance":70.72300000000001,"relativeDirection":"DEPART","streetName":"Travis Street","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":false,"lon":-95.36229927212824,"lat":29.76193091893979,"elevation":[]}]}],"tooSloped":false},{"duration":392,"startTime":1628083900000,"endTime":1628084292000,"walkTime":210,"transitTime":180,"waitingTime":2,"walkDistance":259.1391641774315,"walkLimitExceeded":false,"elevationLost":0.0,"elevationGained":0.0,"transfers":0,"fare":{"fare":{"regular":{"currency":{"symbol":"$","currency":"USD","defaultFractionDigits":2,"currencyCode":"USD"},"cents":125}},"details":{}},"legs":[{"startTime":1628083900000,"endTime":1628083979000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":88.17900000000003,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"1900 Main Street, Houston, TX, USA","lon":-95.370998,"lat":29.750144,"departure":1628083900000,"orig":"1900 Main Street, Houston, TX, USA","vertexType":"NORMAL"},"to":{"name":"Travis St @ St Joseph Pkwy","stopId":"Houston:624","stopCode":"624","lon":-95.371177,"lat":29.750596,"arrival":1628083979000,"departure":1628083980000,"stopIndex":101,"stopSequence":102,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"kqqtDvcbeQw@m@GLCBADCDABCDCFEHCBCFABHF","length":14},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":79.0,"intermediateStops":[],"steps":[{"distance":81.20200000000003,"relativeDirection":"DEPART","streetName":"sidewalk","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":true,"lon":-95.37099129880164,"lat":29.750140100302744,"elevation":[]},{"distance":6.977,"relativeDirection":"LEFT","streetName":"sidewalk","absoluteDirection":"SOUTHWEST","stayOn":true,"area":false,"bogusName":true,"lon":-95.37113400000001,"lat":29.750646500000002,"elevation":[]}]},{"startTime":1628083980000,"endTime":1628084160000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":1423.885970658207,"pathway":false,"mode":"BUS","route":"082","agencyName":"Metropolitan Transit Authority of Harris County","agencyUrl":"http://www.ridemetro.org","agencyTimeZoneOffset":-18000000,"routeColor":"004080","routeType":3,"routeId":"Houston:41336","routeTextColor":"FFFFFF","interlineWithPreviousLeg":false,"tripShortName":"WHEIMER","tripBlockId":"1062307","headsign":"DOWNTOWN","agencyId":"HOU","tripId":"Houston:9129563","serviceDate":"20210804","from":{"name":"Travis St @ St Joseph Pkwy","stopId":"Houston:624","stopCode":"624","lon":-95.371177,"lat":29.750596,"arrival":1628083979000,"departure":1628083980000,"stopIndex":101,"stopSequence":102,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"Travis St @ Prairie St","stopId":"Houston:667","stopCode":"667","lon":-95.362814,"lat":29.761145,"arrival":1628084160000,"departure":1628084161000,"stopIndex":106,"stopSequence":107,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"mtqtDhebeQWSyCwBsCuBuCwB{BcBYSsCsB_CcBSQwCyB}BaBSQwCsBsCuBaCgBSMsCyB{CwBiCiB","length":20},"interStopGeometry":[{"points":"mtqtDhebeQWSyCwBsCuBuCwB{BcB","length":6},{"points":"egrtDjvaeQYSsCsB_CcB","length":4},{"points":"sprtD~naeQSQwCyB}BaB","length":4},{"points":"}yrtDpgaeQSQwCsBsCuBaCgB","length":5},{"points":"_hstDl|`eQSMsCyB{CwBiCiB","length":5}],"alerts":[{"alertDescriptionText":"","alertUrl":"https://www.ridemetro.org/Pages/Coronavirus.aspx","effectiveStartDate":1625842020000,"alertHeaderText":"Federal law requires anyone on the METRO system to wear a face mask. This includes rail stations, transit centers and bus stops. Exemptions are available for children under the age of two and for those with a disability defined by the ADA."}],"routeShortName":"082","routeLongName":"WESTHEIMER","rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":true,"duration":180.0,"intermediateStops":[{"name":"Travis St @ Bell St","stopId":"Houston:628","stopCode":"628","lon":-95.368804,"lat":29.753604,"arrival":1628084031000,"departure":1628084031000,"stopIndex":102,"stopSequence":103,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Polk St","stopId":"Houston:685","stopCode":"685","lon":-95.367596,"lat":29.755096,"arrival":1628084056000,"departure":1628084056000,"stopIndex":103,"stopSequence":104,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Lamar St","stopId":"Houston:661","stopCode":"661","lon":-95.366423,"lat":29.756601,"arrival":1628084081000,"departure":1628084081000,"stopIndex":104,"stopSequence":105,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Rusk St","stopId":"Houston:664","stopCode":"664","lon":-95.364659,"lat":29.758853,"arrival":1628084119000,"departure":1628084119000,"stopIndex":105,"stopSequence":106,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"}],"steps":[]},{"startTime":1628084161000,"endTime":1628084292000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":170.893,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"Travis St @ Prairie St","stopId":"Houston:667","stopCode":"667","lon":-95.362814,"lat":29.761145,"arrival":1628084160000,"departure":1628084161000,"stopIndex":106,"stopSequence":107,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"800 Congress, Houston, TX, USA","lon":-95.362178,"lat":29.76263,"arrival":1628084292000,"orig":"800 Congress, Houston, TX, USA","vertexType":"NORMAL"},"legGeometry":{"points":"kvstD`q`eQSOgAw@y@m@IGMIKIcAu@","length":8},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":131.0,"intermediateStops":[],"steps":[{"distance":170.893,"relativeDirection":"DEPART","streetName":"Travis Street","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":false,"lon":-95.36288624616279,"lat":29.761188019319103,"elevation":[]}]}],"tooSloped":false}]},"debugOutput":{"precalculationTime":35,"pathCalculationTime":32,"pathTimes":[10,9,13],"renderingTime":0,"totalTime":67,"timedOut":false},"elevationMetadata":{"ellipsoidToGeoidDifference":-26.094908498979883,"geoidElevation":false}} \ No newline at end of file +{"requestParameters":{"date":"2021-08-04","walkSpeed":"1.34","fromPlace":"1900 Main Street, Houston, TX, USA::29.750144,-95.370998","maxWalkDistance":"1207","otherThanPreferredRoutesPenalty":"900","numItineraries":"3","mode":"WALK,BUS,TRAM","arriveBy":"false","ignoreRealtimeUpdates":"false","showIntermediateStops":"true","optimize":"QUICK","toPlace":"800 Congress, Houston, TX, USA::29.76263,-95.362178","time":"08:14"},"plan":{"date":1628082840000,"from":{"name":"1900 Main Street, Houston, TX, USA","lon":-95.370998,"lat":29.750144,"orig":"1900 Main Street, Houston, TX, USA","vertexType":"NORMAL"},"to":{"name":"800 Congress, Houston, TX, USA","lon":-95.362178,"lat":29.76263,"orig":"800 Congress, Houston, TX, USA","vertexType":"NORMAL"},"itineraries":[{"duration":392,"startTime":1628083300000,"endTime":1628083692000,"walkTime":210,"transitTime":180,"waitingTime":2,"walkDistance":259.1391641774315,"walkLimitExceeded":false,"elevationLost":0.0,"elevationGained":0.0,"transfers":0,"fare":{"fare":{"regular":{"currency":{"symbol":"$","currency":"USD","defaultFractionDigits":2,"currencyCode":"USD"},"cents":125}},"details":{}},"legs":[{"startTime":1628083300000,"endTime":1628083379000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":88.17900000000003,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"1900 Main Street, Houston, TX, USA","lon":-95.370998,"lat":29.750144,"departure":1628083300000,"orig":"1900 Main Street, Houston, TX, USA","vertexType":"NORMAL"},"to":{"name":"Travis St @ St Joseph Pkwy","stopId":"Houston:624","stopCode":"624","lon":-95.371177,"lat":29.750596,"arrival":1628083379000,"departure":1628083380000,"stopIndex":101,"stopSequence":102,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"kqqtDvcbeQw@m@GLCBADCDABCDCFEHCBCFABHF","length":14},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":79.0,"intermediateStops":[],"steps":[{"distance":81.20200000000003,"relativeDirection":"DEPART","streetName":"sidewalk","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":true,"lon":-95.37099129880164,"lat":29.750140100302744,"elevation":[]},{"distance":6.977,"relativeDirection":"LEFT","streetName":"sidewalk","absoluteDirection":"SOUTHWEST","stayOn":true,"area":false,"bogusName":true,"lon":-95.37113400000001,"lat":29.750646500000002,"elevation":[]}]},{"startTime":1628083380000,"endTime":1628083560000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":1423.885970658207,"pathway":false,"mode":"BUS","route":"082","agencyName":"Metropolitan Transit Authority of Harris County","agencyUrl":"http://www.ridemetro.org","agencyTimeZoneOffset":-18000000,"routeColor":"004080","routeType":3,"routeId":"Houston:41336","routeTextColor":"FFFFFF","interlineWithPreviousLeg":false,"tripShortName":"WHEIMER","tripBlockId":"1062305","headsign":"DOWNTOWN","agencyId":"HOU","tripId":"Houston:9129562","serviceDate":"20210804","from":{"name":"Travis St @ St Joseph Pkwy","stopId":"Houston:624","stopCode":"624","lon":-95.371177,"lat":29.750596,"arrival":1628083379000,"departure":1628083380000,"stopIndex":101,"stopSequence":102,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"Travis St @ Prairie St","stopId":"Houston:667","stopCode":"667","lon":-95.362814,"lat":29.761145,"arrival":1628083560000,"departure":1628083561000,"stopIndex":106,"stopSequence":107,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"mtqtDhebeQWSyCwBsCuBuCwB{BcBYSsCsB_CcBSQwCyB}BaBSQwCsBsCuBaCgBSMsCyB{CwBiCiB","length":20},"interStopGeometry":[{"points":"mtqtDhebeQWSyCwBsCuBuCwB{BcB","length":6},{"points":"egrtDjvaeQYSsCsB_CcB","length":4},{"points":"sprtD~naeQSQwCyB}BaB","length":4},{"points":"}yrtDpgaeQSQwCsBsCuBaCgB","length":5},{"points":"_hstDl|`eQSMsCyB{CwBiCiB","length":5}],"alerts":[{"alertDescriptionText":"","alertUrl":"https://www.ridemetro.org/Pages/Coronavirus.aspx","effectiveStartDate":1625842020000,"alertHeaderText":"Federal law requires anyone on the METRO system to wear a face mask. This includes rail stations, transit centers and bus stops. Exemptions are available for children under the age of two and for those with a disability defined by the ADA."}],"routeShortName":"082","routeLongName":"WESTHEIMER","rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":true,"duration":180.0,"intermediateStops":[{"name":"Travis St @ Bell St","stopId":"Houston:628","stopCode":"628","lon":-95.368804,"lat":29.753604,"arrival":1628083431000,"departure":1628083431000,"stopIndex":102,"stopSequence":103,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Polk St","stopId":"Houston:685","stopCode":"685","lon":-95.367596,"lat":29.755096,"arrival":1628083456000,"departure":1628083456000,"stopIndex":103,"stopSequence":104,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Lamar St","stopId":"Houston:661","stopCode":"661","lon":-95.366423,"lat":29.756601,"arrival":1628083481000,"departure":1628083481000,"stopIndex":104,"stopSequence":105,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Rusk St","stopId":"Houston:664","stopCode":"664","lon":-95.364659,"lat":29.758853,"arrival":1628083519000,"departure":1628083519000,"stopIndex":105,"stopSequence":106,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"}],"steps":[]},{"startTime":1628083561000,"endTime":1628083692000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":170.893,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"Travis St @ Prairie St","stopId":"Houston:667","stopCode":"667","lon":-95.362814,"lat":29.761145,"arrival":1628083560000,"departure":1628083561000,"stopIndex":106,"stopSequence":107,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"800 Congress, Houston, TX, USA","lon":-95.362178,"lat":29.76263,"arrival":1628083692000,"orig":"800 Congress, Houston, TX, USA","vertexType":"NORMAL"},"legGeometry":{"points":"kvstD`q`eQSOgAw@y@m@IGMIKIcAu@","length":8},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":131.0,"intermediateStops":[],"steps":[{"distance":170.893,"relativeDirection":"DEPART","streetName":"Travis Street","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":false,"lon":-95.36288624616279,"lat":29.761188019319103,"elevation":[]}]}],"tooSloped":false},{"duration":515,"startTime":1628083218000,"endTime":1628083733000,"walkTime":156,"transitTime":357,"waitingTime":2,"walkDistance":182.0511194004663,"walkLimitExceeded":false,"elevationLost":0.0,"elevationGained":0.0,"transfers":0,"fare":{"fare":{"regular":{"currency":{"symbol":"$","currency":"USD","defaultFractionDigits":2,"currencyCode":"USD"},"cents":200}},"details":{}},"legs":[{"startTime":1628083218000,"endTime":1628083319000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":111.22700000000003,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"1900 Main Street, Houston, TX, USA","lon":-95.370998,"lat":29.750144,"departure":1628083218000,"orig":"1900 Main Street, Houston, TX, USA","vertexType":"NORMAL"},"to":{"name":"St Joseph Pkwy @ Travis St","stopId":"Houston:310","stopCode":"310","lon":-95.370944,"lat":29.750747,"arrival":1628083319000,"departure":1628083320000,"stopIndex":8,"stopSequence":9,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"kqqtDvcbeQw@m@GLCBADCDABCDCFEHCBCFABOMOMFK","length":16},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":101.0,"intermediateStops":[],"steps":[{"distance":81.20200000000003,"relativeDirection":"DEPART","streetName":"sidewalk","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":true,"lon":-95.37099129880164,"lat":29.750140100302744,"elevation":[]},{"distance":30.025,"relativeDirection":"UTURN_RIGHT","streetName":"sidewalk","absoluteDirection":"SOUTHEAST","stayOn":true,"area":false,"bogusName":true,"lon":-95.37099780000001,"lat":29.750805200000002,"elevation":[]}]},{"startTime":1628083320000,"endTime":1628083677000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":1524.458915954146,"pathway":false,"mode":"BUS","route":"249","agencyName":"Metropolitan Transit Authority of Harris County","agencyUrl":"http://www.ridemetro.org","agencyTimeZoneOffset":-18000000,"routeColor":"004080","routeType":3,"routeId":"Houston:41364","routeTextColor":"FFFFFF","interlineWithPreviousLeg":false,"tripShortName":"BAY AREA","tripBlockId":"1062867","headsign":"DOWNTOWN / VIA EASTWOOD TC","agencyId":"HOU","tripId":"Houston:9135066","serviceDate":"20210804","from":{"name":"St Joseph Pkwy @ Travis St","stopId":"Houston:310","stopCode":"310","lon":-95.370944,"lat":29.750747,"arrival":1628083319000,"departure":1628083320000,"stopIndex":8,"stopSequence":9,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"Travis St @ Preston St","stopId":"Houston:630","stopCode":"630","lon":-95.362244,"lat":29.761898,"arrival":1628083677000,"departure":1628083678000,"stopIndex":15,"stopSequence":16,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"utqtDxcbeQOZyCwBsCuByBaB[UuCwB{BaBWQsCuB}BcBYUqCsBcCcBSOsCuBaCgBSMsCyB_CaB[U_DyB}BeB","length":23},"interStopGeometry":[{"points":"utqtDxcbeQOZyCwBsCuByBaB","length":5},{"points":"mbrtDdzaeQ[UuCwB{BaB","length":4},{"points":"{krtDtraeQWQsCuB}BcB","length":4},{"points":"eurtDhkaeQYUqCsBcCcB","length":4},{"points":"u~rtDzcaeQSOsCuBaCgB","length":4},{"points":"_hstDl|`eQSMsCyB_CaB","length":4},{"points":"gqstDbu`eQ[U_DyB}BeB","length":4}],"alerts":[{"alertDescriptionText":"","alertUrl":"https://www.ridemetro.org/Pages/Coronavirus.aspx","effectiveStartDate":1625842020000,"alertHeaderText":"Federal law requires anyone on the METRO system to wear a face mask. This includes rail stations, transit centers and bus stops. Exemptions are available for children under the age of two and for those with a disability defined by the ADA."}],"routeShortName":"249","routeLongName":"MONROE/FUQUA/EL DORADO/BAY AREA P&R","rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":true,"duration":357.0,"intermediateStops":[{"name":"Travis St @ Leeland St","stopId":"Houston:627","stopCode":"627","lon":-95.369404,"lat":29.752841,"arrival":1628083389000,"departure":1628083389000,"stopIndex":9,"stopSequence":10,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Clay St","stopId":"Houston:629","stopCode":"629","lon":-95.36821,"lat":29.754346,"arrival":1628083435000,"departure":1628083435000,"stopIndex":10,"stopSequence":11,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Dallas St","stopId":"Houston:660","stopCode":"660","lon":-95.367027,"lat":29.755835,"arrival":1628083480000,"departure":1628083480000,"stopIndex":11,"stopSequence":12,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Mc Kinney St","stopId":"Houston:662","stopCode":"662","lon":-95.365814,"lat":29.757345,"arrival":1628083526000,"departure":1628083526000,"stopIndex":12,"stopSequence":13,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Rusk St","stopId":"Houston:664","stopCode":"664","lon":-95.364659,"lat":29.758853,"arrival":1628083572000,"departure":1628083572000,"stopIndex":13,"stopSequence":14,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Texas Ave","stopId":"Houston:666","stopCode":"666","lon":-95.363472,"lat":29.760325,"arrival":1628083620000,"departure":1628083620000,"stopIndex":14,"stopSequence":15,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"}],"steps":[]},{"startTime":1628083678000,"endTime":1628083733000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":70.72300000000001,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"Travis St @ Preston St","stopId":"Houston:630","stopCode":"630","lon":-95.362244,"lat":29.761898,"arrival":1628083677000,"departure":1628083678000,"stopIndex":15,"stopSequence":16,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"800 Congress, Houston, TX, USA","lon":-95.362178,"lat":29.76263,"arrival":1628083733000,"orig":"800 Congress, Houston, TX, USA","vertexType":"NORMAL"},"legGeometry":{"points":"a{stDjm`eQIGMIKIcAu@","length":5},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":55.0,"intermediateStops":[],"steps":[{"distance":70.72300000000001,"relativeDirection":"DEPART","streetName":"Travis Street","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":false,"lon":-95.36229927212824,"lat":29.76193091893979,"elevation":[]}]}],"tooSloped":false},{"duration":392,"startTime":1628083900000,"endTime":1628084292000,"walkTime":210,"transitTime":180,"waitingTime":2,"walkDistance":259.1391641774315,"walkLimitExceeded":false,"elevationLost":0.0,"elevationGained":0.0,"transfers":0,"fare":{"fare":{"regular":{"currency":{"symbol":"$","currency":"USD","defaultFractionDigits":2,"currencyCode":"USD"},"cents":125}},"details":{}},"legs":[{"startTime":1628083900000,"endTime":1628083979000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":88.17900000000003,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"1900 Main Street, Houston, TX, USA","lon":-95.370998,"lat":29.750144,"departure":1628083900000,"orig":"1900 Main Street, Houston, TX, USA","vertexType":"NORMAL"},"to":{"name":"Travis St @ St Joseph Pkwy","stopId":"Houston:624","stopCode":"624","lon":-95.371177,"lat":29.750596,"arrival":1628083979000,"departure":1628083980000,"stopIndex":101,"stopSequence":102,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"kqqtDvcbeQw@m@GLCBADCDABCDCFEHCBCFABHF","length":14},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":79.0,"intermediateStops":[],"steps":[{"distance":81.20200000000003,"relativeDirection":"DEPART","streetName":"sidewalk","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":true,"lon":-95.37099129880164,"lat":29.750140100302744,"elevation":[]},{"distance":6.977,"relativeDirection":"LEFT","streetName":"sidewalk","absoluteDirection":"SOUTHWEST","stayOn":true,"area":false,"bogusName":true,"lon":-95.37113400000001,"lat":29.750646500000002,"elevation":[]}]},{"startTime":1628083980000,"endTime":1628084160000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":1423.885970658207,"pathway":false,"mode":"BUS","route":"082","agencyName":"Metropolitan Transit Authority of Harris County","agencyUrl":"http://www.ridemetro.org","agencyTimeZoneOffset":-18000000,"routeColor":"004080","routeType":3,"routeId":"Houston:41336","routeTextColor":"FFFFFF","interlineWithPreviousLeg":false,"tripShortName":"WHEIMER","tripBlockId":"1062307","headsign":"DOWNTOWN","agencyId":"HOU","tripId":"Houston:9129563","serviceDate":"20210804","from":{"name":"Travis St @ St Joseph Pkwy","stopId":"Houston:624","stopCode":"624","lon":-95.371177,"lat":29.750596,"arrival":1628083979000,"departure":1628083980000,"stopIndex":101,"stopSequence":102,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"Travis St @ Prairie St","stopId":"Houston:667","stopCode":"667","lon":-95.362814,"lat":29.761145,"arrival":1628084160000,"departure":1628084161000,"stopIndex":106,"stopSequence":107,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"legGeometry":{"points":"mtqtDhebeQWSyCwBsCuBuCwB{BcBYSsCsB_CcBSQwCyB}BaBSQwCsBsCuBaCgBSMsCyB{CwBiCiB","length":20},"interStopGeometry":[{"points":"mtqtDhebeQWSyCwBsCuBuCwB{BcB","length":6},{"points":"egrtDjvaeQYSsCsB_CcB","length":4},{"points":"sprtD~naeQSQwCyB}BaB","length":4},{"points":"}yrtDpgaeQSQwCsBsCuBaCgB","length":5},{"points":"_hstDl|`eQSMsCyB{CwBiCiB","length":5}],"alerts":[{"alertDescriptionText":"","alertUrl":"https://www.ridemetro.org/Pages/Coronavirus.aspx","effectiveStartDate":1625842020000,"alertHeaderText":"Federal law requires anyone on the METRO system to wear a face mask. This includes rail stations, transit centers and bus stops. Exemptions are available for children under the age of two and for those with a disability defined by the ADA."}],"routeShortName":"082","routeLongName":"WESTHEIMER","rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":true,"duration":180.0,"intermediateStops":[{"name":"Travis St @ Bell St","stopId":"Houston:628","stopCode":"628","lon":-95.368804,"lat":29.753604,"arrival":1628084031000,"departure":1628084031000,"stopIndex":102,"stopSequence":103,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Polk St","stopId":"Houston:685","stopCode":"685","lon":-95.367596,"lat":29.755096,"arrival":1628084056000,"departure":1628084056000,"stopIndex":103,"stopSequence":104,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Lamar St","stopId":"Houston:661","stopCode":"661","lon":-95.366423,"lat":29.756601,"arrival":1628084081000,"departure":1628084081000,"stopIndex":104,"stopSequence":105,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},{"name":"Travis St @ Rusk St","stopId":"Houston:664","stopCode":"664","lon":-95.364659,"lat":29.758853,"arrival":1628084119000,"departure":1628084119000,"stopIndex":105,"stopSequence":106,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"}],"steps":[]},{"startTime":1628084161000,"endTime":1628084292000,"departureDelay":0,"arrivalDelay":0,"realTime":false,"distance":170.893,"pathway":false,"mode":"WALK","route":"","agencyTimeZoneOffset":-18000000,"interlineWithPreviousLeg":false,"from":{"name":"Travis St @ Prairie St","stopId":"Houston:667","stopCode":"667","lon":-95.362814,"lat":29.761145,"arrival":1628084160000,"departure":1628084161000,"stopIndex":106,"stopSequence":107,"vertexType":"TRANSIT","boardAlightType":"DEFAULT"},"to":{"name":"800 Congress, Houston, TX, USA","lon":-95.362178,"lat":29.76263,"arrival":1628084292000,"orig":"800 Congress, Houston, TX, USA","vertexType":"NORMAL"},"legGeometry":{"points":"kvstD`q`eQSOgAw@y@m@IGMIKIcAu@","length":8},"rentedBike":false,"rentedCar":false,"rentedVehicle":false,"hailedCar":false,"flexDrtAdvanceBookMin":0.0,"transitLeg":false,"duration":131.0,"intermediateStops":[],"steps":[{"distance":170.893,"relativeDirection":"DEPART","streetName":"Travis Street","absoluteDirection":"NORTHEAST","stayOn":false,"area":false,"bogusName":false,"lon":-95.36288624616279,"lat":29.761188019319103,"elevation":[]}]}],"tooSloped":false}]},"debugOutput":{"precalculationTime":35,"pathCalculationTime":32,"pathTimes":[10,9,13],"renderingTime":0,"totalTime":67,"timedOut":false},"elevationMetadata":{"ellipsoidToGeoidDifference":-26.094908498979883,"geoidElevation":false}} \ No newline at end of file diff --git a/example-config.yml b/example-config.yml index 83121d221..a738157bc 100644 --- a/example-config.yml +++ b/example-config.yml @@ -57,7 +57,7 @@ api: ### The default query parameters can be overridden be uncommenting this object. ### Note: the override values must be valid values within otp-ui's query-params.js # defaultQueryParams: -# walkSpeed: 1.34 # 3 mph in meters per second +# maxWalkDistance: 3219 # 2 miles in meters ### The persistence setting is used to enable the storage of places (home, work), ### recent searches/places, user overrides, and favorite stops. @@ -223,6 +223,8 @@ geocoder: # Use this mode config for the enhanced Transit+ config modes: + ### Optional number of itineraries to return by default - Defaults to 3. + # numItineraries: 3 # Definition for the mode buttons to display in trip form modeButtons: - iconName: bus @@ -339,6 +341,8 @@ itinerary: # Whether the plan first/previous/next/last buttons should be shown along with # plan trip itineraries. showPlanFirstLastButtons: false + # adds the 'about' and '~' prefixes to the duration of non transit legs and trip details panel + showApproximatePrefixAccessLegs: false # Show all walking legs regardless of distance showAllWalkLegs: false # Filters out trips returned by OTP by default, unless specifically requested. @@ -609,15 +613,8 @@ itinerary: # vi: # name: Tiếng Việt -# # Chinese (Simplified) must be entered using 'zh-Hans', -# # or, if no other Chinese language is defined, using 'zh'. -# zh-Hans: -# name: 汉语 - -# # Chinese (Traditional) must be entered using 'zh-Hant'. -# # If Chinese (Simplified) is also used, it must be defined as 'zh-Hans' -# zh-Hant: -# name: 漢語 +# zh: +# name: 中国人 # es: # name: Español @@ -675,7 +672,4 @@ itinerary: ### Setting this to true will use the route viewer sort algorithm on routes # useRouteViewSort: false ### Setting this to false will hide the shadowey dot that appears when dragging the map -# showShadowDotOnMapDrag: false -### In routes, this will always show the routeLongName before the headsign -### !!! WARNING: in some feeds, this may show the long name twice. In some feeds, this may cause layout issues !!! -# alwaysShowLongName: false \ No newline at end of file +# showShadowDotOnMapDrag: false \ No newline at end of file diff --git a/i18n/es.yml b/i18n/es.yml index 23318b41a..986cf7037 100644 --- a/i18n/es.yml +++ b/i18n/es.yml @@ -30,8 +30,7 @@ actions: No se puede guardar el plan: este plan no se pudo guardar debido a la falta de capacidad en uno o más vehículos. Por favor, vuelva a planificar su viaje. - maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados - válidos + maxTripRequestsExceeded: Número de solicitudes de viaje superadas sin resultados válidos saveItinerariesError: "No se pudieron guardar los itinerarios: {err}" setDateError: "Error al establecer la fecha:" setGroupSizeError: "No se pudo establecer el tamaño del grupo:" @@ -53,13 +52,10 @@ actions: authTokenError: Error al obtener un token de autorización. confirmDeleteMonitoredTrip: ¿Desea eliminar este viaje? confirmDeletePlace: ¿Quiere eliminar este lugar? - emailVerificationResent: El mensaje de verificación de correo electrónico ha sido - reenviado. + emailVerificationResent: El mensaje de verificación de correo electrónico ha sido reenviado. genericError: "Se ha encontrado un error: {err}" - itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado - es posible. - mustAcceptTermsToSavePlace: Acepte los Términos de uso (en Mi Cuenta) para guardar - las ubicaciones. + itineraryExistenceCheckFailed: Comprobación de errores para ver si el viaje seleccionado es posible. + mustAcceptTermsToSavePlace: Acepte los Términos de uso (en Mi Cuenta) para guardar las ubicaciones. mustBeLoggedInToSavePlace: Por favor, inicia la sesión para guardar las ubicaciones. placeRemembered: La configuración de este lugar se ha guardado. preferencesSaved: Sus preferencias se han guardado. @@ -212,8 +208,7 @@ components: a incluir el transporte publico en la selección de modos. origin: origen planTripTooltip: Planificar viaje - validationMessage: "Por favor, defina los siguientes campos para planificar un - viaje: {issues}" + validationMessage: "Por favor, defina los siguientes campos para planificar un viaje: {issues}" BeforeSignInScreen: mainTitle: Iniciando sesión message: > @@ -374,7 +369,6 @@ components: nearbyListIntro: Lista de {count} entidades cercanas. nothingNearby: No ubicaciónes cercanas. spacesAvailable: "{spacesAvailable} espacios libres disponibles" - distanceAway: '{localizedDistanceString} de distancia' NewAccountWizard: createNewAccount: Crear una nueva cuenta finish: ¡Configuración de la cuenta completa! @@ -455,8 +449,6 @@ components: minutos. verified: Verificado verify: Verificar - verifySms: Por favor, complete el proceso de verificación para configurar las - notificaciones por SMS. Place: deleteThisPlace: Borrar este lugar enterAlert: > @@ -562,8 +554,7 @@ components: header: ¡La sesión está a punto de terminar! keepSession: Continuar sesión SimpleRealtimeAnnotation: - usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo - real + usingRealtimeInfo: Este viaje utiliza información de tráfico y retrasos en tiempo real StackedPaneDisplay: savePreferences: Guardar preferencias StopScheduleTable: @@ -625,18 +616,15 @@ components: travelingAt: Viajando a {milesPerHour} vehicleName: Vehículo {vehicleNumber} TripBasicsPane: - checkingItineraryExistence: Comprobación de la existencia de itinerarios para - cada día de la semana… + checkingItineraryExistence: Comprobación de la existencia de itinerarios para cada día de la semana… tripDaysPrompt: ¿Qué días hace este viaje? - tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana - indicados anteriormente. + tripIsAvailableOnDaysIndicated: Su viaje está disponible en los días de la semana indicados anteriormente. tripNamePrompt: "Por favor, indique un nombre para este viaje:" tripNotAvailableOnDay: El viaje no está disponible el {repeatedDay} unsavedChangesExistingTrip: >- Todavía no ha guardado su viaje. Si abandona la página, los cambios se perderán. - unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página, - se perderá. + unsavedChangesNewTrip: Todavía no ha guardado su nuevo viaje. Si abandona la página, se perderá. TripNotificationsPane: advancedSettings: Configuración avanzada altRouteRecommended: Se recomienda una ruta alternativa o un punto de transferencia @@ -716,8 +704,6 @@ components: happensOnDays: "Ocurre en: {days}" notifications: "{leadTimeInMinutes} minutos antes de la salida programada" notificationsDisabled: Notificaciones desactivadas - timeAndDuration: Tiempo y duración del viaje - monitoredTripDays: Días de viaje monitoreados TripTools: copyLink: Copiar enlace header: Herramientas diff --git a/i18n/zh_Hans.yml b/i18n/zh.yml similarity index 100% rename from i18n/zh_Hans.yml rename to i18n/zh.yml diff --git a/i18n/zh_Hant.yml b/i18n/zh_Hant.yml deleted file mode 100644 index 3cc8aebc8..000000000 --- a/i18n/zh_Hant.yml +++ /dev/null @@ -1,639 +0,0 @@ -_id: zh-Hant -_name: Chinese (Traditional) -actions: - callTaker: - queryFetchError: 擷取查詢時發生錯誤:{err} - callQuerySaveError: 儲存通話查詢時發生錯誤:{err} - callSaveError: 無法儲存通話:{err} - checkSessionError: 建立授權工作階段時發生錯誤:{err} - couldNotFindCallError: 找不到通話。正在取消儲存查詢請求。 - fetchCallsError: 擷取通話時發生錯誤:{err} - fieldTrip: - addNoteError: 新增實地考察備註時發生錯誤: - confirmOverwriteItineraries: "此動作將覆蓋此請求之前規劃的{outbound, select,\n true {外出}\n other - {返回}\n }預定行程。您想繼續嗎?\n" - setGroupSizeError: 設定群組大小時發生錯誤: - deleteItinerariesError: 刪除實地考察計畫時發生錯誤: - deleteNoteError: 刪除實地考察備註時發生錯誤: - editSubmitterNotesError: 編輯提交者備註時發生錯誤: - fetchFieldTripError: 擷取實地考察時發生錯誤:{err} - fetchFieldTripsError: 擷取實地考察時發生錯誤:{err} - fetchTripsForDateError: 擷取實地考察行程日期的行程時發生錯誤:{err} - incompatibleTripDateError: 規劃的行程日期 ({tripDate}) 並非請求的行程日期 ({requestDate}) - itineraryCapacityError: 無法儲存計畫:因為一或多輛車的容量不足,此計畫無法儲存。請重新規劃您的行程。 - maxTripRequestsExceeded: 行程請求數量過多,沒有有效結果 - saveItinerariesError: 無法儲存預定行程:{err} - setDateError: 設定日期時發生錯誤: - setPaymentError: 設定付款資訊時發生錯誤: - setRequestStatusError: 設定請求狀態時發生錯誤: - map: - currentLocation: (目前位置) - user: - accountDeleted: 您的使用者帳戶 ({email}) 已刪除。 - authTokenError: 取得授權權杖時發生錯誤。 - confirmDeleteMonitoredTrip: 是否要移除此行程? - confirmDeletePlace: 是否要移除此地點? - emailVerificationResent: 電子郵件驗證訊息已重新傳送。 - genericError: 發生錯誤:{err} - mustBeLoggedInToSavePlace: 請登入,以儲存地點。 - itineraryExistenceCheckFailed: 檢查您選取的行程是否可行時發生錯誤。 - mustAcceptTermsToSavePlace: 請接受使用條款 (在我的帳戶下),以儲存地點。 - placeRemembered: 此地點的設定已儲存。 - preferencesSaved: 您的偏好已儲存。 - smsInvalidCode: 您輸入的代碼無效。請再試一次。 - smsResendThrottled: 驗證簡訊已在不到一分鐘前傳送到指定的電話號碼。請稍後再試一次。 - smsVerificationFailed: 您的電話無法驗證。您輸入的代碼可能已失效。請要求新的代碼,然後再試一次。 - location: - deniedAccessAlert: "系統已封鎖您存取地點的權限。\n若要使用目前的地點,請從瀏覽器啟用地點權限,然後再重新載入頁面。 \n" - geolocationNotSupportedError: 您的瀏覽器不支援地理位置 - unknownPositionError: 取得位置時發生不明錯誤 - userDeniedPermission: 使用者拒絕提供權限 -common: - coordinates: '{lat}; {lon}' - daysOfWeekCompact: - sunday: 週日 - thursday: 週四 - tuesday: 週二 - wednesday: 週三 - friday: 週五 - monday: 週一 - saturday: 週六 - daysOfWeekPlural: - friday: 每星期五 - monday: 每星期一 - saturday: 每星期六 - sunday: 每星期日 - thursday: 每星期四 - tuesday: 每星期二 - wednesday: 每星期三 - modes: - car_park: 停車轉乘 - drive: 駕車 - ferry: 渡船 - flex: 彈性路線 - bicycle_rent: 自行車共享 - bike: 騎行 - bus: 搭乘公車 - cable_car: 纜車 - car: 汽車 - funicular: 纜索鐵路 - gondola: 空中纜車 - micromobility: 電動滑板車 - micromobility_rent: 電動滑板車 - rail: 鐵路 - rent: 租賃選項 - subway: 捷運 - tram: 西雅圖街車 - transit: 公共交通 - walk: 步行 - notifications: - push: 推播通知 - sms: 簡訊 - email: 電子郵件 - places: - custom: 自訂 - dining: 餐廳 - home: 住家 - work: 工作 - searchForms: - enterDestination: 輸入目的地或{mapAction} 地圖…… - enterStartLocation: 輸入開始位置或{mapAction} 地圖…… - click: 按一下 - tap: 輕觸 - dateExpressions: - today: 今天 - tomorrow: 明天 - yesterday: 昨天 - daysOfWeek: - friday: 星期五 - monday: 星期一 - saturday: 星期六 - sunday: 星期日 - thursday: 星期四 - tuesday: 星期二 - wednesday: 星期三 - forms: - back: 返回 - cancel: 取消 - close: 關閉 - defaultValue: '{value} (預設)' - edit: 編輯 - error: 錯誤! - finish: 完成 - next: 前進 - "no": 否 - print: 列印 - save: 儲存 - startOver: 重新開始 - submitting: 正在提交… - "yes": 是 - itineraryDescriptions: - calories: '{calories, number}卡' - fareUnknown: 無票價資訊 - noItineraryToDisplay: 沒有預定行程可顯示。 - relativeCo2: "{co2}比單獨開車排放的CO₂{isMore, select, true {要多} other {少}}\n" - transfers: '{transfers}次轉乘' - linkOpensNewWindow: (開啟新視窗) - routing: - routeAndNumber: 路線{routeId} - time: - departureArrivalTimes: '{startTime, time, short}—{endTime, time, short}' - duration: - aFewSeconds: 幾秒鐘 - nDays: '{days}天' - nHours: '{hours}小時' - nMinutes: '{minutes}分鐘' - durationAgo: '{duration}前' - tripDurationFormat: '{hours, plural, =0 {} other {# 小時 }}{minutes} 分鐘 { seconds, - plural, =0 {} other {# 秒鐘}}' -components: - AccountSetupFinishPane: - message: 您已經準備好開始規劃行程。 - AfterSignInScreen: - mainTitle: 正在重新導向…… - message: 如果頁面未在幾秒鐘後載入,請按一下這裡。 - AppMenu: - callHistory: 通話記錄 - closeMenu: 關閉功能表 - mailables: 可郵寄 - openMenu: 開啟功能表 - skipNavigation: 跳過導航 - fieldTrip: 實地考察 - BackToTripPlanner: - backToTripPlanner: 返回行程規劃器 - BatchResultsScreen: - showResults: 顯示結果 - expandMap: 展開地圖 - BatchRoutingPanel: - shortTitle: 規劃行程 - BeforeSignInScreen: - mainTitle: 登入中 - message: "您必須登入才能存取此頁面。我們正在將您重新導向到登入頁面,請稍候……\n" - DateTimeOptions: - departAt: 出發時間 - now: 現在 - arriveBy: 最晚抵達時間 - DateTimePreview: - leaveNow: 現在出發 - arriveAt: '{arriveTime, time, short}抵達' - dayLastWeek: 上{formattedDayOfWeek} - departAt: '{departTime, time, short}出發' - editDepartOrArrival: 編輯出發或抵達時間 - DefaultItinerary: - clickDetails: 按一下以檢視詳細資料 - nonTransit: 替代選項 - multiModeSummary: '{accessMode} + {transitMode}' - ExistingAccountDisplay: - notifications: 通知 - places: 最愛的地點 - terms: 條款 - a11y: 可到達性 - mainTitle: 我的設定 - FavoritePlaceList: - addAnotherPlace: 新增其他地點 - editThisPlace: 編輯此地點 - setAddressForPlaceType: 設定您的{placeType}地址 - description: 新增您經常使用的地點,以節省規劃行程的時間: - FavoritePlaceScreen: - placeNotFound: 找不到地點 - addNewPlace: 新增地點 - editPlace: 編輯{placeName} - editPlaceGeneric: 編輯地點 - invalidAddress: 請為此地點設定位置。 - invalidName: 請為此地點輸入名稱。 - nameAlreadyUsed: 您已經對其他地點使用此名稱。請輸入其他名稱。 - placeNotFoundDescription: 很抱歉,找不到請求的地點。 - MapLayers: - satellite: 衛星 - shared-vehicles: 共享車輛 - stops: 公共交通車站 - streets: 街道 - bike-rental: '{companies}共享自行車' - car-rental: 自行車租賃位置 - micromobility-rental: '{companies}電動滑板車' - park-and-ride: 停車轉乘位置 - MetroUI: - originallyScheduledTime: (原定 {originalTime}) - singleModeItineraryDescription: '{time} {mode} 路線' - arriveAt: 您已抵達目的地 - itineraryDescription: '{time}預定行程,使用{routes}' - leaveAt: 您出發 - multipleOptions: 多個選項 - orAlternatives: 或相同方向的其他路線 - timeWalking: 步行{time} - OTP2ErrorRenderer: - NO_STOPS_IN_RANGE: - body: '{inputFields} 地點 未鄰近任何公共交通車站。' - header: 範圍內無車站 - NO_TRANSIT_CONNECTION: - body: 在所選服務日當天使用所選車輛類型進行搜尋後,在您的出發地和目的地之間找不到公共交通連接路線。 - header: 無公共交通連接路線 - LOCATION_NOT_FOUND: - body: '{inputFields} 地點 未鄰近任何街道。' - header: 地點無法到達 - NO_TRANSIT_CONNECTION_IN_SEARCH_WINDOW: - body: 找到一個公共交通連接路線,但此路線超出搜尋視窗範圍,請使用您所選擇的車輛類型試著調整您的搜尋視窗。 - header: 搜尋視窗內無公共交通連接路線 - OUTSIDE_BOUNDS: - body: '{inputFields} 地點 不在行程規劃器的範圍內。' - header: 地點超出範圍 - OUTSIDE_SERVICE_PERIOD: - body: 指定的日期超出目前載入行程規劃器中的資料範圍。 - header: 超出服務期間 - SYSTEM_ERROR: - body: 搜尋時發生不明錯誤。 - header: 行程規劃器失敗 - WALKING_BETTER_THAN_TRANSIT: - body: 在行程中避開公共交通路線會比採用公共交通路線更加快速。 - header: 公共交通工具並非完成此行程的最快方式 - inputFields: - FROM: 起點 - TO: 目的地 - PhoneNumberEditor: - requestNewCode: 要求新代碼 - sendVerificationText: 傳送驗證簡訊 - changeNumber: 變更號碼 - invalidCode: 請輸入6位數的驗證碼。 - invalidPhone: 請輸入有效的電話號碼。 - pending: 待處理 - phoneNumberSubmitted: 已順利提交電話號碼 {phoneNumber}。 - phoneNumberVerified: 已順利驗證電話號碼 {phoneNumber} 。 - placeholder: 輸入您的電話號碼 - prompt: 輸入您用來接收簡訊通知的電話號碼: - smsConsent: "一旦提供您的電話號碼,即表示您同意接收驗證和行程監控簡訊。您的行動電信商可能會收取額外費用。\n" - verificationCode: 驗證碼: - verificationInstructions: "請查看您手機的簡訊應用程式是否收到含有驗證碼的簡訊,並在下方輸入該驗證碼 (驗證碼將在10分鐘後失效)。\n" - verified: 已驗證 - verify: 驗證 - PlaceEditor: - addressPrompt: 地址: - genericLocationPlaceholder: 搜尋位置 - locationPlaceholder: 搜尋{placeName}位置 - locationTypePrompt: 地點類型: - nameExample: 我的咖啡館 - namePrompt: 定地名: - PlanFirstLastButtons: - previous: 上一個 - first: 第一個 - last: 最後一個 - next: 前進 - PlanTripButton: - planTrip: 規劃行程 - PointPopup: - zoomToLocation: 縮放到位置 - PrintLayout: - itinerary: 預定行程 - toggleMap: 切換地圖 - RealtimeStatusLabel: - early: 提早{minutes} - late: 延後{minutes} - onTime: 準時 - scheduled: 預定 - ResultsHeader: - noTripFound: 找不到行程 - tripsFound: 我們找到了{count} 個選項 - waiting: 等待中…… - RouteViewer: - allAgencies: 所有機構 - allModes: 所有模式 - details: ' ' - findARoute: 尋找路線 - header: 路線檢視器 - modeFilter: 模式篩選 - noFilteredRoutesFound: 沒有路線符合您的篩選條件! - agencyFilter: 機構篩選 - openPatternViewer: 檢視預定行程詳細資訊 - shortTitle: 檢視路線 - stopsInDirectionOfTravel: 此行駛方向的沿路車站: - title: 路線檢視器 - SavedTripList: - fromTo: 從 {from} 到 {to} - myTrips: 我的行程 - noSavedTrips: 您沒有儲存的行程 - noSavedTripsInstructions: 請先從地圖進行行程搜尋。 - pause: 暫停 - resume: 繼續 - SimpleRealtimeAnnotation: - usingRealtimeInfo: 此行程使用即時交通和延誤資訊。 - StackedPaneDisplay: - savePreferences: 儲存偏好 - StopScheduleTable: - block: 封鎖 - departure: 出發 - destination: 至 - route: 路線 - StopViewer: - displayStopId: 車站ID:{stopId} - findSchedule: 依日期尋找排程 - forStop: 針對 {stopName} - flexStop: 這是彈性車站。車輛將依要求在彈性區域讓乘客上下車。您在此地區可能需要事先呼叫服務。 - header: 車站檢視器 - loadingText: 正在載入車站…… - noStopsFound: 此日期找不到車站時間。 - operatorLogoAriaLabel: '{operatorName} 車站:' - schedule: 時程表 - timezoneWarning: 出發時間是以{timezoneCode}顯示。 - titleBarStopId: 車站{stopId} - viewNearby: 檢視附近 - viewSchedule: 檢視時程 - zoomToStop: 縮放到車站 - SubNav: - selectALanguage: 選取語言 - settings: 設定 - trips: 行程 - userMenu: 設定檔選項 - languageSelector: 選取語言 - languages: 語言 - myAccount: 我的帳戶 - SwitchButton: - defaultContent: 切換 - switchLocations: 切換位置 - TermsOfUsePane: - mustAgreeToTerms: 您必須同意服務條款才能繼續。 - termsOfServiceStatement: "我確認我已年滿18歲,且我以閱讀並同意使用行程規劃器的服務條款。\n" - termsOfStorageStatement: "選擇性:我同意行程規劃器儲存我的歷史規劃行程,以改善我所在地區的公共交通服務。更多資訊……\n" - confirmDeletionPrompt: "如果移除您對儲存歷史行程的同意,將導致系統刪除您的行程記錄。確定要繼續嗎?\n" - TransitVehicleOverlay: - travelingAt: 以{milesPerHour}前進 - vehicleName: 車輛{vehicleNumber} - in_transit_to: 下一個車站:{stop} - incoming_at: 即將抵達:{stop} - stopped_at: 車門將在{stop}開啟 - TripBasicsPane: - checkingItineraryExistence: 正在檢查一週中每一天是否存在預定行程…… - tripDaysPrompt: 您在哪些日子使用此行程? - tripIsAvailableOnDaysIndicated: 您的行程可在上方指明的週間日期使用。 - tripNamePrompt: 請為此行程提供名稱: - tripNotAvailableOnDay: 行程無法在{repeatedDay}使用 - unsavedChangesExistingTrip: 您尚未儲存行程。如果離開,變更就會遺失。 - unsavedChangesNewTrip: 您尚未儲存新的行程。如果離開,該行程就會遺失。 - TripNotificationsPane: - advancedSettings: 進階設定 - notifyViaChannelWhen: 以下情形時透過{channel}通知我: - altRouteRecommended: 建議使用備選方案路線或轉乘點 - delaysAboveThreshold: 延誤或中斷超過 - howToReceiveAlerts: "若要針對您儲存的行程接收警示,請在帳戶設定中啟用通知,然後嘗試再次儲存行程。\n" - monitorThisTrip: 開始前先監控此行程: - notificationsTurnedOff: 您的帳戶已關閉通知。 - oneHour: 1小時 - realtimeAlertFlagged: 我的旅程上有一個即時警示標記 - timeBefore: '{time} 之前' - TripStatusRenderers: - active: - delayedHeading: 行程正在進行中,而且已延誤{formattedDuration}! - description: 行程預計在{arrivalTime, time, short}抵達目的地。 - earlyHeading: 行程正在進行中,而且將比預期提早{formattedDuration}抵達! - noDataHeading: 行程正在進行中 (沒有可用的即時更新)。 - onTimeHeading: 行程正在進行中,而且大約準時。 - base: - lastCheckedText: 最後檢查時間:{formattedDuration}前 - togglePause: 暫停 - tripIsNotSnoozed: 今天整天延遲 - tripIsSnoozed: 取消延遲行程分析 - unknownState: 未知的行程狀態 - untogglePause: 繼續 - lastCheckedDefaultText: 最後檢查時間未知 - inactive: - description: 繼續行程監控,以查看更新的狀態 - heading: 行程監控已暫停 - nextTripNotPossible: - description: "行程規劃器無法找到您今天的行程。請嘗試重新規劃預定行程,以尋找替代路線。\n" - heading: 行程今天不可行 - noLongerPossible: - description: "行程規劃器無法找到您在週間任一選取日期的行程。請嘗試重新規劃預定行程,以尋找替代路線。\n" - heading: 行程已不再可行 - notCalculated: - awaiting: 正在等待計算…… - description: 請等待行程計算。 - heading: 行程尚未計算 - snoozed: - description: 取消延遲行程監控,以查看更新的狀態。 - heading: 已為今天延遲行程監控 - upcoming: - nextTripBegins: 下一個行程將在{tripDatetime, date, ::eeeee yyyyMMdd}的{tripDatetime, - time, short}開始。 - tripBegins: 行程預計在{tripStart, time, short}開始。(即時監控將在{monitoringStart, time, short}開始。) - tripStartIsDelayed: 行程開始時間延誤${duration}! - tripStartIsEarly: 行程開始時間比預期提早${duration}! - tripStartsSoonNoUpdates: 行程即將開始 (沒有可用的即時更新)。 - tripStartsSoonOnTime: 行程即將開始且大約準時。 - TripSummary: - leaveAt: '離開點 ' - arriveAt: '抵達 ' - TripSummaryPane: - happensOnDays: 發生於:{days} - notifications: 預定出發前{leadTimeInMinutes}分鐘 - notificationsDisabled: 通知已停用 - TripTools: - copyLink: 複製連結 - reportEmailSubject: 回報OpenTripPlanner的問題 - header: 行程工具 - linkCopied: 已複製 - reportEmailTemplate: "\"*** 給使用者的指示 ***\n此功能可讓您透過電子郵件寄送報告給網站管理員進行審查。\n 請填寫下方的提示部分,並使用您平常的電子郵件程式寄送。\n - \n*** 請填寫以下內容 *** \n \n 遇到的問題:\n \n 您想要使用的行程類型 (例如步行+公共交通、自行車+公共交通、汽車+公共交通):\n - \n*** 技術詳細資訊 ***\"\n" - reportIssue: 回報問題 - TripViewer: - listOfRouteStops: 此路線上的車站清單 - startOfTrip: 行程從這裡開始 - accessible: 無障礙 - bicyclesAllowed: 已允許 - endOfTrip: 行程到此結束 - header: 行程檢視器 - routeHeader: 路線:{routeShortName} {routeLongName} - tripDescription: 在 {boardAtStop} 上車,在 {disembarkAtStop} 下車 - viewStop: 檢視 - UserAccountScreen: - confirmDelete: 您確定要刪除使用者帳戶嗎?一旦刪除,就無法復原。 - errorUpdatingProfile: 更新設定檔時發生錯誤。 - fieldUpdated: 此設定已更新。 - updating: 正在更新 - fields: - storeTripHistory: 儲存行程歷史紀錄 - UserSettings: - mySavedPlaces: 我的已儲存地點 (管理) - noFavoriteStops: 沒有最愛的車站 - recentPlaces: 最近的地點 - recentSearchSummary: '{mode},從{from}到{to}' - recentSearches: 最近的搜尋 - rememberSearches: 要記住最近的搜尋/地點嗎? - stopId: 車站ID:{stopId} - confirmDeletion: 您有儲存的最近的搜尋和/或地點。停用儲存最近的地點/搜尋將移除這些項目。是否要繼續? - favoriteStops: 最愛的車站 - myPreferences: 我的偏好 - storageDisclaimer: "您選擇儲存的任何偏好、地點或設定都將儲存在您瀏覽器的本機儲存空間。TriMet無法存取有關您住家、工作或任何其他位置的資訊。您可以隨時選擇不要記住最近的地點/搜尋,並清除您的已儲存住家/工作位置和最愛的車站。\n" - VerifyEmailPane: - instructions2: 驗證之後,請按下方按鈕以繼續。 - resendVerification: 重新寄送驗證電子郵件 - emailIsVerified: 我的電子郵件已驗證! - instructions1: "請查看您的電子郵件收件匣,並前往信件中的連結以驗證您的電子郵件地址,再完成帳戶設定。\n" - ViewSwitcher: - nearby: 檢視附近 - switcher: 切換工具 - WelcomeScreen: - prompt: 您想要去哪裡? - A11yPrefs: - accessibilityRoutingByDefault: 預設優先選擇無障礙行程 - AddPlaceButton: - addPlace: 新增地點 - needOriginDestination: 定義起點/目的地以新增中間地點 - tooManyPlaces: 已達到中間地點數量上限 - AdvancedOptions: - bannedRoutes: 選取禁止的路線…… - preferredRoutes: 選取首選路線…… - BatchSearchScreen: - header: 規劃您的行程 - modeSelectorLabel: 選取出行模式 - BatchSettings: - destination: 目的地 - invalidModeSelection: 無法使用所選模式規劃行程。嘗試將公共交通納入您的模式選取內容。 - origin: 起點 - planTripTooltip: 規劃行程 - validationMessage: 請定義以下欄位以規劃行程:{issues} - CallTakerPanel: - advancedOptions: 進階選項 - groupSize: 群組大小: - intermediateDestination: 輸入中間目的地 - DateTimeScreen: - header: 設定日期/時間 - DeleteUser: - deleteMyAccount: 刪除我的帳戶 - ErrorMessage: - header: 無法規劃行程 - warning: 警告 - FormNavigationButtons: - ariaLabel: 表單導航 - ItinerarySummary: - itineraryDetails: 路線詳細資訊 - minMaxFare: '{minTotalFare} - {maxTotalFare}' - LocationSearch: - enterLocation: 輸入位置 - setDestination: 設定目的地 - setOrigin: 設定起點 - MapillaryFrame: - title: 街道圖像 - MobileOptions: - header: 設定搜尋選項 - NarrativeItinerariesHeader: - changeSortDir: 變更排序方向 - howToFindResults: 要檢視結果,請參閱下方「找到的預定行程」標題。 - itinerariesFound: '{itineraryNum}個預定行程已找到' - numIssues: '{issueNum}個問題' - resultsSortedBy: 行程結果目前依{sortSelected}排序。如需變更結果的排序方式,請使用下方「排序結果」按鈕。 - searching: 正在尋找您的選項…… - selectArrivalTime: 抵達時間 - selectBest: 最佳選項 - selectCost: 費用 - selectDepartureTime: 出發時間 - selectDuration: 期間 - selectWalkTime: 步行時間 - sortResults: 對結果排序 - viewAll: 檢視所有選項 - NavLoginButton: - help: 說明 - myAccount: 我的帳戶 - signIn: 登入 - signOut: 登出 - NearbyView: - bikeRentalStation: 自行車租車站 - bikesAvailable: '{bikesAvailable}輛自行車可用' - companyBicycle: '{company} 自行車' - companyScooter: '{company} 滑板車' - error: 載入鄰近設施時發生錯誤。 - header: 檢視附近 - spacesAvailable: '{spacesAvailable} 有未佔用的空間' - NewAccountWizard: - createNewAccount: 建立新帳戶 - finish: 帳戶設定完成! - notifications: 通知偏好 - places: 新增您的位置 - verify: 驗證您的電子郵件地址 - NotFound: - description: 您要求的內容無法使用。 - header: 找不到內容 - NotificationPrefsPane: - devicesRegistered: '{count}個裝置 已註冊' - noDeviceForPush: 使用行動應用程式註冊您的裝置以存取推播通知。 - notificationChannelPrompt: 透過以下方式接收有關您已儲存之行程的通知: - Place: - deleteThisPlace: 刪除此地點 - enterAlert: "請在表單內輸入起點/目的地 (或按一下地圖來設定),然後按一下產生的標記以設定為{placeType}位置。\n" - viewStop: 檢視車站 - RealtimeAnnotation: - delaysShownInResults: "您的行程結果已依據即時資訊調整。在一般情況下,此形成使用以下路線會需要{normalDuration}:{routes}。\n" - serviceUpdate: 服務更新 - ResultsError: - backToSearch: 返回搜尋 - RouteDetails: - headsignTo: '{headsign} ({lastStop})' - moreDetails: 更多詳細資訊 - operatedBy: 由{agencyName}營運 - selectADirection: 選取方向…… - stopsTo: 朝向 - SaveTripButton: - cantSaveText: 無法儲存 - cantSaveTooltip: 僅能監控包括公共交通且沒有租賃或叫車服務的預定行程。 - saveTripText: 儲存行程 - signInText: 登入以儲存行程 - signInTooltip: 請登入以儲存行程。 - SavedTripEditor: - editSavedTrip: 編輯儲存的行程 - saveNewTrip: 儲存新行程 - tripInformation: 行程資訊 - tripNotFound: 找不到行程 - tripNotFoundDescription: 很抱歉,找不到請求的行程。 - tripNotifications: 行程通知 - SavedTripScreen: - itineraryLoaded: 路線已載入 - itineraryLoading: 正在載入路線 - tooManyTrips: "您已經達到五個儲存行程上限。請將未使用的行程從已儲存行程中移除,然後再試一次。\n" - tripNameAlreadyUsed: 已經有另一個儲存的行程使用此名稱。請選擇其他名稱。 - tripNameRequired: 請輸入行程名稱。 - SequentialPaneDisplay: - stepNumber: 第{step}步,共{total}步 - SessionTimeout: - body: 您的工作階段將在一分鐘內失效。請按下「Continue Session」(繼續工作階段) 以保留搜尋。 - header: 工作階段即將逾時! - keepSession: 繼續工作階段 - StopTimeCell: - imminentArrival: 到 - realtime: 依據即時資料 - scheduled: 依據排程資料 - TripStatus: - alerts: '{alerts}個警示!' - deleteTrip: 刪除行程 - planNewTrip: 規劃新行程 - UserTripSettings: - forgetOptions: 忘記我的選項 - rememberOptions: 記住行程選項 - restoreDefaults: 還原預設值 - restoreMyDefaults: 還原我的預設值 -config: - accessModes: - car_hail: 叫車服務 - car_park: 停車轉乘 - micromobility: 公共交通+個人滑板車 - micromobility_rent: 公共交通+電動滑板車租賃 - bicycle: 公共交通+個人自行車 - bicycle_rent: 公共交通+共享自行車 - bicycleModes: - bicycle: 自有自行車 - bicycle_rent: 自行車共享 - micromobilityModes: - micromobility: 自有電動滑板車 - micromobility_rent: 租賃電動滑板車 - flex: - both: 請查看預定行程底部以瞭解詳細資訊 - call-ahead: 致電預約 - continuous-dropoff: 與業者溝通車站事宜 - flex-service: 彈性服務 - flex-service-colon: 彈性服務: -util: - state: - noTripFoundReason: 指定的最大距離內或指定的時間可能沒有公共交通服務,或是您的起點或終點可能無法安全前往。 - noTripFoundWithReason: '{noTripFound} {reason}' - errorPlanningTrip: 規劃行程時發生錯誤。 - networkUnavailable: '{network}網路目前無法使用。' - noTripFound: 找不到行程。 - noTripFoundForMode: 找不到{modes}的行程。 diff --git a/lib/actions/api.js b/lib/actions/api.js index 2a1f64b7d..22e644314 100644 --- a/lib/actions/api.js +++ b/lib/actions/api.js @@ -7,7 +7,7 @@ import { createAction } from 'redux-actions' import coreUtils from '@opentripplanner/core-utils' import qs from 'qs' -import { combineQueryParams, removeUnusedQueryParams } from '../util/api' +import { combineQueryParams } from '../util/api' import { FETCH_STATUS } from '../util/constants' import { getSecureFetchOptions } from '../util/middleware' @@ -114,8 +114,6 @@ export function updateOtpUrlParams(state, searchId) { const { config, currentQuery } = state.otp // Get updated OTP params from current query. const otpParams = getRoutingParams(config, currentQuery, true) - removeUnusedQueryParams(otpParams) - return function (dispatch, getState) { const params = {} // Get all URL params and ensure non-routing params (UI, sessionId) remain @@ -129,8 +127,8 @@ export function updateOtpUrlParams(state, searchId) { }) params.ui_activeSearch = searchId - // Assumes this is a new search and the active itinerary should be reset (i.e. removed). - params.ui_activeItinerary = undefined + // Assumes this is a new search and the active itinerary should be reset. + params.ui_activeItinerary = -1 // At the same time, reset/delete the ui_itineraryView param. params.ui_itineraryView = undefined // Merge in the provided OTP params and update the URL. diff --git a/lib/actions/apiV2.js b/lib/actions/apiV2.js index fde4ab97b..1b60a448f 100644 --- a/lib/actions/apiV2.js +++ b/lib/actions/apiV2.js @@ -11,7 +11,11 @@ import coreUtils from '@opentripplanner/core-utils' import { checkForRouteModeOverride } from '../util/config' import { convertToPlace, getPersistenceMode } from '../util/user' import { FETCH_STATUS } from '../util/constants' -import { generateModeSettingValues, getServiceStart } from '../util/api' +import { + generateModeSettingValues, + getDefaultNumItineraries, + getServiceStart +} from '../util/api' import { getActiveItineraries, getActiveItinerary, @@ -939,8 +943,7 @@ export function routingQuery(searchId = null, updateSearchInReducer) { modes, numItineraries, routingType, - time, - unpreferred + time } = currentQuery const arriveBy = departArrive === 'ARRIVE' @@ -995,12 +998,11 @@ export function routingQuery(searchId = null, updateSearchInReducer) { from: currentQuery.from, modes: modes || activeModes, modeSettings, + numItineraries: numItineraries || config?.modes?.numItineraries || 7, time, to: currentQuery.to, - unpreferred, // TODO: Does this break everything? - ...currentQuery, - numItineraries: config?.modes?.numItineraries || numItineraries || 7 + ...currentQuery } // Generate combinations if the modes for query are not specified in the query // FIXME: BICYCLE_RENT does not appear in this list unless TRANSIT is also enabled. diff --git a/lib/actions/field-trip.js b/lib/actions/field-trip.js index 9c2b771dd..da34ec27b 100644 --- a/lib/actions/field-trip.js +++ b/lib/actions/field-trip.js @@ -495,9 +495,6 @@ export function saveRequestTripItineraries(request, outbound, intl) { function prepareQueryParams(request, outbound) { return async function (dispatch, getState) { const { config } = getState().otp - const { modules, transitOperators } = config - const fieldTripOptions = modules?.find((m) => m.id === 'ft')?.options - const queryParams = { date: format(parseDate(request.travelDate), OTP_API_DATE_FORMAT) } @@ -523,16 +520,6 @@ function prepareQueryParams(request, outbound) { OTP_API_TIME_FORMAT ) } - // Generate banned list from clear list - if (fieldTripOptions?.allowedAgencies) { - const bannedAgencies = transitOperators - .map((to) => to.agencyId) - .filter((to) => !fieldTripOptions.allowedAgencies.includes(to)) - - queryParams.unpreferred = { - agencies: bannedAgencies - } - } const locations = await planParamsToQueryAsync(locationsToGeocode, config) return dispatch(setQueryParam({ ...locations, ...queryParams })) } diff --git a/lib/actions/form.js b/lib/actions/form.js index 34bdbcb71..bfdc65fe7 100644 --- a/lib/actions/form.js +++ b/lib/actions/form.js @@ -5,6 +5,7 @@ import debounce from 'lodash.debounce' import isEqual from 'lodash.isequal' import qs from 'qs' +import { getDefaultQuery } from '../util/api' import { queryIsValid } from '../util/state' import { MobileScreens } from './ui-constants' @@ -12,12 +13,8 @@ import { routeTo, setMainPanelContent, setMobileScreen } from './ui' import { routingQuery, setUrlSearch } from './api' import { setLocation, settingLocation } from './map' -const { - getDefaultQuery, - getTripOptionsFromQuery, - getUrlParams, - planParamsToQueryAsync -} = coreUtils.query +const { getTripOptionsFromQuery, getUrlParams, planParamsToQueryAsync } = + coreUtils.query export const settingQueryParam = createAction('SET_QUERY_PARAM') export const clearActiveSearch = createAction('CLEAR_ACTIVE_SEARCH') @@ -33,17 +30,15 @@ export const storeDefaultSettings = createAction('STORE_DEFAULT_SETTINGS') export function resetForm(full = false) { return function (dispatch, getState) { const state = getState() - const { transitModes } = state.otp.config.modes + const { config } = state.otp + const { transitModes } = config.modes const { defaults: localUserDefaults } = state.user.localUser if (localUserDefaults) { dispatch(settingQueryParam(localUserDefaults)) } else { // Get user overrides and apply to default query const userOverrides = coreUtils.storage.getItem('defaultQuery', {}) - const defaultQuery = Object.assign( - getDefaultQuery(state.otp.config), - userOverrides - ) + const defaultQuery = Object.assign(getDefaultQuery(config), userOverrides) // Filter out non-options (i.e., date, places). const options = getTripOptionsFromQuery(defaultQuery) // Default mode is currently WALK,TRANSIT. We need to update this value diff --git a/lib/actions/narrative.js b/lib/actions/narrative.js index ac18279a5..88418392c 100644 --- a/lib/actions/narrative.js +++ b/lib/actions/narrative.js @@ -16,8 +16,6 @@ export function setActiveItinerary(payload) { // Remove the ui_itineraryView param if changing to another itinerary. // Note: set to undefined instead of deleting so that it merges with the other search params. urlParams.ui_itineraryView = undefined - // Also remove the ui_activeItinerary from URL because that's the default value. - urlParams.ui_activeItinerary = undefined } dispatch(setUrlSearch(urlParams)) diff --git a/lib/actions/ui.js b/lib/actions/ui.js index cdd0691da..9591853dc 100644 --- a/lib/actions/ui.js +++ b/lib/actions/ui.js @@ -13,7 +13,6 @@ import { getItineraryView, getMapToggleNewItineraryView, getPathFromParts, - isDefined, isDefinedAndNotEqual, ItineraryView } from '../util/ui' @@ -335,9 +334,7 @@ export function handleBackButtonPress(e) { // console.log('back button pressed', e) const urlParams = coreUtils.query.getUrlParams() const previousSearchId = urlParams.ui_activeSearch - const previousItinIndex = isDefined(urlParams.ui_activeItinerary) - ? urlParams.ui_activeItinerary - : -1 + const previousItinIndex = +urlParams.ui_activeItinerary || 0 const previousSearch = state.otp.searches[previousSearchId] if (previousSearch) { // If back button pressed and active search has changed, set search to @@ -453,7 +450,9 @@ export function setLocale(locale) { dispatch(updateLocale({ locale: matchedLocale, messages })) // Update the lang attribute in the root element. - document.documentElement.lang = matchedLocale + // (The lang is the first portion of the locale.) + const lang = matchedLocale.split('-')[0] + document.documentElement.lang = lang window.localStorage.setItem('lang', matchedLocale) diff --git a/lib/components/app/desktop-nav.tsx b/lib/components/app/desktop-nav.tsx index cd877b1b8..f9a265b86 100644 --- a/lib/components/app/desktop-nav.tsx +++ b/lib/components/app/desktop-nav.tsx @@ -31,6 +31,26 @@ const StyledNav = styled(Nav)` margin-left: 5px; margin-right: -10px; } + + .navBarItem { + position: static; + & > button { + background: transparent; + border: none; + color: white; + padding: 15px; + line-height: 20px; + + @media (max-width: 768px) { + padding: 10px; + } + + &:hover { + background: rgba(0, 0, 0, 0.05); + color: #ececec; + } + } + } ` const NavItemOnLargeScreens = styled(NavbarItem)` diff --git a/lib/components/app/locale-selector.tsx b/lib/components/app/locale-selector.tsx index a3681fe86..6e410aa6a 100644 --- a/lib/components/app/locale-selector.tsx +++ b/lib/components/app/locale-selector.tsx @@ -1,10 +1,10 @@ import { connect } from 'react-redux' +import { Dropdown } from '@opentripplanner/building-blocks' import { GlobeAmericas } from '@styled-icons/fa-solid/GlobeAmericas' import { useIntl } from 'react-intl' import React from 'react' import * as uiActions from '../../actions/ui' -import { Dropdown } from '../util/dropdown' import { getLanguageOptions } from '../../util/i18n' import { UnstyledButton } from '../util/unstyled-button' @@ -23,11 +23,12 @@ const LocaleSelector = (props: LocaleSelectorProps): JSX.Element | null => { return languageOptions ? (
                                                        1. } style={{ display: 'block ruby' }} + text={} > {Object.keys(languageOptions).map((locale: string) => (
                                                        2. diff --git a/lib/components/form/batch-styled.ts b/lib/components/form/batch-styled.ts index afaa9159e..2283f3b9e 100644 --- a/lib/components/form/batch-styled.ts +++ b/lib/components/form/batch-styled.ts @@ -4,8 +4,10 @@ import styled, { css } from 'styled-components' export const buttonPixels = 51 export const activeCss = css` - /* Make elements slightly darker on hover. */ - filter: brightness(90%); + /* Make elements internal content slightly transparent on hover. */ + & > * { + opacity: 90%; + } ` const buttonTransitionCss = css` diff --git a/lib/components/map/itinerary-summary-overlay.tsx b/lib/components/map/itinerary-summary-overlay.tsx index 8baf875ac..632ffd7ee 100644 --- a/lib/components/map/itinerary-summary-overlay.tsx +++ b/lib/components/map/itinerary-summary-overlay.tsx @@ -18,7 +18,6 @@ import { getActiveSearch, getVisibleItineraryIndex } from '../../util/state' -import { isDefined } from '../../util/ui' import MetroItineraryRoutes from '../narrative/metro/metro-itinerary-routes' type ItinWithGeometry = Itinerary & { @@ -157,7 +156,7 @@ const ItinerarySummaryOverlay = ({ (mp) => // If no itinerary is hovered, show all of them. If one is selected, show only that one // TODO: clean up conditionals, move these to a more appropriate place without breaking indexing - (isDefined(visibleItinerary) + (visibleItinerary !== null && visibleItinerary !== undefined ? visibleItinerary === mp.itin.index : true) && mp.uniquePoint && ( diff --git a/lib/components/narrative/line-itin/connected-itinerary-body.js b/lib/components/narrative/line-itin/connected-itinerary-body.js index 287a9852a..28a763cd7 100644 --- a/lib/components/narrative/line-itin/connected-itinerary-body.js +++ b/lib/components/narrative/line-itin/connected-itinerary-body.js @@ -84,6 +84,8 @@ class ConnectedItineraryBody extends Component { const showViewTripButton = !config?.itinerary?.hideViewTripButton const allowUserAlertCollapsing = config?.itinerary?.allowUserAlertCollapsing + const showApproximatePrefixAccessLegs = + config?.itinerary?.showApproximatePrefixAccessLegs // Support OTP1 flex messages in Trip Details // Adding empty pickupBookingInfo and dropOffBookingInfo objects @@ -134,6 +136,7 @@ class ConnectedItineraryBody extends Component { setMainPanelContent(MainPanelContent.TRIP_VIEWER) }} showAgencyInfo + showApproximateAccessLegTravelTimes={showApproximatePrefixAccessLegs} showElevationProfile={config.elevationProfile} showLegIcon showMapButtonColumn={false} @@ -144,7 +147,10 @@ class ConnectedItineraryBody extends Component { TransitLegSubheader={TransitLegSubheader} TransitLegSummary={TransitLegSummary} /> - + ) diff --git a/lib/components/narrative/narrative-itineraries-header.tsx b/lib/components/narrative/narrative-itineraries-header.tsx index 6d9615510..6b59f5f37 100644 --- a/lib/components/narrative/narrative-itineraries-header.tsx +++ b/lib/components/narrative/narrative-itineraries-header.tsx @@ -1,5 +1,6 @@ /* eslint-disable complexity */ import { ArrowLeft } from '@styled-icons/fa-solid/ArrowLeft' +import { Dropdown } from '@opentripplanner/building-blocks' import { ExclamationTriangle } from '@styled-icons/fa-solid/ExclamationTriangle' import { FormattedMessage, useIntl } from 'react-intl' import { Itinerary } from '@opentripplanner/types' @@ -11,7 +12,6 @@ import styled from 'styled-components' import { IconWithText, StyledIconWrapper } from '../util/styledIcon' import { ItinerarySortOption } from '../../util/config-types' import { sortOptions } from '../util/sortOptions' -import { SortResultsDropdown } from '../util/dropdown' import { UnstyledButton } from '../util/unstyled-button' import InvisibleA11yLabel from '../util/invisible-a11y-label' import PopupTriggerText from '../app/popup-trigger-text' @@ -206,10 +206,10 @@ export default function NarrativeItinerariesHeader({ )} - {sortOptionsArr.map((sortOption) => ( @@ -223,7 +223,7 @@ export default function NarrativeItinerariesHeader({
                                                        3. ))} - + diff --git a/lib/components/narrative/narrative-itineraries.js b/lib/components/narrative/narrative-itineraries.js index 7d9faded6..06e5adaf9 100644 --- a/lib/components/narrative/narrative-itineraries.js +++ b/lib/components/narrative/narrative-itineraries.js @@ -27,8 +27,7 @@ import { itinerariesAreEqual, sortStartTimes } from '../../util/itinerary' -import { getItineraryView, isDefined, ItineraryView } from '../../util/ui' -import { grey } from '../util/colors' +import { getItineraryView, ItineraryView } from '../../util/ui' import { setActiveItinerary, setActiveLeg, @@ -42,6 +41,7 @@ import PageTitle from '../util/page-title' import * as S from './styled' import { getItineraryDescription } from './default/itinerary-description' +import { grey } from '../util/colors' import ErrorRenderer from './metro/metro-error-renderer' import Loading from './loading' import NarrativeItinerariesErrors from './narrative-itineraries-errors' @@ -586,7 +586,8 @@ const mapStateToProps = (state) => { } = config.itinerary || false // Default to true for backwards compatibility const renderSkeletons = !config.itinerary?.hideSkeletons - const itineraryIsExpanded = isDefined(activeItinerary) && showDetails + const itineraryIsExpanded = + activeItinerary !== undefined && activeItinerary !== null && showDetails const { localUser, loggedInUser } = state.user const user = loggedInUser || localUser diff --git a/lib/components/user/monitored-trip/trip-basics-pane.tsx b/lib/components/user/monitored-trip/trip-basics-pane.tsx index 76dcf1df4..9d98eedd1 100644 --- a/lib/components/user/monitored-trip/trip-basics-pane.tsx +++ b/lib/components/user/monitored-trip/trip-basics-pane.tsx @@ -1,9 +1,9 @@ +import { Ban } from '@styled-icons/fa-solid/Ban' import { connect } from 'react-redux' import { ControlLabel, FormControl, FormGroup, - Glyphicon, HelpBlock, ProgressBar, Radio @@ -26,6 +26,7 @@ import { } from '../../../util/monitored-trip' import { AppReduxState } from '../../../util/state-types' import { FieldSet } from '../styled' +import { getBaseColor, RED_ON_WHITE } from '../../util/colors' import { getErrorStates } from '../../../util/ui' import { ItineraryExistence, MonitoredTrip } from '../types' import FormattedDayOfWeek from '../../util/formatted-day-of-week' @@ -33,7 +34,7 @@ import FormattedDayOfWeekCompact from '../../util/formatted-day-of-week-compact' import FormattedValidationError from '../../util/formatted-validation-error' import InvisibleA11yLabel from '../../util/invisible-a11y-label' -import { BORDER_COLOR } from './trip-summary-pane' +import { MonitoredDayCircle } from './trip-monitored-days' import TripStatus from './trip-status' import TripSummary from './trip-duration-summary' @@ -55,6 +56,9 @@ interface State { // Styles. const AvailableDays = styled(FieldSet)` + display: flex; + gap: 4px; + // Targets the formik checkboxes to provide better contrast on focus styles input { &:focus-visible, @@ -67,54 +71,60 @@ const AvailableDays = styled(FieldSet)` } } & > span { - border: 1px solid ${BORDER_COLOR}; - border-left: none; + align-items: center; + border-radius: 3rem; box-sizing: border-box; - display: inline-block; - height: 3em; - max-width: 150px; - min-width: 14.28%; + display: inline-flex; + flex-direction: row-reverse; + height: 3rem; + min-width: 4.5rem; position: relative; text-align: center; + width: 5rem; } - & > span:first-of-type { - border-left: 1px solid ${BORDER_COLOR}; - } - - .glyphicon { + svg { + color: ${RED_ON_WHITE}; display: none; /* Remove top attribute set by Bootstrap. */ top: inherit; - } - - input { - display: block; + width: 1.3rem; } input, - .glyphicon { - bottom: 6px; - position: absolute; - width: 100%; + svg { + flex-shrink: 0; + /* Remove bootstrap's vertical margin */ + margin: 0 7px 0 2px; } /* Check boxes for disabled days are replaced with the cross mark. */ input[disabled] { - clip: rect(0, 0, 0, 0); - height: 0; - margin: 0; - width: 0; - z-index: -1; + display: none; } - input[disabled] ~ .glyphicon { + input[disabled] ~ svg { display: block; } - /* Make labels occupy the whole space, so the entire block is clickable. */ + /* Add oblique strike for disabled days */ + .disabled-day::after { + border-top: 2px solid ${RED_ON_WHITE}; + content: ''; + left: 0; + position: absolute; + right: 0; + top: 45%; + transform: rotate(-30deg); + transform-origin: center; + } + label { + flex-grow: 1; font-weight: inherit; height: 100%; - width: 100%; + line-height: 3rem; + margin: 0; + position: relative; + text-align: center; } ` @@ -304,11 +314,7 @@ class TripBasicsPane extends Component { day, finalItineraryExistence ) - const boxClass = isDayDisabled - ? 'alert-danger' - : monitoredTrip[day] - ? 'bg-primary' - : '' + const labelClass = isDayDisabled ? 'disabled-day' : '' const notAvailableText = isDayDisabled ? intl.formatMessage( { @@ -320,10 +326,12 @@ class TripBasicsPane extends Component { ) : '' + const baseColor = getBaseColor() return ( - { name={day} type="checkbox" /> + - {notAvailableText} - + ) })} diff --git a/lib/components/user/monitored-trip/trip-monitored-days.tsx b/lib/components/user/monitored-trip/trip-monitored-days.tsx index 81376a1dd..63f5f35f6 100644 --- a/lib/components/user/monitored-trip/trip-monitored-days.tsx +++ b/lib/components/user/monitored-trip/trip-monitored-days.tsx @@ -1,14 +1,12 @@ -import { FormattedList, FormattedMessage, useIntl } from 'react-intl' - -import InvisibleA11yLabel from '../../util/invisible-a11y-label' +import { FormattedList, FormattedMessage } from 'react-intl' import React from 'react' +import styled from 'styled-components' import { ALL_DAYS } from '../../../util/monitored-trip' import { getBaseColor } from '../../util/colors' import FormattedDayOfWeek from '../../util/formatted-day-of-week' import FormattedDayOfWeekCompact from '../../util/formatted-day-of-week-compact' - -import styled from 'styled-components' +import InvisibleA11yLabel from '../../util/invisible-a11y-label' interface Props { days: string[] @@ -19,7 +17,7 @@ const DayCircleContainer = styled.div` gap: 4px; ` -const MonitoredDayCircle = styled.span<{ +export const MonitoredDayCircle = styled.span<{ baseColor: string monitored: boolean }>` @@ -41,7 +39,7 @@ const MonitoredDayCircle = styled.span<{ } ` -const MonitoredDays = ({ days }: Props) => { +const MonitoredDays = ({ days }: Props): JSX.Element => { const monitoredDaysList = ( } - pullRight > -
                                                        4. {displayedName}
                                                        5. - - {links && - links.map((link, i) => { - if (link.url.startsWith('http')) { +

                                                          {displayedName}

                                                          +
                                                            + {links && + links.map((link, i) => { + if (link.url.startsWith('http')) { + return ( +
                                                          • + element here, + // so that the link works even when running the app locally. + as="a" + href={link.url} + target="_blank" + > + + + +
                                                          • + ) + } return (
                                                          • - element here, - // so that the link works even when running the app locally. - as="a" - href={link.url} - target="_blank" - > - - + + {link.messageId === 'myAccount' ? ( // messageId is 'myAccount' or 'help' + + ) : ( + + )}
                                                          • ) - } - return ( -
                                                          • - - {link.messageId === 'myAccount' ? ( // messageId is 'myAccount' or 'help' - - ) : ( - - )} - -
                                                          • - ) - })} + })} -
                                                            +
                                                            -
                                                          • - - - -
                                                          • +
                                                          • + + + +
                                                          • +
                                                          ) diff --git a/lib/components/util/dropdown.tsx b/lib/components/util/dropdown.tsx deleted file mode 100644 index db7d51215..000000000 --- a/lib/components/util/dropdown.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import React, { - HTMLAttributes, - KeyboardEvent, - useCallback, - useEffect, - useRef, - useState -} from 'react' - -import { DARK_TEXT_GREY } from './colors' -import { getEntryRelativeTo } from './get-entry-relative-to' -import { NavbarButton } from '../app/nav-item' -import styled from 'styled-components' - -interface Props extends HTMLAttributes { - id: string - label?: string - listLabel?: string - name?: JSX.Element | string - nav?: boolean - pullRight?: boolean -} - -const DropdownButton = styled(NavbarButton)`` - -const DropdownMenu = styled.ul` - background-clip: padding-box; - background-color: #fff; - border-radius: 4px; - border: 1px solid rgba(0, 0, 0, 0.15); - box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); - color: ${DARK_TEXT_GREY}; - list-style: none; - margin: 2px 0 0; - min-width: 160px; - padding: 5px 0; - position: absolute; - right: 0; - top: 100%; - width: 100%; - z-index: 1000; - - hr { - margin: 0; - padding: 0; - } - a, - button, - li.header { - padding: 5px 15px; - text-align: start; - width: 100%; - } - a, - button { - cursor: pointer; - } - li.header { - cursor: default; - font-weight: 600; - } - li:not(.header):hover { - background: rgba(0, 0, 0, 0.1); - } -` - -/** - * Renders a dropdown menu. By default, only a passed "name" is rendered. If clicked, - * a floating div is rendered below the "name" with list contents inside. Clicking anywhere - * outside the floating div will close the dropdown. - */ -export const Dropdown = ({ - children, - className, - id, - label, - listLabel, - name, - pullRight, - style -}: Props): JSX.Element => { - const [open, setOpen] = useState(false) - const containerRef = useRef(null) - - const toggleOpen = useCallback(() => setOpen(!open), [open, setOpen]) - - // Argument for document.querySelectorAll to target focusable elements. - const queryId = `#${id} button, #${id}-label` - - // Adding document event listeners allows us to close the dropdown - // when the user interacts with any part of the page that isn't the dropdown - useEffect(() => { - const handleExternalAction = (e: Event): void => { - if (!containerRef?.current?.contains(e.target as HTMLElement)) { - setOpen(false) - } - } - document.addEventListener('mousedown', handleExternalAction) - document.addEventListener('focusin', handleExternalAction) - document.addEventListener('keydown', handleExternalAction) - return () => { - document.removeEventListener('mousedown', handleExternalAction) - document.removeEventListener('focusin', handleExternalAction) - document.removeEventListener('keydown', handleExternalAction) - } - }, [containerRef]) - - const _handleKeyDown = useCallback( - (e: KeyboardEvent): void => { - const element = e.target as HTMLElement - switch (e.key) { - case 'ArrowUp': - e.preventDefault() - getEntryRelativeTo(queryId, element, -1)?.focus() - break - case 'ArrowDown': - e.preventDefault() - getEntryRelativeTo(queryId, element, 1)?.focus() - break - case 'Escape': - setOpen(false) - break - case ' ': - case 'Enter': - e.preventDefault() - element.click() - if (element.id === `${id}-label` || element.id === `${id}-wrapper`) { - toggleOpen() - } - break - default: - } - }, - [id, toggleOpen] - ) - - return ( - - - {name} - - - {open && ( - - {children} - - )} - - ) -} - -export const SortResultsDropdown = styled(Dropdown)` - position: relative; - - ${DropdownButton} { - background: #fff; - border-radius: 5px; - color: inherit; - padding: 3px 7px; - - span.caret { - color: inherit; - } - } -` diff --git a/lib/components/viewers/nearby/stop.tsx b/lib/components/viewers/nearby/stop.tsx index de0ccc0f5..0fdc0a694 100644 --- a/lib/components/viewers/nearby/stop.tsx +++ b/lib/components/viewers/nearby/stop.tsx @@ -38,19 +38,9 @@ const Stop = ({ const patternRows = (stopData.stoptimesForPatterns || []) ?.reduce((acc, cur) => { const currentHeadsign = extractHeadsignFromPattern(cur.pattern) - const dupe = acc.findIndex((p) => { - // TODO: use OTP_generated ids - let sameRoute = false - if (p.pattern.route?.shortName && cur.pattern.route?.shortName) { - sameRoute = - p.pattern.route?.shortName === cur.pattern.route?.shortName - } else if (p.pattern.route?.longName && cur.pattern.route?.longName) { - sameRoute = p.pattern.route?.longName === cur.pattern.route?.longName - } - return ( - extractHeadsignFromPattern(p.pattern) === currentHeadsign && sameRoute - ) - }) + const dupe = acc.findIndex( + (p) => extractHeadsignFromPattern(p.pattern) === currentHeadsign + ) if (dupe === -1) { acc.push(cur) } else { @@ -72,7 +62,6 @@ const Stop = ({ ) return ( { * viewer. */ const PatternRow = ({ - alwaysShowLongName, homeTimezone, pattern, roundedTop = true, @@ -103,11 +101,6 @@ const PatternRow = ({ /> - {alwaysShowLongName && !!pattern.route.longName && ( - - {pattern.route.longName} - - )} {extractHeadsignFromPattern(pattern) || (pattern.route.longName !== routeName && pattern.route.longName)} diff --git a/lib/components/viewers/route-details.tsx b/lib/components/viewers/route-details.tsx index 594ea31a4..cf2260a19 100644 --- a/lib/components/viewers/route-details.tsx +++ b/lib/components/viewers/route-details.tsx @@ -1,4 +1,5 @@ import { connect } from 'react-redux' +import { Dropdown } from '@opentripplanner/building-blocks' import { FormattedMessage, injectIntl, IntlShape } from 'react-intl' import { getMostReadableTextColor } from '@opentripplanner/core-utils/lib/route' import { Stop, TransitOperator } from '@opentripplanner/types' @@ -16,7 +17,6 @@ import { SetViewedStopHandler, ViewedRouteObject } from '../util/types' -import { SortResultsDropdown } from '../util/dropdown' import { UnstyledButton } from '../util/unstyled-button' import { @@ -38,6 +38,13 @@ const PatternSelectButton = styled(UnstyledButton)` } ` +const PatternSelectDropdown = styled(Dropdown)` + span, + span.caret { + color: #333; + } +` + interface Props { intl: IntlShape operator: TransitOperator @@ -149,12 +156,12 @@ class RouteDetails extends Component { - {headsigns.map((h: PatternSummary) => (
                                                        6. @@ -166,7 +173,7 @@ class RouteDetails extends Component {
                                                        7. ))} -
                                                          + )} {pattern && ( diff --git a/lib/reducers/create-otp-reducer.js b/lib/reducers/create-otp-reducer.js index 29a5dc0ee..e4038232b 100644 --- a/lib/reducers/create-otp-reducer.js +++ b/lib/reducers/create-otp-reducer.js @@ -12,12 +12,12 @@ import { PERSIST_TO_LOCAL_STORAGE, TIMEOUT_IGNORED_ACTIONS } from '../util/constants' +import { getDefaultQuery } from '../util/api' import { getISOLikeTimestamp } from '../util/state' import { MainPanelContent, MobileScreens } from '../actions/ui-constants' -import { removeUnusedQueryParams } from '../util/api' const { filterProfileOptions } = coreUtils.profile -const { getDefaultQuery, getUrlParams } = coreUtils.query +const { getUrlParams } = coreUtils.query const { getItem } = coreUtils.storage const { getUserTimezone } = coreUtils.time @@ -109,8 +109,6 @@ export function getInitialState(userDefinedConfig) { const userOverrides = getItem('defaultQuery', {}) // Combine user overrides with default query to get default search settings. const defaults = Object.assign(getDefaultQuery(config), userOverrides) - removeUnusedQueryParams(defaults) - // TODO: parse and merge URL query params w/ default query // populate query by merging any provided query params w/ the default params const currentQuery = Object.assign(defaults, userDefinedConfig.initialQuery) diff --git a/lib/reducers/create-user-reducer.js b/lib/reducers/create-user-reducer.js index 5899d0524..a02eb9148 100644 --- a/lib/reducers/create-user-reducer.js +++ b/lib/reducers/create-user-reducer.js @@ -5,10 +5,9 @@ import isEqual from 'lodash.isequal' import update from 'immutability-helper' import { convertToLegacyLocation, convertToPlace } from '../util/user' -import { removeUnusedQueryParams } from '../util/api' const { matchLatLon } = coreUtils.map -const { getDefaultQuery, getTripOptionsFromQuery } = coreUtils.query +const { getTripOptionsFromQuery } = coreUtils.query const { getItem, removeItem, storeItem } = coreUtils.storage const MAX_RECENT_STORAGE = 5 @@ -107,7 +106,6 @@ function loadUserFromLocalStorage(config) { const userOverrides = getItem('defaultQuery', {}) // Combine user overrides with default query to get default search settings. const defaults = Object.assign(getDefaultQuery(config), userOverrides) - removeUnusedQueryParams(defaults) return { localUser: { diff --git a/lib/util/api.ts b/lib/util/api.ts index 685622857..d20b6ac24 100644 --- a/lib/util/api.ts +++ b/lib/util/api.ts @@ -4,7 +4,10 @@ import { toDate } from 'date-fns-tz' import coreUtils from '@opentripplanner/core-utils' import qs from 'qs' +import { AppConfig } from './config-types' + const { getUrlParams } = coreUtils.query +const { getCurrentDate, getCurrentTime } = coreUtils.time export const SERVICE_BREAK = '03:30' @@ -57,17 +60,3 @@ export function combineQueryParams( } return qs.stringify(search, { arrayFormat: 'repeat' }) } - -/** - * Drops unused params so they don't show up in URL. - * TODO: Remove dependency on getDefaultQuery from core-utils. - */ -export function removeUnusedQueryParams(params: Record): void { - delete params.showIntermediateStops - delete params.otherThanPreferredRoutesPenalty - delete params.ignoreRealtimeUpdates - delete params.optimize - delete params.optimizeBike - delete params.maxWalkDistance - delete params.maxBikeDistance -} diff --git a/lib/util/config-types.ts b/lib/util/config-types.ts index 8ee11a359..ed2e560fd 100644 --- a/lib/util/config-types.ts +++ b/lib/util/config-types.ts @@ -69,7 +69,6 @@ export type BugsnagConfig = ApiKeyConfig export type MapillaryConfig = ApiKeyConfig export type NearbyViewConfig = { - alwaysShowLongName?: boolean hideEmptyStops?: boolean radius?: number showShadowDotOnMapDrag?: boolean @@ -280,6 +279,7 @@ export interface ItineraryConfig { previewOverlay?: boolean renderRouteNamesInBlocks?: boolean showAllWalkLegs?: boolean + showApproximatePrefixAccessLegs?: boolean showFirstResultByDefault?: boolean showHeaderText?: boolean showLegDurations?: boolean @@ -318,6 +318,7 @@ export interface ModesConfig { } modeButtons?: ModeButtonDefinition[] modeSettingDefinitions?: ModeSetting[] + numItineraries?: number transitModes: TransitModeConfig[] } diff --git a/lib/util/i18n.js b/lib/util/i18n.js index 6f210c071..baf060672 100644 --- a/lib/util/i18n.js +++ b/lib/util/i18n.js @@ -16,21 +16,17 @@ const merge = require('deepmerge') * Default to english if unsupported. */ export function getMatchingLocaleString( - locale, + locale = '', defaultLocale = 'en-US', configLocales = {} ) { - const [lang, region] = (locale || '').split('-') + const [lang, region] = locale.toLowerCase().split('-') const language = configLocales[lang] if (!language) return defaultLocale const defaultRegion = Object.keys(language)[0] - - return ( - language[region] || - (typeof language === 'string' - ? language // Allow returning w/o region code. - : language[defaultRegion]) - ) + return language[region] || typeof language === 'string' + ? language // Allow returning w/o region code. + : language[defaultRegion] } /** @@ -122,38 +118,36 @@ async function loadOtpUiLocaleData(matchedLocale) { export async function loadLocaleData(matchedLocale, customMessages) { let messages let otpUiLocale = matchedLocale - // Unless noted, non-English-US translations are not specific to a region. switch (matchedLocale) { - case 'es': + case 'es': // Spanish translation is not specific to a region messages = await import('../../i18n/es.yml') break case 'fr': messages = await import('../../i18n/fr.yml') break - case 'ko': + case 'ko': // Korean translation is not specific to a region messages = await import('../../i18n/ko.yml') break - case 'vi': + case 'vi': // Vietnamese translation is not specific to a region messages = await import('../../i18n/vi.yml') break - // If only 'zh' is configured and no other Chinese subset is, use Chinese Simplified. - case 'zh': - case 'zh-Hans': - messages = await import('../../i18n/zh_Hans.yml') + case 'zh': // Chinese (Simplified) translation is not specific to a region + messages = await import('../../i18n/zh.yml') + // The OTP-UI files for Chinese (Simplified) are (correctly) named `zh_Hans`. + // TODO: Rename this repo's zh files to zh_Hans otpUiLocale = 'zh_Hans' break - case 'zh-Hant': - messages = await import('../../i18n/zh_Hant.yml') - otpUiLocale = 'zh_Hant' - break - case 'ru': + case 'ru': // Russian translation is not specific to a region messages = await import('../../i18n/ru.yml') + otpUiLocale = 'ru' break - case 'tl': + case 'tl': // Tagalog translation is not specific to a region messages = await import('../../i18n/tl.yml') + otpUiLocale = 'tl' break default: messages = await import('../../i18n/en-US.yml') + break } const otpUiMessages = await loadOtpUiLocaleData(otpUiLocale) diff --git a/lib/util/pattern-viewer.ts b/lib/util/pattern-viewer.ts deleted file mode 100644 index 1b974df36..000000000 --- a/lib/util/pattern-viewer.ts +++ /dev/null @@ -1,65 +0,0 @@ -import { Pattern } from '../components/util/types' - -import { extractHeadsignFromPattern } from './viewer' - -export interface PatternSummary { - geometryLength: number - headsign: string - id: string - lastStop?: string -} - -export function extractMainHeadsigns( - patterns: Record, - shortName: string, - editHeadsign: (pattern: PatternSummary) => void -): PatternSummary[] { - const mapped = Object.entries(patterns).map( - ([id, pat]): PatternSummary => ({ - geometryLength: pat.patternGeometry?.length || 0, - headsign: extractHeadsignFromPattern(pat, shortName), - id, - lastStop: pat.stops?.[pat.stops?.length - 1]?.name - }) - ) - - // Address duplicate headsigns. - return mapped.reduce((prev: PatternSummary[], cur) => { - const amended = prev - const alreadyExistingIndex = prev.findIndex( - (h) => h.headsign === cur.headsign - ) - // If the headsign is a duplicate, and the last stop of the pattern is not the headsign, - // amend the headsign with the last stop name in parenthesis. - // e.g. "Headsign (Last Stop)" - if ( - alreadyExistingIndex >= 0 && - cur.lastStop && - cur.headsign !== cur.lastStop - ) { - editHeadsign(cur) - - // If there are only two total patterns, then we should rename - // both of them - if (amended.length === 1 && Object.entries(patterns).length === 2) { - editHeadsign(amended[0]) - amended.push(cur) - return amended - } - } - - // With all remaining duplicate headsigns with the same last stops, only keep the pattern with the - // longest geometry. - if ( - alreadyExistingIndex >= 0 && - amended[alreadyExistingIndex].lastStop === cur.lastStop - ) { - if (amended[alreadyExistingIndex].geometryLength < cur.geometryLength) { - amended[alreadyExistingIndex] = cur - } - } else { - amended.push(cur) - } - return amended - }, []) -} diff --git a/lib/util/state.js b/lib/util/state.js index 08f1d2baa..9ceb2b350 100644 --- a/lib/util/state.js +++ b/lib/util/state.js @@ -17,7 +17,6 @@ import { addSortingCosts, collectItinerariesWithoutDuplicates } from './itinerary' -import { isDefined } from './ui' // For lowercase context const LowerCase = styled.span` @@ -661,9 +660,7 @@ export function getShowUserSettings(state) { export function getUiUrlParams(state) { const activeSearch = getActiveSearch(state) const uiParams = { - ui_activeItinerary: isDefined(activeSearch?.activeItinerary) - ? activeSearch?.activeItinerary - : -1, + ui_activeItinerary: activeSearch ? activeSearch.activeItinerary : 0, ui_activeSearch: state.otp.activeSearchId } return uiParams diff --git a/lib/util/ui.ts b/lib/util/ui.ts index e68f28a0d..ed992e860 100644 --- a/lib/util/ui.ts +++ b/lib/util/ui.ts @@ -93,17 +93,13 @@ interface UrlParams { ui_itineraryView: ItineraryView } -export function isDefined( - subject: number | string | null | undefined -): boolean { - return subject !== null && subject !== undefined -} - export function isDefinedAndNotEqual( - subject: number | string | null | undefined, + subject: number | string, value: number | string ): boolean { - return isDefined(subject) && `${subject}` !== `${value}` + return ( + subject !== null && subject !== undefined && `${subject}` !== `${value}` + ) } /** diff --git a/lib/util/viewer.js b/lib/util/viewer.js index 9aabdacc2..d5abd67c4 100644 --- a/lib/util/viewer.js +++ b/lib/util/viewer.js @@ -3,9 +3,8 @@ import { getMostReadableTextColor } from '@opentripplanner/core-utils/lib/route' import tinycolor from 'tinycolor2' -import { DARK_TEXT_GREY } from '../components/util/colors' - import { checkForRouteModeOverride } from './config' +import { DARK_TEXT_GREY } from '../components/util/colors' import { getOperatorAndRoute } from './state' import { isBlank } from './ui' diff --git a/package.json b/package.json index 64f5f4646..8537d4e6b 100644 --- a/package.json +++ b/package.json @@ -42,28 +42,28 @@ "@bugsnag/js": "^7.17.0", "@bugsnag/plugin-react": "^7.17.0", "@floating-ui/react": "^0.19.2", - "@opentripplanner/base-map": "^3.1.0", - "@opentripplanner/building-blocks": "^1.0.3", - "@opentripplanner/core-utils": "^11.4.1", - "@opentripplanner/endpoints-overlay": "^2.1.1", - "@opentripplanner/from-to-location-picker": "^2.1.13", - "@opentripplanner/geocoder": "^3.0.1", + "@opentripplanner/base-map": "^3.2.0", + "@opentripplanner/building-blocks": "^1.1.0", + "@opentripplanner/core-utils": "^11.4.0", + "@opentripplanner/endpoints-overlay": "^2.0.12", + "@opentripplanner/from-to-location-picker": "^2.1.12", + "@opentripplanner/geocoder": "^2.2.2", "@opentripplanner/humanize-distance": "^1.2.0", "@opentripplanner/icons": "^2.0.10", - "@opentripplanner/itinerary-body": "^5.3.2", - "@opentripplanner/location-field": "^2.0.20", + "@opentripplanner/itinerary-body": "^5.3.0", + "@opentripplanner/location-field": "^2.0.17", "@opentripplanner/location-icon": "^1.4.1", - "@opentripplanner/map-popup": "^3.1.0", + "@opentripplanner/map-popup": "^3.1.1", "@opentripplanner/otp2-tile-overlay": "^1.0.12", "@opentripplanner/park-and-ride-overlay": "^2.0.8", - "@opentripplanner/printable-itinerary": "^2.0.21", + "@opentripplanner/printable-itinerary": "^2.0.20", "@opentripplanner/route-viewer-overlay": "^2.0.15", "@opentripplanner/stop-viewer-overlay": "^2.0.8", "@opentripplanner/stops-overlay": "^5.2.2", - "@opentripplanner/transit-vehicle-overlay": "^4.0.11", + "@opentripplanner/transit-vehicle-overlay": "^4.0.10", "@opentripplanner/transitive-overlay": "^3.0.18", - "@opentripplanner/trip-details": "^5.0.12", - "@opentripplanner/trip-form": "^3.6.2", + "@opentripplanner/trip-details": "^5.0.11", + "@opentripplanner/trip-form": "^3.6.0", "@opentripplanner/trip-viewer-overlay": "^2.0.8", "@opentripplanner/vehicle-rental-overlay": "^2.1.7", "@styled-icons/fa-regular": "^10.34.0", @@ -140,7 +140,7 @@ "@graphql-tools/schema": "^10.0.0", "@jackwilsdon/craco-use-babelrc": "^1.0.0", "@opentripplanner/scripts": "^1.2.0", - "@opentripplanner/types": "^6.5.0", + "@opentripplanner/types": "^6.5.1", "@percy/cli": "^1.20.3", "@percy/puppeteer": "^2.0.2", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.1", diff --git a/percy/har-mock-config.yml b/percy/har-mock-config.yml index 954c1a340..146bc3713 100644 --- a/percy/har-mock-config.yml +++ b/percy/har-mock-config.yml @@ -118,3 +118,6 @@ accessibilityScore: 1.0: color: "#a2e099" icon: thumbs-up + +defaultQueryParams: + maxWalkDistance: 1207 # 3/4 miles in meters diff --git a/percy/percy.test.js b/percy/percy.test.js index c4ac7142e..4c46528c4 100644 --- a/percy/percy.test.js +++ b/percy/percy.test.js @@ -105,7 +105,7 @@ async function executeTest(page, isMobile, isCallTaker) { // Triggers mock.har graphql query #1 and #2 (bike-only query, twice). // FIXME: Opening a url with non-default mode params triggers the plan query twice. await page.goto( - `http://localhost:${MOCK_SERVER_PORT}/#/?ui_activeSearch=fg33svlbf&ui_activeItinerary=-1&fromPlace=South%20Prado%20Northeast%2C%20Atlanta%2C%20GA%2C%20USA%3A%3A33.78946214120528%2C-84.37663414886111&toPlace=1%20Copenhill%20Avenue%20NE%2C%20Atlanta%2C%20GA%2C%20USA%3A%3A33.767060728439574%2C-84.35749390533111&date=2023-08-09&time=17%3A56&arriveBy=false&mode=BICYCLE&walkSpeed=1.34&numItineraries=3&modeButtons=walk_bike` + `http://localhost:${MOCK_SERVER_PORT}/#/?ui_activeSearch=fg33svlbf&ui_activeItinerary=-1&fromPlace=South%20Prado%20Northeast%2C%20Atlanta%2C%20GA%2C%20USA%3A%3A33.78946214120528%2C-84.37663414886111&toPlace=1%20Copenhill%20Avenue%20NE%2C%20Atlanta%2C%20GA%2C%20USA%3A%3A33.767060728439574%2C-84.35749390533111&date=2023-08-09&time=17%3A56&arriveBy=false&mode=BICYCLE&showIntermediateStops=true&walkSpeed=1.34&ignoreRealtimeUpdates=true&numItineraries=3&otherThanPreferredRoutesPenalty=900&modeButtons=walk_bike` ) // FIXME: Network idle condition seems never met after navigating to above link. // await page.waitForNavigation({ waitUntil: 'networkidle2' }) diff --git a/yarn.lock b/yarn.lock index 367a6e083..7adef06d5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2383,24 +2383,25 @@ dependencies: "@octokit/openapi-types" "^10.0.0" -"@opentripplanner/base-map@^3.0.16", "@opentripplanner/base-map@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.1.0.tgz#3181d4ec17029db8a40ca1342e20d1a0d449931f" - integrity sha512-feOSOWmiBFvIFWyG+OllCMxOcTmRKzxIoKKeoEgUFjNdVnrkZM6HH5r0m5IaQA9wO7T0N0K64hn/zdRQZBv0rQ== +"@opentripplanner/base-map@^3.0.16", "@opentripplanner/base-map@^3.1.0", "@opentripplanner/base-map@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/base-map/-/base-map-3.2.0.tgz#db4410319d9614077ec925d739165a998c4a2485" + integrity sha512-d/yTKEnXqrw9pXhSvCERT+wLFa077Xr4wEFu4pYB+WYoZFflNxuTuAXXjm268HS/d0kjNndkjSMkxaKk6AjsvA== dependencies: + "@opentripplanner/map-popup" "^3.1.0" mapbox-gl "npm:empty-npm-package@1.0.0" maplibre-gl "^2.1.9" react-map-gl "^7.0.15" -"@opentripplanner/building-blocks@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.0.3.tgz#74de32daba0d7fae7d10d5738db6d2f2824da3dd" - integrity sha512-065pZZTzR+qisgbvJd9swhitMMin1/ooMwuzqqRknsKYK+wOGge3Y3sbgQZATyjR/oH43uF0P2ZhGcbgqgM+YQ== +"@opentripplanner/building-blocks@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/building-blocks/-/building-blocks-1.1.0.tgz#ef9fe862ce0a3e92c9a6c2c2db749a9a02deebd5" + integrity sha512-nx7pU1zIZzJcSkCFYyZ7gt+jd0gXj7bjx8rXn1msgF5uLWmtN/70dsmYNEApeA7haC076KOO3B/Jh44YfXG95g== -"@opentripplanner/core-utils@^11.2.3", "@opentripplanner/core-utils@^11.3.1", "@opentripplanner/core-utils@^11.4.1": - version "11.4.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.1.tgz#9ccfed82f9a05078bd8e815dd4025af164e37acb" - integrity sha512-5FZT0ESVctyoO3V0W80QMZuzAc8hEYZxLAyrEARYXNeAHnBNxngGGMj7QMLK4JZgJDESnNietSRnBJd2MBWhOw== +"@opentripplanner/core-utils@^11.2.3", "@opentripplanner/core-utils@^11.3.1", "@opentripplanner/core-utils@^11.4.0": + version "11.4.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.0.tgz#f8c664d67d36108eab5e0477966c156ccfac6619" + integrity sha512-4weAgo3PwqrDfaQnLVhGxX67/lpjXQsW6OoIFluFFK6HZEN6mu6KW6OkTBGRbTSlVRE+Xz0FwmPuSrI3WlQDMA== dependencies: "@conveyal/lonlat" "^1.4.1" "@mapbox/polyline" "^1.1.0" @@ -2415,33 +2416,14 @@ lodash.isequal "^4.5.0" qs "^6.9.1" -"@opentripplanner/core-utils@^11.4.0": - version "11.4.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-11.4.2.tgz#cc6034fb80ccda44e50f7f0a1e80a7bad8387f84" - integrity sha512-EVYVN73Cgf9IC+uya49843MFJnVkmv0nHAjsQwmPGSx/w5fY49X4fSpDprL7Bn+MTzk58U2udDsn6OzKmV0JdA== - dependencies: - "@conveyal/lonlat" "^1.4.1" - "@mapbox/polyline" "^1.1.0" - "@opentripplanner/geocoder" "^3.0.0" - "@styled-icons/foundation" "^10.34.0" - "@turf/along" "^6.0.1" - chroma-js "^2.4.2" - date-fns "^2.28.0" - date-fns-tz "^1.2.2" - graphql "^16.6.0" - lodash.clonedeep "^4.5.0" - lodash.isequal "^4.5.0" - qs "^6.9.1" - -"@opentripplanner/endpoints-overlay@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.1.1.tgz#e7029d95bd13436aacbc6f854c243d1fcf7e8570" - integrity sha512-llBGk8eRa8JRJreMp73zWXeCzTzirBNd2N4UtK66vLL9s7YYPFm/yKGLTIKg1MRHrJ+DGpaFkEOi/ajos8YiLA== +"@opentripplanner/endpoints-overlay@^2.0.12": + version "2.0.12" + resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-2.0.12.tgz#d320c23777008550f350f614798c4a6300f4dba6" + integrity sha512-Vih8PGEJNEjNEdBzbd8eErQJ3e+VgI0J0BreVTsAejOb+7gEf+YBRVaq7NHVPBkt6dcsiQmZrw8IIhpqDkqo2Q== dependencies: - "@opentripplanner/base-map" "^3.1.0" - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/base-map" "^3.0.16" + "@opentripplanner/core-utils" "^11.2.3" "@opentripplanner/location-icon" "^1.4.1" - "@opentripplanner/map-popup" "^3.1.0" "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" @@ -2453,14 +2435,6 @@ "@opentripplanner/location-icon" "^1.4.1" flat "^5.0.2" -"@opentripplanner/from-to-location-picker@^2.1.13": - version "2.1.13" - resolved "https://registry.yarnpkg.com/@opentripplanner/from-to-location-picker/-/from-to-location-picker-2.1.13.tgz#d13acd582929175c676cd4303a6cdc6e1c289d99" - integrity sha512-6/7+wYQuuQhnGvxkDQcvoACdmuwUL1BlPqBIUFwyBpkdJ1VQGZiUSAAZTxXdY1Fv/p5mKR1vRsvZgtSPhcxgcg== - dependencies: - "@opentripplanner/location-icon" "^1.4.1" - flat "^5.0.2" - "@opentripplanner/geocoder@^2.2.2": version "2.2.2" resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-2.2.2.tgz#8ddc669287ccdfff1a5cce14d1fa8049421c6480" @@ -2472,28 +2446,17 @@ isomorphic-mapzen-search "^1.6.1" lodash.memoize "^4.1.2" -"@opentripplanner/geocoder@^3.0.0", "@opentripplanner/geocoder@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/geocoder/-/geocoder-3.0.1.tgz#834960bc52f515e1223346a8002fb847674d33bc" - integrity sha512-+LHTqY8pHmPE39IjVev5T5baa+BohEyvsLwVwFB2bYWzM+m/RgAJ188uBcDzXKdqk5y3dZR9ZODYVMtrvIiKzQ== - dependencies: - "@conveyal/geocoder-arcgis-geojson" "^0.0.3" - "@conveyal/lonlat" "^1.4.1" - "@leeoniya/ufuzzy" "^1.0.14" - isomorphic-mapzen-search "^1.6.1" - lodash.memoize "^4.1.2" - "@opentripplanner/humanize-distance@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@opentripplanner/humanize-distance/-/humanize-distance-1.2.0.tgz#71cf5d5d1b756adef15300edbba0995ccd4b35ee" integrity sha512-x0QRXMDhypFeazZ6r6vzrdU8vhiV56nZ/WX6zUbxpgp6T9Oclw0gwR2Zdw6DZiiFpSYVNeVNxVzZwsu6NRGjcA== -"@opentripplanner/icons@^2.0.10": +"@opentripplanner/icons@^2.0.10", "@opentripplanner/icons@^2.0.9": version "2.0.10" resolved "https://registry.yarnpkg.com/@opentripplanner/icons/-/icons-2.0.10.tgz#688e75190ebe772ad45bb852517e93bdde28df74" integrity sha512-9X6kV6jDsNnQT4foZU9X530zTN7kjYLtWBjWmeA5EVHth0qZx5T3iFjzqeG4wK+rwZKUMLGS5lAhLIQdaXKZMQ== dependencies: - "@opentripplanner/core-utils" "^11.2.3" + "@opentripplanner/core-utils" "^11.4.0" prop-types "^15.7.2" "@opentripplanner/itinerary-body@^5.2.6", "@opentripplanner/itinerary-body@^5.3.0": @@ -2514,32 +2477,14 @@ react-resize-detector "^4.2.1" string-similarity "^4.0.4" -"@opentripplanner/itinerary-body@^5.3.2": - version "5.3.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/itinerary-body/-/itinerary-body-5.3.2.tgz#282c5963de16b165084d46f6e55d5afc3d563c87" - integrity sha512-1uatzGTnmlY5YoJFH+u4pznb/6MKUqai1/Rb91Kh4GfNwl8eMPQ3RmwGRWejOJEGtXMIlq7LJ5O8I6Swwc+1RQ== - dependencies: - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/humanize-distance" "^1.2.0" - "@opentripplanner/icons" "^2.0.10" - "@opentripplanner/location-icon" "^1.4.1" - "@styled-icons/fa-solid" "^10.34.0" - "@styled-icons/foundation" "^10.34.0" - date-fns "^2.28.0" - date-fns-tz "^1.2.2" - flat "^5.0.2" - react-animate-height "^3.0.4" - react-resize-detector "^4.2.1" - string-similarity "^4.0.4" - -"@opentripplanner/location-field@^2.0.20": - version "2.0.20" - resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.20.tgz#ade02af802ba9295aa73cabc2351da758fcfeb4d" - integrity sha512-sYiemP4v2OmNWRKh2J0soLq9EO53piuJ8I5Du8X6wUfsTIk7yFH+xVLHN1IfA3XPRHy0gE8wEAnWzhxh4Qa+NQ== +"@opentripplanner/location-field@^2.0.17": + version "2.0.17" + resolved "https://registry.yarnpkg.com/@opentripplanner/location-field/-/location-field-2.0.17.tgz#36b2f6f86f3aba41c90462a85b5b729d4085a6be" + integrity sha512-HnijWJ5kN0/F52ommMTYlahehlwq4L0kPkcyAXEjM4H7uPhml+1IwYySrmNgMRa1rEiiDlJY5VkK4FXg/MfqLQ== dependencies: "@conveyal/geocoder-arcgis-geojson" "^0.0.3" - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/geocoder" "^3.0.0" + "@opentripplanner/core-utils" "^11.3.1" + "@opentripplanner/geocoder" "^2.2.2" "@opentripplanner/humanize-distance" "^1.2.0" "@opentripplanner/location-icon" "^1.4.1" "@styled-icons/fa-solid" "^10.34.0" @@ -2553,13 +2498,12 @@ "@styled-icons/fa-regular" "^10.34.0" "@styled-icons/fa-solid" "^10.34.0" -"@opentripplanner/map-popup@^3.0.2", "@opentripplanner/map-popup@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-3.1.0.tgz#51627e4d4c902d10bec6fffa2c3e3eed0994a42c" - integrity sha512-UzQ9OYOslNqDxvGWIPOZ4KyIJ7R0CO2riC56AJeHz5EI0JSv1Rlt1b6JTz0BtJ9cbHksB2QB43x8bJs6if7mfg== +"@opentripplanner/map-popup@^3.0.2", "@opentripplanner/map-popup@^3.1.0", "@opentripplanner/map-popup@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/map-popup/-/map-popup-3.1.1.tgz#54f081162d328cc4bb0e89562f9ea200e29e01a1" + integrity sha512-yWBIPuYGw7biaRNIpglQm5+opZ+D5QQgXHLhKnYaCR0eNijjl9cx34lGXdyKPXt26S6MiyJZXL81uc6w6CnQ3A== dependencies: - "@opentripplanner/base-map" "^3.1.0" - "@opentripplanner/core-utils" "^11.3.1" + "@opentripplanner/core-utils" "^11.4.0" "@opentripplanner/from-to-location-picker" "^2.1.12" flat "^5.0.2" @@ -2578,13 +2522,13 @@ "@opentripplanner/base-map" "^3.0.16" "@opentripplanner/from-to-location-picker" "^2.1.11" -"@opentripplanner/printable-itinerary@^2.0.21": - version "2.0.21" - resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.21.tgz#2b85ad6017491bbae682ece53d57e35819b79959" - integrity sha512-MWcHWmZRiqygjrwJt6I/LyHin88cjsmgqdxx2lh3oLGMgjrF657sxAbXfXAySqsW1rZ1MtHRuZ7IA2ph93GfMQ== +"@opentripplanner/printable-itinerary@^2.0.20": + version "2.0.20" + resolved "https://registry.yarnpkg.com/@opentripplanner/printable-itinerary/-/printable-itinerary-2.0.20.tgz#4554b66fc5021eede2ebe0713d4065a5673fa2cc" + integrity sha512-Pcl5LeZxbnB+VsboNEbyU7VGBM2+7imEFJLkvHvxTR8xoQ+OMZUQaml3VIBvOaYcdoa7Gt+/1AEOAR+YzpU2+g== dependencies: - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/itinerary-body" "^5.3.0" + "@opentripplanner/core-utils" "^11.2.3" + "@opentripplanner/itinerary-body" "^5.2.6" "@opentripplanner/route-viewer-overlay@^2.0.15": version "2.0.15" @@ -2615,24 +2559,24 @@ "@opentripplanner/base-map" "^3.0.16" "@opentripplanner/core-utils" "^11.2.3" -"@opentripplanner/stops-overlay@^5.2.2": - version "5.2.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-5.2.2.tgz#163dbc162c134113b5048905aa5cd2aabc47b807" - integrity sha512-1jYtHBvITWtE8pl4wXlfJ8X4SsoS3FWDPMVuUo05Rcefn8aGqr/AasaKa/wqsrvL1/vC9i+0ESSiu/BwSP8V2g== +"@opentripplanner/stops-overlay@^5.3.0": + version "5.3.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/stops-overlay/-/stops-overlay-5.3.0.tgz#1f35927a769a5fac80e40cfdaf85a7275b90cec5" + integrity sha512-bQBH5vf/F8n7yL6zhWpiU1XyJOkarcZVLovKYGseJpLs+qnPUd+3MMK9W0cQAMn7iuxAjcDHmSNmeK99kwb3jw== dependencies: - "@opentripplanner/base-map" "^3.0.16" - "@opentripplanner/from-to-location-picker" "^2.1.11" - "@opentripplanner/map-popup" "^3.0.2" + "@opentripplanner/base-map" "^3.1.0" + "@opentripplanner/from-to-location-picker" "^2.1.12" + "@opentripplanner/map-popup" "^3.1.0" flat "^5.0.2" -"@opentripplanner/transit-vehicle-overlay@^4.0.11": - version "4.0.11" - resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-4.0.11.tgz#3485514b6000612bba32c4610d9a5f692e01cf95" - integrity sha512-1xwPqAB/NbBKyv+5wJKaXz7mww3Sznbk2MISbjCecpbYaCrYwcXTVhoXDnrkgAELI1mz739mud6qKr/X77SEEg== +"@opentripplanner/transit-vehicle-overlay@^4.0.10": + version "4.0.10" + resolved "https://registry.yarnpkg.com/@opentripplanner/transit-vehicle-overlay/-/transit-vehicle-overlay-4.0.10.tgz#a63e86a2dc5108ddf47ba8d8c0c9f5017c65c86a" + integrity sha512-j8+KCyeCD7WLQgAIbtzX7ckwqLU1fwKjXCMJ5E5/t75YqNuWB8hAiUonerIanuA20TUinm4sPwSL3dr9OnGNlA== dependencies: - "@opentripplanner/base-map" "^3.1.0" - "@opentripplanner/core-utils" "^11.4.0" - "@opentripplanner/icons" "^2.0.10" + "@opentripplanner/base-map" "^3.0.16" + "@opentripplanner/core-utils" "^11.2.3" + "@opentripplanner/icons" "^2.0.9" flat "^5.0.2" "@opentripplanner/transitive-overlay@^3.0.18": @@ -2652,23 +2596,23 @@ "@turf/midpoint" "^6.5.0" lodash.isequal "^4.5.0" -"@opentripplanner/trip-details@^5.0.12": - version "5.0.12" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-5.0.12.tgz#138d009722569d1cb3b97b552a4cf0a855a828ba" - integrity sha512-o+1JNwUYNCb33eQDQLL1aCKf9j88T6yZtDnlrJIysxiYGMsqFtug8+LdYkBJ4SyeO/FqiHk8Q+VLOxTqZgcYUQ== +"@opentripplanner/trip-details@^5.0.11": + version "5.0.11" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-details/-/trip-details-5.0.11.tgz#a672874a042ffcf89bb52a792ea8810545646c9e" + integrity sha512-oRu4o2zJxkm494iWvdwDnSqQ1VxZPlUMDp+FoJpC8S+H43RpHiCB6g/eutA2Ytigy/koezO9dpDveI6a6rPtQA== dependencies: - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/core-utils" "^11.2.3" "@styled-icons/fa-solid" "^10.34.0" flat "^5.0.2" react-animate-height "^3.0.4" -"@opentripplanner/trip-form@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.6.2.tgz#910432d222aafa598e85cce134faffe956ac5c25" - integrity sha512-NWD2WtVjn5Iq/B4Verv+LnZIdt5vYcTMkMn+9Yyc5YBPt5hzK2HUdQbAh35ap30gj77KJFbNJ8lLJ3VPn9A8yg== +"@opentripplanner/trip-form@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@opentripplanner/trip-form/-/trip-form-3.6.0.tgz#e02996e3e21cee951a61522c1c01ea55f978c2b8" + integrity sha512-iV3bQkRhcJxvty7BZ+RUN/ylLmH+twUcveQgHj1HUCkPhEOz98m26ykDYXQhOXP68k/y9PtaLlt+Gzsa6p+8xQ== dependencies: "@floating-ui/react" "^0.19.2" - "@opentripplanner/core-utils" "^11.4.0" + "@opentripplanner/core-utils" "^11.2.3" "@styled-icons/bootstrap" "^10.34.0" "@styled-icons/boxicons-regular" "^10.38.0" "@styled-icons/fa-regular" "^10.37.0" @@ -2687,10 +2631,10 @@ "@opentripplanner/base-map" "^3.0.16" "@opentripplanner/core-utils" "^11.2.3" -"@opentripplanner/types@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.5.0.tgz#d8cca355bf30f0984283faa793113ad6c0dba38d" - integrity sha512-FllEyE+1WQ2GOSKXQOuzrk+OPcJEqr4+zacsHQLB9WVyfm5D/BPHR1/OjfuVngrwLTK5bKP8VlDRS1ba/R8rtg== +"@opentripplanner/types@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/types/-/types-6.5.1.tgz#c19c73e051e516e187e79202de276f6ed3bbc59e" + integrity sha512-5S4otkjzlNLqcbDeMXy3Xi6tcPQgQRoyQZX+uvEdPOTzIERr7wJoltyQCBwi49GX99F+jqyRbd08TJ6SnLapbA== "@opentripplanner/vehicle-rental-overlay@^2.1.7": version "2.1.7" @@ -4433,12 +4377,12 @@ anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" -aproba@^1.0.3, "aproba@^1.0.3 || ^2.0.0", aproba@^1.1.1: +aproba@^1.0.3, aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -aproba@^2.0.0: +"aproba@^1.0.3 || ^2.0.0", aproba@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== @@ -17204,14 +17148,14 @@ strip-ansi@6.0.0: dependencies: ansi-regex "^5.0.0" -strip-ansi@^3.0.0, strip-ansi@^3.0.1, "strip-ansi@^3.0.1 || ^4.0.0": +strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= dependencies: ansi-regex "^2.0.0" -strip-ansi@^4.0.0: +"strip-ansi@^3.0.1 || ^4.0.0", strip-ansi@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=