SQLの窓

2020年11月09日


JScript / VBScript : 指定したフォルダ内のフォルダ毎の使用済みサイズを読める範囲でレポートする

▼ JScript のダウンロード

▼ VBScript のダウンロード

System Volume Information は、無駄に使われてる場合が多いそうです。( 今日 5G 削除しました ) ✅ 参考ページ

show-folders-size.js

// ************************************************
// カンマ編集
// ************************************************
String.prototype.number_format = 
function (prefix) {
	var num = this.valueOf();
	prefix = prefix || '';
	num += '';
	var splitStr = num.split('.');
	var splitLeft = splitStr[0];
	var splitRight = splitStr.length > 1 ? '.' + splitStr[1] : '';
	var regx = /(\d+)(\d{3})/;
	while (regx.test(splitLeft)) {
		splitLeft = splitLeft.replace(regx, '$1' + ',' + '$2');
	}
	return prefix + splitLeft + splitRight;
}

// ************************************************
// オブジェクト
// ************************************************
var Shell = new ActiveXObject("Shell.Application");
var WshShell = new ActiveXObject("WScript.Shell");
var Fso = new ActiveXObject( "Scripting.FileSystemObject" );

// ************************************************
// 管理者権限のコマンドプロンプトで再実行
// ************************************************
if ( WScript.Arguments.length == 0 ) {
	Shell.ShellExecute( "cmd.exe", "/c cscript.exe " + Dd(WScript.ScriptFullName) + " next" + " & pause", "", "runas", 1 );
	WScript.Quit();
}


var target = SelectDir( "対象フォルダを選択して下さい" )
if ( target == "" ) {
	WScript.Quit();
}

WScript.Echo( target )

// ************************************************
// フォルダオブジェクト取得
// ************************************************
var objFolder =  Fso.GetFolder(target)

var folderCollection = new Enumerator(objFolder.SubFolders);

var TargetSize = 0;
var obj;
var num;
var line;
for ( ;!folderCollection.atEnd(); folderCollection.moveNext()) {

	obj = folderCollection.item();
	
	try {
		num = Math.floor(obj.Size / 1024) / 1024;
		num = Math.floor( num * 1000 ) / 1000
		line = Lpad(("" + num).number_format()," ", 15) + " M : " + obj.Name
		WScript.Echo( line );

		// フォルダ全体の合計
		TargetSize = TargetSize + obj.Size
	}
	catch(e) {
		WScript.Echo( obj.Name + " : 処理できません");
	}

}

WScript.Echo( "" );

num = Math.floor(TargetSize / 1024) / 1024;
num = Math.floor( num * 1000 ) / 1000
line = Lpad(("" + num).number_format()," ", 15) + " M : " + "表示合計"
WScript.Echo( line );

// ************************************************
// ディレクトリ選択
// ************************************************
function SelectDir( strTitle ) {

	var obj

	obj = Shell.BrowseForFolder( 0, strTitle, 0x4B, 0 )
	if ( obj == null ) {
		return "";
	}
	if ( !obj.Self.IsFileSystem ) {
		ErrorMessage = "ファイルシステムではありません";
		return "";
	}

	return obj.Self.Path;

}

// ************************************************
// ダブルクォートで囲む
// ************************************************
function Dd( strValue ) {

	return "\"" + strValue + "\""

}

// ************************************************
// 指定数、指定文字列左側を埋める
// ※少数以下3桁の調整
// ************************************************
function Lpad( strValue, str, nLen ) {

	var i;
	var wk = "";

	for( i = 0; i < nLen; i++ ) {
		wk += str;
	}
	
	var test = strValue.split(".");
	if ( test.length == 2 ) {
		if ( test[1].length == 0 ) {
			strValue += "000"
		}
		if ( test[1].length == 1 ) {
			strValue += "00"
		}
		if ( test[1].length == 2 ) {
			strValue += "0"
		}
	}
	else {
		strValue += ".000"
	}

	return ( wk + strValue ).slice( nLen * -1 );

}


show-folders-size.vbs

' ************************************************
' 管理者権限で実行用
' ************************************************
Set Shell = CreateObject( "Shell.Application" )

' ************************************************
' 管理者権限で再実行
' ************************************************
if Wscript.Arguments.Count = 0 then
	Shell.ShellExecute "cmd.exe", "/c cscript.exe " & Dd(WScript.ScriptFullName) & " next" & " & pause", "", "runas", 1
	Wscript.Quit
end if

' ************************************************
' 除外フォルダ名を スペースで区切って並べる
' (簡易的な除外)
' ************************************************
Dim Exclude
Exclude = ".gem"
Exclude = Lcase(Exclude)

' ************************************************
' 処理用
' ************************************************
Set WshShell = CreateObject( "WScript.Shell" )
Set Fso = CreateObject( "Scripting.FileSystemObject" )

Dim target

' ************************************************
' 対象フォルダを選択
' ************************************************
target = SelectDir( "対象フォルダを選択して下さい" )
if target = "" then
	Wscript.Quit
end if

Wscript.Echo target
Wscript.Echo

' ************************************************
' フォルダオブジェクト取得
' ************************************************
Set objFolder =  Fso.GetFolder(target)

' ************************************************
' サブフォルダコレクション取得
' ************************************************
Set colSubFolder =  objFolder.SubFolders

' ************************************************
' 一覧
' ************************************************
Dim TargetSize : TargetSize = 0
For Each obj in colSubFolder

	Do While true

		if InStr(Exclude,Lcase(obj.Name)) > 0 then
			Exit Do
		end if

		on error resume next
		Wscript.Echo Lpad(FormatNumber((Fix(obj.Size / 1024) / 1024),3)," ", 15) & " M : " & obj.Name
		if Err.Number <> 0 then
			Wscript.Echo "                  ( " & obj.Name & " : 処理できません )"
		else
			TargetSize = TargetSize + obj.Size
		end if
		on error goto 0


		Exit Do
	Loop


Next

Wscript.Echo

Dim AllSize
Dim er : er = 0
on error resume next
AllSize = objFolder.Size
if Err.Number <> 0 then
	er = 1
	AllSize	= TargetSize
end if
on error goto 0


Wscript.Echo Lpad(FormatNumber((Fix(TargetSize / 1024) / 1024),3)," ", 15) & " M : " & "表示合計"

if er = 1 then
	Wscript.Echo "                  ( " & target & " のサイズは取得できませんでした )"
else
	Wscript.Echo Lpad(FormatNumber((Fix(AllSize / 1024) / 1024),3)," ", 15) & " M : " & target & " のサイズ"
end if

Dim fsize : fsize = 0
For Each file in objFolder.files
	fsize = fsize + file.size
Next
Wscript.Echo Lpad(FormatNumber((Fix((fsize) / 1024) / 1024),3)," ", 15) & " M : " & target & " 下のファイル"

Wscript.Echo

' ************************************************
' ディレクトリ選択
' ************************************************
Function SelectDir( strTitle )

	Dim obj

	Set obj = Shell.BrowseForFolder( 0, strTitle, &H4B, 0 )
	if obj is nothing then
		SelectDir = ""
		Exit Function
	end if
	if not obj.Self.IsFileSystem then
		ErrorMessage = "ファイルシステムではありません"
		SelectDir = ""
		Exit Function
	end if

	SelectDir = obj.Self.Path

End Function

' ************************************************
' ダブルクォートで囲む
' ************************************************
Function Dd( strValue )

	Dd = """" & strValue & """"

End function

' ************************************************
' 指定数、指定文字列左側を埋める
' ************************************************
Function Lpad( strValue, str, nLen )

	Lpad = Right( String(nLen,str) & strValue, nLen )

End Function






posted by lightbox at 2020-11-09 13:56 | WSH JScript | このブログの読者になる | 更新情報をチェックする

2020年11月02日


ロリポップ用ログインブックマークレット( ユーザ専用ページ・phpMyAdmin・WEBメーラ )

※ パスワード等の情報をブラウザに保存するので、自宅の PC で利用してくださいユーザ専用ページphpMyAdminWEBメーラ

ユーザ専用ページ

ドメインID は自分のアカウントです。ドメイン番号は、ロリポップで選んだ自分のドメインをコンボボックスで選択して Chrome の コンソールで以下のように入力してください
$("#domain-id").val()
※ 画像の例ですと、410 をドメイン番号と差し替えます
javascript:$("input[name='account']").val("ドメインID");$('#domain-id').val(ドメイン番号);$("input[name='passwd']").val("パスワード");jf_Login();

出来上がったコードを ブックマークバーに適当に作成したブックマークの URL に入力すると使用可能になります

phpMyAdmin

アカウント文字列は ユーザー名( DB ページでの呼び名 )です。サーバの選択は自分のサーバをコンボボックスで選択して Chrome の コンソールで以下のように入力してください
$("#select_server").val()
※ 画像の例ですと、192 をサーバー番号と差し替えます
javascript:$('#select_server').val(サーバー番号);$('#input_username').val("アカウント文字列");$('#input_password').val("パスワード");$('#input_go').click();

WEBメーラ

javascript:document.getElementsByName("mail_add")[0].value="メールアドレス";document.getElementsByName("mail_pass")[0].value="パスワード";jf_LoginMail();




posted by lightbox at 2020-11-02 10:46 | Pleiades | このブログの読者になる | 更新情報をチェックする

2020年10月27日


Java : WEB上のテキストファイルを取得する

キャラクタセットを指定してテキストとして取得

テキストファイルの入出力はこちらを参照して下さい。 InputStream の扱いはテキストファイルを基本に考えれば良いと思います。 WEB 上のデータも結局 InputStream で取得しています。
import java.net.*;
import java.io.*;

public class Main {

	public static void main(String[] args) {

		try {

			// 書き込みファイル名
			String filename = "index.html";
			// テキストで書き込み為の俊美
			BufferedWriter bw = new BufferedWriter(
					new OutputStreamWriter(
						new FileOutputStream(filename), "UTF8"
					) 
			);			

			// URL文字列
			String str = "https://lightbox.sakura.ne.jp/demo/template/basic/basic-html/req/basic-req-2div.html";
			// ターゲット
			URL url = new URL( str );
			// 接続オブジェクト
			HttpURLConnection http = (HttpURLConnection)url.openConnection();
			// GET メソッド 
			http.setRequestMethod("GET");
			// 接続 
			http.connect();
			 
			// UTF-8 でリーダーを作成
			InputStreamReader isr = new InputStreamReader(http.getInputStream(), "utf8");   
			// 行単位で読み込む為の準備   
			BufferedReader br = new BufferedReader(isr);   
			String line_buffer;   
			// BufferedReader は、readLine が null を返すと読み込み終了   
			while ( null != (line_buffer = br.readLine() ) ) {   
				// 書き込み
				bw.write( line_buffer + "\r\n" );
			}
 
			// 閉じる   
			br.close();		// BufferedReader
			isr.close();	// InputStreamReader
			http.disconnect();		// HttpURLConnection
			bw.close();		// BufferedWriter

		}
		catch( Exception e ) {
			System.out.println( e.getMessage() );
		}
	}
}

バイナリデータとしてそのままファイル化したものを使う

単純にダウンロードするだけならば、キャラクタセットを考慮する必要はありません
import java.net.*;
import java.io.*;
import java.util.*;

public class Main {

	public static void main(String[] args) {

		byte[] buffer = new byte[4096];
		int readByte = 0;

		try {
			// ターゲット
			URL url = new URL("https://lightbox.sakura.ne.jp/demo/template/basic/basic-html/req/basic-req-2div.html");
			// 接続オブジェクト
			HttpURLConnection http = (HttpURLConnection)url.openConnection();
			// GET メソッド 
			http.setRequestMethod("GET");
			// 接続 
			http.connect();
			
			DataOutputStream dataOutStream =
			new DataOutputStream(
				new BufferedOutputStream(
					new FileOutputStream("index.html")));			

			BufferedInputStream bis = new BufferedInputStream( http.getInputStream() );   
			// バイトでの読込み 
			DataInputStream dis = new DataInputStream(bis);   

			while ( -1 != (readByte = dis.read(buffer) ) ) {   
				// コマンドプロンプトに表示   
				dataOutStream.write(buffer, 0, readByte);
			}

			// 各々受け持ちクラスを閉じる   
			dis.close();
			bis.close();
			
			dataOutStream.close();

			http.disconnect();
		}
		catch( Exception e ) {
			
		}
	}
}



関連するドキュメント

サポートされるエンコーディング ( JDK 11 )
posted by lightbox at 2020-10-27 21:44 | java : 通信関連 | このブログの読者になる | 更新情報をチェックする

Java : テキストファイルの入出力



SHIFT_JIS で入力して UTF8N(UTF8) と EUC-JP で出力します

Java のテキストファイル入力は、3つのクラスを1セットで使用します FileInputStream( バイトストリーム ) ▼ InputStreamReader( キャラクタセット処理 ) ▼ BufferedReader ( 行単位で処理する ) ※ 有効なキャラクタセットはこちら 書き込みで UTF8 を指定すると、いわゆる UTF8N になりますので、 BOM( EF BB BF ) が必要な場合は、事前に自分で FileOutputStream を使用して書き込みます
package lightbox;

import java.io.*;

//*****************************************************
// サンプルテストクラス
//*****************************************************
public class Main {

	//*************************************************
	// ●● テキストファイル処理 ●●
	// 
	// 【1】FileInputStream(String name) で
	// ( InputStream => FileInputStream )
	// InputStream を作成し、
	//
	// 【2】InputStreamReader(InputStream in, String charsetName)
	// ( Reader => InputStreamReader )
	// で Reader を作成し
	//
	// 【3】BufferedReader(Reader in) に渡す
	//*************************************************
    public static void main(String[] args) {

		System.out.println("処理開始");

		String targetFile = "readme.txt";
		String resultFile_utf8n = "readme.utf8n.txt";
		String resultFile_utf8 = "readme.utf8.txt";
		String resultFile_ujis = "readme.ujis.txt";

		try {

			// 生のバイトのストリーム
			// キャラクタセットを指定して読み込む為に、使用する
			// ↓【readme.txt】
			FileInputStream fis = new FileInputStream(targetFile);

			// SHIFT_JIS として読み込む為の準備
			// ↓【 FileInputStream】
			InputStreamReader isr = new InputStreamReader(fis, "ms932");

			// 行単位で読み込む為の準備
			BufferedReader br = new BufferedReader(isr);

			String line_buffer;

			// BufferedReader は、readLine が null を返すと読み込み終了
			while ( null != (line_buffer = br.readLine() ) ) {
				// コマンドプロンプトに表示
				System.out.println(line_buffer);
			}

			// 各々受け持ちクラスを閉じる
			br.close();
			isr.close();
			fis.close();


			// *******************************************************
			// ※ "UTF8" で、UTF8N になります
			// UTF8N に変換の為、再度同じファイルを入力
			// 今度は入力は変数を使わずに書く
			// *******************************************************
			br = new BufferedReader(
					new InputStreamReader(
						new FileInputStream(targetFile), "ms932"
					) 
			);
			// *******************************************************
			// UTF8N 用の書き込み用のインスタンスを同様に作成
			// *******************************************************
			BufferedWriter bw = new BufferedWriter(
					new OutputStreamWriter(
						new FileOutputStream(resultFile_utf8n), "utf8"
					) 
			);

			while ( null != (line_buffer = br.readLine() ) ) {
				// CrLf にするには、その通りに書き込む
				bw.write( line_buffer + "\r\n" );
			}
			bw.close();
			br.close();


			// *******************************************************
			// BOM( EF BB BF ) 付きにするには自分で先に書き出す
			// *******************************************************
			br = new BufferedReader(
					new InputStreamReader(
						new FileInputStream(targetFile), "ms932"
					) 
			);
			FileOutputStream fos = new FileOutputStream(resultFile_utf8);
			fos.write( 0xef );
			fos.write( 0xbb );
			fos.write( 0xbf );
			bw = new BufferedWriter(
					new OutputStreamWriter(
						fos, "utf8"
					) 
			);

			while ( null != (line_buffer = br.readLine() ) ) {
				// CrLf にするには、その通りに書き込む
				bw.write( line_buffer + "\r\n" );
			}
			bw.close();
			fos.close();
			br.close();


			// *******************************************************
			// EUC-JP に変換の為、再度同じファイルを入力
			// *******************************************************
			br = new BufferedReader(
					new InputStreamReader(
						new FileInputStream(targetFile), "ms932"
					) 
			);
			// *******************************************************
			// EUC-JP にするには "EUC_JP" でも "EUC-JP" OK
			// *******************************************************
			bw = new BufferedWriter(
					new OutputStreamWriter(
						new FileOutputStream(resultFile_ujis), "euc-jp"
					) 
			);

			while ( null != (line_buffer = br.readLine() ) ) {
				bw.write( line_buffer + "\r\n" );
			}
			bw.close();
			br.close();

		}
		catch( Exception e  ) {
			System.out.println(e.getMessage());
		}

		System.out.println("処理終了");


	}

}





posted by lightbox at 2020-10-27 18:59 | java : テキストファイル | このブログの読者になる | 更新情報をチェックする

2020年10月18日


Java11 + Visual Studio Code + JavaMail( with JavaBeans Activation Framework )

Java Extension Pack をインストール後 Java11 へパスを通しています

詳細に JSK の参照を設定するには、Java: Configure Java Runtime で設定画面を表示させます。 JavaMail JavaBeans Activation Framework Java11 で JavaMail を使用するには、JavaBeans Activation Framework を参照する必要があります。しかし Maven を使用すれば、使用する JDK を選択して JavaBeans Activation Framework なしで実行可能です。 Maven を使用する場合は、ダウンロードしてパスを通したうえに、JAVA_HOME に JDK のバスを設定する必要があります。

🔻 Java: Configure Java Runtime

Getting Started with Java in VS Code 参考1) Visual Studio Code で Java + Maven 環境を設定してデバッグ実行する 参考2) VSCodeでMavenプロジェクトをデバッグする
import java.util.*;
import java.io.*;
import javax.mail.*;
import javax.mail.internet.*;

public class Main {

	// *******************************************
	// エントリポイント
	// *******************************************
	public static void main(String[] args) {
		new Main();
	}

	// *******************************************
	// コンストラクタ
	// *******************************************
	public Main() {
		my_acton();
	}

	// *******************************************
	// 初期処理
	// *******************************************
	private void my_acton() {

		// 通常入力用
		Scanner scan = new Scanner(System.in);
		// パスワード入力用
		Console console = System.console();

		MyTool out = new MyTool( ">>>" );
		out.println("処理開始");

		// アカウント入力
		out.println("アカウントの入力");
		String user = scan.nextLine();
		if ( user.equals("") ) {
			out.println( "処理を途中で終了します" );
			return;
		}
		out.println( user );

		// パスワード入力
		char[] pass = console.readPassword( "パスワードを入力してください : " );
		String password = new String( pass );

		// 宛先入力
		out.println("宛先の入力");
		String to = scan.nextLine();
		out.println( to );


		// *******************************************
		// プロパティオブジェクトを作成
		// プロパティオブジェクトは、
		// extends Hashtable(連想配列)
		// *******************************************
		Properties props = new Properties();
	
		// *******************************************
		// ( Gmail では、安全性の低いアプリのアクセスを有効にする必要があります )
		// ▼ G Suite では、安全性の低いアプリのアクセスは使用できません
		// https://gsuiteupdates-ja.googleblog.com/2019/12/g-suite_24.html
		// *******************************************
		props.put("mail.smtp.host","smtp.lolipop.jp");	// ロリポップ
//		props.put("mail.smtp.host","smtp.mail.yahoo.co.jp");	// Yahoo!
//		props.put("mail.smtp.host","smtp.gmail.com");	// Gmail
		
		props.put("mail.smtp.auth", "true" );	// SMTP 認証を行う

		// ▼ 465( SSL )
		props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
		props.put("mail.smtp.socketFactory.fallback", "false");
		props.put("mail.smtp.socketFactory.port", "465");

		// *******************************************
		// メール用のセッションを作成
		// *******************************************
		SimpleAuthenticator sa =
			new SimpleAuthenticator( user , password );
		Session MailSession = 
			Session.getInstance( props, sa );
	
		try {
	
			// *******************************************
			// メール用のメッセージオブジェクトを作成
			// *******************************************
			MimeMessage msg = new MimeMessage(MailSession);
	
			// *******************************************
			// 宛先
			// *******************************************
			msg.setRecipients(
				Message.RecipientType.TO, String.format("%s <%s>",
				MimeUtility.encodeText(
					"あなた",
					"iso-2022-jp",
					"B"
				), to )
			);
	
			// *******************************************
			// 送信者
			// *******************************************
			msg.setFrom(
				new InternetAddress( String.format("%s <%s>",
				MimeUtility.encodeText(
					"わたし",
					"iso-2022-jp",
					"B"
				), user )  )
			);
	
			// *******************************************
			// 件名
			// *******************************************
			msg.setSubject(
				MimeUtility.encodeText(
					"日本語件名",
					"iso-2022-jp",
					"B"
				)
			);
	
			// *******************************************
			// 本文
			// *******************************************
			msg.setContent(
				"本文\r\n本文",
				"text/plain; charset=\"iso-2022-jp\""
			);
	
			// *******************************************
			// 送信
			// *******************************************
			Transport.send( msg );
	
		}
		catch (Exception e) {
			out.println( e.getMessage() );
			out.println("送信エラー");
		}

		out.println("処理終了");

	}

	// *******************************************
	// 内部用クラス
	// *******************************************
	private class MyTool {

		private String mark = null;

		MyTool(String pm) {
			mark = pm;
		}

		public void println(String str) {
			System.out.println( this.mark + str );
		}

	}

	// ***********************************************
	// 認証用のプライベートクラス
	// ***********************************************
	private class SimpleAuthenticator extends Authenticator {
	
		private String user_string = null;
		private String pass_string = null;
	
		public SimpleAuthenticator( String user_s, String pass_s ) {
			super();
			user_string = user_s;
			pass_string = pass_s;
		}
	
		protected PasswordAuthentication getPasswordAuthentication(){
			return new PasswordAuthentication( this.user_string, this.pass_string );
		}
	}

}


JavaMail API documentation

安全性の低いアプリによる G Suite アカウントへの接続が無効に



posted by lightbox at 2020-10-18 16:57 | java : 通信関連 | このブログの読者になる | 更新情報をチェックする

2020年10月15日


VBScript を『管理者として実行する』には、Shell の runas ( 右クリックメニューの実行と同等 ) で実現します / Jscript も追加

UAC によるセキュリティの影響で VBScript を使う場合、管理者権限で実行しないとレジストリの一部には書き込めるのに重要なフォルダには書き込めないというような OS が決めたルールがあります。

それに対する対処の最も簡単な方法は、以下の内容ををスクリプトの先頭に記述する事です

🔻 VBScript

Set obj = Wscript.CreateObject("Shell.Application")
if Wscript.Arguments.Count = 0 then
	obj.ShellExecute "wscript.exe", WScript.ScriptFullName & " runas", "", "runas", 1
	Wscript.Quit
end if

Wscript.Echo "ここは管理者権限で実行されます"


🔻 Jscript

※ Jscript は WScript 等、大文字小文字の区別があるので注意です。 ※ ダウンロードは、拡張子 .htm で SHIFT_JIS ですので、利用時は .js に変更してお使い下さい。
var obj = new ActiveXObject("Shell.Application");
if ( WScript.Arguments.length == 0 ) {
	obj.ShellExecute( "wscript.exe", WScript.ScriptFullName + " runas", "", "runas", 1 );
	WScript.Quit();
}

WScript.Echo( "ここは管理者権限で実行されます" );

Shell.ShellExecute method

これは、VBScript から利用可能な Shell の機能を使って、右クリックメニューにある『管理者として実行』を実行する方法です。ここでは日本語では無く runas と言う文字列を使って管理者として実行させています。

但し、引数がなかった場合の処理としては処理終了します。ですからこのスクリプトでは、引数をダミーで一つセットして( この場合一つめの runas がそうです )自分自身を再度呼び出しています。

つまり、Windows からすれば二度目の実行が管理者としての実行になります。

この場合は、スクリプトに引数を渡す事ができません。もし渡したいしたい場合は、違ったトリックを使う必要があるのに注意して下さい。(その場合は、外部ファイルから入力するのがもっとも簡単で確実だと思います)





posted by lightbox at 2020-10-15 08:10 | VBS + Shell | このブログの読者になる | 更新情報をチェックする
container 終わり



フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり