/***********************************************************
  IE用ブックマークレットでFirefox風検索
************************************************************
[動作]
 - Firefox風にしてみた
 - ローマ字のまま検索できる
 - エスケープ入ってる場合は手動正規表現検索
 - スペース区切りでor検索
 - エンターで次、shift+エンターで前
 - 上下キー、PageUP/Down、HOME/ENDはスクロール。

[インストール方法]
 起動するにはこんな感じのBookmarkletを作成して、リンクバーに追加する。
  javascript:(function(){var s=document.createElement("script");s.charset="Shift_JIS";s.src="file:///C:/PATH_TO_SCRIPT/isearch.js";document.body.appendChild(s)})();
 このファイルを単体ダブルクリックで起動すると、Bookmarkletをクリップボードにコピーします。
 また、リンクバーに追加するのもできます。
 IEコンポーネントブラウザ使ってる場合は、
 リンクを手動で登録するなりしてください。

 Sleipnir用スクリプトを使う場合は、起動スクリプトをツールに登録すると
 マウスジェスチャやショートカットキーを割り当てることができます。

[ライセンス]
 Artistic License

 オリジナル: http://d.hatena.ne.jp/leibniz/20050701/1120232028
 改造      : http://la.ma.la/blog/

***********************************************************/

// インストーラー
// windowオブジェクトがない場合WSHとして動作
if(typeof window == "undefined"){
	var objShl = WScript.CreateObject("WScript.Shell");
	
	//クリップボードに貼り付けよう
	var clip = function(){
		this.ie = new ActiveXObject( 'InternetExplorer.Application' );
		this.ie.Navigate( 'about:blank' );
		while (this.ie.Busy) {
			WScript.Sleep(10);
		}
		this.clipboard = this.ie.Document.parentWindow.clipboardData;
		this.setText = function (s){
			this.clipboard.setData('text', s);
			return true;
		};
		this.release = function(){
			this.ie.Quit();
			return true;
		};
		return this;
	}

	var strFav = objShl.SpecialFolders("Favorites") + "\\リンク\\" + "ページ内検索.url";
	var scriptpath = "file:///"+WScript.ScriptFullName.replace(/\\/g,"/");
	var scripturl = 'javascript:(function(){var s=document.createElement("script");s.charset="Shift_JIS";s.src="'
		+scriptpath+'";document.body.appendChild(s)})();';
	var makelink = function(){
		var oUrlLink = objShl.CreateShortcut(strFav);
		oUrlLink.TargetPath = scripturl;
		oUrlLink.Save();
	};
	var c = new clip;
	c.setText(scripturl);
	c.release();
	WScript.echo("起動用リンクをクリップボードにコピーしました");
	var btn = objShl.Popup(
		strFav+"\nにBookmarkletを作成しますか?", 0,"リンクバーにBookmarkletを作成しますか?" , 4 + 32
	);
	if(btn == 6){
		makelink();
		WScript.echo("リンクバーにBookmarkletを作成しました");
	}else{
	}
	WScript.Quit();
}

// ここから本体
var isearch = new Isearch();
isearch.self = isearch;
isearch.init();

var KC = {
	 up    : 38
	,down  : 40
	,left  : 37
	,right : 39
	,shift : 16
	,enter : 13
	,pgup  : 33
	,pgdown: 34
	,home  : 36
	,end   : 35

};
Array.prototype.valuesTokey = function(){
	var tmp = {};
	for(var i=0;i<this.length;i++){
		tmp[this[i]] = i
	};
	return tmp;
}
function Isearch(){
	this.bmk = null;
	this.offset = 1;
	this.word = "";
	this.findstring = "";
	this.searchResult = null;
	this.keydown = function(ev){
		var kc = ev.keyCode;
		//window.status = kc;
		var self = isearch;
		var shift = ev.shiftKey?-1:1;
		var input = self.is_input;
		//スクロール
		switch(kc){
			case KC.up:window.scrollBy(0,-20);break;
			case KC.down:window.scrollBy(0,20);break;
			case KC.pgup:
				var doc = getDoc(this.document);
				with(this.is_menu.style){
					left = 0;
					top  = doc.scrollTop + doc.clientHeight - this.is_menu.offsetHeight - 120;
				}
				window.scrollBy(0,-120);break;
			case KC.pgdown:window.scrollBy(0,120);break;
			case KC.home:
				with(this.is_menu.style){
					left = 0;
					top  = 0;
				}
				window.scrollTo(0,0);break;
			case KC.end:window.scrollTo(0,500000);break;
			case KC.enter:
				if(self.word != input.value){
					self.word = input.value;
					self.bmk = null;
				}
				isearch.self.removeHighlight();
				input.style.background="#ffffff";
				if(!self.word) return;
				if(!self.do_search(ev,shift)){input.style.background="#ff6563"}
		}
	};
	this.search = function(ev,back){
		var kc = ev.keyCode;
		var self = isearch;
		//無視する：enter,shift,←,→
		with(KC){
			var ignore = [shift,left,right,up,down,enter,pgup,pgdown,home,end];
			var ignoreList = ignore.valuesTokey();
		}
		if(kc in ignoreList){return}
		var input = self.is_input;

		// 検索語が変わったらブックマークをクリア
		if(self.word != input.value){
			self.word = input.value;
			self.bmk = null;
			self.offset = 1;
			// 検索結果をキャッシュ
			with(self){
				//スペース区切りで複数検索
				var fuzzy;
				var src = word.replace(/[ 　]/g,"|");
				if(word.search(/[\[\]\(\)\\]/) != -1){
					fuzzy = word;
					is_mode.innerHTML = "正規表現検索";
				}else{
					fuzzy = roma2.fuzzy(src);
					is_mode.innerHTML = "曖昧検索";
				}
				window.status = fuzzy;
				//var 
				if(fuzzy.charAt(fuzzy.length-1) == "|"){
					fuzzy = fuzzy.slice(0,-1);
				}
				try{
					var reg = new RegExp(fuzzy,"ig");
					searchResult = srcText.match(reg);
				}catch(e){
					var reg = "";
					searchResult = null;
				}
			}
		}

		isearch.self.removeHighlight();
		input.style.background="#ffffff";

		if(!self.word) return;
		if(!self.do_search(ev)) input.style.background="#ff6563";
	};
	this.do_search = function(ev,shift){
		var self = isearch;
		var res = self.searchResult;
		var is_status = self.is_status;
		if(res){
			is_status.innerHTML = res.length+"件見つかりました";
		}else{
			is_status.innerHTML = "見つかりません";
			return false;
		}
		// 前方検索
		if(shift == -1){
			self.offset--;
		}
		// 最後から最初に移動
		if(self.offset == res.length){
			is_status.innerHTML += "　§ページの最後まで検索しました。ページの最初から検索を続けます。";
			self.offset = 0;
			self.bmk = null;
		}
		// 最初から最後に移動
		if(self.offset == 0 && shift == -1){
			self.offset = res.length;
			self.bmk = null;
		}
		// 次を検索
		if(shift == 1){self.offset++}
		// 見つかったのが一件のみ
		if(res.length == 1){self.offset = 1}
		
		// 正規表現での検索結果を次に探す文字列に指定
		self.findstring = res[self.offset-1];
		window.status = self.offset + ":　"+ self.findstring;

		//キャレット移動
		var more = self.move(ev,shift);
		return true;
	};
	this.move = function(ev,shift){
		var self = isearch;
		var rng = self.document.body.createTextRange();
		var kc = ev.keyCode;

		//次を検索、前を検索
		if(self.bmk){
			rng.moveToBookmark(self.bmk);
			//上方検索の場合：↑キー
			if(shift == -1){
				//rng.moveStart("textedit",-1);
				rng.moveEnd("character" , -1);
				while (0 != rng.moveStart("textedit", -10000)){}
				//rng.moveEnd("character",-self.findstring.length);
				rng.moveEnd("character" , -1);
			}else if(kc==KC.enter){
				rng.moveStart("character",1);
				while (0 != rng.moveEnd("textedit", 10000)){}
				//rng.moveEnd("textedit", 1);
				//rng.moveStart("character",1);//self.findstring.length-1
				//rng.moveEnd("textedit",0);
				rng.moveStart("character" , 1);
			}
		}
		
//				rng.moveStart("character" , 1);
//				rng.moveEnd("character" , -1);

		if(rng.findText(self.findstring,(shift==-1)?-1:1)){
			self.bmk = rng.getBookmark();
			rng.pasteHTML([
				'<span id="is_highlight" style="background:#39db7b;color:white">'
				, rng.text
				, '</span>'
			].join(""));
			
			// 下方向スクロールの場合は
			// 検索バーが邪魔にならないようにさらにスクロール
			var doc = getDoc(this.document);
			var top_old  = doc.scrollTop;
			rng.scrollIntoView();
			var top_new  = doc.scrollTop;
			if(top_old < top_new){
				doc.scrollTop = doc.scrollTop + (doc.clientHeight/3);
			}
			return true;
		}else{
			self.bmk = null;
			return false;
		}
	};

	//ハイライト表示を戻す
	this.removeHighlight = function(){
		var spans = this.document.getElementsByTagName("span");
		for(var i=0; i<spans.length; i++){
			if(spans[i].id=="is_highlight"){
				spans[i].insertAdjacentText(
					'AfterEnd', spans[i].childNodes[0].nodeValue
				);
				spans[i].parentNode.removeChild(spans[i]);
			}
		}
	};

	//スクロールに合わせてメニューの位置変更
	this.movemenu = function(){
		var doc = getDoc(this.document);
		if(!this.is_menu){return}
		with(this.is_menu.style){
			//left = doc.clientWidth-180;
			left = 0;
			top  = doc.scrollTop + doc.clientHeight - this.is_menu.offsetHeight;
			//top  = doc.scrollTop;
			width = doc.clientWidth - 8;
		}
		doc.style.paddingBottom = "40px";
		setTimeout("isearch.movemenu()",100);
	};

	//DOCTYPEに合わせて挙動変更
	function getDoc(doc){
		return (doc.compatMode=='CSS1Compat') ? doc.documentElement : doc.body;
	}
	
	//メニュー作成
	this.createMenu = function(){
		//フレームの階層にあわせてparentを繋げる
		this.srcText = this.document.body.innerText;
		var tmp = this.document.createElement("div");
		tmp.id = "is_menu";
		with(tmp.style){
			background = "#d6d3ce";
			position   = "absolute";
			margin     = "0px";
			borderTop  = "#848284 1px solid";
			padding    = "4px";
			fontSize   = "11px";
			color      = "black";
			filter     = "alpha(opacity=85)"
		}
		tmp.innerHTML = [
			'<button id="is_close">×</button>'
			,'　検索: <input id="is_input" style="width:150px">'
			,'　<span id="is_status"></span>'
			,'　<span id="is_mode"></span>'
		].join("")
		this.document.body.appendChild(tmp);
		this.is_menu = tmp;
		this.movemenu();
		this.is_input = this.document.getElementById("is_input");
		with(this.is_input.style){
			padding = "2px";
			margin = "0px";
			background = "#FFF";
			border = "inset 2px";
			imeMode = "inactive";
			fontSize = "11px"
		}
		this.is_status = this.document.getElementById("is_status");
		this.is_mode = this.document.getElementById("is_mode");
		this.is_close = this.document.getElementById("is_close");
		with(this.is_close.style){
			border = "1px solid #FFF";
			width = "16px";
			height = "16px";
			padding = "1px";
			lineHeight = "100%";
			fontSize = "10px";
			fontWeight = "bold";
			color = "white";
			background = "#d64d39";
		}
		this.is_input.attachEvent("onkeyup",isearch.search);
		this.is_input.attachEvent("onkeydown",isearch.keydown);
		this.is_close.attachEvent("onclick",function(){
			isearch.document.body.removeChild(isearch.document.getElementById("is_menu"));
		});
		this.is_close.attachEvent("onmouseover",function(){
			isearch.document.getElementById("is_close").style.background = "#FF6655"
		});
		this.is_close.attachEvent("onmouseout",function(){
			isearch.document.getElementById("is_close").style.background = "#d64d39"
		});
		this.is_input.focus();
	};
	
	this.document = document;
	this.maxArea = 0;

	//フレーム解析
	this.getMaxFrame = function(doc){
		if(doc.frames.length==0){
			var area = getDoc(doc).clientWidth * getDoc(doc).clientHeight;
			if(this.maxArea < area){
				this.maxArea = area;
				this.document = doc;
			}
		}else{
			for(var i=0; i<doc.frames.length; i++){
				try{
					this.getMaxFrame(doc.frames[i].document);
				}catch(err){continue;}
			}
		}
	}
	this.init = function(){
		this.getMaxFrame(document,0);
		if(isearch.document.getElementById("is_menu")){
			isearch.document.body.removeChild(isearch.document.getElementById("is_menu"));
		}else{
			this.createMenu();
		}
	}
}



/*
 * ローマ字曖昧化
 */
var roma2 = {};
roma2.fuzzy = function(text){
	return roma2reg(text)
}
//正規表現パターン
function roma2reg(text){
	var newstring = [];
	var temp = "";
	var skip = 0;
	var c = 0;
	var i;
	var kana = "";
	var h = "hiragana";
	var k = "katakana";
	var lb = "[";
	var rb = "]";
	var sep = "|";
	var que = "(?:";
	var rc = ")";
	var latin = /[a-zA-Z.,-]/;
	for(i=0;i<text.length;i++){
		if (skip > 0) {
			skip--;
		} else {
			temp = text.charAt(i);
			if (latin.test(temp)) {
				var loop = 4;
				var f=0;
				while(loop){
					temp = text.slice(i,i+loop);
					if (temp in roma[h]) {
						hira = roma[h][temp];
						kata = roma[k][temp];
						if(loop == 2){
							//「っ」の場合、一文字戻す
							if(hira.charAt(0) == roma[h].tt){i--}
							skip = 1;
						}else{
							skip = loop-1;
						}
						f=1;
						if(hira == kata){
							newstring.push(que+temp+sep+hira+rc);break;
						}else{
							//(ve|ヴ[ぇェ])
							if(hira.length == 2){
								newstring.push(que+temp+sep);
								h1=hira.charAt(0);k1=kata.charAt(0);
								h2=hira.charAt(1);k2=kata.charAt(1);
								newstring.push(lb+h1+k1+rb)
								newstring.push(lb+h2+k2+rb+rc);break;
							}else{
								//っ対応
								if(hira.charAt(0) == roma[h].tt){
								newstring.push(
									que+temp.charAt(0)+sep+lb+hira+kata+rb+rc
								);break;
								}else{
								newstring.push(
									que+temp+sep+lb+hira+kata+rb+rc
								);break;
								}
							}
						}
					}
					loop--;
				}
				if(!f){newstring.push(temp)}
			} else {
				newstring.push(temp);
			}
		}
	}
	return newstring.join("");
}
var roma = {};
roma.hiragana = {"a":"あ","i":"い","yi":"い","u":"う","wu":"う","whu":"う","e":"え","o":"お","la":"ぁ","xa":"ぁ","li":"ぃ","xi":"ぃ","lyi":"ぃ","xyi":"ぃ","lu":"ぅ","xu":"ぅ","le":"ぇ","xe":"ぇ","lye":"ぇ","xye":"ぇ","lo":"ぉ","xo":"ぉ","wha":"うぁ","whi":"うぃ","wi":"うぃ","whe":"うぇ","we":"うぇ","who":"うぉ","ka":"か","ca":"か","ki":"き","ku":"く","cu":"く","qu":"く","ke":"け","ko":"こ","co":"こ","lka":"ヵ","xka":"ヵ","lke":"ヶ","xke":"ヶ","ga":"が","gi":"ぎ","gu":"ぐ","ge":"げ","go":"ご","kya":"きゃ","kyi":"きぃ","kyu":"きゅ","kye":"きぇ","kyo":"きょ","qya":"くゃ","qyu":"くゅ","qwa":"くぁ","qa":"くぁ","kwa":"くぁ","qwi":"くぃ","qi":"くぃ","qyi":"くぃ","qwu":"くぅ","qwe":"くぇ","qe":"くぇ","qye":"くぇ","qwo":"くぉ","qo":"くぉ","gya":"ぎゃ","gyi":"ぎぃ","gyu":"ぎゅ","gye":"ぎぇ","gyo":"ぎょ","gwa":"ぐぁ","gwi":"ぐぃ","gwu":"ぐぅ","gwe":"ぐぇ","gwo":"ぐぉ","sa":"さ","si":"し","ci":"し","shi":"し","su":"す","se":"せ","ce":"せ","so":"そ","za":"ざ","zi":"じ","ji":"じ","zu":"ず","ze":"ぜ","zo":"ぞ","sya":"しゃ","sha":"しゃ","syi":"しぃ","syu":"しゅ","shu":"しゅ","sye":"しぇ","she":"しぇ","syo":"しょ","sho":"しょ","swa":"すぁ","swi":"すぃ","swu":"すぅ","swe":"すぇ","swo":"すぉ","zya":"じゃ","ja":"じゃ","jya":"じゃ","zyi":"じぃ","jyi":"じぃ","zyu":"じゅ","ju":"じゅ","jyu":"じゅ","zye":"じぇ","je":"じぇ","jye":"じぇ","zyo":"じょ","jo":"じょ","jyo":"じょ","ta":"た","ti":"ち","chi":"ち","tu":"つ","tsu":"つ","te":"て","to":"と","ltu":"っ","xtu":"っ","ltsu":"っ","da":"だ","di":"ぢ","du":"づ","de":"で","do":"ど","tya":"ちゃ","cha":"ちゃ","cya":"ちゃ","tyi":"ちぃ","cyi":"ちぃ","tyu":"ちゅ","chu":"ちゅ","cyu":"ちゅ","tye":"ちぇ","che":"ちぇ","cye":"ちぇ","tyo":"ちょ","cho":"ちょ","cyo":"ちょ","tsa":"つぁ","tsi":"つぃ","tse":"つぇ","tso":"つぉ","tha":"てゃ","thi":"てぃ","thu":"てゅ","the":"てぇ","tho":"てょ","twa":"とぁ","twi":"とぃ","twu":"とぅ","twe":"とぇ","two":"とぉ","dya":"ぢゃ","dyi":"ぢぃ","dyu":"ぢゅ","dye":"ぢぇ","dyo":"ぢょ","dha":"でゃ","dhi":"でぃ","dhu":"でゅ","dhe":"でぇ","dho":"でょ","dwa":"どぁ","dwi":"どぃ","dwu":"どぅ","dwe":"どぇ","dwo":"どぉ","na":"な","ni":"に","nu":"ぬ","ne":"ね","no":"の","nya":"にゃ","nyi":"にぃ","nyu":"にゅ","nye":"にぇ","nyo":"にょ","ha":"は","hi":"ひ","hu":"ふ","fu":"ふ","he":"へ","ho":"ほ","ba":"ば","bi":"び","bu":"ぶ","be":"べ","bo":"ぼ","pa":"ぱ","pi":"ぴ","pu":"ぷ","pe":"ぺ","po":"ぽ","hya":"ひゃ","hyi":"ひぃ","hyu":"ひゅ","hye":"ひぇ","hyo":"ひょ","fya":"ふゃ","fyu":"ふゅ","fyo":"ふょ","fwa":"ふぁ","fa":"ふぁ","fwi":"ふぃ","fi":"ふぃ","fyi":"ふぃ","fwu":"ふぅ","fwe":"ふぇ","fe":"ふぇ","fye":"ふぇ","fwo":"ふぉ","fo":"ふぉ","bya":"びゃ","byi":"びぃ","byu":"びゅ","bye":"びぇ","byo":"びょ","va":"ヴぁ","vi":"ヴぃ","vu":"ヴ","ve":"ヴぇ","vo":"ヴぉ","vya":"ヴゃ","vyi":"ヴぃ","vyu":"ヴゅ","vye":"ヴぇ","vyo":"ヴょ","pya":"ぴゃ","pyi":"ぴぃ","pyu":"ぴゅ","pye":"ぴぇ","pyo":"ぴょ","ma":"ま","mi":"み","mu":"む","me":"め","mo":"も","mya":"みゃ","myi":"みぃ","myu":"みゅ","mye":"みぇ","myo":"みょ","ya":"や","yu":"ゆ","yo":"よ","lya":"ゃ","xya":"ゃ","lyu":"ゅ","xyu":"ゅ","lyo":"ょ","xyo":"ょ","ra":"ら","ri":"り","ru":"る","re":"れ","ro":"ろ","rya":"りゃ","ryi":"りぃ","ryu":"りゅ","rye":"りぇ","ryo":"りょ","wa":"わ","wo":"を","n":"ん","nn":"ん","n'":"ん","xn":"ん","lwa":"ゎ","xwa":"ゎ",".":"。",",":"、","bb":"っ","cc":"っ","dd":"っ","ff":"っ","gg":"っ","hh":"っ","jj":"っ","kk":"っ","ll":"っ","mm":"っ","pp":"っ","qq":"っ","rr":"っ","ss":"っ","tt":"っ","vv":"っ","ww":"っ","xx":"っ","yy":"っ","zz":"っ","-":"ー"};
roma.katakana = {"a":"ア","i":"イ","yi":"イ","u":"ウ","wu":"ウ","whu":"ウ","e":"エ","o":"オ","la":"ァ","xa":"ァ","li":"ィ","xi":"ィ","lyi":"ィ","xyi":"ィ","lu":"ゥ","xu":"ゥ","le":"ェ","xe":"ェ","lye":"ェ","xye":"ェ","lo":"ォ","xo":"ォ","wha":"ウァ","whi":"ウィ","wi":"ウィ","whe":"ウェ","we":"ウェ","who":"ウォ","ka":"カ","ca":"カ","ki":"キ","ku":"ク","cu":"ク","qu":"ク","ke":"ケ","ko":"コ","co":"コ","lka":"ヵ","xka":"ヵ","lke":"ヶ","xke":"ヶ","ga":"ガ","gi":"ギ","gu":"グ","ge":"ゲ","go":"ゴ","kya":"キャ","kyi":"キィ","kyu":"キュ","kye":"キェ","kyo":"キョ","qya":"クャ","qyu":"クュ","qwa":"クァ","qa":"クァ","kwa":"クァ","qwi":"クィ","qi":"クィ","qyi":"クィ","qwu":"クゥ","qwe":"クェ","qe":"クェ","qye":"クェ","qwo":"クォ","qo":"クォ","gya":"ギャ","gyi":"ギィ","gyu":"ギュ","gye":"ギェ","gyo":"ギョ","gwa":"グァ","gwi":"グィ","gwu":"グゥ","gwe":"グェ","gwo":"グォ","sa":"サ","si":"シ","ci":"シ","shi":"シ","su":"ス","se":"セ","ce":"セ","so":"ソ","za":"ザ","zi":"ジ","ji":"ジ","zu":"ズ","ze":"ゼ","zo":"ゾ","sya":"シャ","sha":"シャ","syi":"シィ","syu":"シュ","shu":"シュ","sye":"シェ","she":"シェ","syo":"ショ","sho":"ショ","swa":"スァ","swi":"スィ","swu":"スゥ","swe":"スェ","swo":"スォ","zya":"ジャ","ja":"ジャ","jya":"ジャ","zyi":"ジィ","jyi":"ジィ","zyu":"ジュ","ju":"ジュ","jyu":"ジュ","zye":"ジェ","je":"ジェ","jye":"ジェ","zyo":"ジョ","jo":"ジョ","jyo":"ジョ","ta":"タ","ti":"チ","chi":"チ","tu":"ツ","tsu":"ツ","te":"テ","to":"ト","ltu":"ッ","xtu":"ッ","ltsu":"ッ","da":"ダ","di":"ヂ","du":"ヅ","de":"デ","do":"ド","tya":"チャ","cha":"チャ","cya":"チャ","tyi":"チィ","cyi":"チィ","tyu":"チュ","chu":"チュ","cyu":"チュ","tye":"チェ","che":"チェ","cye":"チェ","tyo":"チョ","cho":"チョ","cyo":"チョ","tsa":"ツァ","tsi":"ツィ","tse":"ツェ","tso":"ツォ","tha":"テャ","thi":"ティ","thu":"テュ","the":"テェ","tho":"テョ","twa":"トァ","twi":"トィ","twu":"トゥ","twe":"トェ","two":"トォ","dya":"ヂャ","dyi":"ヂィ","dyu":"ヂュ","dye":"ヂェ","dyo":"ヂョ","dha":"デャ","dhi":"ディ","dhu":"デュ","dhe":"デェ","dho":"デョ","dwa":"ドァ","dwi":"ドィ","dwu":"ドゥ","dwe":"ドェ","dwo":"ドォ","na":"ナ","ni":"ニ","nu":"ヌ","ne":"ネ","no":"ノ","nya":"ニャ","nyi":"ニィ","nyu":"ニュ","nye":"ニェ","nyo":"ニョ","ha":"ハ","hi":"ヒ","hu":"フ","fu":"フ","he":"ヘ","ho":"ホ","ba":"バ","bi":"ビ","bu":"ブ","be":"ベ","bo":"ボ","pa":"パ","pi":"ピ","pu":"プ","pe":"ペ","po":"ポ","hya":"ヒャ","hyi":"ヒィ","hyu":"ヒュ","hye":"ヒェ","hyo":"ヒョ","fya":"フャ","fyu":"フュ","fyo":"フョ","fwa":"ファ","fa":"ファ","fwi":"フィ","fi":"フィ","fyi":"フィ","fwu":"フゥ","fwe":"フェ","fe":"フェ","fye":"フェ","fwo":"フォ","fo":"フォ","bya":"ビャ","byi":"ビィ","byu":"ビュ","bye":"ビェ","byo":"ビョ","va":"ヴァ","vi":"ヴィ","vu":"ヴ","ve":"ヴェ","vo":"ヴォ","vya":"ヴャ","vyi":"ヴィ","vyu":"ヴュ","vye":"ヴェ","vyo":"ヴョ","pya":"ピャ","pyi":"ピィ","pyu":"ピュ","pye":"ピェ","pyo":"ピョ","ma":"マ","mi":"ミ","mu":"ム","me":"メ","mo":"モ","mya":"ミャ","myi":"ミィ","myu":"ミュ","mye":"ミェ","myo":"ミョ","ya":"ヤ","yu":"ユ","yo":"ヨ","lya":"ャ","xya":"ャ","lyu":"ュ","xyu":"ュ","lyo":"ョ","xyo":"ョ","ra":"ラ","ri":"リ","ru":"ル","re":"レ","ro":"ロ","rya":"リャ","ryi":"リィ","ryu":"リュ","rye":"リェ","ryo":"リョ","wa":"ワ","wo":"ヲ","n":"ン","nn":"ン","n'":"ン","xn":"ン","lwa":"ヮ","xwa":"ヮ",".":"。",",":"、","bb":"ッ","cc":"ッ","dd":"ッ","ff":"ッ","gg":"ッ","hh":"ッ","jj":"ッ","kk":"ッ","ll":"ッ","mm":"ッ","pp":"ッ","qq":"ッ","rr":"ッ","ss":"ッ","tt":"ッ","vv":"ッ","ww":"ッ","xx":"ッ","yy":"ッ","zz":"ッ","-":"ー"};

