Compare commits
	
		
			146 Commits
		
	
	
		
			feature/re
			...
			feature/no
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|  | d1d94ef307 | ||
|  | ab0805689f | ||
|  | 4219e12164 | ||
|  | 6300259e70 | ||
|  | 4009b5eef2 | ||
|  | 33c2f00b73 | ||
|  | 7492028a21 | ||
|  | d6a2846f6b | ||
|  | 5a7e0bcd99 | ||
|  | 0d50326507 | ||
|  | 485102b591 | ||
|  | 65080e68f2 | ||
|  | 87129c6815 | ||
|  | 26d9037963 | ||
|  | 263cb750ce | ||
|  | b54f2f6f7e | ||
|  | 0e06b66368 | ||
|  | 0753bf7023 | ||
|  | 16f7d1f7ad | ||
|  | 0f0d69b22d | ||
|  | 29c84bcc1c | ||
|  | 9e7931926f | ||
|  | 60d8caaefa | ||
|  | f72ac1d97b | ||
|  | 3ca91f402e | ||
|  | a4e85ff2e6 | ||
|  | 57459d975b | ||
|  | 23402aef79 | ||
|  | e4ce671e67 | ||
|  | 789af1aa37 | ||
|  | b23b59eab3 | ||
|  | e38f550b94 | ||
|  | 9b70843e9c | ||
|  | f1e98344ca | ||
|  | 2debff6051 | ||
|  | b7c56f4b90 | ||
|  | 761543af90 | ||
|  | 36b199ef98 | ||
|  | 049b138ca5 | ||
|  | 6c3b186c9b | ||
|  | 5678ad5b35 | ||
|  | 6233c94a80 | ||
|  | 305d386fcc | ||
|  | f62fadffb7 | ||
|  | 8f23faacd7 | ||
|  | 91fb41dab0 | ||
|  | ac1c4f3902 | ||
|  | 9306a9cb25 | ||
|  | d6f727710f | ||
|  | 171df01a0d | ||
|  | d5fab2f49b | ||
|  | 94558b784a | ||
|  | 644f066c96 | ||
|  | fc091a2ae6 | ||
|  | 47bba10c04 | ||
|  | b98f61a802 | ||
|  | ccf764005c | ||
|  | a6a2a6dfbb | ||
|  | 2199e9cc57 | ||
|  | e11d8f534e | ||
|  | 831b632e7d | ||
|  | d47191761a | ||
|  | 5e3ef414f6 | ||
|  | 0e11f63bc3 | ||
|  | 84d36b88cc | ||
|  | 711f0bbe9f | ||
|  | dbae477bea | ||
|  | 0de3d73ced | ||
|  | 49098308db | ||
|  | bfec537f56 | ||
|  | bf78287563 | ||
|  | d511b80437 | ||
|  | e90ffd8926 | ||
|  | 4446019ab2 | ||
|  | 92b9a4a044 | ||
|  | f504497bdf | ||
|  | dfdd9a7f37 | ||
|  | b0b15f726c | ||
|  | e8906495c2 | ||
|  | d3c9bca4d3 | ||
|  | eb806e3f8a | ||
|  | dfe3c831bc | ||
|  | 946f669eb0 | ||
|  | b1ecbb1cfe | ||
|  | 480bcbfcd3 | ||
|  | 420a805f3c | ||
|  | 7e092671a2 | ||
|  | 1b16e09633 | ||
|  | 52b15288b9 | ||
|  | b2ee75205b | ||
|  | 5115656050 | ||
|  | f5491200eb | ||
|  | 26111e7ce8 | ||
|  | b2624d319b | ||
|  | 0618ff0180 | ||
|  | b4c306bce3 | ||
|  | cdea9a1e05 | ||
|  | 0ff05f911c | ||
|  | 84efa42e57 | ||
|  | 610f9c21ce | ||
|  | 9fee43d6ff | ||
|  | ce9dccc158 | ||
|  | 7f67fc6cc8 | ||
|  | ed76462436 | ||
|  | a643ab5c56 | ||
|  | ea1c505453 | ||
|  | 35907df3c4 | ||
|  | 180bc95a80 | ||
|  | 6f7f02e4fa | ||
|  | df7608acaf | ||
|  | 34413f522f | ||
|  | 07adaf2ef5 | ||
|  | 34f907ef9b | ||
|  | f815b31720 | ||
|  | 06b1933d1c | ||
|  | 1aac1e40df | ||
|  | 4ef5a13dc3 | ||
|  | 0f56a7ceea | ||
|  | 1622cd2ab8 | ||
|  | a3e8e3cbbe | ||
|  | a83bb27f60 | ||
|  | 320a94565d | ||
|  | fd7fd7f623 | ||
|  | cfbd126fe3 | ||
|  | bfd6decfcc | ||
|  | 81f394d6ca | ||
|  | 357490314a | ||
|  | bb115afe35 | ||
|  | c00073bb32 | ||
|  | 47d84777e2 | ||
|  | 65dd6dd0fd | ||
|  | 054dab518f | ||
|  | 3d09b93df5 | ||
|  | ffe18b8398 | ||
|  | 9381e0ee15 | ||
|  | 9eca679019 | ||
|  | dc4f1d7454 | ||
|  | 98b22db4db | ||
|  | 59df072e45 | ||
|  | 816d96d37b | ||
|  | e9fd753a8f | ||
|  | d627617ca0 | ||
|  | f6a88f09e4 | ||
|  | 12934f0963 | ||
|  | 3f8a753abb | ||
|  | 28c58ce83f | 
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -5,3 +5,4 @@ npm-debug.* | ||||
| *.p12 | ||||
| *.key | ||||
| *.mobileprovision | ||||
| dist/ | ||||
							
								
								
									
										377
									
								
								App.js
									
									
									
									
									
								
							
							
						
						
									
										377
									
								
								App.js
									
									
									
									
									
								
							| @@ -1,59 +1,154 @@ | ||||
| import React, { useEffect, useRef, useState } from "react"; | ||||
| import React, { useEffect, useState, useRef } from "react"; | ||||
| import { NavigationContainer } from "@react-navigation/native"; | ||||
| import { | ||||
|   createStackNavigator, | ||||
|   TransitionPresets, | ||||
| } from "@react-navigation/stack"; | ||||
| import { createStackNavigator } from "@react-navigation/stack"; | ||||
| import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; | ||||
| import { AntDesign, Ionicons } from "@expo/vector-icons"; | ||||
| import { Platform, UIManager } from "react-native"; | ||||
| import { Platform, UIManager, Text, Clipboard } from "react-native"; | ||||
| import { GestureHandlerRootView } from "react-native-gesture-handler"; | ||||
| import * as Device from "expo-device"; | ||||
| import * as Notifications from "expo-notifications"; | ||||
| import Constants from "expo-constants"; | ||||
| import { UpdateAsync } from "./UpdateAsync.js"; | ||||
| import { getStationList2 } from "./lib/getStationList2"; | ||||
| import { AS } from "./storageControl"; | ||||
| import Apps from "./Apps"; | ||||
| import TNDView from "./ndView"; | ||||
| import TrainBase from "./trainbaseview"; | ||||
| import HowTo from "./howto"; | ||||
| import Menu from "./menu"; | ||||
| import News from "./components/news.js"; | ||||
| import Setting from "./components/settings.js"; | ||||
| import TrainMenu from "./components/trainMenu.js"; | ||||
| import FavoriteList from "./components/FavoriteList.js"; | ||||
| import { LogBox } from "react-native"; | ||||
|  | ||||
| import useInterval from "./lib/useInterval"; | ||||
| import { HeaderConfig } from "./lib/HeaderConfig"; | ||||
| import { initIcon } from "./lib/initIcon"; | ||||
| import { | ||||
|   useFavoriteStation, | ||||
|   FavoriteStationProvider, | ||||
| } from "./stateBox/useFavoriteStation"; | ||||
| import { Top } from "./Top.js"; | ||||
| import { MenuPage } from "./MenuPage.js"; | ||||
| import { | ||||
|   useCurrentTrain, | ||||
|   CurrentTrainProvider, | ||||
| } from "./stateBox/useCurrentTrain.js"; | ||||
| import { useAreaInfo, AreaInfoProvider } from "./stateBox/useAreaInfo.js"; | ||||
| import { | ||||
|   useBusAndTrainData, | ||||
|   BusAndTrainDataProvider, | ||||
| } from "./stateBox/useBusAndTrainData.js"; | ||||
| import { AllTrainDiagramProvider } from "./stateBox/useAllTrainDiagram.js"; | ||||
| import { SheetProvider } from "react-native-actions-sheet"; | ||||
| import "./components/ActionSheetComponents/sheets.js"; | ||||
| import { TrainDelayDataProvider } from "./stateBox/useTrainDelayData.js"; | ||||
| import { SafeAreaProvider } from "react-native-safe-area-context"; | ||||
| LogBox.ignoreLogs([ | ||||
|   "ViewPropTypes will be removed", | ||||
|   "ColorPropType will be removed", | ||||
| ]); | ||||
| const Stack = createStackNavigator(); | ||||
| const Tab = createBottomTabNavigator(); | ||||
| if (Platform.OS === "android") { | ||||
|   if (UIManager.setLayoutAnimationEnabledExperimental) { | ||||
|     UIManager.setLayoutAnimationEnabledExperimental(true); | ||||
|   } | ||||
| } | ||||
| Notifications.setNotificationHandler({ | ||||
|   handleNotification: async () => ({ | ||||
|     shouldShowAlert: true, | ||||
|     shouldPlaySound: false, | ||||
|     shouldSetBadge: false, | ||||
|   }), | ||||
| }); | ||||
| async function registerForPushNotificationsAsync() { | ||||
|   let token; | ||||
|  | ||||
|   if (Platform.OS === "android") { | ||||
|     Notifications.setNotificationChannelAsync("default", { | ||||
|       name: "default", | ||||
|       importance: Notifications.AndroidImportance.MAX, | ||||
|       vibrationPattern: [0, 250, 250, 250], | ||||
|       lightColor: "#FF231F7C", | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   if (Device.isDevice) { | ||||
|     const { status: existingStatus } = | ||||
|       await Notifications.getPermissionsAsync(); | ||||
|     let finalStatus = existingStatus; | ||||
|     if (existingStatus !== "granted") { | ||||
|       const { status } = await Notifications.requestPermissionsAsync(); | ||||
|       finalStatus = status; | ||||
|     } | ||||
|     if (finalStatus !== "granted") { | ||||
|       alert("Failed to get push token for push notification!"); | ||||
|       return; | ||||
|     } | ||||
|     token = await Notifications.getExpoPushTokenAsync({ | ||||
|       projectId: Constants.expoConfig.extra.eas.projectId, | ||||
|     }); | ||||
|     console.log(token); | ||||
|   } else { | ||||
|     alert("Must use physical device for Push Notifications"); | ||||
|   } | ||||
|  | ||||
|   return token.data; | ||||
| } | ||||
| export default function App() { | ||||
|   useEffect(() => { | ||||
|     UpdateAsync(); | ||||
|   }, []); | ||||
|   const [favoriteStation, setFavoriteStation] = useState([]); | ||||
|   const [expoPushToken, setExpoPushToken] = useState(""); | ||||
|   const [notification, setNotification] = useState(false); | ||||
|   const notificationListener = useRef(); | ||||
|   const responseListener = useRef(); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     AS.getItem("favoriteStation") | ||||
|       .then((d) => { | ||||
|         const returnData = JSON.parse(d); | ||||
|         setFavoriteStation(returnData); | ||||
|       }) | ||||
|       .catch((d) => console.log(d)); | ||||
|     registerForPushNotificationsAsync().then((token) => | ||||
|       setExpoPushToken(token) | ||||
|     ); | ||||
|  | ||||
|     notificationListener.current = | ||||
|       Notifications.addNotificationReceivedListener((notification) => { | ||||
|         setNotification(notification); | ||||
|       }); | ||||
|  | ||||
|     responseListener.current = | ||||
|       Notifications.addNotificationResponseReceivedListener((response) => { | ||||
|         console.log(response); | ||||
|       }); | ||||
|  | ||||
|     return () => { | ||||
|       Notifications.removeNotificationSubscription( | ||||
|         notificationListener.current | ||||
|       ); | ||||
|       Notifications.removeNotificationSubscription(responseListener.current); | ||||
|     }; | ||||
|   }, []); | ||||
|   const [busAndTrainData, setBusAndTrainData] = useState([]); | ||||
|   useEffect(() => UpdateAsync(), []); | ||||
|  | ||||
|   return ( | ||||
|     <SafeAreaProvider> | ||||
|       <GestureHandlerRootView style={{ flex: 1 }}> | ||||
|         <FavoriteStationProvider> | ||||
|           <TrainDelayDataProvider> | ||||
|             <CurrentTrainProvider> | ||||
|               <AreaInfoProvider> | ||||
|                 <AllTrainDiagramProvider> | ||||
|                   <BusAndTrainDataProvider> | ||||
|                     <SheetProvider> | ||||
|                       <Text onPress={() => Clipboard.setString(expoPushToken)}> | ||||
|                         {expoPushToken} | ||||
|                       </Text> | ||||
|                       <AppContainer /> | ||||
|                     </SheetProvider> | ||||
|                   </BusAndTrainDataProvider> | ||||
|                 </AllTrainDiagramProvider> | ||||
|               </AreaInfoProvider> | ||||
|             </CurrentTrainProvider> | ||||
|           </TrainDelayDataProvider> | ||||
|         </FavoriteStationProvider> | ||||
|       </GestureHandlerRootView> | ||||
|     </SafeAreaProvider> | ||||
|   ); | ||||
| } | ||||
| export function AppContainer() { | ||||
|   const { setBusAndTrainData, setTrainPairData } = useBusAndTrainData(); | ||||
|   useEffect(() => { | ||||
|     AS.getItem("busAndTrain") | ||||
|       .then((d) => { | ||||
|         const returnData = JSON.parse(d); | ||||
|         setBusAndTrainData(returnData); | ||||
|       }) | ||||
|       .catch((d) => { | ||||
|       .catch(() => { | ||||
|         fetch( | ||||
|           "https://script.google.com/macros/s/AKfycbw0UW6ZeCDgUYFRP0zxpc_Oqfy-91dBdbWv-cM8n3narKp14IyCd2wy5HW7taXcW7E/exec" | ||||
|         ) | ||||
| @@ -64,10 +159,39 @@ export default function App() { | ||||
|           }); | ||||
|       }); | ||||
|   }, []); | ||||
|   useEffect(() => { | ||||
|     AS.getItem("trainPairData") | ||||
|       .then((d) => { | ||||
|         const returnData = JSON.parse(d); | ||||
|         setTrainPairData(returnData); | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         fetch( | ||||
|           "https://script.google.com/macros/s/AKfycbyoBH7_rBwzPmhU1ghRBNTAVuvGltIrZtWxE07gDdhGGlDL9Ip2qk3pFM5u2xtRBl8/exec" | ||||
|         ) | ||||
|           .then((d) => d.json()) | ||||
|           .then((d) => { | ||||
|             setTrainPairData(d); | ||||
|             AS.setItem("trainPairData", JSON.stringify(d)); | ||||
|           }); | ||||
|       }); | ||||
|   }, []); | ||||
|  | ||||
|   const { areaInfo, setAreaInfo } = useAreaInfo(); | ||||
|   const getAreaData = () => | ||||
|     fetch( | ||||
|       "https://script.google.com/macros/s/AKfycbz80LcaEUrhnlEsLkJy0LG2IRO3DBVQhfNmN1d_0f_HvtsujNQpxM90SrV9yKWH_JG1Ww/exec" | ||||
|     ) | ||||
|       .then((d) => d.text()) | ||||
|       .then((d) => setAreaInfo(d)); | ||||
|   useEffect(getAreaData, []); | ||||
|   useInterval(getAreaData, 60000); //60秒毎に全在線列車取得 | ||||
|  | ||||
|   return ( | ||||
|     <NavigationContainer name="Root" style={{ flex: 1 }}> | ||||
|       <Tab.Navigator detachInactiveScreens={false}> | ||||
|       <Tab.Navigator | ||||
|         tabBarOptions={{ keyboardHidesTabBar: Platform.OS === "android" }} | ||||
|       > | ||||
|         <Tab.Screen | ||||
|           name="login" | ||||
|           options={{ | ||||
| @@ -77,14 +201,7 @@ export default function App() { | ||||
|             tabBarIcon: initIcon("barchart", "AntDesign"), | ||||
|           }} | ||||
|         > | ||||
|           {(props) => ( | ||||
|             <Top | ||||
|               {...props} | ||||
|               favoriteStation={favoriteStation} | ||||
|               setFavoriteStation={setFavoriteStation} | ||||
|               busAndTrainData={busAndTrainData} | ||||
|             /> | ||||
|           )} | ||||
|           {(props) => <Top {...props} />} | ||||
|         </Tab.Screen> | ||||
|         <Tab.Screen | ||||
|           name="menuPage" | ||||
| @@ -95,14 +212,7 @@ export default function App() { | ||||
|             tabBarIcon: initIcon("ios-radio", "Ionicons"), | ||||
|           }} | ||||
|         > | ||||
|           {(props) => ( | ||||
|             <MenuPage | ||||
|               {...props} | ||||
|               favoriteStation={favoriteStation} | ||||
|               setFavoriteStation={setFavoriteStation} | ||||
|               busAndTrainData={busAndTrainData} | ||||
|             /> | ||||
|           )} | ||||
|           {(props) => <MenuPage {...props} />} | ||||
|         </Tab.Screen> | ||||
|         <Tab.Screen | ||||
|           name="home" | ||||
| @@ -111,6 +221,7 @@ export default function App() { | ||||
|             headerTransparent: true, | ||||
|             gestureEnabled: true, | ||||
|             tabBarIcon: initIcon("md-train", "Ionicons"), | ||||
|             tabBarBadge: areaInfo ? "!" : undefined, | ||||
|           }} | ||||
|         > | ||||
|           {(props) => <TNDView {...props} />} | ||||
| @@ -119,175 +230,3 @@ export default function App() { | ||||
|     </NavigationContainer> | ||||
|   ); | ||||
| } | ||||
|  | ||||
| const initIcon = (name, type) => { | ||||
|   switch (type) { | ||||
|     case "Ionicons": | ||||
|       return ({ focused, color, size }) => ( | ||||
|         <Ionicons name={name} size={32} color={focused ? "#0099CC" : "black"} /> | ||||
|       ); | ||||
|     case "AntDesign": | ||||
|       return ({ focused, color, size }) => ( | ||||
|         <AntDesign | ||||
|           name={name} | ||||
|           size={32} | ||||
|           color={focused ? "#0099CC" : "black"} | ||||
|         /> | ||||
|       ); | ||||
|   } | ||||
| }; | ||||
|  | ||||
| const Top = ({ | ||||
|   navigation, | ||||
|   favoriteStation, | ||||
|   setFavoriteStation, | ||||
|   busAndTrainData, | ||||
| }) => { | ||||
|   const webview = useRef(); | ||||
|  | ||||
|   //地図用 | ||||
|   const [mapsStationData, setMapsStationData] = useState(undefined); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     getStationList2().then(setMapsStationData); | ||||
|   }, []); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     const unsubscribe = navigation.addListener("tabLongPress", (e) => { | ||||
|       navigation.navigate("favoriteList"); | ||||
|     }); | ||||
|  | ||||
|     return unsubscribe; | ||||
|   }, [navigation]); | ||||
|  | ||||
|   return ( | ||||
|     <Stack.Navigator> | ||||
|       <Stack.Screen | ||||
|         name="Apps" | ||||
|         options={{ | ||||
|           headerShown: false, | ||||
|           gestureEnabled: true, | ||||
|           headerTransparent: true, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => ( | ||||
|           <Apps | ||||
|             {...props} | ||||
|             webview={webview} | ||||
|             favoriteStation={favoriteStation} | ||||
|             setFavoriteStation={setFavoriteStation} | ||||
|             busAndTrainData={busAndTrainData} | ||||
|           /> | ||||
|         )} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="trainbase" | ||||
|         options={{ | ||||
|           title: "トレインビジョン", | ||||
|           gestureEnabled: true, | ||||
|           ...TransitionPresets.SlideFromRightIOS, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <TrainBase {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="howto" | ||||
|         options={{ | ||||
|           title: "使い方", | ||||
|           ...optionData, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <HowTo {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen name="news" options={optionData}> | ||||
|         {(props) => <News {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen name="trainMenu" options={optionData}> | ||||
|         {(props) => ( | ||||
|           <TrainMenu | ||||
|             {...props} | ||||
|             webview={webview} | ||||
|             stationData={mapsStationData} | ||||
|           /> | ||||
|         )} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="favoriteList" | ||||
|         options={{ ...optionData, gestureEnabled: false }} | ||||
|       > | ||||
|         {(props) => ( | ||||
|           <FavoriteList | ||||
|             {...props} | ||||
|             webview={webview} | ||||
|             stationData={mapsStationData} | ||||
|             favoriteStation={favoriteStation} | ||||
|             setFavoriteStation={setFavoriteStation} | ||||
|           /> | ||||
|         )} | ||||
|       </Stack.Screen> | ||||
|     </Stack.Navigator> | ||||
|   ); | ||||
| }; | ||||
| function MenuPage({ | ||||
|   navigation, | ||||
|   favoriteStation, | ||||
|   setFavoriteStation, | ||||
|   busAndTrainData, | ||||
| }) { | ||||
|   useEffect(() => { | ||||
|     const unsubscribe = navigation.addListener("tabPress", (e) => { | ||||
|       AS.getItem("favoriteStation") | ||||
|         .then((d) => { | ||||
|           const returnData = JSON.parse(d); | ||||
|           setFavoriteStation(returnData); | ||||
|         }) | ||||
|         .catch((d) => console.log(d)); | ||||
|     }); | ||||
|  | ||||
|     return unsubscribe; | ||||
|   }, [navigation]); | ||||
|   return ( | ||||
|     <Stack.Navigator> | ||||
|       <Stack.Screen | ||||
|         name="menu" | ||||
|         options={{ | ||||
|           headerShown: false, | ||||
|           gestureEnabled: true, | ||||
|           headerTransparent: true, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => ( | ||||
|           <Menu | ||||
|             {...props} | ||||
|             favoriteStation={favoriteStation} | ||||
|             setFavoriteStation={setFavoriteStation} | ||||
|             busAndTrainData={busAndTrainData} | ||||
|           /> | ||||
|         )} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen name="setting" options={optionData}> | ||||
|         {(props) => <Setting {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="trainbase" | ||||
|         options={{ | ||||
|           ...TransitionPresets.ModalPresentationIOS, | ||||
|           cardOverlayEnabled: true, | ||||
|           headerShown: false, | ||||
|           gestureEnabled: true, | ||||
|           headerTransparent: true, | ||||
|           gestureResponseDistance: { vertical: 300 }, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <TrainBase {...props} />} | ||||
|       </Stack.Screen> | ||||
|     </Stack.Navigator> | ||||
|   ); | ||||
| } | ||||
| const optionData = { | ||||
|   gestureEnabled: true, | ||||
|   ...TransitionPresets.ModalPresentationIOS, | ||||
|   cardOverlayEnabled: true, | ||||
|   headerTransparent: true, | ||||
|   headerShown: false, | ||||
| }; | ||||
|   | ||||
							
								
								
									
										222
									
								
								Apps.js
									
									
									
									
									
								
							
							
						
						
									
										222
									
								
								Apps.js
									
									
									
									
									
								
							| @@ -1,44 +1,43 @@ | ||||
| import React, { useEffect, useRef, useState } from "react"; | ||||
| import { | ||||
|   View, | ||||
|   Platform, | ||||
|   ToastAndroid, | ||||
|   Text, | ||||
|   TouchableOpacity, | ||||
| } from "react-native"; | ||||
| import { View, Platform, Text, TouchableOpacity } from "react-native"; | ||||
| import { WebView } from "react-native-webview"; | ||||
| import Constants from "expo-constants"; | ||||
| import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; | ||||
| import { Ionicons } from "@expo/vector-icons"; | ||||
| import { AS } from "./storageControl"; | ||||
| import { news } from "./config/newsUpdate"; | ||||
| import { getStationList, lineList } from "./lib/getStationList"; | ||||
| import { StationDeteilView } from "./components/ActionSheetComponents/StationDeteilView"; | ||||
| import { injectJavascriptData } from "./lib/webViewInjectjavascript"; | ||||
| import { getStationList2 } from "./lib/getStationList2"; | ||||
| import { checkDuplicateTrainData } from "./lib/checkDuplicateTrainData"; | ||||
| import { useFavoriteStation } from "./stateBox/useFavoriteStation"; | ||||
| import { useCurrentTrain } from "./stateBox/useCurrentTrain"; | ||||
| import { SheetManager } from "react-native-actions-sheet"; | ||||
| /*  | ||||
| import StatusbarDetect from './StatusbarDetect'; | ||||
| var Status = StatusbarDetect(); */ | ||||
|  | ||||
| export default function Apps({ | ||||
|   navigation, | ||||
|   webview, | ||||
|   favoriteStation, | ||||
|   setFavoriteStation, | ||||
|   busAndTrainData, | ||||
| }) { | ||||
| export default function Apps({ navigation, webview, stationData }) { | ||||
|   const { currentTrain } = useCurrentTrain(); | ||||
|   const { navigate } = navigation; | ||||
|   var urlcache = ""; | ||||
|   const { favoriteStation } = useFavoriteStation(); | ||||
|  | ||||
|   //画面表示関連 | ||||
|   const [iconSetting, setIconSetting] = useState(undefined); | ||||
|   const [mapSwitch, setMapSwitch] = useState(undefined); | ||||
|   const [stationMenu, setStationMenu] = useState(undefined); | ||||
|   const [LoadError, setLoadError] = useState(false); | ||||
|  | ||||
|   //列車情報表示関連 | ||||
|   const [trainInfo, setTrainInfo] = useState({ | ||||
|     trainNum: undefined, | ||||
|     limited: undefined, | ||||
|     trainData: undefined, | ||||
|   }); | ||||
|  | ||||
|   //駅情報画面用 | ||||
|   const StationBoardAcSR = useRef(null); | ||||
|   const [stationBoardData, setStationBoardData] = useState(undefined); | ||||
|   const [originalStationList, setOriginalStationList] = useState(); | ||||
|   const [selectedStation, setSelectedStation] = useState(undefined); | ||||
|   const [trainMenu, setTrainMenu] = useState("true"); | ||||
|   let once = false; | ||||
|   useEffect(() => { | ||||
|     getStationList().then(setOriginalStationList); | ||||
|   }, []); | ||||
| @@ -47,7 +46,8 @@ export default function Apps({ | ||||
|   const injectJavascript = injectJavascriptData( | ||||
|     mapSwitch, | ||||
|     iconSetting, | ||||
|     stationMenu | ||||
|     stationMenu, | ||||
|     trainMenu | ||||
|   ); | ||||
|  | ||||
|   useEffect(() => { | ||||
| @@ -56,7 +56,7 @@ export default function Apps({ | ||||
|       .then((d) => { | ||||
|         if (d != news) navigate("news"); | ||||
|       }) | ||||
|       .catch((e) => navigate("news")); | ||||
|       .catch(() => navigate("news")); | ||||
|   }, []); | ||||
|  | ||||
|   useEffect(() => { | ||||
| @@ -69,7 +69,7 @@ export default function Apps({ | ||||
|           AS.setItem("iconSwitch", "true").then(Updates.reloadAsync); | ||||
|         } | ||||
|       }) | ||||
|       .catch((d) => AS.setItem("iconSwitch", "true").then(Updates.reloadAsync)); | ||||
|       .catch(() => AS.setItem("iconSwitch", "true").then(Updates.reloadAsync)); | ||||
|   }, []); | ||||
|  | ||||
|   useEffect(() => { | ||||
| @@ -82,7 +82,7 @@ export default function Apps({ | ||||
|           AS.setItem("mapSwitch", "false").then(Updates.reloadAsync); | ||||
|         } | ||||
|       }) | ||||
|       .catch((d) => AS.setItem("mapSwitch", "false").then(Updates.reloadAsync)); | ||||
|       .catch(() => AS.setItem("mapSwitch", "false").then(Updates.reloadAsync)); | ||||
|   }, []); | ||||
|  | ||||
|   useEffect(() => { | ||||
| @@ -95,13 +95,25 @@ export default function Apps({ | ||||
|           AS.setItem("stationSwitch", "true").then(Updates.reloadAsync); | ||||
|         } | ||||
|       }) | ||||
|       .catch((d) => | ||||
|       .catch(() => | ||||
|         AS.setItem("stationSwitch", "true").then(Updates.reloadAsync) | ||||
|       ); | ||||
|   }, []); | ||||
|   useEffect(() => { | ||||
|     //列車メニュースイッチ | ||||
|     AS.getItem("trainSwitch") | ||||
|       .then((d) => { | ||||
|         if (d) { | ||||
|           setTrainMenu(d); | ||||
|         } else { | ||||
|           AS.setItem("trainSwitch", "true").then(Updates.reloadAsync); | ||||
|         } | ||||
|       }) | ||||
|       .catch(() => AS.setItem("trainSwitch", "true").then(Updates.reloadAsync)); | ||||
|   }, []); | ||||
|  | ||||
|   const onMessage = (event) => { | ||||
|     if (!event.nativeEvent.data.includes("PopUpMenu")) { | ||||
|     if (event.nativeEvent.data.includes("train.html")) { | ||||
|       navigate("trainbase", { info: event.nativeEvent.data, from: "Train" }); | ||||
|       return; | ||||
|     } | ||||
| @@ -109,18 +121,21 @@ export default function Apps({ | ||||
|       alert("駅名標データを取得中..."); | ||||
|       return; | ||||
|     } | ||||
|     const selectedStationPDFAddress = event.nativeEvent.data | ||||
|       .split(",")[3] | ||||
|       .replace("'", "") | ||||
|       .replace("'", ""); | ||||
|  | ||||
|     const dataSet = JSON.parse(event.nativeEvent.data); | ||||
|     switch (dataSet.type) { | ||||
|       case "LoadError": { | ||||
|         setLoadError(true); | ||||
|         return; | ||||
|       } | ||||
|       case "PopUpMenu": | ||||
|         { | ||||
|           const selectedStationPDFAddress = dataSet.pdf; | ||||
|           const findStationEachLine = (selectLine) => { | ||||
|             let NearStation = selectLine.filter( | ||||
|               (d) => d.StationTimeTable == selectedStationPDFAddress | ||||
|             ); | ||||
|             return NearStation; | ||||
|           }; | ||||
|  | ||||
|           let returnDataBase = lineList | ||||
|             .map((d) => findStationEachLine(originalStationList[d])) | ||||
|             .filter((d) => d.length > 0) | ||||
| @@ -128,15 +143,55 @@ export default function Apps({ | ||||
|               pre.push(...current); | ||||
|               return pre; | ||||
|             }, []); | ||||
|     if (returnDataBase.length) { | ||||
|       setStationBoardData(returnDataBase); | ||||
|       StationBoardAcSR.current?.setModalVisible(); | ||||
|     } else { | ||||
|       setStationBoardData(undefined); | ||||
|       StationBoardAcSR.current?.hide(); | ||||
|     } | ||||
|  | ||||
|           if (returnDataBase.length) { | ||||
|             const payload = { | ||||
|               currentStation: returnDataBase, | ||||
|               originalStationList: originalStationList, | ||||
|               navigate: navigate, | ||||
|               goTo: "Apps", | ||||
|               useShow: () => | ||||
|                 SheetManager.show("StationDetailView", { | ||||
|                   payload, | ||||
|                 }), | ||||
|               onExit: () => { | ||||
|                 SheetManager.hide("StationDetailView"); | ||||
|               }, | ||||
|             }; | ||||
|             SheetManager.show("StationDetailView", { | ||||
|               payload, | ||||
|             }); | ||||
|           } | ||||
|         } | ||||
|         return; | ||||
|       case "ShowTrainTimeInfo": { | ||||
|         const { trainNum, limited } = dataSet; | ||||
|         //alert(trainNum, limited); | ||||
|         setTrainInfo({ | ||||
|           trainNum, | ||||
|           limited, | ||||
|           trainData: checkDuplicateTrainData( | ||||
|             currentTrain.filter((a) => a.num == trainNum) | ||||
|           ), | ||||
|         }); //遅延情報は未実装 | ||||
|         const payload = { | ||||
|           data: { | ||||
|             trainNum, | ||||
|             limited, | ||||
|           }, | ||||
|           navigate, | ||||
|           originalStationList, | ||||
|           openStationACFromEachTrainInfo, | ||||
|         }; | ||||
|         SheetManager.show("EachTrainInfo", { | ||||
|           payload, | ||||
|         }); | ||||
|         return; | ||||
|       } | ||||
|       default: { | ||||
|         return; | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const onNavigationStateChange = (event) => { | ||||
| @@ -145,7 +200,7 @@ export default function Apps({ | ||||
|       urlcache = event.url; | ||||
|  | ||||
|       if (event.url.includes("https://train.jr-shikoku.co.jp/usage.htm")) { | ||||
|         if (Platform.OS === "android") navigate("howto"); | ||||
|         if (Platform.OS === "android") navigate("howto", { info: event.url }); | ||||
|         webview?.current.goBack(); | ||||
|         //Actions.howto(); | ||||
|       } else if ( | ||||
| @@ -158,7 +213,59 @@ export default function Apps({ | ||||
|       } | ||||
|     } | ||||
|   }; | ||||
|   function sleep(waitSec, callbackFunc) { | ||||
|     // 経過時間(秒) | ||||
|     var spanedSec = 0; | ||||
|  | ||||
|     // 1秒間隔で無名関数を実行 | ||||
|     var id = setInterval(function () { | ||||
|       spanedSec++; | ||||
|  | ||||
|       // 経過時間 >= 待機時間の場合、待機終了。 | ||||
|       if (spanedSec >= waitSec) { | ||||
|         // タイマー停止 | ||||
|         clearInterval(id); | ||||
|  | ||||
|         // 完了時、コールバック関数を実行 | ||||
|         if (callbackFunc) callbackFunc(); | ||||
|       } | ||||
|     }, 1); | ||||
|   } | ||||
|  | ||||
|   const openStationACFromEachTrainInfo = async (stationName) => { | ||||
|     await SheetManager.hide("EachTrainInfo"); | ||||
|     const findStationEachLine = (selectLine) => { | ||||
|       let NearStation = selectLine.filter((d) => d.Station_JP == stationName); | ||||
|       return NearStation; | ||||
|     }; | ||||
|     let returnDataBase = lineList | ||||
|       .map((d) => findStationEachLine(originalStationList[d])) | ||||
|       .filter((d) => d.length > 0) | ||||
|       .reduce((pre, current) => { | ||||
|         pre.push(...current); | ||||
|         return pre; | ||||
|       }, []); | ||||
|     if (returnDataBase.length) { | ||||
|       const payload = { | ||||
|         currentStation: returnDataBase, | ||||
|         originalStationList: originalStationList, | ||||
|         navigate: navigate, | ||||
|         goTo: "Apps", | ||||
|         useShow: () => | ||||
|           SheetManager.show("StationDetailView", { | ||||
|             payload, | ||||
|           }), | ||||
|         onExit: () => { | ||||
|           SheetManager.hide("StationDetailView"); | ||||
|         }, | ||||
|       }; | ||||
|       SheetManager.show("StationDetailView", { | ||||
|         payload, | ||||
|       }); | ||||
|     } else { | ||||
|       SheetManager.hide("StationDetailView"); | ||||
|     } | ||||
|   }; | ||||
|   return ( | ||||
|     <View | ||||
|       style={{ | ||||
| @@ -182,7 +289,26 @@ export default function Apps({ | ||||
|         onNavigationStateChange={onNavigationStateChange} | ||||
|         onMessage={onMessage} | ||||
|         injectedJavaScript={injectJavascript} | ||||
|         onTouchMove={() => StationBoardAcSR.current?.hide()} | ||||
|         onLoadEnd={() => { | ||||
|           if (once) return () => {}; | ||||
|           if (!stationData) return () => {}; | ||||
|           if (favoriteStation.length > 0) { | ||||
|             const getStationLine = (now) => { | ||||
|               const returnData = Object.keys(stationData).filter((d) => { | ||||
|                 const cache = stationData[d].findIndex( | ||||
|                   (data) => data.Station_JP == now.Station_JP | ||||
|                 ); | ||||
|                 return cache != -1; | ||||
|               }); | ||||
|               return returnData[0]; | ||||
|             }; | ||||
|             const lineName = getStationLine(favoriteStation[0][0]); | ||||
|             webview.current?.injectJavaScript( | ||||
|               `MoveDisplayStation('${lineName}_${favoriteStation[0][0].MyStation}_${favoriteStation[0][0].Station_JP}')` | ||||
|             ); | ||||
|             once = true; | ||||
|           } | ||||
|         }} | ||||
|       /> | ||||
|       <MapsButton | ||||
|         onPress={() => navigate("trainMenu", { webview })} | ||||
| @@ -192,15 +318,7 @@ export default function Apps({ | ||||
|       <ReloadButton | ||||
|         onPress={() => webview.current.reload()} | ||||
|         top={Platform.OS == "ios" ? Constants.statusBarHeight : 0} | ||||
|       /> | ||||
|  | ||||
|       <StationDeteilView | ||||
|         StationBoardAcSR={StationBoardAcSR} | ||||
|         currentStation={stationBoardData} | ||||
|         originalStationList={originalStationList} | ||||
|         favoriteStation={favoriteStation} | ||||
|         setFavoriteStation={setFavoriteStation} | ||||
|         busAndTrainData={busAndTrainData} | ||||
|         LoadError={LoadError} | ||||
|       /> | ||||
|     </View> | ||||
|   ); | ||||
| @@ -242,7 +360,7 @@ const MapsButton = ({ onPress, top, mapSwitch }) => { | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const ReloadButton = ({ onPress, top, mapSwitch }) => { | ||||
| const ReloadButton = ({ onPress, top, mapSwitch, LoadError = false }) => { | ||||
|   const styles = { | ||||
|     touch: { | ||||
|       position: "absolute", | ||||
| @@ -250,7 +368,7 @@ const ReloadButton = ({ onPress, top, mapSwitch }) => { | ||||
|       right: 10, | ||||
|       width: 50, | ||||
|       height: 50, | ||||
|       backgroundColor: "#0099CC", | ||||
|       backgroundColor: LoadError ? "red" : "#0099CC", | ||||
|       borderColor: "white", | ||||
|       borderStyle: "solid", | ||||
|       borderWidth: 1, | ||||
|   | ||||
							
								
								
									
										97
									
								
								MenuPage.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								MenuPage.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,97 @@ | ||||
| import React, { useEffect } from "react"; | ||||
| import { | ||||
|   createStackNavigator, | ||||
|   TransitionPresets, | ||||
| } from "@react-navigation/stack"; | ||||
| import { AS } from "./storageControl"; | ||||
| import TrainBase from "./trainbaseview"; | ||||
| import HowTo from "./howto"; | ||||
| import Menu from "./menu"; | ||||
| import Setting from "./components/settings.js"; | ||||
| import { useFavoriteStation } from "./stateBox/useFavoriteStation"; | ||||
| import { optionData } from "./lib/stackOption.js"; | ||||
| import CurrentTrainListView from "./components/CurrentTrainListView.js"; | ||||
| import AllTrainDiagramView from "./components/AllTrainDiagramView.js"; | ||||
| import { useCurrentTrain } from "./stateBox/useCurrentTrain.js"; | ||||
| const Stack = createStackNavigator(); | ||||
|  | ||||
| export function MenuPage({ navigation }) { | ||||
|   const { favoriteStation, setFavoriteStation } = useFavoriteStation(); | ||||
|   const { getCurrentTrain } = useCurrentTrain(); | ||||
|   useEffect(() => { | ||||
|     const unsubscribe = navigation.addListener("tabPress", (e) => { | ||||
|       AS.getItem("favoriteStation") | ||||
|         .then((d) => { | ||||
|           const returnData = JSON.parse(d); | ||||
|           if (favoriteStation.toString() != d) { | ||||
|             setFavoriteStation(returnData); | ||||
|           } | ||||
|         }) | ||||
|         .catch((d) => console.log(d)); | ||||
|     }); | ||||
|  | ||||
|     return unsubscribe; | ||||
|   }, [navigation]); | ||||
|   return ( | ||||
|     <Stack.Navigator> | ||||
|       <Stack.Screen | ||||
|         name="menu" | ||||
|         options={{ | ||||
|           headerShown: false, | ||||
|           gestureEnabled: true, | ||||
|           headerTransparent: true, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <Menu {...props} getCurrentTrain={getCurrentTrain} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen name="setting" options={optionData}> | ||||
|         {(props) => <Setting {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="trainbase" | ||||
|         options={{ | ||||
|           ...TransitionPresets.ModalPresentationIOS, | ||||
|           cardOverlayEnabled: true, | ||||
|           headerShown: false, | ||||
|           gestureEnabled: true, | ||||
|           headerTransparent: true, | ||||
|           gestureResponseDistance: { vertical: 300 }, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <TrainBase {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="currentTrainIDList" | ||||
|         options={{ | ||||
|           ...TransitionPresets.ModalPresentationIOS, | ||||
|           cardOverlayEnabled: true, | ||||
|           headerShown: false, | ||||
|           gestureEnabled: true, | ||||
|           headerTransparent: true, | ||||
|           gestureResponseDistance: { vertical: 300 }, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <CurrentTrainListView {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="AllTrainIDList" | ||||
|         options={{ | ||||
|           ...TransitionPresets.ModalPresentationIOS, | ||||
|           cardOverlayEnabled: true, | ||||
|           headerShown: false, | ||||
|           headerTransparent: true, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <AllTrainDiagramView {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="howto" | ||||
|         options={{ | ||||
|           ...optionData, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <HowTo {...props} />} | ||||
|       </Stack.Screen> | ||||
|     </Stack.Navigator> | ||||
|   ); | ||||
| } | ||||
							
								
								
									
										100
									
								
								Top.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								Top.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,100 @@ | ||||
| import React, { useEffect, useRef, useState } from "react"; | ||||
| import { | ||||
|   createStackNavigator, | ||||
|   TransitionPresets, | ||||
| } from "@react-navigation/stack"; | ||||
| import { getStationList2 } from "./lib/getStationList2"; | ||||
| import Apps from "./Apps"; | ||||
| import TrainBase from "./trainbaseview"; | ||||
| import HowTo from "./howto"; | ||||
| import News from "./components/news.js"; | ||||
| import TrainMenu from "./components/trainMenu.js"; | ||||
| import FavoriteList from "./components/FavoriteList.js"; | ||||
| import { useFavoriteStation } from "./stateBox/useFavoriteStation"; | ||||
| import { optionData } from "./lib/stackOption.js"; | ||||
| import { useCurrentTrain } from "./stateBox/useCurrentTrain.js"; | ||||
| const Stack = createStackNavigator(); | ||||
| export const Top = ({ navigation }) => { | ||||
|   const webview = useRef(); | ||||
|   const { favoriteStation, setFavoriteStation } = useFavoriteStation(); | ||||
|   const { getCurrentTrain } = useCurrentTrain(); | ||||
|  | ||||
|   //地図用 | ||||
|   const [mapsStationData, setMapsStationData] = useState(undefined); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     getStationList2().then(setMapsStationData); | ||||
|   }, []); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     const unsubscribe = navigation.addListener("tabLongPress", (e) => { | ||||
|       navigation.navigate("favoriteList"); | ||||
|     }); | ||||
|  | ||||
|     return unsubscribe; | ||||
|   }, [navigation]); | ||||
|  | ||||
|   return ( | ||||
|     <Stack.Navigator> | ||||
|       <Stack.Screen | ||||
|         name="Apps" | ||||
|         options={{ | ||||
|           headerShown: false, | ||||
|           gestureEnabled: true, | ||||
|           headerTransparent: true, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => ( | ||||
|           <Apps | ||||
|             {...props} | ||||
|             webview={webview} | ||||
|             stationData={mapsStationData} | ||||
|             getCurrentTrain={getCurrentTrain} | ||||
|           /> | ||||
|         )} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="trainbase" | ||||
|         options={{ | ||||
|           title: "トレインビジョン", | ||||
|           gestureEnabled: true, | ||||
|           ...TransitionPresets.SlideFromRightIOS, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <TrainBase {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="howto" | ||||
|         options={{ | ||||
|           ...optionData, | ||||
|         }} | ||||
|       > | ||||
|         {(props) => <HowTo {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen name="news" options={optionData}> | ||||
|         {(props) => <News {...props} />} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen name="trainMenu" options={optionData}> | ||||
|         {(props) => ( | ||||
|           <TrainMenu | ||||
|             {...props} | ||||
|             webview={webview} | ||||
|             stationData={mapsStationData} | ||||
|           /> | ||||
|         )} | ||||
|       </Stack.Screen> | ||||
|       <Stack.Screen | ||||
|         name="favoriteList" | ||||
|         options={{ ...optionData, gestureEnabled: false }} | ||||
|       > | ||||
|         {(props) => ( | ||||
|           <FavoriteList | ||||
|             {...props} | ||||
|             webview={webview} | ||||
|             stationData={mapsStationData} | ||||
|           /> | ||||
|         )} | ||||
|       </Stack.Screen> | ||||
|     </Stack.Navigator> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										12
									
								
								app.json
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								app.json
									
									
									
									
									
								
							| @@ -7,7 +7,7 @@ | ||||
|       "ios", | ||||
|       "android" | ||||
|     ], | ||||
|     "version": "4.5", | ||||
|     "version": "4.6", | ||||
|     "orientation": "portrait", | ||||
|     "icon": "./assets/icon.png", | ||||
|     "splash": { | ||||
| @@ -16,13 +16,14 @@ | ||||
|       "backgroundColor": "#00b8ff" | ||||
|     }, | ||||
|     "updates": { | ||||
|       "fallbackToCacheTimeout": 0 | ||||
|       "fallbackToCacheTimeout": 0, | ||||
|       "url": "https://u.expo.dev/398abf60-57a7-11e9-970c-8f04356d08bf" | ||||
|     }, | ||||
|     "assetBundlePatterns": [ | ||||
|       "**/*" | ||||
|     ], | ||||
|     "ios": { | ||||
|       "buildNumber": "24", | ||||
|       "buildNumber": "31", | ||||
|       "supportsTablet": true, | ||||
|       "bundleIdentifier": "jrshikokuinfo.xprocess.hrkn", | ||||
|       "config": { | ||||
| @@ -31,7 +32,7 @@ | ||||
|     }, | ||||
|     "android": { | ||||
|       "package": "jrshikokuinfo.xprocess.hrkn", | ||||
|       "versionCode": 16, | ||||
|       "versionCode": 20, | ||||
|       "permissions": [ | ||||
|         "ACCESS_FINE_LOCATION" | ||||
|       ], | ||||
| @@ -46,6 +47,9 @@ | ||||
|       "eas": { | ||||
|         "projectId": "398abf60-57a7-11e9-970c-8f04356d08bf" | ||||
|       } | ||||
|     }, | ||||
|     "runtimeVersion": { | ||||
|       "policy": "sdkVersion" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								assets/A.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/A.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 439 KiB | 
							
								
								
									
										
											BIN
										
									
								
								assets/B.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/B.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 405 KiB | 
| @@ -1,5 +1,5 @@ | ||||
| export default | ||||
| {"104M":"多度津,発,5:49#讃岐塩屋,発,5:53#丸亀,発,5:56#宇多津,発,5:59#坂出,発,6:04#八十場,発,6:07#鴨川,発,6:10#讃岐府中,発,6:13#国分,発,6:16#端岡,発,6:23#鬼無,発,6:27#香西,発,6:30#高松,着,6:35#", | ||||
| export default { | ||||
| "104M":"多度津,発,5:49#讃岐塩屋,発,5:53#丸亀,発,5:56#宇多津,発,5:59#坂出,発,6:04#八十場,発,6:07#鴨川,発,6:10#讃岐府中,発,6:13#国分,発,6:16#端岡,発,6:23#鬼無,発,6:27#香西,発,6:30#高松,着,6:35#", | ||||
| "108M":"多度津,発,6:43#讃岐塩屋,発,6:47#丸亀,発,6:49#宇多津,発,6:52#坂出,発,6:57#八十場,発,7:01#鴨川,発,7:03#讃岐府中,発,7:06#国分,発,7:09#端岡,発,7:13#鬼無,発,7:17#香西,発,7:20#高松,着,7:24#", | ||||
| "110M":"観音寺,発,6:26#本山,発,6:31#比地大,発,6:34#高瀬,発,6:38#みの,発,6:41#詫間,発,6:45#海岸寺,発,6:50#多度津,発,6:58#讃岐塩屋,発,7:01#丸亀,発,7:04#宇多津,発,7:08#坂出,発,7:13#八十場,発,7:16#鴨川,発,7:26#讃岐府中,発,7:30#国分,発,7:33#端岡,発,7:36#鬼無,発,7:40#香西,発,7:43#高松,着,7:47#", | ||||
| "112M":"多度津,発,7:18#讃岐塩屋,発,7:21#丸亀,発,7:24#宇多津,発,7:28#坂出,発,7:32#八十場,発,7:36#鴨川,発,7:39#讃岐府中,発,7:42#国分,発,7:45#端岡,発,7:48#鬼無,発,7:52#香西,発,7:55#高松,着,7:59#", | ||||
| @@ -11,7 +11,7 @@ | ||||
| "126M":"観音寺,発,9:26#本山,発,9:35#比地大,発,9:38#高瀬,発,9:42#みの,発,9:46#詫間,発,9:49#海岸寺,発,9:55#多度津,発,10:01#讃岐塩屋,発,10:04#丸亀,発,10:07#宇多津,発,10:10#坂出,発,10:15#八十場,発,10:18#鴨川,発,10:21#讃岐府中,発,10:24#国分,発,10:27#端岡,発,10:34#鬼無,発,10:38#香西,発,10:41#高松,着,10:45#", | ||||
| "128M":"伊予西条,発,8:47#中萩,発,8:54#新居浜,発,9:01#多喜浜,発,9:05#関川,発,9:12#伊予土居,発,9:16#赤星,発,9:20#伊予寒川,発,9:24#伊予三島,発,9:41#川之江,発,9:49#箕浦,発,9:55#豊浜,発,9:59#観音寺,着,10:04#", | ||||
| "132M":"多度津,発,12:09#讃岐塩屋,発,12:12#丸亀,発,12:15#宇多津,発,12:18#坂出,発,12:24#八十場,発,12:27#鴨川,発,12:30#讃岐府中,発,12:33#国分,発,12:36#端岡,発,12:39#鬼無,発,12:43#香西,発,12:46#高松,着,12:50#", | ||||
| "134M":"観音寺,発,12:10#本山,発,12:15#比地大,発,12:18#高瀬,発,12:31#みの,発,12:35#詫間,発,12:39#海岸寺,発,12:48#多度津,発,13:01#讃岐塩屋,発,13:05#丸亀,発,13:08#宇多津,発,13:11#坂出,発,13:16#端岡,発,13:25#高松,着,13:33#", | ||||
| "134M":"観音寺,発,12:10#本山,発,12:15#比地大,発,12:18#高瀬,発,12:32#みの,発,12:35#詫間,発,12:39#海岸寺,発,12:48#多度津,発,13:01#讃岐塩屋,発,13:05#丸亀,発,13:08#宇多津,発,13:11#坂出,発,13:16#端岡,発,13:25#高松,着,13:33#", | ||||
| "136M":"多度津,発,13:09#讃岐塩屋,発,13:12#丸亀,発,13:15#宇多津,発,13:18#坂出,発,13:24#八十場,発,13:27#鴨川,発,13:30#讃岐府中,発,13:33#国分,発,13:36#端岡,発,13:39#鬼無,発,13:43#香西,発,13:46#高松,着,13:50#", | ||||
| "138M":"多度津,発,14:01#讃岐塩屋,発,14:05#丸亀,発,14:08#宇多津,発,14:11#坂出,発,14:16#端岡,発,14:25#高松,着,14:33#", | ||||
| "140M":"多度津,発,14:09#讃岐塩屋,発,14:12#丸亀,発,14:15#宇多津,発,14:18#坂出,発,14:24#八十場,発,14:27#鴨川,発,14:30#讃岐府中,発,14:33#国分,発,14:36#端岡,発,14:39#鬼無,発,14:43#香西,発,14:46#高松,着,14:50#", | ||||
| @@ -27,15 +27,11 @@ | ||||
| "166M":"多度津,発,22:37#讃岐塩屋,発,22:40#丸亀,発,22:43#宇多津,発,22:46#坂出,発,22:58#八十場,発,23:01#鴨川,発,23:04#讃岐府中,発,23:07#国分,発,23:10#端岡,発,23:13#鬼無,発,23:17#香西,発,23:20#高松,着,23:25#", | ||||
| "168M":"多度津,発,23:07#讃岐塩屋,発,23:10#丸亀,発,23:13#宇多津,発,23:17#坂出,発,23:29#八十場,発,23:32#鴨川,発,23:35#讃岐府中,発,23:38#国分,発,23:41#端岡,発,23:44#鬼無,発,23:48#香西,発,23:51#高松,着,23:55#", | ||||
| "510M":"今治,発,6:00#伊予富田,発,6:04#伊予桜井,発,6:09#伊予三芳,発,6:18#壬生川,発,6:23#玉之江,発,6:26#伊予小松,発,6:30#伊予氷見,発,6:32#石鎚山,発,6:35#伊予西条,着,6:39#", | ||||
| "514M":"松山,発,6:34#三津浜,発,6:39#伊予和気,発,6:43#堀江,発,6:46#光洋台,発,6:50#粟井,発,7:00#柳原,発,7:03#伊予北条,発,7:12#大浦,発,7:17#浅海,発,7:21#菊間,発,7:29#伊予亀岡,発,7:38#大西,発,7:50#波方,発,7:55#波止浜,発,8:00#今治,発,8:06#伊予富田,発,8:10#伊予桜井,発,8:14#伊予三芳,発,8:22#壬生川,発,8:26#玉之江,発,8:30#伊予小松,発,8:34#伊予氷見,発,8:36#石鎚山,発,8:40#伊予西条,着,8:44#", | ||||
| "516M":"松山,発,7:23#三津浜,発,7:27#伊予和気,発,7:31#堀江,発,7:34#光洋台,発,7:38#粟井,発,7:41#柳原,発,7:43#伊予北条,発,7:48#大浦,発,7:52#浅海,発,7:56#菊間,発,8:02#伊予亀岡,発,8:09#大西,発,8:15#波方,発,8:19#波止浜,発,8:23#今治,着,8:27#", | ||||
| "518M":"松山,発,7:49#三津浜,発,7:55#伊予和気,発,7:59#堀江,発,8:03#光洋台,発,8:06#粟井,発,8:09#柳原,発,8:12#伊予北条,着,8:14#", | ||||
| "534M":"松山,発,14:26#三津浜,発,14:30#伊予和気,発,14:34#堀江,発,14:37#光洋台,発,14:41#粟井,発,14:44#柳原,発,14:46#伊予北条,発,14:51#大浦,発,14:55#浅海,発,15:02#菊間,発,15:08#伊予亀岡,発,15:13#大西,発,15:19#波方,発,15:24#波止浜,発,15:27#今治,発,15:32#伊予富田,発,15:39#伊予桜井,発,15:43#伊予三芳,発,15:51#壬生川,発,15:56#玉之江,発,15:59#伊予小松,発,16:03#伊予氷見,発,16:05#石鎚山,発,16:08#伊予西条,着,16:13#", | ||||
| "536M":"松山,発,15:03#三津浜,発,15:15#伊予和気,発,15:19#堀江,発,15:23#光洋台,発,15:26#粟井,発,15:29#柳原,発,15:32#伊予北条,発,15:42#大浦,発,15:46#浅海,発,16:00#菊間,発,16:05#伊予亀岡,発,16:10#大西,発,16:15#波方,発,16:22#波止浜,発,16:25#今治,発,16:30#伊予富田,発,16:33#伊予桜井,発,16:40#伊予三芳,発,16:47#壬生川,発,16:51#玉之江,発,16:54#伊予小松,発,16:58#伊予氷見,発,17:00#石鎚山,発,17:03#伊予西条,発,17:09#中萩,発,17:17#新居浜,発,17:23#多喜浜,発,17:28#関川,発,17:35#伊予土居,発,17:39#赤星,発,17:42#伊予寒川,発,17:46#伊予三島,発,18:05#川之江,発,18:11#箕浦,発,18:17#豊浜,発,18:21#観音寺,着,18:26#", | ||||
| "538M":"松山,発,15:45#三津浜,発,15:50#伊予和気,発,15:54#堀江,発,15:57#光洋台,発,16:01#粟井,発,16:08#柳原,発,16:10#伊予北条,発,16:13#大浦,発,16:17#浅海,発,16:21#菊間,発,16:26#伊予亀岡,発,16:33#大西,発,16:38#波方,発,16:43#波止浜,発,16:53#今治,着,16:58#", | ||||
| "542M":"松山,発,16:30#三津浜,発,16:35#伊予和気,発,16:39#堀江,発,16:42#光洋台,発,16:46#粟井,発,16:49#柳原,発,16:52#伊予北条,発,16:56#大浦,発,17:00#浅海,発,17:07#菊間,発,17:13#伊予亀岡,発,17:18#大西,発,17:24#波方,発,17:31#波止浜,発,17:35#今治,発,17:45#伊予富田,発,17:52#伊予桜井,発,17:56#伊予三芳,発,18:04#壬生川,発,18:08#玉之江,発,18:12#伊予小松,発,18:16#伊予氷見,発,18:19#石鎚山,発,18:34#伊予西条,着,18:38#", | ||||
| "548M":"松山,発,17:40#三津浜,発,17:47#伊予和気,発,17:52#堀江,発,17:55#光洋台,発,17:59#粟井,発,18:02#柳原,発,18:05#伊予北条,発,18:13#大浦,発,18:18#浅海,発,18:22#菊間,発,18:28#伊予亀岡,発,18:32#大西,発,18:39#波方,発,18:43#波止浜,発,18:51#今治,発,18:57#伊予富田,発,19:01#伊予桜井,発,19:06#伊予三芳,発,19:15#壬生川,発,19:19#玉之江,発,19:22#伊予小松,発,19:29#伊予氷見,発,19:32#石鎚山,発,19:36#伊予西条,着,19:40#", | ||||
| "550M":"松山,発,18:10#三津浜,発,18:24#伊予和気,発,18:28#堀江,発,18:32#光洋台,発,18:36#粟井,発,18:39#柳原,発,18:42#伊予北条,発,18:55#大浦,発,18:59#浅海,発,19:08#菊間,発,19:14#伊予亀岡,発,19:19#大西,発,19:25#波方,発,19:30#波止浜,発,19:34#今治,発,19:39#伊予富田,発,19:45#伊予桜井,発,19:49#伊予三芳,発,19:57#壬生川,発,20:01#玉之江,発,20:05#伊予小松,発,20:09#伊予氷見,発,20:12#石鎚山,発,20:15#伊予西条,着,20:19#", | ||||
| "552M":"松山,発,19:07#三津浜,発,19:12#伊予和気,発,19:18#堀江,発,19:22#光洋台,発,19:25#粟井,発,19:28#柳原,発,19:32#伊予北条,発,19:47#大浦,発,19:52#浅海,発,19:56#菊間,発,20:08#伊予亀岡,発,20:15#大西,発,20:20#波方,発,20:25#波止浜,発,20:28#今治,着,20:32#", | ||||
| "554M":"松山,発,20:04#三津浜,発,20:10#伊予和気,発,20:14#堀江,発,20:22#光洋台,発,20:25#粟井,発,20:28#柳原,発,20:31#伊予北条,発,20:36#大浦,発,20:40#浅海,発,20:44#菊間,発,20:50#伊予亀岡,発,21:10#大西,発,21:18#波方,発,21:23#波止浜,発,21:26#今治,着,21:31#", | ||||
| "620D":"八幡浜,発,5:22#千丈,発,5:26#伊予平野,発,5:35#西大洲,発,5:38#伊予大洲,発,5:42#新谷,発,5:49#喜多山,発,5:52#五十崎,発,5:56#内子,発,5:59#伊予立川,発,6:09#伊予中山,発,6:17#伊予大平,発,6:25#向井原,発,6:28#伊予市,発,6:55#鳥ノ木,発,6:58#伊予横田,発,7:01#南伊予,発,7:04#北伊予,発,7:07#市坪,発,7:11#松山,着,7:15#", | ||||
| @@ -84,9 +80,9 @@ | ||||
| "1608M":"観音寺,発,20:52#本山,発,20:59#比地大,発,21:02#高瀬,発,21:06#みの,発,21:09#詫間,発,21:12#海岸寺,発,21:17#多度津,着,21:21#", | ||||
| "4108M":"観音寺,発,6:00#本山,発,6:04#比地大,発,6:07#高瀬,発,6:14#みの,発,6:18#詫間,発,6:21#海岸寺,発,6:29#多度津,着,6:32#", | ||||
| "4130M":"伊予西条,発,9:47#中萩,発,9:54#新居浜,発,10:01#多喜浜,発,10:08#関川,発,10:16#伊予土居,発,10:20#赤星,発,10:24#伊予寒川,発,10:28#伊予三島,発,10:33#川之江,発,10:41#箕浦,発,10:47#豊浜,発,10:52#観音寺,着,10:56#", | ||||
| "4138M":"松山,発,9:36#三津浜,発,9:41#伊予和気,発,9:45#堀江,発,9:48#光洋台,発,9:52#粟井,発,9:57#柳原,発,9:59#伊予北条,発,10:05#大浦,発,10:09#浅海,発,10:13#菊間,発,10:18#伊予亀岡,発,10:25#大西,発,10:31#波方,発,10:36#波止浜,発,10:45#今治,発,11:07#伊予富田,発,11:11#伊予桜井,発,11:15#伊予三芳,発,11:26#壬生川,発,11:30#玉之江,発,11:33#伊予小松,発,11:36#伊予氷見,発,11:39#石鎚山,発,11:42#伊予西条,発,11:49#中萩,発,11:55#新居浜,発,11:59#多喜浜,発,12:05#関川,発,12:13#伊予土居,発,12:17#赤星,発,12:20#伊予寒川,発,12:24#伊予三島,発,12:31#川之江,発,12:36#箕浦,発,12:49#豊浜,発,12:54#観音寺,発,13:18#本山,発,13:23#比地大,発,13:26#高瀬,発,13:32#みの,発,13:36#詫間,発,13:40#海岸寺,発,13:45#多度津,着,13:49#", | ||||
| "4138M":"松山,発,9:36#三津浜,発,9:41#伊予和気,発,9:45#堀江,発,9:48#光洋台,発,9:52#粟井,発,9:57#柳原,発,9:59#伊予北条,発,10:05#大浦,発,10:09#浅海,発,10:13#菊間,発,10:18#伊予亀岡,発,10:25#大西,発,10:31#波方,発,10:36#波止浜,発,10:45#今治,発,11:07#伊予富田,発,11:11#伊予桜井,発,11:15#伊予三芳,発,11:26#壬生川,発,11:30#玉之江,発,11:33#伊予小松,発,11:36#伊予氷見,発,11:39#石鎚山,発,11:42#伊予西条,発,11:49#中萩,発,11:55#新居浜,発,11:59#多喜浜,発,12:06#関川,発,12:13#伊予土居,発,12:17#赤星,発,12:20#伊予寒川,発,12:25#伊予三島,発,12:31#川之江,発,12:36#箕浦,発,12:50#豊浜,発,12:54#観音寺,発,13:18#本山,発,13:23#比地大,発,13:26#高瀬,発,13:32#みの,発,13:36#詫間,発,13:40#海岸寺,発,13:45#多度津,着,13:49#", | ||||
| "4142M":"伊予西条,発,12:38#中萩,発,12:47#新居浜,発,13:01#多喜浜,発,13:07#関川,発,13:14#伊予土居,発,13:19#赤星,発,13:22#伊予寒川,発,13:27#伊予三島,発,13:31#川之江,発,13:37#箕浦,発,13:50#豊浜,発,13:55#観音寺,着,14:00#", | ||||
| "4152M":"伊予西条,発,15:30#中萩,発,15:37#新居浜,発,15:41#多喜浜,発,15:45#関川,発,15:53#伊予土居,発,16:00#赤星,発,16:04#伊予寒川,発,16:07#伊予三島,発,16:14#川之江,発,16:19#箕浦,発,16:24#豊浜,発,16:29#観音寺,発,16:47#本山,発,16:52#比地大,発,16:55#高瀬,発,16:59#みの,発,17:03#詫間,発,17:06#海岸寺,発,17:11#多度津,着,17:15#", | ||||
| "4152M":"伊予西条,発,15:30#中萩,発,15:37#新居浜,発,15:41#多喜浜,発,15:45#関川,発,15:53#伊予土居,発,16:01#赤星,発,16:04#伊予寒川,発,16:08#伊予三島,発,16:14#川之江,発,16:19#箕浦,発,16:24#豊浜,発,16:29#観音寺,発,16:47#本山,発,16:52#比地大,発,16:55#高瀬,発,16:59#みの,発,17:03#詫間,発,17:06#海岸寺,発,17:11#多度津,着,17:15#", | ||||
| "4160M":"観音寺,発,18:42#本山,発,18:46#比地大,発,18:49#高瀬,発,18:53#みの,発,18:56#詫間,発,18:59#海岸寺,発,19:04#多度津,着,19:08#", | ||||
| "4166M":"伊予西条,発,20:50#中萩,発,20:56#新居浜,発,21:01#多喜浜,発,21:05#関川,発,21:16#伊予土居,発,21:20#赤星,発,21:23#伊予寒川,発,21:26#伊予三島,発,21:30#川之江,発,21:35#箕浦,発,21:42#豊浜,発,21:47#観音寺,発,21:54#本山,発,21:59#比地大,発,22:01#高瀬,発,22:05#みの,発,22:08#詫間,発,22:11#海岸寺,発,22:16#多度津,着,22:20#", | ||||
| "4168M":"観音寺,発,22:21#本山,発,22:29#比地大,発,22:32#高瀬,発,22:36#みの,発,22:39#詫間,発,22:48#海岸寺,発,22:56#多度津,着,23:00#", | ||||
| @@ -95,9 +91,9 @@ | ||||
| "4520M":"松山,発,8:39#三津浜,発,8:46#伊予和気,発,8:51#堀江,発,8:54#光洋台,発,8:58#粟井,発,9:01#柳原,発,9:04#伊予北条,着,9:07#", | ||||
| "4522M":"伊予西条,発,10:42#中萩,発,10:49#新居浜,発,10:54#多喜浜,発,11:00#関川,発,11:08#伊予土居,発,11:12#赤星,発,11:15#伊予寒川,発,11:19#伊予三島,発,11:29#川之江,発,11:35#箕浦,発,11:49#豊浜,発,11:54#観音寺,着,11:59#", | ||||
| "4524M":"松山,発,10:46#三津浜,発,10:50#伊予和気,発,10:55#堀江,発,10:58#光洋台,発,11:01#粟井,発,11:07#柳原,発,11:09#伊予北条,発,11:17#大浦,発,11:21#浅海,発,11:25#菊間,発,11:31#伊予亀岡,発,11:36#大西,発,11:45#波方,発,11:49#波止浜,発,11:53#今治,着,11:57#", | ||||
| "4526M":"松山,発,11:26#三津浜,発,11:31#伊予和気,発,11:35#堀江,発,11:38#光洋台,発,11:41#粟井,発,11:44#柳原,発,11:46#伊予北条,発,11:51#大浦,発,11:57#浅海,発,12:01#菊間,発,12:07#伊予亀岡,発,12:12#大西,発,12:18#波方,発,12:22#波止浜,発,12:25#今治,発,12:33#伊予富田,発,12:39#伊予桜井,発,12:44#伊予三芳,発,12:51#壬生川,発,12:55#玉之江,発,12:58#伊予小松,発,13:03#伊予氷見,発,13:05#石鎚山,発,13:08#伊予西条,発,13:29#中萩,発,13:35#新居浜,発,13:42#多喜浜,発,13:46#関川,発,13:53#伊予土居,発,13:59#赤星,発,14:03#伊予寒川,発,14:08#伊予三島,発,14:12#川之江,発,14:18#箕浦,発,14:23#豊浜,発,14:28#観音寺,着,14:33#", | ||||
| "4526M":"松山,発,11:26#三津浜,発,11:31#伊予和気,発,11:35#堀江,発,11:38#光洋台,発,11:41#粟井,発,11:44#柳原,発,11:46#伊予北条,発,11:51#大浦,発,11:57#浅海,発,12:01#菊間,発,12:07#伊予亀岡,発,12:12#大西,発,12:18#波方,発,12:22#波止浜,発,12:25#今治,発,12:33#伊予富田,発,12:39#伊予桜井,発,12:44#伊予三芳,発,12:51#壬生川,発,12:55#玉之江,発,12:58#伊予小松,発,13:03#伊予氷見,発,13:05#石鎚山,発,13:08#伊予西条,発,13:29#中萩,発,13:35#新居浜,発,13:42#多喜浜,発,13:46#関川,発,13:53#伊予土居,発,14:00#赤星,発,14:03#伊予寒川,発,14:08#伊予三島,発,14:12#川之江,発,14:18#箕浦,発,14:23#豊浜,発,14:28#観音寺,着,14:33#", | ||||
| "4528M":"松山,発,12:01#三津浜,発,12:12#伊予和気,発,12:16#堀江,発,12:20#光洋台,発,12:23#粟井,発,12:32#柳原,発,12:35#伊予北条,発,12:40#大浦,発,12:44#浅海,発,12:48#菊間,発,12:56#伊予亀岡,発,13:01#大西,発,13:07#波方,発,13:12#波止浜,発,13:15#今治,発,13:23#伊予富田,発,13:27#伊予桜井,発,13:35#伊予三芳,発,13:42#壬生川,発,13:48#玉之江,発,13:51#伊予小松,発,13:55#伊予氷見,発,13:57#石鎚山,発,14:01#伊予西条,着,14:05#", | ||||
| "4530M":"伊予西条,発,14:30#中萩,発,14:37#新居浜,発,14:42#多喜浜,発,14:46#関川,発,14:53#伊予土居,発,15:00#赤星,発,15:03#伊予寒川,発,15:08#伊予三島,発,15:12#川之江,発,15:17#箕浦,発,15:23#豊浜,発,15:28#観音寺,着,15:33#", | ||||
| "4530M":"伊予西条,発,14:30#中萩,発,14:37#新居浜,発,14:42#多喜浜,発,14:46#関川,発,14:53#伊予土居,発,15:00#赤星,発,15:04#伊予寒川,発,15:08#伊予三島,発,15:12#川之江,発,15:17#箕浦,発,15:23#豊浜,発,15:29#観音寺,着,15:33#", | ||||
| "4532M":"松山,発,13:06#三津浜,発,13:13#伊予和気,発,13:20#堀江,発,13:23#光洋台,発,13:26#粟井,発,13:30#柳原,発,13:32#伊予北条,発,13:47#大浦,発,13:51#浅海,発,13:58#菊間,発,14:03#伊予亀岡,発,14:08#大西,発,14:13#波方,発,14:18#波止浜,発,14:21#今治,発,14:28#伊予富田,発,14:32#伊予桜井,発,14:39#伊予三芳,発,14:47#壬生川,発,14:51#玉之江,発,14:54#伊予小松,発,14:58#伊予氷見,発,15:01#石鎚山,発,15:04#伊予西条,着,15:08#", | ||||
| "4534M":"伊予西条,発,16:31#中萩,発,16:37#新居浜,発,16:44#多喜浜,発,16:48#関川,発,16:55#伊予土居,発,17:02#赤星,発,17:05#伊予寒川,発,17:09#伊予三島,発,17:15#川之江,発,17:20#箕浦,発,17:26#豊浜,発,17:31#観音寺,着,17:36#", | ||||
| "4544M":"松山,発,17:03#三津浜,発,17:07#伊予和気,発,17:12#堀江,発,17:17#光洋台,発,17:21#粟井,発,17:31#柳原,発,17:34#伊予北条,着,17:37#", | ||||
| @@ -110,7 +106,7 @@ | ||||
| "4626D":"伊予市,発,8:19#鳥ノ木,発,8:21#伊予横田,発,8:24#南伊予,発,8:27#北伊予,発,8:29#市坪,発,8:33#松山,着,8:37#", | ||||
| "4630M":"伊予市,発,9:16#鳥ノ木,発,9:18#伊予横田,発,9:21#南伊予,発,9:23#北伊予,発,9:26#市坪,発,9:30#松山,着,9:33#", | ||||
| "4632D":"宇和島,発,6:47#北宇和島,発,6:50#高光,発,6:54#伊予吉田,発,7:16#立間,発,7:20#下宇和,発,7:31#卯之町,発,7:36#上宇和,発,7:39#伊予石城,発,7:46#双岩,発,7:53#八幡浜,着,7:59#", | ||||
| "4634D":"八幡浜,発,8:48#千丈,発,8:56#伊予平野,発,9:05#西大洲,発,9:08#伊予大洲,発,9:14#新谷,発,9:21#喜多山,発,9:23#五十崎,発,9:27#内子,発,9:46#伊予立川,発,9:52#伊予中山,発,9:59#伊予大平,発,10:06#向井原,発,10:10#伊予市,発,10:41#鳥ノ木,発,10:44#伊予横田,発,10:47#南伊予,発,10:50#北伊予,発,10:52#市坪,発,10:56#松山,着,11:00#", | ||||
| "4634D":"八幡浜,発,8:48#千丈,発,8:56#伊予平野,発,9:05#西大洲,発,9:08#伊予大洲,発,9:14#新谷,発,9:21#喜多山,発,9:23#五十崎,発,9:27#内子,発,9:46#伊予立川,発,9:52#伊予中山,発,9:59#伊予大平,発,10:06#向井原,発,10:10#伊予市,発,10:42#鳥ノ木,発,10:45#伊予横田,発,10:48#南伊予,発,10:51#北伊予,発,10:53#市坪,発,10:57#松山,着,11:01#", | ||||
| "4636D":"八幡浜,発,11:26#千丈,発,11:31#伊予平野,発,11:39#西大洲,発,11:42#伊予大洲,発,11:49#新谷,発,11:59#喜多山,発,12:01#五十崎,発,12:05#内子,発,12:08#伊予立川,発,12:14#伊予中山,発,12:20#伊予大平,発,12:27#向井原,発,12:31#伊予市,発,12:35#鳥ノ木,発,12:38#伊予横田,発,12:41#南伊予,発,12:43#北伊予,発,12:46#市坪,発,12:49#松山,着,12:54#", | ||||
| "4638M":"伊予市,発,13:32#鳥ノ木,発,13:34#伊予横田,発,13:37#南伊予,発,13:39#北伊予,発,13:42#市坪,発,13:45#松山,発,13:52#三津浜,発,13:57#伊予和気,発,14:01#堀江,発,14:07#光洋台,発,14:11#粟井,発,14:14#柳原,発,14:17#伊予北条,着,14:19#", | ||||
| "4640D":"宇和島,発,12:23#北宇和島,発,12:26#高光,発,12:30#伊予吉田,発,12:39#立間,発,12:44#下宇和,発,12:55#卯之町,発,13:04#上宇和,発,13:08#伊予石城,発,13:28#双岩,発,13:34#八幡浜,発,13:47#千丈,発,13:51#伊予平野,発,14:02#西大洲,発,14:05#伊予大洲,発,14:10#新谷,発,14:20#喜多山,発,14:22#五十崎,発,14:26#内子,発,14:29#伊予立川,発,14:36#伊予中山,発,14:45#伊予大平,発,14:52#向井原,発,14:56#伊予市,発,14:59#鳥ノ木,発,15:02#伊予横田,発,15:05#南伊予,発,15:07#北伊予,発,15:15#市坪,発,15:20#松山,着,15:24#", | ||||
| @@ -142,28 +138,32 @@ | ||||
| "5144M":"観音寺,発,14:38#本山,発,14:43#比地大,発,14:46#高瀬,発,14:50#みの,発,14:54#詫間,発,14:57#海岸寺,発,15:03#多度津,発,15:08#讃岐塩屋,発,15:12#丸亀,発,15:15#宇多津,発,15:19#坂出,発,15:24#八十場,発,15:28#鴨川,発,15:31#讃岐府中,発,15:34#国分,発,15:37#端岡,発,15:40#鬼無,発,15:44#香西,発,15:47#高松,着,15:52#", | ||||
| "5156M":"多度津,発,18:32#讃岐塩屋,発,18:36#丸亀,発,18:39#宇多津,発,18:43#坂出,発,18:54#八十場,発,18:58#鴨川,発,19:01#讃岐府中,発,19:04#国分,発,19:07#端岡,発,19:11#鬼無,発,19:14#香西,発,19:18#高松,着,19:22#", | ||||
| "5512M":"伊予西条,発,7:20#中萩,発,7:28#新居浜,発,7:33#多喜浜,発,7:38#関川,発,7:46#伊予土居,発,7:50#赤星,発,7:54#伊予寒川,発,7:59#伊予三島,発,8:04#川之江,発,8:10#箕浦,発,8:15#豊浜,発,8:20#観音寺,着,8:24#", | ||||
| "5514M":"松山,発,6:34#三津浜,発,6:39#伊予和気,発,6:43#堀江,発,6:46#光洋台,発,6:50#粟井,発,7:00#柳原,発,7:03#伊予北条,発,7:12#大浦,発,7:17#浅海,発,7:21#菊間,発,7:29#伊予亀岡,発,7:38#大西,発,7:50#波方,発,7:55#波止浜,発,8:00#今治,発,8:06#伊予富田,発,8:10#伊予桜井,発,8:14#伊予三芳,発,8:22#壬生川,発,8:26#玉之江,発,8:30#伊予小松,発,8:34#伊予氷見,発,8:36#石鎚山,発,8:40#伊予西条,着,8:44#", | ||||
| "5540M":"伊予西条,発,17:48#中萩,発,17:55#新居浜,発,18:03#多喜浜,発,18:10#関川,発,18:17#伊予土居,発,18:22#赤星,発,18:25#伊予寒川,発,18:30#伊予三島,発,18:35#川之江,発,18:52#箕浦,発,18:58#豊浜,発,19:02#観音寺,着,19:07#", | ||||
| "5542M":"松山,発,16:30#三津浜,発,16:35#伊予和気,発,16:39#堀江,発,16:42#光洋台,発,16:46#粟井,発,16:49#柳原,発,16:52#伊予北条,発,16:56#大浦,発,17:00#浅海,発,17:07#菊間,発,17:13#伊予亀岡,発,17:18#大西,発,17:24#波方,発,17:31#波止浜,発,17:35#今治,発,17:45#伊予富田,発,17:52#伊予桜井,発,17:56#伊予三芳,発,18:04#壬生川,発,18:08#玉之江,発,18:12#伊予小松,発,18:16#伊予氷見,発,18:19#石鎚山,発,18:34#伊予西条,着,18:38#", | ||||
| "5546M":"伊予西条,発,18:59#中萩,発,19:08#新居浜,発,19:16#多喜浜,発,19:25#関川,発,19:32#伊予土居,発,19:37#赤星,発,19:40#伊予寒川,発,19:45#伊予三島,発,19:50#川之江,発,19:59#箕浦,発,20:05#豊浜,発,20:11#観音寺,着,20:15#", | ||||
| "8902D":"伊予大洲,発,10:57#伊予長浜,発,11:30#喜多灘,発,11:42#下灘,発,12:10#伊予上灘,発,12:30#北伊予,発,12:53#松山,着,13:01#", | ||||
| "8904D":"八幡浜,発,16:14#伊予大洲,発,16:33#伊予長浜,発,16:57#下灘,発,17:24#伊予上灘,発,17:36#伊予市,発,17:53#北伊予,発,18:03#市坪,発,18:12#松山,着,18:17#", | ||||
| "101M":"多度津,発,5:50#海岸寺,発,5:56#詫間,発,6:02#みの,発,6:05#高瀬,発,6:11#比地大,発,6:14#本山,発,6:18#観音寺,発,6:25#豊浜,発,6:30#箕浦,発,6:43#川之江,発,6:49#伊予三島,発,7:10#伊予寒川,発,7:14#赤星,発,7:18#伊予土居,発,7:22#関川,発,7:30#多喜浜,発,7:38#新居浜,発,7:42#中萩,発,7:48#伊予西条,発,8:01#石鎚山,発,8:05#伊予氷見,発,8:08#伊予小松,発,8:13#玉之江,発,8:17#壬生川,発,8:26#伊予三芳,発,8:30#伊予桜井,発,8:38#伊予富田,発,8:43#今治,発,8:51#波止浜,発,8:58#波方,発,9:02#大西,発,9:07#伊予亀岡,発,9:14#菊間,発,9:19#浅海,発,9:25#大浦,発,9:31#伊予北条,発,9:36#柳原,発,9:39#粟井,発,9:42#光洋台,発,9:45#堀江,発,9:49#伊予和気,発,9:52#三津浜,発,9:57#松山,着,10:01#", | ||||
| "5548M":"松山,発,17:40#三津浜,発,17:47#伊予和気,発,17:52#堀江,発,17:55#光洋台,発,17:59#粟井,発,18:02#柳原,発,18:05#伊予北条,発,18:13#大浦,発,18:18#浅海,発,18:22#菊間,発,18:28#伊予亀岡,発,18:32#大西,発,18:39#波方,発,18:43#波止浜,発,18:51#今治,発,18:57#伊予富田,発,19:01#伊予桜井,発,19:06#伊予三芳,発,19:15#壬生川,発,19:19#玉之江,発,19:22#伊予小松,発,19:29#伊予氷見,発,19:32#石鎚山,発,19:36#伊予西条,着,19:40#", | ||||
| "5550M":"松山,発,18:10#三津浜,発,18:24#伊予和気,発,18:28#堀江,発,18:32#光洋台,発,18:36#粟井,発,18:39#柳原,発,18:42#伊予北条,発,18:55#大浦,発,18:59#浅海,発,19:08#菊間,発,19:14#伊予亀岡,発,19:19#大西,発,19:25#波方,発,19:30#波止浜,発,19:34#今治,発,19:39#伊予富田,発,19:45#伊予桜井,発,19:49#伊予三芳,発,19:57#壬生川,発,20:01#玉之江,発,20:05#伊予小松,発,20:09#伊予氷見,発,20:12#石鎚山,発,20:15#伊予西条,着,20:19#", | ||||
| "8092D":"伊予大洲,発,10:57#伊予長浜,発,11:30#喜多灘,発,11:42#下灘,発,12:10#伊予上灘,発,12:30#北伊予,発,12:53#松山,着,13:01#", | ||||
| "8094D":"八幡浜,発,16:14#伊予大洲,発,16:33#伊予長浜,発,16:57#下灘,発,17:24#伊予上灘,発,17:36#伊予市,発,17:53#北伊予,発,18:03#市坪,発,18:12#松山,着,18:17#", | ||||
| "101M":"多度津,発,5:50#海岸寺,発,5:56#詫間,発,6:02#みの,発,6:05#高瀬,発,6:11#比地大,発,6:14#本山,発,6:18#観音寺,発,6:25#豊浜,発,6:30#箕浦,発,6:43#川之江,発,6:49#伊予三島,発,7:10#伊予寒川,発,7:14#赤星,発,7:18#伊予土居,発,7:22#関川,発,7:30#多喜浜,発,7:38#新居浜,発,7:42#中萩,発,7:48#伊予西条,着,7:53#", | ||||
| "105M":"高松,発,6:48#香西,発,6:52#鬼無,発,6:55#端岡,発,6:59#国分,発,7:03#讃岐府中,発,7:06#鴨川,発,7:09#八十場,発,7:11#坂出,発,7:15#宇多津,発,7:20#丸亀,発,7:23#讃岐塩屋,発,7:26#多度津,着,7:29#", | ||||
| "109M":"高松,発,7:40#香西,発,7:45#鬼無,発,7:48#端岡,発,7:56#国分,発,7:59#讃岐府中,発,8:02#鴨川,発,8:05#八十場,発,8:08#坂出,発,8:11#宇多津,発,8:16#丸亀,発,8:20#讃岐塩屋,発,8:23#多度津,発,8:31#海岸寺,発,8:36#詫間,発,8:46#みの,発,8:49#高瀬,発,8:53#比地大,発,8:56#本山,発,9:03#観音寺,着,9:06#", | ||||
| "117M":"高松,発,10:13#端岡,発,10:21#坂出,発,10:30#宇多津,発,10:34#丸亀,発,10:38#讃岐塩屋,発,10:40#多度津,発,10:51#海岸寺,発,10:56#詫間,発,11:01#みの,発,11:05#高瀬,発,11:11#比地大,発,11:15#本山,発,11:21#観音寺,着,11:25#", | ||||
| "121M":"多度津,発,11:59#海岸寺,発,12:04#詫間,発,12:15#みの,発,12:19#高瀬,発,12:22#比地大,発,12:26#本山,発,12:29#観音寺,着,12:33#", | ||||
| "123M":"高松,発,12:13#端岡,発,12:21#坂出,発,12:30#宇多津,発,12:34#丸亀,発,12:38#讃岐塩屋,発,12:40#多度津,発,12:44#海岸寺,発,12:48#詫間,発,12:54#みの,発,12:58#高瀬,発,13:01#比地大,発,13:05#本山,発,13:11#観音寺,着,13:15#", | ||||
| "121M":"多度津,発,11:59#海岸寺,発,12:04#詫間,発,12:16#みの,発,12:19#高瀬,発,12:22#比地大,発,12:26#本山,発,12:29#観音寺,着,12:33#", | ||||
| "123M":"高松,発,12:13#端岡,発,12:21#坂出,発,12:30#宇多津,発,12:34#丸亀,発,12:38#讃岐塩屋,発,12:40#多度津,発,12:44#海岸寺,発,12:48#詫間,発,12:54#みの,発,12:58#高瀬,発,13:01#比地大,発,13:05#本山,発,13:11#観音寺,着,13:16#", | ||||
| "125M":"高松,発,12:52#香西,発,12:56#鬼無,発,12:59#端岡,発,13:03#国分,発,13:06#讃岐府中,発,13:09#鴨川,発,13:12#八十場,発,13:15#坂出,発,13:19#宇多津,発,13:24#丸亀,発,13:27#讃岐塩屋,発,13:30#多度津,着,13:33#", | ||||
| "127M":"高松,発,13:13#端岡,発,13:21#坂出,発,13:30#宇多津,発,13:34#丸亀,発,13:38#讃岐塩屋,発,13:40#多度津,発,13:53#海岸寺,発,13:57#詫間,発,14:03#みの,発,14:06#高瀬,発,14:14#比地大,発,14:18#本山,発,14:21#観音寺,着,14:25#", | ||||
| "127M":"高松,発,13:13#端岡,発,13:21#坂出,発,13:30#宇多津,発,13:35#丸亀,発,13:38#讃岐塩屋,発,13:40#多度津,発,13:53#海岸寺,発,13:57#詫間,発,14:03#みの,発,14:06#高瀬,発,14:14#比地大,発,14:18#本山,発,14:21#観音寺,着,14:25#", | ||||
| "129M":"高松,発,13:52#香西,発,13:56#鬼無,発,13:59#端岡,発,14:03#国分,発,14:06#讃岐府中,発,14:09#鴨川,発,14:12#八十場,発,14:15#坂出,発,14:19#宇多津,発,14:24#丸亀,発,14:27#讃岐塩屋,発,14:30#多度津,発,14:40#海岸寺,発,14:48#詫間,発,14:57#みの,発,15:00#高瀬,発,15:03#比地大,発,15:07#本山,発,15:17#観音寺,着,15:21#", | ||||
| "131M":"高松,発,14:13#端岡,発,14:21#坂出,発,14:30#宇多津,発,14:34#丸亀,発,14:38#讃岐塩屋,発,14:40#多度津,着,14:43#", | ||||
| "133M":"高松,発,14:52#香西,発,14:56#鬼無,発,14:59#端岡,発,15:03#国分,発,15:06#讃岐府中,発,15:09#鴨川,発,15:12#八十場,発,15:15#坂出,発,15:19#宇多津,発,15:24#丸亀,発,15:27#讃岐塩屋,発,15:30#多度津,発,15:34#海岸寺,発,15:39#詫間,発,15:44#みの,発,15:48#高瀬,発,15:51#比地大,発,15:55#本山,発,15:58#観音寺,着,16:03#", | ||||
| "135M":"高松,発,15:13#端岡,発,15:21#坂出,発,15:30#宇多津,発,15:34#丸亀,発,15:38#讃岐塩屋,発,15:40#多度津,発,15:54#海岸寺,発,16:03#詫間,発,16:18#みの,発,16:21#高瀬,発,16:24#比地大,発,16:28#本山,発,16:31#観音寺,着,16:35#", | ||||
| "135M":"高松,発,15:13#端岡,発,15:21#坂出,発,15:30#宇多津,発,15:34#丸亀,発,15:38#讃岐塩屋,発,15:40#多度津,発,15:54#海岸寺,発,16:03#詫間,発,16:18#みの,発,16:21#高瀬,発,16:25#比地大,発,16:28#本山,発,16:31#観音寺,着,16:35#", | ||||
| "137M":"高松,発,15:52#香西,発,15:56#鬼無,発,15:59#端岡,発,16:03#国分,発,16:06#讃岐府中,発,16:09#鴨川,発,16:12#八十場,発,16:15#坂出,発,16:19#宇多津,発,16:24#丸亀,発,16:27#讃岐塩屋,発,16:30#多度津,発,16:38#海岸寺,発,16:46#詫間,発,16:52#みの,発,16:55#高瀬,発,17:01#比地大,発,17:04#本山,発,17:14#観音寺,着,17:18#", | ||||
| "139M":"高松,発,16:13#端岡,発,16:21#坂出,発,16:30#宇多津,発,16:34#丸亀,発,16:38#讃岐塩屋,発,16:40#多度津,発,16:55#海岸寺,発,17:00#詫間,発,17:07#みの,発,17:10#高瀬,発,17:16#比地大,発,17:20#本山,発,17:26#観音寺,発,17:44#豊浜,発,17:50#箕浦,発,17:54#川之江,発,18:00#伊予三島,発,18:06#伊予寒川,発,18:10#赤星,発,18:14#伊予土居,発,18:22#関川,発,18:28#多喜浜,発,18:35#新居浜,発,18:42#中萩,発,18:47#伊予西条,発,18:54#石鎚山,発,18:58#伊予氷見,発,19:01#伊予小松,発,19:04#玉之江,発,19:07#壬生川,発,19:11#伊予三芳,発,19:15#伊予桜井,発,19:25#伊予富田,発,19:29#今治,発,19:52#波止浜,発,19:57#波方,発,20:04#大西,発,20:09#伊予亀岡,発,20:15#菊間,発,20:20#浅海,発,20:25#大浦,発,20:29#伊予北条,発,20:35#柳原,発,20:38#粟井,発,20:46#光洋台,発,20:49#堀江,発,20:55#伊予和気,発,20:58#三津浜,発,21:02#松山,着,21:06#", | ||||
| "141M":"高松,発,16:52#香西,発,16:56#鬼無,発,16:59#端岡,発,17:03#国分,発,17:06#讃岐府中,発,17:09#鴨川,発,17:12#八十場,発,17:15#坂出,発,17:19#宇多津,発,17:24#丸亀,発,17:27#讃岐塩屋,発,17:30#多度津,発,17:34#海岸寺,発,17:46#詫間,発,17:52#みの,発,17:55#高瀬,発,17:58#比地大,発,18:02#本山,発,18:05#観音寺,着,18:09#", | ||||
| "143M":"高松,発,17:13#端岡,発,17:21#鴨川,発,17:27#坂出,発,17:32#宇多津,発,17:37#丸亀,発,17:40#讃岐塩屋,発,17:43#多度津,発,17:51#海岸寺,発,17:57#詫間,発,18:05#みの,発,18:09#高瀬,発,18:17#比地大,発,18:21#本山,発,18:24#観音寺,着,18:28#", | ||||
| "145M":"高松,発,17:56#端岡,発,18:04#鴨川,発,18:11#坂出,発,18:15#宇多津,発,18:20#丸亀,発,18:24#讃岐塩屋,発,18:26#多度津,発,18:31#海岸寺,発,18:36#詫間,発,18:43#みの,発,18:47#高瀬,発,18:53#比地大,発,18:57#本山,発,19:00#観音寺,着,19:04#", | ||||
| "147M":"高松,発,18:13#端岡,発,18:22#鴨川,発,18:29#坂出,発,18:33#宇多津,発,18:38#丸亀,発,18:42#讃岐塩屋,発,18:44#多度津,発,18:58#海岸寺,発,19:04#詫間,発,19:10#みの,発,19:14#高瀬,発,19:22#比地大,発,19:26#本山,発,19:29#観音寺,着,19:33#", | ||||
| "147M":"高松,発,18:14#端岡,発,18:22#鴨川,発,18:29#坂出,発,18:33#宇多津,発,18:38#丸亀,発,18:42#讃岐塩屋,発,18:44#多度津,発,18:58#海岸寺,発,19:04#詫間,発,19:10#みの,発,19:14#高瀬,発,19:22#比地大,発,19:26#本山,発,19:29#観音寺,着,19:33#", | ||||
| "149M":"高松,発,18:42#香西,発,18:46#鬼無,発,18:49#端岡,発,18:53#国分,発,18:56#讃岐府中,発,18:59#鴨川,発,19:11#八十場,発,19:14#坂出,発,19:18#宇多津,発,19:23#丸亀,発,19:26#讃岐塩屋,発,19:29#多度津,発,19:38#海岸寺,発,19:42#詫間,発,19:48#みの,発,19:51#高瀬,発,20:00#比地大,発,20:04#本山,発,20:08#観音寺,着,20:12#", | ||||
| "151M":"観音寺,発,20:23#豊浜,発,20:28#箕浦,発,20:33#川之江,発,20:38#伊予三島,発,20:57#伊予寒川,発,21:01#赤星,発,21:05#伊予土居,発,21:20#関川,発,21:24#多喜浜,発,21:33#新居浜,発,21:43#中萩,発,21:48#伊予西条,着,21:54#", | ||||
| "153M":"高松,発,19:16#香西,発,19:20#鬼無,発,19:24#端岡,発,19:28#国分,発,19:31#讃岐府中,発,19:34#鴨川,発,19:37#八十場,発,19:40#坂出,発,19:43#宇多津,発,19:48#丸亀,発,19:52#讃岐塩屋,発,19:55#多度津,発,19:59#海岸寺,発,20:06#詫間,発,20:11#みの,発,20:14#高瀬,発,20:18#比地大,発,20:21#本山,発,20:31#観音寺,着,20:35#", | ||||
| @@ -185,7 +185,6 @@ | ||||
| "621D":"八幡浜,発,6:15#双岩,発,6:25#伊予石城,発,6:34#上宇和,発,6:38#卯之町,発,7:00#下宇和,発,7:04#立間,発,7:11#伊予吉田,発,7:16#高光,発,7:23#北宇和島,発,7:29#宇和島,着,7:32#", | ||||
| "625D":"松山,発,6:16#市坪,発,6:21#北伊予,発,6:25#南伊予,発,6:28#伊予横田,発,6:31#鳥ノ木,発,6:34#伊予市,発,6:42#向井原,発,6:46#伊予大平,発,6:50#伊予中山,発,7:18#伊予立川,発,7:24#内子,発,7:33#五十崎,発,7:35#喜多山,発,7:39#新谷,発,7:41#伊予大洲,着,7:48#", | ||||
| "627D":"松山,発,7:28#市坪,発,7:34#北伊予,発,7:43#南伊予,発,7:46#伊予横田,発,7:48#鳥ノ木,発,7:51#伊予市,着,7:53#", | ||||
| "629M":"今治,発,6:49#波止浜,発,6:55#波方,発,6:58#大西,発,7:03#伊予亀岡,発,7:09#菊間,発,7:14#浅海,発,7:21#大浦,発,7:26#伊予北条,発,7:34#柳原,発,7:37#粟井,発,7:41#光洋台,発,7:44#堀江,発,7:53#伊予和気,発,8:00#三津浜,発,8:04#松山,着,8:08#", | ||||
| "647M":"松山,発,16:51#市坪,発,16:55#北伊予,発,17:02#南伊予,発,17:04#伊予横田,発,17:07#鳥ノ木,発,17:09#伊予市,着,17:11#", | ||||
| "653D":"松山,発,17:33#市坪,発,17:38#北伊予,発,17:41#南伊予,発,17:44#伊予横田,発,17:47#鳥ノ木,発,17:50#伊予市,発,17:53#向井原,発,17:57#伊予大平,発,18:02#伊予中山,発,18:16#伊予立川,発,18:22#内子,発,18:28#五十崎,発,18:31#喜多山,発,18:34#新谷,発,18:37#伊予大洲,着,18:43#", | ||||
| "661M":"伊予西条,発,17:10#石鎚山,発,17:14#伊予氷見,発,17:17#伊予小松,発,17:22#玉之江,発,17:25#壬生川,発,17:36#伊予三芳,発,17:40#伊予桜井,発,17:47#伊予富田,発,17:52#今治,発,17:57#波止浜,発,18:02#波方,発,18:08#大西,発,18:12#伊予亀岡,発,18:19#菊間,発,18:28#浅海,発,18:33#大浦,発,18:38#伊予北条,発,18:52#柳原,発,18:55#粟井,発,18:58#光洋台,発,19:00#堀江,発,19:04#伊予和気,発,19:07#三津浜,発,19:12#松山,着,19:17#", | ||||
| @@ -198,7 +197,7 @@ | ||||
| "1003M":"高松,発,8:45#坂出,発,9:02#宇多津,着,9:10#", | ||||
| "1005M":"高松,発,9:42#坂出,発,9:56#宇多津,着,10:03#", | ||||
| "1007M":"高松,発,10:47#坂出,発,11:04#宇多津,着,11:10#", | ||||
| "1009M":"高松,発,11:50#坂出,発,12:04#宇多津,着,12:10#", | ||||
| "1009M":"高松,発,11:50#坂出,発,12:04#宇多津,着,12:11#", | ||||
| "1011M":"高松,発,12:50#坂出,発,13:04#宇多津,着,13:11#", | ||||
| "1013M":"高松,発,13:50#坂出,発,14:04#宇多津,着,14:11#", | ||||
| "1015M":"高松,発,14:50#坂出,発,15:04#宇多津,着,15:12#", | ||||
| @@ -230,9 +229,9 @@ | ||||
| "1091M":"新居浜,発,5:54#伊予西条,発,6:06#壬生川,発,6:15#今治,発,6:29#伊予北条,発,6:57#松山,着,7:09#", | ||||
| "1603M":"多度津,発,20:33#海岸寺,発,20:39#詫間,発,20:46#みの,発,20:49#高瀬,発,20:52#比地大,発,20:56#本山,発,20:59#観音寺,着,21:03#", | ||||
| "4113M":"多度津,発,9:48#海岸寺,発,9:55#詫間,発,10:03#みの,発,10:06#高瀬,発,10:09#比地大,発,10:13#本山,発,10:16#観音寺,発,10:35#豊浜,発,10:40#箕浦,発,10:47#川之江,発,10:53#伊予三島,発,11:00#伊予寒川,発,11:04#赤星,発,11:08#伊予土居,発,11:12#関川,発,11:16#多喜浜,発,11:24#新居浜,発,11:32#中萩,発,11:37#伊予西条,発,12:06#石鎚山,発,12:11#伊予氷見,発,12:14#伊予小松,発,12:19#玉之江,発,12:22#壬生川,発,12:31#伊予三芳,発,12:36#伊予桜井,発,12:44#伊予富田,発,12:48#今治,発,13:01#波止浜,発,13:06#波方,発,13:12#大西,発,13:16#伊予亀岡,発,13:22#菊間,発,13:27#浅海,発,13:32#大浦,発,13:40#伊予北条,発,13:45#柳原,発,13:48#粟井,発,13:51#光洋台,発,13:54#堀江,発,13:57#伊予和気,発,14:01#三津浜,発,14:05#松山,着,14:09#", | ||||
| "4123M":"観音寺,発,13:41#豊浜,発,13:46#箕浦,発,13:50#川之江,発,13:57#伊予三島,発,14:03#伊予寒川,発,14:08#赤星,発,14:12#伊予土居,発,14:16#関川,発,14:20#多喜浜,発,14:27#新居浜,発,14:41#中萩,発,14:46#伊予西条,着,14:52#", | ||||
| "4123M":"観音寺,発,13:41#豊浜,発,13:46#箕浦,発,13:50#川之江,発,13:58#伊予三島,発,14:03#伊予寒川,発,14:08#赤星,発,14:12#伊予土居,発,14:16#関川,発,14:20#多喜浜,発,14:27#新居浜,発,14:41#中萩,発,14:46#伊予西条,着,14:52#", | ||||
| "4127M":"観音寺,発,14:41#豊浜,発,14:46#箕浦,発,14:50#川之江,発,14:58#伊予三島,発,15:03#伊予寒川,発,15:08#赤星,発,15:12#伊予土居,発,15:16#関川,発,15:20#多喜浜,発,15:27#新居浜,発,15:41#中萩,発,15:46#伊予西条,発,15:54#石鎚山,発,15:58#伊予氷見,発,16:01#伊予小松,発,16:03#玉之江,発,16:07#壬生川,発,16:10#伊予三芳,発,16:17#伊予桜井,発,16:25#伊予富田,発,16:34#今治,着,16:37#", | ||||
| "4131M":"多度津,発,14:54#海岸寺,発,15:03#詫間,発,15:17#みの,発,15:21#高瀬,発,15:24#比地大,発,15:28#本山,発,15:31#観音寺,着,15:35#", | ||||
| "4131M":"多度津,発,14:54#海岸寺,発,15:03#詫間,発,15:18#みの,発,15:21#高瀬,発,15:25#比地大,発,15:28#本山,発,15:31#観音寺,着,15:35#", | ||||
| "4135M":"観音寺,発,16:59#豊浜,発,17:06#箕浦,発,17:14#川之江,発,17:20#伊予三島,発,17:26#伊予寒川,発,17:30#赤星,発,17:35#伊予土居,発,17:39#関川,発,17:45#多喜浜,発,17:53#新居浜,発,17:59#中萩,発,18:05#伊予西条,着,18:10#", | ||||
| "4155M":"多度津,発,21:00#海岸寺,発,21:05#詫間,発,21:12#みの,発,21:15#高瀬,発,21:19#比地大,発,21:23#本山,発,21:26#観音寺,着,21:30#", | ||||
| "4511M":"伊予北条,発,5:47#柳原,発,5:50#粟井,発,5:53#光洋台,発,5:56#堀江,発,5:59#伊予和気,発,6:03#三津浜,発,6:07#松山,着,6:11#", | ||||
| @@ -240,8 +239,8 @@ | ||||
| "4527M":"伊予北条,発,10:03#柳原,発,10:06#粟井,発,10:09#光洋台,発,10:11#堀江,発,10:15#伊予和気,発,10:18#三津浜,発,10:25#松山,着,10:29#", | ||||
| "4529M":"今治,発,10:07#波止浜,発,10:11#波方,発,10:15#大西,発,10:19#伊予亀岡,発,10:25#菊間,発,10:30#浅海,発,10:37#大浦,発,10:41#伊予北条,発,10:45#柳原,発,10:49#粟井,発,10:51#光洋台,発,10:54#堀江,発,10:58#伊予和気,発,11:01#三津浜,発,11:05#松山,着,11:10#", | ||||
| "4533M":"今治,発,12:11#波止浜,発,12:16#波方,発,12:22#大西,発,12:26#伊予亀岡,発,12:32#菊間,発,12:41#浅海,発,12:48#大浦,発,12:53#伊予北条,発,12:57#柳原,発,13:00#粟井,発,13:09#光洋台,発,13:12#堀江,発,13:16#伊予和気,発,13:20#三津浜,発,13:30#松山,着,13:34#", | ||||
| "4535M":"観音寺,発,11:39#豊浜,発,11:45#箕浦,発,11:49#川之江,発,11:56#伊予三島,発,12:04#伊予寒川,発,12:08#赤星,発,12:12#伊予土居,発,12:17#関川,発,12:22#多喜浜,発,12:37#新居浜,発,12:41#中萩,発,12:46#伊予西条,発,13:04#石鎚山,発,13:08#伊予氷見,発,13:11#伊予小松,発,13:16#玉之江,発,13:20#壬生川,発,13:38#伊予三芳,発,13:42#伊予桜井,発,13:50#伊予富田,発,13:54#今治,発,14:05#波止浜,発,14:09#波方,発,14:17#大西,発,14:22#伊予亀岡,発,14:27#菊間,発,14:32#浅海,発,14:39#大浦,発,14:43#伊予北条,発,14:50#柳原,発,14:53#粟井,発,14:56#光洋台,発,14:59#堀江,発,15:02#伊予和気,発,15:05#三津浜,発,15:09#松山,着,15:13#", | ||||
| "4537M":"観音寺,発,12:40#豊浜,発,12:45#箕浦,発,12:49#川之江,発,12:57#伊予三島,発,13:03#伊予寒川,発,13:08#赤星,発,13:12#伊予土居,発,13:18#関川,発,13:23#多喜浜,発,13:38#新居浜,発,13:42#中萩,発,13:47#伊予西条,着,13:53#", | ||||
| "4535M":"観音寺,発,11:40#豊浜,発,11:45#箕浦,発,11:49#川之江,発,11:56#伊予三島,発,12:04#伊予寒川,発,12:08#赤星,発,12:12#伊予土居,発,12:17#関川,発,12:22#多喜浜,発,12:37#新居浜,発,12:41#中萩,発,12:46#伊予西条,発,13:04#石鎚山,発,13:08#伊予氷見,発,13:11#伊予小松,発,13:16#玉之江,発,13:20#壬生川,発,13:38#伊予三芳,発,13:42#伊予桜井,発,13:50#伊予富田,発,13:54#今治,発,14:05#波止浜,発,14:09#波方,発,14:17#大西,発,14:22#伊予亀岡,発,14:27#菊間,発,14:32#浅海,発,14:39#大浦,発,14:43#伊予北条,発,14:50#柳原,発,14:53#粟井,発,14:56#光洋台,発,14:59#堀江,発,15:02#伊予和気,発,15:05#三津浜,発,15:09#松山,着,15:13#", | ||||
| "4537M":"観音寺,発,12:40#豊浜,発,12:46#箕浦,発,12:50#川之江,発,12:57#伊予三島,発,13:03#伊予寒川,発,13:08#赤星,発,13:12#伊予土居,発,13:18#関川,発,13:23#多喜浜,発,13:38#新居浜,発,13:42#中萩,発,13:47#伊予西条,着,13:53#", | ||||
| "4539M":"伊予北条,発,15:10#柳原,発,15:13#粟井,発,15:16#光洋台,発,15:19#堀江,発,15:23#伊予和気,発,15:34#三津浜,発,15:38#松山,着,15:42#", | ||||
| "4549M":"伊予北条,発,17:55#柳原,発,17:59#粟井,発,18:02#光洋台,発,18:05#堀江,発,18:09#伊予和気,発,18:12#三津浜,発,18:16#松山,着,18:21#", | ||||
| "4553M":"観音寺,発,16:21#豊浜,発,16:29#箕浦,発,16:34#川之江,発,16:40#伊予三島,発,17:04#伊予寒川,発,17:09#赤星,発,17:13#伊予土居,発,17:17#関川,発,17:21#多喜浜,発,17:28#新居浜,発,17:36#中萩,発,17:42#伊予西条,着,17:47#", | ||||
| @@ -256,7 +255,7 @@ | ||||
| "4623D":"松山,発,5:23#市坪,発,5:28#北伊予,発,5:32#南伊予,発,5:35#伊予横田,発,5:37#鳥ノ木,発,5:40#伊予市,発,5:43#向井原,発,5:47#伊予大平,発,5:51#伊予中山,発,6:17#伊予立川,発,6:28#内子,発,6:35#五十崎,発,6:37#喜多山,発,6:41#新谷,発,6:43#伊予大洲,発,6:50#西大洲,発,6:54#伊予平野,発,6:57#千丈,発,7:05#八幡浜,発,7:11#双岩,発,7:18#伊予石城,発,7:26#上宇和,発,7:30#卯之町,発,7:36#下宇和,発,7:39#立間,発,7:50#伊予吉田,発,7:54#高光,発,8:00#北宇和島,発,8:03#宇和島,着,8:06#", | ||||
| "4629M":"松山,発,8:18#市坪,発,8:23#北伊予,発,8:29#南伊予,発,8:32#伊予横田,発,8:34#鳥ノ木,発,8:37#伊予市,着,8:39#", | ||||
| "4631D":"松山,発,8:45#市坪,発,8:49#北伊予,発,9:02#南伊予,発,9:04#伊予横田,発,9:07#鳥ノ木,発,9:10#伊予市,発,9:19#向井原,発,9:22#伊予大平,発,9:27#伊予中山,発,9:36#伊予立川,発,9:52#内子,発,9:59#五十崎,発,10:02#喜多山,発,10:06#新谷,発,10:08#伊予大洲,発,10:23#西大洲,発,10:26#伊予平野,発,10:36#千丈,発,10:44#八幡浜,着,10:48#", | ||||
| "4633D":"松山,発,10:23#市坪,発,10:27#北伊予,発,10:31#南伊予,発,10:33#伊予横田,発,10:36#鳥ノ木,発,10:39#伊予市,発,10:41#向井原,発,10:45#伊予大平,発,10:49#伊予中山,発,11:02#伊予立川,発,11:09#内子,発,11:15#五十崎,発,11:18#喜多山,発,11:22#新谷,発,11:25#伊予大洲,着,11:31#", | ||||
| "4633D":"松山,発,10:24#市坪,発,10:28#北伊予,発,10:32#南伊予,発,10:34#伊予横田,発,10:37#鳥ノ木,発,10:40#伊予市,発,10:42#向井原,発,10:46#伊予大平,発,10:50#伊予中山,発,11:02#伊予立川,発,11:09#内子,発,11:15#五十崎,発,11:18#喜多山,発,11:22#新谷,発,11:25#伊予大洲,着,11:31#", | ||||
| "4635M":"伊予西条,発,10:29#石鎚山,発,10:32#伊予氷見,発,10:35#伊予小松,発,10:38#玉之江,発,10:41#壬生川,発,10:45#伊予三芳,発,10:49#伊予桜井,発,10:56#伊予富田,発,11:03#今治,発,11:08#波止浜,発,11:12#波方,発,11:16#大西,発,11:20#伊予亀岡,発,11:26#菊間,発,11:31#浅海,発,11:40#大浦,発,11:44#伊予北条,発,11:50#柳原,発,11:53#粟井,発,11:55#光洋台,発,11:58#堀江,発,12:05#伊予和気,発,12:08#三津浜,発,12:12#松山,発,12:44#市坪,発,12:49#北伊予,発,12:53#南伊予,発,12:56#伊予横田,発,12:58#鳥ノ木,発,13:01#伊予市,着,13:03#", | ||||
| "4637D":"伊予市,発,13:35#向井原,発,13:40#伊予大平,発,13:44#伊予中山,発,13:57#伊予立川,発,14:04#内子,発,14:10#五十崎,発,14:13#喜多山,発,14:17#新谷,発,14:19#伊予大洲,着,14:26#", | ||||
| "4639M":"松山,発,14:39#市坪,発,14:43#北伊予,発,14:46#南伊予,発,14:49#伊予横田,発,14:52#鳥ノ木,発,14:54#伊予市,着,14:57#", | ||||
| @@ -278,6 +277,7 @@ | ||||
| "4919D":"松山,発,13:02#市坪,発,13:07#北伊予,発,13:12#南伊予,発,13:15#伊予横田,発,13:18#鳥ノ木,発,13:21#伊予市,発,13:24#向井原,発,13:27#高野川,発,13:34#伊予上灘,発,13:38#下灘,発,13:45#串,発,13:49#喜多灘,発,13:53#伊予長浜,発,14:05#伊予出石,発,14:10#伊予白滝,発,14:15#八多喜,発,14:19#春賀,発,14:22#五郎,発,14:26#伊予大洲,発,14:44#西大洲,発,14:48#伊予平野,発,14:54#千丈,発,15:04#八幡浜,着,15:07#", | ||||
| "4921D":"伊予市,発,16:12#向井原,発,16:17#高野川,発,16:25#伊予上灘,発,16:30#下灘,発,16:38#串,発,16:42#喜多灘,発,16:46#伊予長浜,発,17:04#伊予出石,発,17:09#伊予白滝,発,17:22#八多喜,発,17:26#春賀,発,17:29#五郎,発,17:33#伊予大洲,発,17:41#西大洲,発,17:44#伊予平野,発,17:50#千丈,発,18:00#八幡浜,着,18:04#", | ||||
| "4927D":"松山,発,21:07#市坪,発,21:12#北伊予,発,21:16#南伊予,発,21:19#伊予横田,発,21:22#鳥ノ木,発,21:24#伊予市,発,21:33#向井原,発,21:37#高野川,発,21:45#伊予上灘,発,21:50#下灘,発,21:57#串,発,22:01#喜多灘,発,22:06#伊予長浜,発,22:14#伊予出石,発,22:19#伊予白滝,発,22:24#八多喜,発,22:28#春賀,発,22:31#五郎,発,22:35#伊予大洲,着,22:40#", | ||||
| "5101M":"伊予西条,発,8:01#石鎚山,発,8:05#伊予氷見,発,8:08#伊予小松,発,8:13#玉之江,発,8:17#壬生川,発,8:26#伊予三芳,発,8:30#伊予桜井,発,8:38#伊予富田,発,8:43#今治,発,8:51#波止浜,発,8:58#波方,発,9:02#大西,発,9:07#伊予亀岡,発,9:14#菊間,発,9:19#浅海,発,9:25#大浦,発,9:31#伊予北条,発,9:36#柳原,発,9:39#粟井,発,9:42#光洋台,発,9:45#堀江,発,9:49#伊予和気,発,9:52#三津浜,発,9:57#松山,着,10:01#", | ||||
| "5103M":"多度津,発,7:04#海岸寺,発,7:09#詫間,発,7:16#みの,発,7:19#高瀬,発,7:32#比地大,発,7:36#本山,発,7:39#観音寺,発,7:54#豊浜,発,7:59#箕浦,発,8:04#川之江,発,8:10#伊予三島,発,8:15#伊予寒川,発,8:20#赤星,発,8:24#伊予土居,発,8:28#関川,発,8:35#多喜浜,発,8:42#新居浜,発,8:47#中萩,発,8:54#伊予西条,着,9:00#", | ||||
| "5107M":"高松,発,6:52#香西,発,6:57#鬼無,発,7:00#端岡,発,7:04#国分,発,7:08#讃岐府中,発,7:11#鴨川,発,7:14#八十場,発,7:17#坂出,発,7:26#宇多津,発,7:32#丸亀,発,7:36#讃岐塩屋,発,7:39#多度津,発,7:44#海岸寺,発,7:48#詫間,発,7:54#みの,発,7:58#高瀬,発,8:02#比地大,発,8:06#本山,発,8:12#観音寺,着,8:16#", | ||||
| "5111M":"高松,発,9:04#端岡,発,9:12#坂出,発,9:22#宇多津,発,9:27#丸亀,発,9:31#讃岐塩屋,発,9:34#多度津,着,9:37#", | ||||
| @@ -286,10 +286,11 @@ | ||||
| "5121M":"高松,発,11:13#端岡,発,11:21#坂出,発,11:31#宇多津,発,11:36#丸亀,発,11:40#讃岐塩屋,発,11:43#多度津,着,11:46#", | ||||
| "5519M":"観音寺,発,6:03#豊浜,発,6:08#箕浦,発,6:13#川之江,発,6:19#伊予三島,発,6:30#伊予寒川,発,6:34#赤星,発,6:39#伊予土居,発,6:43#関川,発,6:47#多喜浜,発,6:56#新居浜,発,7:01#中萩,発,7:06#伊予西条,着,7:11#", | ||||
| "5531M":"観音寺,発,9:11#豊浜,発,9:16#箕浦,発,9:21#川之江,発,9:27#伊予三島,発,9:34#伊予寒川,発,9:38#赤星,発,9:42#伊予土居,発,9:46#関川,発,9:50#多喜浜,発,9:57#新居浜,発,10:01#中萩,発,10:06#伊予西条,着,10:12#", | ||||
| "5547M":"観音寺,発,15:49#豊浜,発,15:55#箕浦,発,16:02#川之江,発,16:08#伊予三島,発,16:14#伊予寒川,発,16:18#赤星,発,16:22#伊予土居,発,16:26#関川,発,16:30#多喜浜,発,16:40#新居浜,発,16:44#中萩,発,16:50#伊予西条,着,16:56#", | ||||
| "5547M":"観音寺,発,15:49#豊浜,発,15:55#箕浦,発,16:03#川之江,発,16:08#伊予三島,発,16:14#伊予寒川,発,16:18#赤星,発,16:23#伊予土居,発,16:26#関川,発,16:30#多喜浜,発,16:40#新居浜,発,16:44#中萩,発,16:50#伊予西条,着,16:56#", | ||||
| "5629M":"今治,発,6:49#波止浜,発,6:55#波方,発,6:58#大西,発,7:03#伊予亀岡,発,7:09#菊間,発,7:14#浅海,発,7:21#大浦,発,7:26#伊予北条,発,7:34#柳原,発,7:37#粟井,発,7:41#光洋台,発,7:44#堀江,発,7:53#伊予和気,発,8:00#三津浜,発,8:04#松山,着,8:08#", | ||||
| "6109M":"高松,発,7:40#香西,発,7:45#鬼無,発,7:48#端岡,発,7:56#国分,発,7:59#讃岐府中,発,8:02#鴨川,発,8:05#八十場,発,8:08#坂出,発,8:11#宇多津,発,8:21#丸亀,発,8:25#讃岐塩屋,発,8:27#多度津,発,8:31#海岸寺,発,8:36#詫間,発,8:46#みの,発,8:49#高瀬,発,8:53#比地大,発,8:56#本山,発,9:03#観音寺,着,9:06#", | ||||
| "8901D":"松山,発,8:26#市坪,発,8:33#伊予市,発,8:44#下灘,発,9:26#喜多灘,発,9:42#伊予大洲,着,10:28#", | ||||
| "8903D":"松山,発,13:31#北伊予,発,13:42#下灘,発,14:22#喜多灘,発,14:38#伊予大洲,発,15:13#伊予平野,発,15:37#八幡浜,着,15:50#", | ||||
| "8091D":"松山,発,8:26#市坪,発,8:33#伊予市,発,8:44#下灘,発,9:26#喜多灘,発,9:42#伊予大洲,着,10:28#", | ||||
| "8093D":"松山,発,13:31#北伊予,発,13:42#下灘,発,14:22#喜多灘,発,14:38#伊予大洲,発,15:13#伊予平野,発,15:37#八幡浜,着,15:50#", | ||||
| "3102M":"高松,発,4:35#鬼無,発,4:40#端岡,発,4:44#国分,発,4:47#鴨川,発,4:51#坂出,発,4:56#児島,発,5:15#上の町,発,5:18#木見,発,5:22#植松,発,5:25#茶屋町,発,5:28#早島,発,5:32#妹尾,発,5:35#備前西市,発,5:39#大元,発,5:42#岡山,着,5:45#", | ||||
| "3104M":"高松,発,5:35#坂出,発,5:49#児島,発,6:05#茶屋町,発,6:14#妹尾,発,6:20#大元,発,6:25#岡山,着,6:28#", | ||||
| "3106M":"高松,発,6:08#坂出,発,6:22#児島,発,6:38#茶屋町,発,6:47#早島,発,6:50#妹尾,発,6:54#大元,発,7:01#岡山,着,7:04#", | ||||
| @@ -301,24 +302,24 @@ | ||||
| "3118M":"高松,発,9:23#坂出,発,9:38#児島,発,9:54#茶屋町,発,10:03#妹尾,発,10:10#岡山,着,10:17#", | ||||
| "3120M":"高松,発,9:52#坂出,発,10:07#児島,発,10:23#茶屋町,発,10:33#早島,発,10:37#岡山,着,10:48#", | ||||
| "3122M":"高松,発,10:10#坂出,発,10:24#児島,発,10:40#茶屋町,発,10:49#妹尾,発,10:56#岡山,着,11:03#", | ||||
| "3124M":"高松,発,10:40#坂出,発,10:54#児島,発,11:11#茶屋町,発,11:19#早島,発,11:23#岡山,着,11:33#", | ||||
| "3124M":"高松,発,10:40#坂出,発,10:54#児島,発,11:11#茶屋町,発,11:19#早島,発,11:23#岡山,着,11:32#", | ||||
| "3126M":"高松,発,11:10#坂出,発,11:24#児島,発,11:40#茶屋町,発,11:49#妹尾,発,11:55#岡山,着,12:02#", | ||||
| "3128M":"高松,発,11:40#坂出,発,11:54#児島,発,12:10#茶屋町,発,12:19#早島,発,12:22#岡山,着,12:32#", | ||||
| "3128M":"高松,発,11:40#坂出,発,11:54#児島,発,12:10#茶屋町,発,12:19#早島,発,12:23#岡山,着,12:32#", | ||||
| "3130M":"高松,発,12:10#坂出,発,12:24#児島,発,12:40#茶屋町,発,12:49#妹尾,発,12:55#岡山,着,13:02#", | ||||
| "3132M":"高松,発,12:40#坂出,発,12:54#児島,発,13:10#茶屋町,発,13:19#早島,発,13:22#岡山,着,13:32#", | ||||
| "3132M":"高松,発,12:40#坂出,発,12:54#児島,発,13:10#茶屋町,発,13:19#早島,発,13:23#岡山,着,13:32#", | ||||
| "3134M":"高松,発,13:10#坂出,発,13:24#児島,発,13:40#茶屋町,発,13:49#妹尾,発,13:55#岡山,着,14:02#", | ||||
| "3136M":"高松,発,13:40#坂出,発,13:54#児島,発,14:11#茶屋町,発,14:20#早島,発,14:24#岡山,着,14:34#", | ||||
| "3136M":"高松,発,13:40#坂出,発,13:54#児島,発,14:11#茶屋町,発,14:19#早島,発,14:23#岡山,着,14:34#", | ||||
| "3138M":"高松,発,14:10#坂出,発,14:24#児島,発,14:40#茶屋町,発,14:49#妹尾,発,14:55#岡山,着,15:02#", | ||||
| "3140M":"高松,発,14:40#坂出,発,14:54#児島,発,15:10#茶屋町,発,15:19#早島,発,15:22#岡山,着,15:32#", | ||||
| "3142M":"高松,発,15:10#坂出,発,15:24#児島,発,15:40#茶屋町,発,15:49#妹尾,発,15:56#岡山,着,16:03#", | ||||
| "3144M":"高松,発,15:40#坂出,発,15:54#児島,発,16:10#茶屋町,発,16:19#早島,発,16:22#岡山,着,16:32#", | ||||
| "3146M":"高松,発,16:10#坂出,発,16:24#児島,発,16:40#茶屋町,発,16:49#妹尾,発,16:56#岡山,着,17:03#", | ||||
| "3148M":"高松,発,16:40#坂出,発,16:54#児島,発,17:10#茶屋町,発,17:19#早島,発,17:22#岡山,着,17:32#", | ||||
| "3150M":"高松,発,17:10#坂出,発,17:24#児島,発,17:40#茶屋町,発,17:49#妹尾,発,17:56#岡山,着,18:03#", | ||||
| "3152M":"高松,発,17:40#坂出,発,17:54#児島,発,18:10#茶屋町,発,18:19#早島,発,18:23#岡山,着,18:32#", | ||||
| "3140M":"高松,発,14:40#坂出,発,14:54#児島,発,15:10#茶屋町,発,15:19#早島,発,15:23#岡山,着,15:32#", | ||||
| "3142M":"高松,発,15:10#坂出,発,15:24#児島,発,15:40#茶屋町,発,15:49#妹尾,発,15:55#岡山,着,16:03#", | ||||
| "3144M":"高松,発,15:40#坂出,発,15:54#児島,発,16:10#茶屋町,発,16:19#早島,発,16:23#岡山,着,16:32#", | ||||
| "3146M":"高松,発,16:10#坂出,発,16:24#児島,発,16:40#茶屋町,発,16:49#妹尾,発,16:55#岡山,着,17:03#", | ||||
| "3148M":"高松,発,16:40#坂出,発,16:54#児島,発,17:10#茶屋町,発,17:19#早島,発,17:23#岡山,着,17:32#", | ||||
| "3150M":"高松,発,17:10#坂出,発,17:24#児島,発,17:40#茶屋町,発,17:49#妹尾,発,17:55#岡山,着,18:03#", | ||||
| "3152M":"高松,発,17:40#坂出,発,17:55#児島,発,18:11#茶屋町,発,18:19#早島,発,18:23#岡山,着,18:32#", | ||||
| "3154M":"高松,発,18:10#坂出,発,18:24#児島,発,18:40#茶屋町,発,18:49#妹尾,発,18:56#岡山,着,19:03#", | ||||
| "3156M":"高松,発,18:40#坂出,発,18:55#児島,発,19:11#茶屋町,発,19:19#早島,発,19:23#岡山,着,19:33#", | ||||
| "3158M":"高松,発,19:10#坂出,発,19:25#児島,発,19:41#茶屋町,発,19:49#妹尾,発,19:56#岡山,着,20:03#", | ||||
| "3158M":"高松,発,19:10#坂出,発,19:25#児島,発,19:41#茶屋町,発,19:49#妹尾,発,19:55#岡山,着,20:03#", | ||||
| "3160M":"高松,発,19:40#坂出,発,19:54#児島,発,20:10#茶屋町,発,20:19#早島,発,20:23#岡山,着,20:35#", | ||||
| "3162M":"高松,発,20:10#坂出,発,20:24#児島,発,20:40#茶屋町,発,20:51#妹尾,発,20:58#岡山,着,21:05#", | ||||
| "3164M":"高松,発,20:43#坂出,発,20:57#児島,発,21:13#茶屋町,発,21:22#早島,発,21:25#岡山,着,21:36#", | ||||
| @@ -329,7 +330,7 @@ | ||||
| "5022D":"徳島,発,16:45#池谷,発,16:54#板野,発,17:00#三本松,発,17:16#志度,発,17:31#栗林,発,17:39#高松,発,17:47#宇多津,着,18:03#", | ||||
| "5032M":"高松,発,21:26#坂出,発,21:44#児島,発,22:01#岡山,着,22:23#", | ||||
| "8176D":"高松,発,9:13#端岡,発,9:24#鴨川,発,9:36#坂出,発,9:43#児島,発,10:15#岡山,着,10:44#", | ||||
| "3101M":"岡山,発,5:27#大元,発,5:30#妹尾,発,5:36#早島,発,5:39#茶屋町,発,5:43#植松,発,5:46#木見,発,5:49#上の町,発,5:52#児島,発,5:57#坂出,発,6:13#高松,着,6:31#", | ||||
| "3101M":"岡山,発,5:27#大元,発,5:30#妹尾,発,5:35#早島,発,5:39#茶屋町,発,5:42#植松,発,5:45#木見,発,5:48#上の町,発,5:52#児島,発,5:57#坂出,発,6:13#高松,着,6:31#", | ||||
| "3103M":"岡山,発,6:01#妹尾,発,6:08#茶屋町,発,6:14#児島,発,6:24#坂出,発,6:39#高松,着,6:56#", | ||||
| "3105M":"岡山,発,6:37#妹尾,発,6:46#早島,発,6:49#茶屋町,発,6:53#児島,発,7:02#坂出,発,7:18#高松,着,7:33#", | ||||
| "3107M":"岡山,発,7:10#大元,発,7:13#妹尾,発,7:19#早島,発,7:23#茶屋町,発,7:26#児島,発,7:35#坂出,発,7:52#高松,着,8:07#", | ||||
| @@ -341,28 +342,28 @@ | ||||
| "3119M":"岡山,発,9:54#早島,発,10:05#茶屋町,発,10:09#児島,発,10:20#坂出,発,10:36#高松,着,10:51#", | ||||
| "3121M":"岡山,発,10:23#妹尾,発,10:33#茶屋町,発,10:39#児島,発,10:48#坂出,発,11:03#高松,着,11:18#", | ||||
| "3123M":"岡山,発,10:53#早島,発,11:06#茶屋町,発,11:10#児島,発,11:19#坂出,発,11:35#高松,着,11:49#", | ||||
| "3125M":"岡山,発,11:12#妹尾,発,11:21#茶屋町,発,11:27#児島,発,11:36#坂出,発,11:53#高松,着,12:07#", | ||||
| "3125M":"岡山,発,11:12#妹尾,発,11:20#茶屋町,発,11:26#児島,発,11:36#坂出,発,11:53#高松,着,12:07#", | ||||
| "3127M":"岡山,発,11:42#早島,発,11:52#茶屋町,発,11:55#児島,発,12:05#坂出,発,12:20#高松,着,12:36#", | ||||
| "3129M":"岡山,発,12:12#妹尾,発,12:20#茶屋町,発,12:26#児島,発,12:35#坂出,発,12:50#高松,着,13:05#", | ||||
| "3129M":"岡山,発,12:13#妹尾,発,12:20#茶屋町,発,12:26#児島,発,12:35#坂出,発,12:51#高松,着,13:05#", | ||||
| "3131M":"岡山,発,12:42#早島,発,12:52#茶屋町,発,12:55#児島,発,13:05#坂出,発,13:20#高松,着,13:36#", | ||||
| "3133M":"岡山,発,13:12#妹尾,発,13:20#茶屋町,発,13:26#児島,発,13:35#坂出,発,13:50#高松,着,14:05#", | ||||
| "3133M":"岡山,発,13:13#妹尾,発,13:20#茶屋町,発,13:26#児島,発,13:35#坂出,発,13:51#高松,着,14:05#", | ||||
| "3135M":"岡山,発,13:42#早島,発,13:52#茶屋町,発,13:55#児島,発,14:05#坂出,発,14:20#高松,着,14:36#", | ||||
| "3137M":"岡山,発,14:12#妹尾,発,14:20#茶屋町,発,14:26#児島,発,14:35#坂出,発,14:50#高松,着,15:05#", | ||||
| "3137M":"岡山,発,14:13#妹尾,発,14:20#茶屋町,発,14:26#児島,発,14:35#坂出,発,14:51#高松,着,15:05#", | ||||
| "3139M":"岡山,発,14:42#早島,発,14:52#茶屋町,発,14:56#児島,発,15:05#坂出,発,15:20#高松,着,15:36#", | ||||
| "3141M":"岡山,発,15:12#妹尾,発,15:19#茶屋町,発,15:25#児島,発,15:34#坂出,発,15:50#高松,着,16:04#", | ||||
| "3143M":"岡山,発,15:42#妹尾,発,15:50#早島,発,15:53#茶屋町,発,15:57#児島,発,16:06#坂出,発,16:21#高松,着,16:36#", | ||||
| "3145M":"岡山,発,16:12#妹尾,発,16:20#茶屋町,発,16:26#児島,発,16:35#坂出,発,16:50#高松,着,17:05#", | ||||
| "3147M":"岡山,発,16:42#妹尾,発,16:50#早島,発,16:53#茶屋町,発,16:57#児島,発,17:06#坂出,発,17:22#高松,着,17:37#", | ||||
| "3149M":"岡山,発,17:12#妹尾,発,17:20#茶屋町,発,17:26#児島,発,17:35#坂出,発,17:50#高松,着,18:06#", | ||||
| "3151M":"岡山,発,17:42#妹尾,発,17:50#早島,発,17:53#茶屋町,発,17:57#児島,発,18:06#坂出,発,18:25#高松,着,18:41#", | ||||
| "3153M":"岡山,発,18:12#妹尾,発,18:20#茶屋町,発,18:26#児島,発,18:36#坂出,発,18:51#高松,着,19:06#", | ||||
| "3141M":"岡山,発,15:13#妹尾,発,15:20#茶屋町,発,15:26#児島,発,15:35#坂出,発,15:51#高松,着,16:06#", | ||||
| "3143M":"岡山,発,15:42#妹尾,発,15:49#早島,発,15:53#茶屋町,発,15:57#児島,発,16:06#坂出,発,16:21#高松,着,16:36#", | ||||
| "3145M":"岡山,発,16:13#妹尾,発,16:20#茶屋町,発,16:26#児島,発,16:35#坂出,発,16:51#高松,着,17:06#", | ||||
| "3147M":"岡山,発,16:42#妹尾,発,16:49#早島,発,16:53#茶屋町,発,16:57#児島,発,17:06#坂出,発,17:22#高松,着,17:37#", | ||||
| "3149M":"岡山,発,17:13#妹尾,発,17:20#茶屋町,発,17:26#児島,発,17:35#坂出,発,17:51#高松,着,18:06#", | ||||
| "3151M":"岡山,発,17:42#妹尾,発,17:49#早島,発,17:53#茶屋町,発,17:57#児島,発,18:06#坂出,発,18:25#高松,着,18:41#", | ||||
| "3153M":"岡山,発,18:13#妹尾,発,18:20#茶屋町,発,18:26#児島,発,18:36#坂出,発,18:51#高松,着,19:06#", | ||||
| "3155M":"岡山,発,18:41#妹尾,発,18:49#早島,発,18:53#茶屋町,発,18:57#児島,発,19:06#坂出,発,19:22#高松,着,19:38#", | ||||
| "3157M":"岡山,発,19:12#妹尾,発,19:20#早島,発,19:24#茶屋町,発,19:27#児島,発,19:37#坂出,発,19:53#高松,着,20:07#", | ||||
| "3159M":"岡山,発,19:42#妹尾,発,19:50#早島,発,19:53#茶屋町,発,19:57#児島,発,20:06#坂出,発,20:21#高松,着,20:37#", | ||||
| "3157M":"岡山,発,19:13#妹尾,発,19:20#早島,発,19:24#茶屋町,発,19:27#児島,発,19:37#坂出,発,19:53#高松,着,20:07#", | ||||
| "3159M":"岡山,発,19:42#妹尾,発,19:49#早島,発,19:53#茶屋町,発,19:57#児島,発,20:06#坂出,発,20:21#高松,着,20:37#", | ||||
| "3161M":"岡山,発,20:13#妹尾,発,20:21#茶屋町,発,20:27#児島,発,20:36#坂出,発,20:52#高松,着,21:07#", | ||||
| "3163M":"岡山,発,20:42#妹尾,発,20:52#早島,発,20:56#茶屋町,発,20:59#児島,発,21:08#坂出,発,21:24#高松,着,21:39#", | ||||
| "3165M":"岡山,発,21:12#妹尾,発,21:22#茶屋町,発,21:28#児島,発,21:38#坂出,発,21:53#高松,着,22:08#", | ||||
| "3167M":"岡山,発,21:42#妹尾,発,21:52#早島,発,21:56#茶屋町,発,22:00#児島,発,22:09#坂出,発,22:24#高松,着,22:39#", | ||||
| "3165M":"岡山,発,21:13#妹尾,発,21:23#茶屋町,発,21:28#児島,発,21:38#坂出,発,21:53#高松,着,22:08#", | ||||
| "3167M":"岡山,発,21:42#妹尾,発,21:52#早島,発,21:56#茶屋町,発,21:59#児島,発,22:09#坂出,発,22:24#高松,着,22:39#", | ||||
| "3169M":"岡山,発,22:12#妹尾,発,22:23#早島,発,22:27#茶屋町,発,22:30#児島,発,22:40#坂出,発,22:55#高松,着,23:10#", | ||||
| "3171M":"岡山,発,22:46#妹尾,発,22:53#早島,発,22:57#茶屋町,発,23:00#上の町,発,23:07#児島,発,23:11#坂出,発,23:27#高松,着,23:41#", | ||||
| "3173M":"岡山,発,23:12#大元,発,23:16#妹尾,発,23:22#早島,発,23:25#茶屋町,発,23:29#植松,発,23:32#木見,発,23:35#上の町,発,23:39#児島,発,23:43#坂出,発,23:59#鴨川,発,0:04#国分,発,0:08#端岡,発,0:11#鬼無,発,0:15#高松,着,0:20#", | ||||
| @@ -378,18 +379,18 @@ | ||||
| "8M":"松山,発,7:20#伊予北条,発,7:32#今治,発,7:57#壬生川,発,8:09#伊予西条,発,8:18#新居浜,発,8:26#伊予三島,発,8:44#川之江,発,8:48#観音寺,発,8:59#詫間,発,9:08#多度津,発,9:16#丸亀,発,9:20#宇多津,発,9:26#児島,発,9:40#岡山,着,10:00#", | ||||
| "10M":"松山,発,8:10#伊予北条,発,8:23#今治,発,8:47#壬生川,発,9:00#伊予西条,発,9:09#新居浜,発,9:17#伊予三島,発,9:34#川之江,発,9:38#観音寺,発,9:53#多度津,発,10:09#丸亀,発,10:14#宇多津,発,10:20#児島,発,10:34#岡山,着,10:58#", | ||||
| "12M":"松山,発,9:15#伊予北条,発,9:28#今治,発,9:57#壬生川,発,10:10#伊予西条,発,10:19#新居浜,発,10:27#伊予三島,発,10:46#川之江,発,10:53#観音寺,発,11:04#多度津,発,11:21#丸亀,発,11:26#宇多津,発,11:34#児島,発,11:50#岡山,着,12:10#", | ||||
| "14M":"松山,発,10:21#今治,発,10:59#壬生川,発,11:12#伊予西条,発,11:24#新居浜,発,11:32#伊予三島,発,11:51#川之江,発,11:56#観音寺,発,12:06#多度津,発,12:22#丸亀,発,12:27#宇多津,発,12:34#児島,発,12:49#岡山,着,13:10#", | ||||
| "14M":"松山,発,10:21#今治,発,10:59#壬生川,発,11:12#伊予西条,発,11:24#新居浜,発,11:32#伊予三島,発,11:52#川之江,発,11:56#観音寺,発,12:07#多度津,発,12:22#丸亀,発,12:27#宇多津,発,12:34#児島,発,12:49#岡山,着,13:10#", | ||||
| "16M":"松山,発,11:23#今治,発,12:02#壬生川,発,12:15#伊予西条,発,12:26#新居浜,発,12:33#伊予三島,発,12:52#川之江,発,12:57#観音寺,発,13:07#多度津,発,13:23#丸亀,発,13:28#宇多津,発,13:35#児島,発,13:50#岡山,着,14:10#", | ||||
| "18M":"松山,発,12:21#今治,発,12:59#壬生川,発,13:12#伊予西条,発,13:25#新居浜,発,13:33#伊予三島,発,13:53#川之江,発,13:57#観音寺,発,14:08#多度津,発,14:23#丸亀,発,14:28#宇多津,発,14:35#児島,発,14:50#岡山,着,15:11#", | ||||
| "18M":"松山,発,12:21#今治,発,12:59#壬生川,発,13:12#伊予西条,発,13:25#新居浜,発,13:33#伊予三島,発,13:53#川之江,発,13:57#観音寺,発,14:08#多度津,発,14:24#丸亀,発,14:28#宇多津,発,14:35#児島,発,14:50#岡山,着,15:11#", | ||||
| "20M":"松山,発,13:26#今治,発,14:05#壬生川,発,14:18#伊予西条,発,14:26#新居浜,発,14:34#伊予三島,発,14:53#川之江,発,14:58#観音寺,発,15:08#多度津,発,15:24#丸亀,発,15:29#宇多津,発,15:35#児島,発,15:50#岡山,着,16:11#", | ||||
| "22M":"松山,発,14:23#今治,発,15:01#壬生川,発,15:14#伊予西条,発,15:26#新居浜,発,15:34#伊予三島,発,15:54#川之江,発,15:58#観音寺,発,16:09#多度津,発,16:24#丸亀,発,16:29#宇多津,発,16:35#児島,発,16:50#岡山,着,17:11#", | ||||
| "22M":"松山,発,14:23#今治,発,15:01#壬生川,発,15:14#伊予西条,発,15:26#新居浜,発,15:34#伊予三島,発,15:54#川之江,発,15:58#観音寺,発,16:09#多度津,発,16:25#丸亀,発,16:29#宇多津,発,16:35#児島,発,16:50#岡山,着,17:11#", | ||||
| "24M":"松山,発,15:28#今治,発,16:06#壬生川,発,16:19#伊予西条,発,16:28#新居浜,発,16:36#伊予三島,発,16:55#川之江,発,16:59#観音寺,発,17:10#多度津,発,17:26#丸亀,発,17:30#宇多津,発,17:36#児島,発,17:50#岡山,着,18:11#", | ||||
| "26M":"松山,発,16:27#伊予北条,発,16:39#今治,発,17:04#壬生川,発,17:18#伊予西条,発,17:28#新居浜,発,17:36#伊予三島,発,17:55#川之江,発,18:00#観音寺,発,18:11#多度津,発,18:26#丸亀,発,18:31#宇多津,発,18:37#児島,発,18:51#岡山,着,19:11#", | ||||
| "28M":"松山,発,17:37#伊予北条,発,17:49#今治,発,18:13#壬生川,発,18:25#伊予西条,発,18:34#新居浜,発,18:42#伊予三島,発,18:59#川之江,発,19:03#観音寺,発,19:14#多度津,発,19:29#丸亀,発,19:33#宇多津,発,19:39#児島,発,19:53#岡山,着,20:12#", | ||||
| "30M":"松山,発,18:39#伊予北条,発,18:51#今治,発,19:19#壬生川,発,19:34#伊予西条,発,19:43#新居浜,発,19:51#伊予三島,発,20:07#川之江,発,20:12#観音寺,発,20:23#高瀬,発,20:30#詫間,発,20:35#多度津,発,20:43#丸亀,発,20:47#宇多津,発,20:53#児島,発,21:07#岡山,着,21:29#", | ||||
| "32D":"高知,発,6:00#後免,発,6:07#土佐山田,発,6:12#大杉,発,6:31#大歩危,発,6:48#阿波池田,発,7:09#琴平,発,7:33#善通寺,発,7:37#多度津,発,7:49#丸亀,発,7:54#宇多津,発,7:58#児島,発,8:14#岡山,着,8:38#", | ||||
| "34D":"高知,発,7:00#後免,発,7:07#土佐山田,発,7:12#大杉,発,7:32#大歩危,発,7:52#阿波池田,発,8:13#琴平,発,8:40#善通寺,発,8:45#多度津,発,8:50#丸亀,発,8:55#宇多津,発,9:01#児島,発,9:15#岡山,着,9:38#", | ||||
| "36D":"高知,発,8:01#後免,発,8:09#土佐山田,発,8:14#大歩危,発,8:49#阿波池田,発,9:07#琴平,発,9:35#善通寺,発,9:39#多度津,発,9:44#丸亀,発,9:48#宇多津,発,9:58#児島,発,10:12#岡山,着,10:33#", | ||||
| "36D":"高知,発,8:01#後免,発,8:09#土佐山田,発,8:14#大歩危,発,8:49#阿波池田,発,9:07#琴平,発,9:34#善通寺,発,9:39#多度津,発,9:44#丸亀,発,9:48#宇多津,発,9:58#児島,発,10:12#岡山,着,10:33#", | ||||
| "38D":"高知,発,9:13#後免,発,9:20#土佐山田,発,9:27#大歩危,発,10:02#阿波池田,発,10:20#琴平,発,10:44#善通寺,発,10:49#多度津,発,10:57#丸亀,発,11:01#宇多津,発,11:05#児島,発,11:20#岡山,着,11:40#", | ||||
| "40D":"高知,発,10:13#後免,発,10:20#土佐山田,発,10:25#大杉,発,10:45#大歩危,発,11:04#阿波池田,発,11:23#琴平,発,11:46#善通寺,発,11:51#多度津,発,11:56#丸亀,発,12:00#宇多津,発,12:04#児島,発,12:19#岡山,着,12:40#", | ||||
| "42D":"高知,発,11:13#後免,発,11:22#土佐山田,発,11:27#大歩危,発,12:05#阿波池田,発,12:23#琴平,発,12:47#善通寺,発,12:53#多度津,発,12:58#丸亀,発,13:02#宇多津,発,13:06#児島,発,13:20#岡山,着,13:40#", | ||||
| @@ -405,11 +406,11 @@ | ||||
| "1M":"岡山,発,7:22#児島,発,7:42#宇多津,発,8:01#丸亀,発,8:04#多度津,発,8:09#詫間,発,8:16#観音寺,発,8:27#川之江,発,8:37#伊予三島,発,8:44#新居浜,発,9:01#伊予西条,発,9:09#壬生川,発,9:18#今治,発,9:30#伊予北条,発,9:54#松山,着,10:06#", | ||||
| "3M":"岡山,発,8:32#児島,発,8:54#宇多津,発,9:13#丸亀,発,9:16#多度津,発,9:21#詫間,発,9:28#観音寺,発,9:38#川之江,発,9:49#伊予三島,発,9:54#新居浜,発,10:11#伊予西条,発,10:19#壬生川,発,10:28#今治,発,10:41#松山,着,11:15#", | ||||
| "5M":"岡山,発,9:25#児島,発,9:47#宇多津,発,10:06#丸亀,発,10:10#多度津,発,10:15#観音寺,発,10:31#川之江,発,10:41#伊予三島,発,10:46#新居浜,発,11:03#伊予西条,発,11:11#壬生川,発,11:22#今治,発,11:36#松山,着,12:10#", | ||||
| "7M":"岡山,発,10:35#児島,発,10:54#宇多津,発,11:13#丸亀,発,11:16#多度津,発,11:21#観音寺,発,11:36#川之江,発,11:47#伊予三島,発,11:51#新居浜,発,12:09#伊予西条,発,12:17#壬生川,発,12:28#今治,発,12:41#松山,着,13:15#", | ||||
| "9M":"岡山,発,11:35#児島,発,11:54#宇多津,発,12:13#丸亀,発,12:17#多度津,発,12:22#観音寺,発,12:37#川之江,発,12:47#伊予三島,発,12:52#新居浜,発,13:10#伊予西条,発,13:18#壬生川,発,13:26#今治,発,13:39#松山,着,14:13#", | ||||
| "11M":"岡山,発,12:35#児島,発,12:54#宇多津,発,13:14#丸亀,発,13:17#多度津,発,13:22#観音寺,発,13:38#川之江,発,13:48#伊予三島,発,13:52#新居浜,発,14:09#伊予西条,発,14:17#壬生川,発,14:30#今治,発,14:43#松山,着,15:17#", | ||||
| "13M":"岡山,発,13:35#児島,発,13:54#宇多津,発,14:14#丸亀,発,14:18#多度津,発,14:23#観音寺,発,14:38#川之江,発,14:48#伊予三島,発,14:53#新居浜,発,15:10#伊予西条,発,15:19#壬生川,発,15:28#今治,発,15:41#伊予北条,発,16:04#松山,着,16:16#", | ||||
| "15M":"岡山,発,14:35#児島,発,14:56#宇多津,発,15:15#丸亀,発,15:19#多度津,発,15:23#観音寺,発,15:39#川之江,発,15:49#伊予三島,発,15:53#新居浜,発,16:11#伊予西条,発,16:19#壬生川,発,16:31#今治,発,16:44#伊予北条,発,17:11#松山,着,17:23#", | ||||
| "7M":"岡山,発,10:35#児島,発,10:55#宇多津,発,11:13#丸亀,発,11:17#多度津,発,11:21#観音寺,発,11:37#川之江,発,11:47#伊予三島,発,11:52#新居浜,発,12:09#伊予西条,発,12:17#壬生川,発,12:28#今治,発,12:41#松山,着,13:15#", | ||||
| "9M":"岡山,発,11:35#児島,発,11:55#宇多津,発,12:14#丸亀,発,12:17#多度津,発,12:22#観音寺,発,12:37#川之江,発,12:48#伊予三島,発,12:52#新居浜,発,13:10#伊予西条,発,13:18#壬生川,発,13:26#今治,発,13:39#松山,着,14:13#", | ||||
| "11M":"岡山,発,12:35#児島,発,12:55#宇多津,発,13:14#丸亀,発,13:18#多度津,発,13:23#観音寺,発,13:38#川之江,発,13:48#伊予三島,発,13:53#新居浜,発,14:10#伊予西条,発,14:17#壬生川,発,14:30#今治,発,14:43#松山,着,15:17#", | ||||
| "13M":"岡山,発,13:35#児島,発,13:55#宇多津,発,14:14#丸亀,発,14:18#多度津,発,14:23#観音寺,発,14:38#川之江,発,14:49#伊予三島,発,14:53#新居浜,発,15:10#伊予西条,発,15:19#壬生川,発,15:28#今治,発,15:41#伊予北条,発,16:04#松山,着,16:16#", | ||||
| "15M":"岡山,発,14:35#児島,発,14:56#宇多津,発,15:15#丸亀,発,15:19#多度津,発,15:24#観音寺,発,15:39#川之江,発,15:49#伊予三島,発,15:54#新居浜,発,16:11#伊予西条,発,16:19#壬生川,発,16:31#今治,発,16:44#伊予北条,発,17:11#松山,着,17:23#", | ||||
| "17M":"岡山,発,15:35#児島,発,15:55#宇多津,発,16:15#丸亀,発,16:19#多度津,発,16:24#観音寺,発,16:40#川之江,発,16:50#伊予三島,発,16:55#新居浜,発,17:13#伊予西条,発,17:21#壬生川,発,17:32#今治,発,17:45#伊予北条,発,18:13#松山,着,18:26#", | ||||
| "19M":"岡山,発,16:35#児島,発,16:55#宇多津,発,17:15#丸亀,発,17:18#多度津,発,17:25#観音寺,発,17:40#川之江,発,17:51#伊予三島,発,17:55#新居浜,発,18:13#伊予西条,発,18:21#壬生川,発,18:34#今治,発,18:47#伊予北条,発,19:11#松山,着,19:23#", | ||||
| "21M":"岡山,発,17:35#児島,発,17:55#宇多津,発,18:09#丸亀,発,18:13#多度津,発,18:26#観音寺,発,18:42#川之江,発,18:52#伊予三島,発,18:58#新居浜,発,19:15#伊予西条,発,19:24#壬生川,発,19:33#今治,発,19:48#伊予北条,発,20:16#松山,着,20:28#", | ||||
| @@ -431,32 +432,33 @@ | ||||
| "53D":"岡山,発,19:05#児島,発,19:27#宇多津,発,19:43#丸亀,発,19:46#多度津,発,19:51#善通寺,発,19:57#琴平,発,20:03#阿波池田,発,20:29#大歩危,発,20:52#大杉,発,21:10#土佐山田,発,21:31#後免,発,21:36#高知,着,21:44#", | ||||
| "55D":"岡山,発,20:05#児島,発,20:29#宇多津,発,20:45#丸亀,発,20:49#多度津,発,20:59#善通寺,発,21:09#琴平,発,21:14#阿波池田,発,21:38#大歩危,発,21:58#大杉,発,22:15#土佐山田,発,22:34#後免,発,22:39#高知,着,22:47#", | ||||
| "57D":"岡山,発,21:39#児島,発,21:59#宇多津,発,22:13#丸亀,発,22:17#多度津,発,22:23#善通寺,発,22:29#琴平,発,22:34#阿波池田,発,22:58#大歩危,発,23:16#大杉,発,23:34#土佐山田,発,23:54#後免,発,23:59#高知,着,0:06#", | ||||
| "8277D":"岡山,発,11:18#児島,発,12:10#宇多津,発,12:30#多度津,発,12:41#琴平,着,13:09#", | ||||
| "8277D":"岡山,発,11:17#児島,発,12:10#宇多津,発,12:30#多度津,発,12:41#琴平,着,13:09#", | ||||
| "3812D":"宇和島,発,7:24#北宇和島,発,7:28#務田,発,7:40#伊予宮野下,発,7:45#二名,発,7:49#大内,発,7:52#深田,発,7:57#近永,着,8:01#", | ||||
| "4810D":"宇和島,発,6:04#北宇和島,発,6:07#務田,発,6:21#伊予宮野下,発,6:23#二名,発,6:27#大内,発,6:31#深田,発,6:36#近永,発,6:40#出目,発,6:43#松丸,発,6:50#吉野生,発,6:56#真土,発,7:00#西ケ方,発,7:08#江川崎,発,7:15#半家,発,7:20#十川,発,7:28#土佐昭和,発,7:33#土佐大正,発,7:42#打井川,発,7:50#家地川,発,7:56#若井,発,8:04#窪川,着,8:09#", | ||||
| "4816D":"宇和島,発,12:18#北宇和島,発,12:21#務田,発,12:33#伊予宮野下,発,12:36#二名,発,12:40#大内,発,12:43#深田,発,12:48#近永,発,12:52#出目,発,12:56#松丸,発,13:02#吉野生,発,13:07#真土,発,13:10#西ケ方,発,13:19#江川崎,発,13:27#半家,発,13:31#十川,発,13:39#土佐昭和,発,13:45#土佐大正,発,13:56#打井川,発,14:03#家地川,発,14:09#若井,発,14:18#窪川,着,14:23#", | ||||
| "4818D":"宇和島,発,14:09#北宇和島,発,14:12#務田,発,14:25#伊予宮野下,発,14:28#二名,発,14:32#大内,発,14:36#深田,発,14:41#近永,発,14:45#出目,発,14:49#松丸,発,14:56#吉野生,発,15:04#真土,発,15:08#西ケ方,発,15:16#江川崎,着,15:21#", | ||||
| "4810D":"宇和島,発,6:00#北宇和島,発,6:03#務田,発,6:16#伊予宮野下,発,6:18#二名,発,6:22#大内,発,6:25#深田,発,6:31#近永,発,6:35#出目,発,6:38#松丸,発,6:44#吉野生,発,6:51#真土,発,6:54#西ケ方,発,7:03#江川崎,発,7:09#半家,発,7:18#十川,発,7:26#土佐昭和,発,7:31#土佐大正,発,7:42#打井川,発,7:50#家地川,発,7:56#若井,発,8:04#窪川,着,8:09#", | ||||
| "4816D":"宇和島,発,12:18#北宇和島,発,12:21#務田,発,12:33#伊予宮野下,発,12:36#二名,発,12:40#大内,発,12:43#深田,発,12:48#近永,発,12:52#出目,発,12:56#松丸,発,13:02#吉野生,発,13:07#真土,発,13:10#西ケ方,発,13:19#江川崎,発,13:25#半家,発,13:33#十川,発,13:41#土佐昭和,発,13:46#土佐大正,発,14:00#打井川,発,14:07#家地川,発,14:13#若井,発,14:22#窪川,着,14:27#", | ||||
| "4818D":"宇和島,発,14:09#北宇和島,発,14:12#務田,発,14:25#伊予宮野下,発,14:28#二名,発,14:32#大内,発,14:36#深田,発,14:41#近永,発,14:45#出目,発,14:49#松丸,発,14:56#吉野生,発,15:09#真土,発,15:13#西ケ方,発,15:21#江川崎,着,15:26#", | ||||
| "4820D":"宇和島,発,15:20#北宇和島,発,15:23#務田,発,15:36#伊予宮野下,発,15:58#二名,発,16:02#大内,発,16:05#深田,発,16:11#近永,発,16:16#出目,発,16:19#松丸,発,16:26#吉野生,発,16:31#真土,発,16:34#西ケ方,発,16:43#江川崎,着,16:47#", | ||||
| "4822D":"宇和島,発,16:40#北宇和島,発,16:44#務田,発,16:58#伊予宮野下,発,17:04#二名,発,17:08#大内,発,17:11#深田,発,17:16#近永,着,17:20#", | ||||
| "4824D":"宇和島,発,17:30#北宇和島,発,17:33#務田,発,17:45#伊予宮野下,発,17:48#二名,発,17:52#大内,発,17:55#深田,発,18:00#近永,発,18:05#出目,発,18:08#松丸,発,18:15#吉野生,発,18:19#真土,発,18:23#西ケ方,発,18:31#江川崎,発,18:39#半家,発,18:44#十川,発,18:52#土佐昭和,発,18:57#土佐大正,発,19:10#打井川,発,19:19#家地川,発,19:25#若井,発,19:34#窪川,着,19:40#", | ||||
| "4824D":"宇和島,発,17:30#北宇和島,発,17:33#務田,発,17:45#伊予宮野下,発,17:48#二名,発,17:52#大内,発,17:55#深田,発,18:00#近永,発,18:05#出目,発,18:08#松丸,発,18:15#吉野生,発,18:19#真土,発,18:23#西ケ方,発,18:31#江川崎,発,18:38#半家,発,18:47#十川,発,18:55#土佐昭和,発,19:00#土佐大正,発,19:14#打井川,発,19:23#家地川,発,19:29#若井,発,19:38#窪川,着,19:44#", | ||||
| "4826D":"宇和島,発,18:35#北宇和島,発,18:39#務田,発,18:52#伊予宮野下,発,18:55#二名,発,18:58#大内,発,19:02#深田,発,19:07#近永,発,19:11#出目,発,19:14#松丸,発,19:21#吉野生,発,19:26#真土,発,19:29#西ケ方,発,19:37#江川崎,着,19:42#", | ||||
| "4828D":"宇和島,発,20:20#北宇和島,発,20:23#務田,発,20:36#伊予宮野下,発,20:38#二名,発,20:42#大内,発,20:45#深田,発,20:51#近永,発,20:59#出目,発,21:03#松丸,発,21:09#吉野生,発,21:14#真土,発,21:17#西ケ方,発,21:26#江川崎,着,21:30#", | ||||
| "4830D":"宇和島,発,21:00#北宇和島,発,21:03#務田,発,21:15#伊予宮野下,発,21:18#二名,発,21:22#大内,発,21:25#深田,発,21:30#近永,着,21:34#", | ||||
| "8814D":"宇和島,発,9:33#北宇和島,発,9:36#務田,発,9:49#伊予宮野下,発,9:52#二名,発,9:56#大内,発,9:59#深田,発,10:05#近永,発,10:09#出目,発,10:13#松丸,発,10:19#吉野生,発,10:24#真土,発,10:27#西ケ方,発,10:36#江川崎,発,10:43#半家,発,10:49#十川,発,10:57#土佐昭和,発,11:03#土佐大正,発,11:35#打井川,発,11:44#家地川,発,11:51#若井,発,12:00#窪川,着,12:06#", | ||||
| "3811D":"江川崎,発,6:40#西ケ方,発,6:45#真土,発,6:53#吉野生,発,7:07#松丸,発,7:12#出目,発,7:18#近永,発,7:23#深田,発,7:27#大内,発,7:33#二名,発,7:36#伊予宮野下,発,7:43#務田,発,7:46#北宇和島,発,7:59#宇和島,着,8:02#", | ||||
| "4813D":"窪川,発,6:22#若井,発,6:28#家地川,発,6:35#打井川,発,6:40#土佐大正,発,6:48#土佐昭和,発,6:57#十川,発,7:02#半家,発,7:10#江川崎,発,7:26#西ケ方,発,7:31#真土,発,7:39#吉野生,発,7:43#松丸,発,7:48#出目,発,7:54#近永,発,8:01#深田,発,8:05#大内,発,8:11#二名,発,8:14#伊予宮野下,発,8:19#務田,発,8:22#北宇和島,発,8:34#宇和島,着,8:37#", | ||||
| "8814D":"宇和島,発,9:33#北宇和島,発,9:36#務田,発,9:49#伊予宮野下,発,9:51#二名,発,9:56#大内,発,9:59#深田,発,10:05#近永,発,10:09#出目,発,10:12#松丸,発,10:19#吉野生,発,10:23#真土,発,10:27#西ケ方,発,10:36#江川崎,発,10:42#半家,発,10:51#十川,発,10:59#土佐昭和,発,11:04#土佐大正,発,11:36#打井川,発,11:45#家地川,発,11:51#若井,発,12:01#窪川,着,12:07#", | ||||
| "4811D":"江川崎,発,6:35#西ケ方,発,6:39#真土,発,6:48#吉野生,発,7:07#松丸,発,7:12#出目,発,7:18#近永,発,7:23#深田,発,7:27#大内,発,7:33#二名,発,7:36#伊予宮野下,発,7:43#務田,発,7:46#北宇和島,発,7:59#宇和島,着,8:02#", | ||||
| "4813D":"窪川,発,6:13#若井,発,6:18#家地川,発,6:25#打井川,発,6:31#土佐大正,発,6:38#土佐昭和,発,6:48#十川,発,6:53#半家,発,7:01#江川崎,発,7:26#西ケ方,発,7:31#真土,発,7:39#吉野生,発,7:43#松丸,発,7:48#出目,発,7:54#近永,発,8:01#深田,発,8:05#大内,発,8:11#二名,発,8:14#伊予宮野下,発,8:19#務田,発,8:22#北宇和島,発,8:34#宇和島,着,8:37#", | ||||
| "4815D":"近永,発,9:00#深田,発,9:04#大内,発,9:09#二名,発,9:13#伊予宮野下,発,9:17#務田,発,9:20#北宇和島,発,9:36#宇和島,着,9:39#", | ||||
| "4817D":"窪川,発,10:43#若井,発,10:49#家地川,発,10:57#打井川,発,11:03#土佐大正,発,11:34#土佐昭和,発,11:43#十川,発,11:48#半家,発,11:55#江川崎,発,12:11#西ケ方,発,12:16#真土,発,12:25#吉野生,発,12:31#松丸,発,12:35#出目,発,12:42#近永,発,12:52#深田,発,12:56#大内,発,13:02#二名,発,13:05#伊予宮野下,発,13:11#務田,発,13:14#北宇和島,発,13:27#宇和島,着,13:29#", | ||||
| "4817D":"窪川,発,10:43#若井,発,10:49#家地川,発,10:57#打井川,発,11:03#土佐大正,発,11:36#土佐昭和,発,11:46#十川,発,11:51#半家,発,11:58#江川崎,発,12:11#西ケ方,発,12:16#真土,発,12:25#吉野生,発,12:31#松丸,発,12:35#出目,発,12:42#近永,発,12:52#深田,発,12:56#大内,発,13:02#二名,発,13:05#伊予宮野下,発,13:11#務田,発,13:14#北宇和島,発,13:27#宇和島,着,13:29#", | ||||
| "4821D":"江川崎,発,16:11#西ケ方,発,16:15#真土,発,16:25#吉野生,発,16:31#松丸,発,16:36#出目,発,16:42#近永,発,16:46#深田,発,16:51#大内,発,16:56#二名,発,17:00#伊予宮野下,発,17:04#務田,発,17:07#北宇和島,発,17:20#宇和島,着,17:23#", | ||||
| "4823D":"近永,発,17:28#深田,発,17:32#大内,発,17:38#二名,発,17:41#伊予宮野下,発,17:48#務田,発,17:51#北宇和島,発,18:03#宇和島,着,18:06#", | ||||
| "4825D":"江川崎,発,18:00#西ケ方,発,18:05#真土,発,18:14#吉野生,発,18:19#松丸,発,18:24#出目,発,18:30#近永,発,18:34#深田,発,18:38#大内,発,18:43#二名,発,18:46#伊予宮野下,発,18:56#務田,発,18:59#北宇和島,発,19:12#宇和島,着,19:15#", | ||||
| "4827D":"窪川,発,17:40#若井,発,17:45#家地川,発,17:52#打井川,発,17:58#土佐大正,発,18:09#土佐昭和,発,18:18#十川,発,18:24#半家,発,18:32#江川崎,発,19:07#西ケ方,発,19:12#真土,発,19:20#吉野生,発,19:26#松丸,発,19:30#出目,発,19:36#近永,発,19:40#深田,発,19:44#大内,発,19:49#二名,発,19:52#伊予宮野下,発,19:57#務田,発,19:59#北宇和島,発,20:12#宇和島,着,20:15#", | ||||
| "4827D":"窪川,発,17:38#若井,発,17:43#家地川,発,17:50#打井川,発,17:56#土佐大正,発,18:06#土佐昭和,発,18:16#十川,発,18:22#半家,発,18:30#江川崎,発,19:07#西ケ方,発,19:12#真土,発,19:20#吉野生,発,19:26#松丸,発,19:30#出目,発,19:36#近永,発,19:40#深田,発,19:44#大内,発,19:49#二名,発,19:52#伊予宮野下,発,19:57#務田,発,19:59#北宇和島,発,20:12#宇和島,着,20:15#", | ||||
| "4829D":"江川崎,発,20:28#西ケ方,発,20:32#真土,発,20:41#吉野生,発,20:44#松丸,発,20:49#出目,発,20:55#近永,発,20:59#深田,発,21:03#大内,発,21:08#二名,発,21:11#伊予宮野下,発,21:18#務田,発,21:21#北宇和島,発,21:33#宇和島,着,21:36#", | ||||
| "8819D":"窪川,発,13:21#若井,発,13:27#家地川,発,13:37#打井川,発,13:43#土佐大正,発,13:54#土佐昭和,発,14:04#十川,発,14:10#半家,発,14:18#江川崎,発,14:46#西ケ方,発,14:51#真土,発,15:00#吉野生,発,15:04#松丸,発,15:09#出目,発,15:15#近永,発,15:19#深田,発,15:23#大内,発,15:29#二名,発,15:32#伊予宮野下,発,15:39#務田,発,15:42#北宇和島,発,15:55#宇和島,着,15:57#", | ||||
| "8819D":"窪川,発,13:21#若井,発,13:27#家地川,発,13:37#打井川,発,13:43#土佐大正,発,13:58#土佐昭和,発,14:08#十川,発,14:14#半家,発,14:22#江川崎,発,14:51#西ケ方,発,14:56#真土,発,15:05#吉野生,発,15:09#松丸,発,15:14#出目,発,15:20#近永,発,15:23#深田,発,15:28#大内,発,15:33#二名,発,15:37#伊予宮野下,発,15:41#務田,発,15:44#北宇和島,発,15:57#宇和島,着,16:00#", | ||||
| "218D":"高知,発,6:36#薊野,発,6:41#土佐一宮,発,6:45#布師田,発,6:47#土佐大津,発,6:51#後免,発,6:55#土佐長岡,発,6:59#山田西町,発,7:02#土佐山田,着,7:04#", | ||||
| "232D":"高知,発,12:44#薊野,発,12:47#土佐一宮,発,12:53#布師田,発,12:55#土佐大津,発,12:59#後免,発,13:04#土佐長岡,発,13:07#山田西町,発,13:11#土佐山田,着,13:12#", | ||||
| "244D":"高知,発,17:18#薊野,発,17:22#土佐一宮,発,17:25#布師田,発,17:27#土佐大津,発,17:37#後免,発,17:41#土佐長岡,発,17:45#山田西町,発,17:48#土佐山田,発,18:06#新改,発,18:27#繁藤,発,18:40#角茂谷,発,18:43#土佐北川,発,18:47#大杉,発,18:53#土佐穴内,発,18:58#大田口,発,19:04#豊永,発,19:10#土佐岩原,発,19:15#大歩危,発,19:33#小歩危,発,19:41#阿波川口,発,19:48#祖谷口,発,19:52#三縄,発,19:57#阿波池田,着,20:02#", | ||||
| "246D":"高知,発,17:49#薊野,発,17:53#土佐一宮,発,17:56#布師田,発,17:59#土佐大津,発,18:02#後免,発,18:06#土佐長岡,発,18:10#山田西町,発,18:13#土佐山田,着,18:15#", | ||||
| "710D":"高知,発,6:03#薊野,発,6:06#土佐一宮,発,6:09#布師田,発,6:12#土佐大津,発,6:15#後免,発,6:21#土佐長岡,発,6:25#山田西町,発,6:28#土佐山田,着,6:30#", | ||||
| "712D":"須崎,発,5:36#大間,発,5:39#多ノ郷,発,5:41#吾桑,発,5:45#斗賀野,発,5:52#襟野々,発,5:55#佐川,発,5:58#西佐川,発,6:02#土佐加茂,発,6:07#岡花,発,6:11#日下,発,6:14#小村神社前,発,6:17#波川,発,6:21#伊野,発,6:24#枝川,発,6:27#朝倉,発,6:32#高知商業前,発,6:35#旭,発,6:41#円行寺口,発,6:43#入明,発,6:46#高知,発,7:02#土佐一宮,発,7:07#土佐大津,発,7:12#後免,発,7:20#土佐山田,着,7:25#", | ||||
| "714D":"須崎,発,6:07#大間,発,6:10#多ノ郷,発,6:13#吾桑,発,6:17#斗賀野,発,6:25#襟野々,発,6:28#佐川,発,6:31#西佐川,発,6:35#土佐加茂,発,6:40#岡花,発,6:44#日下,発,6:47#小村神社前,発,6:51#波川,発,6:54#伊野,発,7:00#枝川,発,7:03#朝倉,発,7:09#高知商業前,発,7:12#旭,発,7:19#円行寺口,発,7:22#入明,発,7:25#高知,発,7:32#薊野,発,7:36#土佐一宮,発,7:40#布師田,発,7:42#土佐大津,発,7:47#後免,発,7:52#土佐長岡,発,7:55#山田西町,発,7:59#土佐山田,着,8:00#", | ||||
| "716D":"窪川,発,5:56#仁井田,発,6:01#六反地,発,6:04#影野,発,6:07#土佐久礼,発,6:18#安和,発,6:25#土佐新荘,発,6:29#須崎,発,6:33#大間,発,6:36#多ノ郷,発,6:38#吾桑,発,6:41#斗賀野,発,6:49#襟野々,発,6:52#佐川,発,6:55#西佐川,発,6:58#土佐加茂,発,7:02#岡花,発,7:06#日下,発,7:09#小村神社前,発,7:13#波川,発,7:16#伊野,発,7:19#枝川,発,7:22#朝倉,発,7:27#高知商業前,発,7:30#旭,発,7:33#円行寺口,発,7:36#入明,発,7:39#高知,着,7:42#", | ||||
| @@ -477,7 +479,7 @@ | ||||
| "1222M":"琴平,発,8:43#善通寺,発,8:56#金蔵寺,発,9:00#多度津,着,9:04#", | ||||
| "1224M":"琴平,発,9:05#善通寺,発,9:10#金蔵寺,発,9:14#多度津,発,9:21#讃岐塩屋,発,9:25#丸亀,発,9:28#宇多津,発,9:31#坂出,発,9:46#八十場,発,9:49#鴨川,発,9:52#讃岐府中,発,9:55#国分,発,9:58#端岡,発,10:01#鬼無,発,10:05#香西,発,10:08#高松,着,10:12#", | ||||
| "1228M":"琴平,発,10:47#善通寺,発,10:56#金蔵寺,発,11:00#多度津,発,11:05#讃岐塩屋,発,11:09#丸亀,発,11:12#宇多津,発,11:15#坂出,発,11:20#八十場,発,11:23#鴨川,発,11:26#讃岐府中,発,11:29#国分,発,11:32#端岡,発,11:35#鬼無,発,11:39#香西,発,11:42#高松,着,11:46#", | ||||
| "1246M":"琴平,発,17:25#善通寺,発,17:30#金蔵寺,発,17:34#多度津,発,17:39#讃岐塩屋,発,17:42#丸亀,発,17:45#宇多津,発,17:49#坂出,発,17:54#八十場,発,17:58#鴨川,発,18:00#讃岐府中,発,18:03#国分,発,18:06#端岡,発,18:10#鬼無,発,18:14#香西,発,18:17#高松,着,18:21#", | ||||
| "1246M":"琴平,発,17:25#善通寺,発,17:30#金蔵寺,発,17:34#多度津,発,17:39#讃岐塩屋,発,17:42#丸亀,発,17:45#宇多津,発,17:49#坂出,発,17:55#八十場,発,17:58#鴨川,発,18:01#讃岐府中,発,18:04#国分,発,18:07#端岡,発,18:10#鬼無,発,18:14#香西,発,18:17#高松,着,18:21#", | ||||
| "1250M":"琴平,発,18:31#善通寺,発,18:37#金蔵寺,発,18:40#多度津,着,18:44#", | ||||
| "1252M":"琴平,発,19:10#善通寺,発,19:17#金蔵寺,発,19:20#多度津,着,19:24#", | ||||
| "1254M":"琴平,発,19:37#善通寺,発,19:43#金蔵寺,発,19:46#多度津,発,19:51#讃岐塩屋,発,19:54#丸亀,発,19:57#宇多津,発,20:01#坂出,発,20:05#八十場,発,20:09#鴨川,発,20:12#讃岐府中,発,20:15#国分,発,20:18#端岡,発,20:21#鬼無,発,20:25#香西,発,20:28#高松,着,20:33#", | ||||
| @@ -513,7 +515,7 @@ | ||||
| "4248D":"土佐山田,発,20:08#繁藤,発,20:27#角茂谷,発,20:30#土佐北川,発,20:34#大杉,発,20:41#土佐穴内,発,20:46#大田口,発,20:50#豊永,発,21:01#土佐岩原,発,21:06#大歩危,発,21:33#小歩危,発,21:41#阿波川口,発,21:49#祖谷口,発,21:53#三縄,発,21:59#阿波池田,着,22:03#", | ||||
| "4250D":"高知,発,20:37#薊野,発,20:41#土佐一宮,発,20:48#布師田,発,20:51#土佐大津,発,20:54#後免,発,20:58#土佐長岡,発,21:01#山田西町,発,21:04#土佐山田,着,21:06#", | ||||
| "4260M":"琴平,発,22:36#善通寺,発,22:42#金蔵寺,発,22:45#多度津,着,22:49#", | ||||
| "4710D":"伊野,発,5:36#枝川,発,5:39#朝倉,発,5:44#高知商業前,発,5:47#旭,発,5:50#円行寺口,発,5:53#入明,発,5:55#高知,発,6:03#薊野,発,6:06#土佐一宮,発,6:09#布師田,発,6:12#土佐大津,発,6:15#後免,発,6:21#土佐長岡,発,6:25#山田西町,発,6:28#土佐山田,着,6:30#", | ||||
| "4710D":"伊野,発,5:36#枝川,発,5:39#朝倉,発,5:44#高知商業前,発,5:47#旭,発,5:50#円行寺口,発,5:53#入明,発,5:55#高知,着,5:57#", | ||||
| "4730D":"須崎,発,9:35#大間,発,9:38#多ノ郷,発,9:41#吾桑,発,9:47#斗賀野,発,9:54#襟野々,発,9:57#佐川,発,10:01#西佐川,発,10:04#土佐加茂,発,10:14#岡花,発,10:18#日下,発,10:21#小村神社前,発,10:24#波川,発,10:27#伊野,発,10:31#枝川,発,10:34#朝倉,発,10:42#高知商業前,発,10:45#旭,発,10:47#円行寺口,発,10:50#入明,発,10:52#高知,着,10:55#", | ||||
| "4732D":"伊野,発,11:03#枝川,発,11:06#朝倉,発,11:11#高知商業前,発,11:13#旭,発,11:18#円行寺口,発,11:21#入明,発,11:24#高知,発,11:44#薊野,発,11:47#土佐一宮,発,11:53#布師田,発,11:55#土佐大津,発,11:59#後免,発,12:04#土佐長岡,発,12:08#山田西町,発,12:12#土佐山田,着,12:13#", | ||||
| "4734D":"須崎,発,10:34#大間,発,10:37#多ノ郷,発,10:39#吾桑,発,10:43#斗賀野,発,10:53#襟野々,発,10:56#佐川,発,10:59#西佐川,発,11:03#土佐加茂,発,11:08#岡花,発,11:12#日下,発,11:16#小村神社前,発,11:19#波川,発,11:22#伊野,発,11:29#枝川,発,11:32#朝倉,発,11:37#高知商業前,発,11:40#旭,発,11:46#円行寺口,発,11:49#入明,発,11:51#高知,着,11:53#", | ||||
| @@ -525,17 +527,17 @@ | ||||
| "4760D":"窪川,発,18:40#仁井田,発,18:45#六反地,発,18:48#影野,発,18:51#土佐久礼,発,19:05#安和,発,19:12#土佐新荘,発,19:16#須崎,発,19:21#大間,発,19:24#多ノ郷,発,19:26#吾桑,発,19:36#斗賀野,発,19:44#襟野々,発,19:47#佐川,発,19:51#西佐川,発,19:54#土佐加茂,発,19:59#岡花,発,20:04#日下,発,20:13#小村神社前,発,20:16#波川,発,20:19#伊野,発,20:25#枝川,発,20:28#朝倉,発,20:33#高知商業前,発,20:36#旭,発,20:39#円行寺口,発,20:42#入明,発,20:44#高知,着,20:47#", | ||||
| "4762D":"伊野,発,21:37#枝川,発,21:40#朝倉,発,21:44#高知商業前,発,21:47#旭,発,21:50#円行寺口,発,21:52#入明,発,21:54#高知,発,22:01#薊野,発,22:04#土佐一宮,発,22:07#布師田,発,22:10#土佐大津,発,22:15#後免,発,22:19#土佐長岡,発,22:22#山田西町,発,22:26#土佐山田,着,22:27#", | ||||
| "4764D":"須崎,発,21:36#大間,発,21:39#多ノ郷,発,21:41#吾桑,発,21:45#斗賀野,発,21:55#襟野々,発,21:58#佐川,発,22:01#西佐川,発,22:04#土佐加茂,発,22:09#岡花,発,22:13#日下,発,22:16#小村神社前,発,22:19#波川,発,22:23#伊野,発,22:31#枝川,発,22:34#朝倉,発,22:39#高知商業前,発,22:42#旭,発,22:45#円行寺口,発,22:47#入明,発,22:49#高知,着,22:52#", | ||||
| "5210M":"琴平,発,6:06#善通寺,発,6:12#金蔵寺,発,6:15#多度津,発,6:20#讃岐塩屋,発,6:24#丸亀,発,6:27#宇多津,発,6:31#坂出,発,6:42#八十場,発,6:46#鴨川,発,6:53#讃岐府中,発,6:57#国分,発,7:00#端岡,発,7:03#鬼無,発,7:07#香西,発,7:10#高松,着,7:14#", | ||||
| "5210M":"琴平,発,6:05#善通寺,発,6:11#金蔵寺,発,6:14#多度津,発,6:20#讃岐塩屋,発,6:24#丸亀,発,6:27#宇多津,発,6:31#坂出,発,6:42#八十場,発,6:46#鴨川,発,6:53#讃岐府中,発,6:57#国分,発,7:00#端岡,発,7:03#鬼無,発,7:07#香西,発,7:10#高松,着,7:14#", | ||||
| "5212M":"琴平,発,6:42#善通寺,発,6:48#金蔵寺,発,6:52#多度津,着,6:56#", | ||||
| "5216M":"琴平,発,7:17#善通寺,発,7:24#金蔵寺,発,7:27#多度津,発,7:33#讃岐塩屋,発,7:37#丸亀,発,7:40#宇多津,発,7:44#坂出,発,8:00#八十場,発,8:04#鴨川,発,8:07#讃岐府中,発,8:10#国分,発,8:14#端岡,発,8:17#鬼無,発,8:21#香西,発,8:25#高松,着,8:29#", | ||||
| "5218M":"琴平,発,7:38#善通寺,発,7:45#金蔵寺,発,7:49#多度津,発,7:58#讃岐塩屋,発,8:01#丸亀,発,8:05#宇多津,発,8:08#坂出,発,8:14#八十場,発,8:17#鴨川,発,8:20#讃岐府中,発,8:23#国分,発,8:27#端岡,発,8:30#鬼無,発,8:34#香西,発,8:37#高松,着,8:41#", | ||||
| "5220M":"琴平,発,8:06#善通寺,発,8:12#金蔵寺,発,8:15#多度津,着,8:19#", | ||||
| "5226M":"琴平,発,10:05#善通寺,発,10:11#金蔵寺,発,10:14#多度津,発,10:24#讃岐塩屋,発,10:28#丸亀,発,10:31#宇多津,発,10:35#坂出,発,10:40#八十場,発,10:43#鴨川,発,10:46#讃岐府中,発,10:49#国分,発,10:53#端岡,発,10:56#鬼無,発,11:00#香西,発,11:03#高松,着,11:07#", | ||||
| "5230M":"琴平,発,11:13#善通寺,発,11:20#金蔵寺,発,11:23#多度津,発,11:30#讃岐塩屋,発,11:33#丸亀,発,11:36#宇多津,発,11:40#坂出,発,11:55#八十場,発,11:59#鴨川,発,12:02#讃岐府中,発,12:05#国分,発,12:08#端岡,発,12:11#鬼無,発,12:15#香西,発,12:18#高松,着,12:22#", | ||||
| "5232M":"琴平,発,12:13#善通寺,発,12:19#金蔵寺,発,12:22#多度津,発,12:30#讃岐塩屋,発,12:33#丸亀,発,12:36#宇多津,発,12:40#坂出,発,12:53#八十場,発,12:56#鴨川,発,12:59#讃岐府中,発,13:03#国分,発,13:06#端岡,発,13:09#鬼無,発,13:13#香西,発,13:16#高松,着,13:21#", | ||||
| "5234M":"琴平,発,13:13#善通寺,発,13:19#金蔵寺,発,13:22#多度津,発,13:30#讃岐塩屋,発,13:33#丸亀,発,13:36#宇多津,発,13:40#坂出,発,13:53#八十場,発,13:56#鴨川,発,13:59#讃岐府中,発,14:03#国分,発,14:06#端岡,発,14:09#鬼無,発,14:13#香西,発,14:16#高松,着,14:21#", | ||||
| "5236M":"琴平,発,14:13#善通寺,発,14:19#金蔵寺,発,14:22#多度津,発,14:30#讃岐塩屋,発,14:33#丸亀,発,14:36#宇多津,発,14:40#坂出,発,14:53#八十場,発,14:56#鴨川,発,14:59#讃岐府中,発,15:03#国分,発,15:06#端岡,発,15:09#鬼無,発,15:13#香西,発,15:16#高松,着,15:21#", | ||||
| "5238M":"琴平,発,15:13#善通寺,発,15:19#金蔵寺,発,15:23#多度津,発,15:30#讃岐塩屋,発,15:33#丸亀,発,15:36#宇多津,発,15:40#坂出,発,15:53#八十場,発,15:56#鴨川,発,15:59#讃岐府中,発,16:03#国分,発,16:06#端岡,発,16:09#鬼無,発,16:13#香西,発,16:16#高松,着,16:21#", | ||||
| "5232M":"琴平,発,12:13#善通寺,発,12:19#金蔵寺,発,12:22#多度津,発,12:30#讃岐塩屋,発,12:33#丸亀,発,12:36#宇多津,発,12:40#坂出,発,12:53#八十場,発,12:57#鴨川,発,13:00#讃岐府中,発,13:03#国分,発,13:06#端岡,発,13:09#鬼無,発,13:13#香西,発,13:16#高松,着,13:21#", | ||||
| "5234M":"琴平,発,13:13#善通寺,発,13:19#金蔵寺,発,13:22#多度津,発,13:30#讃岐塩屋,発,13:33#丸亀,発,13:36#宇多津,発,13:40#坂出,発,13:53#八十場,発,13:57#鴨川,発,14:00#讃岐府中,発,14:03#国分,発,14:06#端岡,発,14:09#鬼無,発,14:13#香西,発,14:16#高松,着,14:21#", | ||||
| "5236M":"琴平,発,14:13#善通寺,発,14:19#金蔵寺,発,14:22#多度津,発,14:30#讃岐塩屋,発,14:33#丸亀,発,14:36#宇多津,発,14:40#坂出,発,14:53#八十場,発,14:57#鴨川,発,15:00#讃岐府中,発,15:03#国分,発,15:06#端岡,発,15:09#鬼無,発,15:13#香西,発,15:16#高松,着,15:21#", | ||||
| "5238M":"琴平,発,15:13#善通寺,発,15:19#金蔵寺,発,15:23#多度津,発,15:30#讃岐塩屋,発,15:33#丸亀,発,15:36#宇多津,発,15:40#坂出,発,15:53#八十場,発,15:57#鴨川,発,16:00#讃岐府中,発,16:03#国分,発,16:06#端岡,発,16:09#鬼無,発,16:13#香西,発,16:16#高松,着,16:21#", | ||||
| "5240M":"琴平,発,15:32#善通寺,発,15:37#金蔵寺,発,15:41#多度津,発,15:47#讃岐塩屋,発,15:50#丸亀,発,15:53#宇多津,発,15:57#坂出,発,16:02#八十場,発,16:05#鴨川,発,16:09#讃岐府中,発,16:12#国分,発,16:15#端岡,発,16:18#鬼無,発,16:22#香西,発,16:26#高松,着,16:30#", | ||||
| "5242M":"琴平,発,16:13#善通寺,発,16:19#金蔵寺,発,16:24#多度津,発,16:30#讃岐塩屋,発,16:33#丸亀,発,16:36#宇多津,発,16:40#坂出,発,16:53#八十場,発,16:57#鴨川,発,17:00#讃岐府中,発,17:03#国分,発,17:06#端岡,発,17:09#鬼無,発,17:13#香西,発,17:16#高松,着,17:20#", | ||||
| "5244M":"琴平,発,16:47#善通寺,発,16:53#金蔵寺,発,16:58#多度津,発,17:04#讃岐塩屋,発,17:07#丸亀,発,17:10#宇多津,発,17:14#坂出,発,17:24#八十場,発,17:28#鴨川,発,17:31#讃岐府中,発,17:34#国分,発,17:37#端岡,発,17:41#鬼無,発,17:44#香西,発,17:48#高松,着,17:52#", | ||||
| @@ -588,7 +590,7 @@ | ||||
| "759D":"高知,発,22:10#入明,発,22:13#円行寺口,発,22:15#旭,発,22:18#高知商業前,発,22:20#朝倉,発,22:23#枝川,発,22:28#伊野,発,22:31#波川,発,22:34#小村神社前,発,22:37#日下,発,22:41#岡花,発,22:44#土佐加茂,発,22:48#西佐川,発,22:53#佐川,発,22:56#襟野々,発,22:59#斗賀野,発,23:02#吾桑,発,23:08#多ノ郷,発,23:12#大間,発,23:14#須崎,着,23:17#", | ||||
| "1213M":"高松,発,5:42#香西,発,5:46#鬼無,発,5:50#端岡,発,5:54#国分,発,5:57#讃岐府中,発,6:00#鴨川,発,6:04#八十場,発,6:07#坂出,発,6:25#宇多津,発,6:30#丸亀,発,6:33#讃岐塩屋,発,6:36#多度津,発,6:40#金蔵寺,発,6:45#善通寺,発,6:48#琴平,着,6:54#", | ||||
| "1219M":"高松,発,7:15#香西,発,7:20#鬼無,発,7:23#端岡,発,7:31#国分,発,7:34#讃岐府中,発,7:38#鴨川,発,7:41#八十場,発,7:44#坂出,発,7:47#宇多津,発,7:52#丸亀,発,7:56#讃岐塩屋,発,7:59#多度津,発,8:10#金蔵寺,発,8:15#善通寺,発,8:18#琴平,着,8:24#", | ||||
| "1221M":"高松,発,7:55#香西,発,8:00#鬼無,発,8:03#端岡,発,8:10#国分,発,8:14#讃岐府中,発,8:17#鴨川,発,8:20#八十場,発,8:23#坂出,発,8:26#宇多津,発,8:31#丸亀,発,8:34#讃岐塩屋,発,8:37#多度津,発,8:41#金蔵寺,発,8:48#善通寺,発,8:51#琴平,着,8:56#", | ||||
| "1221M":"高松,発,7:55#香西,発,8:00#鬼無,発,8:03#端岡,発,8:10#国分,発,8:14#讃岐府中,発,8:17#鴨川,発,8:20#八十場,発,8:23#坂出,発,8:26#宇多津,発,8:31#丸亀,発,8:34#讃岐塩屋,発,8:37#多度津,発,8:41#金蔵寺,発,8:47#善通寺,発,8:51#琴平,着,8:56#", | ||||
| "1227M":"高松,発,9:26#香西,発,9:30#鬼無,発,9:34#端岡,発,9:50#国分,発,9:53#讃岐府中,発,9:56#鴨川,発,10:05#八十場,発,10:08#坂出,発,10:12#宇多津,発,10:17#丸亀,発,10:20#讃岐塩屋,発,10:23#多度津,発,10:28#金蔵寺,発,10:32#善通寺,発,10:35#琴平,着,10:41#", | ||||
| "1243M":"高松,発,16:16#香西,発,16:20#鬼無,発,16:24#端岡,発,16:28#国分,発,16:31#讃岐府中,発,16:34#鴨川,発,16:37#八十場,発,16:40#坂出,発,16:43#宇多津,発,16:49#丸亀,発,16:52#讃岐塩屋,発,16:55#多度津,発,17:04#金蔵寺,発,17:09#善通寺,発,17:13#琴平,着,17:18#", | ||||
| "1247M":"高松,発,17:24#香西,発,17:29#鬼無,発,17:32#端岡,発,17:35#国分,発,17:38#讃岐府中,発,17:41#鴨川,発,17:44#八十場,発,17:47#坂出,発,17:51#宇多津,発,17:56#丸亀,発,17:59#讃岐塩屋,発,18:02#多度津,発,18:06#金蔵寺,発,18:11#善通寺,発,18:14#琴平,着,18:19#", | ||||
| @@ -597,7 +599,7 @@ | ||||
| "1263M":"高松,発,22:08#香西,発,22:13#鬼無,発,22:16#端岡,発,22:19#国分,発,22:22#讃岐府中,発,22:25#鴨川,発,22:33#八十場,発,22:36#坂出,発,22:39#宇多津,発,22:45#丸亀,発,22:48#讃岐塩屋,発,22:51#多度津,着,22:55#", | ||||
| "2001D":"高松,発,6:04#坂出,発,6:18#丸亀,発,6:24#多度津,発,6:29#善通寺,発,6:35#琴平,発,6:40#阿波池田,発,7:06#大歩危,発,7:24#大杉,発,7:44#土佐山田,発,8:04#後免,発,8:10#高知,発,8:20#旭,発,8:24#朝倉,発,8:28#伊野,発,8:33#佐川,発,8:47#須崎,発,9:01#土佐久礼,発,9:11#窪川,発,9:27#土佐佐賀,発,9:45#土佐上川口,発,9:53#土佐入野,発,9:57#中村,着,10:04#", | ||||
| "2003D":"高松,発,7:23#坂出,発,7:37#宇多津,着,7:45#", | ||||
| "2005D":"高松,発,8:25#坂出,発,8:40#丸亀,発,8:46#多度津,発,8:50#善通寺,発,8:56#琴平,発,9:01#阿波池田,発,9:24#大歩危,発,9:42#大杉,発,10:03#土佐山田,発,10:25#後免,発,10:30#高知,着,10:37#", | ||||
| "2005D":"高松,発,8:25#坂出,発,8:40#丸亀,発,8:46#多度津,発,8:50#善通寺,発,8:55#琴平,発,9:00#阿波池田,発,9:24#大歩危,発,9:42#大杉,発,10:03#土佐山田,発,10:25#後免,発,10:30#高知,着,10:37#", | ||||
| "2007D":"高松,発,18:27#坂出,発,18:41#宇多津,発,18:46#丸亀,発,18:49#多度津,着,18:55#", | ||||
| "2071D":"高知,発,9:53#伊野,発,10:04#佐川,発,10:17#須崎,発,10:30#土佐久礼,発,10:40#窪川,発,10:57#土佐佐賀,発,11:15#土佐入野,発,11:26#中村,着,11:32#", | ||||
| "2073D":"高知,発,11:42#旭,発,11:46#朝倉,発,11:50#伊野,発,11:55#佐川,発,12:09#須崎,発,12:22#土佐久礼,発,12:32#窪川,発,12:49#土佐佐賀,発,13:06#土佐入野,発,13:17#中村,着,13:24#", | ||||
| @@ -638,7 +640,7 @@ | ||||
| "4757D":"高知,発,21:00#入明,発,21:03#円行寺口,発,21:05#旭,発,21:08#高知商業前,発,21:10#朝倉,発,21:13#枝川,発,21:18#伊野,着,21:20#", | ||||
| "4759D":"土佐山田,発,21:23#山田西町,発,21:25#土佐長岡,発,21:28#後免,発,21:39#土佐大津,発,21:42#布師田,発,21:45#土佐一宮,発,21:48#薊野,発,21:51#高知,着,21:54#", | ||||
| "4761D":"高知,発,23:02#入明,発,23:05#円行寺口,発,23:07#旭,発,23:10#高知商業前,発,23:12#朝倉,発,23:15#枝川,発,23:20#伊野,着,23:22#", | ||||
| "5211M":"多度津,発,5:42#金蔵寺,発,5:47#善通寺,発,5:52#琴平,着,5:58#", | ||||
| "5211M":"多度津,発,5:42#金蔵寺,発,5:47#善通寺,発,5:51#琴平,着,5:57#", | ||||
| "5215M":"高松,発,6:12#香西,発,6:16#鬼無,発,6:20#端岡,発,6:24#国分,発,6:28#讃岐府中,発,6:31#鴨川,発,6:34#八十場,発,6:37#坂出,発,6:41#宇多津,発,6:46#丸亀,発,6:50#讃岐塩屋,発,6:53#多度津,発,6:58#金蔵寺,発,7:03#善通寺,発,7:06#琴平,着,7:12#", | ||||
| "5217M":"多度津,発,7:33#金蔵寺,発,7:40#善通寺,発,7:45#琴平,着,7:51#", | ||||
| "5223M":"高松,発,8:15#香西,発,8:20#鬼無,発,8:23#端岡,発,8:33#国分,発,8:37#讃岐府中,発,8:40#鴨川,発,8:43#八十場,発,8:46#坂出,発,8:50#宇多津,発,8:56#丸亀,発,8:59#讃岐塩屋,発,9:02#多度津,発,9:09#金蔵寺,発,9:14#善通寺,発,9:18#琴平,着,9:23#", | ||||
| @@ -679,7 +681,7 @@ | ||||
| "312D":"徳島,発,6:01#佐古,発,6:06#吉成,発,6:13#勝瑞,発,6:15#池谷,発,6:20#板東,発,6:24#阿波川端,発,6:27#板野,発,6:31#阿波大宮,発,6:37#讃岐相生,発,6:44#引田,発,6:53#讃岐白鳥,発,6:58#三本松,発,7:03#丹生,発,7:07#鶴羽,発,7:12#讃岐津田,発,7:16#神前,発,7:21#造田,発,7:27#オレンジタウン,発,7:33#志度,発,7:37#讃岐牟礼,発,7:41#八栗口,発,7:44#古高松南,発,7:47#屋島,発,7:51#木太町,発,7:55#栗林,発,8:00#栗林公園北口,発,8:03#昭和町,発,8:06#高松,着,8:09#", | ||||
| "314D":"引田,発,7:09#讃岐白鳥,発,7:15#三本松,発,7:20#丹生,発,7:26#鶴羽,発,7:35#讃岐津田,発,7:52#神前,発,7:59#造田,発,8:05#オレンジタウン,発,8:10#志度,発,8:16#讃岐牟礼,発,8:21#八栗口,発,8:24#古高松南,発,8:27#屋島,発,8:33#木太町,発,8:38#栗林,発,8:43#栗林公園北口,発,8:46#昭和町,発,8:49#高松,着,8:53#", | ||||
| "316D":"徳島,発,6:37#佐古,発,6:40#吉成,発,6:46#勝瑞,発,6:49#池谷,発,6:54#板東,発,6:58#阿波川端,発,7:02#板野,発,7:25#阿波大宮,発,7:34#讃岐相生,発,7:41#引田,発,7:48#讃岐白鳥,発,7:53#三本松,発,8:00#丹生,発,8:05#鶴羽,発,8:11#讃岐津田,発,8:16#神前,発,8:23#造田,発,8:26#オレンジタウン,発,8:31#志度,発,8:39#讃岐牟礼,発,8:44#八栗口,発,8:46#古高松南,発,8:49#屋島,発,8:52#木太町,発,8:56#栗林,発,9:01#栗林公園北口,発,9:03#昭和町,発,9:07#高松,着,9:10#", | ||||
| "318D":"徳島,発,7:05#佐古,発,7:10#吉成,発,7:20#勝瑞,発,7:24#池谷,発,7:31#板東,発,7:35#阿波川端,発,7:39#板野,着,7:42#", | ||||
| "318D":"徳島,発,7:05#佐古,発,7:10#吉成,発,7:20#勝瑞,発,7:25#池谷,発,7:32#板東,発,7:35#阿波川端,発,7:39#板野,着,7:42#", | ||||
| "328D":"引田,発,9:31#讃岐白鳥,発,9:36#三本松,発,9:44#丹生,発,9:48#鶴羽,発,9:53#讃岐津田,発,10:10#神前,発,10:15#造田,発,10:18#オレンジタウン,発,10:29#志度,発,10:33#讃岐牟礼,発,10:36#八栗口,発,10:39#古高松南,発,10:41#屋島,発,10:46#木太町,発,10:50#栗林,発,10:54#栗林公園北口,発,10:56#昭和町,発,11:00#高松,着,11:03#", | ||||
| "356D":"徳島,発,16:00#佐古,発,16:03#吉成,発,16:13#勝瑞,発,16:16#池谷,発,16:24#板東,発,16:28#阿波川端,発,16:31#板野,発,16:35#阿波大宮,発,16:41#讃岐相生,発,16:51#引田,発,16:54#讃岐白鳥,発,17:00#三本松,発,17:04#丹生,発,17:08#鶴羽,発,17:13#讃岐津田,発,17:27#神前,発,17:32#造田,発,17:41#オレンジタウン,発,17:44#志度,発,17:48#讃岐牟礼,発,17:52#八栗口,発,17:55#古高松南,発,17:58#屋島,発,18:01#木太町,発,18:05#栗林,発,18:19#栗林公園北口,発,18:21#昭和町,発,18:24#高松,着,18:28#", | ||||
| "360D":"三本松,発,17:39#丹生,発,17:47#鶴羽,発,17:54#讃岐津田,発,17:58#神前,発,18:04#造田,発,18:18#オレンジタウン,発,18:22#志度,発,18:38#讃岐牟礼,発,18:42#八栗口,発,18:44#古高松南,発,18:47#屋島,発,18:51#木太町,発,18:54#栗林,発,18:58#栗林公園北口,発,19:00#昭和町,発,19:03#高松,着,19:06#", | ||||
| @@ -725,7 +727,7 @@ | ||||
| "4370D":"徳島,発,18:48#佐古,発,18:51#吉成,発,18:58#勝瑞,発,19:05#池谷,発,19:14#板東,発,19:18#阿波川端,発,19:21#板野,着,19:25#", | ||||
| "4376D":"引田,発,20:36#讃岐白鳥,発,20:44#三本松,発,20:51#丹生,発,20:58#鶴羽,発,21:03#讃岐津田,発,21:21#神前,発,21:26#造田,発,21:29#オレンジタウン,発,21:33#志度,発,21:37#讃岐牟礼,発,21:40#八栗口,発,21:43#古高松南,発,21:45#屋島,発,21:48#木太町,発,21:52#栗林,発,21:55#栗林公園北口,発,21:58#昭和町,発,22:00#高松,着,22:03#", | ||||
| "4378D":"徳島,発,20:51#佐古,発,20:55#吉成,発,21:02#勝瑞,発,21:11#池谷,発,21:18#板東,発,21:22#阿波川端,発,21:26#板野,着,21:29#", | ||||
| "4380D":"引田,発,21:49#讃岐白鳥,発,21:59#三本松,発,22:04#丹生,発,22:08#鶴羽,発,22:14#讃岐津田,発,22:19#神前,発,22:24#造田,発,22:28#オレンジタウン,発,22:33#志度,発,22:39#讃岐牟礼,発,22:43#八栗口,発,22:46#古高松南,発,22:49#屋島,発,22:52#木太町,発,22:56#栗林,発,23:00#栗林公園北口,発,23:03#昭和町,発,23:06#高松,着,23:09#", | ||||
| "4380D":"引田,発,21:50#讃岐白鳥,発,22:00#三本松,発,22:05#丹生,発,22:09#鶴羽,発,22:14#讃岐津田,発,22:19#神前,発,22:24#造田,発,22:27#オレンジタウン,発,22:31#志度,発,22:39#讃岐牟礼,発,22:43#八栗口,発,22:47#古高松南,発,22:49#屋島,発,22:53#木太町,発,22:56#栗林,発,23:01#栗林公園北口,発,23:04#昭和町,発,23:06#高松,着,23:09#", | ||||
| "4382D":"徳島,発,22:17#佐古,発,22:20#吉成,発,22:26#勝瑞,発,22:31#池谷,発,22:36#板東,発,22:40#阿波川端,発,22:44#板野,着,22:47#", | ||||
| "5306D":"引田,発,5:40#讃岐白鳥,発,5:46#三本松,発,5:50#丹生,発,5:55#鶴羽,発,6:00#讃岐津田,発,6:05#神前,発,6:10#造田,発,6:16#オレンジタウン,発,6:20#志度,発,6:27#讃岐牟礼,発,6:31#八栗口,発,6:34#古高松南,発,6:37#屋島,発,6:47#木太町,発,6:51#栗林,発,6:55#栗林公園北口,発,6:58#昭和町,発,7:01#高松,着,7:04#", | ||||
| "5308D":"三本松,発,6:20#丹生,発,6:25#鶴羽,発,6:32#讃岐津田,発,6:40#神前,発,6:45#造田,発,6:48#オレンジタウン,発,6:53#志度,発,6:57#讃岐牟礼,発,7:01#八栗口,発,7:08#古高松南,発,7:11#屋島,発,7:15#木太町,発,7:19#栗林,発,7:25#栗林公園北口,発,7:28#昭和町,発,7:31#高松,着,7:34#", | ||||
| @@ -734,6 +736,7 @@ | ||||
| "309D":"板野,発,8:11#阿波川端,発,8:14#板東,発,8:19#池谷,発,8:23#勝瑞,発,8:31#吉成,発,8:35#佐古,発,8:41#徳島,着,8:44#", | ||||
| "313D":"高松,発,7:17#昭和町,発,7:20#栗林公園北口,発,7:23#栗林,発,7:26#木太町,発,7:29#屋島,発,7:36#古高松南,発,7:39#八栗口,発,7:48#讃岐牟礼,発,7:50#志度,発,7:57#オレンジタウン,発,8:01#造田,発,8:05#神前,発,8:09#讃岐津田,発,8:16#鶴羽,発,8:19#丹生,発,8:24#三本松,発,8:29#讃岐白鳥,発,8:33#引田,着,8:37#", | ||||
| "347D":"高松,発,16:15#昭和町,発,16:18#栗林公園北口,発,16:21#栗林,発,16:29#木太町,発,16:33#屋島,発,16:37#古高松南,発,16:39#八栗口,発,16:43#讃岐牟礼,発,16:45#志度,発,16:50#オレンジタウン,発,16:54#造田,発,16:58#神前,発,17:01#讃岐津田,発,17:07#鶴羽,発,17:21#丹生,発,17:27#三本松,着,17:30#", | ||||
| "351D":"板野,発,18:32#阿波川端,発,18:35#板東,発,18:41#池谷,発,18:47#勝瑞,発,18:53#吉成,発,18:58#佐古,発,19:07#徳島,着,19:09#", | ||||
| "353D":"高松,発,16:46#昭和町,発,16:49#栗林公園北口,発,16:52#栗林,発,16:57#木太町,発,17:00#屋島,発,17:06#古高松南,発,17:08#八栗口,発,17:12#讃岐牟礼,発,17:14#志度,発,17:20#オレンジタウン,発,17:37#造田,発,17:41#神前,発,17:44#讃岐津田,発,17:50#鶴羽,発,17:54#丹生,発,18:05#三本松,発,18:09#讃岐白鳥,発,18:14#引田,着,18:18#", | ||||
| "357D":"高松,発,18:03#昭和町,発,18:06#栗林公園北口,発,18:08#栗林,発,18:11#木太町,発,18:14#屋島,発,18:25#古高松南,発,18:28#八栗口,発,18:31#讃岐牟礼,発,18:34#志度,発,18:38#オレンジタウン,発,18:42#造田,発,18:48#神前,発,18:51#讃岐津田,発,18:57#鶴羽,発,19:08#丹生,発,19:14#三本松,発,19:18#讃岐白鳥,発,19:22#引田,着,19:27#", | ||||
| "361D":"高松,発,18:33#昭和町,発,18:36#栗林公園北口,発,18:39#栗林,発,18:42#木太町,発,18:46#屋島,発,18:51#古高松南,発,18:54#八栗口,発,18:57#讃岐牟礼,発,19:00#志度,発,19:04#オレンジタウン,発,19:08#造田,発,19:16#神前,発,19:20#讃岐津田,発,19:26#鶴羽,発,19:30#丹生,発,19:37#三本松,発,19:43#讃岐白鳥,発,20:04#引田,発,20:10#讃岐相生,発,20:15#阿波大宮,発,20:26#板野,発,20:32#阿波川端,発,20:36#板東,発,20:47#池谷,発,20:51#勝瑞,発,20:56#吉成,発,21:02#佐古,発,21:09#徳島,着,21:12#", | ||||
| @@ -771,12 +774,11 @@ | ||||
| "4331D":"高松,発,12:10#昭和町,発,12:13#栗林公園北口,発,12:15#栗林,発,12:18#木太町,発,12:21#屋島,発,12:26#古高松南,発,12:29#八栗口,発,12:31#讃岐牟礼,発,12:34#志度,発,12:38#オレンジタウン,発,12:47#造田,発,12:50#神前,発,12:54#讃岐津田,発,12:59#鶴羽,発,13:06#丹生,発,13:12#三本松,着,13:15#", | ||||
| "4333D":"高松,発,12:53#昭和町,発,12:56#栗林公園北口,発,12:58#栗林,発,13:01#木太町,発,13:04#屋島,発,13:09#古高松南,発,13:12#八栗口,発,13:29#讃岐牟礼,発,13:31#志度,発,13:36#オレンジタウン,発,13:39#造田,発,13:52#神前,発,13:55#讃岐津田,発,14:05#鶴羽,発,14:09#丹生,発,14:13#三本松,発,14:18#讃岐白鳥,発,14:22#引田,着,14:26#", | ||||
| "4335D":"高松,発,13:41#昭和町,発,13:44#栗林公園北口,発,13:47#栗林,発,13:50#木太町,発,13:53#屋島,発,13:57#古高松南,発,14:00#八栗口,発,14:06#讃岐牟礼,発,14:08#志度,発,14:13#オレンジタウン,発,14:17#造田,発,14:21#神前,発,14:24#讃岐津田,発,14:37#鶴羽,発,14:40#丹生,発,14:45#三本松,発,14:56#讃岐白鳥,発,15:01#引田,着,15:05#", | ||||
| "4337D":"高松,発,14:15#昭和町,発,14:18#栗林公園北口,発,14:20#栗林,発,14:29#木太町,発,14:33#屋島,発,14:37#古高松南,発,14:39#八栗口,発,14:42#讃岐牟礼,発,14:44#志度,発,14:50#オレンジタウン,発,14:54#造田,発,15:10#神前,発,15:13#讃岐津田,発,15:18#鶴羽,発,15:22#丹生,発,15:27#三本松,着,15:30#", | ||||
| "4337D":"高松,発,14:16#昭和町,発,14:19#栗林公園北口,発,14:22#栗林,発,14:29#木太町,発,14:33#屋島,発,14:37#古高松南,発,14:39#八栗口,発,14:42#讃岐牟礼,発,14:44#志度,発,14:50#オレンジタウン,発,14:54#造田,発,15:10#神前,発,15:13#讃岐津田,発,15:18#鶴羽,発,15:22#丹生,発,15:27#三本松,着,15:30#", | ||||
| "4339D":"高松,発,15:01#昭和町,発,15:04#栗林公園北口,発,15:06#栗林,発,15:09#木太町,発,15:12#屋島,発,15:23#古高松南,発,15:26#八栗口,発,15:28#讃岐牟礼,発,15:30#志度,発,15:39#オレンジタウン,着,15:42#", | ||||
| "4341D":"板野,発,15:26#阿波川端,発,15:29#板東,発,15:36#池谷,発,15:40#勝瑞,発,15:44#吉成,発,15:46#佐古,発,15:52#徳島,着,15:55#", | ||||
| "4343D":"板野,発,16:21#阿波川端,発,16:24#板東,発,16:28#池谷,発,16:38#勝瑞,発,16:45#吉成,発,16:51#佐古,発,17:03#徳島,着,17:06#", | ||||
| "4343D":"板野,発,16:21#阿波川端,発,16:24#板東,発,16:28#池谷,発,16:38#勝瑞,発,16:45#吉成,発,16:53#佐古,発,17:03#徳島,着,17:06#", | ||||
| "4349D":"板野,発,17:46#阿波川端,発,17:50#板東,発,17:53#池谷,発,17:56#勝瑞,発,18:00#吉成,発,18:03#佐古,発,18:09#徳島,着,18:12#", | ||||
| "4351D":"板野,発,18:32#阿波川端,発,18:35#板東,発,18:41#池谷,発,18:47#勝瑞,発,18:53#吉成,発,18:58#佐古,発,19:07#徳島,着,19:09#", | ||||
| "4353D":"引田,発,18:25#讃岐相生,発,18:29#阿波大宮,発,18:36#板野,発,18:48#阿波川端,発,18:51#板東,発,18:55#池谷,発,19:00#勝瑞,発,19:22#吉成,発,19:25#佐古,発,19:34#徳島,着,19:37#", | ||||
| "4359D":"板野,発,19:35#阿波川端,発,19:38#板東,発,19:44#池谷,発,19:48#勝瑞,発,19:53#吉成,発,19:56#佐古,発,20:02#徳島,着,20:05#", | ||||
| "4365D":"板野,発,21:07#阿波川端,発,21:10#板東,発,21:14#池谷,発,21:17#勝瑞,発,21:21#吉成,発,21:24#佐古,発,21:34#徳島,着,21:37#", | ||||
| @@ -833,6 +835,7 @@ | ||||
| "478D":"阿波池田,発,18:09#佃,発,18:15#辻,発,18:18#阿波加茂,発,18:23#三加茂,発,18:26#江口,発,18:30#阿波半田,発,18:36#貞光,発,18:40#小島,発,18:49#穴吹,発,19:08#川田,発,19:15#阿波山川,発,19:19#山瀬,発,19:23#学,発,19:31#阿波川島,発,19:37#西麻植,発,19:40#鴨島,発,19:43#麻植塚,発,19:46#牛島,発,19:49#下浦,発,19:53#石井,発,19:57#府中,発,20:01#鮎喰,発,20:05#蔵本,発,20:08#佐古,発,20:11#徳島,着,20:14#", | ||||
| "480D":"阿波池田,発,19:05#佃,発,19:13#辻,発,19:16#阿波加茂,発,19:21#三加茂,発,19:25#江口,発,19:28#阿波半田,発,19:35#貞光,発,19:41#小島,発,19:50#穴吹,発,20:02#川田,発,20:07#阿波山川,発,20:11#山瀬,発,20:15#学,発,20:19#阿波川島,発,20:26#西麻植,発,20:29#鴨島,発,20:38#麻植塚,発,20:41#牛島,発,20:54#下浦,発,20:57#石井,発,21:01#府中,発,21:05#鮎喰,発,21:09#蔵本,発,21:14#佐古,発,21:17#徳島,着,21:20#", | ||||
| "482D":"穴吹,発,21:20#川田,発,21:26#阿波山川,発,21:30#山瀬,発,21:34#学,発,21:38#阿波川島,発,21:45#西麻植,発,21:48#鴨島,発,21:51#麻植塚,発,21:54#牛島,発,21:57#下浦,発,22:01#石井,発,22:05#府中,発,22:09#鮎喰,発,22:13#蔵本,発,22:15#佐古,発,22:18#徳島,着,22:21#", | ||||
| "484D":"阿波池田,発,21:17#佃,発,21:23#辻,発,21:29#阿波加茂,発,21:34#三加茂,発,21:37#江口,発,21:41#阿波半田,発,21:48#貞光,発,21:52#小島,発,21:58#穴吹,発,22:08#川田,発,22:13#阿波山川,発,22:18#山瀬,発,22:22#学,発,22:26#阿波川島,発,22:31#西麻植,発,22:34#鴨島,発,22:42#麻植塚,発,22:45#牛島,発,22:48#下浦,発,22:51#石井,発,22:55#府中,発,22:59#鮎喰,発,23:03#蔵本,発,23:07#佐古,発,23:10#徳島,着,23:13#", | ||||
| "4002D":"阿波池田,発,6:46#阿波加茂,発,6:57#貞光,発,7:09#穴吹,発,7:22#阿波山川,発,7:30#阿波川島,発,7:39#鴨島,発,7:43#石井,発,7:51#蔵本,発,7:58#徳島,着,8:02#", | ||||
| "4004D":"阿波池田,発,8:32#阿波加茂,発,8:43#貞光,発,8:55#穴吹,発,9:05#阿波山川,発,9:13#阿波川島,発,9:25#鴨島,発,9:29#石井,発,9:37#蔵本,発,9:43#徳島,着,9:47#", | ||||
| "4006D":"阿波池田,発,11:30#阿波加茂,発,11:41#貞光,発,11:53#穴吹,発,12:03#阿波山川,発,12:11#阿波川島,発,12:23#鴨島,発,12:27#蔵本,発,12:40#徳島,着,12:45#", | ||||
| @@ -848,7 +851,6 @@ | ||||
| "4462D":"阿波川島,発,14:13#西麻植,発,14:16#鴨島,発,14:22#麻植塚,発,14:25#牛島,発,14:29#下浦,発,14:33#石井,発,14:36#府中,発,14:41#鮎喰,発,14:44#蔵本,発,14:50#佐古,発,14:53#徳島,着,14:56#", | ||||
| "4466D":"阿波川島,発,15:04#西麻植,発,15:07#鴨島,発,15:10#麻植塚,発,15:13#牛島,発,15:17#下浦,発,15:20#石井,発,15:37#府中,発,15:41#鮎喰,発,15:45#蔵本,発,15:52#佐古,発,15:55#徳島,着,15:58#", | ||||
| "4468D":"穴吹,発,15:15#川田,発,15:21#阿波山川,発,15:25#山瀬,発,15:29#学,発,15:37#阿波川島,発,15:43#西麻植,発,15:46#鴨島,発,15:52#麻植塚,発,15:55#牛島,発,15:59#下浦,発,16:03#石井,発,16:06#府中,発,16:11#鮎喰,発,16:14#蔵本,発,16:20#佐古,発,16:23#徳島,着,16:26#", | ||||
| "4484D":"阿波池田,発,21:17#佃,発,21:23#辻,発,21:29#阿波加茂,発,21:34#三加茂,発,21:37#江口,発,21:41#阿波半田,発,21:48#貞光,発,21:52#小島,発,21:58#穴吹,発,22:08#川田,発,22:13#阿波山川,発,22:18#山瀬,発,22:22#学,発,22:26#阿波川島,発,22:31#西麻植,発,22:34#鴨島,発,22:42#麻植塚,発,22:45#牛島,発,22:48#下浦,発,22:51#石井,発,22:55#府中,発,22:59#鮎喰,発,23:03#蔵本,発,23:07#佐古,発,23:10#徳島,着,23:13#", | ||||
| "5440D":"阿波池田,発,6:52#佃,発,7:00#辻,発,7:04#阿波加茂,発,7:10#三加茂,発,7:13#江口,発,7:20#阿波半田,発,7:26#貞光,発,7:32#小島,発,7:41#穴吹,発,7:49#川田,発,7:56#阿波山川,発,8:01#山瀬,発,8:05#学,発,8:09#阿波川島,発,8:13#西麻植,発,8:17#鴨島,発,8:20#麻植塚,発,8:23#牛島,発,8:27#下浦,発,8:31#石井,発,8:34#府中,発,8:39#鮎喰,発,8:42#蔵本,発,8:45#佐古,発,8:48#徳島,着,8:51#", | ||||
| "5442D":"穴吹,発,8:12#川田,発,8:18#阿波山川,発,8:22#山瀬,発,8:26#学,発,8:31#阿波川島,発,8:36#西麻植,発,8:40#鴨島,発,8:43#麻植塚,発,8:47#牛島,発,8:50#下浦,発,8:55#石井,発,8:59#府中,発,9:08#鮎喰,発,9:12#蔵本,発,9:20#佐古,発,9:24#徳島,着,9:27#", | ||||
| "5444D":"穴吹,発,8:48#川田,発,8:54#阿波山川,発,8:58#山瀬,発,9:02#学,発,9:06#阿波川島,発,9:11#西麻植,発,9:15#鴨島,発,9:21#麻植塚,発,9:24#牛島,発,9:37#下浦,発,9:40#石井,発,9:44#府中,発,9:49#鮎喰,発,9:52#蔵本,発,9:58#佐古,発,10:01#徳島,着,10:04#", | ||||
| @@ -867,8 +869,8 @@ | ||||
| "477D":"徳島,発,19:15#佐古,発,19:19#蔵本,発,19:23#鮎喰,発,19:25#府中,発,19:29#石井,発,19:34#下浦,発,19:38#牛島,発,19:49#麻植塚,発,19:53#鴨島,発,19:56#西麻植,発,19:59#阿波川島,発,20:03#学,発,20:08#山瀬,発,20:15#阿波山川,発,20:19#川田,発,20:30#穴吹,発,20:37#小島,発,20:44#貞光,発,20:51#阿波半田,発,20:54#江口,発,21:01#三加茂,発,21:05#阿波加茂,発,21:08#辻,発,21:14#佃,発,21:22#阿波池田,着,21:28#", | ||||
| "479D":"徳島,発,19:46#佐古,発,19:50#蔵本,発,19:53#鮎喰,発,19:56#府中,発,20:01#石井,発,20:06#下浦,発,20:10#牛島,発,20:14#麻植塚,発,20:17#鴨島,発,20:20#西麻植,発,20:23#阿波川島,発,20:47#学,発,20:52#山瀬,発,20:56#阿波山川,発,21:00#川田,発,21:04#穴吹,着,21:09#", | ||||
| "483D":"徳島,発,21:07#佐古,発,21:10#蔵本,発,21:14#鮎喰,発,21:16#府中,発,21:19#石井,発,21:24#下浦,発,21:28#牛島,発,21:32#麻植塚,発,21:35#鴨島,発,21:38#西麻植,発,21:42#阿波川島,発,21:45#学,発,21:49#山瀬,発,21:53#阿波山川,発,21:57#川田,発,22:01#穴吹,発,22:09#小島,発,22:15#貞光,発,22:22#阿波半田,発,22:25#江口,発,22:32#三加茂,発,22:36#阿波加茂,発,22:39#辻,発,22:44#佃,発,22:47#阿波池田,着,22:53#", | ||||
| "485D":"徳島,発,22:07#佐古,発,22:10#蔵本,発,22:15#鮎喰,発,22:17#府中,発,22:21#石井,発,22:25#下浦,発,22:29#牛島,発,22:33#麻植塚,発,22:37#鴨島,発,22:40#西麻植,発,22:43#阿波川島,発,22:47#学,発,22:51#山瀬,発,22:56#阿波山川,発,22:59#川田,発,23:03#穴吹,着,23:09#", | ||||
| "487D":"徳島,発,23:00#佐古,発,23:04#蔵本,発,23:07#鮎喰,発,23:09#府中,発,23:12#石井,発,23:17#下浦,発,23:21#牛島,発,23:25#麻植塚,発,23:28#鴨島,発,23:31#西麻植,発,23:34#阿波川島,発,23:37#学,発,23:41#山瀬,発,23:45#阿波山川,発,23:48#川田,発,23:52#穴吹,着,23:57#", | ||||
| "485D":"徳島,発,22:07#佐古,発,22:10#蔵本,発,22:15#鮎喰,発,22:17#府中,発,22:21#石井,発,22:25#下浦,発,22:29#牛島,発,22:33#麻植塚,発,22:37#鴨島,発,22:40#西麻植,発,22:43#阿波川島,発,22:47#学,発,22:51#山瀬,発,22:56#阿波山川,発,22:59#川田,発,23:03#穴吹,着,23:10#", | ||||
| "487D":"徳島,発,23:00#佐古,発,23:04#蔵本,発,23:07#鮎喰,発,23:09#府中,発,23:12#石井,発,23:17#下浦,発,23:21#牛島,発,23:25#麻植塚,発,23:28#鴨島,発,23:31#西麻植,発,23:34#阿波川島,発,23:37#学,発,23:41#山瀬,発,23:45#阿波山川,発,23:48#川田,発,23:52#穴吹,着,23:59#", | ||||
| "4001D":"徳島,発,6:46#蔵本,発,6:50#石井,発,6:57#鴨島,発,7:04#阿波川島,発,7:11#阿波山川,発,7:20#穴吹,発,7:35#貞光,発,7:47#阿波加茂,発,7:59#阿波池田,着,8:10#", | ||||
| "4003D":"徳島,発,9:00#蔵本,発,9:04#石井,発,9:11#鴨島,発,9:20#阿波川島,発,9:25#阿波山川,発,9:34#穴吹,発,9:42#貞光,発,9:53#阿波加茂,発,10:04#阿波池田,着,10:15#", | ||||
| "4005D":"徳島,発,12:00#蔵本,発,12:05#鴨島,発,12:17#阿波川島,発,12:23#阿波山川,発,12:33#穴吹,発,12:42#貞光,発,12:53#阿波加茂,発,13:05#阿波池田,着,13:17#", | ||||
| @@ -887,7 +889,7 @@ | ||||
| "4473D":"穴吹,発,19:29#小島,発,19:35#貞光,発,19:41#阿波半田,発,19:44#江口,発,19:51#三加茂,発,19:54#阿波加茂,発,20:00#辻,発,20:06#佃,発,20:09#阿波池田,着,20:15#", | ||||
| "5431D":"穴吹,発,6:48#小島,発,6:59#貞光,発,7:09#阿波半田,発,7:13#江口,発,7:20#三加茂,発,7:24#阿波加茂,発,7:28#辻,発,7:34#佃,発,7:37#阿波池田,着,7:43#", | ||||
| "5435D":"徳島,発,6:33#佐古,発,6:37#蔵本,発,6:40#鮎喰,発,6:44#府中,発,6:47#石井,発,7:01#下浦,発,7:05#牛島,発,7:22#麻植塚,発,7:26#鴨島,発,7:29#西麻植,発,7:33#阿波川島,発,7:38#学,発,7:43#山瀬,発,7:47#阿波山川,発,7:52#川田,発,7:56#穴吹,着,8:02#", | ||||
| "5473D":"徳島,発,18:13#佐古,発,18:16#蔵本,発,18:22#鮎喰,発,18:25#府中,発,18:28#石井,発,18:33#下浦,発,18:38#牛島,発,18:42#麻植塚,発,18:45#鴨島,発,18:49#西麻植,発,18:54#阿波川島,発,18:58#学,発,19:03#山瀬,発,19:07#阿波山川,発,19:11#川田,発,19:16#穴吹,着,19:21#", | ||||
| "5473D":"徳島,発,18:13#佐古,発,18:16#蔵本,発,18:22#鮎喰,発,18:25#府中,発,18:28#石井,発,18:33#下浦,発,18:38#牛島,発,18:42#麻植塚,発,18:45#鴨島,発,18:49#西麻植,発,18:52#阿波川島,発,18:58#学,発,19:03#山瀬,発,19:07#阿波山川,発,19:11#川田,発,19:16#穴吹,着,19:21#", | ||||
| "5475D":"徳島,発,18:44#佐古,発,18:47#蔵本,発,18:50#鮎喰,発,18:53#府中,発,18:57#石井,発,19:03#下浦,発,19:08#牛島,発,19:21#麻植塚,発,19:24#鴨島,発,19:28#西麻植,発,19:31#阿波川島,発,19:36#学,発,19:41#山瀬,発,19:45#阿波山川,発,19:49#川田,発,19:53#穴吹,着,19:58#", | ||||
| "5481D":"徳島,発,20:33#佐古,発,20:37#蔵本,発,20:40#鮎喰,発,20:43#府中,発,20:47#石井,発,21:01#下浦,発,21:05#牛島,発,21:10#麻植塚,発,21:14#鴨島,発,21:18#西麻植,発,21:21#阿波川島,着,21:24#", | ||||
| "8451D":"徳島,発,10:32#府中,発,10:44#石井,発,10:51#学,発,11:21#山瀬,発,11:28#穴吹,発,11:47#小島,発,11:58#貞光,発,12:19#阿波加茂,発,12:40#阿波池田,着,12:59#", | ||||
| @@ -913,6 +915,8 @@ | ||||
| "574D":"阿南,発,18:58#阿波中島,発,19:02#西原,発,19:05#羽ノ浦,発,19:08#立江,発,19:12#阿波赤石,発,19:14#南小松島,発,19:21#中田,発,19:24#地蔵橋,発,19:28#文化の森,発,19:32#二軒屋,発,19:38#阿波富田,発,19:41#徳島,着,19:43#", | ||||
| "576D":"阿南,発,19:20#阿波中島,発,19:24#西原,発,19:27#羽ノ浦,発,19:33#立江,発,19:36#阿波赤石,発,19:39#南小松島,発,19:46#中田,発,19:49#地蔵橋,発,19:53#文化の森,発,19:56#二軒屋,発,20:06#阿波富田,発,20:08#徳島,着,20:11#", | ||||
| "578D":"阿南,発,20:16#阿波中島,発,20:20#西原,発,20:23#羽ノ浦,発,20:26#立江,発,20:30#阿波赤石,発,20:32#南小松島,発,20:37#中田,発,20:47#地蔵橋,発,20:51#文化の森,発,20:54#二軒屋,発,20:57#阿波富田,発,20:59#徳島,着,21:02#", | ||||
| "580D":"阿南,発,21:16#阿波中島,発,21:20#西原,発,21:23#羽ノ浦,発,21:26#立江,発,21:29#阿波赤石,発,21:32#南小松島,発,21:37#中田,発,21:40#地蔵橋,発,21:44#文化の森,発,21:48#二軒屋,発,21:51#阿波富田,発,21:53#徳島,着,21:56#", | ||||
| "582D":"阿南,発,22:06#阿波中島,発,22:10#西原,発,22:13#羽ノ浦,発,22:16#立江,発,22:19#阿波赤石,発,22:22#南小松島,発,22:27#中田,発,22:30#地蔵橋,発,22:34#文化の森,発,22:38#二軒屋,発,22:41#阿波富田,発,22:43#徳島,着,22:46#", | ||||
| "4538D":"阿波海南,発,8:17#浅川,発,8:21#鯖瀬,発,8:25#牟岐,発,8:44#辺川,発,8:48#山河内,発,8:55#日和佐,発,9:02#北河内,発,9:05#木岐,発,9:10#由岐,発,9:13#阿波福井,発,9:21#新野,発,9:25#桑野,発,9:30#阿波橘,発,9:35#見能林,発,9:38#阿南,着,9:41#", | ||||
| "4546D":"阿南,発,11:56#阿波中島,発,12:00#西原,発,12:03#羽ノ浦,発,12:07#立江,発,12:10#阿波赤石,発,12:13#南小松島,発,12:19#中田,発,12:23#地蔵橋,発,12:27#文化の森,発,12:30#二軒屋,発,12:36#阿波富田,発,12:38#徳島,着,12:41#", | ||||
| "4548D":"阿南,発,12:26#阿波中島,発,12:30#西原,発,12:33#羽ノ浦,発,12:37#立江,発,12:40#阿波赤石,発,12:43#南小松島,発,12:49#中田,発,12:53#地蔵橋,発,12:57#文化の森,発,13:00#二軒屋,発,13:06#阿波富田,発,13:08#徳島,着,13:11#", | ||||
| @@ -925,10 +929,10 @@ | ||||
| "4572D":"阿南,発,18:26#阿波中島,発,18:30#西原,発,18:33#羽ノ浦,発,18:37#立江,発,18:40#阿波赤石,発,18:43#南小松島,発,18:48#中田,発,18:51#地蔵橋,発,18:55#文化の森,発,18:58#二軒屋,発,19:06#阿波富田,発,19:09#徳島,着,19:12#", | ||||
| "4574D":"阿波海南,発,17:26#浅川,発,17:30#鯖瀬,発,17:34#牟岐,発,17:41#辺川,発,17:45#山河内,発,17:53#日和佐,発,18:03#北河内,発,18:06#木岐,発,18:11#由岐,発,18:16#阿波福井,発,18:24#新野,発,18:29#桑野,発,18:34#阿波橘,発,18:39#見能林,発,18:42#阿南,着,18:44#", | ||||
| "4578D":"阿波海南,発,18:30#浅川,発,18:34#鯖瀬,発,18:38#牟岐,発,18:46#辺川,発,18:51#山河内,発,18:58#日和佐,発,19:06#北河内,発,19:09#木岐,発,19:14#由岐,発,19:19#阿波福井,発,19:26#新野,発,19:31#桑野,発,19:36#阿波橘,発,19:41#見能林,発,19:44#阿南,着,19:46#", | ||||
| "4580D":"阿南,発,21:16#阿波中島,発,21:20#西原,発,21:23#羽ノ浦,発,21:26#立江,発,21:29#阿波赤石,発,21:32#南小松島,発,21:37#中田,発,21:40#地蔵橋,発,21:44#文化の森,発,21:48#二軒屋,発,21:51#阿波富田,発,21:53#徳島,着,21:56#", | ||||
| "4582D":"阿波海南,発,20:33#浅川,発,20:37#鯖瀬,発,20:42#牟岐,発,20:52#辺川,発,20:56#山河内,発,21:04#日和佐,発,21:10#北河内,発,21:13#木岐,発,21:18#由岐,発,21:22#阿波福井,発,21:30#新野,発,21:34#桑野,発,21:38#阿波橘,発,21:43#見能林,発,21:46#阿南,発,22:06#阿波中島,発,22:10#西原,発,22:13#羽ノ浦,発,22:16#立江,発,22:19#阿波赤石,発,22:22#南小松島,発,22:27#中田,発,22:30#地蔵橋,発,22:34#文化の森,発,22:38#二軒屋,発,22:41#阿波富田,発,22:43#徳島,着,22:46#", | ||||
| "4582D":"阿波海南,発,20:29#浅川,発,20:33#鯖瀬,発,20:39#牟岐,発,20:52#辺川,発,20:56#山河内,発,21:04#日和佐,発,21:10#北河内,発,21:13#木岐,発,21:18#由岐,発,21:22#阿波福井,発,21:30#新野,発,21:34#桑野,発,21:38#阿波橘,発,21:43#見能林,発,21:46#阿南,着,21:49#", | ||||
| "5052D":"牟岐,発,7:00#日和佐,発,7:13#由岐,発,7:22#新野,発,7:31#桑野,発,7:36#阿波橘,発,7:40#阿南,発,7:50#羽ノ浦,発,7:58#南小松島,発,8:06#阿波富田,発,8:16#徳島,着,8:18#", | ||||
| "521D":"牟岐,発,6:19#鯖瀬,発,6:24#浅川,発,6:28#阿波海南,着,6:31#", | ||||
| "523D":"徳島,発,5:31#阿波富田,発,5:34#二軒屋,発,5:37#文化の森,発,5:39#地蔵橋,発,5:42#中田,発,5:47#南小松島,発,5:50#阿波赤石,発,5:54#立江,発,6:00#羽ノ浦,発,6:03#西原,発,6:07#阿波中島,発,6:10#阿南,着,6:13#", | ||||
| "525D":"徳島,発,6:46#阿波富田,発,6:49#二軒屋,発,6:52#文化の森,発,6:54#地蔵橋,発,6:58#中田,発,7:02#南小松島,発,7:07#阿波赤石,発,7:12#立江,発,7:17#羽ノ浦,発,7:25#西原,発,7:29#阿波中島,発,7:32#阿南,発,7:46#見能林,発,7:49#阿波橘,発,7:52#桑野,発,7:59#新野,発,8:03#阿波福井,発,8:07#由岐,発,8:13#木岐,発,8:17#北河内,発,8:21#日和佐,発,8:24#山河内,発,8:31#辺川,発,8:38#牟岐,着,8:42#", | ||||
| "527D":"徳島,発,7:16#阿波富田,発,7:20#二軒屋,発,7:23#文化の森,発,7:25#地蔵橋,発,7:29#中田,発,7:34#南小松島,発,7:39#阿波赤石,発,7:44#立江,発,7:51#羽ノ浦,発,7:57#西原,発,8:00#阿波中島,発,8:04#阿南,発,8:11#見能林,発,8:14#阿波橘,発,8:18#桑野,着,8:23#", | ||||
| "529D":"徳島,発,7:51#阿波富田,発,7:55#二軒屋,発,7:58#文化の森,発,8:00#地蔵橋,発,8:03#中田,発,8:12#南小松島,発,8:16#阿波赤石,発,8:20#立江,発,8:22#羽ノ浦,発,8:26#西原,発,8:29#阿波中島,発,8:32#阿南,着,8:35#", | ||||
| @@ -949,7 +953,7 @@ | ||||
| "577D":"徳島,発,20:30#阿波富田,発,20:33#二軒屋,発,20:36#文化の森,発,20:39#地蔵橋,発,20:42#中田,発,20:47#南小松島,発,20:51#阿波赤石,発,20:55#立江,発,20:58#羽ノ浦,発,21:02#西原,発,21:06#阿波中島,発,21:09#阿南,着,21:14#", | ||||
| "579D":"徳島,発,21:23#阿波富田,発,21:26#二軒屋,発,21:29#文化の森,発,21:31#地蔵橋,発,21:34#中田,発,21:40#南小松島,発,21:44#阿波赤石,発,21:48#立江,発,21:51#羽ノ浦,発,21:54#西原,発,21:58#阿波中島,発,22:01#阿南,着,22:05#", | ||||
| "583D":"徳島,発,23:17#阿波富田,発,23:20#二軒屋,発,23:23#文化の森,発,23:25#地蔵橋,発,23:29#中田,発,23:34#南小松島,発,23:38#阿波赤石,発,23:42#立江,発,23:45#羽ノ浦,発,23:48#西原,発,23:52#阿波中島,発,23:55#阿南,着,23:59#", | ||||
| "4523D":"徳島,発,5:31#阿波富田,発,5:34#二軒屋,発,5:37#文化の森,発,5:39#地蔵橋,発,5:42#中田,発,5:47#南小松島,発,5:50#阿波赤石,発,5:54#立江,発,6:00#羽ノ浦,発,6:03#西原,発,6:07#阿波中島,発,6:10#阿南,発,6:22#見能林,発,6:25#阿波橘,発,6:28#桑野,発,6:37#新野,発,6:41#阿波福井,発,6:45#由岐,発,6:58#木岐,発,7:01#北河内,発,7:06#日和佐,発,7:31#山河内,発,7:38#辺川,発,7:45#牟岐,発,7:51#鯖瀬,発,7:56#浅川,発,8:00#阿波海南,着,8:03#", | ||||
| "4523D":"阿南,発,6:22#見能林,発,6:25#阿波橘,発,6:28#桑野,発,6:37#新野,発,6:41#阿波福井,発,6:45#由岐,発,6:58#木岐,発,7:01#北河内,発,7:06#日和佐,発,7:31#山河内,発,7:38#辺川,発,7:45#牟岐,発,7:51#鯖瀬,発,7:56#浅川,発,8:00#阿波海南,着,8:03#", | ||||
| "4533D":"徳島,発,9:30#阿波富田,発,9:33#二軒屋,発,9:36#文化の森,発,9:38#地蔵橋,発,9:42#中田,発,9:46#南小松島,発,9:50#阿波赤石,発,9:54#立江,発,9:57#羽ノ浦,発,10:07#西原,発,10:10#阿波中島,発,10:13#阿南,発,10:21#見能林,発,10:24#阿波橘,発,10:27#桑野,発,10:32#新野,発,10:37#阿波福井,発,10:40#由岐,発,10:52#木岐,発,10:55#北河内,発,11:00#日和佐,発,11:03#山河内,発,11:10#辺川,発,11:17#牟岐,発,11:26#鯖瀬,発,11:31#浅川,発,11:35#阿波海南,着,11:38#", | ||||
| "4537D":"徳島,発,10:30#阿波富田,発,10:33#二軒屋,発,10:36#文化の森,発,10:38#地蔵橋,発,10:42#中田,発,10:46#南小松島,発,10:50#阿波赤石,発,10:54#立江,発,10:57#羽ノ浦,発,11:07#西原,発,11:10#阿波中島,発,11:13#阿南,着,11:17#", | ||||
| "4539D":"徳島,発,11:00#阿波富田,発,11:03#二軒屋,発,11:06#文化の森,発,11:08#地蔵橋,発,11:12#中田,発,11:16#南小松島,発,11:20#阿波赤石,発,11:24#立江,発,11:27#羽ノ浦,発,11:37#西原,発,11:40#阿波中島,発,11:43#阿南,着,11:47#", | ||||
| @@ -960,90 +964,94 @@ | ||||
| "4551D":"徳島,発,14:00#阿波富田,発,14:03#二軒屋,発,14:06#文化の森,発,14:08#地蔵橋,発,14:12#中田,発,14:16#南小松島,発,14:20#阿波赤石,発,14:24#立江,発,14:27#羽ノ浦,発,14:37#西原,発,14:40#阿波中島,発,14:43#阿南,着,14:47#", | ||||
| "4557D":"牟岐,発,16:49#鯖瀬,発,16:54#浅川,発,16:58#阿波海南,着,17:01#", | ||||
| "4559D":"阿南,発,16:28#見能林,発,16:31#阿波橘,発,16:34#桑野,発,16:39#新野,発,16:43#阿波福井,発,16:47#由岐,発,16:54#木岐,発,16:57#北河内,発,17:02#日和佐,発,17:05#山河内,発,17:12#辺川,発,17:19#牟岐,発,17:39#鯖瀬,発,17:44#浅川,発,17:48#阿波海南,着,17:51#", | ||||
| "4567D":"牟岐,発,19:33#鯖瀬,発,19:38#浅川,発,19:42#阿波海南,着,19:46#", | ||||
| "4567D":"牟岐,発,19:33#鯖瀬,発,19:40#浅川,発,19:46#阿波海南,着,19:50#", | ||||
| "4579D":"阿南,発,22:12#見能林,発,22:15#阿波橘,発,22:18#桑野,発,22:23#新野,発,22:27#阿波福井,発,22:31#由岐,発,22:38#木岐,発,22:41#北河内,発,22:46#日和佐,発,22:49#山河内,発,22:56#辺川,発,23:03#牟岐,着,23:08#", | ||||
| "4581D":"徳島,発,22:11#阿波富田,発,22:14#二軒屋,発,22:17#文化の森,発,22:19#地蔵橋,発,22:22#中田,発,22:30#南小松島,発,22:34#阿波赤石,発,22:38#立江,発,22:41#羽ノ浦,発,22:44#西原,発,22:48#阿波中島,発,22:51#阿南,着,22:55#", | ||||
| "5051D":"徳島,発,19:33#阿波富田,発,19:36#南小松島,発,19:45#羽ノ浦,発,19:53#阿南,発,20:02#阿波橘,発,20:06#桑野,発,20:11#新野,発,20:16#由岐,発,20:26#日和佐,発,20:35#牟岐,着,20:51#", | ||||
| "9901D":"松山,発,8:26#市坪,発,8:33#伊予市,発,8:44#下灘,発,9:26#喜多灘,発,9:42#伊予大洲,着,10:28#", | ||||
| "9903D":"松山,発,13:31#北伊予,発,13:42#下灘,発,14:22#喜多灘,発,14:38#伊予大洲,発,15:13#伊予平野,発,15:37#八幡浜,着,15:50#", | ||||
| "9902D":"伊予大洲,発,10:57#伊予長浜,発,11:30#喜多灘,発,11:42#下灘,発,12:10#伊予上灘,発,12:30#北伊予,発,12:53#松山,着,13:01#", | ||||
| "9904D":"八幡浜,発,16:14#伊予大洲,発,16:33#伊予長浜,発,16:57#下灘,発,17:24#伊予上灘,発,17:36#伊予市,発,17:53#北伊予,発,18:03#市坪,発,18:12#松山,着,18:17#", | ||||
| "9003M":"高松,発,8:45#坂出,発,9:02#宇多津,発,9:07#丸亀,発,9:11#多度津,着,9:17#", | ||||
| "9003D":"高松,発,8:45#坂出,発,9:02#宇多津,発,9:07#丸亀,発,9:11#多度津,着,9:17#", | ||||
| "9005M":"高松,発,9:42#坂出,発,9:56#宇多津,発,10:01#丸亀,発,10:05#多度津,着,10:10#", | ||||
| "9005D":"高松,発,9:42#坂出,発,9:56#宇多津,発,10:01#丸亀,発,10:05#多度津,着,10:10#", | ||||
| "9007M":"高松,発,10:47#坂出,発,11:04#宇多津,発,11:09#丸亀,発,11:12#多度津,着,11:17#", | ||||
| "9007D":"高松,発,10:47#坂出,発,11:04#宇多津,発,11:09#丸亀,発,11:12#多度津,着,11:17#", | ||||
| "9007M":"高松,発,10:47#坂出,発,11:04#宇多津,発,11:09#丸亀,発,11:12#多度津,着,11:17#", | ||||
| "9009D":"高松,発,11:50#坂出,発,12:04#宇多津,発,12:09#丸亀,発,12:13#多度津,着,12:18#", | ||||
| "9009M":"高松,発,11:50#坂出,発,12:04#宇多津,発,12:09#丸亀,発,12:13#多度津,着,12:18#", | ||||
| "9011M":"高松,発,12:50#坂出,発,13:04#宇多津,発,13:09#丸亀,発,13:13#多度津,着,13:18#", | ||||
| "9013M":"高松,発,13:50#坂出,発,14:04#宇多津,発,14:09#丸亀,発,14:13#多度津,着,14:18#", | ||||
| "9013M":"高松,発,13:50#坂出,発,14:04#宇多津,発,14:10#丸亀,発,14:14#多度津,着,14:18#", | ||||
| "9015M":"高松,発,14:50#坂出,発,15:04#宇多津,発,15:10#丸亀,発,15:14#多度津,着,15:19#", | ||||
| "9017M":"高松,発,15:50#坂出,発,16:04#宇多津,発,16:10#丸亀,発,16:14#多度津,着,16:19#", | ||||
| "9019M":"高松,発,16:50#坂出,発,17:04#宇多津,発,17:10#丸亀,発,17:13#多度津,着,17:18#", | ||||
| "9019D":"高松,発,16:50#坂出,発,17:04#宇多津,発,17:10#丸亀,発,17:13#多度津,着,17:18#", | ||||
| "9019M":"高松,発,16:50#坂出,発,17:04#宇多津,発,17:10#丸亀,発,17:13#多度津,着,17:18#", | ||||
| "9021M":"高松,発,17:53#坂出,発,18:08#宇多津,発,18:13#丸亀,発,18:17#多度津,着,18:21#", | ||||
| "9021D":"高松,発,17:53#坂出,発,18:08#宇多津,発,18:13#丸亀,発,18:17#多度津,着,18:21#", | ||||
| "9023D":"高松,発,18:59#坂出,発,19:13#宇多津,発,19:17#丸亀,発,19:20#多度津,着,19:26#", | ||||
| "9023M":"高松,発,18:59#坂出,発,19:13#宇多津,発,19:17#丸亀,発,19:20#多度津,着,19:26#", | ||||
| "9023D":"高松,発,18:59#坂出,発,19:14#宇多津,発,19:18#丸亀,発,19:22#多度津,着,19:27#", | ||||
| "9025D":"高松,発,19:52#坂出,発,20:07#宇多津,発,20:12#丸亀,発,20:16#多度津,着,20:20#", | ||||
| "9025M":"高松,発,19:52#坂出,発,20:07#宇多津,発,20:12#丸亀,発,20:16#多度津,着,20:20#", | ||||
| "9027M":"高松,発,20:59#坂出,発,21:13#宇多津,発,21:18#丸亀,発,21:21#多度津,着,21:26#", | ||||
| "9057D":"高松,発,18:27#坂出,発,18:41#宇多津,発,18:46#丸亀,発,18:49#多度津,着,18:55#", | ||||
| "9004M":"宇多津,発,7:14#坂出,発,7:21#高松,着,7:36#", | ||||
| "9004D":"宇多津,発,7:14#坂出,発,7:21#高松,着,7:36#", | ||||
| "9006D":"宇多津,発,8:26#坂出,発,8:31#高松,着,8:45#", | ||||
| "9006M":"宇多津,発,8:26#坂出,発,8:31#高松,着,8:45#", | ||||
| "9008D":"宇多津,発,9:25#坂出,発,9:32#高松,着,9:47#", | ||||
| "9008M":"宇多津,発,9:25#坂出,発,9:32#高松,着,9:47#", | ||||
| "9010D":"宇多津,発,10:19#坂出,発,10:24#高松,着,10:39#", | ||||
| "9010M":"宇多津,発,10:19#坂出,発,10:24#高松,着,10:39#", | ||||
| "9012M":"宇多津,発,11:33#坂出,発,11:39#高松,着,11:54#", | ||||
| "9014M":"宇多津,発,12:33#坂出,発,12:39#高松,着,12:54#", | ||||
| "9016M":"宇多津,発,13:34#坂出,発,13:39#高松,着,13:55#", | ||||
| "9018M":"宇多津,発,14:34#坂出,発,14:39#高松,着,14:55#", | ||||
| "9020M":"宇多津,発,15:34#坂出,発,15:39#高松,着,15:55#", | ||||
| "9020D":"宇多津,発,15:34#坂出,発,15:39#高松,着,15:55#", | ||||
| "9022D":"宇多津,発,16:34#坂出,発,16:39#高松,着,16:54#", | ||||
| "9020M":"宇多津,発,15:34#坂出,発,15:39#高松,着,15:55#", | ||||
| "9022M":"宇多津,発,16:34#坂出,発,16:39#高松,着,16:54#", | ||||
| "9024D":"宇多津,発,17:35#坂出,発,17:41#高松,着,17:58#", | ||||
| "9024D":"宇多津,発,17:35#坂出,発,17:41#高松,着,17:57#", | ||||
| "9024M":"宇多津,発,17:35#坂出,発,17:41#高松,着,17:57#", | ||||
| "9026D":"宇多津,発,18:36#坂出,発,18:40#高松,着,18:54#", | ||||
| "9026M":"宇多津,発,18:36#坂出,発,18:40#高松,着,18:54#", | ||||
| "9028M":"宇多津,発,19:38#坂出,発,19:43#高松,着,19:56#", | ||||
| "9054D":"宇多津,発,9:00#坂出,発,9:07#高松,着,9:21#", | ||||
| "9072D":"牟岐,発,13:50#日和佐,発,14:08#由岐,発,14:17#桑野,発,14:32#阿南,発,14:48#羽ノ浦,発,14:56#南小松島,発,15:04#徳島,着,15:19#", | ||||
| "9073D":"後免,発,17:24#土佐大津,発,17:30#土佐一宮,発,17:43#薊野,発,17:53#高知,着,17:57#", | ||||
| "9025D":"高松,発,14:24#坂出,発,14:47#多度津,発,14:59#金蔵寺,発,15:03#善通寺,発,15:07#琴平,発,15:12#讃岐財田,発,15:43#阿波池田,発,15:59#三縄,発,16:25#大歩危,発,17:02#大田口,発,17:18#繁藤,発,17:40#後免,発,18:10#高知,着,18:19#", | ||||
| "9062D":"大歩危,発,14:21#小歩危,発,14:38#阿波川口,発,15:01#阿波池田,発,15:26#坪尻,発,15:53#讃岐財田,発,16:15#琴平,発,16:50#善通寺,発,17:01#金蔵寺,発,17:09#多度津,着,17:14#", | ||||
| "9061D":"多度津,発,10:19#善通寺,発,10:26#琴平,発,10:48#讃岐財田,発,11:12#坪尻,発,11:41#阿波池田,発,12:10#三縄,発,12:19#大歩危,着,12:47#", | ||||
| "9066D":"阿波池田,発,19:53#坪尻,発,20:21#琴平,着,20:42#", | ||||
| "9221D":"高松,発,8:51#端岡,発,9:04#多度津,発,9:25#金蔵寺,発,9:33#善通寺,発,9:53#琴平,発,10:00#箸蔵,発,10:34#阿波池田,発,10:44#小歩危,発,11:10#大杉,発,11:46#繁藤,発,12:10#土佐山田,発,12:28#土佐大津,発,12:36#薊野,発,12:48#高知,着,12:50#", | ||||
| "9226D":"高知運転所,発,14:51#土佐一宮,発,15:00#土佐大津,発,15:09#後免,発,15:33#土佐山田,発,15:41#新改,発,15:55#繁藤,発,16:13#大歩危,発,17:16#三縄,発,17:40#阿波池田,発,17:47#塩入,発,18:12#琴平,発,18:27#多度津,発,18:41#宇多津,発,19:00#坂出,発,19:06#端岡,発,19:18#高松,着,19:25#", | ||||
| "9222D":"高知,発,13:00#土佐一宮,発,13:06#高知運転所,着,13:10#", | ||||
| "9903D":"松山,発,10:34#伊予市,発,10:54#下灘,発,11:51#喜多灘,発,12:07#伊予白滝,発,12:42#伊予大洲,発,13:08#千丈,発,13:30#八幡浜,発,13:40#双岩,発,14:26#卯之町,着,14:40#", | ||||
| "9053M":"高松,発,7:23#坂出,発,7:37#宇多津,発,7:42#丸亀,発,7:46#多度津,着,7:51#", | ||||
| "9057M":"高松,発,18:27#坂出,発,18:41#宇多津,発,18:46#丸亀,発,18:49#多度津,着,18:55#", | ||||
| "9054M":"宇多津,発,9:00#坂出,発,9:07#高松,着,9:21#", | ||||
| "9056M":"宇多津,発,21:22#坂出,発,21:28#高松,着,21:42#", | ||||
| "9044D":"徳島,発,22:48#池谷,発,23:00#板野,発,23:06#引田,発,23:21#三本松,発,23:30#讃岐津田,発,23:38#志度,発,23:47#屋島,発,23:53#栗林,発,23:58#高松,着,0:03#", | ||||
| "9052D":"窪川,発,15:13#土佐久礼,発,15:46#安和,発,15:57#須崎,発,16:25#佐川,発,16:54#日下,発,17:11#伊野,発,17:32#朝倉,発,17:42#高知,着,17:53#", | ||||
| "9071D":"徳島,発,8:40#南小松島,発,9:08#羽ノ浦,発,9:15#阿南,発,9:23#桑野,発,9:33#由岐,発,9:46#日和佐,発,9:58#牟岐,着,10:12#", | ||||
| "9074D":"窪川,発,16:18#土佐久礼,発,16:35#吾桑,発,16:57#佐川,発,17:10#日下,発,17:32#伊野,発,18:00#朝倉,発,18:10#旭,発,18:21#高知,着,18:25#", | ||||
| "9124D":"松山,発,10:07#伊予和気,発,10:18#伊予北条,発,10:45#浅海,発,11:00#伊予亀岡,発,11:54#波止浜,発,12:16#今治,発,12:41#伊予富田,発,12:48#壬生川,発,13:26#伊予西条,発,13:39#中荻,発,13:49#新居浜,発,13:54#多喜浜,発,14:06#関川,発,14:20#伊予三島,発,15:17#川之江,発,15:30#箕浦,発,15:45#豊浜,発,15:55#観音寺,発,16:23#本山,発,16:37#詫間,発,16:51#海岸寺,発,17:02#多度津,発,17:35#宇多津,発,17:55#鴨川,発,18:15#端岡,発,18:38#高松,着,18:46#", | ||||
| "9107D":"児島,発,20:20#坂出,発,20:41#端岡,発,21:09#高松,着,21:17#", | ||||
| "9102D":"高松,発,8:48#坂出,発,9:15#児島,着,9:43#", | ||||
| "9906D":"卯之町,発,15:32#伊予石城,発,15:44#八幡浜,発,16:14#伊予大洲,発,16:33#伊予長浜,発,16:57#下灘,発,17:24#伊予上灘,発,17:36#伊予市,発,17:53#北伊予,発,18:03#市坪,発,18:12#松山,着,18:17#", | ||||
| "9081D":"高松,発,8:58#端岡,発,9:19#坂出,発,9:34#宇多津,発,9:46#多度津,発,10:01#善通寺,発,10:12#琴平,着,10:17#", | ||||
| "9084D":"琴平,発,13:36#善通寺,発,14:10#多度津,着,14:16#", | ||||
| "9086D":"多度津,発,16:40#宇多津,発,16:56#鴨川,発,17:28#端岡,発,17:36#高松,着,17:44#", | ||||
| "9065D":"塩入,発,17:40#讃岐財田,発,17:56#坪尻,発,18:58#箸蔵,発,19:13#阿波池田,着,19:28#", | ||||
| "9093D":"松山,発,13:31#北伊予,発,13:42#下灘,発,14:22#喜多灘,発,14:38#伊予大洲,発,15:13#伊予平野,発,15:37#八幡浜,着,15:50#", | ||||
| "9095D":"松山,発,10:34#伊予市,発,10:54#下灘,発,11:51#喜多灘,発,12:07#伊予白滝,発,12:42#伊予大洲,着,13:07#", | ||||
| "9096D":"伊予大洲,発,13:30#伊予白滝,発,13:47#伊予長浜,発,14:24#喜多灘,発,14:36#下灘,発,15:09#伊予上灘,発,15:31#北伊予,発,15:54#松山,着,16:00#", | ||||
| "9063D":"琴平,発,11:29#塩入,発,11:42#坪尻,発,12:12#箸蔵,発,12:31#阿波池田,発,13:56#阿波川口,発,14:15#大歩危,着,14:34#", | ||||
| "9051D":"高知,発,12:04#朝倉,発,12:29#伊野,発,12:49#日下,発,13:06#西佐川,発,13:21#須崎,発,13:45#安和,発,14:05#土佐久礼,発,14:17#影野,発,14:31#窪川,着,14:40", | ||||
| "9087D":"高松,発,15:07#端岡,発,15:24#坂出,発,15:44#宇多津,発,15:52#多度津,発,16:07#善通寺,発,16:21#琴平,発,16:54#讃岐財田,発,17:18#坪尻,発,17:30#阿波池田,発,17:40#阿波川口,発,17:54#大歩危,発,18:06#大杉,発,18:24#繁藤,発,18:40#新改,発,18:58#御免,発,19:09#土佐大津,発,19:17#薊野,発,19:33#高知,着,19:36#", | ||||
| "9064D":"大歩危,発,13:30#小歩危,発,13:46#阿波川口,発,14:03#阿波池田,発,14:41#箸蔵,発,15:00#坪尻,発,15:14#琴平,着,15:43#", | ||||
| "9323D":"高松,発,9:32#栗林,発,9:53#屋島,発,10:24#八栗口,発,10:40#志度,発,11:32#造田,発,12:14#讃岐津田,発,12:36#三本松,発,13:02#讃岐相生,発,13:31#阿波大宮,発,13:46#板野,発,14:06#板東,発,14:24#池谷,発,14:33#勝瑞,発,14:43#徳島,着,14:56#", | ||||
| "9105D":"児島,発,13:44#坂出,発,14:10#鴨川,発,14:37#端岡,発,14:52#高松,着,15:01#", | ||||
| "9104D":"高松,発,10:21#鴨川,発,10:38#坂出,発,11:08#児島,着,11:29#", | ||||
| "9633D":"八幡浜,発,10:08#双岩,発,10:24#伊予石城,発,10:43#上宇和,発,10:47#卯之町,着,10:50#", | ||||
| "9637D":"八幡浜,発,14:31#双岩,発,14:40#伊予石城,発,14:59#上宇和,発,15:03#卯之町,着,15:06#", | ||||
| "9665D":"八幡浜,発,13:40#双岩,発,13:47#伊予石城,発,14:04#上宇和,発,14:08#卯之町,発,14:34#下宇和,発,14:38#立間,発,14:45#伊予吉田,発,15:04#高光,発,15:10#北宇和島,発,15:14#宇和島,着,15:16#", | ||||
| "9662D":"宇和島,発,10:00#北宇和島,発,10:04#高光,発,10:07#伊予吉田,発,10:13#立間,発,10:19#下宇和,発,10:30#卯之町,発,10:34#上宇和,発,10:37#伊予石城,発,10:45#双岩,発,10:51#八幡浜,着,10:57#", | ||||
| "9634D":"卯之町,発,11:22#上宇和,発,11:25#伊予石城,発,11:40#双岩,発,11:46#八幡浜,着,11:52#", | ||||
| "9636D":"卯之町,発,15:35#上宇和,発,15:38#伊予石城,発,15:52#双岩,発,15:58#八幡浜,着,16:04#", | ||||
| "9091D":"松山,発,8:26#市坪,発,8:33#伊予市,発,8:44#下灘,発,9:26#喜多灘,発,9:42#伊予大洲,着,10:28#", | ||||
| "9641M":"松山,発,15:00#市坪,着,15:04#", | ||||
| "9643M":"松山,発,15:41#市坪,着,15:45#", | ||||
| "9645M":"松山,発,16:06#市坪,着,16:10#", | ||||
| "9647M":"松山,発,16:27#市坪,着,16:31#", | ||||
| "9649M":"松山,発,16:59#市坪,着,17:03#", | ||||
| "9651M":"松山,発,17:46#市坪,着,17:50#", | ||||
| "9661D":"松山,発,21:38#市坪,発,21:42#北伊予,発,21:46#南伊予,発,21:49#伊予横田,発,21:51#鳥ノ木,発,21:54#伊予市,着,21:56#", | ||||
| "9652M":"市坪,発,18:59#松山,着,19:03#", | ||||
| "9654M":"市坪,発,19:54#松山,着,19:58#", | ||||
| "9656M":"市坪,発,20:32#松山,着,20:36#", | ||||
| "9658D":"市坪,発,20:51#松山,着,20:55#", | ||||
| "9660M":"市坪,発,21:19#松山,着,21:23#", | ||||
| "9662M":"市坪,発,21:50#松山,着,21:54#", | ||||
| "9664M":"市坪,発,22:13#松山,着,22:17#", | ||||
| "9666D":"北伊予,発,22:46#市坪,発,22:50#松山,着,22:55#", | ||||
| "9668M":"市坪,発,23:00#松山,着,23:04#", | ||||
| "9052D":"窪川,発,15:13#土佐久礼,発,15:46#安和,発,15:57#須崎,発,16:25#佐川,発,16:54#日下,発,17:11#伊野,発,17:32#朝倉,発,17:42#高知,着,17:53#", | ||||
| "9062D":"大歩危,発,14:21#小歩危,発,14:38#阿波川口,発,15:01#阿波池田,発,15:26#坪尻,発,15:53#讃岐財田,発,16:15#琴平,発,16:50#善通寺,発,17:01#金蔵寺,発,17:09#多度津,着,17:14#", | ||||
| "9920D":"伊予大洲,発,14:33#五郎,発,14:39#伊予白滝,発,14:59#伊予長浜,発,15:09#下灘,発,15:23#伊予上灘,発,15:30#伊予市,発,15:44#南伊予,発,15:49#北伊予,発,15:55#松山,着,16:01#", | ||||
| "9051D":"高知,発,12:04#朝倉,発,12:29#伊野,発,12:49#日下,発,13:06#西佐川,発,13:21#須崎,発,13:45#安和,発,14:05#土佐久礼,発,14:17#影野,発,14:31#窪川,着,14:40#", | ||||
| "9061D":"多度津,発,10:19#善通寺,発,10:26#琴平,発,10:48#讃岐財田,発,11:12#坪尻,発,11:41#阿波池田,発,12:10#三縄,発,12:19#大歩危,着,12:47#", | ||||
| "9523D":"川之江,発,9:00#伊予三島,発,9:15#伊予寒川,発,9:31#伊予土居,発,10:03#関川,発,10:16#多喜浜,発,10:31#中萩,発,10:49#伊予西条,着,10:57#", | ||||
| "9524D":"伊予西条,発,11:11#新居浜,発,11:35#伊予土居,発,11:59#伊予寒川,発,12:08#伊予三島,発,12:17#川之江,着,12:24#", | ||||
| "9987D":"鳴門,発,22:15#撫養,発,22:18#金比羅前,発,22:21#教会前,発,22:24#立道,発,22:27#阿波大谷,発,22:31#池谷,発,22:36#勝瑞,発,22:41#吉成,発,22:44#佐古,発,22:57#徳島,着,23:00#", | ||||
| "9093D":"松山,発,13:31#北伊予,発,13:42#下灘,発,14:22#喜多灘,発,14:38#伊予大洲,発,15:13#伊予平野,発,15:37#八幡浜,着,15:50#", | ||||
| "9094D":"八幡浜,発,16:14#伊予大洲,発,16:33#伊予長浜,発,16:57#下灘,発,17:24#伊予上灘,発,17:36#伊予市,発,17:53#北伊予,発,18:03#市坪,発,18:12#松山,着,18:17#", | ||||
| "9061M":"高松,発,9:13#端岡,発,9:23#鴨川,発,9:38#丸亀,発,9:50#多度津,発,10:09#詫間,発,10:25#高瀬,発,10:35#豊浜,発,11:00#伊予寒川,発,11:20#多喜浜,発,11:36#伊予西条,発,11:48#伊予桜井,発,12:11#波止浜,発,12:26#伊予亀岡,発,13:02#堀江,発,13:23#伊予和気,発,13:32#松山,発,13:49#伊予市,着,13:59#", | ||||
| "9062M":"伊予市,発,14:39#北伊予,発,14:47#松山,発,14:55#伊予和気,発,15:06#堀江,発,15:11#粟井,発,15:16#大西,発,15:35#波止浜,発,15:45#伊予桜井,発,15:59#壬生川,発,16:11#伊予小松,発,16:29#伊予西条,発,16:40#中荻,発,16:50#関川,発,17:05#伊予土居,発,17:17#伊予三島,発,17:27#豊浜,発,17:50#観音寺,発,17:56#本山,発,18:05#高瀬,発,18:12#詫間,発,18:33#多度津,発,18:42#宇多津,発,19:00#坂出,発,19:11#高松,着,19:25#", | ||||
| "9091D":"伊予大洲,発,10:58#千丈,発,11:31#八幡浜,発,11:55#伊予石城,発,12:31#卯之町,発,14:55#立間,発,15:08#伊予吉田,発,15:19#北宇和島,発,15:37#宇和島,着,15:40#", | ||||
| "9092D":"宇和島,発,8:55#北宇和島,発,9:08#伊予吉田,発,9:22#卯之町,発,9:47#双岩,発,10:00#伊予大洲,着,10:26#", | ||||
| "9503D":"徳島,発,8:40#二軒屋,発,8:49#南小松島,発,9:08#阿南,発,9:27#牟岐,発,10:06#阿波海南,着,10:15#", | ||||
| "9506D":"阿波海南,発,15:10#牟岐,発,15:21#桑野,発,16:39#阿南,発,16:49#羽ノ浦,発,17:01#中田,発,17:16#二軒屋,発,17:27#徳島,着,17:31#"} | ||||
| "9205D":"児島,発,15:10#宇多津,発,15:28#丸亀,発,15:31#多度津,発,15:36#琴平,発,15:47#讃岐財田,発,16:14#坪尻,発,16:35#佃,発,16:51#阿波池田,発,16:57#阿波川口,発,17:16#大歩危,発,17:35#大田口,発,17:58#大杉,発,18:30#土佐北川,発,18:47#繁藤,発,19:02#土佐山田,発,19:17#後免,発,19:22#土佐一宮,発,19:43#高知,着,19:47#", | ||||
| "9204D":"高知,発,8:43#土佐一宮,発,8:49#繁藤,発,9:16#大杉,発,9:28#土佐岩原,発,9:48#大歩危,発,10:08#阿波川口,発,10:29#阿波池田,発,10:42#讃岐財田,発,11:09#琴平,発,11:33#金蔵寺,発,11:59#多度津,発,12:06#丸亀,発,12:10#児島,着,12:25#", | ||||
| "9003M":"高松,発,8:45#坂出,発,9:02#宇多津,着,9:06#", | ||||
| "9005D":"高松,発,9:42#坂出,発,9:56#宇多津,発,10:01#丸亀,発,10:05#多度津,着,10:10#", | ||||
| "9004M":"宇多津,発,7:14#坂出,発,7:21#高松,着,7:36#", | ||||
| "9006D":"宇多津,発,8:26#坂出,発,8:31#高松,着,8:45#", | ||||
| "9253M":"児島,発,11:02#多度津,発,11:30#善通寺,発,11:54#琴平,着,12:00#", | ||||
| "9256M":"琴平,発,15:20#善通寺,発,15:26#多度津,発,15:35#宇多津,発,15:44#児島,着,16:04#", | ||||
| "9057M":"高松,発,18:27#坂出,発,18:41#宇多津,発,18:46#丸亀,発,18:49#多度津,着,18:55#", | ||||
| "9054M":"宇多津,発,9:00#坂出,発,9:07#高松,着,9:21#" | ||||
| } | ||||
| @@ -14,7 +14,7 @@ export default [ | ||||
| {"Station_JP" : "八幡浜",   "Station_EN" : "Yawatahama",    "MyStation" : "11", "StationNumber" : "U18", "DispNum" : "3", "StationTimeTable" : "http://www.jr-shikoku.co.jp/01_trainbus/jikoku/pdf/yawatahama.pdf",    "StationMap":"https://www.google.co.jp/maps/place/33.458146,132.436002", "JrHpUrl" : "http://www.jr-shikoku.co.jp/01_trainbus/kakueki/yawatahama/"}, | ||||
| {"Station_JP" : "双岩",     "Station_EN" : "Futaiwa",       "MyStation" : "12", "StationNumber" : "U19", "DispNum" : "2", "StationTimeTable" : "http://www.jr-shikoku.co.jp/01_trainbus/jikoku/pdf/futaiwa.pdf",       "StationMap":"https://www.google.co.jp/maps/place/33.424669,132.457934", "JrHpUrl" : ""}, | ||||
| {"Station_JP" : "伊予石城", "Station_EN" : "Iyo-Iwaki",     "MyStation" : "13", "StationNumber" : "U20", "DispNum" : "2", "StationTimeTable" : "http://www.jr-shikoku.co.jp/01_trainbus/jikoku/pdf/iyo-iwaki.pdf",     "StationMap":"https://www.google.co.jp/maps/place/33.391413,132.473259", "JrHpUrl" : ""}, | ||||
| {"Station_JP" : "卯之町",   "Station_EN" : "Unomachi",      "MyStation" : "14", "StationNumber" : "U22", "DispNum" : "3", "StationTimeTable" : "http://www.jr-shikoku.co.jp/01_trainbus/jikoku/pdf/unomachi.pdf",      "StationMap":"https://www.google.co.jp/maps/place/33.363175,132.509959", "JrHpUrl" : "http://www.jr-shikoku.co.jp/01_trainbus/kakueki/unomachi/"}, | ||||
| {"Station_JP" : "卯之町",   "Station_EN" : "Unomachi",      "MyStation" : "14", "StationNumber" : "U22", "DispNum" : "3", "StationTimeTable" : "http://www.jr-shikoku.co.jp/01_trainbus/jikoku/pdf/unomachi.pdf",      "StationMap":"https://www.google.co.jp/maps/place/33.363175,132.509959", "JrHpUrl" : ""}, | ||||
| {"Station_JP" : "下宇和",   "Station_EN" : "Shimo-Uwa",     "MyStation" : "15", "StationNumber" : "U23", "DispNum" : "2", "StationTimeTable" : "http://www.jr-shikoku.co.jp/01_trainbus/jikoku/pdf/shimo-uwa.pdf",     "StationMap":"https://www.google.co.jp/maps/place/33.349786,132.531172", "JrHpUrl" : ""}, | ||||
| {"Station_JP" : "立間",     "Station_EN" : "Tachima",       "MyStation" : "16", "StationNumber" : "U24", "DispNum" : "2", "StationTimeTable" : "http://www.jr-shikoku.co.jp/01_trainbus/jikoku/pdf/tachima.pdf",       "StationMap":"https://www.google.co.jp/maps/place/33.296721,132.539509", "JrHpUrl" : ""}, | ||||
| {"Station_JP" : "伊予吉田", "Station_EN" : "Iyo-Yoshida",   "MyStation" : "17", "StationNumber" : "U25", "DispNum" : "2", "StationTimeTable" : "http://www.jr-shikoku.co.jp/01_trainbus/jikoku/pdf/iyo-yoshida.pdf",   "StationMap":"https://www.google.co.jp/maps/place/33.273287,132.544098", "JrHpUrl" : ""}, | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								assets/雑.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								assets/雑.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 1.3 MiB | 
							
								
								
									
										896
									
								
								components/ActionSheetComponents/EachTrainInfo.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										896
									
								
								components/ActionSheetComponents/EachTrainInfo.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,896 @@ | ||||
| import React, { useEffect, useState, useRef } from "react"; | ||||
| import { | ||||
|   View, | ||||
|   LayoutAnimation, | ||||
|   ScrollView, | ||||
|   Linking, | ||||
|   Text, | ||||
|   TouchableOpacity, | ||||
|   TouchableWithoutFeedback, | ||||
|   TouchableHighlight, | ||||
|   Platform, | ||||
| } from "react-native"; | ||||
| import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; | ||||
| import ActionSheet, { | ||||
|   SheetManager, | ||||
|   useScrollHandlers, | ||||
| } from "react-native-actions-sheet"; | ||||
| import { useSafeAreaInsets } from "react-native-safe-area-context"; | ||||
| import { AS } from "../../storageControl"; | ||||
| import LottieView from "lottie-react-native"; | ||||
| import trainList from "../../assets/originData/trainList"; | ||||
| import { lineList } from "../../lib/getStationList"; | ||||
| import { | ||||
|   heightPercentageToDP, | ||||
|   widthPercentageToDP, | ||||
| } from "react-native-responsive-screen"; | ||||
| import lineColorList from "../../assets/originData/lineColorList"; | ||||
| import { useCurrentTrain } from "../../stateBox/useCurrentTrain"; | ||||
| import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData"; | ||||
| import dayjs from "dayjs"; | ||||
| import { getTrainType } from "../../lib/getTrainType"; | ||||
| import { customTrainDataDetector } from "../custom-train-data"; | ||||
| import { useBusAndTrainData } from "../../stateBox/useBusAndTrainData"; | ||||
| import { Swipeable } from "react-native-gesture-handler"; | ||||
|  | ||||
| export const EachTrainInfo = (props) => { | ||||
|   if (!props.payload) return <></>; | ||||
|   const { | ||||
|     data, | ||||
|     navigate, | ||||
|     originalStationList, | ||||
|     openStationACFromEachTrainInfo = () => {}, | ||||
|     from, | ||||
|   } = props.payload; | ||||
|   const [trainData, setTrainData] = useState([]); | ||||
|   const [currentPosition, setCurrentPosition] = useState([]); | ||||
|  | ||||
|   const [trainPositionSwitch, setTrainPositionSwitch] = useState("false"); | ||||
|  | ||||
|   const { currentTrain } = useCurrentTrain(); | ||||
|   const { initializeTrainPairList } = useBusAndTrainData(); | ||||
|  | ||||
|   const [currentTrainData, setCurrentTrainData] = useState([]); | ||||
|   const [nearTrainIDList, setNearTrainIDList] = useState([]); | ||||
|   const [showNearTrain, setShowNearTrain] = useState([]); | ||||
|   const [isConcatNear, setIsConcatNear] = useState(false); | ||||
|  | ||||
|   //裏列車探索 | ||||
|   useEffect(() => { | ||||
|     const trainPairList = initializeTrainPairList(); | ||||
|  | ||||
|     const returnArray = []; | ||||
|     if (!data.trainNum) return; | ||||
|     if (trainPairList[data.trainNum]) { | ||||
|       returnArray.push(Object.keys(trainPairList[data.trainNum])[0]); | ||||
|     } | ||||
|     if ( | ||||
|       // 列番が4xxDまたは5xxDの場合はxxDの列番を検索 | ||||
|       new RegExp(/^4[1-9]\d\d[DM]$/).test(data.trainNum) || | ||||
|       new RegExp(/^5[1-7]\d\d[DM]$/).test(data.trainNum) | ||||
|     ) { | ||||
|       if (trainList[data.trainNum.substring(1)]) { | ||||
|         returnArray.push(data.trainNum.substring(1)); | ||||
|       } | ||||
|     } | ||||
|     if (new RegExp(/^[1-9]\d\d[DM]$/).test(data.trainNum)) { | ||||
|       // 列番がxxDの場合は4xxDと5xxDの列番を検索 | ||||
|       if (trainList["4" + data.trainNum]) returnArray.push("4" + data.trainNum); | ||||
|       if (trainList["5" + data.trainNum]) returnArray.push("5" + data.trainNum); | ||||
|     } | ||||
|     setNearTrainIDList(returnArray); | ||||
|     if (!returnArray[0]) return; | ||||
|     const TD = trainList[returnArray[0]]; | ||||
|     if (!TD) return; | ||||
|     const TDArray = TD.split("#").filter((d) => d != ""); | ||||
|     setShowNearTrain(TDArray); | ||||
|   }, [data]); | ||||
|  | ||||
|   const openBackTrainInfo = (stationInfo, currentTrainIndex) => { | ||||
|     console.log(trainData); //trainDataは現在の列車の停車駅リスト | ||||
|     console.log(showNearTrain); //showNearTrainは裏列車の停車駅リスト | ||||
|     const mainTrainStationPosition = trainData.findIndex( | ||||
|       (d) => d.split(",")[0] == stationInfo | ||||
|     ); | ||||
|     const relationMain = | ||||
|       mainTrainStationPosition == 0 | ||||
|         ? "head" | ||||
|         : mainTrainStationPosition == trainData.length - 1 | ||||
|         ? "tail" | ||||
|         : "middle"; | ||||
|     console.log(relationMain); | ||||
|  | ||||
|     const subTrainStationPosition = showNearTrain.findIndex( | ||||
|       (d) => d.split(",")[0] == stationInfo | ||||
|     ); | ||||
|     const relationSub = | ||||
|       subTrainStationPosition == 0 | ||||
|         ? "head" | ||||
|         : subTrainStationPosition == showNearTrain.length - 1 | ||||
|         ? "tail" | ||||
|         : "middle"; | ||||
|     console.log(relationSub); | ||||
|     switch (relationMain) { | ||||
|       case "head": | ||||
|         if (relationSub == "head") { | ||||
|           break; | ||||
|         } else if (relationSub == "tail") { | ||||
|           const migrationTrainData = [ | ||||
|             ...showNearTrain.slice(0, subTrainStationPosition), | ||||
|             ...trainData, | ||||
|           ]; | ||||
|           setTrainData(migrationTrainData); | ||||
|         } else if (relationSub == "middle") { | ||||
|           const migrationTrainData = [ | ||||
|             ...showNearTrain.slice(0, subTrainStationPosition), | ||||
|             ...trainData, | ||||
|           ]; | ||||
|           setTrainData(migrationTrainData); | ||||
|         } | ||||
|         break; | ||||
|       case "tail": | ||||
|         if (relationSub == "head") { | ||||
|           const migrationTrainData = [ | ||||
|             ...trainData.slice(0, mainTrainStationPosition), | ||||
|             ...showNearTrain, | ||||
|           ]; | ||||
|           setTrainData(migrationTrainData); | ||||
|         } else if (relationSub == "tail") { | ||||
|           break; | ||||
|         } else if (relationSub == "middle") { | ||||
|           const migrationTrainData = [ | ||||
|             ...trainData.slice(0, mainTrainStationPosition), | ||||
|             ...showNearTrain.slice(subTrainStationPosition), | ||||
|           ]; | ||||
|           setTrainData(migrationTrainData); | ||||
|         } | ||||
|         break; | ||||
|       case "middle": | ||||
|         if (relationSub == "head") { | ||||
|           const migrationTrainData = [ | ||||
|             ...trainData.slice(0, mainTrainStationPosition), | ||||
|             ...showNearTrain, | ||||
|           ]; | ||||
|           setTrainData(migrationTrainData); | ||||
|         } else if (relationSub == "tail") { | ||||
|           const migrationTrainData = [ | ||||
|             ...showNearTrain.slice(0, subTrainStationPosition), | ||||
|             ...trainData.slice(mainTrainStationPosition), | ||||
|           ]; | ||||
|           setTrainData(migrationTrainData); | ||||
|         } | ||||
|         break; | ||||
|     } | ||||
|     setIsConcatNear(true); | ||||
|   }; | ||||
|  | ||||
|   const openTrainInfo = (d) => { | ||||
|     const train = customTrainDataDetector(d); | ||||
|     let TrainNumber = ""; | ||||
|     if (train.trainNumDistance != undefined) { | ||||
|       const timeInfo = | ||||
|         parseInt(d.replace("M", "").replace("D", "")) - train.trainNumDistance; | ||||
|       TrainNumber = timeInfo + "号"; | ||||
|     } | ||||
|     const payload = { | ||||
|       data: { | ||||
|         trainNum: d, | ||||
|         limited: `${getTrainType(train.type).data}:${ | ||||
|           train.trainName | ||||
|         }${TrainNumber}`, | ||||
|       }, | ||||
|       navigate, | ||||
|       originalStationList, | ||||
|       from: "AllTrainDiagramView", | ||||
|     }; | ||||
|     //SheetManager.show("EachTrainInfo", { payload }); | ||||
|   }; | ||||
|   useEffect(() => { | ||||
|     setCurrentTrainData( | ||||
|       checkDuplicateTrainData( | ||||
|         currentTrain.filter((d) => d.num == data.trainNum) | ||||
|       ) | ||||
|     ); | ||||
|   }, [currentTrain]); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     //列車現在地アイコン表示スイッチ | ||||
|     AS.getItem("trainPositionSwitch") | ||||
|       .then((d) => { | ||||
|         if (d) { | ||||
|           setTrainPositionSwitch(d); | ||||
|         } else { | ||||
|         } | ||||
|       }) | ||||
|       .catch((d) => AS.setItem("trainPositionSwitch", "false")); | ||||
|   }, []); | ||||
|   //bconst insets = useSafeAreaInsets(); | ||||
|   const getStationData = (stationName) => { | ||||
|     const Stations = stationList.map((a) => | ||||
|       a.filter((d) => d.StationName == stationName) | ||||
|     ); | ||||
|     const Station = | ||||
|       Stations && | ||||
|       Stations.reduce((newArray, e) => { | ||||
|         return newArray.concat(e); | ||||
|       }, []); | ||||
|     if (!Station[0]) return []; | ||||
|     return Station.map((d) => d.StationNumber)[0]; | ||||
|   }; | ||||
|   useEffect(() => { | ||||
|     //currentTrainData.Pos = "鴨川~端岡"; //test | ||||
|     if (!currentTrainData?.Pos) return; | ||||
|     if (currentTrainData?.Pos.match("~")) { | ||||
|       const pos = currentTrainData?.Pos.replace("(下り)", "") | ||||
|         .replace("(上り)", "") | ||||
|         .split("~"); | ||||
|       setCurrentPosition([getStationData(pos[0]), getStationData(pos[1])]); | ||||
|     } else { | ||||
|       setCurrentPosition([getStationData(currentTrainData?.Pos)]); | ||||
|     } | ||||
|   }, [currentTrainData]); | ||||
|  | ||||
|   const stationList = | ||||
|     originalStationList && | ||||
|     lineList.map((d) => | ||||
|       originalStationList[d].map((a) => ({ | ||||
|         StationNumber: a.StationNumber, | ||||
|         StationName: a.Station_JP, | ||||
|       })) | ||||
|     ); | ||||
|   const stopStationIDList = trainData.map((i, index) => { | ||||
|     const [station, se, time] = i.split(","); | ||||
|     const Stations = stationList.map((a) => | ||||
|       a.filter((d) => d.StationName == station) | ||||
|     ); | ||||
|     const StationNumbers = | ||||
|       Stations && | ||||
|       Stations.reduce((newArray, e) => { | ||||
|         return newArray.concat(e); | ||||
|       }, []) | ||||
|         .filter((d) => d.StationNumber) | ||||
|         .map((d) => d.StationNumber); | ||||
|     return StationNumbers[0]; | ||||
|   }); | ||||
|   function findReversalPoints(array) { | ||||
|     try { | ||||
|       // arrayは現在位置の駅ID(駅在宅の場合は1つの配列、駅間の場合は2つの配列) | ||||
|       // stopStationIDListは停車駅の駅IDの配列 | ||||
|       if (!stopStationIDList.length) return []; | ||||
|       // arrayが二次元配列だったら早期リターン | ||||
|       if (!array instanceof Array) return []; | ||||
|       if (!array.length) return []; | ||||
|       if (array[0] instanceof Array) return []; | ||||
|       const arrayNumber = array.map((d) => ({ | ||||
|         line: d | ||||
|           .split("") | ||||
|           .filter((s) => "A" < s && s < "Z") | ||||
|           .join(""), | ||||
|         ID: d | ||||
|           .split("") | ||||
|           .filter((s) => "0" <= s && s <= "9") | ||||
|           .join(""), | ||||
|       })); | ||||
|       const stopStationIDListNumber = stopStationIDList.map((d) => { | ||||
|         if (!d) return { line: [], ID: [] }; | ||||
|         return { | ||||
|           line: d | ||||
|             .split("") | ||||
|             .filter((s) => "A" < s && s < "Z") | ||||
|             .join(""), | ||||
|           ID: d | ||||
|             .split("") | ||||
|             .filter((s) => "0" <= s && s <= "9") | ||||
|             .join(""), | ||||
|         }; | ||||
|       }); | ||||
|       // 完全一致 | ||||
|       if (array.length == 1) { | ||||
|         const index = stopStationIDList.indexOf(array[0]); | ||||
|         if (index != -1) return [index]; | ||||
|         // 通過駅の場合 | ||||
|         for (let i = 0; i < stopStationIDListNumber.length - 1; i++) { | ||||
|           if (stopStationIDListNumber[i].ID < arrayNumber[0].ID) { | ||||
|             if (stopStationIDListNumber[i + 1].ID > arrayNumber[0].ID) { | ||||
|               return [i + 1]; | ||||
|             } | ||||
|           } | ||||
|           if (stopStationIDListNumber[i].ID > arrayNumber[0].ID) { | ||||
|             if (stopStationIDListNumber[i + 1].ID < arrayNumber[0].ID) { | ||||
|               return [i + 1]; | ||||
|             } | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|       // 駅間の場合 | ||||
|       if (array.length == 2) { | ||||
|         const index1 = stopStationIDList.indexOf(array[0]); | ||||
|         const index2 = stopStationIDList.indexOf(array[1]); | ||||
|         if (index1 != -1 && index2 != -1) { | ||||
|           // 駅間で通過駅も無い場合 | ||||
|           if (index1 < index2) { | ||||
|             if (index1 + 1 == index2) { | ||||
|               return [index2]; | ||||
|             } else { | ||||
|               const returnArray = []; | ||||
|               for (let i = index1 + 1; i <= index2; i++) { | ||||
|                 returnArray.push(i); | ||||
|               } | ||||
|               return returnArray; | ||||
|             } | ||||
|           } | ||||
|           if (index1 > index2) { | ||||
|             if (index2 + 1 == index1) return [index1]; | ||||
|             else { | ||||
|               const returnArray = []; | ||||
|               for (let i = index2 + 1; i <= index1; i++) { | ||||
|                 returnArray.push(i); | ||||
|               } | ||||
|               return returnArray; | ||||
|             } | ||||
|           } | ||||
|         } else { | ||||
|           const getNearStationID = (stationID) => { | ||||
|             for (let i = 0; i <= stopStationIDListNumber.length; i++) { | ||||
|               if (stopStationIDListNumber[i].ID < stationID) { | ||||
|                 if (stopStationIDListNumber[i + 1].ID > stationID) { | ||||
|                   return i + 1; | ||||
|                 } | ||||
|               } | ||||
|               if (stopStationIDListNumber[i].ID > stationID) { | ||||
|                 if (stopStationIDListNumber[i + 1].ID < stationID) { | ||||
|                   return i + 1; | ||||
|                 } | ||||
|               } | ||||
|             } | ||||
|           }; | ||||
|           let newIndex1 = index1; | ||||
|           let newIndex2 = index2; | ||||
|           if (index1 == -1) { | ||||
|             newIndex1 = getNearStationID(arrayNumber[0].ID); | ||||
|           } | ||||
|           if (index2 == -1) { | ||||
|             newIndex2 = getNearStationID(arrayNumber[1].ID); | ||||
|           } | ||||
|           if (newIndex1 && newIndex2) { | ||||
|             return [newIndex1, newIndex2]; | ||||
|           } | ||||
|  | ||||
|           // 通過駅の場合 | ||||
|         } | ||||
|  | ||||
|         return []; | ||||
|       } | ||||
|     } catch (e) { | ||||
|       console.log(e); | ||||
|     } | ||||
|   } | ||||
|   // 使用例 | ||||
|   const points = | ||||
|     trainPositionSwitch == "true" ? findReversalPoints(currentPosition) : []; | ||||
|  | ||||
|   useEffect(() => { | ||||
|     if (!data.trainNum) return; | ||||
|     const TD = trainList[data.trainNum]; | ||||
|     if (!TD) { | ||||
|       setTrainData([]); | ||||
|       return; | ||||
|     } | ||||
|     setTrainData(TD.split("#").filter((d) => d != "")); | ||||
|   }, [data]); | ||||
|   const getType = (string) => { | ||||
|     switch (string) { | ||||
|       case "express": | ||||
|         return "特急"; | ||||
|       case "rapid": | ||||
|         return "快速"; | ||||
|       default: | ||||
|         return ""; | ||||
|     } | ||||
|   }; | ||||
|  | ||||
|   const migrateTrainName = (string) => { | ||||
|     return string | ||||
|       .replace("マリン", "マリンライナー") | ||||
|       .replace("ライナーライナー", "ライナー"); | ||||
|   }; | ||||
|   const actionSheetRef = useRef(null); | ||||
|   const scrollHandlers = useScrollHandlers("scrollview-1", actionSheetRef); | ||||
|   return ( | ||||
|     <ActionSheet | ||||
|       gestureEnabled={true} | ||||
|       CustomHeaderComponent={<></>} | ||||
|       ref={actionSheetRef} | ||||
|       drawUnderStatusBar={false} | ||||
|       isModal={Platform.OS == "ios"} | ||||
|       //useBottomSafeAreaPadding={Platform.OS == "android"} | ||||
|     > | ||||
|       <View | ||||
|         style={{ | ||||
|           backgroundColor: "#0099CC", | ||||
|           borderTopRadius: 5, | ||||
|           borderColor: "dark", | ||||
|           borderWidth: 1, | ||||
|         }} | ||||
|       > | ||||
|         <View style={{ height: 26, width: "100%" }}> | ||||
|           <View | ||||
|             style={{ | ||||
|               height: 6, | ||||
|               width: 45, | ||||
|               borderRadius: 100, | ||||
|               backgroundColor: "#f0f0f0", | ||||
|               marginVertical: 10, | ||||
|               alignSelf: "center", | ||||
|             }} | ||||
|           /> | ||||
|         </View> | ||||
|         <View | ||||
|           style={{ padding: 10, flexDirection: "row", alignItems: "center" }} | ||||
|         > | ||||
|           <Text style={{ fontSize: 20, fontWeight: "bold", color: "white" }}> | ||||
|             {data.limited | ||||
|               ? getType(data.limited.split(":")[0]) + | ||||
|                 migrateTrainName( | ||||
|                   data.limited.split(":")[1] || | ||||
|                     (trainData.length > 0 | ||||
|                       ? trainData[trainData.length - 1].split(",")[0] + "行き" | ||||
|                       : " ") | ||||
|                 ) | ||||
|               : ""} | ||||
|           </Text> | ||||
|           <View style={{ flex: 1 }} /> | ||||
|           <Text style={{ fontSize: 20, fontWeight: "bold", color: "white" }}> | ||||
|             {data.trainNum} | ||||
|             {isConcatNear ? ` + ${nearTrainIDList}` : ""} | ||||
|           </Text> | ||||
|  | ||||
|           {data.limited != undefined && | ||||
|             getType(data.limited.split(":")[0]) && | ||||
|             !data.limited.split(":")[1].match("サンポート") && ( | ||||
|               <Ionicons | ||||
|                 name="subway" | ||||
|                 color="white" | ||||
|                 size={30} | ||||
|                 style={{ margin: 5 }} | ||||
|                 onPress={() => { | ||||
|                   LayoutAnimation.easeInEaseOut(); //setLoadingDelayData(true); | ||||
|                   navigate("trainbase", { | ||||
|                     info: "train.html?tn=" + data.trainNum, | ||||
|                     from, | ||||
|                   }); | ||||
|                   SheetManager.hide("EachTrainInfo"); | ||||
|                 }} | ||||
|               /> | ||||
|             )} | ||||
|         </View> | ||||
|         {from == "AllTrainDiagramView" || ( | ||||
|           <ScrollView | ||||
|             style={{ | ||||
|               flexDirection: "row", | ||||
|               //width: widthPercentageToDP("200%"), | ||||
|               minHeight: 200, | ||||
|               height: heightPercentageToDP("20%"), | ||||
|             }} | ||||
|             horizontal | ||||
|             pagingEnabled | ||||
|           > | ||||
|             <TrainDataView | ||||
|               currentTrainData={currentTrainData} | ||||
|               currentPosition={currentPosition} | ||||
|             /> | ||||
|             {/* <View | ||||
|               style={{ | ||||
|                 flexDirection: "column", | ||||
|                 height: heightPercentageToDP("20%"), | ||||
|                 flex: 1, | ||||
|                 width: widthPercentageToDP("100%"), | ||||
|               }} | ||||
|             > | ||||
|               <View style={{ flex: 1, flexDirection: "row" }}> | ||||
|                 <View | ||||
|                   style={{ | ||||
|                     flex: 1, | ||||
|                     backgroundColor: "white", | ||||
|                     borderRadius: 10, | ||||
|                     padding: 10, | ||||
|                     margin: 10, | ||||
|                   }} | ||||
|                 > | ||||
|                   <Text style={{ fontSize: 15, color: "#0099CC" }}>行先</Text> | ||||
|                   <View style={{ flex: 1 }} /> | ||||
|                   <Text | ||||
|                     style={{ | ||||
|                       fontSize: 20, | ||||
|                       color: "#0099CC", | ||||
|                       textAlign: "right", | ||||
|                     }} | ||||
|                   > | ||||
|                     岡山 | ||||
|                   </Text> | ||||
|                 </View> | ||||
|  | ||||
|                 <View | ||||
|                   style={{ | ||||
|                     flex: 3, | ||||
|                     backgroundColor: "white", | ||||
|                     borderRadius: 10, | ||||
|                     padding: 10, | ||||
|                     margin: 10, | ||||
|                   }} | ||||
|                 > | ||||
|                   <Text style={{ fontSize: 15, color: "#0099CC" }}> | ||||
|                     車両案内 | ||||
|                   </Text> | ||||
|                   <View style={{ flex: 1 }} /> | ||||
|                   <Text | ||||
|                     style={{ | ||||
|                       fontSize: 20, | ||||
|                       color: "#0099CC", | ||||
|                       textAlign: "right", | ||||
|                     }} | ||||
|                   > | ||||
|                     宇多津でうずしお号と連結 | ||||
|                   </Text> | ||||
|                 </View> | ||||
|               </View> | ||||
|               <View style={{ flex: 1, flexDirection: "row" }}> | ||||
|                 <View | ||||
|                   style={{ | ||||
|                     flex: 1, | ||||
|                     backgroundColor: "white", | ||||
|                     borderRadius: 10, | ||||
|                     padding: 10, | ||||
|                     margin: 10, | ||||
|                   }} | ||||
|                 > | ||||
|                   <Text style={{ fontSize: 15, color: "#0099CC" }}> | ||||
|                     編成(使用車両:2700系) | ||||
|                   </Text> | ||||
|                   <View style={{ flex: 1 }} /> | ||||
|                   <Text | ||||
|                     style={{ | ||||
|                       fontSize: 20, | ||||
|                       color: "#0099CC", | ||||
|                       textAlign: "left", | ||||
|                     }} | ||||
|                   > | ||||
|                     {"[<自][自>][アン自|指>][アン指|G>]"} | ||||
|                   </Text> | ||||
|                 </View> | ||||
|               </View> | ||||
|             </View> */} | ||||
|           </ScrollView> | ||||
|         )} | ||||
|         <View | ||||
|           style={{ | ||||
|             alignItems: "center", | ||||
|             backgroundColor: "white", | ||||
|             flexDirection: "row", | ||||
|           }} | ||||
|         > | ||||
|           <View | ||||
|             style={{ | ||||
|               padding: 8, | ||||
|               flexDirection: "row", | ||||
|               borderBottomWidth: 1, | ||||
|               borderBottomColor: "#f0f0f0", | ||||
|               flex: 1, | ||||
|             }} | ||||
|           > | ||||
|             <Text style={{ fontSize: 20 }}>停車駅</Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|             <View style={{ flexDirection: "row" }}> | ||||
|               {!isNaN(currentTrainData?.delay) && | ||||
|                 currentTrainData?.delay != 0 && ( | ||||
|                   <Text | ||||
|                     style={{ | ||||
|                       fontSize: 15, | ||||
|                       color: "black", | ||||
|                       position: "absolute", | ||||
|                       right: 110, | ||||
|                       textAlign: "right", | ||||
|                       textDecorationLine: "line-through", | ||||
|                     }} | ||||
|                   > | ||||
|                     (定刻) | ||||
|                   </Text> | ||||
|                 )} | ||||
|               <Text | ||||
|                 style={{ | ||||
|                   fontSize: 20, | ||||
|                   color: isNaN(currentTrainData?.delay) | ||||
|                     ? "black" | ||||
|                     : currentTrainData?.delay == 0 | ||||
|                     ? "black" | ||||
|                     : "red", | ||||
|                   width: 60, | ||||
|                 }} | ||||
|               > | ||||
|                 見込 | ||||
|               </Text> | ||||
|               <Text style={{ fontSize: 20, width: 50 }}></Text> | ||||
|             </View> | ||||
|           </View> | ||||
|         </View> | ||||
|         <ScrollView | ||||
|           {...scrollHandlers} | ||||
|           style={{ | ||||
|             maxHeight: heightPercentageToDP( | ||||
|               from == "AllTrainDiagramView" ? "70%" : "50%" | ||||
|             ), | ||||
|             backgroundColor: "white", | ||||
|           }} | ||||
|         > | ||||
|           {/* <LottieView | ||||
|                 autoPlay | ||||
|                 loop | ||||
|                 style={{ width: 150, height: 150, backgroundColor: "#fff" }} | ||||
|                 source={require("../../assets/51690-loading-diamonds.json")} | ||||
|               /> | ||||
|               <Text>ほげほげふがふが</Text> */} | ||||
|  | ||||
|           {trainData.map((i, index) => ( | ||||
|             <StationButton | ||||
|               i={i} | ||||
|               index={index} | ||||
|               stationList={stationList} | ||||
|               points={points} | ||||
|               currentTrainData={currentTrainData} | ||||
|               openStationACFromEachTrainInfo={openStationACFromEachTrainInfo} | ||||
|               headAndTail={showNearTrain.map((d) => d.split(",")[0])} | ||||
|               openBackTrainInfo={openBackTrainInfo} | ||||
|               isConcatNear={isConcatNear} | ||||
|             /> | ||||
|           ))} | ||||
|  | ||||
|           <View style={{ flexDirection: "row" }}> | ||||
|             <View | ||||
|               style={{ | ||||
|                 padding: 8, | ||||
|                 flexDirection: "row", | ||||
|                 borderBottomWidth: 1, | ||||
|                 borderBottomColor: "#f0f0f0", | ||||
|                 flex: 1, | ||||
|               }} | ||||
|             > | ||||
|               <Text style={{ fontSize: 20 }}> </Text> | ||||
|               <View style={{ flex: 1 }} /> | ||||
|             </View> | ||||
|           </View> | ||||
|         </ScrollView> | ||||
|       </View> | ||||
|     </ActionSheet> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const StationButton = ({ | ||||
|   i, | ||||
|   index, | ||||
|   stationList, | ||||
|   points, | ||||
|   currentTrainData, | ||||
|   openStationACFromEachTrainInfo, | ||||
|   headAndTail, | ||||
|   openBackTrainInfo, | ||||
|   isConcatNear, | ||||
| }) => { | ||||
|   const [station, se, time] = i.split(","); // 阿波池田,発,6:21 | ||||
|   const Stations = stationList | ||||
|     .map((a) => a.filter((d) => d.StationName == station)) | ||||
|     .reduce((newArray, e) => newArray.concat(e), []); | ||||
|   /*Array [ | ||||
|       Object { | ||||
|         "StationName": "佐古", | ||||
|         "StationNumber": "T01", | ||||
|       }, | ||||
|       Object { | ||||
|         "StationName": "佐古", | ||||
|         "StationNumber": "B01", | ||||
|       }, | ||||
|     ] */ | ||||
|   const StationNumbers = | ||||
|     Stations && | ||||
|     Stations.filter((d) => d.StationNumber).map((d) => d.StationNumber); | ||||
|   // Array [  "T01",  "B01",] | ||||
|   const lineIDs = []; | ||||
|   const EachIDs = []; | ||||
|   StationNumbers.forEach((d) => { | ||||
|     const textArray = d.split(""); | ||||
|     lineIDs.push(textArray.filter((s) => "A" < s && s < "Z").join("")); | ||||
|     EachIDs.push(textArray.filter((s) => "0" <= s && s <= "9").join("")); | ||||
|   }); | ||||
|   // Array [  "T",  "B",] | ||||
|   // Array [  "01",  "01",] | ||||
|  | ||||
|   const dates = dayjs() | ||||
|     .set("hour", parseInt(time.split(":")[0])) | ||||
|     .set("minute", parseInt(time.split(":")[1])) | ||||
|     .add(isNaN(currentTrainData?.delay) ? 0 : currentTrainData.delay, "minute"); | ||||
|   const timeString = dates.format("HH:mm").split(":"); | ||||
|  | ||||
|   const StationNames = Stations && Stations[0]?.StationName; | ||||
|   const [isConnected, setIsConnected] = useState( | ||||
|     headAndTail.includes(StationNames) | ||||
|   ); | ||||
|   const swipagleRef = useRef(null); | ||||
|   return ( | ||||
|     <Swipeable | ||||
|       ref={swipagleRef} | ||||
|       key={station} | ||||
|       onSwipeableOpen={() => { | ||||
|         openBackTrainInfo(station, index); | ||||
|         swipagleRef.current.close(); | ||||
|       }} | ||||
|       renderRightActions={ | ||||
|         isConnected && !isConcatNear | ||||
|           ? (progress, dragX) => { | ||||
|               //openBackTrainInfo(station, index); | ||||
|               return <View style={{ flex: 1, backgroundColor: "red" }}></View>; | ||||
|             } | ||||
|           : null | ||||
|       } | ||||
|     > | ||||
|       <TouchableWithoutFeedback | ||||
|         onPress={() => openStationACFromEachTrainInfo(station)} | ||||
|         key={station} | ||||
|       > | ||||
|         <View style={{ flexDirection: "row", backgroundColor: "white" }}> | ||||
|           <View | ||||
|             style={{ | ||||
|               width: 35, | ||||
|               position: "relative", | ||||
|               marginHorizontal: 15, | ||||
|               flexDirection: "row", | ||||
|               height: "101%", | ||||
|             }} | ||||
|           > | ||||
|             {lineIDs.map((lineID, index) => ( | ||||
|               <View | ||||
|                 style={{ | ||||
|                   backgroundColor: lineColorList[lineID], | ||||
|                   flex: 1, | ||||
|                 }} | ||||
|                 key={lineID} | ||||
|               > | ||||
|                 <View style={{ flex: 1 }} /> | ||||
|                 <Text | ||||
|                   style={{ | ||||
|                     color: "white", | ||||
|                     textAlign: "center", | ||||
|                     fontSize: 10, | ||||
|                     fontWeight: "bold", | ||||
|                   }} | ||||
|                 > | ||||
|                   {lineIDs[index]} | ||||
|                   {"\n"} | ||||
|                   {EachIDs[index]} | ||||
|                 </Text> | ||||
|                 <View style={{ flex: 1 }} /> | ||||
|               </View> | ||||
|             ))} | ||||
|           </View> | ||||
|           <View | ||||
|             style={{ | ||||
|               padding: 8, | ||||
|               flexDirection: "row", | ||||
|               borderBottomWidth: 1, | ||||
|               borderBottomColor: "#f0f0f0", | ||||
|               borderRightColor: isConnected && !isConcatNear ? "red" : "white", | ||||
|               borderRightWidth: 10, | ||||
|               paddingRight: 10, | ||||
|               flex: 1, | ||||
|             }} | ||||
|           > | ||||
|             <Text style={{ fontSize: 20 }}>{station}</Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|             {points && points.findIndex((d) => d == index) >= 0 ? ( | ||||
|               <Text style={{ fontSize: 20, marginRight: 70 }}>🚊</Text> | ||||
|             ) : null} | ||||
|             {!isNaN(currentTrainData?.delay) && | ||||
|               currentTrainData?.delay != 0 && ( | ||||
|                 <Text | ||||
|                   style={{ | ||||
|                     fontSize: 15, | ||||
|                     color: "black", | ||||
|                     width: 60, | ||||
|                     position: "absolute", | ||||
|                     right: 120, | ||||
|                     textAlign: "right", | ||||
|                     textDecorationLine: "line-through", | ||||
|                   }} | ||||
|                 > | ||||
|                   {time} | ||||
|                 </Text> | ||||
|               )} | ||||
|             <Text | ||||
|               style={{ | ||||
|                 fontSize: 20, | ||||
|                 color: isNaN(currentTrainData?.delay) | ||||
|                   ? "black" | ||||
|                   : currentTrainData?.delay == 0 | ||||
|                   ? "black" | ||||
|                   : "red", | ||||
|                 width: 60, | ||||
|               }} | ||||
|             > | ||||
|               {timeString[0]}:{timeString[1]} | ||||
|             </Text> | ||||
|             <Text style={{ fontSize: 18, width: 50 }}> | ||||
|               {se?.replace("発", "出発").replace("着", "到着")} | ||||
|             </Text> | ||||
|           </View> | ||||
|         </View> | ||||
|       </TouchableWithoutFeedback> | ||||
|     </Swipeable> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const TrainDataView = ({ currentTrainData, currentPosition }) => { | ||||
|   return ( | ||||
|     <View | ||||
|       style={{ | ||||
|         flexDirection: "row", | ||||
|         minHeight: 200, | ||||
|         height: heightPercentageToDP("20%"), | ||||
|         width: widthPercentageToDP("100%"), | ||||
|       }} | ||||
|     > | ||||
|       <StateBox | ||||
|         title={`現在地 ${currentPosition.toString()}`} | ||||
|         text={ | ||||
|           currentTrainData?.Pos.match("~") | ||||
|             ? `${ | ||||
|                 currentTrainData?.Pos.replace("(下り)", "") | ||||
|                   .replace("(上り)", "") | ||||
|                   .split("~")[0] | ||||
|               }~${ | ||||
|                 currentTrainData?.Pos.replace("(下り)", "") | ||||
|                   .replace("(上り)", "") | ||||
|                   .split("~")[1] | ||||
|               }` | ||||
|             : currentTrainData?.Pos | ||||
|         } | ||||
|       /> | ||||
|       <View style={{ flex: 1, flexDirection: "column" }}> | ||||
|         <StateBox | ||||
|           title={isNaN(currentTrainData?.delay) ? "状態" : "遅延時分"} | ||||
|           text={`${currentTrainData?.delay}${ | ||||
|             isNaN(currentTrainData?.delay) ? "" : "分" | ||||
|           }`} | ||||
|         /> | ||||
|         <StateBox title="列番" text={currentTrainData?.num} /> | ||||
|       </View> | ||||
|     </View> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const StateBox = ({ text, title }) => ( | ||||
|   <View style={boxStyle}> | ||||
|     <Text style={{ fontSize: 15, color: "#0099CC" }}>{title}</Text> | ||||
|     <View style={{ flex: 1 }} /> | ||||
|     <View style={{ fontSize: 32, color: "#0099CC", textAlign: "right" }}> | ||||
|       {text?.match("~") ? ( | ||||
|         <> | ||||
|           <Text style={boxTextStyle}>{text.split("~")[0]}</Text> | ||||
|           <Text style={{ color: "#0099CC", textAlign: "right" }}>~</Text> | ||||
|           <Text style={boxTextStyle}>{text.split("~")[1]}</Text> | ||||
|         </> | ||||
|       ) : ( | ||||
|         <Text style={boxTextStyle}>{text}</Text> | ||||
|       )} | ||||
|     </View> | ||||
|   </View> | ||||
| ); | ||||
| const boxStyle = { | ||||
|   flex: 1, | ||||
|   backgroundColor: "white", | ||||
|   borderRadius: 10, | ||||
|   padding: 10, | ||||
|   margin: 10, | ||||
| }; | ||||
| const boxTextStyle = { | ||||
|   fontSize: 28, | ||||
|   color: "#0099CC", | ||||
|   textAlign: "right", | ||||
| }; | ||||
| @@ -1,4 +1,4 @@ | ||||
| import React from "react"; | ||||
| import React, { useRef } from "react"; | ||||
| import { | ||||
|   View, | ||||
|   LayoutAnimation, | ||||
| @@ -6,28 +6,38 @@ import { | ||||
|   Linking, | ||||
|   Text, | ||||
|   TouchableOpacity, | ||||
|   Platform, | ||||
| } from "react-native"; | ||||
| import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; | ||||
| import ActionSheet from "react-native-actions-sheet"; | ||||
| import ActionSheet, { useScrollHandlers } from "react-native-actions-sheet"; | ||||
| import LottieView from "lottie-react-native"; | ||||
| export const JRSTraInfo = (props) => { | ||||
|   const { | ||||
|     JRSTraInfoEXAcSR, | ||||
|     getTime, | ||||
|     loadingDelayData, | ||||
|     setLoadingDelayData, | ||||
|     delayData, | ||||
|   } = props; | ||||
| import { useSafeAreaInsets } from "react-native-safe-area-context"; | ||||
| import { useTrainDelayData } from "../../stateBox/useTrainDelayData"; | ||||
| export const JRSTraInfo = () => { | ||||
|   const { getTime, delayData, loadingDelayData, setLoadingDelayData } = | ||||
|     useTrainDelayData(); | ||||
|   const actionSheetRef = useRef(null); | ||||
|   const scrollHandlers = useScrollHandlers("scrollview-1", actionSheetRef); | ||||
|   const insets = useSafeAreaInsets(); | ||||
|   return ( | ||||
|     <ActionSheet | ||||
|       ref={JRSTraInfoEXAcSR} | ||||
|       gestureEnabled | ||||
|       CustomHeaderComponent={<></>} | ||||
|       ref={actionSheetRef} | ||||
|       isModal={Platform.OS == "ios"} | ||||
|       containerStyle={ | ||||
|         Platform.OS == "android" | ||||
|           ? { | ||||
|               paddingBottom: insets.bottom, | ||||
|             } | ||||
|           : {} | ||||
|       } | ||||
|       useBottomSafeAreaPadding={Platform.OS == "android"} | ||||
|     > | ||||
|       <View | ||||
|         style={{ | ||||
|           backgroundColor: "#0099CC", | ||||
|           borderRadius: 5, | ||||
|           borderTopRadius: 5, | ||||
|           borderColor: "dark", | ||||
|           borderWidth: 1, | ||||
|         }} | ||||
| @@ -71,13 +81,11 @@ export const JRSTraInfo = (props) => { | ||||
|             }} | ||||
|           /> | ||||
|         </View> | ||||
|         <ScrollView> | ||||
|         <ScrollView {...scrollHandlers}> | ||||
|           <View | ||||
|             style={{ | ||||
|               padding: 10, | ||||
|               backgroundColor: "white", | ||||
|               borderBottomLeftRadius: 5, | ||||
|               borderBottomRightRadius: 5, | ||||
|             }} | ||||
|           > | ||||
|             {loadingDelayData ? ( | ||||
| @@ -125,12 +133,14 @@ export const JRSTraInfo = (props) => { | ||||
|               borderRadius: 5, | ||||
|               alignItems: "center", | ||||
|             }} | ||||
|             onPress={() => Linking.openURL("https://twitter.com/JRSTrainfoEX")} | ||||
|             onPress={() => | ||||
|               Linking.openURL("https://mstdn.y-zu.org/@JRSTraInfoEX") | ||||
|             } | ||||
|           > | ||||
|             <MaterialCommunityIcons name="twitter" color="white" size={30} /> | ||||
|             <MaterialCommunityIcons name="mastodon" color="white" size={30} /> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|             <Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}> | ||||
|               TwitterBOTはこちら! | ||||
|               MastodonBOTはこちら! | ||||
|             </Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|             <Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}> | ||||
|   | ||||
| @@ -1,34 +1,29 @@ | ||||
| import React, { useState, useEffect } from "react"; | ||||
| import { | ||||
|   StatusBar, | ||||
|   View, | ||||
|   LayoutAnimation, | ||||
|   ScrollView, | ||||
|   Linking, | ||||
|   Text, | ||||
|   TouchableOpacity, | ||||
| } from "react-native"; | ||||
| import { View, Linking, Text, TouchableOpacity, Platform } from "react-native"; | ||||
| import AutoHeightImage from "react-native-auto-height-image"; | ||||
| import { FontAwesome, Foundation, Ionicons } from "@expo/vector-icons"; | ||||
| import { useSafeAreaInsets } from "react-native-safe-area-context"; | ||||
| import ActionSheet from "react-native-actions-sheet"; | ||||
| import Sign from "../../components/駅名表/Sign"; | ||||
| import { useInterval } from "../../lib/useInterval"; | ||||
|  | ||||
| import { TicketBox } from "../atom/TicketBox"; | ||||
| import { | ||||
|   widthPercentageToDP as wp, | ||||
|   heightPercentageToDP as hp, | ||||
| } from "react-native-responsive-screen"; | ||||
| import { widthPercentageToDP as wp } from "react-native-responsive-screen"; | ||||
| import lineColorList from "../../assets/originData/lineColorList"; | ||||
| import { getPDFViewURL } from "../../lib/getPdfViewURL"; | ||||
| import { useBusAndTrainData } from "../../stateBox/useBusAndTrainData"; | ||||
| import { AS } from "../../storageControl"; | ||||
|  | ||||
| export const StationDeteilView = (props) => { | ||||
|   if (!props.payload) return <></>; | ||||
|   const { | ||||
|     StationBoardAcSR, | ||||
|     currentStation, | ||||
|     originalStationList, | ||||
|     favoriteStation, | ||||
|     setFavoriteStation, | ||||
|     busAndTrainData, | ||||
|   } = props; | ||||
|     navigate, | ||||
|     onExit, | ||||
|     goTo, | ||||
|     useShow, | ||||
|   } = props.payload; | ||||
|   const { busAndTrainData } = useBusAndTrainData(); | ||||
|   const [trainBus, setTrainBus] = useState(); | ||||
|   useEffect(() => { | ||||
|     if (!currentStation) return () => {}; | ||||
| @@ -41,17 +36,35 @@ export const StationDeteilView = (props) => { | ||||
|     setTrainBus(data[0]); | ||||
|   }, [currentStation]); | ||||
|  | ||||
|   const [usePDFView, setUsePDFView] = useState(undefined); | ||||
|   useEffect(() => { | ||||
|     AS.getItem("usePDFView").then(setUsePDFView); | ||||
|   }, []); | ||||
|   const info = | ||||
|     currentStation && | ||||
|     (currentStation[0].StationTimeTable.match(".pdf") | ||||
|       ? getPDFViewURL(currentStation[0].StationTimeTable) | ||||
|       : currentStation[0].StationTimeTable); | ||||
|   const insets = useSafeAreaInsets(); | ||||
|   return ( | ||||
|     <ActionSheet | ||||
|       ref={StationBoardAcSR} | ||||
|       gestureEnabled | ||||
|       CustomHeaderComponent={<></>} | ||||
|       isModal={Platform.OS == "ios"} | ||||
|       containerStyle={ | ||||
|         Platform.OS == "android" | ||||
|           ? { | ||||
|               paddingBottom: insets.bottom, | ||||
|             } | ||||
|           : {} | ||||
|       } | ||||
|       useBottomSafeAreaPadding={Platform.OS == "android"} | ||||
|     > | ||||
|       <View | ||||
|         key={currentStation} | ||||
|         style={{ | ||||
|           backgroundColor: "white", | ||||
|           borderRadius: 5, | ||||
|           borderTopRadius: 5, | ||||
|           borderColor: "dark", | ||||
|           borderWidth: 1, | ||||
|         }} | ||||
| @@ -79,9 +92,17 @@ export const StationDeteilView = (props) => { | ||||
|               <Sign | ||||
|                 currentStation={currentStation} | ||||
|                 originalStationList={originalStationList} | ||||
|                 favoriteStation={favoriteStation} | ||||
|                 setFavoriteStation={setFavoriteStation} | ||||
|                 oP={() => Linking.openURL(currentStation[0].StationTimeTable)} | ||||
|                 oP={() => { | ||||
|                   usePDFView == "true" | ||||
|                     ? Linking.openURL(currentStation[0].StationTimeTable) | ||||
|                     : navigate("howto", { | ||||
|                         info, | ||||
|                         goTo, | ||||
|                         useShow, | ||||
|                       }); | ||||
|                   onExit(); | ||||
|                 }} | ||||
|                 oLP={() => Linking.openURL(currentStation[0].StationTimeTable)} | ||||
|               /> | ||||
|             </View> | ||||
|           )} | ||||
| @@ -90,10 +111,32 @@ export const StationDeteilView = (props) => { | ||||
|               <NexPreStationLine | ||||
|                 currentStation={d} | ||||
|                 originalStationList={originalStationList} | ||||
|                 favoriteStation={favoriteStation} | ||||
|                 setFavoriteStation={setFavoriteStation} | ||||
|               /> | ||||
|             ))} | ||||
|           {currentStation && | ||||
|             currentStation[0].JrHpUrl && | ||||
|             currentStation[0].StationNumber != "M12" && ( | ||||
|               <駅構内図 //高松/阿波池田&後免&須崎kounai.png児島例外/ | ||||
|                 oP={() => { | ||||
|                   navigate("howto", { | ||||
|                     info: | ||||
|                       currentStation[0].JrHpUrl.replace("/index.html", "/") + | ||||
|                       "/kounai_map.html", | ||||
|  | ||||
|                     goTo, | ||||
|                     useShow, | ||||
|                   }); | ||||
|                   onExit(); | ||||
|                 }} | ||||
|                 oLP={() => { | ||||
|                   Linking.openURL( | ||||
|                     currentStation[0].JrHpUrl.replace("/index.html", "/") + | ||||
|                       "/kounai_map.html" | ||||
|                   ); | ||||
|                 }} | ||||
|                 uri={currentStation[0].JrHpUrl.replace("/index.html", "/")} | ||||
|               /> | ||||
|             )} | ||||
|           {currentStation && ( | ||||
|             <View style={{ flexDirection: "row" }}> | ||||
|               {!currentStation[0].JrHpUrl || ( | ||||
| @@ -101,7 +144,16 @@ export const StationDeteilView = (props) => { | ||||
|                   backgroundColor={"#AD7FA8"} | ||||
|                   icon={<Foundation name="web" color="white" size={50} />} | ||||
|                   flex={1} | ||||
|                   onPressButton={() => | ||||
|                   onPressButton={() => { | ||||
|                     navigate("howto", { | ||||
|                       info: currentStation[0].JrHpUrl, | ||||
|  | ||||
|                       goTo, | ||||
|                       useShow, | ||||
|                     }); | ||||
|                     onExit(); | ||||
|                   }} | ||||
|                   onLongPressButton={() => | ||||
|                     Linking.openURL(currentStation[0].JrHpUrl) | ||||
|                   } | ||||
|                 > | ||||
| @@ -113,7 +165,18 @@ export const StationDeteilView = (props) => { | ||||
|                   backgroundColor={"#8F5902"} | ||||
|                   icon={<FontAwesome name="table" color="white" size={50} />} | ||||
|                   flex={1} | ||||
|                   onPressButton={() => | ||||
|                   onPressButton={() => { | ||||
|                     usePDFView == "true" | ||||
|                       ? Linking.openURL(currentStation[0].StationTimeTable) | ||||
|                       : navigate("howto", { | ||||
|                           info, | ||||
|  | ||||
|                           goTo, | ||||
|                           useShow, | ||||
|                         }); | ||||
|                     onExit(); | ||||
|                   }} | ||||
|                   onLongPressButton={() => | ||||
|                     Linking.openURL(currentStation[0].StationTimeTable) | ||||
|                   } | ||||
|                 > | ||||
| @@ -137,9 +200,18 @@ export const StationDeteilView = (props) => { | ||||
|                   backgroundColor={"#CE5C00"} | ||||
|                   icon={<Ionicons name="bus" color="white" size={50} />} | ||||
|                   flex={1} | ||||
|                   onPressButton={() => Linking.openURL(trainBus.address)} | ||||
|                   onPressButton={() => { | ||||
|                     navigate("howto", { | ||||
|                       info: trainBus.address, | ||||
|  | ||||
|                       goTo, | ||||
|                       useShow, | ||||
|                     }); | ||||
|                     onExit(); | ||||
|                   }} | ||||
|                   onLongPressButton={() => Linking.openURL(trainBus.address)} | ||||
|                 > | ||||
|                   平行バス | ||||
|                   並行バス | ||||
|                 </TicketBox> | ||||
|               )} | ||||
|             </View> | ||||
| @@ -160,13 +232,7 @@ const StationName = (props) => { | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const NexPreStationLine = ({ | ||||
|   currentStation, | ||||
|   originalStationList, | ||||
|   oP, | ||||
|   favoriteStation, | ||||
|   setFavoriteStation, | ||||
| }) => { | ||||
| const NexPreStationLine = ({ currentStation, originalStationList }) => { | ||||
|   const [preStation, setPreStation] = useState(); | ||||
|   const [nexStation, setNexStation] = useState(); | ||||
|   const [lineName, setLineName] = useState(); | ||||
| @@ -291,6 +357,66 @@ const NexPreStationLine = ({ | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const 駅構内図 = (props) => { | ||||
|   const [open, setOpen] = useState(false); | ||||
|   return ( | ||||
|     <> | ||||
|       <TouchableOpacity | ||||
|         style={{ | ||||
|           height: 50, | ||||
|           backgroundColor: "#888A85", | ||||
|           flexDirection: "column", | ||||
|           alignContent: "center", | ||||
|           alignItems: "center", | ||||
|           margin: 2, | ||||
|         }} | ||||
|         onPress={props.oP} | ||||
|         onLongPress={props.oLP} | ||||
|         //onPress={() => setOpen(!open)} | ||||
|       > | ||||
|         <View style={{ flex: 1 }} /> | ||||
|         <Text | ||||
|           style={{ | ||||
|             color: "white", | ||||
|             textAlign: "center", | ||||
|             textAlignVertical: "center", | ||||
|             flex: 1, | ||||
|           }} | ||||
|         > | ||||
|           {open ? "駅構内図を非表示" : "駅構内図を表示"} | ||||
|         </Text> | ||||
|         <View style={{ flex: 1 }} /> | ||||
|       </TouchableOpacity> | ||||
|       <View> | ||||
|         {open && ( | ||||
|           <> | ||||
|             <AutoHeightImage | ||||
|               source={{ uri: props.uri + "images/kounai.gif" }} | ||||
|               resizeMode="contain" | ||||
|               width={wp("100%")} | ||||
|             /> | ||||
|             <AutoHeightImage | ||||
|               source={{ uri: props.uri + "images/kounai.png" }} | ||||
|               resizeMode="contain" | ||||
|               width={wp("100%")} | ||||
|             /> | ||||
|             <AutoHeightImage | ||||
|               source={{ uri: props.uri + "images/kounai_1f.gif" }} | ||||
|               resizeMode="contain" | ||||
|               width={wp("100%")} | ||||
|             /> | ||||
|             <AutoHeightImage | ||||
|               source={{ uri: props.uri + "images/kounai_2f.png" }} | ||||
|               resizeMode="contain" | ||||
|               width={wp("100%")} | ||||
|             /> | ||||
|           </> | ||||
|         )} | ||||
|       </View> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const styleSheet = { | ||||
|   外枠: { | ||||
|     width: wp("80%"), | ||||
|   | ||||
							
								
								
									
										10
									
								
								components/ActionSheetComponents/sheets.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								components/ActionSheetComponents/sheets.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,10 @@ | ||||
| import { registerSheet } from "react-native-actions-sheet"; | ||||
| import { EachTrainInfo } from "./EachTrainInfo"; | ||||
| import { JRSTraInfo } from "./JRSTraInfo"; | ||||
| import { StationDeteilView } from "./StationDeteilView"; | ||||
|  | ||||
| registerSheet("EachTrainInfo", EachTrainInfo); | ||||
| registerSheet("JRSTraInfo", JRSTraInfo); | ||||
| registerSheet("StationDetailView", StationDeteilView); | ||||
|  | ||||
| export {}; | ||||
							
								
								
									
										164
									
								
								components/AllTrainDiagramView.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								components/AllTrainDiagramView.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,164 @@ | ||||
| import React, { useRef, useState, useEffect } from "react"; | ||||
| import { | ||||
|   View, | ||||
|   Text, | ||||
|   TouchableOpacity, | ||||
|   Linking, | ||||
|   ScrollView, | ||||
|   FlatList, | ||||
|   KeyboardAvoidingView, | ||||
|   TextInput, | ||||
|   Platform, | ||||
|   Keyboard, | ||||
| } from "react-native"; | ||||
| import MapView, { Marker } from "react-native-maps"; | ||||
| import { MaterialCommunityIcons } from "@expo/vector-icons"; | ||||
| import { useCurrentTrain } from "../stateBox/useCurrentTrain"; | ||||
| import { useAreaInfo } from "../stateBox/useAreaInfo"; | ||||
| import { useAllTrainDiagram } from "../stateBox/useAllTrainDiagram"; | ||||
|  | ||||
| import { customTrainDataDetector } from "./custom-train-data"; | ||||
| import { getStationList, lineList } from "../lib/getStationList"; | ||||
| import { getTrainType } from "../lib/getTrainType"; | ||||
| import { checkDuplicateTrainData } from "../lib/checkDuplicateTrainData"; | ||||
| import { SheetManager } from "react-native-actions-sheet"; | ||||
| export default function AllTrainDiagramView({ navigation: { navigate } }) { | ||||
|   const { currentTrain } = useCurrentTrain(); | ||||
|   const { areaInfo } = useAreaInfo(); | ||||
|   const { allTrainDiagram } = useAllTrainDiagram(); | ||||
|   const [originalStationList, setOriginalStationList] = useState(); // 第一要素 | ||||
|   const [keyList, setKeyList] = useState(); // 第二要素 | ||||
|   useEffect(() => getStationList().then(setOriginalStationList), []); | ||||
|   useEffect( | ||||
|     () => allTrainDiagram && setKeyList(Object.keys(allTrainDiagram)), | ||||
|     [] | ||||
|   ); | ||||
|   const [input, setInput] = useState(""); // 文字入力 | ||||
|   const [keyBoardVisible, setKeyBoardVisible] = useState(false); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     const showSubscription = Keyboard.addListener("keyboardDidShow", () => { | ||||
|       setKeyBoardVisible(true); | ||||
|     }); | ||||
|     const hideSubscription = Keyboard.addListener("keyboardDidHide", () => { | ||||
|       setKeyBoardVisible(false); | ||||
|     }); | ||||
|  | ||||
|     return () => { | ||||
|       showSubscription.remove(); | ||||
|       hideSubscription.remove(); | ||||
|     }; | ||||
|   }, []); | ||||
|  | ||||
|   const openTrainInfo = (d) => { | ||||
|     const train = customTrainDataDetector(d); | ||||
|     let TrainNumber = ""; | ||||
|     if (train.trainNumDistance != undefined) { | ||||
|       const timeInfo = | ||||
|         parseInt(d.replace("M", "").replace("D", "")) - train.trainNumDistance; | ||||
|       TrainNumber = timeInfo + "号"; | ||||
|     } | ||||
|     const payload = { | ||||
|       data: { | ||||
|         trainNum: d, | ||||
|         limited: `${getTrainType(train.type).data}:${ | ||||
|           train.trainName | ||||
|         }${TrainNumber}`, | ||||
|       }, | ||||
|       navigate, | ||||
|       originalStationList, | ||||
|       from: "AllTrainDiagramView", | ||||
|     }; | ||||
|     SheetManager.show("EachTrainInfo", { | ||||
|       payload, | ||||
|     }); | ||||
|   }; | ||||
|   return ( | ||||
|     <View style={{ backgroundColor: "#0099CC", height: "100%" }}> | ||||
|       <FlatList | ||||
|         style={{ flex: 1 }} | ||||
|         data={keyList?.filter((d) => d.includes(input))} | ||||
|         renderItem={({ item }) => ( | ||||
|           <Item openTrainInfo={openTrainInfo} id={item} /> | ||||
|         )} | ||||
|         keyExtractor={(item) => item} | ||||
|         initialNumToRender={100} | ||||
|       /> | ||||
|       <KeyboardAvoidingView | ||||
|         behavior="padding" | ||||
|         keyboardVerticalOffset={80} | ||||
|         enabled={Platform.OS === "ios"} | ||||
|       > | ||||
|         <View | ||||
|           style={{ | ||||
|             height: 35, | ||||
|             margin: 5, | ||||
|             alignItems: "center", | ||||
|             backgroundColor: "#F4F4F4", | ||||
|             flexDirection: "row", | ||||
|             paddingLeft: 10, | ||||
|             paddingRight: 10, | ||||
|             borderRadius: 25, | ||||
|             borderColor: "#F4F4F4", | ||||
|           }} | ||||
|         > | ||||
|           <TextInput | ||||
|             placeholder="列番を入力してフィルタリングします。" | ||||
|             onFocus={() => { | ||||
|               setKeyBoardVisible(true); | ||||
|             }} | ||||
|             onEndEditing={() => {}} | ||||
|             onChange={(ret) => { | ||||
|               setInput(ret.nativeEvent.text); | ||||
|             }} | ||||
|             value={input} | ||||
|             style={{ flex: 1 }} | ||||
|           /> | ||||
|         </View> | ||||
|       </KeyboardAvoidingView> | ||||
|  | ||||
|       <TouchableOpacity | ||||
|         style={{ | ||||
|           padding: 10, | ||||
|           flexDirection: "row", | ||||
|           borderColor: "white", | ||||
|           borderWidth: 1, | ||||
|           margin: 10, | ||||
|           borderRadius: 5, | ||||
|           alignItems: "center", | ||||
|           display: | ||||
|             Platform.OS === "ios" ? "flex" : keyBoardVisible ? "none" : "flex", | ||||
|         }} | ||||
|         onPress={() => navigate("menu")} | ||||
|       > | ||||
|         <View style={{ flex: 1 }} /> | ||||
|         <Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}> | ||||
|           閉じる | ||||
|         </Text> | ||||
|         <View style={{ flex: 1 }} /> | ||||
|       </TouchableOpacity> | ||||
|     </View> | ||||
|   ); | ||||
| } | ||||
| const Item = ({ id, openTrainInfo }) => { | ||||
|   return ( | ||||
|     <TouchableOpacity | ||||
|       style={{ | ||||
|         padding: 5, | ||||
|         flexDirection: "row", | ||||
|         borderColor: "white", | ||||
|         borderWidth: 1, | ||||
|         margin: 5, | ||||
|         borderRadius: 5, | ||||
|         alignItems: "center", | ||||
|       }} | ||||
|       onPress={() => openTrainInfo(id)} | ||||
|     > | ||||
|       <View style={{ flex: 1 }} /> | ||||
|       <Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}> | ||||
|         {id} | ||||
|       </Text> | ||||
|       <View style={{ flex: 1 }} /> | ||||
|     </TouchableOpacity> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										51
									
								
								components/CurrentTrainListView.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								components/CurrentTrainListView.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| import React, { useRef } from "react"; | ||||
| import { View, Text, TouchableOpacity, Linking } from "react-native"; | ||||
| import MapView, { Marker } from "react-native-maps"; | ||||
| import { MaterialCommunityIcons } from "@expo/vector-icons"; | ||||
| import { useCurrentTrain } from "../stateBox/useCurrentTrain"; | ||||
| export default function CurrentTrainListView({ navigation: { navigate } }) { | ||||
|   const { currentTrain } = useCurrentTrain(); | ||||
|   return ( | ||||
|     <View style={{ height: "100%", backgroundColor: "#0099CC" }}> | ||||
|       {currentTrain && currentTrain.map((d) => <Text>{d.num}</Text>)} | ||||
|       <TouchableOpacity | ||||
|         style={{ | ||||
|           padding: 10, | ||||
|           flexDirection: "row", | ||||
|           borderColor: "white", | ||||
|           borderWidth: 1, | ||||
|           margin: 10, | ||||
|           borderRadius: 5, | ||||
|           alignItems: "center", | ||||
|         }} | ||||
|         onPress={() => navigate("menu")} | ||||
|       > | ||||
|         <View style={{ flex: 1 }} /> | ||||
|         <Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}> | ||||
|           閉じる | ||||
|         </Text> | ||||
|         <View style={{ flex: 1 }} /> | ||||
|       </TouchableOpacity> | ||||
|     </View> | ||||
|   ); | ||||
| } | ||||
| const UsefulBox = (props) => { | ||||
|   const { icon, backgroundColor, flex, onPressButton, children } = props; | ||||
|   return ( | ||||
|     <TouchableOpacity | ||||
|       style={{ | ||||
|         flex: flex, | ||||
|         backgroundColor: backgroundColor, | ||||
|         padding: 10, | ||||
|         alignItems: "center", | ||||
|         margin: 2, | ||||
|       }} | ||||
|       onPress={onPressButton} | ||||
|     > | ||||
|       <MaterialCommunityIcons name={icon} color="white" size={50} /> | ||||
|       <Text style={{ color: "white", fontWeight: "bold", fontSize: 18 }}> | ||||
|         {children} | ||||
|       </Text> | ||||
|     </TouchableOpacity> | ||||
|   ); | ||||
| }; | ||||
| @@ -1,21 +1,11 @@ | ||||
| import React, { Component, useRef, useState, useEffect } from "react"; | ||||
| import React from "react"; | ||||
| import { View, Text, TouchableOpacity, ScrollView } from "react-native"; | ||||
| import { WebView } from "react-native-webview"; | ||||
| import { ListItem } from "native-base"; | ||||
| import Icon from "react-native-vector-icons/Entypo"; | ||||
| import StatusbarDetect from "../StatusbarDetect"; | ||||
| import { AS } from "../storageControl"; | ||||
| import { news } from "../config/newsUpdate"; | ||||
| import { getStationList, lineList } from "../lib/getStationList"; | ||||
| var Status = StatusbarDetect(); | ||||
| export default function FavoriteList({ | ||||
|   navigation, | ||||
|   webview, | ||||
|   stationData, | ||||
|   favoriteStation, | ||||
|   setFavoriteStation, | ||||
| }) { | ||||
| import { useFavoriteStation } from "../stateBox/useFavoriteStation"; | ||||
| export default function FavoriteList({ navigation, webview, stationData }) { | ||||
|   const { navigate } = navigation; | ||||
|   const { favoriteStation } = useFavoriteStation(); | ||||
|  | ||||
|   return ( | ||||
|     <View style={{ height: "100%", backgroundColor: "#0099CC" }}> | ||||
|   | ||||
| @@ -7,8 +7,8 @@ export const TextBox = (props) => { | ||||
|       style={{ | ||||
|         flex: flex, | ||||
|         backgroundColor: backgroundColor, | ||||
|         padding: 10, | ||||
|         height: 70, | ||||
|         padding: 5, | ||||
|         minHeight: 70, | ||||
|         alignItems: "center", | ||||
|         alignContent: "center", | ||||
|         margin: 2, | ||||
|   | ||||
| @@ -1,7 +1,14 @@ | ||||
| import { TouchableOpacity, Text } from "react-native"; | ||||
|  | ||||
| export const TicketBox = (props) => { | ||||
|   const { icon, backgroundColor, flex, onPressButton, children } = props; | ||||
|   const { | ||||
|     icon, | ||||
|     backgroundColor, | ||||
|     flex, | ||||
|     onPressButton, | ||||
|     children, | ||||
|     onLongPressButton, | ||||
|   } = props; | ||||
|   return ( | ||||
|     <TouchableOpacity | ||||
|       style={{ | ||||
| @@ -14,6 +21,7 @@ export const TicketBox = (props) => { | ||||
|         alignItems: "center", | ||||
|       }} | ||||
|       onPress={onPressButton} | ||||
|       onLongPress={onLongPressButton} | ||||
|     > | ||||
|       <Text style={{ color: "white", fontWeight: "bold", fontSize: 18 }}> | ||||
|         {children} | ||||
|   | ||||
| @@ -2,7 +2,6 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|   switch (TrainNumber) { | ||||
|     //しおかぜメイン | ||||
|     //8000 ノーマル | ||||
|     case "2M": | ||||
|     case "4M": | ||||
|     case "6M": | ||||
|     case "14M": | ||||
| @@ -27,10 +26,18 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|         trainNumDistance: 0, | ||||
|         info: "いしづちと併結 / 8000系で運転", | ||||
|       }; | ||||
|     case "2M": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
|         trainName: "しおかぜ", | ||||
|         trainIcon: "http://www.trainfrontview.net/b/s8000nr.png", | ||||
|         trainNumDistance: 0, | ||||
|         info: "8000系で運転", | ||||
|       }; | ||||
|     //8000 アンパン | ||||
|     case "10M": | ||||
|     case "22M": | ||||
|     case "9M": | ||||
|     case "10M": | ||||
|     case "21M": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
| @@ -158,22 +165,36 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|  | ||||
|     //南風 2700ノーマル | ||||
|     case "34D": | ||||
|     case "58D": | ||||
|     case "31D": | ||||
|     case "51D": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
|         trainName: "南風", | ||||
|         trainIcon: "http://www.trainfrontview.net/b/s2700.png", | ||||
|         trainNumDistance: 30, | ||||
|         info: "しまんとと併結 / 2700系で運転", | ||||
|       }; | ||||
|     case "52D": | ||||
|     case "53D": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
|         trainName: "南風", | ||||
|         trainIcon: "http://www.trainfrontview.net/b/s2700.png", | ||||
|         trainNumDistance: 30, | ||||
|         info: "うずしおと併結 / 2700系で運転", | ||||
|       }; | ||||
|     case "38D": | ||||
|     case "40D": | ||||
|     case "42D": | ||||
|     case "46D": | ||||
|     case "50D": | ||||
|     case "52D": | ||||
|     case "54D": | ||||
|     case "58D": | ||||
|     case "31D": | ||||
|     case "35D": | ||||
|     case "39D": | ||||
|     case "41D": | ||||
|     case "43D": | ||||
|     case "47D": | ||||
|     case "51D": | ||||
|     case "53D": | ||||
|     case "55D": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
| @@ -182,14 +203,22 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|         trainNumDistance: 30, | ||||
|         info: "2700系で運転", | ||||
|       }; | ||||
|  | ||||
|     //2700アンパン | ||||
|     case "32D": | ||||
|     case "36D": | ||||
|     case "37D": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
|         trainName: "南風", | ||||
|         trainIcon: "http://www.trainfrontview.net/f/s2700apr.png", | ||||
|         trainNumDistance: 30, | ||||
|         info: "うずしおと連結 / アンパンマン列車で運転", | ||||
|       }; | ||||
|     case "32D": | ||||
|     case "44D": | ||||
|     case "48D": | ||||
|     case "56D": | ||||
|     case "33D": | ||||
|     case "37D": | ||||
|     case "45D": | ||||
|     case "49D": | ||||
|     case "57D": | ||||
| @@ -200,7 +229,6 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|         trainNumDistance: 30, | ||||
|         info: "アンパンマン列車で運転", | ||||
|       }; | ||||
|       break; | ||||
|  | ||||
|     //うずしお | ||||
|     //2700 | ||||
| @@ -213,7 +241,7 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|         trainName: "うずしお", | ||||
|         trainIcon: "http://www.trainfrontview.net/b/s2700_uzu.png", | ||||
|         trainNumDistance: 5000, | ||||
|         info: "南風と宇多津で併結 / 高松-宇多津間進行方向逆転 / 2700系で運転", | ||||
|         info: "南風と併結 / 高松-宇多津間進行方向逆転 / 2700系で運転", | ||||
|       }; | ||||
|     case "3002D": | ||||
|     case "3004D": | ||||
| @@ -384,7 +412,9 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|     case "1052D": | ||||
|     case "1056D": | ||||
|     case "1058D": | ||||
|     case "1062D": | ||||
|     case "1064D": | ||||
|     case "1068D": | ||||
|     case "1070D": | ||||
|     case "1074D": | ||||
|     case "1076D": | ||||
| @@ -392,7 +422,10 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|     case "1080D": | ||||
|     case "1082D": | ||||
|     case "1051D": | ||||
|     case "1053D": | ||||
|     case "1057D": | ||||
|     case "1059D": | ||||
|     case "1063D": | ||||
|     case "1065D": | ||||
|     case "1069D": | ||||
|     case "1071D": | ||||
| @@ -400,7 +433,6 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|     case "1075D": | ||||
|     case "1077D": | ||||
|     case "1079D": | ||||
|     case "1053D": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
|         trainName: "宇和海", | ||||
| @@ -411,14 +443,10 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|     //2000 アンパン込み | ||||
|     case "1054D": | ||||
|     case "1060D": | ||||
|     case "1062D": | ||||
|     case "1066D": | ||||
|     case "1068D": | ||||
|     case "1072D": | ||||
|     case "1055D": | ||||
|     case "1057D": | ||||
|     case "1061D": | ||||
|     case "1063D": | ||||
|     case "1067D": | ||||
|     case "1081D": | ||||
|       return { | ||||
| @@ -430,13 +458,9 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|       }; | ||||
|     //しまんと | ||||
|     case "2002D": | ||||
|     case "2004D": | ||||
|     case "2006D": | ||||
|     case "2008D": | ||||
|     case "2001D": | ||||
|     case "2003D": | ||||
|     case "2005D": | ||||
|     case "2007D": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
|         trainName: "しまんと", | ||||
| @@ -444,6 +468,17 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|         trainNumDistance: 2000, | ||||
|         info: "2700系で運転", | ||||
|       }; | ||||
|     case "2004D": | ||||
|     case "2006D": | ||||
|     case "2003D": | ||||
|     case "2007D": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
|         trainName: "しまんと", | ||||
|         trainIcon: "http://www.trainfrontview.net/b/s2700_smn.png", | ||||
|         trainNumDistance: 2000, | ||||
|         info: "南風と併結 / 2700系で運転", | ||||
|       }; | ||||
|  | ||||
|     //あしずり 2000 | ||||
|     case "2074D": | ||||
| @@ -537,10 +572,10 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|       }; | ||||
|  | ||||
|     //伊予灘ものがたり | ||||
|     case "8901D": | ||||
|     case "8903D": | ||||
|     case "8902D": | ||||
|     case "8904D": | ||||
|     case "8091D": | ||||
|     case "8093D": | ||||
|     case "8092D": | ||||
|     case "8094D": | ||||
|       return { | ||||
|         type: "LTDEXP", | ||||
|         trainName: "伊予灘ものがたり", | ||||
| @@ -584,3 +619,37 @@ export const customTrainDataDetector = (TrainNumber) => { | ||||
|       break; | ||||
|   } | ||||
| }; | ||||
| export const getJRF = (num) => { | ||||
|   switch (num) { | ||||
|     case "71": | ||||
|       return "東京(タ)→高松(タ)\\n"; | ||||
|     case "73": | ||||
|     case "75": | ||||
|       return "大阪(タ)→高松(タ)\\n"; | ||||
|     case "3079": | ||||
|       return "高松(タ)→伊予三島\\n"; | ||||
|     case "3071": | ||||
|     case "3077": | ||||
|       return "高松(タ)→新居浜\\n"; | ||||
|     case "3073": | ||||
|       return "高松(タ)→松山貨物\\n"; | ||||
|     case "70": | ||||
|       return "高松(タ)→東京(タ)\\n"; | ||||
|     case "74": | ||||
|     case "76": | ||||
|       return "高松(タ)→大阪(タ)\\n"; | ||||
|     case "3078": | ||||
|       return "伊予三島→高松(タ)\\n"; | ||||
|     case "3070": | ||||
|       return "新居浜→高松(タ)\\n"; | ||||
|     case "3076": | ||||
|       return "新居浜→高松(タ)\\n"; | ||||
|     case "3072": | ||||
|       return "松山貨物→高松(タ)\\n"; | ||||
|     case "9070": | ||||
|       return "臨時貨物\\n"; | ||||
|     default: | ||||
|       JRF = true; | ||||
|       return null; | ||||
|   } | ||||
| }; | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| import React, { useState, useEffect } from "react"; | ||||
| import { View, Text, TouchableOpacity } from "react-native"; | ||||
| import { View, Text, TouchableOpacity, Linking } from "react-native"; | ||||
| import * as Updates from "expo-updates"; | ||||
| import StatusbarDetect from "../StatusbarDetect"; | ||||
| import { AS } from "../storageControl"; | ||||
| @@ -10,13 +10,19 @@ export default function Setting(props) { | ||||
|   const { | ||||
|     navigation: { navigate }, | ||||
|   } = props; | ||||
|   const [iconSetting, setIconSetting] = useState(undefined); | ||||
|   const [mapSwitch, setMapSwitch] = useState(undefined); | ||||
|   const [stationMenu, setStationMenu] = useState(undefined); | ||||
|   const [iconSetting, setIconSetting] = useState(false); | ||||
|   const [mapSwitch, setMapSwitch] = useState(false); | ||||
|   const [stationMenu, setStationMenu] = useState(false); | ||||
|   const [usePDFView, setUsePDFView] = useState(false); | ||||
|   const [trainMenu, setTrainMenu] = useState(false); | ||||
|   const [trainPosition, setTrainPosition] = useState(false); | ||||
|   useEffect(() => { | ||||
|     AS.getItem("iconSwitch").then(setIconSetting); | ||||
|     AS.getItem("mapSwitch").then(setMapSwitch); | ||||
|     AS.getItem("stationSwitch").then(setStationMenu); | ||||
|     AS.getItem("usePDFView").then(setUsePDFView); | ||||
|     AS.getItem("trainSwitch").then(setTrainMenu); | ||||
|     AS.getItem("trainPositionSwitch").then(setTrainPosition); | ||||
|   }, []); | ||||
|   return ( | ||||
|     <View style={{ height: "100%", backgroundColor: "#0099CC" }}> | ||||
| @@ -83,7 +89,7 @@ export default function Setting(props) { | ||||
|                 textAlignVertical: "center", | ||||
|               }} | ||||
|             > | ||||
|               駅メニューを表示(beta) | ||||
|               駅メニューを表示 | ||||
|             </Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|             <Switch | ||||
| @@ -102,7 +108,64 @@ export default function Setting(props) { | ||||
|                 textAlignVertical: "center", | ||||
|               }} | ||||
|             > | ||||
|               内部バージョン: 4.5 beta-1 | ||||
|               時刻表PDFをアプリ外で表示 | ||||
|             </Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|             <Switch | ||||
|               value={usePDFView == "true" ? true : false} | ||||
|               color={usePDFView == "true" ? "red" : null} | ||||
|               onValueChange={(value) => setUsePDFView(value.toString())} | ||||
|             /> | ||||
|           </View> | ||||
|           <View style={{ flexDirection: "row", padding: 10 }}> | ||||
|             <Text | ||||
|               style={{ | ||||
|                 fontSize: 25, | ||||
|                 alignItems: "center", | ||||
|                 alignContent: "center", | ||||
|                 textAlign: "center", | ||||
|                 textAlignVertical: "center", | ||||
|               }} | ||||
|             > | ||||
|               列車メニュー | ||||
|             </Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|             <Switch | ||||
|               value={trainMenu == "true" ? true : false} | ||||
|               color={trainMenu == "true" ? "red" : null} | ||||
|               onValueChange={(value) => setTrainMenu(value.toString())} | ||||
|             /> | ||||
|           </View> | ||||
|           <View style={{ flexDirection: "row", padding: 10 }}> | ||||
|             <Text | ||||
|               style={{ | ||||
|                 fontSize: 25, | ||||
|                 alignItems: "center", | ||||
|                 alignContent: "center", | ||||
|                 textAlign: "center", | ||||
|                 textAlignVertical: "center", | ||||
|               }} | ||||
|             > | ||||
|               →列車現在位置表示(alpha) | ||||
|             </Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|             <Switch | ||||
|               value={trainPosition == "true" ? true : false} | ||||
|               color={trainPosition == "true" ? "red" : null} | ||||
|               onValueChange={(value) => setTrainPosition(value.toString())} | ||||
|             /> | ||||
|           </View> | ||||
|           <View style={{ flexDirection: "row", padding: 10 }}> | ||||
|             <Text | ||||
|               style={{ | ||||
|                 fontSize: 25, | ||||
|                 alignItems: "center", | ||||
|                 alignContent: "center", | ||||
|                 textAlign: "center", | ||||
|                 textAlignVertical: "center", | ||||
|               }} | ||||
|             > | ||||
|               内部バージョン: 4.6.3.1 | ||||
|             </Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|           </View> | ||||
| @@ -116,10 +179,31 @@ export default function Setting(props) { | ||||
|                 textAlignVertical: "center", | ||||
|               }} | ||||
|             > | ||||
|               releaseChannel: {Updates.releaseChannel} | ||||
|               releaseChannel: {Updates.channel} | ||||
|             </Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|           </View> | ||||
|           <TouchableOpacity | ||||
|             style={{ flexDirection: "row", padding: 10 }} | ||||
|             onPress={() => | ||||
|               Linking.openURL( | ||||
|                 "https://nexcloud.haruk.in/sites/press-harukin/JRShikokuApps/policy" | ||||
|               ) | ||||
|             } | ||||
|           > | ||||
|             <Text | ||||
|               style={{ | ||||
|                 fontSize: 25, | ||||
|                 alignItems: "center", | ||||
|                 alignContent: "center", | ||||
|                 textAlign: "center", | ||||
|                 textAlignVertical: "center", | ||||
|               }} | ||||
|             > | ||||
|               プライバシーポリシー | ||||
|             </Text> | ||||
|             <View style={{ flex: 1 }} /> | ||||
|           </TouchableOpacity> | ||||
|         </View> | ||||
|       </View> | ||||
|       <TouchableOpacity | ||||
| @@ -137,6 +221,9 @@ export default function Setting(props) { | ||||
|             AS.setItem("iconSwitch", iconSetting.toString()), | ||||
|             AS.setItem("mapSwitch", mapSwitch.toString()), | ||||
|             AS.setItem("stationSwitch", stationMenu.toString()), | ||||
|             AS.setItem("usePDFView", usePDFView.toString()), | ||||
|             AS.setItem("trainSwitch", trainMenu.toString()), | ||||
|             AS.setItem("trainPositionSwitch", trainPosition.toString()), | ||||
|           ]).then(() => { | ||||
|             Updates.reloadAsync(); | ||||
|           }); | ||||
|   | ||||
| @@ -58,7 +58,11 @@ export default function TrainMenu({ | ||||
|           backgroundColor={"#F89038"} | ||||
|           icon="train-car" | ||||
|           flex={1} | ||||
|           onPressButton={() => navigate("howto")} | ||||
|           onPressButton={() => | ||||
|             navigate("howto", { | ||||
|               info: "https://train.jr-shikoku.co.jp/usage.htm", | ||||
|             }) | ||||
|           } | ||||
|         > | ||||
|           使い方 | ||||
|         </UsefulBox> | ||||
|   | ||||
| @@ -3,13 +3,16 @@ import { View, Text, TouchableOpacity } from "react-native"; | ||||
| import { Switch } from "react-native-elements"; | ||||
| import { widthPercentageToDP as wp } from "react-native-responsive-screen"; | ||||
| import LottieView from "lottie-react-native"; | ||||
| import { Ionicons, MaterialCommunityIcons } from "@expo/vector-icons"; | ||||
| import { Ionicons } from "@expo/vector-icons"; | ||||
| import { customTrainDataDetector } from "../custom-train-data"; | ||||
| import { useInterval } from "../../lib/useInterval"; | ||||
| import trainList from "../../assets/originData/trainList"; | ||||
| import { objectIsEmpty } from "../../lib/objectIsEmpty"; | ||||
|  | ||||
| let diagramData = undefined; | ||||
| import { getTrainType } from "../../lib/getTrainType"; | ||||
| import { getTrainDelayStatus } from "../../lib/getTrainDelayStatus"; | ||||
| import { checkDuplicateTrainData } from "../../lib/checkDuplicateTrainData"; | ||||
| import { useCurrentTrain } from "../../stateBox/useCurrentTrain"; | ||||
| import { useAreaInfo } from "../../stateBox/useAreaInfo"; | ||||
| import { SheetManager } from "react-native-actions-sheet"; | ||||
|  | ||||
| /** | ||||
|  * | ||||
| @@ -41,47 +44,20 @@ let diagramData = undefined; | ||||
|  * 9062D 四国まんなか千年ものがたり(臨時?) | ||||
|  */ | ||||
| export default function LED_vision(props) { | ||||
|   const HeaderConfig = { | ||||
|     headers: { | ||||
|       referer: "https://train.jr-shikoku.co.jp/sp.html", | ||||
|     }, | ||||
|   }; | ||||
|   const [trainDiagram, setTrainDiagram] = useState(null); // 全列車のダイヤを列番ベースで整理 | ||||
|   const { | ||||
|     station, | ||||
|     trainDiagram, | ||||
|     getCurrentTrain, | ||||
|     navigate, | ||||
|     originalStationList, | ||||
|     openStationACFromEachTrainInfo, | ||||
|   } = props; | ||||
|   const { currentTrain } = useCurrentTrain(); | ||||
|   const [stationDiagram, setStationDiagram] = useState({}); //当該駅の全時刻表 | ||||
|   const [currentTrain, setCurrentTrain] = useState(null); //現在在線中の全列車 | ||||
|   const [currentTrainLoading, setCurrentTrainLoading] = useState("loading"); | ||||
|   const [finalSwitch, setFinalSwitch] = useState(false); | ||||
|   const [trainIDSwitch, setTrainIDSwitch] = useState(false); | ||||
|   const [trainDescriptionSwitch, setTrainDescriptionSwitch] = useState(false); | ||||
|  | ||||
|   const parseAllTrainDiagram = (text) => { | ||||
|     const val = text.replace("[\r\n", "").split(",\r\n"); | ||||
|     let trainDiagram = {}; | ||||
|     val.forEach((element) => { | ||||
|       try { | ||||
|         let data = JSON.parse(element); | ||||
|         Object.keys(data).forEach((key) => (trainDiagram[key] = data[key])); | ||||
|       } catch (e) {} | ||||
|     }); | ||||
|     return trainDiagram; | ||||
|   }; | ||||
|  | ||||
|   useEffect(() => { | ||||
|     //全列車リストを生成する副作用[無条件初回実行] | ||||
|     fetch( | ||||
|       "https://train.jr-shikoku.co.jp/g?arg1=station&arg2=traintimeinfo&arg3=dia", | ||||
|       HeaderConfig | ||||
|     ) | ||||
|       .then((response) => response.text()) | ||||
|       .then((d) => { | ||||
|         if (d.indexOf("<title>404 Not Found</title>") != -1) throw Error; | ||||
|         setTrainDiagram(parseAllTrainDiagram(d)); | ||||
|       }) | ||||
|       .catch((d) => { | ||||
|         console.log("fallback"); | ||||
|         setTrainDiagram(trainList); | ||||
|       }); | ||||
|   }, []); | ||||
|   const { areaInfo } = useAreaInfo(); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     // 現在の駅に停車するダイヤを作成する副作用[列車ダイヤと現在駅情報] | ||||
| @@ -91,52 +67,54 @@ export default function LED_vision(props) { | ||||
|     } | ||||
|     let returnData = {}; | ||||
|     Object.keys(trainDiagram).forEach((key) => { | ||||
|       if (trainDiagram[key].match(props.station.Station_JP + ",")) { | ||||
|       if (trainDiagram[key].match(station.Station_JP + ",")) { | ||||
|         returnData[key] = trainDiagram[key]; | ||||
|       } | ||||
|     }); | ||||
|     setStationDiagram(returnData); | ||||
|   }, [trainDiagram, props.station]); | ||||
|   }, [trainDiagram, station]); | ||||
|  | ||||
|   const getCurrentTrain = () => | ||||
|     fetch( | ||||
|       "https://train.jr-shikoku.co.jp/g?arg1=train&arg2=train", | ||||
|       HeaderConfig | ||||
|     ) | ||||
|       .then((response) => response.json()) | ||||
|       .then((d) => | ||||
|         d.map((x) => ({ num: x.TrainNum, delay: x.delay, Pos: x.Pos })) | ||||
|       ) | ||||
|       .then((d) => { | ||||
|         setCurrentTrain(d); | ||||
|         setCurrentTrainLoading("success"); | ||||
|       }) | ||||
|       .catch((e) => { | ||||
|         console.log("えらー"); | ||||
|         setCurrentTrainLoading("error"); | ||||
|       }); | ||||
|   const [trainTimeAndNumber, setTrainTimeAndNumber] = useState(null); | ||||
|  | ||||
|   useEffect(getCurrentTrain, []); //初回だけ現在の全在線列車取得 | ||||
|   useEffect(() => { | ||||
|     //現在の駅に停車する列車から時刻を切り出してLEDベースにフォーマット | ||||
|     if (objectIsEmpty(stationDiagram)) return () => {}; | ||||
|     const getTimeData = getTime(stationDiagram, station); | ||||
|     setTrainTimeAndNumber(getTimeData); | ||||
|   }, [stationDiagram]); | ||||
|  | ||||
|   useInterval(getCurrentTrain, 15000); //15秒毎に全在線列車取得 | ||||
|   const [selectedTrain, setSelectedTrain] = useState([]); | ||||
|   useEffect(() => { | ||||
|     if (!trainTimeAndNumber) return () => {}; | ||||
|     if (!currentTrain) return () => {}; | ||||
|     const data = trainTimeAndNumber | ||||
|       .filter((d) => currentTrain.map((m) => m.num).includes(d.train)) | ||||
|       .filter(timeFiltering) | ||||
|       .filter((d) => !!finalSwitch || d.lastStation != "当駅止"); | ||||
|     setSelectedTrain(data); | ||||
|   }, [trainTimeAndNumber, currentTrain, finalSwitch]); | ||||
|  | ||||
|   const getTime = (stationDiagram, station) => { | ||||
|     const returnData = Object.keys(stationDiagram).map((d) => { | ||||
|       let a = {}; | ||||
|       stationDiagram[d].split("#").forEach((data) => { | ||||
|     const returnData = Object.keys(stationDiagram).map((trainNum) => { | ||||
|       let trainData = {}; | ||||
|       stationDiagram[trainNum].split("#").forEach((data) => { | ||||
|         if (data.match("着")) { | ||||
|           a.lastStation = data.split(",着,")[0]; | ||||
|           trainData.lastStation = data.split(",着,")[0]; | ||||
|         } | ||||
|         if (data.split(",")[0] === station.Station_JP) { | ||||
|           if (data.match(",発,")) { | ||||
|             a.time = data.split(",発,")[1]; | ||||
|             trainData.time = data.split(",発,")[1]; | ||||
|           } else { | ||||
|             a.time = data.split(",着,")[1]; | ||||
|             a.lastStation = "当駅止"; | ||||
|             trainData.time = data.split(",着,")[1]; | ||||
|             trainData.lastStation = "当駅止"; | ||||
|           } | ||||
|         } | ||||
|       }); | ||||
|       return { train: d, time: a.time, lastStation: a.lastStation }; | ||||
|       return { | ||||
|         train: trainNum, | ||||
|         time: trainData.time, | ||||
|         lastStation: trainData.lastStation, | ||||
|       }; | ||||
|     }); | ||||
|     return returnData.sort((a, b) => { | ||||
|       switch (true) { | ||||
| @@ -152,15 +130,6 @@ export default function LED_vision(props) { | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
|   const [trainTimeAndNumber, setTrainTimeAndNumber] = useState(null); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     //現在の駅に停車する列車から時刻を切り出してLEDベースにフォーマット | ||||
|     if (objectIsEmpty(stationDiagram)) return () => {}; | ||||
|     const getTimeData = getTime(stationDiagram, props.station); | ||||
|     setTrainTimeAndNumber(getTimeData); | ||||
|   }, [stationDiagram]); | ||||
|  | ||||
|   const timeFiltering = (d) => { | ||||
|     const date = new Date(); | ||||
|     const newDate = new Date(); | ||||
| @@ -178,16 +147,34 @@ export default function LED_vision(props) { | ||||
|     return false; | ||||
|   }; | ||||
|  | ||||
|   const [selectedTrain, setSelectedTrain] = useState([]); | ||||
|   const [areaString, setAreaString] = useState(""); | ||||
|   const [areaStringLength, setAreaStringLength] = useState(0); | ||||
|   const [move, setMove] = useState(0); | ||||
|   useInterval( | ||||
|     () => { | ||||
|       if (areaInfo != "") { | ||||
|         if (areaStringLength < move) { | ||||
|           setMove(0); | ||||
|         } else { | ||||
|           setMove(move + 1); | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     350, | ||||
|     true | ||||
|   ); | ||||
|   useEffect(() => { | ||||
|     if (!trainTimeAndNumber) return () => {}; | ||||
|     if (!currentTrain) return () => {}; | ||||
|     const data = trainTimeAndNumber | ||||
|       .filter((d) => currentTrain.map((m) => m.num).includes(d.train)) | ||||
|       .filter(timeFiltering) | ||||
|       .filter((d) => !!finalSwitch || d.lastStation != "当駅止"); | ||||
|     setSelectedTrain(data); | ||||
|   }, [trainTimeAndNumber, currentTrain, finalSwitch]); | ||||
|     if (!areaInfo) return () => {}; | ||||
|     setAreaString( | ||||
|       areaInfo.substring(move, areaInfo.length) + areaInfo.substring(0, move) | ||||
|     ); | ||||
|   }, [move]); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     if (!areaInfo) return () => {}; | ||||
|     setAreaStringLength(areaInfo.length); | ||||
|   }, [areaInfo]); | ||||
|  | ||||
|   return ( | ||||
|     <View | ||||
|       style={{ | ||||
| @@ -198,22 +185,27 @@ export default function LED_vision(props) { | ||||
|         marginHorizontal: wp("1%"), | ||||
|       }} | ||||
|     > | ||||
|       <Header | ||||
|         currentTrainLoading={currentTrainLoading} | ||||
|         setCurrentTrainLoading={setCurrentTrainLoading} | ||||
|         getCurrentTrain={getCurrentTrain} | ||||
|       /> | ||||
|       {selectedTrain.map((d, index) => ( | ||||
|       <Header getCurrentTrain={getCurrentTrain} /> | ||||
|       {selectedTrain.map((d) => ( | ||||
|         <EachData | ||||
|           d={d} | ||||
|           trainIDSwitch={trainIDSwitch} | ||||
|           trainDescriptionSwitch={trainDescriptionSwitch} | ||||
|           props={props} | ||||
|           currentTrain={currentTrain} | ||||
|           station={station} | ||||
|           customTrainDataDetector={customTrainDataDetector} | ||||
|           navigate={props.navigate} | ||||
|           navigate={navigate} | ||||
|           originalStationList={originalStationList} | ||||
|           openStationACFromEachTrainInfo={openStationACFromEachTrainInfo} | ||||
|         /> | ||||
|       ))} | ||||
|       {areaString != "" && ( | ||||
|         <Description | ||||
|           numberOfLines={1} | ||||
|           info={areaString.replace("\n", "").replace("\r", "")} | ||||
|           onClick={() => alert(areaInfo)} | ||||
|         /> | ||||
|       )} | ||||
|  | ||||
|       <Footer | ||||
|         trainIDSwitch={trainIDSwitch} | ||||
|         setTrainIDSwitch={setTrainIDSwitch} | ||||
| @@ -225,11 +217,9 @@ export default function LED_vision(props) { | ||||
|     </View> | ||||
|   ); | ||||
| } | ||||
| const Header = ({ | ||||
|   currentTrainLoading, | ||||
|   setCurrentTrainLoading, | ||||
|   getCurrentTrain, | ||||
| }) => ( | ||||
| const Header = ({ getCurrentTrain }) => { | ||||
|   const { currentTrainLoading, setCurrentTrainLoading } = useCurrentTrain(); | ||||
|   return ( | ||||
|     <View | ||||
|       style={{ | ||||
|         alignContent: "center", | ||||
| @@ -268,58 +258,39 @@ const Header = ({ | ||||
|         ) : null} | ||||
|       </View> | ||||
|     </View> | ||||
| ); | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const Footer = ({ | ||||
| const Footer = (props) => { | ||||
|   const { | ||||
|     trainIDSwitch, | ||||
|     setTrainIDSwitch, | ||||
|     trainDescriptionSwitch, | ||||
|     setTrainDescriptionSwitch, | ||||
|     finalSwitch, | ||||
|     setFinalSwitch, | ||||
| }) => { | ||||
|   } = props; | ||||
|  | ||||
|   const textStyle = { | ||||
|     alignItems: "center", | ||||
|     alignContent: "center", | ||||
|     textAlign: "center", | ||||
|     textAlignVertical: "center", | ||||
|     color: "white", | ||||
|   }; | ||||
|  | ||||
|   return ( | ||||
|     <View style={{ flexDirection: "row", padding: 10, alignItems: "center" }}> | ||||
|       <Text | ||||
|         style={{ | ||||
|           alignItems: "center", | ||||
|           alignContent: "center", | ||||
|           textAlign: "center", | ||||
|           textAlignVertical: "center", | ||||
|           color: "white", | ||||
|         }} | ||||
|       > | ||||
|         種別名 / 列番 | ||||
|       </Text> | ||||
|       <Text style={textStyle}>種別名 / 列番</Text> | ||||
|       <Switch value={trainIDSwitch} onValueChange={setTrainIDSwitch} /> | ||||
|       <View style={{ flex: 1 }} /> | ||||
|       <Text | ||||
|         style={{ | ||||
|           alignItems: "center", | ||||
|           alignContent: "center", | ||||
|           textAlign: "center", | ||||
|           textAlignVertical: "center", | ||||
|           color: "white", | ||||
|         }} | ||||
|       > | ||||
|         列車情報 | ||||
|       </Text> | ||||
|       <Text style={textStyle}>列車情報</Text> | ||||
|       <Switch | ||||
|         value={trainDescriptionSwitch} | ||||
|         onValueChange={setTrainDescriptionSwitch} | ||||
|       /> | ||||
|       <View style={{ flex: 1 }} /> | ||||
|       <Text | ||||
|         style={{ | ||||
|           alignItems: "center", | ||||
|           alignContent: "center", | ||||
|           textAlign: "center", | ||||
|           textAlignVertical: "center", | ||||
|           color: "white", | ||||
|         }} | ||||
|       > | ||||
|         当駅止表示 | ||||
|       </Text> | ||||
|       <Text style={textStyle}>当駅止表示</Text> | ||||
|       <Switch value={finalSwitch} onValueChange={setFinalSwitch} /> | ||||
|     </View> | ||||
|   ); | ||||
| @@ -329,27 +300,46 @@ const EachData = ({ | ||||
|   d, | ||||
|   trainIDSwitch, | ||||
|   trainDescriptionSwitch, | ||||
|   props, | ||||
|   currentTrain, | ||||
|   station, | ||||
|   customTrainDataDetector, | ||||
|   navigate, | ||||
|   originalStationList, | ||||
|   openStationACFromEachTrainInfo, | ||||
| }) => { | ||||
|   const getTrainType = (data) => { | ||||
|     switch (data) { | ||||
|       case "Rapid": | ||||
|         return { color: "aqua", name: "快速" }; | ||||
|       case "LTDEXP": | ||||
|         return { color: "red", name: "特急" }; | ||||
|       case "NightLTDEXP": | ||||
|         return { color: "red", name: "寝台特急" }; | ||||
|       case "Normal": | ||||
|         return { color: "white", name: "普通列車" }; | ||||
|   const { currentTrain } = useCurrentTrain(); | ||||
|   const openTrainInfo = (d) => { | ||||
|     let TrainNumber = ""; | ||||
|     if (train.trainNumDistance != undefined) { | ||||
|       const timeInfo = | ||||
|         parseInt(d.train.replace("M", "").replace("D", "")) - | ||||
|         train.trainNumDistance; | ||||
|       TrainNumber = timeInfo + "号"; | ||||
|     } | ||||
|     const payload = { | ||||
|       data: { | ||||
|         trainNum: d.train, | ||||
|         limited: `${getTrainType(train.type).data}:${ | ||||
|           train.trainName | ||||
|         }${TrainNumber}`, | ||||
|       }, | ||||
|       navigate, | ||||
|       originalStationList, | ||||
|       openStationACFromEachTrainInfo, | ||||
|       from: "LED", | ||||
|     }; | ||||
|     SheetManager.show("EachTrainInfo", { | ||||
|       payload, | ||||
|     }); | ||||
|   }; | ||||
|   const [train, setTrain] = useState(customTrainDataDetector(d.train)); | ||||
|   useEffect(() => { | ||||
|     setTrain(customTrainDataDetector(d.train)); | ||||
|   }, [currentTrain, d.train, trainDescriptionSwitch]); | ||||
|   // 土讃線複数存在対策 | ||||
|   const trainDelayStatus = getTrainDelayStatus( | ||||
|     checkDuplicateTrainData(currentTrain.filter((a) => a.num == d.train)), | ||||
|     station.Station_JP | ||||
|   ); | ||||
|   return ( | ||||
|     <> | ||||
|       <TouchableOpacity | ||||
| @@ -362,78 +352,72 @@ const EachData = ({ | ||||
|           backgroundColor: "#000", | ||||
|           flexDirection: "row", | ||||
|         }} | ||||
|         onPress={() => { | ||||
|           if (train.type != "Normal") { | ||||
|             navigate("trainbase", { | ||||
|               info: "train.html?tn=" + d.train, | ||||
|               from: "LED", | ||||
|             }); | ||||
|           } | ||||
|         }} | ||||
|         onPress={() => openTrainInfo(d)} | ||||
|       > | ||||
|         <TrainName | ||||
|           train={train} | ||||
|           trainName={train.trainName} | ||||
|           trainNumDistance={train.trainNumDistance} | ||||
|           trainIDSwitch={trainIDSwitch} | ||||
|           d={d} | ||||
|           getTrainType={getTrainType(train.type)} | ||||
|         /> | ||||
|         <LastStation d={d} /> | ||||
|         <DependTime d={d} /> | ||||
|         <StatusAndDelay | ||||
|           currentTrain={currentTrain} | ||||
|           d={d} | ||||
|           props={props} | ||||
|           trainDescriptionSwitch={trainDescriptionSwitch} | ||||
|           trainID={d.train} | ||||
|           type={train.type} | ||||
|         /> | ||||
|         <LastStation lastStation={d.lastStation} /> | ||||
|         <DependTime time={d.time} /> | ||||
|         <StatusAndDelay trainDelayStatus={trainDelayStatus} /> | ||||
|       </TouchableOpacity> | ||||
|       {trainDescriptionSwitch && !!train.info && <Description train={train} />} | ||||
|       {trainDescriptionSwitch && !!train.info && ( | ||||
|         <Description info={train.info} /> | ||||
|       )} | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const TrainName = ({ train, trainIDSwitch, d, getTrainType }) => { | ||||
|   const { trainName, trainNumDistance } = train; | ||||
|   let TrainNumber = ""; | ||||
|   if (trainNumDistance != undefined) { | ||||
|     const timeInfo = | ||||
|       parseInt(d.train.replace("M", "").replace("D", "")) - trainNumDistance; | ||||
|     TrainNumber = timeInfo + "号"; | ||||
|   } | ||||
| const TrainName = ({ | ||||
|   trainName, | ||||
|   trainNumDistance, | ||||
|   trainIDSwitch, | ||||
|   trainID, | ||||
|   type, | ||||
| }) => { | ||||
|   const { name, color } = getTrainType(type); | ||||
|   let TrainNumber = | ||||
|     trainNumDistance != undefined | ||||
|       ? `${ | ||||
|           parseInt(trainID.replace("M", "").replace("D", "")) - trainNumDistance | ||||
|         }号` | ||||
|       : ""; | ||||
|   return ( | ||||
|     <View style={{ flex: 9 }}> | ||||
|       <Text | ||||
|         style={{ | ||||
|           fontSize: trainName.length > 6 ? parseInt("13%") : parseInt("18%"), | ||||
|           color: getTrainType.color, | ||||
|           color: color, | ||||
|           fontWeight: "bold", | ||||
|         }} | ||||
|       > | ||||
|         {trainIDSwitch | ||||
|           ? d.train | ||||
|           : `${getTrainType.name} ${trainName}${TrainNumber}`} | ||||
|         {trainIDSwitch ? trainID : `${name} ${trainName}${TrainNumber}`} | ||||
|       </Text> | ||||
|     </View> | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const LastStation = ({ d }) => { | ||||
| const LastStation = ({ lastStation }) => { | ||||
|   return ( | ||||
|     <View style={{ flex: 4, flexDirection: "row" }}> | ||||
|       <Text | ||||
|         style={{ | ||||
|           fontSize: | ||||
|             d.lastStation.length > 4 ? parseInt("13%") : parseInt("18%"), | ||||
|           fontSize: lastStation.length > 4 ? parseInt("13%") : parseInt("18%"), | ||||
|           color: "white", | ||||
|           fontWeight: "bold", | ||||
|         }} | ||||
|       > | ||||
|         {d.lastStation} | ||||
|         {lastStation} | ||||
|       </Text> | ||||
|     </View> | ||||
|   ); | ||||
| }; | ||||
| const DependTime = ({ d }) => { | ||||
|   return ( | ||||
|  | ||||
| const DependTime = ({ time }) => ( | ||||
|   <View style={{ flex: 3 }}> | ||||
|     <Text | ||||
|       style={{ | ||||
| @@ -442,46 +426,12 @@ const DependTime = ({ d }) => { | ||||
|         fontWeight: "bold", | ||||
|       }} | ||||
|     > | ||||
|         {d.time} | ||||
|       {time} | ||||
|     </Text> | ||||
|   </View> | ||||
|   ); | ||||
| }; | ||||
| ); | ||||
|  | ||||
| const checkDuplicateTrainData = (currentTrainArray) => { | ||||
|   const notNyujoData = currentTrainArray.filter((d) => d.delay !== "入線"); | ||||
|   if (currentTrainArray.length == 1) return currentTrainArray[0]; | ||||
|   if (notNyujoData.length == 0) return currentTrainArray[0]; | ||||
|   else return notNyujoData[0]; | ||||
| }; | ||||
| const StatusAndDelay = ({ currentTrain, d, props, trainDescriptionSwitch }) => { | ||||
|   const [status, setStatus] = useState(""); | ||||
|   useEffect(() => { | ||||
|     const array = currentTrain.filter((a) => a.num == d.train); | ||||
|     const current = checkDuplicateTrainData(array); | ||||
|     // 土讃線複数存在対策 | ||||
|     if (!current) return () => {}; | ||||
|     const delay = current.delay; | ||||
|     switch (true) { | ||||
|       case delay === "入線": | ||||
|         if (current.Pos === props.station.Station_JP) { | ||||
|           setStatus("当駅始発"); | ||||
|           break; | ||||
|         } else { | ||||
|           setStatus("発車前"); | ||||
|           break; | ||||
|         } | ||||
|       case isNaN(delay): | ||||
|         setStatus(delay); | ||||
|         break; | ||||
|       case delay === 0: | ||||
|         setStatus("定刻通り"); | ||||
|         break; | ||||
|       default: | ||||
|         setStatus(delay + "分遅れ"); | ||||
|         break; | ||||
|     } | ||||
|   }, [currentTrain, d.train, trainDescriptionSwitch]); | ||||
| const StatusAndDelay = ({ trainDelayStatus }) => { | ||||
|   return ( | ||||
|     <View style={{ flex: 4 }}> | ||||
|       <Text | ||||
| @@ -492,14 +442,14 @@ const StatusAndDelay = ({ currentTrain, d, props, trainDescriptionSwitch }) => { | ||||
|           paddingLeft: 1, | ||||
|         }} | ||||
|       > | ||||
|         {status} | ||||
|         {trainDelayStatus} | ||||
|       </Text> | ||||
|     </View> | ||||
|   ); | ||||
| }; | ||||
| const Description = ({ train }) => { | ||||
|   return ( | ||||
|     <View | ||||
|  | ||||
| const Description = ({ info, numberOfLines = 0, onClick }) => ( | ||||
|   <TouchableOpacity | ||||
|     style={{ | ||||
|       alignContent: "center", | ||||
|       alignItems: "center", | ||||
| @@ -509,6 +459,7 @@ const Description = ({ train }) => { | ||||
|       backgroundColor: "#000", | ||||
|       flexDirection: "row", | ||||
|     }} | ||||
|     onPress={onClick} | ||||
|   > | ||||
|     <View style={{ flex: 4 }}> | ||||
|       <Text | ||||
| @@ -517,11 +468,11 @@ const Description = ({ train }) => { | ||||
|           color: "green", | ||||
|           fontWeight: "bold", | ||||
|         }} | ||||
|         numberOfLines={numberOfLines} | ||||
|       > | ||||
|         {" "} | ||||
|           > {train.info} | ||||
|         > {info} | ||||
|       </Text> | ||||
|     </View> | ||||
|     </View> | ||||
|   ); | ||||
| }; | ||||
|   </TouchableOpacity> | ||||
| ); | ||||
|   | ||||
| @@ -1,35 +1,21 @@ | ||||
| import React, { Component, useRef, useState, useEffect } from "react"; | ||||
| import { | ||||
|   StatusBar, | ||||
|   View, | ||||
|   LayoutAnimation, | ||||
|   ScrollView, | ||||
|   Linking, | ||||
|   Text, | ||||
|   TouchableOpacity, | ||||
| } from "react-native"; | ||||
| import { | ||||
|   widthPercentageToDP as wp, | ||||
|   heightPercentageToDP as hp, | ||||
| } from "react-native-responsive-screen"; | ||||
| import React, { useRef, useState, useEffect } from "react"; | ||||
| import { View, Text, TouchableOpacity } from "react-native"; | ||||
| import { widthPercentageToDP as wp } from "react-native-responsive-screen"; | ||||
| import LottieView from "lottie-react-native"; | ||||
| import { useInterval } from "../../lib/useInterval"; | ||||
| import { AS } from "../../storageControl"; | ||||
| import { useFavoriteStation } from "../../stateBox/useFavoriteStation"; | ||||
|  | ||||
| import lineColorList from "../../assets/originData/lineColorList"; | ||||
|  | ||||
| export default function Sign(props) { | ||||
|   const { | ||||
|     currentStation, | ||||
|     originalStationList, | ||||
|     oP, | ||||
|     favoriteStation, | ||||
|     setFavoriteStation, | ||||
|   } = props; | ||||
|   const { currentStation, originalStationList, oP, oLP } = props; | ||||
|   const { favoriteStation, setFavoriteStation } = useFavoriteStation(); | ||||
|   const [nexPrePosition, setNexPrePosition] = useState(0); | ||||
|  | ||||
|   const [preStation, setPreStation] = useState(); | ||||
|   const [nexStation, setNexStation] = useState(); | ||||
|   const [testButtonStatus, setTestButtonStatus] = useState(false); | ||||
|  | ||||
|   useEffect(() => { | ||||
|     const isFavorite = favoriteStation.filter((d) => { | ||||
|       const compare = JSON.stringify(d); | ||||
| @@ -40,7 +26,7 @@ export default function Sign(props) { | ||||
|         return false; | ||||
|       } | ||||
|     }); | ||||
|     setTestButtonStatus(isFavorite.length != 0); | ||||
|     setTestButtonStatus(isFavorite.length == 0 ? false : true); | ||||
|   }, [favoriteStation, currentStation]); | ||||
|  | ||||
|   useInterval(() => { | ||||
| @@ -48,7 +34,6 @@ export default function Sign(props) { | ||||
|       setNexPrePosition(0); | ||||
|       return () => {}; | ||||
|     } | ||||
|     LayoutAnimation.easeInEaseOut(); | ||||
|     setNexPrePosition( | ||||
|       nexPrePosition + 1 == currentStation.length ? 0 : nexPrePosition + 1 | ||||
|     ); | ||||
| @@ -92,7 +77,7 @@ export default function Sign(props) { | ||||
|   }; | ||||
|   const lottieRef = useRef(); | ||||
|   return ( | ||||
|     <TouchableOpacity style={styleSheet.外枠} onPress={oP}> | ||||
|     <TouchableOpacity style={styleSheet.外枠} onPress={oP} onLongPress={oLP}> | ||||
|       <StationNumberMaker currentStation={currentStation} /> | ||||
|       <StationNameArea currentStation={currentStation} /> | ||||
|       <TouchableOpacity | ||||
| @@ -237,7 +222,10 @@ const StationNumberMaker = (props) => { | ||||
|   }; | ||||
|   return props.currentStation | ||||
|     .filter((d) => (d.StationNumber ? true : false)) | ||||
|     .map((d, index, array) => ( | ||||
|     .map((d, index, array) => { | ||||
|       const lineID = d.StationNumber.slice(0, 1); | ||||
|       const lineName = d.StationNumber.slice(1); | ||||
|       return ( | ||||
|         <View | ||||
|           style={{ | ||||
|             position: "absolute", | ||||
| @@ -247,16 +235,27 @@ const StationNumberMaker = (props) => { | ||||
|             right: "10%", | ||||
|             width: wp("10%"), | ||||
|             height: wp("10%"), | ||||
|           borderColor: "#2E94BB", | ||||
|           borderWidth: parseInt("2%"), | ||||
|             borderColor: lineColorList[lineID], | ||||
|             borderWidth: parseInt("3%"), | ||||
|             borderRadius: parseInt("100%"), | ||||
|           }} | ||||
|           key={array[index].StationNumber} | ||||
|         > | ||||
|           <View style={{ flex: 1 }} /> | ||||
|         <Text style={{ fontSize: parseInt("20%") }}>{d.StationNumber}</Text> | ||||
|           <Text | ||||
|             style={{ | ||||
|               fontSize: parseInt("13%"), | ||||
|               margin: 0, | ||||
|               padding: 0, | ||||
|               textAlign: "center", | ||||
|             }} | ||||
|           > | ||||
|             {lineID + "\n" + lineName} | ||||
|           </Text> | ||||
|           <View style={{ flex: 1 }} /> | ||||
|         </View> | ||||
|     )); | ||||
|       ); | ||||
|     }); | ||||
| }; | ||||
|  | ||||
| const StationNameArea = (props) => { | ||||
|   | ||||
| @@ -1 +1 @@ | ||||
| export const news = "2022-9-30"; | ||||
| export const news = "2023-12-25"; | ||||
|   | ||||
							
								
								
									
										12
									
								
								eas.json
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								eas.json
									
									
									
									
									
								
							| @@ -5,10 +5,12 @@ | ||||
|   "build": { | ||||
|     "development": { | ||||
|       "developmentClient": true, | ||||
|       "distribution": "internal" | ||||
|       "distribution": "internal", | ||||
|       "channel": "development" | ||||
|     }, | ||||
|     "preview": { | ||||
|       "distribution": "internal" | ||||
|       "distribution": "internal", | ||||
|       "channel": "preview" | ||||
|     }, | ||||
|     "mapsbuild": { | ||||
|       "releaseChannel": "mapsbuild" | ||||
| @@ -21,6 +23,12 @@ | ||||
|     }, | ||||
|     "production4.5": { | ||||
|       "releaseChannel": "buyma" | ||||
|     }, | ||||
|     "beta4.6": { | ||||
|       "channel": "catch" | ||||
|     }, | ||||
|     "production4.6": { | ||||
|       "channel": "costoco" | ||||
|     } | ||||
|   }, | ||||
|   "submit": { | ||||
|   | ||||
							
								
								
									
										15
									
								
								howto.js
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								howto.js
									
									
									
									
									
								
							| @@ -2,13 +2,19 @@ const WEBVIEW = "WEBVIEW"; | ||||
| import React, { Component } from "react"; | ||||
| import { StatusBar, View, TouchableOpacity, Text } from "react-native"; | ||||
| import { WebView } from "react-native-webview"; | ||||
| export default ({ navigation: { navigate } }) => ( | ||||
| export default ({ navigation: { navigate }, route }) => { | ||||
|   const { info, goTo, useShow } = route.params; | ||||
|   const onExit = () => { | ||||
|     navigate(goTo); | ||||
|     useShow(); | ||||
|   }; | ||||
|   return ( | ||||
|     <View style={styles.View}> | ||||
|       <WebView | ||||
|         useWebKit | ||||
|       source={{ uri: "https://train.jr-shikoku.co.jp/usage.htm" }} | ||||
|         source={{ uri: info.replace("http://", "https://") }} | ||||
|       /> | ||||
|     <TouchableOpacity style={styles.touch} onPress={() => navigate("Apps")}> | ||||
|       <TouchableOpacity style={styles.touch} onPress={onExit}> | ||||
|         <View style={{ flex: 1 }} /> | ||||
|         <Text style={{ fontSize: 25, fontWeight: "bold", color: "white" }}> | ||||
|           閉じる | ||||
| @@ -16,7 +22,8 @@ export default ({ navigation: { navigate } }) => ( | ||||
|         <View style={{ flex: 1 }} /> | ||||
|       </TouchableOpacity> | ||||
|     </View> | ||||
| ); | ||||
|   ); | ||||
| }; | ||||
| const styles = { | ||||
|   View: { height: "100%", backgroundColor: "#0099CC" }, | ||||
|   touch: { | ||||
|   | ||||
							
								
								
									
										5
									
								
								lib/HeaderConfig.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								lib/HeaderConfig.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| export const HeaderConfig = { | ||||
|   headers: { | ||||
|     referer: "https://train.jr-shikoku.co.jp/sp.html", | ||||
|   }, | ||||
| }; | ||||
							
								
								
									
										6
									
								
								lib/checkDuplicateTrainData.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								lib/checkDuplicateTrainData.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| export const checkDuplicateTrainData = (currentTrainArray) => { | ||||
|   const notNyujoData = currentTrainArray.filter((d) => d.delay !== "入線"); | ||||
|   if (currentTrainArray.length == 1) return currentTrainArray[0]; | ||||
|   if (notNyujoData.length == 0) return currentTrainArray[0]; | ||||
|   else return notNyujoData[0]; | ||||
| }; | ||||
							
								
								
									
										7
									
								
								lib/getPdfViewURL.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								lib/getPdfViewURL.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| import { Platform } from "react-native"; | ||||
|  | ||||
| export const getPDFViewURL = (url) => { | ||||
|   if (Platform.OS == "ios") return url; | ||||
|   else | ||||
|     return `https://mozilla.github.io/pdf.js/web/viewer.html?file=${encodeURI(url)}`; | ||||
| }; | ||||
| @@ -33,11 +33,6 @@ export const lineList = [ | ||||
| export const getStationList = async (props) => { | ||||
|   if (status) return status; | ||||
|   //駅リストイニシャライズ | ||||
|   const HeaderConfig = { | ||||
|     headers: { | ||||
|       referer: "https://train.jr-shikoku.co.jp/sp.html", | ||||
|     }, | ||||
|   }; | ||||
|   return await Promise.all([ | ||||
|     yosan, | ||||
|     uwajima, | ||||
|   | ||||
							
								
								
									
										18
									
								
								lib/getTrainDelayStatus.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								lib/getTrainDelayStatus.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| export const getTrainDelayStatus = (current, Station_JP) => { | ||||
|   if (!current) return () => {}; | ||||
|   const delay = current.delay; | ||||
|   switch (true) { | ||||
|     case delay === "入線": | ||||
|       if (current.Pos === Station_JP) { | ||||
|         return "当駅始発"; | ||||
|       } else { | ||||
|         return "発車前"; | ||||
|       } | ||||
|     case isNaN(delay): | ||||
|       return delay; | ||||
|     case delay === 0: | ||||
|       return "定刻通り"; | ||||
|     default: | ||||
|       return delay + "分遅れ"; | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										14
									
								
								lib/getTrainType.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								lib/getTrainType.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| export const getTrainType = (nameString) => { | ||||
|   switch (nameString) { | ||||
|     case "Rapid": | ||||
|       return { color: "aqua", name: "快速", data: "rapid" }; | ||||
|     case "LTDEXP": | ||||
|       return { color: "red", name: "特急", data: "express" }; | ||||
|     case "NightLTDEXP": | ||||
|       return { color: "red", name: "寝台特急", data: "express" }; | ||||
|     case "Normal": | ||||
|       return { color: "white", name: "普通列車", data: "normal" }; | ||||
|     default: | ||||
|       return { color: "white", name: "その他", data: "normal" }; | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										19
									
								
								lib/initIcon.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								lib/initIcon.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,19 @@ | ||||
| import React from "react"; | ||||
| import { Ionicons, AntDesign } from "@expo/vector-icons"; | ||||
|  | ||||
| export const initIcon = (name, type) => { | ||||
|   switch (type) { | ||||
|     case "Ionicons": | ||||
|       return ({ focused, color, size }) => ( | ||||
|         <Ionicons name={name} size={32} color={focused ? "#0099CC" : "black"} /> | ||||
|       ); | ||||
|     case "AntDesign": | ||||
|       return ({ focused, color, size }) => ( | ||||
|         <AntDesign | ||||
|           name={name} | ||||
|           size={32} | ||||
|           color={focused ? "#0099CC" : "black"} | ||||
|         /> | ||||
|       ); | ||||
|   } | ||||
| }; | ||||
							
								
								
									
										11
									
								
								lib/parseAllTrainDiagram.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								lib/parseAllTrainDiagram.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| export const parseAllTrainDiagram = (text) => { | ||||
|   const val = text.replace("[\r\n", "").split(",\r\n"); | ||||
|   let trainDiagram = {}; | ||||
|   val.forEach((element) => { | ||||
|     try { | ||||
|       let data = JSON.parse(element); | ||||
|       Object.keys(data).forEach((key) => (trainDiagram[key] = data[key])); | ||||
|     } catch (e) {} | ||||
|   }); | ||||
|   return trainDiagram; | ||||
| }; | ||||
							
								
								
									
										8
									
								
								lib/stackOption.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								lib/stackOption.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| import { TransitionPresets } from "@react-navigation/stack"; | ||||
| export const optionData = { | ||||
|   gestureEnabled: true, | ||||
|   ...TransitionPresets.ModalPresentationIOS, | ||||
|   cardOverlayEnabled: true, | ||||
|   headerTransparent: true, | ||||
|   headerShown: false, | ||||
| }; | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										323
									
								
								menu.js
									
									
									
									
									
								
							
							
						
						
									
										323
									
								
								menu.js
									
									
									
									
									
								
							| @@ -1,9 +1,8 @@ | ||||
| import React, { useRef, useState, useEffect, useMemo } from "react"; | ||||
| import React, { useRef, useState, useEffect, useLayoutEffect } from "react"; | ||||
| import Carousel from "react-native-snap-carousel"; | ||||
| import { | ||||
|   Platform, | ||||
|   View, | ||||
|   LayoutAnimation, | ||||
|   ScrollView, | ||||
|   Linking, | ||||
|   Text, | ||||
| @@ -14,7 +13,6 @@ import { ListItem } from "native-base"; | ||||
| import Icon from "react-native-vector-icons/Entypo"; | ||||
| import * as Location from "expo-location"; | ||||
| import StatusbarDetect from "./StatusbarDetect"; | ||||
| import { useNavigation } from "@react-navigation/native"; | ||||
| import AutoHeightImage from "react-native-auto-height-image"; | ||||
| import { widthPercentageToDP as wp } from "react-native-responsive-screen"; | ||||
| import { | ||||
| @@ -24,7 +22,8 @@ import { | ||||
|   MaterialCommunityIcons, | ||||
| } from "@expo/vector-icons"; | ||||
| import LottieView from "lottie-react-native"; | ||||
| import { StationDeteilView } from "./components/ActionSheetComponents/StationDeteilView"; | ||||
| import { parseAllTrainDiagram } from "./lib/parseAllTrainDiagram"; | ||||
| import trainList from "./assets/originData/trainList"; | ||||
|  | ||||
| import LED_vision from "./components/発車時刻表/LED_vidion"; | ||||
| import Sign from "./components/駅名表/Sign"; | ||||
| @@ -33,55 +32,34 @@ import { UsefulBox } from "./components/atom/UsefulBox"; | ||||
| import { TicketBox } from "./components/atom/TicketBox"; | ||||
| import { TextBox } from "./components/atom/TextBox"; | ||||
| import { getStationList, lineList } from "./lib/getStationList"; | ||||
| import { JRSTraInfo } from "./components/ActionSheetComponents/JRSTraInfo"; | ||||
| import useInterval from "./lib/useInterval"; | ||||
| import { HeaderConfig } from "./lib/HeaderConfig"; | ||||
| import { useFavoriteStation } from "./stateBox/useFavoriteStation"; | ||||
| import { SheetManager } from "react-native-actions-sheet"; | ||||
| import { useTrainDelayData } from "./stateBox/useTrainDelayData"; | ||||
|  | ||||
| export default function Menu(props) { | ||||
|   const { | ||||
|     navigation: { navigate }, | ||||
|     favoriteStation, | ||||
|     setFavoriteStation, | ||||
|     busAndTrainData, | ||||
|     getCurrentTrain, | ||||
|   } = props; | ||||
|   const JRSTraInfoEXAcSR = useRef(null); | ||||
|   const StationBoardAcSR = useRef(null); | ||||
|   const navigation = useNavigation(); | ||||
|   const { favoriteStation } = useFavoriteStation(); | ||||
|  | ||||
|   //ここから位置情報 | ||||
|   const [location, setLocation] = useState(null); | ||||
|   //位置情報 | ||||
|   const [locationStatus, setLocationStatus] = useState(null); | ||||
|   useEffect(() => { | ||||
|     Location.requestForegroundPermissionsAsync().then((data) => { | ||||
|       setLocationStatus(data.status); | ||||
|     }); | ||||
|   }, []); | ||||
|   useEffect(() => { | ||||
|     if (locationStatus !== "granted") return () => {}; | ||||
|     getCurrentPosition(); | ||||
|   }, [locationStatus]); | ||||
|  | ||||
|   const getCurrentPosition = () => { | ||||
|     if (locationStatus !== "granted") return () => {}; | ||||
|     Location.getCurrentPositionAsync({}).then((location) => | ||||
|       setLocation(location) | ||||
|       makeCurrentStation(location) | ||||
|     ); | ||||
|   }; | ||||
|  | ||||
|   useInterval(() => { | ||||
|     if (locationStatus !== "granted") return () => {}; | ||||
|     getCurrentPosition(); | ||||
|   }, 5000); | ||||
|   //ここまで位置情報 | ||||
|  | ||||
|   //基礎駅情報取得 | ||||
|   const [originalStationList, setOriginalStationList] = useState(); | ||||
|   useEffect(() => { | ||||
|     getStationList().then(setOriginalStationList); | ||||
|   }, []); | ||||
|  | ||||
|   //ここから現在地付近の駅情報整理 | ||||
|   const [currentAreaStation, setCurrentAreaStation] = useState([]); | ||||
|   useEffect(() => { | ||||
|     if (!location) return () => {}; | ||||
|   const makeCurrentStation = (location) => { | ||||
|     if (!originalStationList) return () => {}; | ||||
|     const findStationEachLine = (selectLine) => { | ||||
|       const searchArea = 0.0015; | ||||
| @@ -107,64 +85,93 @@ export default function Menu(props) { | ||||
|         pre.push(...current); | ||||
|         return pre; | ||||
|       }, []); | ||||
|     LayoutAnimation.easeInEaseOut(); | ||||
|     if (returnDataBase.length) { | ||||
|       if (currentAreaStation.toString() != returnDataBase.toString()) { | ||||
|         setCurrentAreaStation(returnDataBase); | ||||
|       let currentStation = currentStation == undefined ? [] : currentStation; | ||||
|       if (currentStation.toString() != returnDataBase.toString()) { | ||||
|         setCurrentStation(returnDataBase); | ||||
|       } | ||||
|     } else { | ||||
|       setCurrentAreaStation([]); | ||||
|       setCurrentStation(undefined); | ||||
|     } | ||||
|   }, [location, originalStationList]); | ||||
|   }; | ||||
|  | ||||
|   //Favoriteから現在地を排除し現在地を最初に持ってくるバージョン | ||||
|   //const [locationAndFavorite, setLocationAndFavorite] = useState([]); | ||||
|   const locationAndFavorite = useMemo(() => { | ||||
|     const data = favoriteStation.filter((d) => | ||||
|       JSON.stringify(d) === JSON.stringify(currentAreaStation) ? false : true | ||||
|     ); | ||||
|     return [...currentAreaStation, ...data]; | ||||
|   }, [currentAreaStation, favoriteStation]); | ||||
|   // useEffect(() => { | ||||
|   //   if (!favoriteStation) return () => {}; | ||||
|   //   const data = favoriteStation.filter((d) => | ||||
|   //     JSON.stringify(d) === JSON.stringify(currentAreaStation) ? false : true | ||||
|   //   ); | ||||
|   //   setLocationAndFavorite([...currentAreaStation, ...data]); | ||||
|   // }, [currentAreaStation, favoriteStation]); | ||||
|   useEffect(getCurrentPosition, [locationStatus]); | ||||
|   useInterval(getCurrentPosition, 5000); | ||||
|  | ||||
|   const [selectedCurrentStation, setSelectedCurrentStation] = useState(0); | ||||
|   useEffect(() => { | ||||
|     console.log(selectedCurrentStation > locationAndFavorite.length); | ||||
|     if (locationAndFavorite.length == 0) { | ||||
|       //carouselRef.current.snapToItem(0); | ||||
|       setSelectedCurrentStation(0); | ||||
|     } | ||||
|     if (selectedCurrentStation > locationAndFavorite.length - 1) { | ||||
|       //carouselRef.current.snapToItem(locationAndFavorite.length - 1); | ||||
|       setSelectedCurrentStation(locationAndFavorite.length - 1); | ||||
|     } | ||||
|   }, [locationAndFavorite]); | ||||
|   const [currentStation, setCurrentStation] = useState(undefined); //第三要素 | ||||
|  | ||||
|   const [originalStationList, setOriginalStationList] = useState(); // 第一要素 | ||||
|   useLayoutEffect(() => getStationList().then(setOriginalStationList), []); | ||||
|  | ||||
|   const [count, setCount] = useState(0); | ||||
|   const [delayData, setDelayData] = useState(undefined); | ||||
|   const [getTime, setGetTime] = useState(new Date()); | ||||
|   const [loadingDelayData, setLoadingDelayData] = useState(true); | ||||
|   const carouselRef = useRef(); | ||||
|   const scrollRef = useRef(); | ||||
|   const [isScroll, setIsScroll] = useState(true); | ||||
|   const [selectedCurrentStation, setSelectedCurrentStation] = useState(0); | ||||
|  | ||||
|   const [allStationData, setAllStationData] = useState([]); | ||||
|   useEffect(() => { | ||||
|     setAllStationData( | ||||
|       [currentStation, ...favoriteStation].filter((d) => d != undefined) | ||||
|     ); | ||||
|   }, [currentStation, favoriteStation]); | ||||
|   useEffect(() => { | ||||
|     if (allStationData.length == 0) { | ||||
|       setSelectedCurrentStation(0); | ||||
|       return; | ||||
|     } | ||||
|     if (allStationData[selectedCurrentStation] == undefined) { | ||||
|       const count = selectedCurrentStation - 1; | ||||
|       setSelectedCurrentStation(count); | ||||
|     } | ||||
|   }, [selectedCurrentStation, currentStation, favoriteStation]); | ||||
|   useEffect(() => { | ||||
|     if (!carouselRef.current) return; | ||||
|     if (carouselRef.current?._itemToSnapTo != selectedCurrentStation) { | ||||
|       carouselRef.current.snapToItem(0); | ||||
|       carouselRef.current.snapToItem(selectedCurrentStation); | ||||
|     } | ||||
|   }, [selectedCurrentStation]); | ||||
|  | ||||
|   //全列車ダイヤリストを作成するuseEffect | ||||
|   const [trainDiagram, setTrainDiagram] = useState(null); // 全列車のダイヤを列番ベースで整理 | ||||
|   useEffect(() => { | ||||
|     //全列車リストを生成する副作用[無条件初回実行] | ||||
|     fetch( | ||||
|       "https://script.google.com/macros/s/AKfycbyKxch7z7l8e07LXulRHqxjVoIiB13kcgvoToLE-rqlxLmLSKdlmqz0FI1F2EuA7Zfg/exec" | ||||
|       "https://train.jr-shikoku.co.jp/g?arg1=station&arg2=traintimeinfo&arg3=dia", | ||||
|       HeaderConfig | ||||
|     ) | ||||
|       .then((response) => response.text()) | ||||
|       .then((data) => setDelayData(data !== "" ? data.split("^") : null)) | ||||
|       .then(LayoutAnimation.easeInEaseOut) | ||||
|       .then(() => setGetTime(new Date())) | ||||
|       .finally(() => setLoadingDelayData(false)); | ||||
|   }, [loadingDelayData]); | ||||
|       .then((d) => { | ||||
|         if (d.indexOf("<title>404 Not Found</title>") != -1) throw Error; | ||||
|         setTrainDiagram(parseAllTrainDiagram(d)); | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         console.log("fallback"); | ||||
|         setTrainDiagram(trainList); | ||||
|       }); | ||||
|   }, []); | ||||
|  | ||||
|   const openStationACFromEachTrainInfo = () => { | ||||
|     // EachTrainInfoAsSR.current?.hide(); | ||||
|     // const findStationEachLine = (selectLine) => { | ||||
|     //   let NearStation = selectLine.filter((d) => d.Station_JP == stationName); | ||||
|     //   return NearStation; | ||||
|     // }; | ||||
|     // let returnDataBase = lineList | ||||
|     //   .map((d) => findStationEachLine(originalStationList[d])) | ||||
|     //   .filter((d) => d.length > 0) | ||||
|     //   .reduce((pre, current) => { | ||||
|     //     pre.push(...current); | ||||
|     //     return pre; | ||||
|     //   }, []); | ||||
|     // if (returnDataBase.length) { | ||||
|     //   setStationBoardData(returnDataBase); | ||||
|     //   sleep(30, function () { | ||||
|     //     StationBoardAcSR.current?.show(); | ||||
|     //   }); | ||||
|     // } else { | ||||
|     //   setStationBoardData(undefined); | ||||
|     //   StationBoardAcSR.current?.hide(); | ||||
|     // } | ||||
|   }; | ||||
|   return ( | ||||
|     <View | ||||
|       style={{ | ||||
| @@ -175,15 +182,13 @@ export default function Menu(props) { | ||||
|     > | ||||
|       <StatusbarDetect /> | ||||
|       <TitleBar /> | ||||
|       <FixedContent | ||||
|         scrollRef={scrollRef} | ||||
|         isScroll={isScroll} | ||||
|         navigate={navigate} | ||||
|       > | ||||
|       <ScrollView> | ||||
|         <FixedContentTop navigate={navigate} /> | ||||
|         {originalStationList && allStationData.length != 0 && ( | ||||
|           <Carousel | ||||
|             ref={carouselRef} | ||||
|             layout={"default"} | ||||
|           data={originalStationList && locationAndFavorite} | ||||
|             data={originalStationList && allStationData} | ||||
|             sliderWidth={wp("100%")} | ||||
|             itemWidth={wp("80%")} | ||||
|             enableMomentum | ||||
| @@ -192,54 +197,59 @@ export default function Menu(props) { | ||||
|             onSnapToItem={(d) => { | ||||
|               setSelectedCurrentStation(d); | ||||
|             }} | ||||
|           renderItem={({ item, index }) => { | ||||
|             renderItem={({ item }) => { | ||||
|               return ( | ||||
|               <View style={{ marginVertical: 10 }} key={item[0].StationNumber}> | ||||
|                 <View | ||||
|                   style={{ marginVertical: 10 }} | ||||
|                   key={item[0].StationNumber} | ||||
|                 > | ||||
|                   <Sign | ||||
|                     currentStation={item} | ||||
|                     originalStationList={originalStationList} | ||||
|                   favoriteStation={favoriteStation} | ||||
|                   setFavoriteStation={setFavoriteStation} | ||||
|                   oP={StationBoardAcSR.current?.setModalVisible} | ||||
|                     oP={() => { | ||||
|                       const payload = { | ||||
|                         currentStation: | ||||
|                           originalStationList && | ||||
|                           allStationData.length != 0 && | ||||
|                           allStationData[selectedCurrentStation], | ||||
|                         originalStationList: originalStationList, | ||||
|                         navigate: navigate, | ||||
|                         goTo: "menu", | ||||
|                         useShow: () => | ||||
|                           SheetManager.show("StationDetailView", { | ||||
|                             payload, | ||||
|                           }), | ||||
|                         onExit: () => { | ||||
|                           SheetManager.hide("StationDetailView"); | ||||
|                         }, | ||||
|                       }; | ||||
|                       SheetManager.show("StationDetailView", { | ||||
|                         payload, | ||||
|                       }); | ||||
|                     }} | ||||
|                   /> | ||||
|                 </View> | ||||
|               ); | ||||
|             }} | ||||
|           /> | ||||
|         {originalStationList && locationAndFavorite[selectedCurrentStation] && ( | ||||
|         )} | ||||
|         {allStationData.length != 0 && | ||||
|           originalStationList && | ||||
|           allStationData[selectedCurrentStation] && ( | ||||
|             <LED_vision | ||||
|               station={ | ||||
|               originalStationList && | ||||
|               locationAndFavorite[selectedCurrentStation][0] | ||||
|                 originalStationList && allStationData[selectedCurrentStation][0] | ||||
|               } | ||||
|               trainDiagram={trainDiagram} | ||||
|               getCurrentTrain={getCurrentTrain} | ||||
|               navigate={navigate} | ||||
|               originalStationList={originalStationList} | ||||
|               openStationACFromEachTrainInfo={openStationACFromEachTrainInfo} | ||||
|             /> | ||||
|           )} | ||||
|         <JRSTraInfoBox | ||||
|           JRSTraInfoEXAcSR={JRSTraInfoEXAcSR} | ||||
|           getTime={getTime} | ||||
|           setLoadingDelayData={setLoadingDelayData} | ||||
|           loadingDelayData={loadingDelayData} | ||||
|           delayData={delayData} | ||||
|         /> | ||||
|       </FixedContent> | ||||
|       <StationDeteilView | ||||
|         StationBoardAcSR={StationBoardAcSR} | ||||
|         currentStation={ | ||||
|           originalStationList && locationAndFavorite[selectedCurrentStation] | ||||
|         } | ||||
|         originalStationList={originalStationList} | ||||
|         favoriteStation={favoriteStation} | ||||
|         setFavoriteStation={setFavoriteStation} | ||||
|         busAndTrainData={busAndTrainData} | ||||
|       /> | ||||
|       <JRSTraInfo | ||||
|         JRSTraInfoEXAcSR={JRSTraInfoEXAcSR} | ||||
|         getTime={getTime} | ||||
|         loadingDelayData={loadingDelayData} | ||||
|         setLoadingDelayData={setLoadingDelayData} | ||||
|         delayData={delayData} | ||||
|       /> | ||||
|         <JRSTraInfoBox /> | ||||
|         <FixedContentBottom navigate={navigate} /> | ||||
|       </ScrollView> | ||||
|     </View> | ||||
|   ); | ||||
| } | ||||
| @@ -302,14 +312,15 @@ const TopMenuButton = () => { | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const JRSTraInfoBox = (props) => { | ||||
| const JRSTraInfoBox = () => { | ||||
|   const { | ||||
|     JRSTraInfoEXAcSR, | ||||
|     getTime, | ||||
|     setLoadingDelayData, | ||||
|     loadingDelayData, | ||||
|     setGetTime, | ||||
|     delayData, | ||||
|   } = props; | ||||
|     setDelayData, | ||||
|     loadingDelayData, | ||||
|     setLoadingDelayData, | ||||
|   } = useTrainDelayData(); | ||||
|   const styles = { | ||||
|     touch: { | ||||
|       backgroundColor: "#0099CC", | ||||
| @@ -341,7 +352,7 @@ const JRSTraInfoBox = (props) => { | ||||
|   }; | ||||
|   return ( | ||||
|     <TouchableOpacity | ||||
|       onPress={JRSTraInfoEXAcSR.current?.setModalVisible} | ||||
|       onPress={() => SheetManager.show("JRSTraInfo")} | ||||
|       style={styles.touch} | ||||
|     > | ||||
|       <ScrollView scrollEnabled={false} style={styles.scroll}> | ||||
| @@ -365,7 +376,6 @@ const JRSTraInfoBox = (props) => { | ||||
|             size={30} | ||||
|             style={{ margin: 5 }} | ||||
|             onPress={() => { | ||||
|               LayoutAnimation.easeInEaseOut(); | ||||
|               setLoadingDelayData(true); | ||||
|             }} | ||||
|           /> | ||||
| @@ -381,7 +391,7 @@ const JRSTraInfoBox = (props) => { | ||||
|               /> | ||||
|             </View> | ||||
|           ) : delayData ? ( | ||||
|             delayData.map((d, index) => { | ||||
|             delayData.map((d) => { | ||||
|               let data = d.split(" "); | ||||
|               return ( | ||||
|                 <View style={{ flexDirection: "row" }} key={data[1] + "key"}> | ||||
| @@ -409,26 +419,16 @@ const JRSTraInfoBox = (props) => { | ||||
|   ); | ||||
| }; | ||||
|  | ||||
| const FixedContent = (props) => ( | ||||
| const FixedContentTop = () => { | ||||
|   return ( | ||||
|     <> | ||||
|     <ScrollView ref={props.scrollRef} scrollEnabled={props.isScroll}> | ||||
|       <TopMenuButton /> | ||||
|       <TextBox | ||||
|         backgroundColor="#0099CC" | ||||
|         flex={1} | ||||
|         onPressButton={() => | ||||
|           Linking.openURL( | ||||
|             "https://www.jr-shikoku.co.jp/02_information/suspension/sp/" | ||||
|           ) | ||||
|         } | ||||
|       > | ||||
|         <Text style={{ color: "white", fontWeight: "bold", fontSize: 18 }}> | ||||
|           新型コロナウイルスに関するお知らせ | ||||
|         </Text> | ||||
|         <Text style={{ color: "white", fontSize: 15 }}> | ||||
|           列車の運行計画・混雑状況・感染症対策への取り組み | ||||
|         </Text> | ||||
|       </TextBox> | ||||
|     </> | ||||
|   ); | ||||
| }; | ||||
| const FixedContentBottom = (props) => { | ||||
|   return ( | ||||
|     <> | ||||
|       {props.children} | ||||
|  | ||||
|       <View style={{ flexDirection: "row" }}> | ||||
| @@ -610,14 +610,7 @@ const FixedContent = (props) => ( | ||||
|             borderBottomRightRadius: 10, | ||||
|           }} | ||||
|         > | ||||
|           {((data) => | ||||
|             data.map((d) => ( | ||||
|               <ListItem onPress={() => Linking.openURL(d.url)}> | ||||
|                 <Text>{d.name}</Text> | ||||
|                 <View style={{ flex: 1 }} /> | ||||
|                 <Icon name="chevron-right" size={20} /> | ||||
|               </ListItem> | ||||
|             )))([ | ||||
|           {[ | ||||
|             { | ||||
|               url: "https://twitter.com/JRshikoku_eigyo", | ||||
|               name: "JR四国営業部【公式】", | ||||
| @@ -666,15 +659,35 @@ const FixedContent = (props) => ( | ||||
|               url: "https://twitter.com/Yoakemonogatari", | ||||
|               name: "志国土佐 時代の夜明けのものがたり【公式】", | ||||
|             }, | ||||
|           ])} | ||||
|           ].map((d) => ( | ||||
|             <ListItem onPress={() => Linking.openURL(d.url)}> | ||||
|               <Text>{d.name}</Text> | ||||
|               <View style={{ flex: 1 }} /> | ||||
|               <Icon name="chevron-right" size={20} /> | ||||
|             </ListItem> | ||||
|           ))} | ||||
|         </View> | ||||
|       </View> | ||||
|       <Text style={{ fontWeight: "bold", fontSize: 20 }}>上級者向け機能</Text> | ||||
|       <TextBox | ||||
|         backgroundColor="#8c00d6" | ||||
|         flex={1} | ||||
|         onPressButton={() => props.navigate("AllTrainIDList")} | ||||
|       > | ||||
|         <Text style={{ color: "white", fontWeight: "bold", fontSize: 20 }}> | ||||
|           列番探索 | ||||
|         </Text> | ||||
|         <Text style={{ color: "white", fontSize: 18 }}> | ||||
|           データベースに存在する全列車のダイヤを探索 | ||||
|         </Text> | ||||
|       </TextBox> | ||||
|       <Text style={{ fontWeight: "bold", fontSize: 20 }}> | ||||
|         このアプリについて | ||||
|       </Text> | ||||
|       <Text> | ||||
|         このアプリはXprocess(HARUKIN)が製作しているJR四国の完全非公式アシストアプリケーションです。このアプリに関することでのJR四国公式へ問合せすることはお控えください。以下のTwitterよりお願いします。 | ||||
|       </Text> | ||||
|  | ||||
|       <TextBox | ||||
|         backgroundColor="#CC0000" | ||||
|         flex={1} | ||||
| @@ -707,6 +720,6 @@ const FixedContent = (props) => ( | ||||
|     height="200" | ||||
|     source={require("./assets/トレインビジョン関係/1.svg")} | ||||
|   /> */} | ||||
|     </ScrollView> | ||||
|     </> | ||||
| ); | ||||
|   ); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										54
									
								
								ndView.js
									
									
									
									
									
								
							
							
						
						
									
										54
									
								
								ndView.js
									
									
									
									
									
								
							| @@ -1,8 +1,11 @@ | ||||
| import React from "react"; | ||||
| import { View, Platform } from "react-native"; | ||||
| import React, { useRef, useState } from "react"; | ||||
| import { View, Platform, TouchableOpacity } from "react-native"; | ||||
| import { WebView } from "react-native-webview"; | ||||
| import Constants from "expo-constants"; | ||||
| import { Ionicons } from "@expo/vector-icons"; | ||||
| export default function tndView() { | ||||
|   const webview = useRef(); | ||||
|   const [LoadError, setLoadError] = useState(false); | ||||
|   return ( | ||||
|     <View | ||||
|       style={{ | ||||
| @@ -13,11 +16,22 @@ export default function tndView() { | ||||
|     > | ||||
|       <WebView | ||||
|         useWebKit={true} | ||||
|         ref={webview} | ||||
|         source={{ uri: "https://www.jr-shikoku.co.jp/info/" }} | ||||
|         originWhitelist={["https://www.jr-shikoku.co.jp"]} | ||||
|         mixedContentMode={"compatibility"} | ||||
|         javaScriptEnabled={true} | ||||
|         injectedJavaScript={jsa} | ||||
|         pullToRefreshEnabled | ||||
|         onError={(syntheticEvent) => { | ||||
|           //webViewの再読み込みを行う | ||||
|           this.webView.reload(); | ||||
|         }} | ||||
|       /> | ||||
|       <ReloadButton | ||||
|         onPress={() => webview.current.reload()} | ||||
|         top={Platform.OS == "ios" ? Constants.statusBarHeight : 0} | ||||
|         LoadError={LoadError} | ||||
|       /> | ||||
|     </View> | ||||
|   ); | ||||
| @@ -26,3 +40,39 @@ const jsa = ` | ||||
| document.querySelector('.sitettl').style.display = 'none';	 | ||||
| document.querySelector('.attention').style.display = 'none'; | ||||
| `; | ||||
|  | ||||
| const ReloadButton = ({ onPress, top, mapSwitch, LoadError = false }) => { | ||||
|   const styles = { | ||||
|     touch: { | ||||
|       position: "absolute", | ||||
|       top, | ||||
|       right: 10, | ||||
|       width: 50, | ||||
|       height: 50, | ||||
|       backgroundColor: LoadError ? "red" : "#0099CC", | ||||
|       borderColor: "white", | ||||
|       borderStyle: "solid", | ||||
|       borderWidth: 1, | ||||
|       borderRadius: 50, | ||||
|       alignContent: "center", | ||||
|       alignSelf: "center", | ||||
|       alignItems: "center", | ||||
|       display: mapSwitch, | ||||
|     }, | ||||
|     text: { | ||||
|       textAlign: "center", | ||||
|       width: "auto", | ||||
|       height: "auto", | ||||
|       textAlignVertical: "center", | ||||
|       fontWeight: "bold", | ||||
|       color: "white", | ||||
|     }, | ||||
|   }; | ||||
|   return ( | ||||
|     <TouchableOpacity onPress={onPress} style={styles.touch}> | ||||
|       <View style={{ flex: 1 }} /> | ||||
|       <Ionicons name="reload" color="white" size={30} /> | ||||
|       <View style={{ flex: 1 }} /> | ||||
|     </TouchableOpacity> | ||||
|   ); | ||||
| }; | ||||
|   | ||||
							
								
								
									
										38
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										38
									
								
								package.json
									
									
									
									
									
								
							| @@ -8,43 +8,47 @@ | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@expo/vector-icons": "^13.0.0", | ||||
|     "@react-native-async-storage/async-storage": "1.17.11", | ||||
|     "@react-native-async-storage/async-storage": "1.18.2", | ||||
|     "@react-native-community/masked-view": "0.1.10", | ||||
|     "@react-navigation/bottom-tabs": "^5.11.11", | ||||
|     "@react-navigation/native": "^5.9.4", | ||||
|     "@react-navigation/stack": "^5.14.5", | ||||
|     "expo": "^48.0.0", | ||||
|     "expo-font": "~11.1.1", | ||||
|     "expo-location": "~15.1.1", | ||||
|     "expo-updates": "~0.16.3", | ||||
|     "expo-web-browser": "~12.1.1", | ||||
|     "dayjs": "^1.11.9", | ||||
|     "eas-cli": "^5.9.1", | ||||
|     "expo": "^49.0.21", | ||||
|     "expo-device": "~5.4.0", | ||||
|     "expo-font": "~11.4.0", | ||||
|     "expo-location": "~16.1.0", | ||||
|     "expo-notifications": "~0.20.1", | ||||
|     "expo-updates": "~0.18.17", | ||||
|     "expo-web-browser": "~12.3.2", | ||||
|     "firebase": "8.2.3", | ||||
|     "lottie-react-native": "5.1.4", | ||||
|     "lottie-react-native": "5.1.6", | ||||
|     "native-base": "^2.15.2", | ||||
|     "npm": "^7.18.1", | ||||
|     "pushy-react-native": "^1.0.18", | ||||
|     "react": "18.2.0", | ||||
|     "react-native": "0.71.3", | ||||
|     "react-native-actions-sheet": "^0.4.9", | ||||
|     "react-native": "0.72.6", | ||||
|     "react-native-actions-sheet": "0.8.21", | ||||
|     "react-native-auto-height-image": "^3.2.4", | ||||
|     "react-native-elements": "^3.4.2", | ||||
|     "react-native-gesture-handler": "~2.9.0", | ||||
|     "react-native-maps": "1.3.2", | ||||
|     "react-native-reanimated": "~2.14.4", | ||||
|     "react-native-gesture-handler": "~2.12.0", | ||||
|     "react-native-maps": "1.7.1", | ||||
|     "react-native-reanimated": "^3.6.1", | ||||
|     "react-native-remote-svg": "^2.0.6", | ||||
|     "react-native-responsive-screen": "^1.4.2", | ||||
|     "react-native-router-flux": "^4.3.1", | ||||
|     "react-native-safe-area-context": "4.5.0", | ||||
|     "react-native-screens": "~3.20.0", | ||||
|     "react-native-safe-area-context": "4.6.3", | ||||
|     "react-native-screens": "~3.22.0", | ||||
|     "react-native-snap-carousel": "^3.9.1", | ||||
|     "react-native-storage": "^1.0.1", | ||||
|     "react-native-svg": "13.4.0", | ||||
|     "react-native-svg": "13.9.0", | ||||
|     "react-native-svg-uri": "^1.2.3", | ||||
|     "react-native-vector-icons": "^8.1.0", | ||||
|     "react-native-webview": "11.26.0" | ||||
|     "react-native-webview": "^13.6.3" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "babel-preset-expo": "^9.3.0" | ||||
|     "babel-preset-expo": "^9.5.0" | ||||
|   }, | ||||
|   "private": true | ||||
| } | ||||
|   | ||||
							
								
								
									
										38
									
								
								stateBox/useAllTrainDiagram.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								stateBox/useAllTrainDiagram.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| import React, { createContext, useContext, useEffect, useState } from "react"; | ||||
| const initialState = { | ||||
|   allTrainDiagram: undefined, | ||||
|   setAllTrainDiagram: () => {}, | ||||
| }; | ||||
|  | ||||
| const AllTrainDiagramContext = createContext(initialState); | ||||
|  | ||||
| export const useAllTrainDiagram = () => { | ||||
|   return useContext(AllTrainDiagramContext); | ||||
| }; | ||||
|  | ||||
| export const AllTrainDiagramProvider = ({ children }) => { | ||||
|   const [allTrainDiagram, setAllTrainDiagram] = useState(); | ||||
|   useEffect(() => { | ||||
|     fetch( | ||||
|       "https://script.google.com/macros/s/AKfycbx_s7RB-xTy-iAslFJg7LfplLV09-hjDXEjdi9kCP_JT45wq17Af_IPOKIOqIfaNDg/exec" | ||||
|     ) | ||||
|       .then((res) => res.json()) | ||||
|       .then((res) => { | ||||
|         const data = {}; | ||||
|         res.forEach((d) => { | ||||
|           const keys = Object.keys(d); | ||||
|           data[keys] = d[keys]; | ||||
|         }); | ||||
|         return data; | ||||
|       }) | ||||
|       .then((res) => setAllTrainDiagram(res)); | ||||
|   }, []); | ||||
|  | ||||
|   return ( | ||||
|     <AllTrainDiagramContext.Provider | ||||
|       value={{ allTrainDiagram, setAllTrainDiagram }} | ||||
|     > | ||||
|       {children} | ||||
|     </AllTrainDiagramContext.Provider> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										21
									
								
								stateBox/useAreaInfo.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								stateBox/useAreaInfo.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| import React, { createContext, useContext, useState } from "react"; | ||||
| const initialState = { | ||||
|   areaInfo: "", | ||||
|   setAreainfo: () => {}, | ||||
| }; | ||||
|  | ||||
| const AreaInfoContext = createContext(initialState); | ||||
|  | ||||
| export const useAreaInfo = () => { | ||||
|   return useContext(AreaInfoContext); | ||||
| }; | ||||
|  | ||||
| export const AreaInfoProvider = ({ children }) => { | ||||
|   const [areaInfo, setAreaInfo] = useState(""); | ||||
|  | ||||
|   return ( | ||||
|     <AreaInfoContext.Provider value={{ areaInfo, setAreaInfo }}> | ||||
|       {children} | ||||
|     </AreaInfoContext.Provider> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										39
									
								
								stateBox/useBusAndTrainData.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								stateBox/useBusAndTrainData.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| import React, { createContext, useContext, useState } from "react"; | ||||
| const initialState = { | ||||
|   busAndTrainData: [], | ||||
|   setBusAndTrainData: () => {}, | ||||
|   trainPairData: [], | ||||
|   setTrainPairData: () => {}, | ||||
|   initializeTrainPairList: () => {}, | ||||
| }; | ||||
|  | ||||
| const BusAndTrainDataContext = createContext(initialState); | ||||
|  | ||||
| export const useBusAndTrainData = () => { | ||||
|   return useContext(BusAndTrainDataContext); | ||||
| }; | ||||
|  | ||||
| export const BusAndTrainDataProvider = ({ children }) => { | ||||
|   const [busAndTrainData, setBusAndTrainData] = useState([]); | ||||
|   const [trainPairData, setTrainPairData] = useState([]); | ||||
|   const initializeTrainPairList = () => { | ||||
|     const trainPairList = {}; | ||||
|     trainPairData.forEach((d) => { | ||||
|       trainPairList[Object.keys(d)[0]] = d[Object.keys(d)[0]]; | ||||
|     }); | ||||
|     return trainPairList; | ||||
|   }; | ||||
|   return ( | ||||
|     <BusAndTrainDataContext.Provider | ||||
|       value={{ | ||||
|         busAndTrainData, | ||||
|         setBusAndTrainData, | ||||
|         trainPairData, | ||||
|         setTrainPairData, | ||||
|         initializeTrainPairList, | ||||
|       }} | ||||
|     > | ||||
|       {children} | ||||
|     </BusAndTrainDataContext.Provider> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										56
									
								
								stateBox/useCurrentTrain.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								stateBox/useCurrentTrain.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,56 @@ | ||||
| import React, { createContext, useContext, useState, useEffect } from "react"; | ||||
| import { HeaderConfig } from "../lib/HeaderConfig"; | ||||
|  | ||||
| import useInterval from "../lib/useInterval"; | ||||
| const initialState = { | ||||
|   currentTrain: [], | ||||
|   setCurrentTrain: () => {}, | ||||
|   currentTrainLoading: "loading", | ||||
|   setCurrentTrainLoading: () => {}, | ||||
|   getCurrentTrain: () => {}, | ||||
| }; | ||||
|  | ||||
| const CurrentTrainContext = createContext(initialState); | ||||
|  | ||||
| export const useCurrentTrain = () => { | ||||
|   return useContext(CurrentTrainContext); | ||||
| }; | ||||
|  | ||||
| export const CurrentTrainProvider = ({ children }) => { | ||||
|   const [currentTrain, setCurrentTrain] = useState([]); //現在在線中の全列車 { num: 列車番号, delay: 遅延時分(状態), Pos: 位置情報 } | ||||
|   const [currentTrainLoading, setCurrentTrainLoading] = useState("loading"); // success, error, loading | ||||
|   const getCurrentTrain = () => | ||||
|     fetch( | ||||
|       "https://script.google.com/macros/s/AKfycby9Y2-Bm75J_WkbZimi7iS8v5r9wMa9wtzpdwES9sOGF4i6HIYEJOM60W6gM1gXzt1o/exec", | ||||
|       HeaderConfig | ||||
|     ) | ||||
|       .then((response) => response.json()) | ||||
|       .then((d) => | ||||
|         d.map((x) => ({ num: x.TrainNum, delay: x.delay, Pos: x.Pos })) | ||||
|       ) | ||||
|       .then((d) => { | ||||
|         setCurrentTrain(d); | ||||
|         setCurrentTrainLoading("success"); | ||||
|       }) | ||||
|       .catch(() => { | ||||
|         console.log("えらー"); | ||||
|         setCurrentTrainLoading("error"); | ||||
|       }); | ||||
|  | ||||
|   useEffect(getCurrentTrain, []); //初回だけ現在の全在線列車取得 | ||||
|  | ||||
|   useInterval(getCurrentTrain, 15000); //15秒毎に全在線列車取得 | ||||
|   return ( | ||||
|     <CurrentTrainContext.Provider | ||||
|       value={{ | ||||
|         currentTrain, | ||||
|         setCurrentTrain, | ||||
|         currentTrainLoading, | ||||
|         setCurrentTrainLoading, | ||||
|         getCurrentTrain, | ||||
|       }} | ||||
|     > | ||||
|       {children} | ||||
|     </CurrentTrainContext.Provider> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										36
									
								
								stateBox/useFavoriteStation.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								stateBox/useFavoriteStation.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| import React, { | ||||
|   createContext, | ||||
|   useContext, | ||||
|   useState, | ||||
|   useLayoutEffect, | ||||
| } from "react"; | ||||
| import { AS } from "../storageControl"; | ||||
| const initialState = { | ||||
|   favoriteStation: [], | ||||
|   setFavoriteStation: () => {}, | ||||
| }; | ||||
|  | ||||
| const FavoriteStationContext = createContext(initialState); | ||||
|  | ||||
| export const useFavoriteStation = () => { | ||||
|   return useContext(FavoriteStationContext); | ||||
| }; | ||||
|  | ||||
| export const FavoriteStationProvider = ({ children }) => { | ||||
|   const [favoriteStation, setFavoriteStation] = useState([]); | ||||
|   useLayoutEffect(() => { | ||||
|     AS.getItem("favoriteStation") | ||||
|       .then((d) => { | ||||
|         const returnData = JSON.parse(d); | ||||
|         setFavoriteStation(returnData); | ||||
|       }) | ||||
|       .catch((d) => console.log(d)); | ||||
|   }, []); | ||||
|   return ( | ||||
|     <FavoriteStationContext.Provider | ||||
|       value={{ favoriteStation, setFavoriteStation }} | ||||
|     > | ||||
|       {children} | ||||
|     </FavoriteStationContext.Provider> | ||||
|   ); | ||||
| }; | ||||
							
								
								
									
										45
									
								
								stateBox/useTrainDelayData.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								stateBox/useTrainDelayData.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,45 @@ | ||||
| import React, { createContext, useContext, useEffect, useState } from "react"; | ||||
| const initialState = { | ||||
|   getTime: new Date(), | ||||
|   setGetTime: () => {}, | ||||
|   loadingDelayData: true, | ||||
|   setLoadingDelayData: () => {}, | ||||
|   delayData: undefined, | ||||
|   setDelayData: () => {}, | ||||
| }; | ||||
|  | ||||
| const TrainDelayDataContext = createContext(initialState); | ||||
|  | ||||
| export const useTrainDelayData = () => { | ||||
|   return useContext(TrainDelayDataContext); | ||||
| }; | ||||
|  | ||||
| export const TrainDelayDataProvider = ({ children }) => { | ||||
|   const [delayData, setDelayData] = useState(undefined); | ||||
|   const [getTime, setGetTime] = useState(new Date()); | ||||
|   const [loadingDelayData, setLoadingDelayData] = useState(true); | ||||
|   useEffect(() => { | ||||
|     fetch( | ||||
|       "https://script.google.com/macros/s/AKfycbyKxch7z7l8e07LXulRHqxjVoIiB13kcgvoToLE-rqlxLmLSKdlmqz0FI1F2EuA7Zfg/exec" | ||||
|     ) | ||||
|       .then((response) => response.text()) | ||||
|       .then((data) => setDelayData(data !== "" ? data.split("^") : null)) | ||||
|       .then(() => setGetTime(new Date())) | ||||
|       .finally(() => setLoadingDelayData(false)); | ||||
|   }, [loadingDelayData]); | ||||
|  | ||||
|   return ( | ||||
|     <TrainDelayDataContext.Provider | ||||
|       value={{ | ||||
|         getTime, | ||||
|         setGetTime, | ||||
|         loadingDelayData, | ||||
|         setLoadingDelayData, | ||||
|         delayData, | ||||
|         setDelayData, | ||||
|       }} | ||||
|     > | ||||
|       {children} | ||||
|     </TrainDelayDataContext.Provider> | ||||
|   ); | ||||
| }; | ||||
| @@ -36,7 +36,7 @@ export default function TrainBase({ route, navigation }) { | ||||
|         setSupportMultipleWindows={false} | ||||
|         onMessage={(event) => {}} | ||||
|       /> | ||||
|       {from == "LED" && ( | ||||
|       {(from == "LED" || from == "AllTrainDiagramView") && ( | ||||
|         <TouchableOpacity | ||||
|           style={{ | ||||
|             padding: 10, | ||||
| @@ -47,7 +47,9 @@ export default function TrainBase({ route, navigation }) { | ||||
|             borderRadius: 5, | ||||
|             alignItems: "center", | ||||
|           }} | ||||
|           onPress={() => navigate("menu")} | ||||
|           onPress={() => | ||||
|             navigate(from == "AllTrainDiagramView" ? "AllTrainIDList" : "menu") | ||||
|           } | ||||
|         > | ||||
|           <View style={{ flex: 1 }} /> | ||||
|           <MaterialCommunityIcons name="close" color="black" size={30} /> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user