- All module modified.
*.loadpath
*.project
*.dat
-plugins/*
\ No newline at end of file
+*.prefs
+logs/*
+plugins/*
+plugins_exclude*
\ No newline at end of file
--- /dev/null
+#!/usr/local/bin/ruby\r
+# -*- coding: utf-8 -*-\r
+#\r
+#= 共通ライブラリ集\r
+#\r
+#Autohr:: Kureha Hisame (http://lunardial.sakura.ne.jp/)\r
+#Version:: 1.0.0.0\r
+#Copyright:: Copyright 2013 Kureha Hisame (http://lunardial.sakura.ne.jp/)\r
+#License:: GPLv3\r
+\r
+require "logger"\r
+\r
+# = WebLoggerクラス\r
+#\r
+# ロガーを取得する為のクラスです\r
+class WebLogger\r
+ @@max_log_size = 10 * 1024 * 1024\r
+ \r
+ def self.get_logger(script_name = "", log_dir = "", release_flag = false)\r
+ if script_name.empty?\r
+ log_filename = "#{log_dir}/default.log"\r
+ log_filename_bk = "#{log_dir}/default.log.bk.log"\r
+ else\r
+ log_filename = "#{log_dir}/" + File.basename(script_name, ".*") + ".log"\r
+ log_filename_bk = "#{log_dir}/" + File.basename(script_name, ".*") + ".bk.log"\r
+ end\r
+ if File.exist?(log_filename)\r
+ status = File::stat(log_filename)\r
+ if status.size > @@max_log_size\r
+ File.rename(log_filename, log_filename_bk)\r
+ end\r
+ end\r
+\r
+ logger = Object::Logger.new(log_filename)\r
+\r
+ if release_flag == true\r
+ logger.level = Object::Logger::ERROR\r
+ else\r
+ logger.level = Object::Logger::DEBUG\r
+ end\r
+\r
+ logger\r
+ end\r
+end\r
+\r
+# = HtmlWriterクラス\r
+# \r
+# テンプレートファイル(*.erb)を読み込み、管理するクラスです\r
+class HtmlWriter\r
+ # 初期化メソッドです\r
+ #\r
+ # _template_ :: テンプレートファイル(*.erb)のパス\r
+ # _binding_ :: binding変数\r
+ def initialize(template, binding)\r
+ @erb = ERB.new(myopen(template, "r:utf-8") {|f| f.read}, nil, "-")\r
+ @binding = binding\r
+ end\r
+\r
+ # テンプレートファイルの文字列を返却するメソッドです\r
+ def to_code\r
+ @erb.result(@binding)\r
+ end\r
+end\r
+\r
+\r
+# = Objectクラス\r
+#\r
+# 基本クラスのオーバーライドを行います\r
+class Object\r
+ # myopenメソッド\r
+ #\r
+ # ruby-1.9.x以降ではファイルを開いた際、エンコードの指定を行わないとエラーの原因になります。\r
+ # ただしruby-1.8.6以前はエンコードの指定に対応していないため、独自メソッドを定義してファイルの入出力を行います。\r
+ #\r
+ # _arg[0]_ :: 入出力を行うファイルのパス\r
+ # _arg[1]_ :: モードの指定。例 : w:utf-8(書き込みモード・UTF-8エンコードでファイルを開く)\r
+ def myopen(*arg)\r
+ mode = arg[1]\r
+ rdonly_p = true\r
+ case mode\r
+ when String\r
+ arg[1] = mode[/[^:]+/] if RUBY_VERSION < "1.8.7" && mode.include?(':')\r
+ rdonly_p = /\A[^:]*[wa+]/ !~ mode\r
+ when Numeric\r
+ rdonly_p = !(mode & (IO::WRONY | IO::RDWR))\r
+ end\r
+ open(*arg) do |f|\r
+ f.flock(rdonly_p ? File::LOCK_SH : File::LOCK_EX)\r
+ return yield(f)\r
+ end\r
+ end\r
+end\r
+\r
+class NilClass\r
+ def blank?\r
+ nil?\r
+ end\r
+end\r
+\r
+class Array\r
+ def blank?\r
+ empty?\r
+ end\r
+end\r
+\r
+class String\r
+ def blank?\r
+ empty?\r
+ end\r
+end\r
+\r
--- /dev/null
+<!--
+PIE: CSS3 rendering for IE
+Version 1.0.0
+http://css3pie.com
+Dual-licensed for use under the Apache License Version 2.0 or the General Public License (GPL) Version 2.
+-->
+<PUBLIC:COMPONENT lightWeight="true">
+<!-- saved from url=(0014)about:internet -->
+<PUBLIC:ATTACH EVENT="oncontentready" FOR="element" ONEVENT="init()" />
+<PUBLIC:ATTACH EVENT="ondocumentready" FOR="element" ONEVENT="init()" />
+<PUBLIC:ATTACH EVENT="ondetach" FOR="element" ONEVENT="cleanup()" />
+
+<script type="text/javascript">
+var doc = element.document;var f=window.PIE;
+if(!f){f=window.PIE={F:"-pie-",nb:"Pie",La:"pie_",Ac:{TD:1,TH:1},cc:{TABLE:1,THEAD:1,TBODY:1,TFOOT:1,TR:1,INPUT:1,TEXTAREA:1,SELECT:1,OPTION:1,IMG:1,HR:1},fc:{A:1,INPUT:1,TEXTAREA:1,SELECT:1,BUTTON:1},Gd:{submit:1,button:1,reset:1},aa:function(){}};try{doc.execCommand("BackgroundImageCache",false,true)}catch(aa){}for(var ba=4,Z=doc.createElement("div"),ca=Z.getElementsByTagName("i"),ga;Z.innerHTML="<!--[if gt IE "+ ++ba+"]><i></i><![endif]--\>",ca[0];);f.O=ba;if(ba===6)f.F=f.F.replace(/^-/,"");f.ja=
+doc.documentMode||f.O;Z.innerHTML='<v:shape adj="1"/>';ga=Z.firstChild;ga.style.behavior="url(#default#VML)";f.zc=typeof ga.adj==="object";(function(){var a,b=0,c={};f.p={Za:function(d){if(!a){a=doc.createDocumentFragment();a.namespaces.add("css3vml","urn:schemas-microsoft-com:vml")}return a.createElement("css3vml:"+d)},Ba:function(d){return d&&d._pieId||(d._pieId="_"+ ++b)},Eb:function(d){var e,g,j,i,h=arguments;e=1;for(g=h.length;e<g;e++){i=h[e];for(j in i)if(i.hasOwnProperty(j))d[j]=i[j]}return d},
+Rb:function(d,e,g){var j=c[d],i,h;if(j)Object.prototype.toString.call(j)==="[object Array]"?j.push([e,g]):e.call(g,j);else{h=c[d]=[[e,g]];i=new Image;i.onload=function(){j=c[d]={h:i.width,f:i.height};for(var k=0,n=h.length;k<n;k++)h[k][0].call(h[k][1],j);i.onload=null};i.src=d}}}})();f.Na={gc:function(a,b,c,d){function e(){k=j>=90&&j<270?b:0;n=j<180?c:0;m=b-k;p=c-n}function g(){for(;j<0;)j+=360;j%=360}var j=d.sa;d=d.zb;var i,h,k,n,m,p,r,t;if(d){d=d.coords(a,b,c);i=d.x;h=d.y}if(j){j=j.jd();g();e();
+if(!d){i=k;h=n}d=f.Na.tc(i,h,j,m,p);a=d[0];d=d[1]}else if(d){a=b-i;d=c-h}else{i=h=a=0;d=c}r=a-i;t=d-h;if(j===void 0){j=!r?t<0?90:270:!t?r<0?180:0:-Math.atan2(t,r)/Math.PI*180;g();e()}return{sa:j,xc:i,yc:h,td:a,ud:d,Wd:k,Xd:n,rd:m,sd:p,kd:r,ld:t,rc:f.Na.dc(i,h,a,d)}},tc:function(a,b,c,d,e){if(c===0||c===180)return[d,b];else if(c===90||c===270)return[a,e];else{c=Math.tan(-c*Math.PI/180);a=c*a-b;b=-1/c;d=b*d-e;e=b-c;return[(d-a)/e,(c*d-b*a)/e]}},dc:function(a,b,c,d){a=c-a;b=d-b;return Math.abs(a===0?
+b:b===0?a:Math.sqrt(a*a+b*b))}};f.ea=function(){this.Gb=[];this.oc={}};f.ea.prototype={ba:function(a){var b=f.p.Ba(a),c=this.oc,d=this.Gb;if(!(b in c)){c[b]=d.length;d.push(a)}},Ha:function(a){a=f.p.Ba(a);var b=this.oc;if(a&&a in b){delete this.Gb[b[a]];delete b[a]}},xa:function(){for(var a=this.Gb,b=a.length;b--;)a[b]&&a[b]()}};f.Oa=new f.ea;f.Oa.Rd=function(){var a=this,b;if(!a.Sd){b=doc.documentElement.currentStyle.getAttribute(f.F+"poll-interval")||250;(function c(){a.xa();setTimeout(c,b)})();
+a.Sd=1}};(function(){function a(){f.L.xa();window.detachEvent("onunload",a);window.PIE=null}f.L=new f.ea;window.attachEvent("onunload",a);f.L.ta=function(b,c,d){b.attachEvent(c,d);this.ba(function(){b.detachEvent(c,d)})}})();f.Qa=new f.ea;f.L.ta(window,"onresize",function(){f.Qa.xa()});(function(){function a(){f.mb.xa()}f.mb=new f.ea;f.L.ta(window,"onscroll",a);f.Qa.ba(a)})();(function(){function a(){c=f.kb.md()}function b(){if(c){for(var d=0,e=c.length;d<e;d++)f.attach(c[d]);c=0}}var c;if(f.ja<9){f.L.ta(window,
+"onbeforeprint",a);f.L.ta(window,"onafterprint",b)}})();f.lb=new f.ea;f.L.ta(doc,"onmouseup",function(){f.lb.xa()});f.he=function(){function a(h){this.Y=h}var b=doc.createElement("length-calc"),c=doc.body||doc.documentElement,d=b.style,e={},g=["mm","cm","in","pt","pc"],j=g.length,i={};d.position="absolute";d.top=d.left="-9999px";for(c.appendChild(b);j--;){d.width="100"+g[j];e[g[j]]=b.offsetWidth/100}c.removeChild(b);d.width="1em";a.prototype={Kb:/(px|em|ex|mm|cm|in|pt|pc|%)$/,ic:function(){var h=
+this.Jd;if(h===void 0)h=this.Jd=parseFloat(this.Y);return h},yb:function(){var h=this.ae;if(!h)h=this.ae=(h=this.Y.match(this.Kb))&&h[0]||"px";return h},a:function(h,k){var n=this.ic(),m=this.yb();switch(m){case "px":return n;case "%":return n*(typeof k==="function"?k():k)/100;case "em":return n*this.xb(h);case "ex":return n*this.xb(h)/2;default:return n*e[m]}},xb:function(h){var k=h.currentStyle.fontSize,n,m;if(k.indexOf("px")>0)return parseFloat(k);else if(h.tagName in f.cc){m=this;n=h.parentNode;
+return f.n(k).a(n,function(){return m.xb(n)})}else{h.appendChild(b);k=b.offsetWidth;b.parentNode===h&&h.removeChild(b);return k}}};f.n=function(h){return i[h]||(i[h]=new a(h))};return a}();f.Ja=function(){function a(e){this.X=e}var b=f.n("50%"),c={top:1,center:1,bottom:1},d={left:1,center:1,right:1};a.prototype={zd:function(){if(!this.ac){var e=this.X,g=e.length,j=f.v,i=j.qa,h=f.n("0");i=i.na;h=["left",h,"top",h];if(g===1){e.push(new j.ob(i,"center"));g++}if(g===2){i&(e[0].k|e[1].k)&&e[0].d in c&&
+e[1].d in d&&e.push(e.shift());if(e[0].k&i)if(e[0].d==="center")h[1]=b;else h[0]=e[0].d;else if(e[0].W())h[1]=f.n(e[0].d);if(e[1].k&i)if(e[1].d==="center")h[3]=b;else h[2]=e[1].d;else if(e[1].W())h[3]=f.n(e[1].d)}this.ac=h}return this.ac},coords:function(e,g,j){var i=this.zd(),h=i[1].a(e,g);e=i[3].a(e,j);return{x:i[0]==="right"?g-h:h,y:i[2]==="bottom"?j-e:e}}};return a}();f.Ka=function(){function a(b,c){this.h=b;this.f=c}a.prototype={a:function(b,c,d,e,g){var j=this.h,i=this.f,h=c/d;e=e/g;if(j===
+"contain"){j=e>h?c:d*e;i=e>h?c/e:d}else if(j==="cover"){j=e<h?c:d*e;i=e<h?c/e:d}else if(j==="auto"){i=i==="auto"?g:i.a(b,d);j=i*e}else{j=j.a(b,c);i=i==="auto"?j/e:i.a(b,d)}return{h:j,f:i}}};a.Kc=new a("auto","auto");return a}();f.Ec=function(){function a(b){this.Y=b}a.prototype={Kb:/[a-z]+$/i,yb:function(){return this.ad||(this.ad=this.Y.match(this.Kb)[0].toLowerCase())},jd:function(){var b=this.Vc,c;if(b===undefined){b=this.yb();c=parseFloat(this.Y,10);b=this.Vc=b==="deg"?c:b==="rad"?c/Math.PI*180:
+b==="grad"?c/400*360:b==="turn"?c*360:0}return b}};return a}();f.Jc=function(){function a(c){this.Y=c}var b={};a.Qd=/\s*rgba\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d+|\d*\.\d+)\s*\)\s*/;a.Fb={aliceblue:"F0F8FF",antiquewhite:"FAEBD7",aqua:"0FF",aquamarine:"7FFFD4",azure:"F0FFFF",beige:"F5F5DC",bisque:"FFE4C4",black:"000",blanchedalmond:"FFEBCD",blue:"00F",blueviolet:"8A2BE2",brown:"A52A2A",burlywood:"DEB887",cadetblue:"5F9EA0",chartreuse:"7FFF00",chocolate:"D2691E",coral:"FF7F50",cornflowerblue:"6495ED",
+cornsilk:"FFF8DC",crimson:"DC143C",cyan:"0FF",darkblue:"00008B",darkcyan:"008B8B",darkgoldenrod:"B8860B",darkgray:"A9A9A9",darkgreen:"006400",darkkhaki:"BDB76B",darkmagenta:"8B008B",darkolivegreen:"556B2F",darkorange:"FF8C00",darkorchid:"9932CC",darkred:"8B0000",darksalmon:"E9967A",darkseagreen:"8FBC8F",darkslateblue:"483D8B",darkslategray:"2F4F4F",darkturquoise:"00CED1",darkviolet:"9400D3",deeppink:"FF1493",deepskyblue:"00BFFF",dimgray:"696969",dodgerblue:"1E90FF",firebrick:"B22222",floralwhite:"FFFAF0",
+forestgreen:"228B22",fuchsia:"F0F",gainsboro:"DCDCDC",ghostwhite:"F8F8FF",gold:"FFD700",goldenrod:"DAA520",gray:"808080",green:"008000",greenyellow:"ADFF2F",honeydew:"F0FFF0",hotpink:"FF69B4",indianred:"CD5C5C",indigo:"4B0082",ivory:"FFFFF0",khaki:"F0E68C",lavender:"E6E6FA",lavenderblush:"FFF0F5",lawngreen:"7CFC00",lemonchiffon:"FFFACD",lightblue:"ADD8E6",lightcoral:"F08080",lightcyan:"E0FFFF",lightgoldenrodyellow:"FAFAD2",lightgreen:"90EE90",lightgrey:"D3D3D3",lightpink:"FFB6C1",lightsalmon:"FFA07A",
+lightseagreen:"20B2AA",lightskyblue:"87CEFA",lightslategray:"789",lightsteelblue:"B0C4DE",lightyellow:"FFFFE0",lime:"0F0",limegreen:"32CD32",linen:"FAF0E6",magenta:"F0F",maroon:"800000",mediumauqamarine:"66CDAA",mediumblue:"0000CD",mediumorchid:"BA55D3",mediumpurple:"9370D8",mediumseagreen:"3CB371",mediumslateblue:"7B68EE",mediumspringgreen:"00FA9A",mediumturquoise:"48D1CC",mediumvioletred:"C71585",midnightblue:"191970",mintcream:"F5FFFA",mistyrose:"FFE4E1",moccasin:"FFE4B5",navajowhite:"FFDEAD",
+navy:"000080",oldlace:"FDF5E6",olive:"808000",olivedrab:"688E23",orange:"FFA500",orangered:"FF4500",orchid:"DA70D6",palegoldenrod:"EEE8AA",palegreen:"98FB98",paleturquoise:"AFEEEE",palevioletred:"D87093",papayawhip:"FFEFD5",peachpuff:"FFDAB9",peru:"CD853F",pink:"FFC0CB",plum:"DDA0DD",powderblue:"B0E0E6",purple:"800080",red:"F00",rosybrown:"BC8F8F",royalblue:"4169E1",saddlebrown:"8B4513",salmon:"FA8072",sandybrown:"F4A460",seagreen:"2E8B57",seashell:"FFF5EE",sienna:"A0522D",silver:"C0C0C0",skyblue:"87CEEB",
+slateblue:"6A5ACD",slategray:"708090",snow:"FFFAFA",springgreen:"00FF7F",steelblue:"4682B4",tan:"D2B48C",teal:"008080",thistle:"D8BFD8",tomato:"FF6347",turquoise:"40E0D0",violet:"EE82EE",wheat:"F5DEB3",white:"FFF",whitesmoke:"F5F5F5",yellow:"FF0",yellowgreen:"9ACD32"};a.prototype={parse:function(){if(!this.Ua){var c=this.Y,d;if(d=c.match(a.Qd)){this.Ua="rgb("+d[1]+","+d[2]+","+d[3]+")";this.Yb=parseFloat(d[4])}else{if((d=c.toLowerCase())in a.Fb)c="#"+a.Fb[d];this.Ua=c;this.Yb=c==="transparent"?0:
+1}}},U:function(c){this.parse();return this.Ua==="currentColor"?c.currentStyle.color:this.Ua},fa:function(){this.parse();return this.Yb}};f.ha=function(c){return b[c]||(b[c]=new a(c))};return a}();f.v=function(){function a(c){this.$a=c;this.ch=0;this.X=[];this.Ga=0}var b=a.qa={Ia:1,Wb:2,z:4,Lc:8,Xb:16,na:32,K:64,oa:128,pa:256,Ra:512,Tc:1024,URL:2048};a.ob=function(c,d){this.k=c;this.d=d};a.ob.prototype={Ca:function(){return this.k&b.K||this.k&b.oa&&this.d==="0"},W:function(){return this.Ca()||this.k&
+b.Ra}};a.prototype={de:/\s/,Kd:/^[\+\-]?(\d*\.)?\d+/,url:/^url\(\s*("([^"]*)"|'([^']*)'|([!#$%&*-~]*))\s*\)/i,nc:/^\-?[_a-z][\w-]*/i,Yd:/^("([^"]*)"|'([^']*)')/,Bd:/^#([\da-f]{6}|[\da-f]{3})/i,be:{px:b.K,em:b.K,ex:b.K,mm:b.K,cm:b.K,"in":b.K,pt:b.K,pc:b.K,deg:b.Ia,rad:b.Ia,grad:b.Ia},fd:{rgb:1,rgba:1,hsl:1,hsla:1},next:function(c){function d(p,r){p=new a.ob(p,r);if(!c){k.X.push(p);k.Ga++}return p}function e(){k.Ga++;return null}var g,j,i,h,k=this;if(this.Ga<this.X.length)return this.X[this.Ga++];for(;this.de.test(this.$a.charAt(this.ch));)this.ch++;
+if(this.ch>=this.$a.length)return e();j=this.ch;g=this.$a.substring(this.ch);i=g.charAt(0);switch(i){case "#":if(h=g.match(this.Bd)){this.ch+=h[0].length;return d(b.z,h[0])}break;case '"':case "'":if(h=g.match(this.Yd)){this.ch+=h[0].length;return d(b.Tc,h[2]||h[3]||"")}break;case "/":case ",":this.ch++;return d(b.pa,i);case "u":if(h=g.match(this.url)){this.ch+=h[0].length;return d(b.URL,h[2]||h[3]||h[4]||"")}}if(h=g.match(this.Kd)){i=h[0];this.ch+=i.length;if(g.charAt(i.length)==="%"){this.ch++;
+return d(b.Ra,i+"%")}if(h=g.substring(i.length).match(this.nc)){i+=h[0];this.ch+=h[0].length;return d(this.be[h[0].toLowerCase()]||b.Lc,i)}return d(b.oa,i)}if(h=g.match(this.nc)){i=h[0];this.ch+=i.length;if(i.toLowerCase()in f.Jc.Fb||i==="currentColor"||i==="transparent")return d(b.z,i);if(g.charAt(i.length)==="("){this.ch++;if(i.toLowerCase()in this.fd){g=function(p){return p&&p.k&b.oa};h=function(p){return p&&p.k&(b.oa|b.Ra)};var n=function(p,r){return p&&p.d===r},m=function(){return k.next(1)};
+if((i.charAt(0)==="r"?h(m()):g(m()))&&n(m(),",")&&h(m())&&n(m(),",")&&h(m())&&(i==="rgb"||i==="hsa"||n(m(),",")&&g(m()))&&n(m(),")"))return d(b.z,this.$a.substring(j,this.ch));return e()}return d(b.Xb,i)}return d(b.na,i)}this.ch++;return d(b.Wb,i)},D:function(){return this.X[this.Ga-- -2]},all:function(){for(;this.next(););return this.X},ma:function(c,d){for(var e=[],g,j;g=this.next();){if(c(g)){j=true;this.D();break}e.push(g)}return d&&!j?null:e}};return a}();var ha=function(a){this.e=a};ha.prototype=
+{Z:0,Od:function(){var a=this.qb,b;return!a||(b=this.o())&&(a.x!==b.x||a.y!==b.y)},Td:function(){var a=this.qb,b;return!a||(b=this.o())&&(a.h!==b.h||a.f!==b.f)},hc:function(){var a=this.e,b=a.getBoundingClientRect(),c=f.ja===9,d=f.O===7,e=b.right-b.left;return{x:b.left,y:b.top,h:c||d?a.offsetWidth:e,f:c||d?a.offsetHeight:b.bottom-b.top,Hd:d&&e?a.offsetWidth/e:1}},o:function(){return this.Z?this.Va||(this.Va=this.hc()):this.hc()},Ad:function(){return!!this.qb},cb:function(){++this.Z},hb:function(){if(!--this.Z){if(this.Va)this.qb=
+this.Va;this.Va=null}}};(function(){function a(b){var c=f.p.Ba(b);return function(){if(this.Z){var d=this.$b||(this.$b={});return c in d?d[c]:(d[c]=b.call(this))}else return b.call(this)}}f.B={Z:0,ka:function(b){function c(d){this.e=d;this.Zb=this.ia()}f.p.Eb(c.prototype,f.B,b);c.$c={};return c},j:function(){var b=this.ia(),c=this.constructor.$c;return b?b in c?c[b]:(c[b]=this.la(b)):null},ia:a(function(){var b=this.e,c=this.constructor,d=b.style;b=b.currentStyle;var e=this.wa,g=this.Fa,j=c.Yc||(c.Yc=
+f.F+e);c=c.Zc||(c.Zc=f.nb+g.charAt(0).toUpperCase()+g.substring(1));return d[c]||b.getAttribute(j)||d[g]||b.getAttribute(e)}),i:a(function(){return!!this.j()}),H:a(function(){var b=this.ia(),c=b!==this.Zb;this.Zb=b;return c}),va:a,cb:function(){++this.Z},hb:function(){--this.Z||delete this.$b}}})();f.Sb=f.B.ka({wa:f.F+"background",Fa:f.nb+"Background",cd:{scroll:1,fixed:1,local:1},fb:{"repeat-x":1,"repeat-y":1,repeat:1,"no-repeat":1},sc:{"padding-box":1,"border-box":1,"content-box":1},Pd:{top:1,right:1,
+bottom:1,left:1,center:1},Ud:{contain:1,cover:1},eb:{Ma:"backgroundClip",z:"backgroundColor",da:"backgroundImage",Pa:"backgroundOrigin",S:"backgroundPosition",T:"backgroundRepeat",Sa:"backgroundSize"},la:function(a){function b(s){return s&&s.W()||s.k&k&&s.d in t}function c(s){return s&&(s.W()&&f.n(s.d)||s.d==="auto"&&"auto")}var d=this.e.currentStyle,e,g,j,i=f.v.qa,h=i.pa,k=i.na,n=i.z,m,p,r=0,t=this.Pd,v,l,q={M:[]};if(this.wb()){e=new f.v(a);for(j={};g=e.next();){m=g.k;p=g.d;if(!j.P&&m&i.Xb&&p===
+"linear-gradient"){v={ca:[],P:p};for(l={};g=e.next();){m=g.k;p=g.d;if(m&i.Wb&&p===")"){l.color&&v.ca.push(l);v.ca.length>1&&f.p.Eb(j,v);break}if(m&n){if(v.sa||v.zb){g=e.D();if(g.k!==h)break;e.next()}l={color:f.ha(p)};g=e.next();if(g.W())l.db=f.n(g.d);else e.D()}else if(m&i.Ia&&!v.sa&&!l.color&&!v.ca.length)v.sa=new f.Ec(g.d);else if(b(g)&&!v.zb&&!l.color&&!v.ca.length){e.D();v.zb=new f.Ja(e.ma(function(s){return!b(s)},false))}else if(m&h&&p===","){if(l.color){v.ca.push(l);l={}}}else break}}else if(!j.P&&
+m&i.URL){j.Ab=p;j.P="image"}else if(b(g)&&!j.$){e.D();j.$=new f.Ja(e.ma(function(s){return!b(s)},false))}else if(m&k)if(p in this.fb&&!j.bb)j.bb=p;else if(p in this.sc&&!j.Wa){j.Wa=p;if((g=e.next())&&g.k&k&&g.d in this.sc)j.ub=g.d;else{j.ub=p;e.D()}}else if(p in this.cd&&!j.bc)j.bc=p;else return null;else if(m&n&&!q.color)q.color=f.ha(p);else if(m&h&&p==="/"&&!j.Xa&&j.$){g=e.next();if(g.k&k&&g.d in this.Ud)j.Xa=new f.Ka(g.d);else if(g=c(g)){m=c(e.next());if(!m){m=g;e.D()}j.Xa=new f.Ka(g,m)}else return null}else if(m&
+h&&p===","&&j.P){j.Hb=a.substring(r,e.ch-1);r=e.ch;q.M.push(j);j={}}else return null}if(j.P){j.Hb=a.substring(r);q.M.push(j)}}else this.Bc(f.ja<9?function(){var s=this.eb,o=d[s.S+"X"],u=d[s.S+"Y"],x=d[s.da],y=d[s.z];if(y!=="transparent")q.color=f.ha(y);if(x!=="none")q.M=[{P:"image",Ab:(new f.v(x)).next().d,bb:d[s.T],$:new f.Ja((new f.v(o+" "+u)).all())}]}:function(){var s=this.eb,o=/\s*,\s*/,u=d[s.da].split(o),x=d[s.z],y,z,B,E,D,C;if(x!=="transparent")q.color=f.ha(x);if((E=u.length)&&u[0]!=="none"){x=
+d[s.T].split(o);y=d[s.S].split(o);z=d[s.Pa].split(o);B=d[s.Ma].split(o);s=d[s.Sa].split(o);q.M=[];for(o=0;o<E;o++)if((D=u[o])&&D!=="none"){C=s[o].split(" ");q.M.push({Hb:D+" "+x[o]+" "+y[o]+" / "+s[o]+" "+z[o]+" "+B[o],P:"image",Ab:(new f.v(D)).next().d,bb:x[o],$:new f.Ja((new f.v(y[o])).all()),Wa:z[o],ub:B[o],Xa:new f.Ka(C[0],C[1])})}}});return q.color||q.M[0]?q:null},Bc:function(a){var b=f.ja>8,c=this.eb,d=this.e.runtimeStyle,e=d[c.da],g=d[c.z],j=d[c.T],i,h,k,n;if(e)d[c.da]="";if(g)d[c.z]="";if(j)d[c.T]=
+"";if(b){i=d[c.Ma];h=d[c.Pa];n=d[c.S];k=d[c.Sa];if(i)d[c.Ma]="";if(h)d[c.Pa]="";if(n)d[c.S]="";if(k)d[c.Sa]=""}a=a.call(this);if(e)d[c.da]=e;if(g)d[c.z]=g;if(j)d[c.T]=j;if(b){if(i)d[c.Ma]=i;if(h)d[c.Pa]=h;if(n)d[c.S]=n;if(k)d[c.Sa]=k}return a},ia:f.B.va(function(){return this.wb()||this.Bc(function(){var a=this.e.currentStyle,b=this.eb;return a[b.z]+" "+a[b.da]+" "+a[b.T]+" "+a[b.S+"X"]+" "+a[b.S+"Y"]})}),wb:f.B.va(function(){var a=this.e;return a.style[this.Fa]||a.currentStyle.getAttribute(this.wa)}),
+qc:function(){var a=0;if(f.O<7){a=this.e;a=""+(a.style[f.nb+"PngFix"]||a.currentStyle.getAttribute(f.F+"png-fix"))==="true"}return a},i:f.B.va(function(){return(this.wb()||this.qc())&&!!this.j()})});f.Vb=f.B.ka({wc:["Top","Right","Bottom","Left"],Id:{thin:"1px",medium:"3px",thick:"5px"},la:function(){var a={},b={},c={},d=false,e=true,g=true,j=true;this.Cc(function(){for(var i=this.e.currentStyle,h=0,k,n,m,p,r,t,v;h<4;h++){m=this.wc[h];v=m.charAt(0).toLowerCase();k=b[v]=i["border"+m+"Style"];n=i["border"+
+m+"Color"];m=i["border"+m+"Width"];if(h>0){if(k!==p)g=false;if(n!==r)e=false;if(m!==t)j=false}p=k;r=n;t=m;c[v]=f.ha(n);m=a[v]=f.n(b[v]==="none"?"0":this.Id[m]||m);if(m.a(this.e)>0)d=true}});return d?{J:a,Zd:b,gd:c,ee:j,hd:e,$d:g}:null},ia:f.B.va(function(){var a=this.e,b=a.currentStyle,c;a.tagName in f.Ac&&a.offsetParent.currentStyle.borderCollapse==="collapse"||this.Cc(function(){c=b.borderWidth+"|"+b.borderStyle+"|"+b.borderColor});return c}),Cc:function(a){var b=this.e.runtimeStyle,c=b.borderWidth,
+d=b.borderColor;if(c)b.borderWidth="";if(d)b.borderColor="";a=a.call(this);if(c)b.borderWidth=c;if(d)b.borderColor=d;return a}});(function(){f.jb=f.B.ka({wa:"border-radius",Fa:"borderRadius",la:function(b){var c=null,d,e,g,j,i=false;if(b){e=new f.v(b);var h=function(){for(var k=[],n;(g=e.next())&&g.W();){j=f.n(g.d);n=j.ic();if(n<0)return null;if(n>0)i=true;k.push(j)}return k.length>0&&k.length<5?{tl:k[0],tr:k[1]||k[0],br:k[2]||k[0],bl:k[3]||k[1]||k[0]}:null};if(b=h()){if(g){if(g.k&f.v.qa.pa&&g.d===
+"/")d=h()}else d=b;if(i&&b&&d)c={x:b,y:d}}}return c}});var a=f.n("0");a={tl:a,tr:a,br:a,bl:a};f.jb.Dc={x:a,y:a}})();f.Ub=f.B.ka({wa:"border-image",Fa:"borderImage",fb:{stretch:1,round:1,repeat:1,space:1},la:function(a){var b=null,c,d,e,g,j,i,h=0,k=f.v.qa,n=k.na,m=k.oa,p=k.Ra;if(a){c=new f.v(a);b={};for(var r=function(l){return l&&l.k&k.pa&&l.d==="/"},t=function(l){return l&&l.k&n&&l.d==="fill"},v=function(){g=c.ma(function(l){return!(l.k&(m|p))});if(t(c.next())&&!b.fill)b.fill=true;else c.D();if(r(c.next())){h++;
+j=c.ma(function(l){return!l.W()&&!(l.k&n&&l.d==="auto")});if(r(c.next())){h++;i=c.ma(function(l){return!l.Ca()})}}else c.D()};a=c.next();){d=a.k;e=a.d;if(d&(m|p)&&!g){c.D();v()}else if(t(a)&&!b.fill){b.fill=true;v()}else if(d&n&&this.fb[e]&&!b.repeat){b.repeat={f:e};if(a=c.next())if(a.k&n&&this.fb[a.d])b.repeat.Ob=a.d;else c.D()}else if(d&k.URL&&!b.src)b.src=e;else return null}if(!b.src||!g||g.length<1||g.length>4||j&&j.length>4||h===1&&j.length<1||i&&i.length>4||h===2&&i.length<1)return null;if(!b.repeat)b.repeat=
+{f:"stretch"};if(!b.repeat.Ob)b.repeat.Ob=b.repeat.f;a=function(l,q){return{t:q(l[0]),r:q(l[1]||l[0]),b:q(l[2]||l[0]),l:q(l[3]||l[1]||l[0])}};b.slice=a(g,function(l){return f.n(l.k&m?l.d+"px":l.d)});if(j&&j[0])b.J=a(j,function(l){return l.W()?f.n(l.d):l.d});if(i&&i[0])b.Da=a(i,function(l){return l.Ca()?f.n(l.d):l.d})}return b}});f.Ic=f.B.ka({wa:"box-shadow",Fa:"boxShadow",la:function(a){var b,c=f.n,d=f.v.qa,e;if(a){e=new f.v(a);b={Da:[],Bb:[]};for(a=function(){for(var g,j,i,h,k,n;g=e.next();){i=g.d;
+j=g.k;if(j&d.pa&&i===",")break;else if(g.Ca()&&!k){e.D();k=e.ma(function(m){return!m.Ca()})}else if(j&d.z&&!h)h=i;else if(j&d.na&&i==="inset"&&!n)n=true;else return false}g=k&&k.length;if(g>1&&g<5){(n?b.Bb:b.Da).push({fe:c(k[0].d),ge:c(k[1].d),blur:c(k[2]?k[2].d:"0"),Vd:c(k[3]?k[3].d:"0"),color:f.ha(h||"currentColor")});return true}return false};a(););}return b&&(b.Bb.length||b.Da.length)?b:null}});f.Uc=f.B.ka({ia:f.B.va(function(){var a=this.e.currentStyle;return a.visibility+"|"+a.display}),la:function(){var a=
+this.e,b=a.runtimeStyle;a=a.currentStyle;var c=b.visibility,d;b.visibility="";d=a.visibility;b.visibility=c;return{ce:d!=="hidden",nd:a.display!=="none"}},i:function(){return false}});f.u={R:function(a){function b(c,d,e,g){this.e=c;this.s=d;this.g=e;this.parent=g}f.p.Eb(b.prototype,f.u,a);return b},Cb:false,Q:function(){return false},Ea:f.aa,Lb:function(){this.m();this.i()&&this.V()},ib:function(){this.Cb=true},Mb:function(){this.i()?this.V():this.m()},sb:function(a,b){this.vc(a);for(var c=this.ra||
+(this.ra=[]),d=a+1,e=c.length,g;d<e;d++)if(g=c[d])break;c[a]=b;this.I().insertBefore(b,g||null)},za:function(a){var b=this.ra;return b&&b[a]||null},vc:function(a){var b=this.za(a),c=this.Ta;if(b&&c){c.removeChild(b);this.ra[a]=null}},Aa:function(a,b,c,d){var e=this.rb||(this.rb={}),g=e[a];if(!g){g=e[a]=f.p.Za("shape");if(b)g.appendChild(g[b]=f.p.Za(b));if(d){c=this.za(d);if(!c){this.sb(d,doc.createElement("group"+d));c=this.za(d)}}c.appendChild(g);a=g.style;a.position="absolute";a.left=a.top=0;a.behavior=
+"url(#default#VML)"}return g},vb:function(a){var b=this.rb,c=b&&b[a];if(c){c.parentNode.removeChild(c);delete b[a]}return!!c},kc:function(a){var b=this.e,c=this.s.o(),d=c.h,e=c.f,g,j,i,h,k,n;c=a.x.tl.a(b,d);g=a.y.tl.a(b,e);j=a.x.tr.a(b,d);i=a.y.tr.a(b,e);h=a.x.br.a(b,d);k=a.y.br.a(b,e);n=a.x.bl.a(b,d);a=a.y.bl.a(b,e);d=Math.min(d/(c+j),e/(i+k),d/(n+h),e/(g+a));if(d<1){c*=d;g*=d;j*=d;i*=d;h*=d;k*=d;n*=d;a*=d}return{x:{tl:c,tr:j,br:h,bl:n},y:{tl:g,tr:i,br:k,bl:a}}},ya:function(a,b,c){b=b||1;var d,e,
+g=this.s.o();e=g.h*b;g=g.f*b;var j=this.g.G,i=Math.floor,h=Math.ceil,k=a?a.Jb*b:0,n=a?a.Ib*b:0,m=a?a.tb*b:0;a=a?a.Db*b:0;var p,r,t,v,l;if(c||j.i()){d=this.kc(c||j.j());c=d.x.tl*b;j=d.y.tl*b;p=d.x.tr*b;r=d.y.tr*b;t=d.x.br*b;v=d.y.br*b;l=d.x.bl*b;b=d.y.bl*b;e="m"+i(a)+","+i(j)+"qy"+i(c)+","+i(k)+"l"+h(e-p)+","+i(k)+"qx"+h(e-n)+","+i(r)+"l"+h(e-n)+","+h(g-v)+"qy"+h(e-t)+","+h(g-m)+"l"+i(l)+","+h(g-m)+"qx"+i(a)+","+h(g-b)+" x e"}else e="m"+i(a)+","+i(k)+"l"+h(e-n)+","+i(k)+"l"+h(e-n)+","+h(g-m)+"l"+i(a)+
+","+h(g-m)+"xe";return e},I:function(){var a=this.parent.za(this.N),b;if(!a){a=doc.createElement(this.Ya);b=a.style;b.position="absolute";b.top=b.left=0;this.parent.sb(this.N,a)}return a},mc:function(){var a=this.e,b=a.currentStyle,c=a.runtimeStyle,d=a.tagName,e=f.O===6,g;if(e&&(d in f.cc||d==="FIELDSET")||d==="BUTTON"||d==="INPUT"&&a.type in f.Gd){c.borderWidth="";d=this.g.w.wc;for(g=d.length;g--;){e=d[g];c["padding"+e]="";c["padding"+e]=f.n(b["padding"+e]).a(a)+f.n(b["border"+e+"Width"]).a(a)+(f.O!==
+8&&g%2?1:0)}c.borderWidth=0}else if(e){if(a.childNodes.length!==1||a.firstChild.tagName!=="ie6-mask"){b=doc.createElement("ie6-mask");d=b.style;d.visibility="visible";for(d.zoom=1;d=a.firstChild;)b.appendChild(d);a.appendChild(b);c.visibility="hidden"}}else c.borderColor="transparent"},ie:function(){},m:function(){this.parent.vc(this.N);delete this.rb;delete this.ra}};f.Rc=f.u.R({i:function(){var a=this.ed;for(var b in a)if(a.hasOwnProperty(b)&&a[b].i())return true;return false},Q:function(){return this.g.Pb.H()},
+ib:function(){if(this.i()){var a=this.jc(),b=a,c;a=a.currentStyle;var d=a.position,e=this.I().style,g=0,j=0;j=this.s.o();var i=j.Hd;if(d==="fixed"&&f.O>6){g=j.x*i;j=j.y*i;b=d}else{do b=b.offsetParent;while(b&&b.currentStyle.position==="static");if(b){c=b.getBoundingClientRect();b=b.currentStyle;g=(j.x-c.left)*i-(parseFloat(b.borderLeftWidth)||0);j=(j.y-c.top)*i-(parseFloat(b.borderTopWidth)||0)}else{b=doc.documentElement;g=(j.x+b.scrollLeft-b.clientLeft)*i;j=(j.y+b.scrollTop-b.clientTop)*i}b="absolute"}e.position=
+b;e.left=g;e.top=j;e.zIndex=d==="static"?-1:a.zIndex;this.Cb=true}},Mb:f.aa,Nb:function(){var a=this.g.Pb.j();this.I().style.display=a.ce&&a.nd?"":"none"},Lb:function(){this.i()?this.Nb():this.m()},jc:function(){var a=this.e;return a.tagName in f.Ac?a.offsetParent:a},I:function(){var a=this.Ta,b;if(!a){b=this.jc();a=this.Ta=doc.createElement("css3-container");a.style.direction="ltr";this.Nb();b.parentNode.insertBefore(a,b)}return a},ab:f.aa,m:function(){var a=this.Ta,b;if(a&&(b=a.parentNode))b.removeChild(a);
+delete this.Ta;delete this.ra}});f.Fc=f.u.R({N:2,Ya:"background",Q:function(){var a=this.g;return a.C.H()||a.G.H()},i:function(){var a=this.g;return a.q.i()||a.G.i()||a.C.i()||a.ga.i()&&a.ga.j().Bb},V:function(){var a=this.s.o();if(a.h&&a.f){this.od();this.pd()}},od:function(){var a=this.g.C.j(),b=this.s.o(),c=this.e,d=a&&a.color,e,g;if(d&&d.fa()>0){this.lc();a=this.Aa("bgColor","fill",this.I(),1);e=b.h;b=b.f;a.stroked=false;a.coordsize=e*2+","+b*2;a.coordorigin="1,1";a.path=this.ya(null,2);g=a.style;
+g.width=e;g.height=b;a.fill.color=d.U(c);c=d.fa();if(c<1)a.fill.opacity=c}else this.vb("bgColor")},pd:function(){var a=this.g.C.j(),b=this.s.o();a=a&&a.M;var c,d,e,g,j;if(a){this.lc();d=b.h;e=b.f;for(j=a.length;j--;){b=a[j];c=this.Aa("bgImage"+j,"fill",this.I(),2);c.stroked=false;c.fill.type="tile";c.fillcolor="none";c.coordsize=d*2+","+e*2;c.coordorigin="1,1";c.path=this.ya(0,2);g=c.style;g.width=d;g.height=e;if(b.P==="linear-gradient")this.bd(c,b);else{c.fill.src=b.Ab;this.Nd(c,j)}}}for(j=a?a.length:
+0;this.vb("bgImage"+j++););},Nd:function(a,b){var c=this;f.p.Rb(a.fill.src,function(d){var e=c.e,g=c.s.o(),j=g.h;g=g.f;if(j&&g){var i=a.fill,h=c.g,k=h.w.j(),n=k&&k.J;k=n?n.t.a(e):0;var m=n?n.r.a(e):0,p=n?n.b.a(e):0;n=n?n.l.a(e):0;h=h.C.j().M[b];e=h.$?h.$.coords(e,j-d.h-n-m,g-d.f-k-p):{x:0,y:0};h=h.bb;p=m=0;var r=j+1,t=g+1,v=f.O===8?0:1;n=Math.round(e.x)+n+0.5;k=Math.round(e.y)+k+0.5;i.position=n/j+","+k/g;i.size.x=1;i.size=d.h+"px,"+d.f+"px";if(h&&h!=="repeat"){if(h==="repeat-x"||h==="no-repeat"){m=
+k+1;t=k+d.f+v}if(h==="repeat-y"||h==="no-repeat"){p=n+1;r=n+d.h+v}a.style.clip="rect("+m+"px,"+r+"px,"+t+"px,"+p+"px)"}}})},bd:function(a,b){var c=this.e,d=this.s.o(),e=d.h,g=d.f;a=a.fill;d=b.ca;var j=d.length,i=Math.PI,h=f.Na,k=h.tc,n=h.dc;b=h.gc(c,e,g,b);h=b.sa;var m=b.xc,p=b.yc,r=b.Wd,t=b.Xd,v=b.rd,l=b.sd,q=b.kd,s=b.ld;b=b.rc;e=h%90?Math.atan2(q*e/g,s)/i*180:h+90;e+=180;e%=360;v=k(r,t,h,v,l);g=n(r,t,v[0],v[1]);i=[];v=k(m,p,h,r,t);n=n(m,p,v[0],v[1])/g*100;k=[];for(h=0;h<j;h++)k.push(d[h].db?d[h].db.a(c,
+b):h===0?0:h===j-1?b:null);for(h=1;h<j;h++){if(k[h]===null){m=k[h-1];b=h;do p=k[++b];while(p===null);k[h]=m+(p-m)/(b-h+1)}k[h]=Math.max(k[h],k[h-1])}for(h=0;h<j;h++)i.push(n+k[h]/g*100+"% "+d[h].color.U(c));a.angle=e;a.type="gradient";a.method="sigma";a.color=d[0].color.U(c);a.color2=d[j-1].color.U(c);if(a.colors)a.colors.value=i.join(",");else a.colors=i.join(",")},lc:function(){var a=this.e.runtimeStyle;a.backgroundImage="url(about:blank)";a.backgroundColor="transparent"},m:function(){f.u.m.call(this);
+var a=this.e.runtimeStyle;a.backgroundImage=a.backgroundColor=""}});f.Gc=f.u.R({N:4,Ya:"border",Q:function(){var a=this.g;return a.w.H()||a.G.H()},i:function(){var a=this.g;return a.G.i()&&!a.q.i()&&a.w.i()},V:function(){var a=this.e,b=this.g.w.j(),c=this.s.o(),d=c.h;c=c.f;var e,g,j,i,h;if(b){this.mc();b=this.wd(2);i=0;for(h=b.length;i<h;i++){j=b[i];e=this.Aa("borderPiece"+i,j.stroke?"stroke":"fill",this.I());e.coordsize=d*2+","+c*2;e.coordorigin="1,1";e.path=j.path;g=e.style;g.width=d;g.height=c;
+e.filled=!!j.fill;e.stroked=!!j.stroke;if(j.stroke){e=e.stroke;e.weight=j.Qb+"px";e.color=j.color.U(a);e.dashstyle=j.stroke==="dashed"?"2 2":j.stroke==="dotted"?"1 1":"solid";e.linestyle=j.stroke==="double"&&j.Qb>2?"ThinThin":"Single"}else e.fill.color=j.fill.U(a)}for(;this.vb("borderPiece"+i++););}},wd:function(a){var b=this.e,c,d,e,g=this.g.w,j=[],i,h,k,n,m=Math.round,p,r,t;if(g.i()){c=g.j();g=c.J;r=c.Zd;t=c.gd;if(c.ee&&c.$d&&c.hd){if(t.t.fa()>0){c=g.t.a(b);k=c/2;j.push({path:this.ya({Jb:k,Ib:k,
+tb:k,Db:k},a),stroke:r.t,color:t.t,Qb:c})}}else{a=a||1;c=this.s.o();d=c.h;e=c.f;c=m(g.t.a(b));k=m(g.r.a(b));n=m(g.b.a(b));b=m(g.l.a(b));var v={t:c,r:k,b:n,l:b};b=this.g.G;if(b.i())p=this.kc(b.j());i=Math.floor;h=Math.ceil;var l=function(o,u){return p?p[o][u]:0},q=function(o,u,x,y,z,B){var E=l("x",o),D=l("y",o),C=o.charAt(1)==="r";o=o.charAt(0)==="b";return E>0&&D>0?(B?"al":"ae")+(C?h(d-E):i(E))*a+","+(o?h(e-D):i(D))*a+","+(i(E)-u)*a+","+(i(D)-x)*a+","+y*65535+","+2949075*(z?1:-1):(B?"m":"l")+(C?d-
+u:u)*a+","+(o?e-x:x)*a},s=function(o,u,x,y){var z=o==="t"?i(l("x","tl"))*a+","+h(u)*a:o==="r"?h(d-u)*a+","+i(l("y","tr"))*a:o==="b"?h(d-l("x","br"))*a+","+i(e-u)*a:i(u)*a+","+h(e-l("y","bl"))*a;o=o==="t"?h(d-l("x","tr"))*a+","+h(u)*a:o==="r"?h(d-u)*a+","+h(e-l("y","br"))*a:o==="b"?i(l("x","bl"))*a+","+i(e-u)*a:i(u)*a+","+i(l("y","tl"))*a;return x?(y?"m"+o:"")+"l"+z:(y?"m"+z:"")+"l"+o};b=function(o,u,x,y,z,B){var E=o==="l"||o==="r",D=v[o],C,F;if(D>0&&r[o]!=="none"&&t[o].fa()>0){C=v[E?o:u];u=v[E?u:
+o];F=v[E?o:x];x=v[E?x:o];if(r[o]==="dashed"||r[o]==="dotted"){j.push({path:q(y,C,u,B+45,0,1)+q(y,0,0,B,1,0),fill:t[o]});j.push({path:s(o,D/2,0,1),stroke:r[o],Qb:D,color:t[o]});j.push({path:q(z,F,x,B,0,1)+q(z,0,0,B-45,1,0),fill:t[o]})}else j.push({path:q(y,C,u,B+45,0,1)+s(o,D,0,0)+q(z,F,x,B,0,0)+(r[o]==="double"&&D>2?q(z,F-i(F/3),x-i(x/3),B-45,1,0)+s(o,h(D/3*2),1,0)+q(y,C-i(C/3),u-i(u/3),B,1,0)+"x "+q(y,i(C/3),i(u/3),B+45,0,1)+s(o,i(D/3),1,0)+q(z,i(F/3),i(x/3),B,0,0):"")+q(z,0,0,B-45,1,0)+s(o,0,1,
+0)+q(y,0,0,B,1,0),fill:t[o]})}};b("t","l","r","tl","tr",90);b("r","t","b","tr","br",0);b("b","r","l","br","bl",-90);b("l","b","t","bl","tl",-180)}}return j},m:function(){if(this.ec||!this.g.q.i())this.e.runtimeStyle.borderColor="";f.u.m.call(this)}});f.Tb=f.u.R({N:5,Md:["t","tr","r","br","b","bl","l","tl","c"],Q:function(){return this.g.q.H()},i:function(){return this.g.q.i()},V:function(){this.I();var a=this.g.q.j(),b=this.g.w.j(),c=this.s.o(),d=this.e,e=this.uc;f.p.Rb(a.src,function(g){function j(s,
+o,u,x,y){s=e[s].style;var z=Math.max;s.width=z(o,0);s.height=z(u,0);s.left=x;s.top=y}function i(s,o,u){for(var x=0,y=s.length;x<y;x++)e[s[x]].imagedata[o]=u}var h=c.h,k=c.f,n=f.n("0"),m=a.J||(b?b.J:{t:n,r:n,b:n,l:n});n=m.t.a(d);var p=m.r.a(d),r=m.b.a(d);m=m.l.a(d);var t=a.slice,v=t.t.a(d),l=t.r.a(d),q=t.b.a(d);t=t.l.a(d);j("tl",m,n,0,0);j("t",h-m-p,n,m,0);j("tr",p,n,h-p,0);j("r",p,k-n-r,h-p,n);j("br",p,r,h-p,k-r);j("b",h-m-p,r,m,k-r);j("bl",m,r,0,k-r);j("l",m,k-n-r,0,n);j("c",h-m-p,k-n-r,m,n);i(["tl",
+"t","tr"],"cropBottom",(g.f-v)/g.f);i(["tl","l","bl"],"cropRight",(g.h-t)/g.h);i(["bl","b","br"],"cropTop",(g.f-q)/g.f);i(["tr","r","br"],"cropLeft",(g.h-l)/g.h);i(["l","r","c"],"cropTop",v/g.f);i(["l","r","c"],"cropBottom",q/g.f);i(["t","b","c"],"cropLeft",t/g.h);i(["t","b","c"],"cropRight",l/g.h);e.c.style.display=a.fill?"":"none"},this)},I:function(){var a=this.parent.za(this.N),b,c,d,e=this.Md,g=e.length;if(!a){a=doc.createElement("border-image");b=a.style;b.position="absolute";this.uc={};for(d=
+0;d<g;d++){c=this.uc[e[d]]=f.p.Za("rect");c.appendChild(f.p.Za("imagedata"));b=c.style;b.behavior="url(#default#VML)";b.position="absolute";b.top=b.left=0;c.imagedata.src=this.g.q.j().src;c.stroked=false;c.filled=false;a.appendChild(c)}this.parent.sb(this.N,a)}return a},Ea:function(){if(this.i()){var a=this.e,b=a.runtimeStyle,c=this.g.q.j().J;b.borderStyle="solid";if(c){b.borderTopWidth=c.t.a(a)+"px";b.borderRightWidth=c.r.a(a)+"px";b.borderBottomWidth=c.b.a(a)+"px";b.borderLeftWidth=c.l.a(a)+"px"}this.mc()}},
+m:function(){var a=this.e.runtimeStyle;a.borderStyle="";if(this.ec||!this.g.w.i())a.borderColor=a.borderWidth="";f.u.m.call(this)}});f.Hc=f.u.R({N:1,Ya:"outset-box-shadow",Q:function(){var a=this.g;return a.ga.H()||a.G.H()},i:function(){var a=this.g.ga;return a.i()&&a.j().Da[0]},V:function(){function a(C,F,O,H,M,P,I){C=b.Aa("shadow"+C+F,"fill",d,j-C);F=C.fill;C.coordsize=n*2+","+m*2;C.coordorigin="1,1";C.stroked=false;C.filled=true;F.color=M.U(c);if(P){F.type="gradienttitle";F.color2=F.color;F.opacity=
+0}C.path=I;l=C.style;l.left=O;l.top=H;l.width=n;l.height=m;return C}var b=this,c=this.e,d=this.I(),e=this.g,g=e.ga.j().Da;e=e.G.j();var j=g.length,i=j,h,k=this.s.o(),n=k.h,m=k.f;k=f.O===8?1:0;for(var p=["tl","tr","br","bl"],r,t,v,l,q,s,o,u,x,y,z,B,E,D;i--;){t=g[i];q=t.fe.a(c);s=t.ge.a(c);h=t.Vd.a(c);o=t.blur.a(c);t=t.color;u=-h-o;if(!e&&o)e=f.jb.Dc;u=this.ya({Jb:u,Ib:u,tb:u,Db:u},2,e);if(o){x=(h+o)*2+n;y=(h+o)*2+m;z=x?o*2/x:0;B=y?o*2/y:0;if(o-h>n/2||o-h>m/2)for(h=4;h--;){r=p[h];E=r.charAt(0)==="b";
+D=r.charAt(1)==="r";r=a(i,r,q,s,t,o,u);v=r.fill;v.focusposition=(D?1-z:z)+","+(E?1-B:B);v.focussize="0,0";r.style.clip="rect("+((E?y/2:0)+k)+"px,"+(D?x:x/2)+"px,"+(E?y:y/2)+"px,"+((D?x/2:0)+k)+"px)"}else{r=a(i,"",q,s,t,o,u);v=r.fill;v.focusposition=z+","+B;v.focussize=1-z*2+","+(1-B*2)}}else{r=a(i,"",q,s,t,o,u);q=t.fa();if(q<1)r.fill.opacity=q}}}});f.Pc=f.u.R({N:6,Ya:"imgEl",Q:function(){var a=this.g;return this.e.src!==this.Xc||a.G.H()},i:function(){var a=this.g;return a.G.i()||a.C.qc()},V:function(){this.Xc=
+j;this.Cd();var a=this.Aa("img","fill",this.I()),b=a.fill,c=this.s.o(),d=c.h;c=c.f;var e=this.g.w.j(),g=e&&e.J;e=this.e;var j=e.src,i=Math.round,h=e.currentStyle,k=f.n;if(!g||f.O<7){g=f.n("0");g={t:g,r:g,b:g,l:g}}a.stroked=false;b.type="frame";b.src=j;b.position=(d?0.5/d:0)+","+(c?0.5/c:0);a.coordsize=d*2+","+c*2;a.coordorigin="1,1";a.path=this.ya({Jb:i(g.t.a(e)+k(h.paddingTop).a(e)),Ib:i(g.r.a(e)+k(h.paddingRight).a(e)),tb:i(g.b.a(e)+k(h.paddingBottom).a(e)),Db:i(g.l.a(e)+k(h.paddingLeft).a(e))},
+2);a=a.style;a.width=d;a.height=c},Cd:function(){this.e.runtimeStyle.filter="alpha(opacity=0)"},m:function(){f.u.m.call(this);this.e.runtimeStyle.filter=""}});f.Oc=f.u.R({ib:f.aa,Mb:f.aa,Nb:f.aa,Lb:f.aa,Ld:/^,+|,+$/g,Fd:/,+/g,gb:function(a,b){(this.pb||(this.pb=[]))[a]=b||void 0},ab:function(){var a=this.pb,b;if(a&&(b=a.join(",").replace(this.Ld,"").replace(this.Fd,","))!==this.Wc)this.Wc=this.e.runtimeStyle.background=b},m:function(){this.e.runtimeStyle.background="";delete this.pb}});f.Mc=f.u.R({ua:1,
+Q:function(){return this.g.C.H()},i:function(){var a=this.g;return a.C.i()||a.q.i()},V:function(){var a=this.g.C.j(),b,c,d=0,e,g;if(a){b=[];if(c=a.M)for(;e=c[d++];)if(e.P==="linear-gradient"){g=this.vd(e.Wa);g=(e.Xa||f.Ka.Kc).a(this.e,g.h,g.f,g.h,g.f);b.push("url(data:image/svg+xml,"+escape(this.xd(e,g.h,g.f))+") "+this.dd(e.$)+" / "+g.h+"px "+g.f+"px "+(e.bc||"")+" "+(e.Wa||"")+" "+(e.ub||""))}else b.push(e.Hb);a.color&&b.push(a.color.Y);this.parent.gb(this.ua,b.join(","))}},dd:function(a){return a?
+a.X.map(function(b){return b.d}).join(" "):"0 0"},vd:function(a){var b=this.e,c=this.s.o(),d=c.h;c=c.f;var e;if(a!=="border-box")if((e=this.g.w.j())&&(e=e.J)){d-=e.l.a(b)+e.l.a(b);c-=e.t.a(b)+e.b.a(b)}if(a==="content-box"){a=f.n;e=b.currentStyle;d-=a(e.paddingLeft).a(b)+a(e.paddingRight).a(b);c-=a(e.paddingTop).a(b)+a(e.paddingBottom).a(b)}return{h:d,f:c}},xd:function(a,b,c){var d=this.e,e=a.ca,g=e.length,j=f.Na.gc(d,b,c,a);a=j.xc;var i=j.yc,h=j.td,k=j.ud;j=j.rc;var n,m,p,r,t;n=[];for(m=0;m<g;m++)n.push(e[m].db?
+e[m].db.a(d,j):m===0?0:m===g-1?j:null);for(m=1;m<g;m++)if(n[m]===null){r=n[m-1];p=m;do t=n[++p];while(t===null);n[m]=r+(t-r)/(p-m+1)}b=['<svg width="'+b+'" height="'+c+'" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="g" gradientUnits="userSpaceOnUse" x1="'+a/b*100+'%" y1="'+i/c*100+'%" x2="'+h/b*100+'%" y2="'+k/c*100+'%">'];for(m=0;m<g;m++)b.push('<stop offset="'+n[m]/j+'" stop-color="'+e[m].color.U(d)+'" stop-opacity="'+e[m].color.fa()+'"/>');b.push('</linearGradient></defs><rect width="100%" height="100%" fill="url(#g)"/></svg>');
+return b.join("")},m:function(){this.parent.gb(this.ua)}});f.Nc=f.u.R({T:"repeat",Sc:"stretch",Qc:"round",ua:0,Q:function(){return this.g.q.H()},i:function(){return this.g.q.i()},V:function(){var a=this,b=a.g.q.j(),c=a.g.w.j(),d=a.s.o(),e=b.repeat,g=e.f,j=e.Ob,i=a.e,h=0;f.p.Rb(b.src,function(k){function n(Q,R,U,V,W,Y,X,S,w,A){K.push('<pattern patternUnits="userSpaceOnUse" id="pattern'+G+'" x="'+(g===l?Q+U/2-w/2:Q)+'" y="'+(j===l?R+V/2-A/2:R)+'" width="'+w+'" height="'+A+'"><svg width="'+w+'" height="'+
+A+'" viewBox="'+W+" "+Y+" "+X+" "+S+'" preserveAspectRatio="none"><image xlink:href="'+v+'" x="0" y="0" width="'+r+'" height="'+t+'" /></svg></pattern>');J.push('<rect x="'+Q+'" y="'+R+'" width="'+U+'" height="'+V+'" fill="url(#pattern'+G+')" />');G++}var m=d.h,p=d.f,r=k.h,t=k.f,v=a.Dd(b.src,r,t),l=a.T,q=a.Sc;k=a.Qc;var s=Math.ceil,o=f.n("0"),u=b.J||(c?c.J:{t:o,r:o,b:o,l:o});o=u.t.a(i);var x=u.r.a(i),y=u.b.a(i);u=u.l.a(i);var z=b.slice,B=z.t.a(i),E=z.r.a(i),D=z.b.a(i);z=z.l.a(i);var C=m-u-x,F=p-o-
+y,O=r-z-E,H=t-B-D,M=g===q?C:O*o/B,P=j===q?F:H*x/E,I=g===q?C:O*y/D;q=j===q?F:H*u/z;var K=[],J=[],G=0;if(g===k){M-=(M-(C%M||M))/s(C/M);I-=(I-(C%I||I))/s(C/I)}if(j===k){P-=(P-(F%P||P))/s(F/P);q-=(q-(F%q||q))/s(F/q)}k=['<svg width="'+m+'" height="'+p+'" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">'];n(0,0,u,o,0,0,z,B,u,o);n(u,0,C,o,z,0,O,B,M,o);n(m-x,0,x,o,r-E,0,E,B,x,o);n(0,o,u,F,0,B,z,H,u,q);if(b.fill)n(u,o,C,F,z,B,O,H,M||I||O,q||P||H);n(m-x,o,x,F,r-E,B,E,H,x,P);n(0,
+p-y,u,y,0,t-D,z,D,u,y);n(u,p-y,C,y,z,t-D,O,D,I,y);n(m-x,p-y,x,y,r-E,t-D,E,D,x,y);k.push("<defs>"+K.join("\n")+"</defs>"+J.join("\n")+"</svg>");a.parent.gb(a.ua,"url(data:image/svg+xml,"+escape(k.join(""))+") no-repeat border-box border-box");h&&a.parent.ab()},a);h=1},Dd:function(){var a={};return function(b,c,d){var e=a[b],g;if(!e){e=new Image;g=doc.createElement("canvas");e.src=b;g.width=c;g.height=d;g.getContext("2d").drawImage(e,0,0);e=a[b]=g.toDataURL()}return e}}(),Ea:f.Tb.prototype.Ea,m:function(){var a=
+this.e.runtimeStyle;this.parent.gb(this.ua);a.borderColor=a.borderStyle=a.borderWidth=""}});f.kb=function(){function a(l,q){l.className+=" "+q}function b(l){var q=v.slice.call(arguments,1),s=q.length;setTimeout(function(){if(l)for(;s--;)a(l,q[s])},0)}function c(l){var q=v.slice.call(arguments,1),s=q.length;setTimeout(function(){if(l)for(;s--;){var o=q[s];o=t[o]||(t[o]=new RegExp("\\b"+o+"\\b","g"));l.className=l.className.replace(o,"")}},0)}function d(l){function q(){if(!U){var w,A,L=f.ja,T=l.currentStyle,
+N=T.getAttribute(g)==="true",da=T.getAttribute(i)!=="false",ea=T.getAttribute(h)!=="false";S=T.getAttribute(j);S=L>7?S!=="false":S==="true";if(!R){R=1;l.runtimeStyle.zoom=1;T=l;for(var fa=1;T=T.previousSibling;)if(T.nodeType===1){fa=0;break}fa&&a(l,p)}J.cb();if(N&&(A=J.o())&&(w=doc.documentElement||doc.body)&&(A.y>w.clientHeight||A.x>w.clientWidth||A.y+A.f<0||A.x+A.h<0)){if(!Y){Y=1;f.mb.ba(q)}}else{U=1;Y=R=0;f.mb.Ha(q);if(L===9){G={C:new f.Sb(l),q:new f.Ub(l),w:new f.Vb(l)};Q=[G.C,G.q];K=new f.Oc(l,
+J,G);w=[new f.Mc(l,J,G,K),new f.Nc(l,J,G,K)]}else{G={C:new f.Sb(l),w:new f.Vb(l),q:new f.Ub(l),G:new f.jb(l),ga:new f.Ic(l),Pb:new f.Uc(l)};Q=[G.C,G.w,G.q,G.G,G.ga,G.Pb];K=new f.Rc(l,J,G);w=[new f.Hc(l,J,G,K),new f.Fc(l,J,G,K),new f.Gc(l,J,G,K),new f.Tb(l,J,G,K)];l.tagName==="IMG"&&w.push(new f.Pc(l,J,G,K));K.ed=w}I=[K].concat(w);if(w=l.currentStyle.getAttribute(f.F+"watch-ancestors")){w=parseInt(w,10);A=0;for(N=l.parentNode;N&&(w==="NaN"||A++<w);){H(N,"onpropertychange",C);H(N,"onmouseenter",x);
+H(N,"onmouseleave",y);H(N,"onmousedown",z);if(N.tagName in f.fc){H(N,"onfocus",E);H(N,"onblur",D)}N=N.parentNode}}if(S){f.Oa.ba(o);f.Oa.Rd()}o(1)}if(!V){V=1;L<9&&H(l,"onmove",s);H(l,"onresize",s);H(l,"onpropertychange",u);ea&&H(l,"onmouseenter",x);if(ea||da)H(l,"onmouseleave",y);da&&H(l,"onmousedown",z);if(l.tagName in f.fc){H(l,"onfocus",E);H(l,"onblur",D)}f.Qa.ba(s);f.L.ba(M)}J.hb()}}function s(){J&&J.Ad()&&o()}function o(w){if(!X)if(U){var A,L=I.length;F();for(A=0;A<L;A++)I[A].Ea();if(w||J.Od())for(A=
+0;A<L;A++)I[A].ib();if(w||J.Td())for(A=0;A<L;A++)I[A].Mb();K.ab();O()}else R||q()}function u(){var w,A=I.length,L;w=event;if(!X&&!(w&&w.propertyName in r))if(U){F();for(w=0;w<A;w++)I[w].Ea();for(w=0;w<A;w++){L=I[w];L.Cb||L.ib();L.Q()&&L.Lb()}K.ab();O()}else R||q()}function x(){b(l,k)}function y(){c(l,k,n)}function z(){b(l,n);f.lb.ba(B)}function B(){c(l,n);f.lb.Ha(B)}function E(){b(l,m)}function D(){c(l,m)}function C(){var w=event.propertyName;if(w==="className"||w==="id")u()}function F(){J.cb();for(var w=
+Q.length;w--;)Q[w].cb()}function O(){for(var w=Q.length;w--;)Q[w].hb();J.hb()}function H(w,A,L){w.attachEvent(A,L);W.push([w,A,L])}function M(){if(V){for(var w=W.length,A;w--;){A=W[w];A[0].detachEvent(A[1],A[2])}f.L.Ha(M);V=0;W=[]}}function P(){if(!X){var w,A;M();X=1;if(I){w=0;for(A=I.length;w<A;w++){I[w].ec=1;I[w].m()}}S&&f.Oa.Ha(o);f.Qa.Ha(o);I=J=G=Q=l=null}}var I,K,J=new ha(l),G,Q,R,U,V,W=[],Y,X,S;this.Ed=q;this.update=o;this.m=P;this.qd=l}var e={},g=f.F+"lazy-init",j=f.F+"poll",i=f.F+"track-active",
+h=f.F+"track-hover",k=f.La+"hover",n=f.La+"active",m=f.La+"focus",p=f.La+"first-child",r={background:1,bgColor:1,display:1},t={},v=[];d.yd=function(l){var q=f.p.Ba(l);return e[q]||(e[q]=new d(l))};d.m=function(l){l=f.p.Ba(l);var q=e[l];if(q){q.m();delete e[l]}};d.md=function(){var l=[],q;if(e){for(var s in e)if(e.hasOwnProperty(s)){q=e[s];l.push(q.qd);q.m()}e={}}return l};return d}();f.supportsVML=f.zc;f.attach=function(a){f.ja<10&&f.zc&&f.kb.yd(a).Ed()};f.detach=function(a){f.kb.m(a)}};
+var $=element;function init(){if(doc.media!=="print"){var a=window.PIE;a&&a.attach($)}}function cleanup(){if(doc.media!=="print"){var a=window.PIE;if(a){a.detach($);$=0}}}$.readyState==="complete"&&init();
+</script>
+</PUBLIC:COMPONENT>
--- /dev/null
+@charset "utf-8";\r
+\r
+/** 基本設定 **/\r
+body {\r
+ margin: 0px;\r
+ padding: 0px;\r
+ background-color: #ffffff;\r
+ color: #1E4080;\r
+ font-size: 12px;\r
+ font-family: 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'メイリオ', Meiryo, 'MS Pゴシック', sans-serif;\r
+ line-height: 18px;\r
+ -webkit-text-size-adjust: 100%;\r
+}\r
+\r
+a img {\r
+ border-style: none;\r
+}\r
+\r
+/** メニュー部分 **/\r
+div.menu_wrapper {\r
+ display: table;\r
+ width: 100%;\r
+ background-color: #1E4080;\r
+ border-bottom: 1px solid #8888BE;\r
+ padding-bottom: 5px;\r
+ margin-bottom: 10px;\r
+ vertical-align: bottom;\r
+ padding-top: 5px;\r
+}\r
+div.menu {\r
+ width: 930px;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ display: table;\r
+}\r
+ul.menu {\r
+ display: block;\r
+ margin: 0px 0px 0px 0px;\r
+ padding: 0px 0px 0px 0px;\r
+ list-style: none;\r
+}\r
+li.menu_left {\r
+ display: inline;\r
+ float: left;\r
+ width: 138px;\r
+ border: 1px solid #8888BE;\r
+ text-align: center;\r
+ background-color: #ffffff;\r
+ padding: 10px 18px 10px 18px;\r
+ margin-right: 5px;\r
+ margin-left: 5px;\r
+ margin-top: 3px;\r
+ margin-bottom: 3px;\r
+ text-decoration: none;\r
+ border-radius: 8px;\r
+ behavior: url("./css/PIE.htc");\r
+}\r
+a.menu {\r
+ color: #1E4080;\r
+ text-decoration: none;\r
+}\r
+a:hover.menu {\r
+ color: #67A7CC;\r
+ text-decoration: none;\r
+}\r
+\r
+/** 見出し設定 **/\r
+h1 {\r
+ font-weight: bold;\r
+ font-size: 20px;\r
+ line-height: 26px;\r
+ margin-top: 0px;\r
+ margin-bottom: 20px;\r
+ border-bottom: 1px solid #A5A5BE;\r
+ text-align: left;\r
+ padding-top: 14px;\r
+ padding-bottom: 10px;\r
+ padding-left: 10px;\r
+}\r
+h2 {\r
+ font-weight: normal;\r
+ font-size: 16px;\r
+ line-height: 22px;\r
+ margin-top: 0px;\r
+ margin-bottom: 16px;\r
+}\r
+\r
+/** その他強調 **/\r
+.shadow {\r
+ box-shadow: 2px 4px 10px #666666;\r
+ behavior: url("./css/PIE.htc");\r
+}\r
+.red {\r
+ color: #ff0000;\r
+}\r
+.border_red {\r
+ border-color: #ff0000;\r
+}\r
+\r
+/** コンテンツ用DIV **/\r
+div.contents {\r
+ display: table;\r
+ width: 920px;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ margin-bottom: 20px;\r
+ border: 1px solid #A5A5BE;\r
+ box-shadow: 2px 4px 10px #cacaca;\r
+ background-color: #ffffff;\r
+ border-radius: 10px;\r
+ behavior: url("./css/PIE.htc");\r
+}\r
+div.middlemargin_bottom {\r
+ margin-bottom: 20px;\r
+}\r
+div.nomargin_bottom {\r
+ margin-bottom: 0px;\r
+}\r
+div.section_header {\r
+ display: table;\r
+ width: 920px;\r
+ height: 20px;\r
+ background-color: #000000;\r
+ background-repeat: no-repeat;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ margin-bottom: 30px;\r
+}\r
+div.wrapper {\r
+ width: 100%;\r
+ padding-top: 20px;\r
+ padding-bottom: 20px;\r
+ margin-bottom: 40px;\r
+}\r
+div.left {\r
+ text-align: left;\r
+}\r
+div.center {\r
+ text-align: center;\r
+}\r
+div.right {\r
+ text-align: right;\r
+}\r
+div.padding_normal {\r
+ padding: 5px 3px;\r
+}\r
+\r
+/** コンテンツ(小) **/\r
+div.small_contents {\r
+ display: table;\r
+ width: 600px;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ margin-bottom: 40px;\r
+ border: 1px solid #A5A5BE;\r
+ background-color: #ffffff;\r
+ box-shadow: 2px 4px 10px #cacaca;\r
+ border-radius: 10px;\r
+ behavior: url("./css/PIE.htc");\r
+}\r
+\r
+/** 選択中ファイル用 **/\r
+div.select_file {\r
+ display: table;\r
+ width: 920px;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ margin-bottom: 20px;\r
+ border: 1px solid #A5A5BE;\r
+ box-shadow: 2px 4px 5px #cacaca;\r
+ background-color: #ffffff;\r
+ border-radius: 10px;\r
+ behavior: url("./css/PIE.htc");\r
+ padding: 5px 0px;\r
+}\r
+\r
+/** インフォ・エラー用 **/\r
+div.info {\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ font-weight: bold;\r
+}\r
+div.info_contents {\r
+ color: #008822;\r
+ border: 1px solid #008822;\r
+}\r
+div.info_contens_inner {\r
+ margin-left: 20px;\r
+}\r
+h1.info {\r
+ color: #008822;\r
+ border-bottom: 1px solid #008822;\r
+}\r
+div.error {\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ font-weight: bold;\r
+ color: #ff0000;\r
+}\r
+div.error_contents {\r
+ color: #ff0000;\r
+ border: 1px solid #ff0000;\r
+}\r
+div.error_contens_inner {\r
+ margin-left: 20px;\r
+}\r
+h1.error {\r
+ color: #ff0000;\r
+ border-bottom: 1px solid #ff0000;\r
+}\r
+\r
+/** フッタ用部位 **/\r
+div.bottom_area {\r
+ display: table;\r
+ width: 920px;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ text-align: center;\r
+ padding-bottom: 40px;\r
+}\r
+\r
+/** デフォルトテーブル構成 **/\r
+table {\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+}\r
+\r
+th {\r
+ border: 1px solid #1E4080;\r
+ background-color: #1E4080;\r
+ color: #ffffff;\r
+}\r
+\r
+td {\r
+ border: 1px solid #1E4080;\r
+}\r
+\r
+td.small {\r
+ width: 350px;\r
+}\r
+\r
+th.small {\r
+ width: 200px;\r
+}\r
+\r
+td.normal {\r
+ width: 580px;\r
+}\r
+\r
+th.normal {\r
+ width: 300px;\r
+}\r
+\r
+td.large {\r
+ width: 680px;\r
+}\r
+\r
+th.large {\r
+ width: 530px;\r
+}\r
+\r
+td.maximum {\r
+ width: 880px;\r
+}\r
+\r
+th.maximum {\r
+ width: 880px;\r
+}\r
+\r
+td.padding_normal {\r
+ padding: 5px 3px;\r
+}\r
+\r
+th.padding_normal {\r
+ padding: 5px 3px;\r
+}\r
+\r
+td.default_word_break {\r
+ word-break: break-all;\r
+}\r
+\r
+td.hr {\r
+ height: 1px;\r
+ background-color: #ffffff;\r
+ border: none;\r
+}\r
+\r
+/** ファイルリスト一覧 **/\r
+table.filelist {\r
+ width: 96%;\r
+}\r
+\r
+th.filelist {\r
+ text-align: center;\r
+ vertical-align: middle;\r
+ color: #ffffff;\r
+ border: 1px solid #1E4080;\r
+ background-color: #1E4080;\r
+ padding: 4px;\r
+}\r
+\r
+td.filelist {\r
+ text-align: center;\r
+ vertical-align: middle;\r
+ border: 1px solid #1E4080;\r
+ padding: 4px;\r
+}\r
+\r
+div.filelist {\r
+ width: 95%;\r
+ margin-left: auto;\r
+ margin-right: auto;\r
+ padding: 5px;\r
+ border: 1px solid #A5A5BE;\r
+ box-shadow: 2px 4px 10px #cacaca;\r
+ background-color: #ffffff;\r
+ border-radius: 3px;\r
+ behavior: url("./css/PIE.htc");\r
+}\r
+\r
+/** 共通 **/\r
+.left {\r
+ text-align: left;\r
+}\r
+\r
+.center {\r
+ text-align: center;\r
+}\r
+\r
+.right {\r
+ text-align: right;\r
+}\r
+\r
+.top {\r
+ vertical-align: top;\r
+}\r
+\r
+.middle {\r
+ vertical-align: middle;\r
+}\r
+\r
+.bottom {\r
+ vertical-align: bottom;\r
+}\r
+\r
+/** インプット部品 **/\r
+input.border {\r
+ border: 1px solid #A0A0FF;\r
+}\r
+input.max_width {\r
+ width: 98%;\r
+}\r
+input.middle_width {\r
+ width: 250px;\r
+}\r
+textarea.border {\r
+ border: 1px solid #A0A0FF;\r
+}\r
+\r
+/** リンクタグ設定 **/\r
+a {\r
+ color: #67A7CC;\r
+}\r
+a:hover {\r
+ color: #A3D8F6;\r
+}\r
+a:visited {\r
+}\r
+a:active {\r
+}\r
+\r
+a.button {\r
+ color: #000000;\r
+ border: 1px solid #666666;\r
+ background-color: #ffffff;\r
+ padding: 16px 22px 15px 22px;\r
+ text-decoration: none;\r
+ border-radius: 10px;\r
+ box-shadow: 2px 4px 10px #cacaca;\r
+ behavior: url("./css/PIE.htc");\r
+}\r
+a:hover.button {\r
+ color: #ffffff;\r
+ border: 1px solid #000000;\r
+ background-color: #333333;\r
+}\r
+\r
+/** メディアクエリー用 **/\r
+div[name="for_pc"] {\r
+ display: table;\r
+}\r
+\r
+div[name="for_smartphone"] {\r
+ display: none;\r
+}\r
--- /dev/null
+/*\r
+html5doctor.com Reset Stylesheet\r
+v1.4\r
+2009-07-27\r
+Author: Richard Clark - http://richclarkdesign.com\r
+*/\r
+\r
+html, body, div, span, object, iframe,\r
+h1, h2, h3, h4, h5, h6, p, blockquote, pre,\r
+abbr, address, cite, code,\r
+del, dfn, em, img, ins, kbd, q, samp,\r
+small, strong, sub, sup, var,\r
+b, i,\r
+dl, dt, dd, ol, ul, li,\r
+fieldset, form, label, legend,\r
+table, caption, tbody, tfoot, thead, tr, th, td,\r
+article, aside, dialog, figure, footer, header,\r
+hgroup, menu, nav, section,\r
+time, mark, audio, video {\r
+ margin:0;\r
+ padding:0;\r
+ border:0;\r
+ outline:0;\r
+ font-size:100%;\r
+ vertical-align:baseline;\r
+ background:transparent;\r
+}\r
+body {\r
+ line-height:1;\r
+}\r
+\r
+article, aside, dialog, figure, footer, header,\r
+hgroup, nav, section {\r
+ display:block;\r
+}\r
+\r
+nav ul {\r
+ list-style:none;\r
+}\r
+\r
+blockquote, q {\r
+ quotes:none;\r
+}\r
+\r
+blockquote:before, blockquote:after,\r
+q:before, q:after {\r
+ content:'';\r
+ content:none;\r
+}\r
+\r
+a {\r
+ margin:0;\r
+ padding:0;\r
+ border:0;\r
+ font-size:100%;\r
+ vertical-align:baseline;\r
+ background:transparent;\r
+}\r
+\r
+ins {\r
+ background-color:#ff9;\r
+ color:#000;\r
+ text-decoration:none;\r
+}\r
+\r
+mark {\r
+ background-color:#ff9;\r
+ color:#000;\r
+ font-style:italic;\r
+ font-weight:bold;\r
+}\r
+\r
+del {\r
+ text-decoration: line-through;\r
+}\r
+\r
+abbr[title], dfn[title] {\r
+ border-bottom:1px dotted #000;\r
+ cursor:help;\r
+}\r
+\r
+table {\r
+ border-collapse:collapse;\r
+ border-spacing:0;\r
+}\r
+\r
+hr {\r
+ display:block;\r
+ height:1px;\r
+ border:0;\r
+ border-top:1px solid #cccccc;\r
+ margin:1em 0;\r
+ padding:0;\r
+}\r
+\r
+input, select {\r
+ vertical-align:middle;\r
+}\r
+\r
+html{\r
+ overflow-y:scroll;\r
+}\r
+\r
+html,body,#wrap {\r
+ height:100%;\r
+}\r
+\r
+body > #wrap{\r
+ height:auto;\r
+ min-height:100%;\r
+}\r
+\r
+body{\r
+ font-family:'Lucida Grande','Hiragino Kaku Gothic ProN',Meiryo, sans-serif;\r
+ line-height:1.8;\r
+ color:#333;\r
+ font-size:14px;\r
+}\r
+\r
+#wrap {\r
+ width: 100%;\r
+}\r
+\r
+/*======================================\r
+\r
+ 逕サ蜒上�險ュ螳\1a\r
+ \r
+=======================================*/\r
+img{\r
+ border-style:none;\r
+ vertical-align:bottom;\r
+}\r
+\r
+/*======================================\r
+\r
+ Clearfix縺ョ鬲疲ウ\1a\r
+ \r
+=======================================*/\r
+/* Clearfix */\r
+.clearfix:after {\r
+ content: " "; \r
+ display: block; \r
+ height: 0; \r
+ clear: both; \r
+ visibility: hidden;\r
+}\r
+.clearfix {\r
+ display: inline-block;\r
+ min-height: 1%;\r
+}\r
+/* Hides from IE-mac \*/\r
+\r
+* html .clearfix {\r
+ height: 1%;\r
+}\r
+.clearfix {\r
+ display: block;\r
+}\r
+/* End hide from IE-Mac */
\ No newline at end of file
--- /dev/null
+#!/usr/local/bin/ruby\r
+# -*- coding: utf-8 -*-\r
+#\r
+#= Atom Feed 1.0を管理するWEBアプリケーション\r
+#\r
+#Autohr:: Kureha Hisame (http://lunardial.sakura.ne.jp/) & Yui Naruse (http://airemix.com/)\r
+#Version:: 3.0.0.0\r
+#Copyright:: Copyright 2009 FeedBlog Project (http://sourceforge.jp/projects/feedblog/)\r
+#License:: GPLv3\r
+\r
+# ログイン情報配列\r
+LOGININFO = [\r
+ {:id => "login", :password => "password", :name => "テストユーザ"}\r
+]\r
+# インターフェースのテーブルの幅\r
+TABLEWIDTH = 1000\r
+# XMLファイル格納先までの相対パス\r
+XMLPATH = "./../lunardial/xml/"\r
+# FeedBlogを設置したディレクトリのURL\r
+HOMEBASE = "https://lunardial.sakura.ne.jp/"\r
+# 入力されたフルパスURL(HOMEBASE)を置換する文字列\r
+RELAYPATH = "./"\r
+# loglist.xmlファイルの定義\r
+LISTXMLPATH = "#{XMLPATH}loglist.xml"\r
+# FeedBlog上の表示ページからログ格納ディレクトリまでのパス\r
+FEEDXMLDIR = "./xml/"\r
+# デバッガモード\r
+DEBUG = false\r
+# ファイルマネージャー機能を使用するならtrue\r
+USEFILEMANAGER = true\r
+# ファイルマネージャー機能スクリプト(filemanager.rb)のパス\r
+FILEMANAGER = "./filemanager.rb"\r
+# XMLに書き込む際、改行部分を<br>のまま保持するか、改行記号に直すか\r
+REPLACEBRTAG = false\r
+# ファイルの書き込み時にENTRYのIDおよびURLを、FEEDオブジェクトから自動生成した値に置換するか否か\r
+REPLACEENTRYIDANDURL = false\r
+# プラグインディレクトリ\r
+PLUGINDIR = "./plugins/"\r
+# 記事用初期ファイル名\r
+INITIALXML = "diary.xml"\r
+\r
+# 画像フォルダの場所を定義\r
+IMGPATH = "./../lunardial/xml/img/"\r
+# アップロード可能な最大ファイルサイズ\r
+UPLOADLIMIT = 2 * 1024 * 1024\r
+\r
+# ログディレクトリ\r
+LOG_DIR = "./logs/"\r
+# 開発用ログを出力するか?\r
+LOG_RELEASE_MODE = false\r
+\r
+# バージョン情報を示す文字列です\r
+APPVERSION = "- FeedGenerator for Ruby version 4.0.0.0 -<br>Copyright(c) 2009 Kureha.H (<a href=\"http://lunardial.sakura.ne.jp/\" target=\"_blank\">http://lunardial.sakura.ne.jp/</a>) & Yui Naruse (<a href=\"http://airemix.com/\" target=\"_blank\">http://airemix.com/</a>)"\r
+# タイトル領域に表示される文字列です\r
+APPTITLE = "FeedGenerator for Ruby version 4.0.0.0"\r
+\r
+\r
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <script type="text/javascript">
- function switchsubmit(form, action){
- document.getElementsByName("action").item(0).value = action;
- form.submit();
- }
- </script>
- </head>
- <body>
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST">
- <input type="hidden" name="target_filepath" value="<%= session["target_filepath"] %>"><% case params["action"]
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ </head>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <div class="contents">
+ <h1>記事削除</h1>
+ <input type="hidden" name="target_filepath" value="<%= session["target_filepath"] %>"><% case params["action"]
when "confirm" %>
<input type="hidden" name="delid" value="<%= session["delid"] %>">
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ ■ 次の記事を削除します。よろしいですか?
+ <br>
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 以下の内容の記事を削除します。よろしいですか?
- </td>
- </tr>
<% db.transaction do
entry = db["delentry"]
entry.paramlist.each do |val| %>
<tr style="display: <%= entry.display[val] %>;">
- <td class="formnavi" style="width: 140px;">
+ <th class="small middle padding_normal">
<%= entry.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large middle padding_normal">
<% if val != "content" %><%= entry.send(val) %><% else %><%= entry.content_for_view %><% end %>
</td>
</tr>
+ <tr style="display: <%= entry.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
<% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="delentry"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')"><% when "exec" %>
- <table align="center" style="width: <%= TABLEWIDTH %>px">
- <tbody>
- <tr>
- <td class="forminput" style="text-align: center;">
- 記事の削除が完了しました。
- </td>
- </tr>
- </tbody>
- </table>
+ <div class="center">
+ <input type="hidden" name="mode" value="delentry"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')">
+ </div>
<br>
- <a href="<%= cgi.script_name %>">メニューに戻る</a>
<% else %>
<% db.transaction do %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
<tr>
- <td class="formheader" colspan="3">
- ■ 削除する記事を選択してください。
- </td>
- </tr>
- <tr>
- <td class="formheader">
+ <td class="center" style="width: 50px;">
</td>
- <td class="formheader" style="text-align: center;">
+ <th class="large center padding_normal">
記事のタイトル
- </td>
- <td class="formheader" style="text-align: center;">
+ </th>
+ <th class="small center padding_normal">
最終更新時間
- </td>
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
<% db["entry"].each_with_index do |entry, i| %>
<tr>
- <td class="forminput" style="width: 30px; text-align: center;">
+ <td class="center padding_normal">
<% if params["action"] == "back" and session["delid"] == entry.entryid %>
<input type="radio" name="delid" value="<%= entry.send("entryid") %>" checked="checked"><% else %>
<input type="radio" name="delid" value="<%= entry.send("entryid") %>"><% end %>
</td>
- <td class="forminput">
+ <td class="left padding_normal default_word_break">
<%= entry.send("title") %>
</td>
- <td class="forminput" style="width: 150px; text-align: center;">
+ <td class="center padding_normal">
<%= entry.send("published").gsub("+09:00", "").gsub("T", " ") %>
</td>
</tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
<% end %>
</tbody>
</table>
<br>
<% if db["entry"].length != 0 %>
- <input type="hidden" name="mode" value="delentry"><input type="hidden" name="action" value="confirm"><input type="submit" value="確認"><% else %>
- 削除対象となる記事が存在しません。
+ <div class="center">
+ <input type="hidden" name="mode" value="delentry"><input type="hidden" name="action" value="confirm"><input type="submit" value="確認">
+ </div>
+ <br>
+ <% else %>
+ <div class="center">
+ 削除対象となる記事が存在しません。
+ </div>
<br>
<br>
<% end %>
<% end %>
<% end %>
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <% unless cgi.user_agent =~ /(iPod|iPhone|iPad|Android)/ %>
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ <% unless cgi.user_agent =~ /(iPod|iPhone|iPad|Android)/ %>
<link rel="stylesheet" type="text/css" href="./yui/build/menu/assets/skins/sam/menu.css" />
<link rel="stylesheet" type="text/css" href="./yui/build/button/assets/skins/sam/button.css" />
<link rel="stylesheet" type="text/css" href="./yui/build/fonts/fonts-min.css" />
margin: 0;
padding: 0;
}
+
+ body {
+ font-family: 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'メイリオ', Meiryo, 'MS Pゴシック', sans-serif;
+ font-size: 12px;
+ line-height: 18px;
+ }
</style>
<% end %>
- </head>
- <body class="yui-skin-sam">
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST">
- <input type="hidden" name="target_filepath" value="<%= session["target_filepath"] %>"><% case params["action"]
+ </head>
+ <body class="yui-skin-sam">
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <div class="contents">
+ <h1>記事編集</h1>
+ <input type="hidden" name="target_filepath" value="<%= session["target_filepath"] %>"><% case params["action"]
when "confirm" %>
<input type="hidden" name="editid" value="<%= session["editid"] %>">
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 入力内容を確認してください
- </td>
- </tr>
<% db.transaction do
entry = db["editentry"]
entry.paramlist.each do |val| %>
<tr style="display: <%= entry.display[val] %>;">
- <td class="formnavi" style="width: 140px;">
+ <th class="small middle padding_normal">
<%= entry.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large middle padding_normal">
<input type="hidden" name="<%= val %>" value="<%= entry.send(val) %>"><% if val != "content" %><%= entry.send(val) %><% else %><%= entry.content_for_view %><% end %>
</td>
- </tr><% end %>
+ </tr>
+ <tr style="display: <%= entry.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="editentry"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')"><% when "exec" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px">
- <tbody>
- <tr>
- <td class="forminput" style="text-align: center;">
- 記事の編集が完了しました。
- </td>
- </tr>
- </tbody>
- </table>
+ <div class="center">
+ <input type="hidden" name="mode" value="editentry"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')">
+ </div>
<br>
- <a href="<%= cgi.script_name %>">メニューに戻る</a>
<% when "edit" %>
<input type="hidden" name="editid" value="<%= session["editid"] %>">
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 記事編集
- <br>
- </td>
- </tr>
<% db.transaction do
entry = db["editentry"]
entry.paramlist.each do |val| %>
<tr style="display: <%= entry.display[val] %>;">
- <td class="formnavi" style="width: 140px;">
+ <th class="small middle padding_normal">
<%= entry.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large middle padding_normal center">
<% if val == "content" %>
- <textarea name="<%= val %>" rows="10" style="width: 100%" id="contenteditor"><%= entry.content_for_generator %></textarea>
+ <textarea name="<%= val %>" rows="10" class="max_width" id="contenteditor"><%= entry.content_for_generator %></textarea>
<% elsif val == "updated" %>
- <input type="text" name="<%= val %>" value="<%= Time.now.iso8601 %>" style="width: 100%;"><% else %>
- <input type="text" name="<%= val %>" value="<%= entry.send(val) %>" style="width: 100%;"><% end %>
+ <input type="text" name="<%= val %>" value="<%= Time.now.iso8601 %>" class="max_width"><% else %>
+ <input type="text" name="<%= val %>" value="<%= entry.send(val) %>" class="max_width"><% end %>
</td>
- </tr><% end %>
+ </tr>
+ <tr style="display: <%= entry.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="editentry"><input type="hidden" name="action" value="confirm"><input type="submit" value="確認"><% when "back" %>
+ <div class="center">
+ <input type="hidden" name="mode" value="editentry"><input type="hidden" name="action" value="confirm"><input type="submit" value="確認">
+ </div>
+ <br>
+ <% when "back" %>
<input type="hidden" name="editid" value="<%= session["editid"] %>">
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 記事内容
- <br>
- </td>
- </tr>
<% db.transaction do
entry = db["editentry"]
entry.paramlist.each do |val| %>
<tr style="display: <%= entry.display[val] %>;">
- <td class="formnavi" style="width: 140px;">
+ <th class="small middle padding_normal">
<%= entry.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large middle padding_normal center">
<% if val == "content" %>
- <textarea name="<%= val %>" rows="10" style="width: 100%" id="contenteditor"><%= entry.content_for_generator %></textarea>
+ <textarea name="<%= val %>" rows="10" class="max_width" id="contenteditor"><%= entry.content_for_generator %></textarea>
<% else %>
- <input type="text" name="<%= val %>" value="<%= entry.send(val) %>" style="width: 100%;"><% end %>
+ <input type="text" name="<%= val %>" value="<%= entry.send(val) %>" class="max_width"><% end %>
</td>
- </tr><% end %>
+ </tr>
+ <tr style="display: <%= entry.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="editentry"><input type="hidden" name="action" value="confirm"><input type="submit" class="wymupdate" value="確認"><% else %>
+ <div class="center">
+ <input type="hidden" name="mode" value="editentry"><input type="hidden" name="action" value="confirm"><input type="submit" class="wymupdate" value="確認">
+ </div>
+ <br>
+ <% else %>
<% db.transaction do %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
<tr>
- <td class="formheader" colspan="3">
- ■ 編集する記事を選択してください。
- </td>
- </tr>
- <tr>
- <td class="formheader">
+ <td class="center" style="width: 50px;">
</td>
- <td class="formheader" style="text-align: center;">
+ <th class="large center padding_normal">
記事のタイトル
- </td>
- <td class="formheader" style="text-align: center;">
+ </th>
+ <th class="small center padding_normal">
最終更新時間
- </td>
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
<% db["entry"].each_with_index do |entry, i| %>
<tr>
- <td class="forminput" style="width: 30px; text-align: center;">
+ <td class="center padding_normal">
<input type="radio" name="editid" value="<%= entry.send("entryid") %>">
</td>
- <td class="forminput">
+ <td class="left padding_normal default_word_break">
<%= entry.send("title") %>
</td>
- <td class="forminput" style="width: 150px; text-align: center;">
+ <td class="center padding_normal">
<%= entry.send("published").gsub("+09:00", "").gsub("T", " ") %>
</td>
</tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
<% end %>
</tbody>
</table>
<br>
<% if db["entry"].length != 0 %>
- <input type="hidden" name="mode" value="editentry"><input type="hidden" name="action" value="edit"><input type="submit" value="編集"><% else %>
- 編集対象となる記事が存在しません。
+ <div class="center">
+ <input type="hidden" name="mode" value="editentry"><input type="hidden" name="action" value="edit"><input type="submit" value="編集">
+ </div>
+ <br>
+ <% else %>
+ <div class="center">
+ 編集対象となる記事が存在しません。
+ </div>
<br>
<br>
<% end %>
<% end %>
<% end %>
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <script type="text/javascript">
- function switchsubmit(form, action){
- document.getElementsByName("action").item(0).value = action;
- form.submit();
- }
-
- function autocomp_feedid(){
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ <script>
+ function autocomp_feedid(){
document.getElementsByName("feedid").item(0).value = document.getElementsByName("url").item(0).value;
}
</script>
- </head>
- <body>
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST">
- <input type="hidden" name="target_filepath" value="<%= session["target_filepath"] %>">
+ </head>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <div class="contents">
+ <h1>基本情報編集</h1>
+ <input type="hidden" name="target_filepath" value="<%= session["target_filepath"] %>">
<% case params["action"]
when "confirm" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 入力内容を確認してください
- </td>
- </tr>
<% db.transaction do
feed = db["feed"]
feed.paramlist.each do |val| %>
<tr style="display: <%= feed.display[val] %>;">
- <td class="formnavi" style="width: 200px;">
+ <th class="small middle padding_normal">
<%= feed.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large left padding_normal">
<%= feed.send(val) %>
<input type="hidden" name="<%= val %>" value="<%= feed.send(val) %>">
</td>
- </tr><% end %>
+ </tr>
+ <tr style="display: <%= feed.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="editfeed"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')"><% when "exec" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td class="forminput" style="text-align: center;">
- 記事の情報を更新しました。
- </td>
- </tr>
- </tbody>
- </table>
+ <div class="center">
+ <input type="hidden" name="mode" value="editfeed"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')">
+ </div>
<br>
- <a href="<%= cgi.script_name %>">メニューに戻る</a>
<% else %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ XML情報編集
- <br>
- </td>
- </tr>
<% db.transaction do
feed = db["feed"]
feed.paramlist.each do |val| %>
<tr style="display: <%= feed.display[val] %>;">
- <td class="formnavi" style="width: 200px;">
+ <th class="small middle padding_normal">
<%= feed.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large middle padding_normal center">
<% date = Time.now.iso8601 %>
<% if val == "updated" %>
- <input type="text" name="<%= val %>" value="<%= date %>" style="width: 100%"><% elsif val == "url" %>
- <input type="text" name="<%= val %>" value="<%= feed.send(val) %>" style="width: 100%" onchange="autocomp_feedid();"><% elsif val == "feedid" %>
- <input type="text" name="<%= val %>" value="<%= feed.send(val) %>" style="width: 100%">
+ <input type="text" name="<%= val %>" value="<%= date %>" class="max_width"><% elsif val == "url" %>
+ <input type="text" name="<%= val %>" value="<%= feed.send(val) %>" class="max_width" onchange="autocomp_feedid();"><% elsif val == "feedid" %>
+ <input type="text" name="<%= val %>" value="<%= feed.send(val) %>" class="max_width">
<br>
- <span style="font-style: italic;">é\80\9a常ã\82¦ã\82§ã\83\96ã\83\9aã\83¼ã\82¸ã\81®idã\81¯ã\81\82ã\81ªã\81\9fã\81®ã\82¦ã\82§ã\83\96ã\83\9aã\83¼ã\82¸URLã\81¨å\90\8cä¸\80ã\81®ã\82\82ã\81®ã\82\92使ç\94¨ã\81\97ã\81¦ã\81\8fã\81 ã\81\95ã\81\84。</span>
+ <span style="font-style: italic;">é\80\9a常ã\80\81ã\82¦ã\82§ã\83\96ã\83\9aã\83¼ã\82¸ã\81®IDæ\83\85å ±ã\81¯ã\80\81ã\81\82ã\81ªã\81\9fã\81®ã\82¦ã\82§ã\83\96ã\83\9aã\83¼ã\82¸URLã\81¨å\90\8cä¸\80ã\81®ã\82\82ã\81®ã\82\92使ç\94¨ã\81\99ã\82\8bã\81\93ã\81¨ã\82\92æ\8e¨å¥¨ã\81\97ã\81¾ã\81\99。</span>
<% else %>
- <input type="text" name="<%= val %>" value="<%= feed.send(val) %>" style="width: 100%"><% end %>
+ <input type="text" name="<%= val %>" value="<%= feed.send(val) %>" class="max_width"><% end %>
</td>
- </tr><% end %>
+ </tr>
+ <tr style="display: <%= feed.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="editfeed"><input type="hidden" name="action" value="confirm"><input type="submit" value="確認"><% end %>
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ <div class="center">
+ <input type="hidden" name="mode" value="editfeed"><input type="hidden" name="action" value="confirm"><input type="submit" value="確認">
+ </div>
+ <br>
+ <% end %>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- </head>
- <body>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <table align="center">
- <tbody>
- <tr>
- <td style="width: <%= (TABLEWIDTH - 20) %>px;" class="formnavi">
- ■ エラーが発生しました!
- <br>
- </td>
- </tr>
- <tr>
- <td class="forminput">
- ▼ エラー詳細 :
- <br>
- <table>
- <tbody>
- <tr>
- <td style="color: #ff0000; width: <%= (TABLEWIDTH - 30) %>px;" class="forminput">
- <% db.transaction do %>
- <%= db["error"] %>
- <% end %>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- <div style="text-align: center; width: 100%;">
- [ <a href="<%= cgi.script_name %>?mode=logout">ログアウトする</a>
- ]
- </div>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <title><%= APPTITLE %></title>
+ <link rel="stylesheet" href="./css/reset.css" type="text/css"/>
+ <link rel="stylesheet" href="./css/base.css" type="text/css"/>
+ </head>
+ <body>
+ <br>
+ <br>
+ <div class="small_contents center">
+ <h1>エラーが発生しました。</h1>
+ <%= session["error"] %>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </body>
</html>
+
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- </head>
- <body>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <table align="center">
- <tbody>
- <tr>
- <td style="width: <%= (TABLEWIDTH - 20) %>px;" class="formnavi">
- ■ エラーが発生しました!アプリケーションの設定を見直してください。
- <br>
- </td>
- </tr>
- <tr>
- <td class="forminput">
- ▼ エラー詳細 :
- <br>
- <table>
- <tbody>
- <tr>
- <td style="color: #ff0000; width: <%= (TABLEWIDTH - 30) %>px;" class="forminput">
- <%= CGI.escapeHTML(exception.to_s).gsub("\n", "<br>") %>
- </td>
- </tr>
- </tbody>
- </table>
- ▼ バックトレース :
- <br>
- <table>
- <tbody>
- <tr>
- <td style="color: #ff0000; width: <%= (TABLEWIDTH - 30) %>px;" class="forminput">
- <% exception.backtrace.each do |val| %>
- <%= CGI.escapeHTML(val.to_s) + "<br>" %>
- <% end %>
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- <div style="text-align: center; width: 100%;">
- [ <a href="<%= cgi.script_name %>?mode=logout">ログアウトする</a>
- ]
- </div>
- <br>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <title><%= APPTITLE %></title>
+ <link rel="stylesheet" href="./css/reset.css" type="text/css"/>
+ <link rel="stylesheet" href="./css/base.css" type="text/css"/>
+ </head>
+ <body>
+ <br>
+ <br>
+ <div class="small_contents left">
+ <h1>エラーが発生しました。</h1>
+ ■ エラー詳細 :
+ <br>
+ <%= CGI.escapeHTML(exception.to_s).gsub("\n", "<br>") %>
+ <br>
+ <br>
+ ■ バックトレース :
+ <br>
+ <% exception.backtrace.each do |val| %>
+ <%= CGI.escapeHTML(val.to_s) + "<br>" %>
+ <% end %>
+ <br>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css"/>
- </head>
- <body>
- <br>
- <br>
- <div class="divstyle" style="width: 400px; padding: 15px;">
- FileManager for Ruby
- <br>
- <br>
- 認証されていません。FeedGenerator for Rubyから起動してください。
- <br>
- <br>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ <head>
+ <%= htmlparts["headtag"] %>
+ </head>
+ <body>
+ <br>
+ <br>
+ <div class="small_contents center">
+ <form action="<%= cgi.script_name %>" method="POST">
+ <br>
+ <%= APPTITLE %>
+ <br>
+ <br>
+ ユーザ認証されていません。
+ <br>
+ <br>
+ </form>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <script type="text/javascript">
- function switchsubmit(form, action, arg){
- document.getElementsByName("action").item(0).value = action;
- document.getElementsByName("arg").item(0).value = arg;
- document.getElementById(form).submit();
- }
-
- function checkall(formid, flag){
- var form = document.getElementById(formid);
- for (i = 0; i < form.length; i++) {
- if (form.elements[i].type == "checkbox") {
- form.elements[i].checked = flag;
- }
- }
- }
- </script>
- </head>
- <body>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form id="fileform" action="<%= cgi.script_name %>" method="POST" enctype="multipart/form-data">
- <% unless session["info"] == "" %>
- <div class="divstyle" align="center" style="margin-bottom: 4px;">
- <%= session["info"] %>
- </div>
- <% end %>
- <% unless session["error"] == "" %>
- <div class="divstyle" align="center" style="color: #ff0000; margin-bottom: 4px;">
- <%= session["error"] %>
- </div>
- <% end %>
- <div class="divstyle" align="center">
- アップロードするファイルを選択してください。 (アップロード上限サイズ : <%= (UPLOADLIMIT / 1024 / 1024 ) %>MB)
- </div>
- <br>
- <table align="center">
- <tbody>
- <tr>
- <td>
- </td>
- <td>
- <input type="file" name="updata">
- </td>
- </tr>
- <tr>
- <td colspan="2" style="text-align: center;">
- <input type="button" value="アップロード" onclick="javascript:switchsubmit('fileform', 'upload', '')">
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- <div class="divstyle" align="center">
- 現在のディレクトリ : <span style="font-weight: bold;">/<a href="javascript:switchsubmit('fileform', 'cd_abs', '0')">root</a>/<% session["relpath_list"].split("/").each_with_index { |rp, i| %><a href="javascript:switchsubmit('fileform', 'cd_abs', '<%= (i + 1) %>')"><%= rp %></a>/<% } %></span> [<a href="javascript:switchsubmit('fileform', 'refresh', '')">更新</a>]
- </div>
- <br>
- <input type="text" name="dirname"> <input type="button" value="フォルダ作成" onclick="javascript:switchsubmit('fileform', 'mkdir', '')">
- <br>
- <br>
- <input type="button" value="全選択" onclick="checkall('fileform', true)"> <input type="button" value="全解除" onclick="checkall('fileform', false)"> <input type="button" value="マークしたファイルを削除" onclick="javascript:switchsubmit('fileform', 'delete', '')">
- <br>
- <br>
- <table align="center" style="width: 90%">
- <tbody>
- <tr>
- <td class="formnavi" style="text-align: center; padding: 2px;">
- 削除
- </td>
- <td class="formnavi" style="text-align: center; padding: 2px;">
- ファイル名
- </td>
- <td class="formnavi" style="text-align: center; padding: 2px;">
- ファイルタイプ
- </td>
- <td class="formnavi" style="text-align: center; padding: 2px;">
- ファイルサイズ
- </td>
- <td class="formnavi" style="text-align: center; padding: 2px;">
- 最終更新時間
- </td>
- </tr>
- <% unless IMGPATH == session["pwd"] %>
- <tr>
- <td class="formnavi" style="text-align: center; padding: 2px;">
-
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- <span style="font-weight: bold;">[ <a href="javascript:switchsubmit('fileform', 'cd', '..')">Parent Directory</a> ]</span>
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- -
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- -
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- -
- </td>
- </tr>
- <% end %>
- <% session["filelist"].each do |fname| %>
- <% if session["fileinfo"][fname][:ftype] == "directory" %>
- <tr>
- <td class="formnavi" style="text-align: center; padding: 2px;">
- <input type="checkbox" name="filename_<%= fname %>" value="delete">
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- <span style="font-weight: bold;">[ <a href="javascript:switchsubmit('fileform', 'cd', '<%= fname %>')"><%= fname %></a> ]</span>
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- <%= session["fileinfo"][fname][:ftype] %>
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- -
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- <%= session["fileinfo"][fname][:ctime].strftime("%Y年%m月%d日 %H時%M分%S秒") %>
- </td>
- </tr>
- <% end %>
- <% end %>
- <% session["filelist"].each do |fname| %>
- <% if session["fileinfo"][fname][:ftype] == "file" %>
- <tr>
- <td class="formnavi" style="text-align: center; padding: 2px;">
- <input type="checkbox" name="filename_<%= fname %>" value="delete">
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- <a href="<%= session["pwd"] %><%= fname %>" target="_blank"><%= fname %></a>
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- <%= session["fileinfo"][fname][:ftype] %>
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- <%= session["fileinfo"][fname][:size] %>KB
- </td>
- <td class="forminput" style="text-align: center; padding: 2px;">
- <%= session["fileinfo"][fname][:ctime].strftime("%Y年%m月%d日 %H時%M分%S秒") %>
- </td>
- </tr>
- <% end %>
- <% end %>
- </tbody>
- </table>
- <br>
- <input type="hidden" name="relpath_list" value="<%= session["relpath_list"] %>"><input type="hidden" name="mode" value="file"><input type="hidden" name="action" value=""><input type="hidden" name="arg" value="">
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <title><%= APPTITLE %></title>
+ <link rel="stylesheet" href="./css/reset.css" type="text/css"/>
+ <link rel="stylesheet" href="./css/base.css" type="text/css"/>
+ <script type="text/javascript" src="./js/jquery-1.6.1.min.js"></script>
+ <script type="text/javascript">
+ function switchsubmit(form, action, arg) {
+ $("*[name=action]").val(action);
+ $("*[name=arg]").val(arg);
+ $("#" + form).submit();
+ }
+
+ function sortchange(sort_type) {
+ var now_sort_type = $("#sort_type").val();
+ var now_sort_reverse = $("#sort_reverse").val();
+
+ if (sort_type == now_sort_type) {
+ if (now_sort_reverse == "true") {
+ $("#sort_reverse").val("false");
+ } else {
+ $("#sort_reverse").val("true");
+ }
+ } else {
+ $("#sort_type").val(sort_type);
+ $("#sort_reverse").val("false");
+ }
+
+ switchsubmit('fileform', 'refresh', '');
+ }
+
+ function checkall(formid, flag) {
+ var form = document.getElementById(formid);
+ for ( i = 0; i < form.length; i++) {
+ if (form.elements[i].type == "checkbox") {
+ form.elements[i].checked = flag;
+ }
+ }
+ }
+
+ function autoRename() {
+ $("#file_rename").val(+new Date())
+ }
+
+ function addExtension(ext) {
+ $("#file_rename").val($("#file_rename").val() + '.' + ext)
+ }
+ </script>
+ </head>
+ <body>
+ <form id="fileform" action="<%= cgi.script_name %>" method="POST" enctype="multipart/form-data">
+ <div class="menu_wrapper">
+ <div class="menu">
+ <ul class="menu">
+ <li class="menu_left">
+ <a href="#file_upload" class="menu">ファイルアップロード</a>
+ </li>
+ <li class="menu_left">
+ <a href="#file_manage" class="menu">ファイル操作</a>
+ </li>
+ <li class="menu_left">
+ <a href="#" class="menu" onclick="javascript: window.close();">ウインドウを閉じる</a>
+ </li>
+ </ul>
+ </div>
+ </div>
+ <% unless session["info"] == "" %>
+ <div class="contents info_contents">
+ <h1 class="info">以下の操作を実施しました</h1>
+ <div class="info_contens_inner">
+ <%= session["info"] %>
+ </div>
+ <br>
+ </div>
+ <% end %>
+ <% unless session["error"] == "" %>
+ <div class="contents error_contents">
+ <h1 class="error">エラーが発生しました</h1>
+ <div class="error_contens_inner">
+ <%= session["error"] %>
+ </div>
+ <br>
+ </div>
+ <% end %>
+ <div class="contents">
+ <h1>
+ <a name="file_upload">ファイルアップロード</a>
+ </h1>
+ アップロードするファイルを選択してください。 (アップロード上限サイズ : <%= (UPLOADLIMIT / 1024 / 1024 ) %>MB)
+ <br>
+ <br>
+ <table>
+ <tr>
+ <th class="normal middle"> ファイルアップロード </th>
+ <td class="padding_normal normal left">
+ <input type="file" name="updata">
+ <br>
+ <input type="checkbox" name="thumbs" id="thumbs" value="true" checked="checked">
+ <label for="thumbs">サムネイル自動生成(拡張子jpg,pngのファイルのみ有効)</label></td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="normal middle">(オプション)アップロード後のファイル名を指定</th>
+ <td class="padding_normal normal left">
+ <input type="text" id="file_rename" name="file_rename" class="middle_width border">
+
+ <input type="button" value="ファイル名自動生成" onclick="javascript: autoRename();">
+
+ <input type="button" value=".jpg" onclick="javascript: addExtension('jpg')">
+
+ <input type="button" value=".png" onclick="javascript: addExtension('png')">
+ <br>
+ ファイル名は拡張子を含めて指定して下さい。 </td>
+ </tr>
+ </table>
+ <br>
+ <div class="center">
+ <input type="button" value="アップロード" onclick="javascript:switchsubmit('fileform', 'upload', '')">
+ </div>
+ <br>
+ </div>
+ <div class="contents">
+ <h1><a name="file_manage">ファイル操作</a></h1>
+ <table>
+ <tr>
+ <th class="normal middle">フォルダ作成</th>
+ <td class="padding_normal normal left">
+ <input type="text" name="dirname" class="middle_width border"> <input type="button" value="フォルダ作成" onclick="javascript:switchsubmit('fileform', 'mkdir', '')">
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="normal middle">ファイル・フォルダリネーム</th>
+ <td class="padding_normal normal left">
+ <input type="text" name="destname" class="middle_width border"> <input type="button" value="リネーム実施" onclick="javascript:switchsubmit('fileform', 'move', '')">
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="normal middle">ファイル・フォルダ削除</th>
+ <td class="padding_normal normal left">
+ <input type="button" value="削除実施" onclick="javascript:switchsubmit('fileform', 'delete', '')">
+ <br>
+ ファイル一覧から削除したいファイル・フォルダを選択した後「削除実施」ボタンを押して下さい。
+ <br>
+ (※ フォルダは中身が空ではない場合、削除が実施できません)
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ </table>
+ <br>
+ <br>
+ <div class="filelist center">
+ 現在の表示中のディレクトリ : <span style="font-weight: bold;">/<a href="javascript:switchsubmit('fileform', 'cd_abs', '0')">root</a>/<% session["relpath_list"].split("/").each_with_index { |rp, i| %><a href="javascript:switchsubmit('fileform', 'cd_abs', '<%= (i + 1) %>')"><%= rp %></a>/<% } %></span> [<a href="javascript:switchsubmit('fileform', 'refresh', '')">更新</a>]
+ </div>
+ <br>
+ <table class="filelist">
+ <tbody>
+ <tr>
+ <th class="filelist">
+ 選択
+ </th>
+ <th class="filelist">
+ <a href="javascript:sortchange('name')"><% if session["sort_type"] == "name" %><strong><% if session["sort_reverse"] == "true" %>▲ <% else %>▼ <% end %><% end %>ファイル名<% if session["sort_type"] == "name" %></strong><% end %></a>
+ </th>
+ <th class="filelist">
+ <a href="javascript:sortchange('ftype')"><% if session["sort_type"] == "ftype" %><strong><% if session["sort_reverse"] == "true" %>▲ <% else %>▼ <% end %><% end %>ファイルタイプ<% if session["sort_type"] == "ftype" %></strong><% end %></a>
+ </th>
+ <th class="filelist">
+ <a href="javascript:sortchange('size')"><% if session["sort_type"] == "size" %><strong><% if session["sort_reverse"] == "true" %>▲ <% else %>▼ <% end %><% end %>ファイルサイズ<% if session["sort_type"] == "size" %></strong><% end %></a>
+ </th>
+ <th class="filelist">
+ <a href="javascript:sortchange('mtime')"><% if session["sort_type"] == "mtime" %><strong><% if session["sort_reverse"] == "true" %>▲ <% else %>▼ <% end %><% end %>最終更新時間<% if session["sort_type"] == "mtime" %></strong><% end %></a>
+ </th>
+ </tr>
+ <% unless IMGPATH == session["pwd"] %>
+ <tr>
+ <td class="filelist">
+
+ </td>
+ <td class="filelist">
+ <span style="font-weight: bold;">[ <a href="javascript:switchsubmit('fileform', 'cd', '..')">Parent Directory</a> ]</span>
+ </td>
+ <td class="filelist">
+ -
+ </td>
+ <td class="filelist">
+ -
+ </td>
+ <td class="filelist">
+ -
+ </td>
+ </tr>
+ <% end %>
+ <% session["filelist"].each do |fname| %>
+ <% if session["fileinfo"][fname][:ftype] == "directory" %>
+ <tr>
+ <td class="filelist">
+ <input type="checkbox" name="filename_<%= fname %>" value="true">
+ </td>
+ <td class="filelist">
+ <span style="font-weight: bold;">[ <a href="javascript:switchsubmit('fileform', 'cd', '<%= fname %>')"><%= fname %></a> ]</span>
+ </td>
+ <td class="filelist">
+ <%= session["fileinfo"][fname][:ftype] %>
+ </td>
+ <td class="filelist">
+ -
+ </td>
+ <td class="filelist">
+ <%= session["fileinfo"][fname][:mtime].strftime("%Y年%m月%d日 %H時%M分%S秒") %>
+ </td>
+ </tr>
+ <% end %>
+ <% if session["fileinfo"][fname][:ftype] == "file" %>
+ <tr>
+ <td class="filelist">
+ <input type="checkbox" name="filename_<%= fname %>" value="true">
+ </td>
+ <td class="filelist">
+ <a href="<%= session["pwd"] %><%= fname %>" target="_blank"><%= fname %></a>
+ </td>
+ <td class="filelist">
+ <%= session["fileinfo"][fname][:ftype] %>
+ </td>
+ <td class="filelist">
+ <%= session["fileinfo"][fname][:size] %>KB
+ </td>
+ <td class="filelist">
+ <%= session["fileinfo"][fname][:mtime].strftime("%Y年%m月%d日 %H時%M分%S秒") %>
+ </td>
+ </tr>
+ <% end %>
+ <% end %>
+ </tbody>
+ </table>
+ <div>
+ <input type="button" value="全て選択" onclick="checkall('fileform', true)"> <input type="button" value="全て解除" onclick="checkall('fileform', false)">
+ </div>
+ <br>
+ <br>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ <input type="hidden" name="relpath_list" value="<%= session["relpath_list"] %>">
+ <input type="hidden" name="mode" value="file">
+ <input type="hidden" name="action" value="">
+ <input type="hidden" name="arg" value="">
+ <input type="hidden" id="sort_type" name="sort_type" value="<%= session["sort_type"] %>">
+ <input type="hidden" id="sort_reverse" name="sort_reverse" value="<%= session["sort_reverse"] %>">
+ </form>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- </head>
- <body>
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <table align="center">
- <tbody>
- <tr>
- <td class="formheader" style="width: <%= (TABLEWIDTH - 20) %>px;">
- ■ 機能一覧
- </td>
- </tr>
- <tr>
- <td style="text-align: left;" class="forminput">
- ■ 現在編集中のファイル - 記事モードで編集可能なXMLファイル名を表示します
- <br>
- + [ <a href="<%= cgi.script_name %>?mode=selectlog">他のファイルを選択</a>
- ] - 記事モードで編集するXMLファイルを選択します
- </td>
- </tr>
- <tr>
- <td style="text-align: left;" class="forminput">
- ■ 記事管理
- <br>
- + [ <a href="<%= cgi.script_name %>?mode=newentry">作成</a>
- ] - 新規に記事を作成します
- <br>
- + [ <a href="<%= cgi.script_name %>?mode=editentry">編集</a>
- ] - 既に存在する記事を編集します
- <br>
- + [ <a href="<%= cgi.script_name %>?mode=delentry">削除</a>
- ] - 既に存在する記事を削除します
- <br>
- </td>
- </tr>
- <tr>
- <td style="text-align: left;" class="forminput">
- ■ <a href="<%= cgi.script_name %>?mode=editfeed">XML情報編集</a>
- - XML本体に付加する情報を編集します
- </td>
- </tr>
- <tr>
- <td style="text-align: left;" class="forminput">
- ■ <a href="<%= cgi.script_name %>?mode=log">ログ管理</a>
- <br>
- + [ 作成 ] - 最新のXMLファイルに付加する情報だけを残し、記事を全て過去ログとして名前をつけて保存します
- <br>
- + [ 編集 ] - 既に存在するログの情報・ファイル名・順序を編集します
- <br>
- + [ 削除 ] - 既に存在するログの削除を行います
- <br>
- </td>
- </tr>
- <tr>
- <td style="text-align: left;" class="forminput">
- ■ <a href="<%= cgi.script_name %>?mode=import">インポート</a>
- - 既存のFeed XMLファイルを取り込みます
- </td>
- </tr>
- <% if USEFILEMANAGER == true %>
- <tr>
- <td style="text-align: left;" class="forminput">
- ■ <a href="<%= FILEMANAGER %>" target="_blank">ファイルマネージャ</a>
- - 記事に使用する画像ファイル等のアップロード、削除が可能です
- </td>
- </tr>
- <% end %>
- <tr>
- <td style="text-align: left;" class="forminput">
- ■ <a href="<%= cgi.script_name %>?mode=reset">初期化</a>
- - 現存する全てのログを初期化し、空のdiary.xml及びloglist.xmlのみを再配置します。
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ <head>
+ <%= htmlparts["headtag"] %>
+ </head>
+ <body>
+ <br>
+ <br>
+ <div class="small_contents center">
+ <form action="<%= cgi.script_name %>" method="POST">
+ <br>
+ <%= APPTITLE %>
+ <br>
+ <br>
+ <table>
+ <tr>
+ <th class="small padding_normal"> ユーザID </th>
+ <td class="small padding_normal">
+ <input type="text" name="loginid" value="<%= params["loginid"] %>" class="max_width border">
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="small padding_normal"> パスワード </th>
+ <td class="small padding_normal">
+ <input type="password" name="password" value="<%= params["password"] %>" class="max_width border">
+ </td>
+ </tr>
+ </table>
+ <br>
+ <input type="submit" value="ログインを実行する">
+ <br>
+ <% unless session["error"] == "" %>
+ <br>
+ <div class="error">
+ <%= session["error"] %>
+ </div>
+ <% end %>
+ <br>
+ </form>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <script type="text/javascript">
- function switchsubmit(form, action){
- document.getElementsByName("action").item(0).value = action;
- form.submit();
- }
- </script>
- </head>
- <body>
- <% db.transaction do %>
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <table align="center" style="width: <%= TABLEWIDTH - 20 %>px">
- <tbody>
- <tr>
- <td class="formheader">
- ■ インポート機能
- </td>
- </tr>
- <tr>
- <td class="forminput">
- <span style="font-weight: bold;">[ 注意! ]</span>
- <br>
- インポート処理を行った後は、必ずFeedGeneratorのトップページに戻るか、一度ログアウトの後ログインしてから作業を再開してください。インポートデータが破壊される可能性があります。
- </td>
- </tr>
- <tr>
- <td class="forminput">
- ■ 既存のFeed XMLファイルを読み込む
- <br>
- + [ <a href="<%= cgi.script_name %>?mode=insert">挿入モード</a>
- ] - インポートデータをログファイルとして追加します。
- <br>
- + [ <a href="<%= cgi.script_name %>?mode=replace">置換モード</a>
- ] - インポートデータをdiary.xmlとして置き換えます。既存のdiary.xmlはログファイルとして保存します。
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- <% end %>
- </body>
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ </head>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <div class="contents">
+ <h1>ファイルインポート</h1>
+ <span style="font-weight: bold;">[ 注意! ]</span>
+ <br>
+ インポート処理を行った後は、必ずトップページに戻るか、一度ログアウト→ログインしてから作業を再開してください。
+ <br>
+ インポートデータが破壊される可能性があります。
+ <br>
+ <br>
+ ■ 既存のFeed XMLファイルを読み込む
+ <br>
+ + [ <a href="<%= cgi.script_name %>?mode=insert">挿入モード</a>] - インポートデータをログファイルとして追加します。
+ <br>
+ + [ <a href="<%= cgi.script_name %>?mode=replace">置換モード</a>] - インポートデータをdiary.xmlとして置き換えます。既存のdiary.xmlはログファイルとして保存します。
+ <br>
+ <br>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <script type="text/javascript">
- function switchsubmit(form, action){
- document.getElementsByName("action").item(0).value = action;
- form.submit();
- }
- </script>
- </head>
- <body>
- <% db.transaction do %>
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST" enctype="multipart/form-data">
- <% case params["action"]
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ </head>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST" enctype="multipart/form-data">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <% db.transaction do %>
+ <div class="contents">
+ <h1>ファイルインポート</h1>
+ <% case params["action"]
when "confirm" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ ■ 赤色の位置にログを挿入します
+ <br>
+ <br>
+ <table>
<tbody>
- <tr>
- <td class="formheader" colspan="3">
- ■ 赤色の位置にログを挿入します
- </td>
- </tr>
- <tr>
- <td colspan="" style="text-align: center;" class="formnavi">
+ <tr>
+ <th class="large center padding_normal">
ログファイルのパス
- </td>
- <td style="text-align: center;" class="formnavi">
+ </th>
+ <th class="small center padding_normal">
ログの表示名
- </td>
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
<% written = false %>
<% db["loglist"].path.each_with_index do |log, i| %>
<% if i == db["loginsertindex"] %>
<tr>
- <td style="text-align: center;" class="forminputhilight">
+ <td class="center padding_normal red border_red">
<%= db["logpath"] %>
<input type="hidden" name="logpath" value="<%= db["logpath"] %>">
</td>
- <td style="text-align: center;" class="forminputhilight">
+ <td class="center padding_normal red border_red">
<%= db["logdisplay"] %>
<input type="hidden" name="logdisplay" value="<%= db["logdisplay"] %>">
</td>
- </tr><% written = true %>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% written = true %>
<% end %>
<tr>
- <td style="text-align: center;" class="forminput">
+ <td class="center padding_normal">
<%= log %>
</td>
- <td style="text-align: center;" class="forminput">
+ <td class="center padding_normal">
<%= db["loglist"].display[i] %>
</td>
</tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
<% end %>
<% if written == false %>
<tr>
- <td style="text-align: center;" class="forminputhilight">
+ <td class="center padding_normal red border_red">
<%= db["logpath"] %>
<input type="hidden" name="logpath" value="<%= db["logpath"] %>">
</td>
- <td style="text-align: center;" class="forminputhilight">
+ <td class="center padding_normal red border_red">
<%= db["logdisplay"] %>
<input type="hidden" name="logdisplay" value="<%= db["logdisplay"] %>">
</td>
- </tr><% end %>
- </tbody>
- </table>
- <br>
- <input type="hidden" name="loginsertindex" value="<%= db["loginsertindex"] %>"><input type="hidden" name="mode" value="insert"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, '')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')"><% when "exec" %>
- <table align="center" style="width: <%= TABLEWIDTH %>px">
- <tbody>
+ </tr>
<tr>
- <td class="forminput" style="text-align: center;">
- インポート処理が完了しました。
- </td>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
+ <% end %>
</tbody>
</table>
<br>
- <a href="<%= cgi.script_name %>">トップページに戻る</a>
+ <div class="center">
+ <input type="hidden" name="loginsertindex" value="<%= db["loginsertindex"] %>"><input type="hidden" name="mode" value="insert"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, '')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')">
+ </div>
+ <br>
+ <br>
<% else %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ ■ 指定されたログの後にインポートされたファイルを挿入します
+ <br>
+ <br>
+ <table>
<tbody>
<tr>
- <td class="formheader" colspan="3">
- ■ 指定されたログの後にインポートされたファイルを挿入します
- </td>
- </tr>
- <tr>
- <td class="formnavi" style="width: 30px;">
+ <td class="center" style="width: 50px;">
</td>
- <td colspan="" style="text-align: center;" class="formnavi">
+ <th class="normal center padding_normal">
ログファイルのパス
- </td>
- <td style="text-align: center;" class="formnavi">
+ </th>
+ <th class="normal center padding_normal">
ログの表示名
- </td>
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
<% index = 1 %>
<% db["loglist"].path.each_with_index do |log, i| %>
<tr>
- <td style="text-align: center; width: 30px;" class="forminput">
+ <td class="center padding_normal">
<% if index == 1 %>
<input type="radio" name="loginsertindex" value="<%= index %>" checked="checked"><% else %>
<input type="radio" name="loginsertindex" value="<%= index %>"><% end %>
</td>
- <td style="text-align: center;" class="forminput">
+ <td class="center padding_normal">
<%= log %>
</td>
- <td style="text-align: center;" class="forminput">
+ <td class="center padding_normal">
<%= db["loglist"].display[i] %>
</td>
</tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
<% index = index + 1 %>
<% end %>
</tbody>
</table>
<br>
- <table align="center" style="width: 600px;">
+ <table>
<tbody>
<tr>
- <td class="formnavi" style="width: 200px;">
+ <th class="small middle padding_normal">
インポートファイル
- </td>
- <td class="forminput">
- <input type="file" name="updata" style="width: 100%;">
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="file" name="updata" class="max_width">
</td>
</tr>
<tr>
- <td class="formnavi" style="width: 200px;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="small middle padding_normal">
インポート後のファイルパス
- </td>
- <td class="forminput">
- <input type="text" name="logpath" style="width: 100%;">
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="text" name="logpath" class="max_width">
</td>
</tr>
<tr>
- <td class="formnavi">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="small middle padding_normal">
ファイルのインポート表示名
- </td>
- <td class="forminput">
- <input type="text" name="logdisplay" style="width: 100%;">
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="text" name="logdisplay" class="max_width">
</td>
</tr>
</tbody>
- </table><%= db["error"] %>
+ </table>
+ <br>
+ <div class="center">
+ <input type="hidden" name="mode" value="insert"><input type="hidden" name="action" value=""><input type="button" value="確認" onclick="switchsubmit(this.form, 'confirm')">
+ </div>
<br>
- <input type="hidden" name="mode" value="insert"><input type="hidden" name="action" value=""><input type="button" value="確認" onclick="switchsubmit(this.form, 'confirm')">
<br>
<% end %>
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- <% end %>
- </body>
+ </div>
+ <% end %>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <script type="text/javascript">
- function switchsubmit(form, action){
- document.getElementsByName("action").item(0).value = action;
- form.submit();
- }
- </script>
- </head>
- <body>
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST">
- <% case params["action"] when "addconfirm" %>
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ </head>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <div class="contents">
+ <h1>ログ管理</h1>
+ <% case params["action"] when "addconfirm" %>
<% db.transaction do %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ ■ 赤枠の位置に現在の記事をログとして保存します
+ <br>
+ <br>
+ <table>
<tbody>
<tr>
- <td colspan="2" class="formheader">
- ■ 赤枠の位置に現在の記事をログとして保存します
+ <th class="normal center padding_normal">
+ ログファイルのパス
+ </th>
+ <th class="normal center padding_normal">
+ ログの表示名
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% db["loglist"].path.each_with_index do |log, i| %>
+ <tr>
+ <td class="center padding_normal">
+ <%= log %>
+ </td>
+ <td class="center padding_normal">
+ <%= db["loglist"].display[i] %>
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% if i == 0 %>
+ <tr>
+ <td class="center padding_normal red border_red">
+ <%= db["logpath"] %>
+ <input type="hidden" name="logpath" value="<%= db["logpath"] %>">
+ </td>
+ <td class="center padding_normal red border_red">
+ <%= db["logdisplay"] %>
+ <input type="hidden" name="logdisplay" value="<%= db["logdisplay"] %>">
</td>
</tr>
<tr>
- <td style="width: 306px; text-align: center;" class="formnavi">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
+ <% end %>
+ <% end %>
+ </tbody>
+ </table>
+ <br>
+ <div class="center">
+ <input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'addexec')">
+ </div>
+ <br>
+ <br>
+ <% when "delconfirm" %>
+ <% db.transaction do %>
+ <input type="hidden" name="logdelindex" value="<%= db["logdelindex"] %>">
+ ■ 赤枠の位置のログを削除します。よろしいですか?
+ <br>
+ <br>
+ <table>
+ <tbody>
+ <tr>
+ <th class="normal center padding_normal">
ログファイルのパス
+ </th>
+ <th class="normal center padding_normal">
+ ログの表示名
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% db["loglist"].path.each_with_index do |log, i| %>
+ <% if db["logdelindex"] != i %>
+ <tr>
+ <td class="center padding_normal">
+ <%= log %>
+ </td>
+ <td class="center padding_normal">
+ <%= db["loglist"].display[i] %>
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% else %>
+ <tr>
+ <td class="center padding_normal red border_red">
+ <%= log %>
+ </td>
+ <td class="center padding_normal red border_red">
+ <%= db["loglist"].display[i] %>
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
+ <% end %>
+ <% end %>
+ </tbody>
+ </table>
+ <br>
+ <div class="center">
+ <input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'delexec')">
+ </div>
+ <br>
+ <br>
+ <% when "edit" %>
+ <% db.transaction do %>
+ ■ ログファイル管理
+ <br>
+ 赤枠のログを入力された名前で、チェックされたログの後に挿入します。
+ <br>
+ <br>
+ <table>
+ <tbody>
+ <tr>
+ <td class="center" style="width: 50px;">
+
+ </td>
+ <th class="normal center padding_normal">
+ ログファイルのパス
+ </th>
+ <th class="normal center padding_normal">
+ ログの表示名
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% editcounter = 0 %>
+ <% db["loglist"].path.each_with_index do |log, i| %>
+ <% if db["logeditindex"] != i %>
+ <tr>
+ <td class="center padding_normal">
+ <% if db["logeditindex"] == (i + 1) %>
+ <input type="radio" name="loginsertindex" value="<%= editcounter %>" checked="checked"><% else %>
+ <input type="radio" name="loginsertindex" value="<%= editcounter %>"><% end %>
+ </td>
+ <td class="center padding_normal">
+ <%= log %>
+ </td>
+ <td class="center padding_normal">
+ <%= db["loglist"].display[i] %>
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% editcounter = editcounter + 1 %>
+ <% else %>
+ <tr>
+ <td class="center padding_normal red border_red">
+
+ </td>
+ <td class="center padding_normal red border_red">
+ <%= log %>
+ </td>
+ <td class="center padding_normal red border_red">
+ <%= db["loglist"].display[i] %>
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
+ <% end %>
+ </tbody>
+ </table>
+ <br>
+ <br>
+ ■ <%= db["logpath"] %>の新しい情報を入力してください
+ <br>
+ <br>
+ <table>
+ <tbody>
+ <tr>
+ <th class="small middle padding_normal">
+ ログのパス
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="text" name="logpath" class="max_width" value="<%= db["logpath"] %>">
</td>
- <td style="text-align: center;" class="formnavi">
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="small middle padding_normal">
ログの表示名
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="text" name="logdisplay" class="max_width" value="<%= db["logdisplay"] %>">
</td>
</tr>
+ </tbody>
+ </table>
+ <br>
+ <div class="center">
+ <input type="hidden" name="logeditindex" value="<%= db["logeditindex"] %>"><input type="hidden" name="logdelindex" value="<%= db["logeditindex"] %>"><input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確認" onclick="switchsubmit(this.form, 'editconfirm')">
+ </div>
+ <br>
+ <br>
+ <% end %>
+ <% when "editconfirm" %>
+ <% db.transaction do %>
+ ■ 確認
+ <br>
+ 以下のように変更を適用します。よろしいですか?
+ <br>
+ <br>
+ <table>
+ <tbody>
+ <tr>
+ <th class="normal center padding_normal">
+ ログファイルのパス
+ </th>
+ <th class="normal center padding_normal">
+ ログの表示名
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% editcounter = 0 %>
<% db["loglist"].path.each_with_index do |log, i| %>
+ <% if db["logeditindex"] != i %>
<tr>
- <td style="text-align: center;" class="forminput">
+ <td class="center padding_normal">
<%= log %>
</td>
- <td style="text-align: center;" class="forminput">
+ <td class="center padding_normal">
<%= db["loglist"].display[i] %>
</td>
</tr>
- <% if i == 0 %>
<tr>
- <td style="text-align: center;" class="forminputhilight">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% if editcounter == db["loginsertindex"] %>
+ <tr>
+ <td class="center padding_normal red border_red">
<%= db["logpath"] %>
<input type="hidden" name="logpath" value="<%= db["logpath"] %>">
</td>
- <td style="text-align: center;" class="forminputhilight">
+ <td class="center padding_normal red border_red">
<%= db["logdisplay"] %>
<input type="hidden" name="logdisplay" value="<%= db["logdisplay"] %>">
</td>
- </tr><% end %>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
+ <% editcounter = editcounter + 1 %>
<% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'addexec')"><% when "addexec" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <br>
+ <div class="center">
+ <input type="hidden" name="logdelindex" value="<%= db["logeditindex"] %>"><input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'edit')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'editexec')">
+ </div>
+ <br>
+ <br>
+ <% end %>
+ <% else %>
+ <% db.transaction do %>
+ ■ ログファイル管理
+ <br>
+ 現在の<%= db["loglist"].path[0] %>をログとして保存します。その後loglist.xmlを変更します。
+ <br>
+ <br>
+ <table>
<tbody>
<tr>
- <td class="forminput" style="text-align: center;">
- ログファイルの作成が完了しました。
+ <td class="center" style="width: 50px;">
+
+ </td>
+ <th class="large center padding_normal">
+ ログファイルのパス
+ </th>
+ <th class="small center padding_normal">
+ ログの表示名
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% db["loglist"].path.each_with_index do |log, i| %>
+ <tr>
+ <td class="center padding_normal">
+ <% if i != 0 %>
+ <input type="radio" name="logdelindex" value="<%= i %>"><% else %> <% end %>
+ </td>
+ <td class="left padding_normal">
+ <%= log %>
+ </td>
+ <td class="center padding_normal">
+ <%= db["loglist"].display[i] %>
</td>
</tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
</tbody>
</table>
<br>
- <a href="<%= cgi.script_name %>">メニューに戻る</a>
- <% when "delconfirm" %>
- <div class="divstyle" align="center">
- <% db.transaction do %>
- <input type="hidden" name="logdelindex" value="<%= db["logdelindex"] %>">
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 赤枠の位置のログを削除します。よろしいですか?
- </td>
- </tr>
- <tr>
- <td style="width: 306px; text-align: center;" class="formnavi">
- ログファイルのパス
- </td>
- <td style="text-align: center;" class="formnavi">
- ログの表示名
- </td>
- </tr>
- <% db["loglist"].path.each_with_index do |log, i| %>
- <% if db["logdelindex"] != i %>
- <tr>
- <td style="text-align: center;" class="forminput">
- <%= log %>
- </td>
- <td style="text-align: center;" class="forminput">
- <%= db["loglist"].display[i] %>
- </td>
- </tr>
- <% else %>
- <tr>
- <td style="text-align: center;" class="forminputhilight">
- <%= log %>
- </td>
- <td style="text-align: center;" class="forminputhilight">
- <%= db["loglist"].display[i] %>
- </td>
- </tr>
- <% end %>
- <% end %>
- <% end %>
- </tbody>
- </table>
- <br>
- <input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'delexec')"><% when "delexec" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td class="forminput" style="text-align: center;">
- ログファイルの削除が完了しました。
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- <a href="<%= cgi.script_name %>">メニューに戻る</a>
- <% when "edit" %>
- <% db.transaction do %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td colspan="3" class="formheader">
- ■ ログファイル管理
- <br>
- 赤枠のログを入力された名前で、チェックされたログの後に挿入します。
- <br>
- </td>
- </tr>
- <tr>
- <td class="formnavi">
-
- </td>
- <td style="text-align: center;" class="formnavi">
- ログファイルのパス
- </td>
- <td style="text-align: center;" class="formnavi">
- ログの表示名
- </td>
- </tr>
- <% editcounter = 0 %>
- <% db["loglist"].path.each_with_index do |log, i| %>
- <% if db["logeditindex"] != i %>
- <tr>
- <td style="text-align: center; width: 30px;" class="forminput">
- <% if db["logeditindex"] == (i + 1) %>
- <input type="radio" name="loginsertindex" value="<%= editcounter %>" checked="checked"><% else %>
- <input type="radio" name="loginsertindex" value="<%= editcounter %>"><% end %>
- </td>
- <td style="text-align: center;" class="forminput">
- <%= log %>
- </td>
- <td style="text-align: center;" class="forminput">
- <%= db["loglist"].display[i] %>
- </td>
- </tr>
- <% editcounter = editcounter + 1 %>
- <% else %>
- <tr>
- <td style="text-align: center; width: 30px;" class="forminputhilight">
-
- </td>
- <td style="text-align: center;" class="forminputhilight">
- <%= log %>
- </td>
- <td style="text-align: center;" class="forminputhilight">
- <%= db["loglist"].display[i] %>
- </td>
- </tr>
- <% end %>
- <% end %>
- </tbody>
- </table>
- <br>
- <table align="center">
- <tbody>
- <tr>
- <td colspan="2" class="forminput">
- ■ <%= db["logpath"] %>の新しい情報を入力してください
- </td>
- <tr>
- <td style="text-align: right;">
- ログのパス
- </td>
- <td>
- <input type="text" name="logpath" style="width: 100%" value="<%= db["logpath"] %>">
- </td>
- </tr>
- <tr>
- <td style="text-align: right;">
- ログの表示名
- </td>
- <td>
- <input type="text" name="logdisplay" style="width: 100%" value="<%= db["logdisplay"] %>">
- </td>
- </tr>
- </tbody>
- </table><%= db["error"] %>
- <br>
- <input type="hidden" name="logeditindex" value="<%= db["logeditindex"] %>"><input type="hidden" name="logdelindex" value="<%= db["logeditindex"] %>"><input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確認" onclick="switchsubmit(this.form, 'editconfirm')"><% end %>
- <% when "editconfirm" %>
- <% db.transaction do %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td colspan="3" class="formheader">
- ■ 確認
- <br>
- 以下のように変更を適用します。よろしいですか?
- <br>
- </td>
- </tr>
- <tr>
- <td style="text-align: center;" class="formnavi">
- ログファイルのパス
- </td>
- <td style="text-align: center;" class="formnavi">
- ログの表示名
- </td>
- </tr>
- <% editcounter = 0 %>
- <% db["loglist"].path.each_with_index do |log, i| %>
- <% if db["logeditindex"] != i %>
- <tr>
- <td style="text-align: center;" class="forminput">
- <%= log %>
- </td>
- <td style="text-align: center;" class="forminput">
- <%= db["loglist"].display[i] %>
- </td>
- </tr>
- <% if editcounter == db["loginsertindex"] %>
- <tr>
- <td style="text-align: center;" class="forminputhilight">
- <%= db["logpath"] %>
- <input type="hidden" name="logpath" value="<%= db["logpath"] %>">
- </td>
- <td style="text-align: center;" class="forminputhilight">
- <%= db["logdisplay"] %>
- <input type="hidden" name="logdisplay" value="<%= db["logdisplay"] %>">
- </td>
- </tr><% end %>
- <% editcounter = editcounter + 1 %>
- <% end %>
- <% end %>
- </tbody>
- </table>
- <br>
- <br>
- <input type="hidden" name="logdelindex" value="<%= db["logeditindex"] %>"><input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'edit')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'editexec')"><% end %>
- <% when "editexec" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td class="forminput" style="text-align: center;">
- ログファイルの編集が完了しました。
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- <a href="<%= cgi.script_name %>">メニューに戻る</a>
- <% else %>
- <% db.transaction do %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td colspan="3" class="formheader">
- ■ ログファイル管理
- <br>
- (現在の<%= db["loglist"].path[0] %>をログとして保存します。その後loglist.xmlを変更します。)
- <br>
- </td>
- </tr>
- <tr>
- <td class="formnavi">
-
- </td>
- <td colspan="" style="text-align: center;" class="formnavi">
- ログファイルのパス
- </td>
- <td style="text-align: center;" class="formnavi">
- ログの表示名
- </td>
- </tr>
- <% db["loglist"].path.each_with_index do |log, i| %>
- <tr>
- <td style="text-align: center; width: 30px;" class="forminput">
- <% if i != 0 %>
- <input type="radio" name="logdelindex" value="<%= i %>"><% else %> <% end %>
- </td>
- <td style="text-align: center;" class="forminput">
- <%= log %>
- </td>
- <td style="text-align: center;" class="forminput">
- <%= db["loglist"].display[i] %>
- </td>
- </tr>
- <% end %>
- </tbody>
- </table>
- <br>
- <input type="button" value="編集" onclick="switchsubmit(this.form, 'edit')"> <input type="button" value="削除" onclick="switchsubmit(this.form, 'delconfirm')">
- <br>
- <br>
- <table align="center">
- <tbody>
- <tr>
- <td colspan="2" class="forminput">
- ■ 現在のdiary.xmlを保存する情報を設定してください
- </td>
- <tr>
- <td style="text-align: right;">
- ログのパス
- </td>
- <td>
- <input type="text" name="logpath" style="width: 100%" value="<%= db["logpath"] %>">
- </td>
- </tr>
- <tr>
- <td style="text-align: right;">
- ログの表示名
- </td>
- <td>
- <input type="text" name="logdisplay" style="width: 100%" value="<%= db["logdisplay"] %>">
- </td>
- </tr>
- </tbody>
- </table><%= db["error"] %>
- <br>
- <input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="確定" onclick="switchsubmit(this.form, 'addconfirm')"><% end %>
- <% end %>
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
- </html>
+ <div class="center">
+ <input type="button" value="編集" onclick="switchsubmit(this.form, 'edit')"> <input type="button" value="削除" onclick="switchsubmit(this.form, 'delconfirm')">
+ </div>
+ <br>
+ ■ 現在のdiary.xmlを保存する為の情報を入力してください
+ <br>
+ <br>
+ <table>
+ <tbody>
+ <tr>
+ <th class="small middle padding_normal">
+ ログのパス
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="text" name="logpath" class="max_width" value="<%= db["logpath"] %>">
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="small middle padding_normal">
+ ログの表示名
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="text" name="logdisplay" class="max_width" value="<%= db["logdisplay"] %>">
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <br>
+ <div class="center">
+ <input type="hidden" name="mode" value="log"><input type="hidden" name="action" value=""><input type="button" value="確定" onclick="switchsubmit(this.form, 'addconfirm')">
+ </div>
+ <br>
+ <br>
+ <% end %>
+ <% end %>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
+</html>
--- /dev/null
+<!DOCTYPE html>
+<html>
+ <head>
+ <%= htmlparts["headtag"] %>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <div class="contents">
+ <h1>
+ <a name="#">メニュー</a>
+ </h1>
+ <table>
+ <tr>
+ <th class="maximum left padding_normal">
+ ■ 機能一覧
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <td class="maximum padding_normal">
+ ■ 現在編集中のファイル - 記事モードで編集可能なXMLファイル名を表示します
+ <br>
+ + [ <a href="<%= cgi.script_name %>?mode=selectlog">他のファイルを選択</a>
+ ] - 記事モードで編集するXMLファイルを選択します
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <td class="maximum padding_normal">
+ ■ 記事管理
+ <br>
+ + [ <a href="<%= cgi.script_name %>?mode=newentry">作成</a>
+ ] - 新規に記事を作成します
+ <br>
+ + [ <a href="<%= cgi.script_name %>?mode=editentry">編集</a>
+ ] - 既に存在する記事を編集します
+ <br>
+ + [ <a href="<%= cgi.script_name %>?mode=delentry">削除</a>
+ ] - 既に存在する記事を削除します
+ <br>
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <td class="maximum padding_normal">
+ ■ <a href="<%= cgi.script_name %>?mode=editfeed">基本情報編集</a>
+ - XML本体に付加する基本情報を編集します
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <td class="maximum padding_normal">
+ ■ <a href="<%= cgi.script_name %>?mode=log">ログ管理</a>
+ <br>
+ + [ 作成 ] - 最新のXMLファイルに付加する情報だけを残し、記事を全て過去ログとして名前をつけて保存します
+ <br>
+ + [ 編集 ] - 既に存在するログの情報・ファイル名・順序を編集します
+ <br>
+ + [ 削除 ] - 既に存在するログの削除を行います
+ <br>
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <td class="maximum padding_normal">
+ ■ <a href="<%= cgi.script_name %>?mode=import">インポート</a>
+ - 既存のFeed XMLファイルを取り込みます
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ </tr>
+ <% if USEFILEMANAGER == true %>
+ <tr>
+ <td class="maximum padding_normal">
+ ■ <a href="<%= FILEMANAGER %>" target="_blank">ファイルマネージャ</a>
+ - 記事に使用する画像ファイル等のアップロード、削除が可能です
+ </td>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
+ <tr>
+ <td class="maximum padding_normal">
+ ■ <a href="<%= cgi.script_name %>?mode=reset">初期化</a>
+ - 現存する全てのログを初期化し、空のdiary.xml及びloglist.xmlのみを再配置します。
+ </td>
+ </tr>
+ </table>
+ <br>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
+</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <% unless cgi.user_agent =~ /(iPod|iPhone|iPad|Android)/ %>
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ <% unless cgi.user_agent =~ /(iPod|iPhone|iPad|Android)/ %>
<link rel="stylesheet" type="text/css" href="./yui/build/menu/assets/skins/sam/menu.css" />
<link rel="stylesheet" type="text/css" href="./yui/build/button/assets/skins/sam/button.css" />
<link rel="stylesheet" type="text/css" href="./yui/build/fonts/fonts-min.css" />
margin: 0;
padding: 0;
}
+
+ body {
+ font-family: 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', 'メイリオ', Meiryo, 'MS Pゴシック', sans-serif;
+ font-size: 12px;
+ line-height: 18px;
+ }
</style>
<% end %>
- </head>
- <body class="yui-skin-sam">
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST">
- <input type="hidden" name="target_filepath" value="<%= session["target_filepath"] %>"><% case params["action"]
+ </head>
+ <body class="yui-skin-sam">
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <div class="contents">
+ <h1>記事作成</h1>
+ <input type="hidden" name="target_filepath" value="<%= session["target_filepath"] %>">
+ <% case params["action"]
when "confirm" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 入力内容を確認してください
- </td>
- </tr>
<% db.transaction do
entry = db["newentry"]
entry.paramlist.each do |val| %>
<tr style="display: <%= entry.display[val] %>;">
- <td class="formnavi" style="width: 140px;">
+ <th class="small middle padding_normal">
<%= entry.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large middle padding_normal">
<input type="hidden" name="<%= val %>" value="<%= entry.send(val) %>"><% if val != "content" %><%= entry.send(val) %><% else %><%= entry.content_for_view %><% end %>
</td>
- </tr><% end %>
+ </tr>
+ <tr style="display: <%= entry.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="newentry"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')"><% when "exec" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td class="forminput" style="text-align: center;">
- 記事の書き込みが完了しました。
- </td>
- </tr>
- </tbody>
- </table>
+ <div class="center">
+ <input type="hidden" name="mode" value="newentry"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, 'back')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')">
+ </div>
<br>
- <a href="<%= cgi.script_name %>">メニューに戻る</a>
<% when "back" %>
- <table style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 新規作成
- <br>
- </td>
- </tr>
<% db.transaction do
if cgi["action"] == "back"
entry = db["newentry"]
end
entry.paramlist.each do |val| %>
<tr style="display: <%= entry.display[val] %>;">
- <td class="formnavi" style="width: 140px;">
+ <th class="small middle padding_normal">
<%= entry.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large left padding_normal">
<% if val != "content" %>
- <input type="text" name="<%= val %>" value="<%= entry.send(val) %>" style="width: 100%"><% else %>
- <textarea name="<%= val %>" rows="10" style="width: 100%" id="contenteditor"><%= entry.content_for_generator %></textarea>
+ <input type="text" name="<%= val %>" value="<%= entry.send(val) %>" class="max_width"><% else %>
+ <textarea name="<%= val %>" rows="10" class="max_width" id="contenteditor"><%= entry.content_for_generator %></textarea>
<% end %>
</td>
</tr>
+ <tr style="display: <%= entry.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
<% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="newentry"><input type="hidden" name="action" value="confirm"><input type="submit" value="確認"><% else %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ <div class="center">
+ <input type="hidden" name="mode" value="newentry"><input type="hidden" name="action" value="confirm"><input type="submit" value="確認">
+ </div>
+ <br>
+ <% else %>
+ <table>
<tbody>
- <tr>
- <td colspan="2" class="formheader">
- ■ 新規作成
- <br>
- </td>
- </tr>
<% db.transaction do
if cgi["action"] == "back"
entry = db["newentry"]
end
entry.paramlist.each do |val| %>
<tr style="display: <%= entry.display[val] %>;">
- <td class="formnavi" style="width: 140px;">
+ <th class="small middle padding_normal">
<%= entry.name[val] %>
- </td>
- <td class="forminput">
+ </th>
+ <td class="large left padding_normal">
<% date = Time.now.iso8601 %>
<% if val == "content" %>
- <textarea name="<%= val %>" rows="10" style="width: 100%" id="contenteditor"><% if entry.content.empty? %><p><br></p><% else %><%= entry.content_for_generator %><% end %></textarea>
+ <textarea name="<%= val %>" rows="10" class="max_width" id="contenteditor"><% if entry.content.empty? %><p><br></p><% else %><%= entry.content_for_generator %><% end %></textarea>
<% elsif val == "entryid" %>
- <input type="text" name="<%= val %>" value="<%= db["feed"].feedid %>?<%= date %>" style="width: 100%"><% elsif val == "updated" || val == "published" %>
- <input type="text" name="<%= val %>" value="<%= date %>" style="width: 100%"><% elsif val == "url" %>
- <input type="text" name="<%= val %>" value="<%= db["feed"].url %>#<%= db["feed"].feedid %>?<%= date %>" style="width: 100%"><% else %>
- <input type="text" name="<%= val %>" value="<%= entry.send(val) %>" style="width: 100%"><% end %>
+ <input type="text" name="<%= val %>" value="<%= db["feed"].feedid %>?<%= date %>" class="max_width"><% elsif val == "updated" || val == "published" %>
+ <input type="text" name="<%= val %>" value="<%= date %>" class="max_width"><% elsif val == "url" %>
+ <input type="text" name="<%= val %>" value="<%= db["feed"].url %>#<%= db["feed"].feedid %>?<%= date %>" class="max_width"><% else %>
+ <input type="text" name="<%= val %>" value="<%= entry.send(val) %>" class="max_width"><% end %>
</td>
- </tr><% end %>
+ </tr>
+ <tr style="display: <%= entry.display[val] %>;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="newentry"><input type="hidden" name="action" value="confirm"><input type="submit" class="wymupdate" value="確認"><% end %>
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ <div class="center">
+ <input type="hidden" name="mode" value="newentry"><input type="hidden" name="action" value="confirm"><input type="submit" class="wymupdate" value="確認">
+ </div>
+ <br>
+ <% end %>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
--- /dev/null
+<html>
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+ <title><%= APPTITLE %></title>
+ <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css"/>
+ </head>
+ <body>
+ <br>
+ <br>
+ <div class="divstyle" style="width: 400px; padding: 15px;">
+ <form action="<%= cgi.script_name %>" method="POST">
+ FeedGenerator for Ruby
+ <br>
+ <br>
+ <table align="center">
+ <tbody>
+ <tr>
+ <td>
+ <br>
+ ユーザが認証されていません。
+ <br>
+ トップページで再認証して下さい。
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </form>
+ </div>
+ <br>
+ <div class="divstyle" style="border: none;">
+ <%= APPVERSION %>
+ </div>
+ </body>
+</html>
--- /dev/null
+<script type="text/javascript">\r
+ function switchsubmit(form, action){\r
+ document.getElementsByName("action").item(0).value = action;\r
+ form.submit();\r
+ }\r
+ </script>
\ No newline at end of file
--- /dev/null
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>\r
+ <title><%= APPTITLE %></title>\r
+ <link rel="stylesheet" href="./css/reset.css" type="text/css"/>\r
+ <link rel="stylesheet" href="./css/base.css" type="text/css"/>\r
+ <script type="text/javascript" src="./js/jquery-1.6.1.min.js"></script>
\ No newline at end of file
--- /dev/null
+<% unless session["info"] == "" %>\r
+ <div class="contents info_contents">\r
+ <h1 class="info">以下の操作を実施しました</h1>\r
+ <div class="info_contens_inner">\r
+ <%= session["info"] %>\r
+ </div>\r
+ <br>\r
+ </div>\r
+ <% end %>\r
+ <% unless session["error"] == "" %>\r
+ <div class="contents error_contents">\r
+ <h1 class="error">エラーが発生しました</h1>\r
+ <div class="error_contens_inner">\r
+ <%= session["error"] %>\r
+ </div>\r
+ <br>\r
+ </div>\r
+ <% end %>\r
--- /dev/null
+<div class="menu">\r
+ <ul class="menu">\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>" class="menu">トップページ</a>\r
+ </li>\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>?mode=newentry" class="menu">記事作成</a>\r
+ </li>\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>?mode=editentry" class="menu">記事編集</a>\r
+ </li>\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>?mode=delentry" class="menu">記事削除</a>\r
+ </li>\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>?mode=editfeed" class="menu">基本情報編集</a>\r
+ </li>\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>?mode=log" class="menu">ログ管理</a>\r
+ </li>\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>?mode=import" class="menu">インポート</a>\r
+ </li>\r
+ <% if USEFILEMANAGER == true %>\r
+ <li class="menu_left">\r
+ <a href="<%= FILEMANAGER %>" class="menu" target="_blank">ファイル操作</a>\r
+ </li>\r
+ <% end %>\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>?mode=reset" class="menu">初期化</a>\r
+ </li>\r
+ <li class="menu_left">\r
+ <a href="<%= cgi.script_name %>?mode=logout" class="menu">ログアウト</a>\r
+ </li>\r
+ </ul>\r
+ </div>
\ No newline at end of file
--- /dev/null
+<div class="select_file center">\r
+ 現在編集中のファイル:\r
+ <% if params["target_filepath"].blank? %>\r
+ <%= session["filepath"] %>\r
+ <% else %>\r
+ <%= session["target_filepath"] %>\r
+ <% end %>\r
+ [ <a href="<%= cgi.script_name %>?mode=selectlog">他のファイルを選択</a> ]\r
+ </div>
\ No newline at end of file
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- <script type="text/javascript">
- function switchsubmit(form, action){
- document.getElementsByName("action").item(0).value = action;
- form.submit();
- }
- </script>
- </head>
- <body>
- <% db.transaction do %>
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST" enctype="multipart/form-data">
- <% case params["action"]
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ </head>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST" enctype="multipart/form-data">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <% db.transaction do %>
+ <div class="contents">
+ <h1>基本情報編集</h1>
+ <% case params["action"]
when "confirm" %>
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
+ ■ diary.xmlが以下の赤色の位置にログとして挿入されます
+ <br>
+ <br>
+ <table>
<tbody>
<tr>
- <td class="formheader" colspan="3">
- ■ diary.xmlが以下の赤色の位置にログとして挿入されます
- </td>
- </tr>
- <tr>
- <td colspan="" style="text-align: center;" class="formnavi">
+ <th class="large center padding_normal">
ログファイルのパス
- </td>
- <td style="text-align: center;" class="formnavi">
+ </th>
+ <th class="small center padding_normal">
ログの表示名
- </td>
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
<% db["loglist"].path.each_with_index do |log, i| %>
<tr>
- <td style="text-align: center;" class="forminput">
+ <td class="center padding_normal">
<%= log %>
</td>
- <td style="text-align: center;" class="forminput">
+ <td class="center padding_normal">
<%= db["loglist"].display[i] %>
</td>
</tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
<% if i == 0 %>
<tr>
- <td style="text-align: center;" class="forminputhilight">
+ <td class="center padding_normal red border_red">
<%= db["logpath"] %>
<input type="hidden" name="logpath" value="<%= db["logpath"] %>">
</td>
- <td style="text-align: center;" class="forminputhilight">
+ <td class="center padding_normal red border_red">
<%= db["logdisplay"] %>
<input type="hidden" name="logdisplay" value="<%= db["logdisplay"] %>">
</td>
- </tr><% end %>
- <% end %>
- </tbody>
- </table>
- <br>
- <input type="hidden" name="mode" value="replace"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, '')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')"><% when "exec" %>
- <table align="center" style="width: <%= TABLEWIDTH %>px">
- <tbody>
+ </tr>
<tr>
- <td class="forminput" style="text-align: center;">
- インポート処理が完了しました。
- </td>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
+ <% end %>
+ <% end %>
</tbody>
</table>
<br>
- <a href="<%= cgi.script_name %>">トップページに戻る</a>
+ <div class="center">
+ <input type="hidden" name="mode" value="replace"><input type="hidden" name="action" value=""><input type="button" value="戻る" onclick="switchsubmit(this.form, '')"> <input type="button" value="確定" onclick="switchsubmit(this.form, 'exec')">
+ </div>
+ <br>
+ <br>
<% else %>
- <table align="center" style="width: <%= TABLEWIDTH - 20 %>px;">
+ ■ diary.xmlとして保存するファイルを選択してください
+ <br>
+ <br>
+ <table>
<tbody>
<tr>
- <td colspan="2" class="formnavi">
- ■ diary.xmlとして保存するファイルを選択してください
- </td>
- </tr>
- <tr>
- <td class="formnavi" style="width: 200px;">
+ <th class="small middle padding_normal">
インポートファイル
- </td>
- <td class="forminput">
- <input type="file" name="updata" style="width: 100%;">
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="file" name="updata" class="max_width">
</td>
</tr>
<tr>
- <td colspan="2" class="formnavi">
- ■ 現在のdiary.xmlを保存する情報を設定してください
- </td>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
+ </tbody>
+ </table>
+ <br>
+ ■ 現在のdiary.xmlを保存する情報を設定してください
+ <br>
+ <br>
+ <table>
+ <tbody>
<tr>
- <td class="formnavi" style="width: 200px;">
+ <th class="small middle padding_normal">
ログ化されたdiary.xmlのパス
- </td>
- <td class="forminput">
- <input type="text" name="logpath" style="width: 100%;">
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="text" name="logpath" class="max_width">
</td>
</tr>
<tr>
- <td class="formnavi" style="width: 200px;">
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
+ <tr>
+ <th class="small middle padding_normal">
ログ化されたdiary.xmlの表示名
- </td>
- <td class="forminput">
- <input type="text" name="logdisplay" style="width: 100%;">
+ </th>
+ <td class="large middle padding_normal center">
+ <input type="text" name="logdisplay" class="max_width">
</td>
</tr>
</tbody>
- </table><%= db["error"] %>
+ </table>
+ <br>
+ <div class="center">
+ <input type="hidden" name="mode" value="replace"><input type="hidden" name="action" value=""><input type="button" value="確認" onclick="switchsubmit(this.form, 'confirm')">
+ </div>
<br>
- <input type="hidden" name="mode" value="replace"><input type="hidden" name="action" value=""><input type="button" value="確認" onclick="switchsubmit(this.form, 'confirm')">
<br>
<% end %>
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- <% end %>
- </body>
+ </div>
+ <% end %>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
<script type="text/javascript">
/**
* ページのロード時に呼ばれるメソッド
}
}
</script>
- </head>
- <body onload="loadexec()">
- <br>
- <%= menu %>
- <br>
- <% db.transaction do %>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST">
- <table align="center" style="width: <%= (TABLEWIDTH - 20) %>px;">
- <tbody>
- <tr>
- <td class="formnavi" style="text-align: left;">
- <span style="font-weight: bold;">
- ■ 初期化機能</a>
- </td>
- </tr>
- <tr>
- <td class="forminput" style="text-align: left;">
- <span style="font-weight: bold;">[ 説明 ]</span>
- <br>
- この機能を使用することで、日記に関するデータ全てを消去することができます。
- <br>
- 初期化処理を行うと、ディレクトリ [ <%= XMLPATH %>] の中のファイルを全て消去します。その後空のdiary.xmlとloglist.xmlを生成して設置します。消去前のAtom Feedの情報は一切保持されませんので気をつけてください。
- <br>
- <table align="center" style="width: 80%; margin-top: 8px; margin-bottom: 8px;">
- <tbody>
- <tr>
- <td class="formnavi" style="text-align: center; padding: 3px;">
- [ <%= XMLPATH %>] ディレクトリ内部のファイル一覧
- </td>
- </tr>
- <% db["filelist"].each do |fname| %>
- <tr>
- <td class="forminput" style="text-align: center; padding: 3px;">
- <a href="<%= XMLPATH %><%= fname %>" target="_blank"><%= fname %></a>
- </td>
- </tr>
- <% end %>
- </tbody>
- </table>
- </td>
- </tr>
- <tr>
- <td class="forminput" style="text-align: left;">
- <span style="font-weight: bold; color: #ff0000">[ 注意! ]</span>
- <br>
- 初期化後にリセットしたデータを戻すことは出来ません!初期化を行う前に、入念に検討を行ってください。
- <br>
- </td>
- </tr>
- <tr>
- <td class="forminput" style="text-align: center;">
- <input type="button" value="ロック解除" onclick="unlock('initButton')"> <input type="hidden" name="mode" value="reset"><input type="hidden" name="action" value=""><input type="button" value="初期化を行う" onclick="beforeexec(this.form, 'exec')" disabled="true" id="initButton">
- </td>
- </tr>
- </tbody>
- </table>
- <br>
- <a href="<%= cgi.script_name %>">メニューに戻る</a>
- <br>
- </form>
- </div>
- <% end %>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ </head>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <% db.transaction do %>
+ <div class="contents">
+ <h1>初期化機能</h1>
+ <span style="font-weight: bold;">[ 説明 ]</span>
+ <br>
+ この機能を使用することで、記事に関するデータ全てを消去することができます。
+ <br>
+ 初期化処理を行うと、ディレクトリ [ <%= XMLPATH %>] の中のファイルを全て消去します。その後空のdiary.xmlとloglist.xmlを生成して設置します。消去前のAtom Feedの情報は一切保持されませんので気をつけてください。
+ <br>
+ <br>
+ <table>
+ <tr>
+ <th class="maximum center padding_normal">
+ [ <%= XMLPATH %>] ディレクトリ内部のファイル一覧
+ </th>
+ </tr>
+ <% db["filelist"].each do |fname| %>
+ <tr>
+ <td class="maximum center padding_normal">
+ <a href="<%= XMLPATH %><%= fname %>" target="_blank"><%= fname %></a>
+ </td>
+ </tr>
+ <% end %>
+ </table>
+ <br>
+ <span style="font-weight: bold; color: #ff0000">[ 注意! ]</span>
+ <br>
+ 初期化後にリセットしたデータを戻すことは出来ません!初期化を行う前に、入念に検討を行ってください。
+ <br>
+ <br>
+ <div class="center">
+ <input type="button" value="ロック解除" onclick="unlock('initButton')"> <input type="hidden" name="mode" value="reset"><input type="hidden" name="action" value=""><input type="button" value="初期化を行う" onclick="beforeexec(this.form, 'exec')" disabled="true" id="initButton">
+ </div>
+ <br>
+ </div>
+ <% end %>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
+<!DOCTYPE html>
<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
- <title><%= APPTITLE %></title>
- <link rel="stylesheet" href="./erbtemp/stylesheet.css" type="text/css">
- </head>
- <body>
- <br>
- <%= menu %>
- <br>
- <div class="divstyle" style="width: <%= TABLEWIDTH %>px;">
- <form action="<%= cgi.script_name %>" method="POST">
- <table align="center">
+ <head>
+ <%= htmlparts["headtag"] %>
+ <%= htmlparts['headjs_switchpost'] %>
+ </head>
+ <body>
+ <form action="<%= cgi.script_name %>" method="POST">
+ <div class="menu_wrapper">
+ <%= htmlparts["menu"] %>
+ </div>
+ <%= htmlparts["selectfile"] %>
+ <%= htmlparts["infoarea"] %>
+ <div class="contents">
+ <h1>編集ファイル選択</h1>
+ <table align="center">
<tbody>
<tr>
- <td colspan="4" class="formheader" style="width: <%= (TABLEWIDTH - 20) %>px;">
- ■ 編集するファイルを選択してください。
- </td>
- </tr>
- <tr>
- <td style="text-align: center;" class="formnavi">
+ <th class="middle padding_normal" style="width: 50px;">
- </td>
- <td style="text-align: center;" class="formnavi">
+ </th>
+ <th class="normal middle padding_normal">
ログファイルの説明
- </td>
- <td style="text-align: center;" class="formnavi">
+ </th>
+ <th class="normal middle padding_normal">
ログファイルパス
- </td>
- <td style="text-align: center;" class="formnavi">
+ </th>
+ <th class="middle padding_normal" style="width: 100px;">
開く
- </td>
+ </th>
+ </tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
</tr>
<% db.transaction do %>
<% db["loglist"].display.each_with_index do |val, i| %>
<tr>
- <td style="text-align: center; width: 25px;" class="forminput">
+ <td class="middle padding_normal center">
<input type="radio" name="logpath" value="<%= db["loglist"].path[i] %>"<% if db["loglist"].path[i] == session["filepath"] %>checked="checked"<% end %>>
</td>
- <td style="text-align: center;" class="forminput">
+ <td class="middle padding_normal center">
<%= db["loglist"].display[i] %>
</td>
- <td style="text-align: center;" class="forminput">
+ <td class="middle padding_normal center">
<%= db["loglist"].path[i] %>
</td>
- <td style="text-align: center;" class="forminput">
+ <td class="middle padding_normal center">
[ <a href="<%= XMLPATH + db["loglist"].path[i].match(/[^\/]*?$/).to_a[0] %>" target="_blank">OPEN</a>
]
</td>
</tr>
+ <tr>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ <td class="hr"></td>
+ </tr>
<% end %>
<% end %>
</tbody>
</table>
<br>
- <input type="hidden" name="mode" value="logselect"><input type="submit" value="選択">
- </form>
- </div>
- <br>
- <div class="divstyle" style="border: none;">
- <%= APPVERSION %>
- </div>
- </body>
+ <div class="center">
+ <input type="hidden" name="mode" value="logselect"><input type="submit" value="選択">
+ </div>
+ <br>
+ <br>
+ </div>
+ <div class="bottom_area">
+ <%= APPVERSION %>
+ </div>
+ </form>
+ </body>
</html>
+++ /dev/null
-body {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- font-family: 'MS Pゴシック', sans-serif;\r
- color: #1E4080;\r
- background-image: url('../img/background.jpg');\r
- background-color: white;\r
- background-repeat: no-repeat;\r
- background-attachment: fixed;\r
- background-position: right bottom;\r
- text-align: center;\r
- margin-left: auto;\r
- margin-right: auto;\r
- -webkit-text-size-adjust: none;\r
-}\r
-\r
-table {\r
- border-width: 0px 0px 0px 0px;\r
-}\r
-\r
-td {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- font-family: 'MS Pゴシック', sans-serif;\r
-}\r
-\r
-td.formheader {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- font-family: 'MS Pゴシック', sans-serif;\r
- font-weight: bold;\r
- padding: 3px;\r
- border: 1px solid #C5C5DE;\r
- background-color: #FAFAFF;\r
-}\r
-\r
-td.forminput {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- font-family: 'MS Pゴシック', sans-serif;\r
- padding: 5px;\r
- border: 1px dotted #C5C5DE;\r
-}\r
-\r
-td.forminputhilight {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- font-family: 'MS Pゴシック', sans-serif;\r
- padding: 5px;\r
- border: 1px dotted #BEA5A5;\r
- background-color: #FFFAFA;\r
-}\r
-\r
-td.formnavi {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- font-family: 'MS Pゴシック', sans-serif;\r
- padding: 5px;\r
- border: 1px solid #C5C5DE;\r
- background-color: #FAFAFF;\r
-}\r
-\r
-a:link {\r
- text-decoration: none;\r
- color: #A5A5BE;\r
-}\r
-\r
-a:visited {\r
- text-decoration: none;\r
- color: #A5A5BE;\r
-}\r
-\r
-a:active {\r
- text-decoration: none;\r
- color: #A5A5BE;\r
-}\r
-\r
-a:hover {\r
- text-decoration: underline;\r
- color: #A5A5BE;\r
-}\r
-\r
-div.divstyle {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- text-align: center;\r
- margin-left: auto;\r
- margin-right: auto;\r
- padding: 5px;\r
- border: 1px solid #A5A5BE;\r
-}\r
-\r
-input {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- font-family: 'MS Pゴシック', sans-serif;\r
- color: #1E4080;\r
- border: 1px dotted #BABAFE;\r
- background-color: #F5F5FF;\r
-}\r
-\r
-textarea {\r
- font-size: 9pt;\r
- line-height: 13pt;\r
- font-family: 'MS Pゴシック', sans-serif;\r
- color: #1E4080;\r
- border: 1px dotted #BABAFE;\r
- background-color: #F5F5FF;\r
-}\r
-\r
-.menu_link {\r
- text-decoration: none;\r
- color: #A5A5BE;\r
-}\r
-#!/usr/local/bin/ruby
-# -*- coding: utf-8 -*-
-#
-#= Atom Feed 1.0を管理するWEBアプリケーション
-#
-#Autohr:: Kureha Hisame (http://lunardial.sakura.ne.jp/) & Yui Naruse (http://airemix.com/)
-#Version:: 2.0.0.0
-#Copyright:: Copyright 2009 FeedBlog Project (http://sourceforge.jp/projects/feedblog/)
-#License:: GPLv3
-
-require "cgi"
-require "cgi/session"
-require "erb"
-require "rexml/document"
-require "pstore"
-require 'time'
-require "date"
-require "fileutils"
-
-# ログイン情報配列
-LOGININFO = [
-{:id => "login", :password => "password", :name => "テストユーザ"}
-]
-# インターフェースのテーブルの幅
-TABLEWIDTH = 1000
-# XMLファイル格納先までの相対パス
-XMLPATH = "./../lunardial/xml/"
-# FeedBlogを設置したディレクトリのURL
-HOMEBASE = "https://lunardial.sakura.ne.jp/"
-# 入力されたフルパスURL(HOMEBASE)を置換する文字列
-RELAYPATH = "./"
-# loglist.xmlファイルの定義
-LISTXMLPATH = "#{XMLPATH}loglist.xml"
-# FeedBlog上の表示ページからログ格納ディレクトリまでのパス
-FEEDXMLDIR = "./xml/"
-# デバッガモード
-DEBUG = false
-# ファイルマネージャー機能を使用するならtrue
-USEFILEMANAGER = true
-# ファイルマネージャー機能スクリプト(filemanager.rb)のパス
-FILEMANAGER = "./filemanager.rb"
-# XMLに書き込む際、改行部分を<br>のまま保持するか、改行記号に直すか
-REPLACEBRTAG = false
-# ファイルの書き込み時にENTRYのIDおよびURLを、FEEDオブジェクトから自動生成した値に置換するか否か
-REPLACEENTRYIDANDURL = false
-# プラグインディレクトリ
-PLUGINDIR = "./plugins/"
-# 記事用初期ファイル名
-INITIALXML = "diary.xml"
-
-# バージョン情報を示す文字列です
-APPVERSION = "- FeedGenerator for Ruby version 2.0.0.0 -<br>Copyright(c) 2009 Kureha.H (<a href=\"http://lunardial.sakura.ne.jp/\" target=\"_blank\">http://lunardial.sakura.ne.jp/</a>) & Yui Naruse (<a href=\"http://airemix.com/\" target=\"_blank\">http://airemix.com/</a>)"
-# タイトル領域に表示される文字列です
-APPTITLE = "FeedGenerator for Ruby version 2.0.0.0"
-
-# = Objectクラス
-#
-# 基本クラスのオーバーライドを行います
-class Object
- # myopenメソッド
- #
- # ruby-1.9.x以降ではファイルを開いた際、エンコードの指定を行わないとエラーの原因になります。
- # ただしruby-1.8.6以前はエンコードの指定に対応していないため、独自メソッドを定義してファイルの入出力を行います。
- #
- # _arg[0]_ :: 入出力を行うファイルのパス
- # _arg[1]_ :: モードの指定。例 : w:utf-8(書き込みモード・UTF-8エンコードでファイルを開く)
- def myopen(*arg)
- mode = arg[1]
- rdonly_p = true
- case mode
- when String
- arg[1] = mode[/[^:]+/] if RUBY_VERSION < "1.8.7" && mode.include?(':')
- rdonly_p = /\A[^:]*[wa+]/ !~ mode
- when Numeric
- rdonly_p = !(mode & (IO::WRONY | IO::RDWR))
- end
- open(*arg) do |f|
- f.flock(rdonly_p ? File::LOCK_SH : File::LOCK_EX)
- return yield(f)
- end
- end
-end
-
-class NilClass
- def blank?
- nil?
- end
-end
-
-class Array
- def blank?
- empty?
- end
-end
-
-class String
- def blank?
- empty?
- end
-end
-
-# = Feed/Entryのスーパークラス
-#
-# 入出力用のメソッドなど、共通する機能を提供します
-class AbstractEntry
- # 初期化メソッドです
- #
- # _hash_ :: 値を格納したhash配列。superfeed.new(CGI::Session.new(new CGI).params)のようにして使う。
- def initialize(hash)
- # 内部データ保持用のハッシュ配列です
- @attr = {}
-
- # 引数を格納します
- @paramlist.each do |key|
- val = hash[key.to_sym] || hash[key.to_s]
- if val
- val.strip!
- val.gsub!(/\r\n|\r/, "\n")
- @attr[key.to_sym] = CGI.escapeHTML(val)
- else
- # 空の場合の対策
- @attr[key.to_sym] = ""
- end
- end
-
- # 可視・不可視を示すハッシュキーを格納する配列です
- @display = {}
-
- # ハッシュキーの日本語説明を格納する配列です
- @name = []
- end
-
- # Accessor
- attr_reader :attr, :paramlist, :name, :display
-
- # 内部の@attrハッシュにアクセスする手段を提供するメソッドです
- #
- # AbstractEntry.attr[:title]にアクセスしたい場合はAbstractEntry.titleで可能になります。
- # AbstractEntry.send("title")という方法でもアクセス可能です。
- def method_missing(methname, *args)
- methname = methname.to_s
-
- if methname[-1] == ?=
- # setter
- raise ArgumentError, "wrong number of arguments (#{args.length} for 1)" unless args.length == 1
- methname.chop!
- methname = @paramlist.find{|par|par == methname}
- return @attr[methname.to_sym] = args[0] if methname
- else
- # getter
- raise ArgumentError, "wrong number of arguments (#{args.length} for 0)" unless args.empty?
- return @attr[methname.to_sym] if @attr.key?(methname.to_sym)
- end
- # attr上にキーがない値を入れようとした場合はNoMethodError
- raise NoMethodError
- end
-
- def [](key)
- @attr[key.to_sym]
- end
-
- def []=(key, value)
- @attr[key.to_sym] = value
- end
-end
-
-# = Feedクラス
-#
-# Feedの基礎情報を保有するクラスです
-class Feed < AbstractEntry
- # 初期化メソッドです
- #
- # _hash_ :: 値を格納したhash配列。feed.new(CGI::Session.new(new CGI).params)のようにして使います。
- def initialize(hash)
- # 内部データ保持用のハッシュ配列です
- @attr = {}
-
- # 内部データの項目名を格納する配列です
- @paramlist = ["feedattr", "title", "subtitle", "self", "url", "updated", "feedid", "rights", "aname", "amail", "others"]
-
- # AbstractEntryのinitializeメソッドを呼び出し、値を@attr配列に格納します
- super(hash)
-
- # 可視・不可視を示すハッシュキーを格納する配列です
- @display = {"feedattr" => "none", "title" => "", "subtitle" => "",
- "self" => "", "url" => "",
- "updated" => "none", "feedid" => "",
- "rights" => "", "aname" => "",
- "amail" => "", "others" => "none"}
-
- # デバッグモードの場合、全ての入力要素を表示します
- if DEBUG == true
- @display.each do |key, val|
- @display[key] = ""
- end
- end
-
- # ハッシュキーの日本語説明を格納する配列です
- @name = {"feedattr" => "feedの保持している属性", "title" => "ウェブページのタイトル", "subtitle" => "ウェブページの簡単な説明",
- "self" => "このXMLファイルのURL", "url" => "ウェブページのURL",
- "updated" => "XMLファイルの最終更新日", "feedid" => "あなたのページ独自のID",
- "rights" => "ページの著作権表記", "aname" => "ページの製作者",
- "amail" => "ページ製作者のメールアドレス", "others" => "その他の要素"}
-
- end
-
- # Atom XMLファイルを読み込んで解析し、等価なFeedオブジェクトを返却するメソッドです
- #
- # _path_ :: Atom XMLファイルのパス
- def self.readxml(path)
-
- # ファイルを読み込みます
- doc = REXML::Document.new(myopen(path, "r:utf-8"){|f|f.read})
- xml = {}
- others = []
-
- # Feedの属性値を取得します
- xmlattr = []
- doc.elements["feed"].attributes.each_attribute do |attr|
- xmlattr.push("#{attr.to_string} ")
- end
- xml[:feedattr] = xmlattr.join("\n").gsub(/"/, "'")
-
- # XML解析部分です。各element毎に判定を行います
- doc.elements.each("feed") do |elm|
- elm.elements.each { |child|
- begin
- case child.name
- when "id"
- xml[:feedid] = child.text
- when "title", "subtitle", "updated", "rights"
- xml[child.name.to_sym] = child.text
- when "author"
- child.elements.each do |gchild|
- case gchild.name
- when "name"
- xml[:aname] = gchild.text
- when "email"
- xml[:amail] = gchild.text
- end
- end
- when "link"
- child.attributes.each do |k, v|
- if k == "rel"
- if v == "self"
- xml[:self] = child.attributes["href"]
- elsif v == "alternate"
- xml[:url] = child.attributes["href"]
- end
- end
- end
- when "entry"
- # Entry要素は無視します
- else
- # 上記判定以外の全要素は配列に格納します
- others.push(child.to_s)
- end
- rescue NoMethodError
- end
-
- }
- end
-
- # Others要素を結合して代入します
- xml[:others] = others.join("\n")
- feed = Feed.new(xml)
- return feed
- end
-
- # 内部に保持している情報を、Atom Feed1.0形式の文字列に出力するメソッドです
- def to_s
- buf = []
-
- # buf.push("<feed #{@attr[:feedattr]}>")
- buf.push("<feed xml:lang='ja-jp' xmlns='http://www.w3.org/2005/Atom'>");
- buf.push("<title type=\"text\">#{@attr[:title]}</title>")
- buf.push("<subtitle type=\"text\">#{@attr[:subtitle]}</subtitle>")
- buf.push("<link rel=\"self\" type=\"application/atom+xml\" href=\"#{@attr[:self]}\" />")
- buf.push("<link rel=\"alternate\" type=\"text/html\" href=\"#{@attr[:url]}\" />")
- buf.push("<updated>#{Time.now.iso8601}</updated>")
- buf.push("<id>#{@attr[:feedid]}</id>")
- buf.push("<rights type=\"text\">#{@attr[:rights]}</rights>")
- buf.push("<author>")
- buf.push("\t<name>#{@attr[:aname]}</name>")
- buf.push("\t<email>#{@attr[:amail]}</email>")
- buf.push("</author>")
- buf.push("#{CGI.unescapeHTML(@attr[:others])}") if @attr[:others] != ""
-
- return buf.join("\n")
- end
-
- # Feed情報更新メソッド
- def self.update(path, feed)
- entrylist = Entry.readxml(path)
- Feed.to_xml(path, feed, entrylist)
-
- true
- end
-
- # XMLファイル出力用メソッドです
- #
- # _feed_ :: Feedオブジェクト
- # _entry_ :: Entryオブジェクトの配列
- def self.to_xml(path, feed, entrylist_tmp)
- buf = []
- entrylist = entrylist_tmp.dup
- buf.push("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
- buf.push("#{feed.to_s}\n")
- entrylist.each { |entry|
- if REPLACEENTRYIDANDURL
- entry.entryid.gsub!(/^[^\?]*\?/, "")
- entry.entryid = feed.url + "?" + entry.entryid
- entry.url = feed.url + "#" + entry.entryid
- end
- buf.push("#{entry.to_s}\n")
- }
- buf.push("</feed>")
-
- myopen(path, "w") do |f|
- f.print buf.join("\n")
- end
- end
-
- # XMLファイル出力用メソッドです
- #
- # _feed_ :: Feedオブジェクト
- # _entry_ :: Entryオブジェクトの配列
- def self.to_xml_plain(path, feed, entrylist)
- buf = []
- buf.push("<?xml version=\"1.0\" encoding=\"utf-8\"?>")
- buf.push("#{feed.to_s}\n")
- entrylist.each { |entry|
- buf.push("#{entry.to_s}\n")
- }
- buf.push("</feed>")
-
- myopen(path, "w") do |f|
- f.print buf.join("\n")
- end
- end
-
-end
-
-# = Entryクラス
-#
-# Entryの基礎情報を保有するクラスです
-class Entry < AbstractEntry
- # 初期化メソッドです
- #
- # _hash_ :: 値を格納したhash配列。entry.new(CGI::Session.new(new CGI).params)のようにして使います。
- def initialize(hash)
- # 内部データ保持用のハッシュ配列です
- @attr = {}
-
- # 内部データの項目名を格納する配列です
- @paramlist = ["entryid", "title", "summary", "published", "updated", "url", "content", "others"]
-
- # AbstractEntryのinitializeメソッドを呼び出し、値を@attr配列に格納します
- super(hash)
-
- # 可視・不可視を示すハッシュキーを格納する配列です
- @display = {"entryid" => "none", "title" => "",
- "summary" => "", "published" => "none",
- "updated" => "none", "url" => "",
- "content" => "", "others"=>"none"}
-
- # デバッグモードの場合、全ての入力要素を表示します
- if DEBUG == true
- @display.each do |key, val|
- @display[key] = ""
- end
- end
-
- # ハッシュキーの日本語説明を格納する配列です
- @name = {"entryid" => "記事固有のID", "title" => "記事のタイトル",
- "summary" => "記事の簡単な説明", "published" => "記事の出版時刻",
- "updated" => "記事の更新時刻", "url" => "記事へのURLアドレス",
- "content" => "記事の本文", "others"=>"その他の項目"}
- end
-
- # Atom XMLファイルを読み込んで解析し、等価なEntryオブジェクト配列を返却するメソッドです
- #
- # _path_ :: Atom XMLファイルのパス
- def self.readxml(path)
-
- # ファイルを読み込みます
- doc = REXML::Document.new(myopen(path, "r:utf-8"){|f|f.read})
- entrylist = []
- xml = {}
-
- # XML解析部分です。各element毎に判定を行います
- doc.elements.each("feed/entry") do |elm|
- xml = {}
- others = []
- elm.elements.each do |child|
- begin
- case child.name
- when "id"
- xml[:entryid] = child.text
- when "link"
- xml[:url] = child.attributes["href"]
- when "title", "summary", "summary", "published", "updated", "content"
- xml[child.name.to_sym] = child.text
- else
- # 上記判定以外の全要素は配列に格納します
- others.push(child.to_s)
- end
- rescue NoMethodError
- end
- end
- # Others要素を結合して代入します
- xml[:others] = others.join("\n")
- entrylist.push(Entry.new(xml))
- end
-
- return entrylist
- end
-
- # Atom XMLファイルを読み込んで解析し、テンプレートファイルにしたがってHTMLに変換するメソッドです
- def self.to_html(xmlpath, destpath, entry_temppath, html_temppath)
- # 引数チェック - 全必須
- if xmlpath.empty? or destpath.empty? or entry_temppath.empty? or html_temppath.empty?
- raise ArgumentError
- end
-
- # 必須ファイル存在チェック
- unless File.exist?(xmlpath) and File.exist?(entry_temppath) and File.exist?(html_temppath)
- raise IOError
- end
-
- # XML読み込み
- entrylist = Entry.readxml(xmlpath)
-
- body = ''
- entrylist.each { |e|
- # Entry毎のHTML表示部分を生成
- body << e.to_template(entry_temppath)
- }
-
- # HTML全体のテンプレートを生成
- html_temp = HtmlWriter.new(html_temppath, binding)
-
- # HTMLに書き込み
- myopen(destpath, 'w:utf-8') { |f|
- f.write(CGI.pretty(html_temp.to_code))
- }
- end
-
- # Entryをテンプレートに沿って変形するメソッド
- def to_template(temppath)
- erb = HtmlWriter.new(temppath, binding)
- title = CGI.unescapeHTML(@attr[:title])
- date = @attr[:published]
- content = CGI.unescapeHTML(@attr[:content])
- erb.to_code
- end
-
- # Entry挿入メソッド
- def self.insert(path, entry)
- feed = Feed.readxml(path)
- entrylist = Entry.readxml(path)
- entrylist.unshift entry
-
- Feed.to_xml(path, feed, entrylist)
-
- true
- end
-
- # Entry更新メソッド
- def self.update(path, entry)
- feed = Feed.readxml(path)
- entrylist = Entry.readxml(path)
-
- successed = false
- entrylist.each_with_index { |e, i|
- if e.entryid == entry.entryid
- entrylist[i] = entry
- successed = true
- end
- }
- Feed.to_xml(path, feed, entrylist) if successed
-
- successed
- end
-
- # Entryロードメソッド
- def self.select(path, entryid)
- feed = Feed.readxml(path)
- entrylist = Entry.readxml(path)
-
- entry = nil
- entrylist.each_with_index { |e, i|
- entry = entrylist[i].dup if e.entryid == entryid
- }
-
- entry
- end
-
- # Entry消去メソッド
- def self.delete(path, entryid)
- feed = Feed.readxml(path)
- entrylist = Entry.readxml(path)
-
- successed = false
- delete_index = -1
- entrylist.each_with_index { |e, i|
- if e.entryid == entryid
- delete_index = i
- successed = true
- end
- }
-
- if successed
- entrylist.delete_at delete_index
- Feed.to_xml(path, feed, entrylist)
- end
-
- successed
- end
-
- # データソースから読み取ったHTMLを、エディタで編集可能な形式に変換するメソッドです
- def content_for_generator
- str = @attr[:content].dup
- str.strip!
- str.gsub!(/(<\/(?:p|h\d|div)(?:>|>))\n/i, '\1')
- str.gsub!(/\n/, '<br>') if REPLACEBRTAG
- str.gsub!(/(<(?:(?!>).)*?)#{Regexp.escape(RELAYPATH)}/) { "#$1#{HOMEBASE}" }
- str
- end
-
- # エディタで編集されたCONTENT要素を、データソースに書き込める形式に変換するメソッドです
- def content_for_blog
- str = @attr[:content].dup
- str = CGI.unescapeHTML(str)
- str.strip!
- str.gsub!(/(\r\n|\n)/, "")
- str.gsub!(/<br>|<br[ ]*\/>/i, "\n") if REPLACEBRTAG
- str.gsub!(/(<br>|<br[ ]*\/>|<\/p>|<\/h\d>|<\/div>)(?=[^\n])/i) { "#$1\n" } unless REPLACEBRTAG
- str.gsub!(/(<[^>]*?)#{Regexp.escape(HOMEBASE)}/) { "#$1#{RELAYPATH}" }
- CGI.escapeHTML(str)
- end
-
- # 確認画面で表示されるCONTENT要素を生成するメソッドです
- def content_for_view
- str = @attr[:content].dup
- str = CGI.unescapeHTML(str)
- str.strip!
- str.gsub!(/<br>|<br[ ]*\/>/i, "\n") if REPLACEBRTAG
- str.gsub!(/(<[^>]*?)#{Regexp.escape(RELAYPATH)}/) { "#$1#{HOMEBASE}" }
- str
- end
-
- # 内部に保持している情報を、Atom Feed1.0形式の文字列に出力するメソッドです
- def to_s
- buf = []
- buf.push("<entry>")
- buf.push("<id>#{@attr[:entryid]}</id>")
- buf.push("<title>#{@attr[:title]}</title>")
- buf.push("<summary>#{@attr[:summary]}</summary>")
- buf.push("<published>#{@attr[:published]}</published>")
- buf.push("<updated>#{@attr[:updated]}</updated>")
- buf.push("<link href=\"#{@attr[:url]}\" />")
- buf.push("<content type=\"html\">#{@attr[:content]}</content>")
- buf.push("#{CGI.unescapeHTML(@attr[:others])}") if @attr[:others] != ""
- buf.push("</entry>")
-
- return buf.join("\n")
- end
-end
-
-# = HtmlWriterクラス
-#
-# テンプレートファイル(*.erb)を読み込み、管理するクラスです
-class HtmlWriter
- # 初期化メソッドです
- #
- # _template_ :: テンプレートファイル(*.erb)のパス
- # _binding_ :: binding変数
- def initialize(template, binding)
- @erb = ERB.new(myopen(template, "r:utf-8") {|f| f.read}, nil, "-")
- @binding = binding
- end
-
- # テンプレートファイルの文字列を返却するメソッドです
- def to_code
- @erb.result(@binding)
- end
-end
-
-# = LogListクラス
-#
-# loglist.xmlにかかわる入出力を行います
-class LogList
- # 初期化メソッドです
- #
- # _display_ :: 画面表示用文字の配列
- # _path_ :: XMLファイルパスの配列
- # _logpath_ :: loglist.xmlのパス
- def initialize(display, path, logpath)
- @display = display
- @path = path
- @logpath = logpath
- end
-
- attr_accessor :display, :path, :logpath
-
- # loglist.xmlファイルを読み込んで解析し、LogListオブジェクトを返却するメソッドです
- #
- # _logpath_ :: loglist.xmlへのパス
- def LogList.readxml(logpath)
-
- # ファイルを読み込みます
- lines = []
- myopen(logpath, "r:utf-8") { |f|
- lines = f.readlines
- }
-
- doc = REXML::Document.new(lines.join("\n"))
- @display = []
- @path = []
-
- doc.elements.each("list/file") { |elm|
- elm.elements.each {|child|
- case child.name
- when "display"
- @display.push(child.text)
- when "path"
- @path.push(child.text)
- else
- # With no action
- end
- }
- }
-
- return LogList.new(@display, @path, logpath)
- end
-
- # loglist.xmlにオブジェクトの内容を反映するメソッドです
- def to_xml
- buf = []
- buf.push("<list>")
- path.each_with_index do |path, i|
- buf.push("<file>")
- buf.push("<display>#{@display[i]}</display>")
- buf.push("<path>#{@path[i]}</path>")
- buf.push("</file>")
- end
- buf.push("</list>")
-
- myopen(@logpath, "w") do |f|
- f.print buf.join("\n")
- end
- end
-
-end
-
-# = FileUploaderクラス
-#
-# 画像の管理を行うクラスです
-class FileUploader
- # 初期化メソッドです
- def initialize
- end
-
- # ファイルの一覧を取得し、ファイル名称を格納した配列を返却します
- def filelist
- arr = Dir::entries(XMLPATH).sort
- arr.delete(".")
- arr.delete("..")
-
- return arr
- end
-
- # ファイルの消去を実行します
- #
- # _name_ :: 消去するファイル名
- def delete(name)
- File.delete(XMLPATH + name.match(/[^\/]*?$/).to_a[0])
- end
-
- # ファイルのアップロードを実行します
- #
- # _name_ :: アップロードファイルの名称
- # _img_ :: アップロードファイル
- def upload(name, img)
- open(XMLPATH + File.basename(name), "w") do |f|
- f.binmode
- f.write img
- end
- end
-end
-
-# = Pluginクラス
-#
-# プラグインの処理を行うクラスです
-class FeedGenPluginManager
- def self.exec(mode, filepath)
- feed = Feed.readxml(XMLPATH + filepath)
- entries = Entry.readxml(XMLPATH + filepath)
- feed.freeze
- entries.freeze
- Dir.foreach(PLUGINDIR) do |fn|
- next unless File.extname(fn) == '.rb'
- require File.join(PLUGINDIR, fn)
- plugin_name = "FeedGenPlugins::"
- plugin_name << File.basename(fn).gsub(/\.rb\Z/, "")
- plugin_ins = plugin_name.split(/::/).inject(Object) { |c,name| c.const_get(name) }
- plugin_ins.new.exec(mode, feed, entries)
- end
- end
-end
-
-# = Controllerクラス
-#
-# コントローラ部分に相当する処理を受け持つクラスです
-class Controller
- def Controller.NormalForm(cgi, session, params, db)
- db.transaction do
- # modeとactionの相関図は以下のようになります。
- # [mode] + [action]
- # + [action]
- # + [action]
- # + ... and more
- case params["mode"]
- # ログ選択画面
- when "logselect"
- session["filepath"] = params["logpath"]
- db["loglist"] = LogList.readxml(LISTXMLPATH)
- # 初期状態で選択されるログは「loglist.xml」の最上に位置するログになります
- session["filepath"] = db["loglist"].path[0] if session["filepath"] == nil
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))
-
- # 新規記事追加部分
- when "newentry"
- case params["action"]
- # 確認画面
- when "confirm"
- session["target_filepath"] = params["target_filepath"]
- db["newentry"] = Entry.new(params)
- db["newentry"].content = db["newentry"].content_for_blog
- # 記事の追記を実際にファイルに反映
- when "exec"
- session["target_filepath"] = params["target_filepath"]
- successed = Entry.insert(XMLPATH + File.basename(params["target_filepath"]), Entry.new(params))
- unless successed
- db["error"] = "日記の新規追加に失敗しました。"
- params["mode"] = "error"
- else
- # 成功時はプラグイン処理を実施する
- FeedGenPluginManager.exec("newentry", File.basename(session["filepath"]))
- end
- # 画面を戻った際の処理
- when "back"
- session["target_filepath"] = params["target_filepath"]
- db["newentry"] = Entry.new(params)
- else
- # New Diary - Default
- session["target_filepath"] = session["filepath"]
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))
- end
-
- # 記事編集部分
- when "editentry"
- case params["action"]
- # 編集画面
- when "edit"
- session["target_filepath"] = params["target_filepath"]
- session["editid"] = cgi["editid"].to_s
- db["editentry"] = Entry.select(XMLPATH + File.basename(session["target_filepath"]), session["editid"])
- # 確認画面
- when "confirm"
- session["target_filepath"] = params["target_filepath"]
- session["editid"] = cgi["editid"].to_s
- db["editentry"] = Entry.new(params)
- db["editentry"].content = db["editentry"].content_for_blog
- # 記事の変更を実際にファイルに反映
- when "exec"
- session["target_filepath"] = params["target_filepath"]
- successed = Entry.update(XMLPATH + File.basename(params["target_filepath"]), Entry.new(params))
- unless successed
- db["error"] = "日記の編集処理に失敗しました。<br>該当の日記が既に存在しない可能性があります。"
- params["mode"] = "error"
- else
- # 成功時はプラグイン処理を実施する
- FeedGenPluginManager.exec("editentry", File.basename(session["filepath"]))
- end
- when "back"
- session["target_filepath"] = params["target_filepath"]
- db["editentry"] = Entry.new(params)
- else
- # Edit Diary - Default
- session["target_filepath"] = session["filepath"]
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))
- end
-
- # 記事削除部分
- when "delentry"
- case params["action"]
- # 確認画面
- when "confirm"
- session["target_filepath"] = params["target_filepath"]
- session["delid"] = cgi["delid"].to_s
- db["delentry"] = Entry.select(XMLPATH + File.basename(session["target_filepath"]), session["delid"])
- # 記事の削除を実際にファイルに反映
- when "exec"
- session["target_filepath"] = params["target_filepath"]
- successed = Entry.delete(XMLPATH + File.basename(params["target_filepath"]), cgi["delid"].to_s)
- unless successed
- db["error"] = "日記の編集処理に失敗しました。<br>該当の日記が既に存在しない可能性があります。"
- params["mode"] = "error"
- else
- # 成功時はプラグイン処理を実施する
- FeedGenPluginManager.exec("delentry", File.basename(session["filepath"]))
- end
- when "back"
- session["target_filepath"] = params["target_filepath"]
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["target_filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["target_filepath"]))
- else
- # Delete Diary - Default
- session["target_filepath"] = session["filepath"]
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))
- end
-
- # Feed情報変更部分
- when "editfeed"
- case params["action"]
- # 確認画面
- when "confirm"
- session["target_filepath"] = params["target_filepath"]
- db["feed"] = Feed.new(params)
- # 実際にFeed情報の変更をファイルに反映
- when "back"
- session["target_filepath"] = params["target_filepath"]
- db["feed"] = Feed.new(params)
- when "exec"
- session["target_filepath"] = params["target_filepath"]
- Feed.update(XMLPATH + File.basename(params["target_filepath"]), Feed.new(params))
- else
- session["target_filepath"] = session["filepath"]
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- end
-
- # ログ編集モード
- when "log"
- # 必ず内部データをリフレッシュする
- db["loglist"] = LogList.readxml(LISTXMLPATH)
- case params["action"]
- # ログファイルの編集を実際にファイルに反映
- when "addexec"
- # エラーチェック。この段階のエラーは強度のエラーを発する。
- db["loglist"].path.each do |val|
- if val == cgi["logpath"]
- # 重複していた場合エラーメッセージを表示し、処理を行わない
- params["action"] = ""
- params["mode"] = "error"
- db["error"] = "ログファイルの追加中に重大なエラーが発生しました。<br>環境を見直してください。"
- return
- end
- end
-
- # 入力された内容を保持する配列に追加
- db["loglist"].path[1, 0] = cgi["logpath"]
- db["loglist"].display[1, 0] = cgi["logdisplay"]
- db["loglist"].to_xml
- # 既存のdiary.xmlを指定された名称でコピーして保存
- FileUtils.copy_file(XMLPATH + File.basename(db["loglist"].path[0]), XMLPATH + File.basename(db["logpath"]), true)
- # 保持している情報を更新する
- db["loglist"] = LogList.readxml(LISTXMLPATH)
- db["entry"] = []
- # 新たなdiary.xmlを生成。この際保持する情報は同一のFeedオブジェクトnew()
- Feed.to_xml(XMLPATH + File.basename(db["loglist"].path[0]), db["feed"], [])
- # 確認画面
- when "addconfirm"
- # 入力されたログが既に存在するかを確認
- db["loglist"].path.each do |val|
- if val == cgi["logpath"]
- # 重複していた場合エラーメッセージを表示し、処理を行わない
- params["action"] = ""
- db["error"] = "<span style='color: #ff0000'>同一のファイルが存在します!別の名前を指定してください。</span><br>"
- return
- end
- end
-
- db["logpath"] = cgi["logpath"]
- db["logdisplay"] = cgi["logdisplay"]
-
- if db["logpath"].blank? || db["logdisplay"].blank?
- params["action"] = ""
- end
- when "back"
-
- # 削除確認画面
- when "delconfirm"
- db["logdelindex"] = params["logdelindex"].to_i
-
- if db["logdelindex"] < 1
- db["error"] = "<span style='color: #ff0000'>ログファイルの削除パラメタが不正です。</span><br>"
- params["action"] = ""
- end
- # 削除処理
- when "delexec"
- if cgi["logdelindex"].to_i < 1
- params["action"] = ""
- params["mode"] = "error"
- db["error"] = "ログファイルの削除中に重大なエラーが発生しました。<br>環境を見直してください。"
- return
- else
- # 記事ファイルを削除します
- File.delete(XMLPATH + File.basename(db["loglist"].path[db["logdelindex"]]))
- # ログリストから削除します
- db["loglist"].path.delete_at(cgi["logdelindex"].to_i)
- db["loglist"].display.delete_at(cgi["logdelindex"].to_i)
- db["loglist"].to_xml
- # 保持している情報を更新する
- db["loglist"] = LogList.readxml(LISTXMLPATH)
- db["entry"] = []
- end
-
- # 編集画面
- when "edit"
- db["logeditindex"] = params["logdelindex"].to_i
-
- db["logpath"] = db["loglist"].path[db["logeditindex"]]
- db["logdisplay"] = db["loglist"].display[db["logeditindex"]]
-
- if db["logeditindex"] == 0
- db["error"] = "<span style='color: #ff0000'>ログファイルの編集パラメタが不正です。</span><br>"
- params["action"] = ""
- end
- # 編集確認画面
- when "editconfirm"
- checkflag = true
- db["loglist"].path.each_with_index do |val, i|
- if db["logeditindex"] != i
- if params["logpath"].to_s == db["loglist"].path[i].to_s
- checkflag = false
- end
- end
- end
-
- if checkflag == false
- params["action"] = "edit"
- db["error"] = "<span style='color: #ff0000'>同一のファイルが存在します!別の名前を指定してください。</span><br>"
- else
- db["loginsertindex"] = params["loginsertindex"].to_i
-
- db["logpath"] = params["logpath"].to_s
- db["logdisplay"] = params["logdisplay"].to_s
- end
- # 編集実行
- when "editexec"
- checkflag = true
- db["loglist"].path.each_with_index do |val, i|
- if db["logeditindex"] != i
- if params["logpath"].to_s == db["loglist"].path[i].to_s
- checkflag = false
- end
- end
- end
-
- if checkflag == false
- params["action"] = ""
- params["mode"] = "error"
- db["error"] = "ログファイルの編集中に重大なエラーが発生しました。<br>環境を見直してください。"
- return
- else
- db["loginsertindex"] = params["loginsertindex"].to_i
-
- db["logpath"] = params["logpath"].to_s
- db["logdisplay"] = params["logdisplay"].to_s
-
- # ファイルを移動します
- if XMLPATH + File.basename(db["loglist"].path[db["logeditindex"]]) != XMLPATH + File.basename(db["logpath"])
- FileUtils.move(XMLPATH + File.basename(db["loglist"].path[db["logeditindex"]]), XMLPATH + File.basename(db["logpath"]))
- # ログリストを更新します
- db["loglist"].path.delete_at(db["logeditindex"])
- db["loglist"].display.delete_at(db["logeditindex"])
- db["loglist"].path.insert(db["loginsertindex"] + 1, db["logpath"])
- db["loglist"].display.insert(db["loginsertindex"] + 1, db["logdisplay"])
- db["loglist"].to_xml
- end
- end
-
- # 初期表示画面
- else
- # 現在編集中のデータを強制的に最上のファイルパスに変更
- session["filepath"] = db["loglist"].path[0]
-
- # 前月の時刻を作成します
- prevmonth = (DateTime.now << 1)
-
- # 前月の時刻を元に、ディフォルト書式を生成します
- db["logpath"] = FEEDXMLDIR + prevmonth.strftime("%Y%m") + ".xml"
- db["logdisplay"] = prevmonth.strftime("%Y年%m月").gsub("年0", "年")
- end
-
- # インポートモードの場合の処理
- when "import"
- db["loglist"] = LogList.readxml(LISTXMLPATH)
-
- # リセットモードの場合の処理
- when "reset"
- case params["action"]
- # リセット実行時の処理
- when "exec"
- file = FileUploader.new
- file.filelist().each { |fname|
- file.delete(fname) if File.ftype(XMLPATH + fname) == "file"
- }
-
- # 全ファイルの初期化を実行する
- # loglist.xmlの初期化
- loglist = LogList.new(["最新の記事"], ["#{FEEDXMLDIR}#{INITIALXML}"], LISTXMLPATH)
- loglist.to_xml
-
- db["loglist"] = LogList.readxml(LISTXMLPATH)
-
- # diary.xmlの初期化
- Feed.to_xml(XMLPATH + db["loglist"].path[0].match(/[^\/]*?$/).to_a[0], Feed.new({}), [])
-
- # 初期の編集ファイルはloglist.xml上の最も上のファイル
- session["filepath"] = db["loglist"].path[0]
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))
-
- # 画面の遷移先をトップページにする
- params["mode"] = ""
- params["action"] = ""
- # パラメタ無しの処理
- else
- # ファイル一覧を取得する
- filelist = FileUploader.new.filelist()
-
- # タイプがファイルのみリストとして取得する
- db["filelist"] = []
- filelist.each { |fname| db["filelist"] << fname if File.ftype(XMLPATH + fname) == "file"}
- end
-
- # ログイン時の画面
- else
- # loglist.xmlが存在するかチェック
- if File.exist?(LISTXMLPATH) == false
- # なかった場合はloglist.xmlを自動生成
- loglist = LogList.new(["最新の記事"], ["#{FEEDXMLDIR}#{INITIALXML}"], LISTXMLPATH)
- loglist.to_xml
- Feed.to_xml(XMLPATH + File.basename(loglist.path[0]), Feed.new({}), [])
- end
-
- db["loglist"] = LogList.readxml(LISTXMLPATH)
-
- # diary.xmlが存在するかチェック
- if File.exist?(XMLPATH + File.basename(db["loglist"].path[0])) == false
- # なかった場合はdiary.xmlを自動生成
- Feed.to_xml(XMLPATH + File.basename(db["loglist"].path[0]), Feed.new({}), [])
- end
-
- # 初期の編集ファイルはloglist.xml上の最も上のファイル
- session["filepath"] = db["loglist"].path[0] if session["filepath"] == nil
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))
- end
- end
- end
-
- # マルチパートフォームの場合の処理です
- def Controller.MultiForm(cgi, session, params, db)
- db.transaction do
- # loglist.xmlをロードします
- db["loglist"] = LogList.readxml(LISTXMLPATH)
- case params["mode"]
- # 特定位置に挿入する場合の処理
- when "insert"
- case params["action"]
- when "exec"
- # この段階のエラーに対しては強度のエラーを発する
- checkflag = true
- db["logpath"] = Controller.get_mpart_value(cgi["logpath"])
- db["loglist"].path.each do |val|
- if val == db["logpath"]
- # 重複していた場合エラーメッセージを表示し、処理を行わない
- db["logpath"] = ""
- params["action"] = ""
- params["mode"] = "error"
- db["error"] = "ログファイルの追加中に重大なエラーが発生しました。"
- return
- end
- end
-
- db["loginsertindex"] = cgi["loginsertindex"].read.to_i
- db["logdisplay"] = Controller.get_mpart_value(cgi["logdisplay"])
-
- # 0位置への挿入防止
- if db["loginsertindex"] == 0
- params["action"] = ""
- params["mode"] = "error"
- db["error"] = "ログファイルの追加中に重大なエラーが発生しました。"
- return
- end
-
- if File.basename(db["logpath"]).blank? || db["logdisplay"].blank?
- params["action"] = ""
- params["mode"] = "error"
- db["error"] = "ログファイルの追加中に重大なエラーが発生しました。"
- return
- end
-
- # ファイルを実際にアップロードします
- file = FileUploader.new
- file.upload(db["logpath"], db["importxml"])
-
- # loglist.xmlを更新します
- db["loglist"].path[db["loginsertindex"], 0] = db["logpath"]
- db["loglist"].display[db["loginsertindex"], 0] = db["logdisplay"]
- db["loglist"].to_xml
-
- # 情報を更新します
- db["loglist"] = LogList.readxml(LISTXMLPATH)
- session["filepath"] = db["loglist"].path[0] if session["filepath"] == nil
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))
-
- when "confirm"
- # 入力されたログファイルパスが既に存在するかを確認
- checkflag = true
- db["logpath"] = Controller.get_mpart_value(cgi["logpath"])
- db["loglist"].path.each do |val|
- if val == db["logpath"]
- # 重複していた場合エラーメッセージを表示し、処理を行わない
- db["logpath"] = ""
- params["action"] = ""
- db["error"] = "<br><span style='color: #ff0000'>同一のファイルが存在します!別の名前を指定してください。</span><br>"
- checkflag = false
- return
- end
- end
-
- if checkflag
- db["loginsertindex"] = cgi["loginsertindex"].read.to_i
- db["logdisplay"] = Controller.get_mpart_value(cgi["logdisplay"])
- db["importxml"] = cgi["updata"].read
-
- # XMLの整合性をチェックします
- begin
- REXML::Document.new(Controller.fix_updata_enc(db["importxml"].to_s))
- rescue => exception
- db["error"] = "<br><span style='color: #ff0000'>不正な整形のXMLです!ファイルを見直してください。</span><br>"
- db["error"] << "<div class='divstyle' style='width: 560px; color: #ff0000; text-align: left;'>"
- db["error"] << CGI.escapeHTML(exception.to_s).gsub("\n", "<br>")
- db["error"] << "</div>"
- params["action"] = ""
- return
- end
- end
-
- # 0位置への挿入防止
- if db["loginsertindex"] == 0
- params["action"] = ""
- db["error"] = "<br><span style='color: #ff0000'>ラジオボックスでログの挿入位置を選択してください!</span><br>"
- return
- end
-
- if db["logpath"] == FEEDXMLDIR || db["logdisplay"].blank?
- params["action"] = ""
- db["error"] = "<br><span style='color: #ff0000'>インポートファイル、及び、ログの表示名は空欄にできません。</span><br>"
- return
- end
-
- else
- end
-
- # diary.xmlを入れ替える処理
- when "replace"
- case params["action"]
- when "exec"
- # この段階のエラーに対しては強度のエラーを発する
- checkflag = true
- db["logpath"] = Controller.get_mpart_value(cgi["logpath"])
- db["loglist"].path.each do |val|
- if val == db["logpath"]
- # 重複していた場合エラーメッセージを表示し、処理を行わない
- params["action"] = ""
- params["mode"] = "error"
- db["error"] = "ログファイルの追加中に重大なエラーが発生しました。"
- return
- end
- end
-
- db["logdisplay"] = Controller.get_mpart_value(cgi["logdisplay"])
-
- if File.basename(db["logpath"]).blank? || db["logdisplay"].blank? || db["importxml"].blank?
- params["action"] = ""
- params["mode"] = "error"
- db["error"] = "ログファイルの追加中に重大なエラーが発生しました。"
- return
- end
-
- # diary.xmlを移動します
- FileUtils.move(XMLPATH + INITIALXML, XMLPATH + File.basename(db["logpath"]))
- # ファイルをアップロードします
- file = FileUploader.new
- file.upload(INITIALXML, db["importxml"])
-
- # loglist.xmlを更新します
- db["loglist"].path[1, 0] = db["logpath"]
- db["loglist"].display[1, 0] = db["logdisplay"]
- db["loglist"].to_xml
-
- # 情報を更新します
- db["loglist"] = LogList.readxml(LISTXMLPATH)
- session["filepath"] = db["loglist"].path[0] if session["filepath"] == nil
- db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))
- db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))
-
- when "confirm"
- # 入力されたログファイルパスが既に存在するかを確認
- checkflag = true
- db["logpath"] = Controller.get_mpart_value(cgi["logpath"])
- db["loglist"].path.each do |val|
- if val == db["logpath"]
- # 重複していた場合エラーメッセージを表示し、処理を行わない
- params["action"] = ""
- db["error"] = "<br><span style='color: #ff0000'>同一のファイルが存在します!別の名前を指定してください。</span><br>"
- checkflag = false
- return
- end
- end
-
- if checkflag == true
- db["logdisplay"] = Controller.get_mpart_value(cgi["logdisplay"])
- db["importxml"] = cgi["updata"].read
-
- # XMLの整合性をチェックします
- begin
- REXML::Document.new(Controller.fix_updata_enc(db["importxml"].to_s))
- rescue => exception
- db["error"] = "<br><span style='color: #ff0000'>不正な整形のXMLです!ファイルを見直してください。</span><br>"
- db["error"] << "<div class='divstyle' style='width: 560px; color: #ff0000; text-align: left;'>"
- db["error"] << CGI.escapeHTML(exception.to_s).gsub("\n", "<br>")
- db["error"] << "</div>"
- params["action"] = ""
- return
- end
- end
-
- if db["logpath"].blank? || db["logdisplay"].blank? || db["importxml"].blank?
- params["action"] = ""
- db["error"] = "<br><span style='color: #ff0000'>インポートファイル、及び、ログの表示名、ログのパスは空欄にできません。</span><br>"
- return
- end
-
- else
- end
-
- else
- end
- end
- end
-
- # Formのenctypeがmultypartだった場合、入力された値をrubyバージョンに左右されずに読み取るメソッドです。
- def Controller.get_mpart_value(cgi_param)
- if RUBY_VERSION >= "1.9.0"
- cgi_param[0..cgi_param.length].to_s
- else
- cgi_param.read.to_s
- end
- end
-
- # アップロードされたXMLをバージョンに左右されずに読み取るために、ruby-1.9.1以上ではエンコーディングを強制指定します
- def Controller.fix_updata_enc(file_to_s)
- if RUBY_VERSION >= "1.9.0"
- file_to_s.force_encoding("UTF-8")
- else
- file_to_s
- end
- end
-
-end
-
-def main
- # SESSION変数、パラメータなどを取得します
- cgi = CGI.new
- session = CGI::Session.new(cgi)
- params = Hash[*cgi.params.to_a.map{|k, v| [k, v[0].to_s]}.flatten]
-
- # コントローラー部分
- # セッション管理
- if session["login"] != "true"
-
- # ログイン情報を確認
- LOGININFO.each {|h|
- if (cgi["loginid"] == h[:id] && cgi["password"] == h[:password])
- session["login"] = "true"
- session["name"] = h[:name]
- break
- end
- }
-
- if (session["login"] == "true")
- # ワークフォルダの中をクリーンアップします
- filelist = Dir::entries("./work")
- # 削除条件 : 最終変更日時から1日(60*60*24sec)かつ、ファイルタイプがファイルの場合
- filelist.each do |file|
- File.delete("./work/#{file}") if Time.now - File.ctime("./work/#{file}") > 86400 && File.ftype("./work/#{file}") == "file"
- end
- end
- end
-
- # ログアウト処理
- if params["mode"] == "logout"
- session["login"] = nil
- session.delete
- end
-
- begin
- # メインコントローラー
- # セッションが有効な場合のも実行します
- if session["login"] == "true"
- # PStore破損チェック!
- begin
- db = PStore.new("./work/#{session.session_id}.dat")
- db.transaction do
- db["error"] = ""
- end
- rescue
- # PStoreファイルを破棄する
- File.delete("./work/#{session.session_id}.dat")
- # PStoreが破損していた場合はセッション情報を破棄する
- session["login"] = nil
- session.delete
- end
-
- # フォームによって挙動を変更します
- if cgi["mode"].respond_to?(:read) && cgi["action"].respond_to?(:read)
- params["mode"] = cgi["mode"].read
- params["action"] = cgi["action"].read
- Controller.MultiForm(cgi, session, params, db)
- else
- Controller.NormalForm(cgi, session, params, db)
- end
-
- # エラー画面移行時はセッション情報を破棄する
- if params["mode"] == "error"
- session["login"] = nil
- session.delete
- end
- end
-
- # メニューとして表示されるHTML文字列です
- if params["target_filepath"].blank?
- menu = "<div class=\"divstyle\" style=\"width: #{TABLEWIDTH}px;\"><div class=\"divstyle\" align=\"center\" style=\"margin-bottom: 5px;\">現在編集中のファイル : #{session["filepath"]} "
- else
- menu = "<div class=\"divstyle\" style=\"width: #{TABLEWIDTH}px;\"><div class=\"divstyle\" align=\"center\" style=\"margin-bottom: 5px;\">現在編集中のファイル : #{session["target_filepath"]} "
- end
- if USEFILEMANAGER == true
- menu += "[ <a href=\"#{cgi.script_name}?mode=selectlog\">他のファイルを選択</a> ]</div>[ <a href=\"#{cgi.script_name}\">トップページ</a> | 記事管理 ( <a href=\"#{cgi.script_name}?mode=newentry\">作成</a> | <a href=\"#{cgi.script_name}?mode=editentry\">編集</a> | <a href=\"#{cgi.script_name}?mode=delentry\">消去</a> ) | <a href=\"#{cgi.script_name}?mode=editfeed\">XML情報編集</a> | <a href=\"#{cgi.script_name}?mode=log\">ログ管理</a> | <a href=\"#{cgi.script_name}?mode=import\">インポート</a> | <a href=\"#{FILEMANAGER}\" target=\"_blank\">ファイル管理</a> | <a href=\"#{cgi.script_name}?mode=reset\">初期化</a> | <a href=\"#{cgi.script_name}?mode=logout\">ログアウト</a> ]</div>"
- else
- menu += "[ <a href=\"#{cgi.script_name}?mode=selectlog\">他のファイルを選択</a> ]</div>[ <a href=\"#{cgi.script_name}\">トップページ</a> | 記事管理 ( <a href=\"#{cgi.script_name}?mode=newentry\">作成</a> | <a href=\"#{cgi.script_name}?mode=editentry\">編集</a> | <a href=\"#{cgi.script_name}?mode=delentry\">消去</a> ) | <a href=\"#{cgi.script_name}?mode=editfeed\">XML情報編集</a> | <a href=\"#{cgi.script_name}?mode=log\">ログ管理</a> | <a href=\"#{cgi.script_name}?mode=import\">インポート</a> | <a href=\"#{cgi.script_name}?mode=reset\">初期化</a> | <a href=\"#{cgi.script_name}?mode=logout\">ログアウト</a> ]</div>"
- end
-
- # ビュー部分
- # modeとactionの相関図は以下のようになります。
- # [mode] + [action]
- # + [action]
- # + [action]
- # + ... and more
- if session["login"] != "true"
- # セッションが存在しない場合は強制的にトップページに遷移
- htmlwriter = HtmlWriter.new("./erbtemp/login.html.erb", binding)
- else
- case params["mode"]
- when "selectlog"
- htmlwriter = HtmlWriter.new("./erbtemp/select.html.erb", binding)
- when "newentry"
- htmlwriter = HtmlWriter.new("./erbtemp/newentry.html.erb", binding)
- when "editentry"
- htmlwriter = HtmlWriter.new("./erbtemp/editentry.html.erb", binding)
- when "delentry"
- htmlwriter = HtmlWriter.new("./erbtemp/delentry.html.erb", binding)
- when "editfeed"
- htmlwriter = HtmlWriter.new("./erbtemp/editfeed.html.erb", binding)
- when "log"
- htmlwriter = HtmlWriter.new("./erbtemp/log.html.erb", binding)
- when "insert"
- htmlwriter = HtmlWriter.new("./erbtemp/insertfeed.html.erb", binding)
- when "replace"
- htmlwriter = HtmlWriter.new("./erbtemp/replacefeed.html.erb", binding)
- when "import"
- htmlwriter = HtmlWriter.new("./erbtemp/indeximport.html.erb", binding)
- when "reset"
- htmlwriter = HtmlWriter.new("./erbtemp/reset.html.erb", binding)
- when "error"
- htmlwriter = HtmlWriter.new("./erbtemp/error.html.erb", binding)
- else
- htmlwriter = HtmlWriter.new("./erbtemp/index.html.erb", binding)
- end
- end
- rescue => exception
- # エラーが発生した場合、それを画面に表示します
- htmlwriter = HtmlWriter.new("./erbtemp/exception.html.erb", binding)
- end
-
- # 実際にHTMLを出力します
- begin
- cgi.out{htmlwriter.to_code}
- rescue => exception
- # エラーが発生した場合、それを画面に表示します
- htmlwriter = HtmlWriter.new("./erbtemp/exception.html.erb", binding)
- cgi.out{htmlwriter.to_code}
- end
-end
-
-begin
- main
-rescue => evar
- # エラーが発生した場合、それを画面に表示します
- detail = ("%s: %s (%s)\n" %
- [evar.backtrace[0], evar.message, evar.send('class')]) +
- evar.backtrace[1..-1].join("\n")
- puts "content-type: text/html\n\n<plaintext>\n" + detail
-end
+#!/usr/local/bin/ruby\r
+# -*- coding: utf-8 -*-\r
+#\r
+#= Atom Feed 1.0を管理するWEBアプリケーション\r
+#\r
+#Autohr:: Kureha Hisame (http://lunardial.sakura.ne.jp/) & Yui Naruse (http://airemix.com/)\r
+#Version:: 3.0.0.0\r
+#Copyright:: Copyright 2009 FeedBlog Project (http://sourceforge.jp/projects/feedblog/)\r
+#License:: GPLv3\r
+\r
+require "cgi"\r
+require "cgi/session"\r
+require "erb"\r
+require "rexml/document"\r
+require "pstore"\r
+require 'time'\r
+require "date"\r
+require "fileutils"\r
+\r
+require "./common.rb"\r
+require "./define.rb"\r
+\r
+# = Feed/Entryのスーパークラス\r
+# \r
+# 入出力用のメソッドなど、共通する機能を提供します\r
+class AbstractEntry\r
+ # 初期化メソッドです\r
+ #\r
+ # _hash_ :: 値を格納したhash配列。superfeed.new(CGI::Session.new(new CGI).params)のようにして使う。\r
+ def initialize(hash)\r
+ # 内部データ保持用のハッシュ配列です\r
+ @attr = {}\r
+ \r
+ # 引数を格納します\r
+ @paramlist.each do |key|\r
+ val = hash[key.to_sym] || hash[key.to_s]\r
+ if val\r
+ val.strip!\r
+ val.gsub!(/\r\n|\r/, "\n")\r
+ @attr[key.to_sym] = CGI.escapeHTML(val)\r
+ else\r
+ # 空の場合の対策\r
+ @attr[key.to_sym] = ""\r
+ end\r
+ end\r
+ \r
+ # 可視・不可視を示すハッシュキーを格納する配列です\r
+ @display = {}\r
+ \r
+ # ハッシュキーの日本語説明を格納する配列です\r
+ @name = []\r
+ end\r
+ \r
+ # Accessor\r
+ attr_reader :attr, :paramlist, :name, :display\r
+ \r
+ # 内部の@attrハッシュにアクセスする手段を提供するメソッドです\r
+ #\r
+ # AbstractEntry.attr[:title]にアクセスしたい場合はAbstractEntry.titleで可能になります。\r
+ # AbstractEntry.send("title")という方法でもアクセス可能です。\r
+ def method_missing(methname, *args)\r
+ methname = methname.to_s\r
+ \r
+ if methname[-1] == ?=\r
+ # setter\r
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 1)" unless args.length == 1\r
+ methname.chop!\r
+ methname = @paramlist.find{|par|par == methname}\r
+ return @attr[methname.to_sym] = args[0] if methname\r
+ else\r
+ # getter\r
+ raise ArgumentError, "wrong number of arguments (#{args.length} for 0)" unless args.empty?\r
+ return @attr[methname.to_sym] if @attr.key?(methname.to_sym)\r
+ end\r
+ # attr上にキーがない値を入れようとした場合はNoMethodError\r
+ raise NoMethodError\r
+ end\r
+ \r
+ def [](key)\r
+ @attr[key.to_sym]\r
+ end\r
+ \r
+ def []=(key, value)\r
+ @attr[key.to_sym] = value\r
+ end\r
+end\r
+\r
+# = Feedクラス\r
+#\r
+# Feedの基礎情報を保有するクラスです\r
+class Feed < AbstractEntry\r
+ # 初期化メソッドです\r
+ #\r
+ # _hash_ :: 値を格納したhash配列。feed.new(CGI::Session.new(new CGI).params)のようにして使います。\r
+ def initialize(hash)\r
+ # 内部データ保持用のハッシュ配列です\r
+ @attr = {}\r
+ \r
+ # 内部データの項目名を格納する配列です\r
+ @paramlist = ["feedattr", "title", "subtitle", "self", "url", "updated", "feedid", "rights", "aname", "amail", "others"]\r
+ \r
+ # AbstractEntryのinitializeメソッドを呼び出し、値を@attr配列に格納します\r
+ super(hash)\r
+ \r
+ # 可視・不可視を示すハッシュキーを格納する配列です\r
+ @display = {"feedattr" => "none", "title" => "", "subtitle" => "", \r
+ "self" => "", "url" => "", \r
+ "updated" => "none", "feedid" => "", \r
+ "rights" => "", "aname" => "", \r
+ "amail" => "", "others" => "none"}\r
+ \r
+ # デバッグモードの場合、全ての入力要素を表示します\r
+ if DEBUG == true\r
+ @display.each do |key, val|\r
+ @display[key] = ""\r
+ end\r
+ end\r
+ \r
+ # ハッシュキーの日本語説明を格納する配列です\r
+ @name = {"feedattr" => "feedの保持している属性", "title" => "ウェブページのタイトル", "subtitle" => "ウェブページの簡単な説明", \r
+ "self" => "このXMLファイルのURL", "url" => "ウェブページのURL", \r
+ "updated" => "XMLファイルの最終更新日", "feedid" => "あなたのページ独自のID", \r
+ "rights" => "ページの著作権表記", "aname" => "ページの製作者", \r
+ "amail" => "ページ製作者のメールアドレス", "others" => "その他の要素"}\r
+ \r
+ end\r
+ \r
+ # Atom XMLファイルを読み込んで解析し、等価なFeedオブジェクトを返却するメソッドです\r
+ #\r
+ # _path_ :: Atom XMLファイルのパス\r
+ def self.readxml(path)\r
+ \r
+ # ファイルを読み込みます\r
+ doc = REXML::Document.new(myopen(path, "r:utf-8"){|f|f.read})\r
+ xml = {}\r
+ others = []\r
+ \r
+ # Feedの属性値を取得します\r
+ xmlattr = []\r
+ doc.elements["feed"].attributes.each_attribute do |attr|\r
+ xmlattr.push("#{attr.to_string} ")\r
+ end\r
+ xml[:feedattr] = xmlattr.join("\n").gsub(/"/, "'")\r
+ \r
+ # XML解析部分です。各element毎に判定を行います\r
+ doc.elements.each("feed") do |elm|\r
+ elm.elements.each { |child|\r
+ begin\r
+ case child.name\r
+ when "id"\r
+ xml[:feedid] = child.text\r
+ when "title", "subtitle", "updated", "rights"\r
+ xml[child.name.to_sym] = child.text\r
+ when "author"\r
+ child.elements.each do |gchild|\r
+ case gchild.name\r
+ when "name"\r
+ xml[:aname] = gchild.text\r
+ when "email"\r
+ xml[:amail] = gchild.text\r
+ end\r
+ end\r
+ when "link"\r
+ child.attributes.each do |k, v|\r
+ if k == "rel"\r
+ if v == "self"\r
+ xml[:self] = child.attributes["href"]\r
+ elsif v == "alternate"\r
+ xml[:url] = child.attributes["href"]\r
+ end\r
+ end\r
+ end\r
+ when "entry"\r
+ # Entry要素は無視します\r
+ else\r
+ # 上記判定以外の全要素は配列に格納します\r
+ others.push(child.to_s)\r
+ end\r
+ rescue NoMethodError\r
+ end\r
+ \r
+ }\r
+ end\r
+ \r
+ # Others要素を結合して代入します\r
+ xml[:others] = others.join("\n")\r
+ feed = Feed.new(xml)\r
+ return feed\r
+ end\r
+ \r
+ # 内部に保持している情報を、Atom Feed1.0形式の文字列に出力するメソッドです\r
+ def to_s\r
+ buf = []\r
+ \r
+ # buf.push("<feed #{@attr[:feedattr]}>")\r
+ buf.push("<feed xml:lang='ja-jp' xmlns='http://www.w3.org/2005/Atom'>");\r
+ buf.push("<title type=\"text\">#{@attr[:title]}</title>")\r
+ buf.push("<subtitle type=\"text\">#{@attr[:subtitle]}</subtitle>")\r
+ buf.push("<link rel=\"self\" type=\"application/atom+xml\" href=\"#{@attr[:self]}\" />")\r
+ buf.push("<link rel=\"alternate\" type=\"text/html\" href=\"#{@attr[:url]}\" />")\r
+ buf.push("<updated>#{Time.now.iso8601}</updated>")\r
+ buf.push("<id>#{@attr[:feedid]}</id>")\r
+ buf.push("<rights type=\"text\">#{@attr[:rights]}</rights>")\r
+ buf.push("<author>")\r
+ buf.push("\t<name>#{@attr[:aname]}</name>")\r
+ buf.push("\t<email>#{@attr[:amail]}</email>")\r
+ buf.push("</author>")\r
+ buf.push("#{CGI.unescapeHTML(@attr[:others])}") if @attr[:others] != ""\r
+ \r
+ return buf.join("\n")\r
+ end\r
+ \r
+ # Feed情報更新メソッド\r
+ def self.update(path, feed)\r
+ entrylist = Entry.readxml(path)\r
+ Feed.to_xml(path, feed, entrylist)\r
+ \r
+ true\r
+ end\r
+ \r
+ # XMLファイル出力用メソッドです\r
+ #\r
+ # _feed_ :: Feedオブジェクト\r
+ # _entry_ :: Entryオブジェクトの配列\r
+ def self.to_xml(path, feed, entrylist_tmp)\r
+ buf = []\r
+ entrylist = entrylist_tmp.dup\r
+ buf.push("<?xml version=\"1.0\" encoding=\"utf-8\"?>")\r
+ buf.push("#{feed.to_s}\n")\r
+ entrylist.each { |entry|\r
+ if REPLACEENTRYIDANDURL\r
+ entry.entryid.gsub!(/^[^\?]*\?/, "")\r
+ entry.entryid = feed.url + "?" + entry.entryid\r
+ entry.url = feed.url + "#" + entry.entryid\r
+ end\r
+ buf.push("#{entry.to_s}\n")\r
+ }\r
+ buf.push("</feed>")\r
+ \r
+ myopen(path, "w") do |f|\r
+ f.print buf.join("\n")\r
+ end\r
+ end\r
+ \r
+ # XMLファイル出力用メソッドです\r
+ #\r
+ # _feed_ :: Feedオブジェクト\r
+ # _entry_ :: Entryオブジェクトの配列\r
+ def self.to_xml_plain(path, feed, entrylist)\r
+ buf = []\r
+ buf.push("<?xml version=\"1.0\" encoding=\"utf-8\"?>")\r
+ buf.push("#{feed.to_s}\n")\r
+ entrylist.each { |entry|\r
+ buf.push("#{entry.to_s}\n")\r
+ }\r
+ buf.push("</feed>")\r
+ \r
+ myopen(path, "w") do |f|\r
+ f.print buf.join("\n")\r
+ end\r
+ end\r
+ \r
+end\r
+\r
+# = Entryクラス\r
+#\r
+# Entryの基礎情報を保有するクラスです\r
+class Entry < AbstractEntry\r
+ # 初期化メソッドです\r
+ #\r
+ # _hash_ :: 値を格納したhash配列。entry.new(CGI::Session.new(new CGI).params)のようにして使います。\r
+ def initialize(hash)\r
+ # 内部データ保持用のハッシュ配列です\r
+ @attr = {}\r
+ \r
+ # 内部データの項目名を格納する配列です\r
+ @paramlist = ["entryid", "title", "summary", "published", "updated", "url", "content", "others"]\r
+ \r
+ # AbstractEntryのinitializeメソッドを呼び出し、値を@attr配列に格納します\r
+ super(hash)\r
+ \r
+ # 可視・不可視を示すハッシュキーを格納する配列です\r
+ @display = {"entryid" => "none", "title" => "",\r
+ "summary" => "", "published" => "none",\r
+ "updated" => "none", "url" => "",\r
+ "content" => "", "others"=>"none"}\r
+ \r
+ # デバッグモードの場合、全ての入力要素を表示します\r
+ if DEBUG == true\r
+ @display.each do |key, val|\r
+ @display[key] = ""\r
+ end\r
+ end\r
+ \r
+ # ハッシュキーの日本語説明を格納する配列です\r
+ @name = {"entryid" => "記事固有のID", "title" => "記事のタイトル",\r
+ "summary" => "記事の簡単な説明", "published" => "記事の出版時刻",\r
+ "updated" => "記事の更新時刻", "url" => "記事へのURLアドレス",\r
+ "content" => "記事の本文", "others"=>"その他の項目"}\r
+ end\r
+ \r
+ # Atom XMLファイルを読み込んで解析し、等価なEntryオブジェクト配列を返却するメソッドです\r
+ #\r
+ # _path_ :: Atom XMLファイルのパス\r
+ def self.readxml(path)\r
+ \r
+ # ファイルを読み込みます\r
+ doc = REXML::Document.new(myopen(path, "r:utf-8"){|f|f.read})\r
+ entrylist = []\r
+ xml = {}\r
+ \r
+ # XML解析部分です。各element毎に判定を行います\r
+ doc.elements.each("feed/entry") do |elm|\r
+ xml = {}\r
+ others = []\r
+ elm.elements.each do |child|\r
+ begin\r
+ case child.name\r
+ when "id"\r
+ xml[:entryid] = child.text\r
+ when "link"\r
+ xml[:url] = child.attributes["href"]\r
+ when "title", "summary", "summary", "published", "updated", "content"\r
+ xml[child.name.to_sym] = child.text\r
+ else\r
+ # 上記判定以外の全要素は配列に格納します\r
+ others.push(child.to_s)\r
+ end\r
+ rescue NoMethodError\r
+ end\r
+ end\r
+ # Others要素を結合して代入します\r
+ xml[:others] = others.join("\n")\r
+ entrylist.push(Entry.new(xml))\r
+ end\r
+ \r
+ return entrylist\r
+ end\r
+ \r
+ # Atom XMLファイルを読み込んで解析し、テンプレートファイルにしたがってHTMLに変換するメソッドです\r
+ def self.to_html(xmlpath, destpath, entry_temppath, html_temppath)\r
+ # 引数チェック - 全必須\r
+ if xmlpath.empty? or destpath.empty? or entry_temppath.empty? or html_temppath.empty?\r
+ raise ArgumentError\r
+ end\r
+ \r
+ # 必須ファイル存在チェック\r
+ unless File.exist?(xmlpath) and File.exist?(entry_temppath) and File.exist?(html_temppath)\r
+ raise IOError\r
+ end\r
+ \r
+ # XML読み込み\r
+ entrylist = Entry.readxml(xmlpath)\r
+ \r
+ body = ''\r
+ entrylist.each { |e|\r
+ # Entry毎のHTML表示部分を生成\r
+ body << e.to_template(entry_temppath)\r
+ }\r
+ \r
+ # HTML全体のテンプレートを生成\r
+ html_temp = HtmlWriter.new(html_temppath, binding)\r
+ \r
+ # HTMLに書き込み\r
+ myopen(destpath, 'w:utf-8') { |f|\r
+ f.write(CGI.pretty(html_temp.to_code))\r
+ }\r
+ end\r
+ \r
+ # Entryをテンプレートに沿って変形するメソッド\r
+ def to_template(temppath)\r
+ erb = HtmlWriter.new(temppath, binding)\r
+ title = CGI.unescapeHTML(@attr[:title])\r
+ date = @attr[:published]\r
+ content = CGI.unescapeHTML(@attr[:content])\r
+ erb.to_code\r
+ end\r
+ \r
+ # Entry挿入メソッド\r
+ def self.insert(path, entry)\r
+ feed = Feed.readxml(path)\r
+ entrylist = Entry.readxml(path)\r
+ entrylist.unshift entry\r
+ \r
+ Feed.to_xml(path, feed, entrylist)\r
+ \r
+ true\r
+ end\r
+ \r
+ # Entry更新メソッド\r
+ def self.update(path, entry)\r
+ feed = Feed.readxml(path)\r
+ entrylist = Entry.readxml(path)\r
+ \r
+ successed = false\r
+ entrylist.each_with_index { |e, i|\r
+ if e.entryid == entry.entryid\r
+ entrylist[i] = entry \r
+ successed = true\r
+ end\r
+ }\r
+ Feed.to_xml(path, feed, entrylist) if successed\r
+ \r
+ successed\r
+ end\r
+ \r
+ # Entryロードメソッド\r
+ def self.select(path, entryid)\r
+ feed = Feed.readxml(path)\r
+ entrylist = Entry.readxml(path)\r
+ \r
+ entry = nil\r
+ entrylist.each_with_index { |e, i|\r
+ entry = entrylist[i].dup if e.entryid == entryid\r
+ }\r
+ \r
+ entry\r
+ end\r
+ \r
+ # Entry消去メソッド\r
+ def self.delete(path, entryid)\r
+ feed = Feed.readxml(path)\r
+ entrylist = Entry.readxml(path)\r
+ \r
+ successed = false\r
+ delete_index = -1\r
+ entrylist.each_with_index { |e, i|\r
+ if e.entryid == entryid\r
+ delete_index = i\r
+ successed = true\r
+ end\r
+ }\r
+ \r
+ if successed\r
+ entrylist.delete_at delete_index\r
+ Feed.to_xml(path, feed, entrylist)\r
+ end\r
+ \r
+ successed\r
+ end\r
+ \r
+ # データソースから読み取ったHTMLを、エディタで編集可能な形式に変換するメソッドです\r
+ def content_for_generator\r
+ str = @attr[:content].dup\r
+ str.strip!\r
+ str.gsub!(/(<\/(?:p|h\d|div)(?:>|>))\n/i, '\1')\r
+ str.gsub!(/\n/, '<br>') if REPLACEBRTAG\r
+ str.gsub!(/(<(?:(?!>).)*?)#{Regexp.escape(RELAYPATH)}/) { "#$1#{HOMEBASE}" }\r
+ str\r
+ end\r
+ \r
+ # エディタで編集されたCONTENT要素を、データソースに書き込める形式に変換するメソッドです\r
+ def content_for_blog\r
+ str = @attr[:content].dup\r
+ str = CGI.unescapeHTML(str)\r
+ str.strip!\r
+ str.gsub!(/(\r\n|\n)/, "")\r
+ str.gsub!(/<br>|<br[ ]*\/>/i, "\n") if REPLACEBRTAG\r
+ str.gsub!(/(<br>|<br[ ]*\/>|<\/p>|<\/h\d>|<\/div>)(?=[^\n])/i) { "#$1\n" } unless REPLACEBRTAG\r
+ str.gsub!(/(<[^>]*?)#{Regexp.escape(HOMEBASE)}/) { "#$1#{RELAYPATH}" }\r
+ CGI.escapeHTML(str)\r
+ end\r
+ \r
+ # 確認画面で表示されるCONTENT要素を生成するメソッドです\r
+ def content_for_view\r
+ str = @attr[:content].dup\r
+ str = CGI.unescapeHTML(str)\r
+ str.strip!\r
+ str.gsub!(/<br>|<br[ ]*\/>/i, "\n") if REPLACEBRTAG\r
+ str.gsub!(/(<[^>]*?)#{Regexp.escape(RELAYPATH)}/) { "#$1#{HOMEBASE}" }\r
+ str\r
+ end\r
+ \r
+ # 内部に保持している情報を、Atom Feed1.0形式の文字列に出力するメソッドです\r
+ def to_s\r
+ buf = []\r
+ buf.push("<entry>")\r
+ buf.push("<id>#{@attr[:entryid]}</id>")\r
+ buf.push("<title>#{@attr[:title]}</title>")\r
+ buf.push("<summary>#{@attr[:summary]}</summary>")\r
+ buf.push("<published>#{@attr[:published]}</published>")\r
+ buf.push("<updated>#{@attr[:updated]}</updated>")\r
+ buf.push("<link href=\"#{@attr[:url]}\" />")\r
+ buf.push("<content type=\"html\">#{@attr[:content]}</content>")\r
+ buf.push("#{CGI.unescapeHTML(@attr[:others])}") if @attr[:others] != ""\r
+ buf.push("</entry>")\r
+ \r
+ return buf.join("\n")\r
+ end\r
+end\r
+\r
+# = LogListクラス\r
+#\r
+# loglist.xmlにかかわる入出力を行います\r
+class LogList\r
+ # 初期化メソッドです\r
+ #\r
+ # _display_ :: 画面表示用文字の配列\r
+ # _path_ :: XMLファイルパスの配列\r
+ # _logpath_ :: loglist.xmlのパス\r
+ def initialize(display, path, logpath)\r
+ @display = display\r
+ @path = path\r
+ @logpath = logpath\r
+ end\r
+ \r
+ attr_accessor :display, :path, :logpath\r
+ \r
+ # loglist.xmlファイルを読み込んで解析し、LogListオブジェクトを返却するメソッドです\r
+ #\r
+ # _logpath_ :: loglist.xmlへのパス\r
+ def LogList.readxml(logpath)\r
+ \r
+ # ファイルを読み込みます\r
+ lines = []\r
+ myopen(logpath, "r:utf-8") { |f|\r
+ lines = f.readlines\r
+ }\r
+ \r
+ doc = REXML::Document.new(lines.join("\n"))\r
+ @display = []\r
+ @path = []\r
+ \r
+ doc.elements.each("list/file") { |elm|\r
+ elm.elements.each {|child|\r
+ case child.name\r
+ when "display"\r
+ @display.push(child.text)\r
+ when "path"\r
+ @path.push(child.text)\r
+ else \r
+ # With no action\r
+ end\r
+ }\r
+ }\r
+ \r
+ return LogList.new(@display, @path, logpath)\r
+ end\r
+ \r
+ # loglist.xmlにオブジェクトの内容を反映するメソッドです\r
+ def to_xml\r
+ buf = []\r
+ buf.push("<list>")\r
+ path.each_with_index do |path, i|\r
+ buf.push("<file>")\r
+ buf.push("<display>#{@display[i]}</display>")\r
+ buf.push("<path>#{@path[i]}</path>")\r
+ buf.push("</file>")\r
+ end\r
+ buf.push("</list>")\r
+ \r
+ myopen(@logpath, "w") do |f|\r
+ f.print buf.join("\n")\r
+ end\r
+ end\r
+ \r
+end\r
+\r
+# = FileUploaderクラス\r
+#\r
+# 画像の管理を行うクラスです\r
+class FileUploader\r
+ # 初期化メソッドです\r
+ def initialize\r
+ end\r
+ \r
+ # ファイルの一覧を取得し、ファイル名称を格納した配列を返却します\r
+ def filelist\r
+ arr = Dir::entries(XMLPATH).sort\r
+ arr.delete(".")\r
+ arr.delete("..")\r
+ \r
+ return arr\r
+ end\r
+ \r
+ # ファイルの消去を実行します\r
+ #\r
+ # _name_ :: 消去するファイル名\r
+ def delete(name)\r
+ File.delete(XMLPATH + name.match(/[^\/]*?$/).to_a[0])\r
+ end\r
+ \r
+ # ファイルのアップロードを実行します\r
+ #\r
+ # _name_ :: アップロードファイルの名称\r
+ # _img_ :: アップロードファイル\r
+ def upload(name, img)\r
+ open(XMLPATH + File.basename(name), "w") do |f|\r
+ f.binmode\r
+ f.write img\r
+ end\r
+ end\r
+end\r
+\r
+# = Pluginクラス\r
+#\r
+# プラグインの処理を行うクラスです\r
+class FeedGenPluginManager\r
+ def self.exec(mode, filepath)\r
+ feed = Feed.readxml(XMLPATH + filepath)\r
+ entries = Entry.readxml(XMLPATH + filepath)\r
+ feed.freeze\r
+ entries.freeze\r
+ Dir.foreach(PLUGINDIR) do |fn|\r
+ next unless File.extname(fn) == '.rb'\r
+ require File.join(PLUGINDIR, fn)\r
+ plugin_name = "FeedGenPlugins::"\r
+ plugin_name << File.basename(fn).gsub(/\.rb\Z/, "")\r
+ plugin_ins = plugin_name.split(/::/).inject(Object) { |c,name| c.const_get(name) }\r
+ plugin_ins.new.exec(mode, feed, entries)\r
+ end\r
+ end\r
+end\r
+\r
+# = Controllerクラス\r
+#\r
+# コントローラ部分に相当する処理を受け持つクラスです\r
+class Controller\r
+ def Controller.NormalForm(cgi, session, params, db)\r
+ db.transaction do\r
+ # modeとactionの相関図は以下のようになります。\r
+ # [mode] + [action]\r
+ # + [action]\r
+ # + [action]\r
+ # + ... and more\r
+ case params["mode"]\r
+ # ログ選択画面\r
+ when "logselect"\r
+ session["filepath"] = params["logpath"]\r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ # 初期状態で選択されるログは「loglist.xml」の最上に位置するログになります\r
+ session["filepath"] = db["loglist"].path[0] if session["filepath"] == nil\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ \r
+ # 新規記事追加部分\r
+ when "newentry"\r
+ case params["action"]\r
+ # 確認画面\r
+ when "confirm"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ db["newentry"] = Entry.new(params)\r
+ db["newentry"].content = db["newentry"].content_for_blog\r
+ # 記事の追記を実際にファイルに反映\r
+ when "exec"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ successed = Entry.insert(XMLPATH + File.basename(params["target_filepath"]), Entry.new(params))\r
+ unless successed\r
+ session["error"] = "記事の新規追加に失敗しました。" \r
+ params["mode"] = "error"\r
+ else\r
+ # 成功時はプラグイン処理を実施する\r
+ FeedGenPluginManager.exec("newentry", File.basename(session["filepath"]))\r
+ session["info"] = "記事の新規作成が成功しました。"\r
+ end\r
+ # 画面を戻った際の処理\r
+ when "back"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ db["newentry"] = Entry.new(params)\r
+ else \r
+ # New Diary - Default\r
+ session["target_filepath"] = session["filepath"]\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ end\r
+ \r
+ # 記事編集部分\r
+ when "editentry"\r
+ case params["action"]\r
+ # 編集画面\r
+ when "edit"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ session["editid"] = cgi["editid"].to_s\r
+ db["editentry"] = Entry.select(XMLPATH + File.basename(session["target_filepath"]), session["editid"])\r
+ # 確認画面\r
+ when "confirm"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ session["editid"] = cgi["editid"].to_s\r
+ db["editentry"] = Entry.new(params)\r
+ db["editentry"].content = db["editentry"].content_for_blog\r
+ # 記事の変更を実際にファイルに反映\r
+ when "exec"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ successed = Entry.update(XMLPATH + File.basename(params["target_filepath"]), Entry.new(params))\r
+ unless successed\r
+ session["error"] = "記事の編集処理に失敗しました。該当の日記が既に存在しない可能性があります。" \r
+ params["mode"] = "error"\r
+ else\r
+ # 成功時はプラグイン処理を実施する\r
+ FeedGenPluginManager.exec("editentry", File.basename(session["filepath"]))\r
+ session["info"] = "記事の編集が完了しました。"\r
+ \r
+ # 一覧を更新後の内容で更新する。\r
+ session["target_filepath"] = session["filepath"]\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ end\r
+ when "back"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ db["editentry"] = Entry.new(params)\r
+ else\r
+ # Edit Diary - Default\r
+ session["target_filepath"] = session["filepath"]\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ end\r
+ \r
+ # 記事削除部分\r
+ when "delentry"\r
+ case params["action"]\r
+ # 確認画面\r
+ when "confirm"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ session["delid"] = cgi["delid"].to_s\r
+ db["delentry"] = Entry.select(XMLPATH + File.basename(session["target_filepath"]), session["delid"])\r
+ # 記事の削除を実際にファイルに反映\r
+ when "exec"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ successed = Entry.delete(XMLPATH + File.basename(params["target_filepath"]), cgi["delid"].to_s)\r
+ unless successed\r
+ session["error"] = "日記の編集処理に失敗しました。該当の日記が既に存在しない可能性があります。" \r
+ params["mode"] = "error"\r
+ else\r
+ # 成功時はプラグイン処理を実施する\r
+ FeedGenPluginManager.exec("delentry", File.basename(session["filepath"]))\r
+ session["info"] = "記事の削除に成功しました。"\r
+ \r
+ # 内容を更新する\r
+ session["target_filepath"] = session["filepath"]\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ end\r
+ when "back"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["target_filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["target_filepath"]))\r
+ else\r
+ # Delete Diary - Default\r
+ session["target_filepath"] = session["filepath"]\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ end\r
+ \r
+ # Feed情報変更部分\r
+ when "editfeed"\r
+ case params["action"]\r
+ # 確認画面\r
+ when "confirm"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ db["feed"] = Feed.new(params)\r
+ # 実際にFeed情報の変更をファイルに反映\r
+ when "back"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ db["feed"] = Feed.new(params)\r
+ when "exec"\r
+ session["target_filepath"] = params["target_filepath"]\r
+ Feed.update(XMLPATH + File.basename(params["target_filepath"]), Feed.new(params))\r
+ session["info"] = "基本情報の更新が完了しました。"\r
+ else\r
+ session["target_filepath"] = session["filepath"]\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ end\r
+ \r
+ # ログ編集モード\r
+ when "log"\r
+ # 必ず内部データをリフレッシュする\r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ case params["action"]\r
+ # ログファイルの編集を実際にファイルに反映\r
+ when "addexec"\r
+ # エラーチェック。この段階のエラーは強度のエラーを発する。\r
+ db["loglist"].path.each do |val|\r
+ if val == cgi["logpath"]\r
+ # 重複していた場合エラーメッセージを表示し、処理を行わない\r
+ params["action"] = ""\r
+ params["mode"] = "error"\r
+ session["error"] = "ログファイルの追加中に重大なエラーが発生しました。環境を見直してください。"\r
+ return\r
+ end\r
+ end\r
+ \r
+ # 入力された内容を保持する配列に追加\r
+ db["loglist"].path[1, 0] = cgi["logpath"]\r
+ db["loglist"].display[1, 0] = cgi["logdisplay"]\r
+ db["loglist"].to_xml\r
+ # 既存のdiary.xmlを指定された名称でコピーして保存\r
+ FileUtils.copy_file(XMLPATH + File.basename(db["loglist"].path[0]), XMLPATH + File.basename(db["logpath"]), true)\r
+ # 保持している情報を更新する\r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ db["entry"] = []\r
+ # 新たなdiary.xmlを生成。この際保持する情報は同一のFeedオブジェクトnew()\r
+ Feed.to_xml(XMLPATH + File.basename(db["loglist"].path[0]), db["feed"], [])\r
+ \r
+ session["info"] = "ログファイルの追加が完了しました。"\r
+ \r
+ # 現在編集中のデータを強制的に最上のファイルパスに変更\r
+ session["filepath"] = db["loglist"].path[0]\r
+ \r
+ # 前月の時刻を作成します\r
+ prevmonth = (DateTime.now << 1)\r
+ \r
+ # 前月の時刻を元に、ディフォルト書式を生成します\r
+ db["logpath"] = FEEDXMLDIR + prevmonth.strftime("%Y%m") + ".xml"\r
+ db["logdisplay"] = prevmonth.strftime("%Y年%m月").gsub("年0", "年")\r
+ \r
+ # 確認画面\r
+ when "addconfirm"\r
+ # 入力されたログが既に存在するかを確認\r
+ db["loglist"].path.each do |val|\r
+ if val == cgi["logpath"]\r
+ # 重複していた場合エラーメッセージを表示し、処理を行わない\r
+ params["action"] = ""\r
+ session["error"] = "同一のファイルが存在します!別の名前を指定してください。"\r
+ return\r
+ end\r
+ end\r
+ \r
+ db["logpath"] = cgi["logpath"]\r
+ db["logdisplay"] = cgi["logdisplay"]\r
+ \r
+ if db["logpath"].blank? || db["logdisplay"].blank?\r
+ params["action"] = ""\r
+ end\r
+ \r
+ when "back"\r
+ \r
+ # 削除確認画面\r
+ when "delconfirm"\r
+ db["logdelindex"] = params["logdelindex"].to_i\r
+ \r
+ if db["logdelindex"] < 1\r
+ session["error"] = "ログファイルの削除パラメタが不正です。"\r
+ params["action"] = ""\r
+ end\r
+ \r
+ # 削除処理\r
+ when "delexec"\r
+ if cgi["logdelindex"].to_i < 1\r
+ params["action"] = ""\r
+ params["mode"] = "error"\r
+ session["error"] = "ログファイルの削除中に重大なエラーが発生しました。環境を見直してください。"\r
+ return\r
+ else\r
+ # 記事ファイルを削除します\r
+ File.delete(XMLPATH + File.basename(db["loglist"].path[db["logdelindex"]]))\r
+ # ログリストから削除します\r
+ db["loglist"].path.delete_at(cgi["logdelindex"].to_i)\r
+ db["loglist"].display.delete_at(cgi["logdelindex"].to_i)\r
+ db["loglist"].to_xml\r
+ # 保持している情報を更新する\r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ db["entry"] = []\r
+ \r
+ session["info"] = "ログファイルの削除が完了しました。"\r
+ \r
+ # 現在編集中のデータを強制的に最上のファイルパスに変更\r
+ session["filepath"] = db["loglist"].path[0]\r
+ \r
+ # 前月の時刻を作成します\r
+ prevmonth = (DateTime.now << 1)\r
+ \r
+ # 前月の時刻を元に、ディフォルト書式を生成します\r
+ db["logpath"] = FEEDXMLDIR + prevmonth.strftime("%Y%m") + ".xml"\r
+ db["logdisplay"] = prevmonth.strftime("%Y年%m月").gsub("年0", "年")\r
+ end\r
+ \r
+ # 編集画面\r
+ when "edit"\r
+ db["logeditindex"] = params["logdelindex"].to_i\r
+ \r
+ db["logpath"] = db["loglist"].path[db["logeditindex"]]\r
+ db["logdisplay"] = db["loglist"].display[db["logeditindex"]]\r
+ \r
+ if db["logeditindex"] == 0\r
+ session["error"] = "ログファイルの編集パラメタが不正です。"\r
+ params["action"] = ""\r
+ end\r
+ \r
+ # 編集確認画面\r
+ when "editconfirm"\r
+ checkflag = true\r
+ db["loglist"].path.each_with_index do |val, i|\r
+ if db["logeditindex"] != i\r
+ if params["logpath"].to_s == db["loglist"].path[i].to_s\r
+ checkflag = false\r
+ end\r
+ end\r
+ end\r
+ \r
+ if checkflag == false\r
+ params["action"] = "edit"\r
+ session["error"] = "同一のファイルが存在します!別の名前を指定してください。"\r
+ else\r
+ db["loginsertindex"] = params["loginsertindex"].to_i\r
+ \r
+ db["logpath"] = params["logpath"].to_s\r
+ db["logdisplay"] = params["logdisplay"].to_s\r
+ end\r
+ \r
+ # 編集実行\r
+ when "editexec"\r
+ checkflag = true\r
+ db["loglist"].path.each_with_index do |val, i|\r
+ if db["logeditindex"] != i\r
+ if params["logpath"].to_s == db["loglist"].path[i].to_s\r
+ checkflag = false\r
+ end\r
+ end\r
+ end\r
+ \r
+ if checkflag == false\r
+ params["action"] = ""\r
+ params["mode"] = "error"\r
+ session["error"] = "ログファイルの編集中に重大なエラーが発生しました。環境を見直してください。"\r
+ return\r
+ else\r
+ db["loginsertindex"] = params["loginsertindex"].to_i\r
+ \r
+ db["logpath"] = params["logpath"].to_s\r
+ db["logdisplay"] = params["logdisplay"].to_s\r
+ \r
+ # ファイルを移動します\r
+ if XMLPATH + File.basename(db["loglist"].path[db["logeditindex"]]) != XMLPATH + File.basename(db["logpath"])\r
+ FileUtils.move(XMLPATH + File.basename(db["loglist"].path[db["logeditindex"]]), XMLPATH + File.basename(db["logpath"]))\r
+ # ログリストを更新します\r
+ db["loglist"].path.delete_at(db["logeditindex"])\r
+ db["loglist"].display.delete_at(db["logeditindex"])\r
+ db["loglist"].path.insert(db["loginsertindex"] + 1, db["logpath"])\r
+ db["loglist"].display.insert(db["loginsertindex"] + 1, db["logdisplay"])\r
+ db["loglist"].to_xml\r
+ end\r
+ \r
+ session["info"] = "ログファイルの編集が完了しました。"\r
+ \r
+ # 現在編集中のデータを強制的に最上のファイルパスに変更\r
+ session["filepath"] = db["loglist"].path[0]\r
+ \r
+ # 前月の時刻を作成します\r
+ prevmonth = (DateTime.now << 1)\r
+ \r
+ # 前月の時刻を元に、ディフォルト書式を生成します\r
+ db["logpath"] = FEEDXMLDIR + prevmonth.strftime("%Y%m") + ".xml"\r
+ db["logdisplay"] = prevmonth.strftime("%Y年%m月").gsub("年0", "年")\r
+ end\r
+ \r
+ # 初期表示画面\r
+ else\r
+ # 現在編集中のデータを強制的に最上のファイルパスに変更\r
+ session["filepath"] = db["loglist"].path[0]\r
+ \r
+ # 前月の時刻を作成します\r
+ prevmonth = (DateTime.now << 1)\r
+ \r
+ # 前月の時刻を元に、ディフォルト書式を生成します\r
+ db["logpath"] = FEEDXMLDIR + prevmonth.strftime("%Y%m") + ".xml"\r
+ db["logdisplay"] = prevmonth.strftime("%Y年%m月").gsub("年0", "年")\r
+ end\r
+ \r
+ # インポートモードの場合の処理\r
+ when "import"\r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ \r
+ # リセットモードの場合の処理\r
+ when "reset"\r
+ case params["action"]\r
+ # リセット実行時の処理\r
+ when "exec"\r
+ file = FileUploader.new\r
+ file.filelist().each { |fname|\r
+ file.delete(fname) if File.ftype(XMLPATH + fname) == "file"\r
+ }\r
+ \r
+ # 全ファイルの初期化を実行する\r
+ # loglist.xmlの初期化\r
+ loglist = LogList.new(["最新の記事"], ["#{FEEDXMLDIR}#{INITIALXML}"], LISTXMLPATH)\r
+ loglist.to_xml\r
+ \r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ \r
+ # diary.xmlの初期化\r
+ Feed.to_xml(XMLPATH + db["loglist"].path[0].match(/[^\/]*?$/).to_a[0], Feed.new({}), [])\r
+ \r
+ # 初期の編集ファイルはloglist.xml上の最も上のファイル\r
+ session["filepath"] = db["loglist"].path[0]\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ \r
+ # 画面の遷移先をトップページにする\r
+ params["mode"] = ""\r
+ params["action"] = ""\r
+ # パラメタ無しの処理\r
+ else\r
+ # ファイル一覧を取得する\r
+ filelist = FileUploader.new.filelist()\r
+ \r
+ # タイプがファイルのみリストとして取得する\r
+ db["filelist"] = []\r
+ filelist.each { |fname| db["filelist"] << fname if File.ftype(XMLPATH + fname) == "file"}\r
+ end\r
+ \r
+ # ログイン時の画面\r
+ else\r
+ # loglist.xmlが存在するかチェック\r
+ if File.exist?(LISTXMLPATH) == false\r
+ # なかった場合はloglist.xmlを自動生成\r
+ loglist = LogList.new(["最新の記事"], ["#{FEEDXMLDIR}#{INITIALXML}"], LISTXMLPATH)\r
+ loglist.to_xml\r
+ Feed.to_xml(XMLPATH + File.basename(loglist.path[0]), Feed.new({}), [])\r
+ end\r
+ \r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ \r
+ # diary.xmlが存在するかチェック\r
+ if File.exist?(XMLPATH + File.basename(db["loglist"].path[0])) == false\r
+ # なかった場合はdiary.xmlを自動生成\r
+ Feed.to_xml(XMLPATH + File.basename(db["loglist"].path[0]), Feed.new({}), [])\r
+ end\r
+ \r
+ # 初期の編集ファイルはloglist.xml上の最も上のファイル\r
+ session["filepath"] = db["loglist"].path[0] if session["filepath"] == nil\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ end\r
+ end\r
+ end\r
+ \r
+ # マルチパートフォームの場合の処理です\r
+ def Controller.MultiForm(cgi, session, params, db)\r
+ db.transaction do\r
+ # loglist.xmlをロードします\r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ case params["mode"]\r
+ # 特定位置に挿入する場合の処理\r
+ when "insert"\r
+ case params["action"]\r
+ when "exec"\r
+ # この段階のエラーに対しては強度のエラーを発する\r
+ checkflag = true\r
+ db["logpath"] = Controller.get_mpart_value(cgi["logpath"])\r
+ db["loglist"].path.each do |val|\r
+ if val == db["logpath"]\r
+ # 重複していた場合エラーメッセージを表示し、処理を行わない\r
+ db["logpath"] = ""\r
+ params["action"] = ""\r
+ params["mode"] = "error"\r
+ session["error"] = "ログファイルの追加中に重大なエラーが発生しました。"\r
+ return\r
+ end\r
+ end\r
+ \r
+ db["loginsertindex"] = cgi["loginsertindex"].read.to_i\r
+ db["logdisplay"] = Controller.get_mpart_value(cgi["logdisplay"])\r
+ \r
+ # 0位置への挿入防止\r
+ if db["loginsertindex"] == 0\r
+ params["action"] = ""\r
+ params["mode"] = "error"\r
+ session["error"] = "ログファイルの追加中に重大なエラーが発生しました。"\r
+ return\r
+ end\r
+ \r
+ if File.basename(db["logpath"]).blank? || db["logdisplay"].blank?\r
+ params["action"] = ""\r
+ params["mode"] = "error"\r
+ session["error"] = "ログファイルの追加中に重大なエラーが発生しました。"\r
+ return\r
+ end\r
+ \r
+ # ファイルを実際にアップロードします\r
+ file = FileUploader.new\r
+ file.upload(db["logpath"], db["importxml"])\r
+ \r
+ # loglist.xmlを更新します\r
+ db["loglist"].path[db["loginsertindex"], 0] = db["logpath"]\r
+ db["loglist"].display[db["loginsertindex"], 0] = db["logdisplay"]\r
+ db["loglist"].to_xml\r
+ \r
+ # 情報を更新します\r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ session["filepath"] = db["loglist"].path[0] if session["filepath"] == nil\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ \r
+ session["info"] = "ログファイルのインポート処理が完了しました。"\r
+ \r
+ when "confirm"\r
+ # 入力されたログファイルパスが既に存在するかを確認\r
+ checkflag = true\r
+ db["logpath"] = Controller.get_mpart_value(cgi["logpath"])\r
+ db["loglist"].path.each do |val|\r
+ if val == db["logpath"]\r
+ # 重複していた場合エラーメッセージを表示し、処理を行わない\r
+ db["logpath"] = ""\r
+ params["action"] = ""\r
+ session["error"] = "同一のファイルが存在します!別の名前を指定してください。"\r
+ checkflag = false\r
+ return\r
+ end\r
+ end\r
+ \r
+ if checkflag\r
+ db["loginsertindex"] = cgi["loginsertindex"].read.to_i\r
+ db["logdisplay"] = Controller.get_mpart_value(cgi["logdisplay"])\r
+ db["importxml"] = cgi["updata"].read\r
+ \r
+ # XMLの整合性をチェックします\r
+ begin\r
+ REXML::Document.new(Controller.fix_updata_enc(db["importxml"].to_s))\r
+ rescue => exception\r
+ session["error"] = "不正な整形のXMLです!ファイルを見直してください。<br>"\r
+ session["error"] << CGI.escapeHTML(exception.to_s).gsub("\n", "<br>")\r
+ params["action"] = ""\r
+ return\r
+ end\r
+ end\r
+ \r
+ # 0位置への挿入防止\r
+ if db["loginsertindex"] == 0\r
+ params["action"] = ""\r
+ session["error"] = "ラジオボックスでログの挿入位置を選択してください!"\r
+ return\r
+ end\r
+ \r
+ if db["logpath"] == FEEDXMLDIR || db["logdisplay"].blank?\r
+ params["action"] = ""\r
+ session["error"] = "インポートファイル、及び、ログの表示名は空欄にできません。"\r
+ return\r
+ end\r
+ \r
+ else\r
+ end\r
+ \r
+ # diary.xmlを入れ替える処理\r
+ when "replace"\r
+ case params["action"]\r
+ when "exec"\r
+ # この段階のエラーに対しては強度のエラーを発する\r
+ checkflag = true\r
+ db["logpath"] = Controller.get_mpart_value(cgi["logpath"])\r
+ db["loglist"].path.each do |val|\r
+ if val == db["logpath"]\r
+ # 重複していた場合エラーメッセージを表示し、処理を行わない\r
+ params["action"] = ""\r
+ params["mode"] = "error"\r
+ session["error"] = "ログファイルの追加中に重大なエラーが発生しました。"\r
+ return\r
+ end\r
+ end\r
+ \r
+ db["logdisplay"] = Controller.get_mpart_value(cgi["logdisplay"])\r
+ \r
+ if File.basename(db["logpath"]).blank? || db["logdisplay"].blank? || db["importxml"].blank?\r
+ params["action"] = ""\r
+ params["mode"] = "error"\r
+ session["error"] = "ログファイルの追加中に重大なエラーが発生しました。"\r
+ return\r
+ end\r
+ \r
+ # diary.xmlを移動します\r
+ FileUtils.move(XMLPATH + INITIALXML, XMLPATH + File.basename(db["logpath"]))\r
+ # ファイルをアップロードします\r
+ file = FileUploader.new\r
+ file.upload(INITIALXML, db["importxml"])\r
+ \r
+ # loglist.xmlを更新します\r
+ db["loglist"].path[1, 0] = db["logpath"]\r
+ db["loglist"].display[1, 0] = db["logdisplay"]\r
+ db["loglist"].to_xml\r
+ \r
+ # 情報を更新します\r
+ db["loglist"] = LogList.readxml(LISTXMLPATH)\r
+ session["filepath"] = db["loglist"].path[0] if session["filepath"] == nil\r
+ db["feed"] = Feed.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ db["entry"] = Entry.readxml(XMLPATH + File.basename(session["filepath"]))\r
+ \r
+ session["info"] = "ログファイルのインポート処理が完了しました。"\r
+ \r
+ when "confirm"\r
+ # 入力されたログファイルパスが既に存在するかを確認\r
+ checkflag = true\r
+ db["logpath"] = Controller.get_mpart_value(cgi["logpath"])\r
+ db["loglist"].path.each do |val|\r
+ if val == db["logpath"]\r
+ # 重複していた場合エラーメッセージを表示し、処理を行わない\r
+ params["action"] = ""\r
+ session["error"] = "同一のファイルが存在します!別の名前を指定してください。"\r
+ checkflag = false\r
+ return\r
+ end\r
+ end\r
+ \r
+ if checkflag == true\r
+ db["logdisplay"] = Controller.get_mpart_value(cgi["logdisplay"])\r
+ db["importxml"] = cgi["updata"].read\r
+ \r
+ # XMLの整合性をチェックします\r
+ begin\r
+ REXML::Document.new(Controller.fix_updata_enc(db["importxml"].to_s))\r
+ rescue => exception\r
+ session["error"] = "不正な整形のXMLです!ファイルを見直してください。<br>"\r
+ session["error"] << CGI.escapeHTML(exception.to_s).gsub("\n", "<br>")\r
+ params["action"] = ""\r
+ return\r
+ end\r
+ end\r
+ \r
+ if db["logpath"].blank? || db["logdisplay"].blank? || db["importxml"].blank?\r
+ params["action"] = ""\r
+ session["error"] = "インポートファイル、及び、ログの表示名、ログのパスは空欄にできません。"\r
+ return\r
+ end\r
+ \r
+ else\r
+ end\r
+ \r
+ else\r
+ end\r
+ end\r
+ end\r
+ \r
+ # Formのenctypeがmultypartだった場合、入力された値をrubyバージョンに左右されずに読み取るメソッドです。\r
+ def Controller.get_mpart_value(cgi_param)\r
+ if RUBY_VERSION >= "1.9.0"\r
+ cgi_param[0..cgi_param.length].to_s\r
+ else\r
+ cgi_param.read.to_s\r
+ end\r
+ end\r
+ \r
+ # アップロードされたXMLをバージョンに左右されずに読み取るために、ruby-1.9.1以上ではエンコーディングを強制指定します\r
+ def Controller.fix_updata_enc(file_to_s)\r
+ if RUBY_VERSION >= "1.9.0"\r
+ file_to_s.force_encoding("UTF-8")\r
+ else\r
+ file_to_s\r
+ end\r
+ end\r
+ \r
+end\r
+\r
+def main\r
+ # SESSION変数、パラメータなどを取得します\r
+ cgi = CGI.new\r
+ session = CGI::Session.new(cgi)\r
+ params = Hash[*cgi.params.to_a.map{|k, v| [k, v[0].to_s]}.flatten]\r
+ \r
+ # ロガーを作成する\r
+ logger = WebLogger.get_logger(cgi.script_name, LOG_DIR, LOG_RELEASE_MODE)\r
+ \r
+ # コントローラー部分\r
+ # セッション管理\r
+ session["info"] = ""\r
+ session["error"] = ""\r
+ if session["login"] != "true"\r
+ \r
+ # ログイン情報を確認\r
+ LOGININFO.each {|h|\r
+ if (cgi["loginid"] == h[:id] && cgi["password"] == h[:password])\r
+ session["login"] = "true"\r
+ session["name"] = h[:name]\r
+ \r
+ # ログを記録\r
+ logger.info "ログインユーザ:#{h[:id]}, IPアドレス:#{cgi.remote_addr}"\r
+ \r
+ break\r
+ end\r
+ }\r
+ \r
+ if (session["login"] == "true") \r
+ # ワークフォルダの中をクリーンアップします\r
+ filelist = Dir::entries("./work")\r
+ # 削除条件 : 最終変更日時から1日(60*60*24sec)かつ、ファイルタイプがファイルの場合\r
+ filelist.each do |file|\r
+ File.delete("./work/#{file}") if Time.now - File.ctime("./work/#{file}") > 86400 && File.ftype("./work/#{file}") == "file"\r
+ end\r
+ end\r
+ \r
+ # ログイン失敗ユーザを記録\r
+ if (session["login"] != "true" and (cgi["loginid"] != "" or cgi["password"] != ""))\r
+ logger.info "次のアクセスがログインに失敗しました。ログインユーザ:#{cgi["loginid"]}, IPアドレス:#{cgi.remote_addr}"\r
+ end\r
+ end\r
+ \r
+ # ログアウト処理\r
+ if params["mode"] == "logout"\r
+ session["login"] = nil\r
+ session.delete\r
+ end\r
+ \r
+ begin\r
+ # メインコントローラー\r
+ # セッションが有効な場合のも実行します\r
+ if session["login"] == "true"\r
+ # PStore破損チェック!\r
+ begin\r
+ db = PStore.new("./work/#{session.session_id}.dat")\r
+ db.transaction do\r
+ session["error"] = ""\r
+ end\r
+ rescue\r
+ # PStoreファイルを破棄する\r
+ File.delete("./work/#{session.session_id}.dat")\r
+ # PStoreが破損していた場合はセッション情報を破棄する\r
+ session["login"] = nil\r
+ session.delete\r
+ end\r
+ \r
+ # フォームによって挙動を変更します\r
+ if cgi["mode"].respond_to?(:read) && cgi["action"].respond_to?(:read)\r
+ params["mode"] = cgi["mode"].read\r
+ params["action"] = cgi["action"].read\r
+ Controller.MultiForm(cgi, session, params, db)\r
+ else\r
+ Controller.NormalForm(cgi, session, params, db)\r
+ end\r
+ \r
+ # エラー画面移行時はセッション情報を破棄する\r
+ if params["mode"] == "error"\r
+ session["login"] = nil\r
+ session.delete\r
+ end\r
+ end\r
+ \r
+ # ログイン失敗ユーザを記録\r
+ if (session["login"] != "true" and (cgi["loginid"] != "" or cgi["password"] != ""))\r
+ session["error"] = "ログインに失敗しました。ユーザIDまたはパスワードを確認して下さい。"\r
+ logger.info "次のアクセスがログインに失敗しました。ログインID:#{cgi["loginid"]}, IPアドレス:#{cgi.remote_addr}"\r
+ end\r
+ \r
+ # メニューとして表示されるHTML文字列です\r
+ if params["target_filepath"].blank?\r
+ menu = "<div class=\"divstyle\" style=\"width: #{TABLEWIDTH}px;\"><div class=\"divstyle\" align=\"center\" style=\"margin-bottom: 5px;\">現在編集中のファイル : #{session["filepath"]} "\r
+ else\r
+ menu = "<div class=\"divstyle\" style=\"width: #{TABLEWIDTH}px;\"><div class=\"divstyle\" align=\"center\" style=\"margin-bottom: 5px;\">現在編集中のファイル : #{session["target_filepath"]} "\r
+ end\r
+ if USEFILEMANAGER == true\r
+ menu += "[ <a href=\"#{cgi.script_name}?mode=selectlog\">他のファイルを選択</a> ]</div>[ <a href=\"#{cgi.script_name}\">トップページ</a> | 記事管理 ( <a href=\"#{cgi.script_name}?mode=newentry\">作成</a> | <a href=\"#{cgi.script_name}?mode=editentry\">編集</a> | <a href=\"#{cgi.script_name}?mode=delentry\">消去</a> ) | <a href=\"#{cgi.script_name}?mode=editfeed\">XML情報編集</a> | <a href=\"#{cgi.script_name}?mode=log\">ログ管理</a> | <a href=\"#{cgi.script_name}?mode=import\">インポート</a> | <a href=\"#{FILEMANAGER}\" target=\"_blank\">ファイル管理</a> | <a href=\"#{cgi.script_name}?mode=reset\">初期化</a> | <a href=\"#{cgi.script_name}?mode=logout\">ログアウト</a> ]</div>"\r
+ else\r
+ menu += "[ <a href=\"#{cgi.script_name}?mode=selectlog\">他のファイルを選択</a> ]</div>[ <a href=\"#{cgi.script_name}\">トップページ</a> | 記事管理 ( <a href=\"#{cgi.script_name}?mode=newentry\">作成</a> | <a href=\"#{cgi.script_name}?mode=editentry\">編集</a> | <a href=\"#{cgi.script_name}?mode=delentry\">消去</a> ) | <a href=\"#{cgi.script_name}?mode=editfeed\">XML情報編集</a> | <a href=\"#{cgi.script_name}?mode=log\">ログ管理</a> | <a href=\"#{cgi.script_name}?mode=import\">インポート</a> | <a href=\"#{cgi.script_name}?mode=reset\">初期化</a> | <a href=\"#{cgi.script_name}?mode=logout\">ログアウト</a> ]</div>"\r
+ end\r
+ \r
+ # ビュー部分\r
+ # modeとactionの相関図は以下のようになります。\r
+ # [mode] + [action]\r
+ # + [action]\r
+ # + [action]\r
+ # + ... and more\r
+ if session["login"] != "true"\r
+ # セッションが存在しない場合は強制的にトップページに遷移\r
+ htmlwriter = HtmlWriter.new("./erbtemp/index.html.erb", binding)\r
+ else\r
+ case params["mode"]\r
+ when "selectlog"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/select.html.erb", binding)\r
+ when "newentry"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/newentry.html.erb", binding)\r
+ when "editentry"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/editentry.html.erb", binding)\r
+ when "delentry"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/delentry.html.erb", binding)\r
+ when "editfeed"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/editfeed.html.erb", binding)\r
+ when "log"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/log.html.erb", binding)\r
+ when "insert"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/insertfeed.html.erb", binding)\r
+ when "replace"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/replacefeed.html.erb", binding)\r
+ when "import"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/indeximport.html.erb", binding)\r
+ when "reset"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/reset.html.erb", binding)\r
+ when "error"\r
+ htmlwriter = HtmlWriter.new("./erbtemp/error.html.erb", binding)\r
+ else\r
+ htmlwriter = HtmlWriter.new("./erbtemp/menu.html.erb", binding)\r
+ end\r
+ end\r
+ \r
+ # ビュー部分(インクルード用ファイル読み込み)\r
+ htmlparts = {}\r
+ # ヘッダタグ出力\r
+ htmlparts['headtag'] = HtmlWriter.new("./erbtemp/parts_headtag.html.erb", binding).to_code\r
+ htmlparts['headjs_switchpost'] = HtmlWriter.new("./erbtemp/parts_headjs_switchpost.html.erb", binding).to_code\r
+ htmlparts['menu'] = HtmlWriter.new("./erbtemp/parts_menu.html.erb", binding).to_code\r
+ htmlparts['selectfile'] = HtmlWriter.new("./erbtemp/parts_selectfile.html.erb", binding).to_code\r
+ # インフォメーションエリア\r
+ htmlparts['infoarea'] = HtmlWriter.new("./erbtemp/parts_infoarea.html.erb", binding).to_code\r
+ \r
+ # 実際にHTMLを出力します\r
+ cgi.out{htmlwriter.to_code}\r
+ \r
+ rescue => exception\r
+ # ログに記録を実施します\r
+ logger.error(exception.to_s)\r
+ logger.error(exception.backtrace.join "\n")\r
+ \r
+ # エラーが発生した場合、それを画面に表示します\r
+ htmlwriter = HtmlWriter.new("./erbtemp/exception.html.erb", binding)\r
+ cgi.out{htmlwriter.to_code}\r
+ end\r
+end\r
+\r
+begin\r
+ main\r
+rescue => evar\r
+ # エラーが発生した場合、それを画面に表示します\r
+ detail = ("%s: %s (%s)\n" %\r
+ [evar.backtrace[0], evar.message, evar.send('class')]) +\r
+ evar.backtrace[1..-1].join("\n")\r
+ puts "content-type: text/html\n\n<plaintext>\n" + detail\r
+end\r
-#!/usr/local/bin/ruby
-# -*- coding: utf-8 -*-
-#
-#= FeedGeneratorから起動するファイルマネージャWEBアプリケーション
-#
-#Autohr:: Kureha Hisame (http://lunardial.sakura.ne.jp/) & Yui Naruse (http://airemix.com/)
-#Version:: 2.0.0.0
-#Copyright:: Copyright 2009 FeedBlog Project (http://sourceforge.jp/projects/feedblog/)
-#License:: GPLv3
-
-require "cgi"
-require "cgi/session"
-require "erb"
-require "rexml/document"
-require "pstore"
-require "fileutils"
-
-# インターフェースのテーブルの幅
-TABLEWIDTH = 800
-# 画像フォルダの場所を定義
-IMGPATH = "./../lunardial/xml/img/"
-
-# バージョン情報を示す文字列です
-APPVERSION = "- FileManager for Ruby version 2.0.0.0 -<br>Copyright(c) 2009 Kureha.H (<a href=\"http://lunardial.sakura.ne.jp/\" target=\"_blank\">http://lunardial.sakura.ne.jp/</a>) & Yui Naruse (<a href=\"http://airemix.com/\" target=\"_blank\">http://airemix.com/</a>)"
-# タイトル領域に表示される文字列です
-APPTITLE = "FileManager for Ruby version 2.0.0.0"
-
-# アップロード可能な最大ファイルサイズ
-UPLOADLIMIT = 2 * 1024 * 1024
-
-# = Objectクラス
-#
-# 基本クラスのオーバーライドを行います
-class Object
- # myopenメソッド
- #
- # ruby-1.9.x以降ではファイルを開いた際、エンコードの指定を行わないとエラーの原因になります。
- # ただしruby-1.8.6以前はエンコードの指定に対応していないため、独自メソッドを定義してファイルの入出力を行います。
- #
- # _arg[0]_ :: 入出力を行うファイルのパス
- # _arg[1]_ :: モードの指定。例 : w:utf-8(書き込みモード・UTF-8エンコードでファイルを開く)
- def myopen(*arg)
- mode = arg[1]
- rdonly_p = true
- case mode
- when String
- arg[1] = mode[/[^:]+/] if RUBY_VERSION < "1.8.7" && mode.include?(':')
- rdonly_p = /\A[^:]*[wa+]/ !~ mode
- when Numeric
- rdonly_p = !(mode & (IO::WRONY | IO::RDWR))
- end
- open(*arg) do |f|
- f.flock(rdonly_p ? File::LOCK_SH : File::LOCK_EX)
- return yield(f)
- end
- end
-end
-
-class NilClass
- def blank?
- nil?
- end
-end
-
-class Array
- def blank?
- empty?
- end
-end
-
-class String
- def blank?
- empty?
- end
-end
-
-# = WebSecurityExceptionクラス
-#
-# 独自定義の例外クラスです。WebFilerインスタンス内の処理でセキュリティ違反が発生した場合にthrowされます。
-class WebSecurityException < Exception
-end
-
-# = FileExistedExceptionクラス
-#
-# 独自定義の例外クラスです。WebFileインスタンスの処理で、既に存在するファイルに上書きしようとした場合にthrowされます。
-class FileExistedException < Exception
-end
-
-# = HtmlWriterクラス
-#
-# テンプレートファイル(*.erb)を読み込み、管理するクラスです
-class HtmlWriter
- # 初期化メソッドです
- #
- # _template_ :: テンプレートファイル(*.erb)のパス
- # _binding_ :: binding変数
- def initialize(template, binding)
- @erb = ERB.new(myopen(template, "r:utf-8") {|f| f.read}, nil, "-")
- @binding = binding
- end
-
- # テンプレートファイルの文字列を返却するメソッドです
- def to_code
- @erb.result(@binding)
- end
-end
-
-# = WebFilerクラス
-#
-# Web上にローカルと同じフォルダ管理機能を利用できるクラスです
-class WebFiler
- # 初期化メソッドです
- #
- # _basepath_ :: クラス内で扱う最上位のフォルダ(root)とする実パス
- def initialize(basepath)
- @basepath = basepath
- @basepath << "/" unless @basepath[-1..-1] == "/"
- @relpath_list = []
-
- raise "Target dir not found." unless File.directory?(pwd)
- end
-
- # ファイルに使用できない文字列を調べるための正規表現を定義します
- FILEREGEXP = /\A[-_+~^0-9a-zA-Z]+(\.[-_+~^0-9a-zA-Z]+)*\z/
-
- attr_reader :basepath
- attr_accessor :relpath_list
-
- # ディレクトリ内部のファイル・フォルダ一覧を取得するメソッド
- def ls
- filelist = Dir::entries(pwd)
- filelist.delete(".")
- filelist.delete("..")
-
- filelist.sort!
- end
-
- # ディレクトリ内部のファイル・フォルダ一覧の詳細情報を取得するメソッド
- def lsinfo
- filelist = Dir::entries(pwd)
- filelist.delete(".")
- filelist.delete("..")
-
- fileinfo = {}
- filelist.each { |fname|
- fileinfo[fname] = {}
- fileinfo[fname][:ftype] = File.ftype(pwd + "/" + fname)
- fileinfo[fname][:atime] = File.atime(pwd + "/" + fname)
- fileinfo[fname][:ctime] = File.ctime(pwd + "/" + fname)
- fileinfo[fname][:mtime] = File.mtime(pwd + "/" + fname)
- fileinfo[fname][:size] = File.size(pwd + "/" + fname) / 1000
- }
-
- fileinfo
- end
-
- # ファイルタイプを取得するメソッド
- def ftype(fname)
- File.ftype(pwd + File.basename(fname))
- end
-
- # ディレクトリを移動するメソッド
- def cd(pathname)
- if pathname == ".."
- @relpath_list.delete_at(-1) unless @relpath_list.length == 0
- elsif pathname.match(FILEREGEXP)
- if File.directory?(pwd + "/" + File.basename(pathname))
- @relpath_list << File.basename(pathname)
- else
- raise FileExistedException
- end
- else
- raise WebSecurityException
- end
- end
-
- # ディレクトリを絶対指定で移動するメソッド
- def cd_abs(relpath_arr)
- relpath_arr.each { |name|
- unless name.match(FILEREGEXP)
- raise WebSecurityException
- end
- }
- @relpath_list = relpath_arr
- end
-
- # 現在のディレクトリを表示するメソッド
- def pwd
- @basepath + relpath
- end
-
- # 相対パスを算出するメソッド
- def relpath
- if @relpath_list.length == 0
- ""
- else
- @relpath_list.join("/") << "/"
- end
- end
-
- # ファイルをアップロードするメソッド
- def upload(file, fname)
- fname.gsub!(/( | )/, "_")
- if File.exist?(pwd + File.basename(fname))
- raise FileExistedException
- elsif File.basename(fname).match(FILEREGEXP)
- open(pwd + File.basename(fname), "w") do |f|
- f.binmode
- f.write file.read
- end
- else
- raise WebSecurityException
- end
- end
-
- # ファイルを消去するメソッド
- def delete(fname)
- if File.exist?(pwd + File.basename(fname)) && fname.match(FILEREGEXP)
- File.delete(pwd + File.basename(fname))
- else
- raise WebSecurityException
- end
- end
-
- # ディレクトリを製作するメソッド
- def mkdir(dirname)
- dirname.gsub!(/( | )/, "_")
- if File.exist?(pwd + File.basename(dirname))
- raise FileExistedException
- elsif dirname.match(FILEREGEXP)
- Dir.mkdir(pwd + File.basename(dirname))
- else
- raise WebSecurityException
- end
- end
-
- # 内部が空のディレクトリを消去するメソッド
- def rmdir(dirname)
- if File.exist?(pwd + File.basename(dirname)) && dirname.match(FILEREGEXP)
- Dir.rmdir(pwd + File.basename(dirname))
- else
- raise WebSecurityException
- end
- end
-
-end
-
-# = Controllerクラス
-#
-# コントローラ部分に相当する処理を受け持つクラスです
-class Controller
- def self.update_session(session, filer)
- session["filelist"] = filer.ls.reverse
- session["fileinfo"] = filer.lsinfo
- session["pwd"] = filer.pwd
- session["relpath_list"] = filer.relpath_list.join("/")
- end
-
- def Controller.MultiForm(cgi, session, params, db)
- db.transaction do
- case params["action"]
- # アップロード時
- when "upload"
- filer = WebFiler.new(IMGPATH)
- filer.relpath_list = params["relpath_list"].split("/")
- Controller.update_session(session, filer);
-
- if (cgi["updata"].size <= UPLOADLIMIT)
- begin
- filer.upload(cgi["updata"], cgi["updata"].original_filename)
- rescue FileExistedException
- session["error"] = "既に同名のファイルが存在します!"
- rescue WebSecurityException
- session["error"] = "ファイル名に使用できない文字列が含まれています!"
- end
- else
- session["error"] = "ファイルの容量が大きすぎます!"
- end
-
- Controller.update_session(session, filer);
-
- session["info"] = "正常にアップロードが完了しました。" if session["error"] == ""
-
- # 削除時
- when "delete"
- filer = WebFiler.new(IMGPATH)
- filer.relpath_list = params["relpath_list"].split("/")
- Controller.update_session(session, filer);
-
- session["dellist"] = []
- count = 0
- session["filelist"].each do |file|
- if params["filename_" + file] == "delete" && filer.ftype(file) == "file"
- filer.delete(file)
- count = count + 1
- elsif params["filename_" + file] == "delete" && filer.ftype(file) == "directory"
- begin
- filer.rmdir(file)
- count = count + 1
- rescue
- mes = "対象のディレクトリは空ではありません!<br>"
- mes << "ディレクトリを削除する場合は、事前にディレクトリ内部の全てのファイルを削除してください。"
- session["error"] = mes
- end
- end
- end
-
- Controller.update_session(session, filer);
-
- session["info"] = "正常にファイルの削除が完了しました。" if session["error"] == "" && count != 0
-
- # ディレクトリ製作時
- when "mkdir"
- filer = WebFiler.new(IMGPATH)
- filer.relpath_list = params["relpath_list"].split("/")
- Controller.update_session(session, filer);
-
- begin
- filer.mkdir(params["dirname"])
- rescue FileExistedException
- session["error"] = "既に同名のディレクトリが存在します!"
- rescue WebSecurityException
- session["error"] = "ディレクトリ名に使用できない文字列が含まれています!"
- end
-
- Controller.update_session(session, filer);
-
- session["info"] = "正常にディレクトリの作成が完了しました。" if session["error"] == ""
-
- # ディレクトリ移動時
- when "cd"
- filer = WebFiler.new(IMGPATH)
- filer.relpath_list = params["relpath_list"].split("/")
- Controller.update_session(session, filer);
-
- begin
- filer.cd(params["arg"])
- rescue
- session["error"] = "移動先のディレクトリが見つかりません!"
- end
-
- Controller.update_session(session, filer);
-
- # 絶対位置でのディレクトリ移動時
- when "cd_abs"
- filer = WebFiler.new(IMGPATH)
- filer.relpath_list = params["relpath_list"].split("/")
- Controller.update_session(session, filer);
-
- if params["arg"].to_i >= 0
- begin
- movepath = []
- params["arg"].to_i.times { |i|
- movepath << params["relpath_list"].split("/")[i]
- }
- filer.cd_abs(movepath)
- rescue
- session["error"] = "移動先のディレクトリが見つかりません!"
- end
- else
- session["error"] = "移動先のディレクトリが見つかりません!"
- end
-
- Controller.update_session(session, filer);
-
- # 表示更新時
- when "refresh"
- filer = WebFiler.new(IMGPATH)
- filer.relpath_list = params["relpath_list"].split("/")
- Controller.update_session(session, filer);
-
- # 初期表示
- else
- filer = WebFiler.new(IMGPATH)
- Controller.update_session(session, filer);
- end
- end
- end
-end
-
-def main
- # SESSION変数、パラメータなどを取得します
- cgi = CGI.new
- session = CGI::Session.new(cgi)
- params = Hash[*cgi.params.to_a.map{|k, v| [k, v[0].to_s]}.flatten]
- params.each { |k, v| params[k] = cgi[k].read if cgi[k].respond_to?(:read) && k != "updata"}
-
- # ログアウト処理
- if params["mode"] == "logout"
- session["login"] = nil
- session["logini"] = nil
- session["password"] = nil
- session.delete
- end
-
- # メインコントローラー
- # セッションが有効な場合のも実行します
- if session["login"] == "true"
- db = PStore.new("./work/#{session.session_id}_file.dat")
- session["info"] = ""
- session["error"] = ""
-
- # コントローラ部分
- Controller.MultiForm(cgi, session, params, db)
- end
-
- # ビュー部分
- if session["login"] != "true"
- # if session["login"] == "true"
- # セッションが存在しない場合は強制的にエラーページに遷移
- htmlwriter = HtmlWriter.new("./erbtemp/fileindex.html.erb", binding)
- else
- htmlwriter = HtmlWriter.new("./erbtemp/filemanager.html.erb", binding)
- end
-
- # 実際にHTMLを出力します
- begin
- cgi.out{htmlwriter.to_code}
- rescue => exception
- # エラーが発生した場合、それを画面に表示します
- htmlwriter = HtmlWriter.new("./erbtemp/exception.html.erb", binding)
- cgi.out{ htmlwriter.to_code }
- end
-end
-
-begin
- main
-rescue => evar
- # エラーが発生した場合、それを画面に表示します
- detail = ("%s: %s (%s)\n" %
- [evar.backtrace[0], evar.message, evar.send('class')]) +
- evar.backtrace[1..-1].join("\n")
- puts "content-type: text/html\n\n<plaintext>\n" + detail
-end
+#!/usr/local/bin/ruby\r
+# -*- coding: utf-8 -*-\r
+#\r
+#= Galleryマネージャ用アプリケーション\r
+#\r
+#Autohr:: Kureha Hisame (http://lunardial.sakura.ne.jp/)\r
+#Version:: 1.0.0.0\r
+#Copyright:: Copyright 2013 Kureha Hisame (http://lunardial.sakura.ne.jp/)\r
+#License:: GPLv3\r
+\r
+require "cgi"\r
+require "cgi/session"\r
+require "erb"\r
+require "rexml/document"\r
+require "pstore"\r
+require "fileutils"\r
+\r
+require "./common.rb"\r
+require "./define.rb"\r
+\r
+# = WebSecurityExceptionクラス\r
+#\r
+# 独自定義の例外クラスです。WebFilerインスタンス内の処理でセキュリティ違反が発生した場合にthrowされます。\r
+class WebSecurityException < Exception\r
+end\r
+\r
+# = FileExistedExceptionクラス\r
+#\r
+# 独自定義の例外クラスです。WebFileインスタンスの処理で、既に存在するファイルに上書きしようとした場合にthrowされます。\r
+class FileExistedException < Exception\r
+end\r
+\r
+# = FileNotExistedExceptionクラス\r
+#\r
+# 独自定義の例外クラスです。WebFileインスタンスの処理で、対象ファイルが存在しない場合にthrowされます。\r
+class FileNotExistedException < Exception\r
+end\r
+\r
+# = HtmlWriterクラス\r
+# \r
+# テンプレートファイル(*.erb)を読み込み、管理するクラスです\r
+class HtmlWriter\r
+ # 初期化メソッドです\r
+ #\r
+ # _template_ :: テンプレートファイル(*.erb)のパス\r
+ # _binding_ :: binding変数\r
+ def initialize(template, binding)\r
+ @erb = ERB.new(myopen(template, "r:utf-8") {|f| f.read}, nil, "-")\r
+ @binding = binding\r
+ end\r
+\r
+ # テンプレートファイルの文字列を返却するメソッドです\r
+ def to_code\r
+ @erb.result(@binding)\r
+ end\r
+end\r
+\r
+# = WebFilerクラス\r
+#\r
+# Web上にローカルと同じフォルダ管理機能を利用できるクラスです\r
+class WebFiler\r
+ # 初期化メソッドです\r
+ #\r
+ # _basepath_ :: クラス内で扱う最上位のフォルダ(root)とする実パス\r
+ def initialize(basepath)\r
+ @basepath = basepath\r
+ @basepath << "/" unless @basepath[-1..-1] == "/"\r
+ @relpath_list = []\r
+ @sort_type = ''\r
+ @sort_reverse = ''\r
+\r
+ raise "Target dir not found." unless File.directory?(pwd)\r
+ end\r
+\r
+ # ファイルに使用できない文字列を調べるための正規表現を定義します\r
+ FILEREGEXP = /\A[-_+~^0-9a-zA-Z]+(\.[-_+~^0-9a-zA-Z]+)*\z/\r
+\r
+ attr_reader :basepath\r
+ attr_accessor :relpath_list, :sort_type, :sort_reverse\r
+\r
+ # ディレクトリ内部のファイル・フォルダ一覧を取得するメソッド\r
+ def ls\r
+ filelist = Dir::entries(pwd)\r
+ filelist.delete(".")\r
+ filelist.delete("..")\r
+\r
+ # ファイルリスト一覧のソート処理。\r
+ case @sort_type\r
+ when "ftype"\r
+ if @sort_reverse == "true"\r
+ filelist.sort!{|a, b| \r
+ (File.ftype(pwd + b) <=> File.ftype(pwd + a)).nonzero? || \r
+ (File.basename(pwd + a) <=> File.basename(pwd + b))\r
+ }\r
+ else\r
+ filelist.sort!{|a, b| \r
+ (File.ftype(pwd + a) <=> File.ftype(pwd + b)).nonzero? || \r
+ (File.basename(pwd + a) <=> File.basename(pwd + b))\r
+ }\r
+ end\r
+ when "ctime"\r
+ filelist.sort!{|a, b| File.ctime(pwd + b) <=> File.ctime(pwd + a) }\r
+ # ファイルリストを逆順にするか\r
+ filelist.reverse! if @sort_reverse == "true"\r
+ when "mtime"\r
+ filelist.sort!{|a, b| File.mtime(pwd + b) <=> File.mtime(pwd + a) }\r
+ # ファイルリストを逆順にするか\r
+ filelist.reverse! if @sort_reverse == "true"\r
+ when "size"\r
+ if @sort_reverse == "true"\r
+ filelist.sort!{|a, b| \r
+ (File.ftype(pwd + a) <=> File.ftype(pwd + b)).nonzero? || \r
+ (File.size(pwd + a) <=> File.size(pwd + b)).nonzero? || \r
+ (File.basename(pwd + a) <=> File.basename(pwd + b))\r
+ }\r
+ else\r
+ filelist.sort!{|a, b| \r
+ (File.ftype(pwd + a) <=> File.ftype(pwd + b)).nonzero? || \r
+ (File.size(pwd + b) <=> File.size(pwd + a)).nonzero? || \r
+ (File.basename(pwd + a) <=> File.basename(pwd + b))\r
+ }\r
+ end\r
+ when "name"\r
+ filelist.sort!{|a, b| File.basename(pwd + a) <=> File.basename(pwd + b) }\r
+ # ファイルリストを逆順にするか\r
+ filelist.reverse! if @sort_reverse == "true"\r
+ else\r
+ if @sort_reverse == "true"\r
+ filelist.sort!{|a, b| \r
+ (File.ftype(pwd + b) <=> File.ftype(pwd + a)).nonzero? || \r
+ (File.basename(pwd + a) <=> File.basename(pwd + b))\r
+ }\r
+ else\r
+ filelist.sort!{|a, b| \r
+ (File.ftype(pwd + a) <=> File.ftype(pwd + b)).nonzero? || \r
+ (File.basename(pwd + a) <=> File.basename(pwd + b))\r
+ }\r
+ end\r
+ end\r
+ \r
+ filelist\r
+ end\r
+\r
+ # ディレクトリ内部のファイル・フォルダ一覧の詳細情報を取得するメソッド\r
+ def lsinfo\r
+ filelist = Dir::entries(pwd)\r
+ filelist.delete(".")\r
+ filelist.delete("..")\r
+\r
+ fileinfo = {}\r
+ filelist.each { |fname| \r
+ fileinfo[fname] = {}\r
+ fileinfo[fname][:ftype] = File.ftype(pwd + "/" + fname)\r
+ fileinfo[fname][:atime] = File.atime(pwd + "/" + fname)\r
+ fileinfo[fname][:ctime] = File.ctime(pwd + "/" + fname)\r
+ fileinfo[fname][:mtime] = File.mtime(pwd + "/" + fname)\r
+ fileinfo[fname][:size] = File.size(pwd + "/" + fname) / 1000\r
+ \r
+ fileinfo[fname][:sort] = File.mtime(pwd + "/" + fname).to_i\r
+ }\r
+ \r
+ fileinfo\r
+ end\r
+\r
+ # ファイルタイプを取得するメソッド\r
+ def ftype(fname)\r
+ File.ftype(pwd + File.basename(fname))\r
+ end\r
+\r
+ # ディレクトリを移動するメソッド\r
+ def cd(pathname)\r
+ if pathname == ".."\r
+ @relpath_list.delete_at(-1) unless @relpath_list.length == 0\r
+ elsif pathname.match(FILEREGEXP)\r
+ if File.directory?(pwd + "/" + File.basename(pathname))\r
+ @relpath_list << File.basename(pathname)\r
+ else\r
+ raise FileExistedException\r
+ end\r
+ else\r
+ raise WebSecurityException\r
+ end\r
+ end\r
+\r
+ # ディレクトリを絶対指定で移動するメソッド\r
+ def cd_abs(relpath_arr)\r
+ relpath_arr.each { |name|\r
+ unless name.match(FILEREGEXP)\r
+ raise WebSecurityException\r
+ end\r
+ }\r
+ @relpath_list = relpath_arr\r
+ end\r
+\r
+ # 現在のディレクトリを表示するメソッド\r
+ def pwd\r
+ @basepath + relpath\r
+ end\r
+\r
+ # 相対パスを算出するメソッド\r
+ def relpath\r
+ if @relpath_list.length == 0\r
+ ""\r
+ else\r
+ @relpath_list.join("/") << "/"\r
+ end\r
+ end\r
+\r
+ # ファイルをアップロードするメソッド\r
+ def upload(file, fname)\r
+ fname.gsub!(/( | )/, "_")\r
+ \r
+ if File.exist?(pwd + File.basename(fname))\r
+ raise FileExistedException\r
+ elsif File.basename(fname).match(FILEREGEXP)\r
+ open(pwd + File.basename(fname), "w") do |f|\r
+ f.binmode\r
+ f.write file.read\r
+ end\r
+ else\r
+ raise WebSecurityException\r
+ end\r
+ end\r
+ \r
+ # ファイルを移動するメソッド\r
+ def move(from_name, dest_name)\r
+ if File.exist?(pwd + File.basename(dest_name))\r
+ raise FileExistedException\r
+ end\r
+ \r
+ unless File.exist?(pwd + File.basename(from_name))\r
+ raise FileNotExistedException\r
+ end\r
+ \r
+ unless File.basename(from_name).match(FILEREGEXP)\r
+ raise WebSecurityException\r
+ end\r
+ \r
+ unless File.basename(dest_name).match(FILEREGEXP)\r
+ raise WebSecurityException\r
+ end\r
+ \r
+ File.rename(pwd + File.basename(from_name), pwd + File.basename(dest_name))\r
+ end\r
+\r
+ # ファイルを消去するメソッド\r
+ def delete(fname)\r
+ if File.exist?(pwd + File.basename(fname)) && fname.match(FILEREGEXP)\r
+ File.delete(pwd + File.basename(fname))\r
+ else\r
+ raise WebSecurityException\r
+ end\r
+ end\r
+\r
+ # ディレクトリを製作するメソッド\r
+ def mkdir(dirname)\r
+ dirname.gsub!(/( | )/, "_")\r
+ if File.exist?(pwd + File.basename(dirname))\r
+ raise FileExistedException\r
+ elsif dirname.match(FILEREGEXP)\r
+ Dir.mkdir(pwd + File.basename(dirname))\r
+ else\r
+ raise WebSecurityException\r
+ end\r
+ end\r
+\r
+ # 内部が空のディレクトリを消去するメソッド\r
+ def rmdir(dirname)\r
+ if File.exist?(pwd + File.basename(dirname)) && dirname.match(FILEREGEXP)\r
+ Dir.rmdir(pwd + File.basename(dirname))\r
+ else\r
+ raise WebSecurityException\r
+ end\r
+ end\r
+\r
+end\r
+\r
+# = Controllerクラス\r
+#\r
+# コントローラ部分に相当する処理を受け持つクラスです\r
+class Controller\r
+ def self.update_session(session, filer)\r
+ session["filelist"] = filer.ls\r
+ session["fileinfo"] = filer.lsinfo\r
+ session["sort_type"] = filer.sort_type\r
+ session["sort_reverse"] = filer.sort_reverse\r
+ session["pwd"] = filer.pwd\r
+ session["relpath_list"] = filer.relpath_list.join("/")\r
+ end\r
+\r
+ def Controller.MultiForm(cgi, session, params, db)\r
+ db.transaction do\r
+ # 共通初期化処理\r
+ filer = WebFiler.new(IMGPATH)\r
+ begin\r
+ filer.relpath_list = params["relpath_list"].split("/")\r
+ filer.sort_type = params["sort_type"]\r
+ filer.sort_reverse = params["sort_reverse"]\r
+ rescue\r
+ end\r
+ filer.sort_type = "ftype" if filer.sort_type == nil or filer.sort_type.empty?\r
+ Controller.update_session(session, filer);\r
+ \r
+ case params["action"]\r
+ # アップロード時\r
+ when "upload"\r
+ if (cgi["updata"].size == 0)\r
+ session["error"] = "アップロードするファイルが選択されていません!"\r
+ elsif (cgi["updata"].size <= UPLOADLIMIT)\r
+ begin\r
+ # ファイル名称指定判定\r
+ upload_filename = nil\r
+ unless params["file_rename"].empty?\r
+ upload_filename = File.basename(params["file_rename"])\r
+ # 空白は自動変換する\r
+ upload_filename.gsub!(/( | )/, "_")\r
+ else\r
+ upload_filename = cgi["updata"].original_filename\r
+ end\r
+ \r
+ filer.upload(cgi["updata"], upload_filename)\r
+ # 独自改造 開始\r
+ if params["thumbs"] == "true" and File.extname(upload_filename) =~ /\.(jpg|JPG|png|PNG)\Z/\r
+ begin\r
+ require('./resize.rb')\r
+ if filer.relpath_list.size == 0\r
+ ResizeManager.create_thumbs(IMGPATH + upload_filename)\r
+ else\r
+ ResizeManager.create_thumbs(IMGPATH + filer.relpath_list.join("/") + "/" + upload_filename)\r
+ end\r
+ rescue LoadError\r
+ # With no action\r
+ rescue => evar\r
+ # With no action\r
+ session["error"] = "サムネイル作成に失敗しました。<br>"\r
+ session["error"] << evar.to_s\r
+ end\r
+ end\r
+ # 独自改造 終了\r
+ rescue FileExistedException\r
+ session["error"] = "既に同名のファイルが存在します!"\r
+ rescue WebSecurityException\r
+ session["error"] = "ファイル名に使用できない文字列が含まれています!"\r
+ end\r
+ else\r
+ session["error"] = "ファイルの容量が大きすぎます!"\r
+ end\r
+ \r
+ # ファイル一覧を更新\r
+ Controller.update_session(session, filer);\r
+\r
+ session["info"] = "正常にファイル(#{upload_filename})のアップロードが完了しました。" if session["error"] == ""\r
+ \r
+ # 移動時\r
+ when "move"\r
+ session["selectlist"] = []\r
+ count = 0\r
+ from_name = nil;\r
+ dest_name = params["destname"]\r
+ session["filelist"].each do |file|\r
+ if params["filename_" + file] == "true"\r
+ count = count + 1\r
+ from_name = file\r
+ end\r
+ end\r
+ \r
+ if count == 0\r
+ mes = "対象が選択されていません。"\r
+ session["error"] = mes\r
+ elsif count > 1\r
+ mes = "一つ以上の対象がチェックされています。<br>"\r
+ mes << "リネーム処理は一度に一つの対象にしか行えません。"\r
+ session["error"] = mes\r
+ elsif dest_name.empty?\r
+ mes = "リネーム名称が入力されていません。"\r
+ session["error"] = mes\r
+ else\r
+ begin\r
+ filer.move(from_name, dest_name)\r
+ rescue FileExistedException\r
+ session["error"] = "既に同名のファイルが存在します!"\r
+ rescue FileNotExistedException\r
+ session["error"] = "選択したファイルは既に削除されました。"\r
+ rescue WebSecurityException\r
+ session["error"] = "リネーム名称に使用できない文字列が含まれています!"\r
+ end\r
+ end\r
+ \r
+ # ファイル一覧を更新\r
+ Controller.update_session(session, filer);\r
+\r
+ session["info"] = "正常にファイルのリネームが完了しました。" if session["error"] == ""\r
+\r
+ # 削除時\r
+ when "delete"\r
+ session["dellist"] = []\r
+ count = 0\r
+ session["filelist"].each do |file|\r
+ if params["filename_" + file] == "true" && filer.ftype(file) == "file"\r
+ filer.delete(file) \r
+ count = count + 1\r
+ elsif params["filename_" + file] == "true" && filer.ftype(file) == "directory"\r
+ begin\r
+ filer.rmdir(file)\r
+ count = count + 1\r
+ rescue\r
+ mes = "対象のフォルダは空ではありません!<br>"\r
+ mes << "フォルダを削除する場合は、事前にフォルダ内部の全てのファイルを削除してください。"\r
+ session["error"] = mes\r
+ end\r
+ end\r
+ end\r
+ \r
+ # ファイル一覧を更新\r
+ Controller.update_session(session, filer);\r
+\r
+ session["info"] = "正常にファイルの削除が完了しました。" if session["error"] == "" && count != 0\r
+\r
+ # ディレクトリ製作時\r
+ when "mkdir"\r
+ begin\r
+ filer.mkdir(params["dirname"])\r
+ rescue FileExistedException\r
+ session["error"] = "既に同名のフォルダが存在します!"\r
+ rescue WebSecurityException\r
+ session["error"] = "フォルダ名に使用できない文字列が含まれています!"\r
+ end\r
+ \r
+ # ファイル一覧を更新\r
+ Controller.update_session(session, filer);\r
+\r
+ session["info"] = "正常にフォルダの作成が完了しました。" if session["error"] == ""\r
+\r
+ # ディレクトリ移動時\r
+ when "cd"\r
+ begin\r
+ filer.cd(params["arg"])\r
+ rescue\r
+ session["error"] = "移動先のフォルダが見つかりません!"\r
+ end\r
+ \r
+ # ファイル一覧を更新\r
+ Controller.update_session(session, filer);\r
+\r
+ # 絶対位置でのディレクトリ移動時\r
+ when "cd_abs"\r
+ if params["arg"].to_i >= 0\r
+ begin\r
+ movepath = []\r
+ params["arg"].to_i.times { |i|\r
+ movepath << params["relpath_list"].split("/")[i]\r
+ }\r
+ filer.cd_abs(movepath)\r
+ rescue\r
+ session["error"] = "移動先のフォルダが見つかりません!"\r
+ end\r
+ else\r
+ session["error"] = "移動先のフォルダが見つかりません!"\r
+ end\r
+ \r
+ # ファイル一覧を更新\r
+ Controller.update_session(session, filer);\r
+\r
+ # 表示更新時\r
+ when "refresh"\r
+ \r
+ # 初期表示\r
+ else\r
+ \r
+ end\r
+ end\r
+ end\r
+end\r
+\r
+def main\r
+ # SESSION変数、パラメータなどを取得します\r
+ cgi = CGI.new\r
+ session = CGI::Session.new(cgi)\r
+ params = Hash[*cgi.params.to_a.map{|k, v| [k, v[0].to_s]}.flatten]\r
+ params.each { |k, v| params[k] = cgi[k].read if cgi[k].respond_to?(:read) && k != "updata"}\r
+ \r
+ # ロガーを作成する\r
+ logger = WebLogger.get_logger(cgi.script_name, LOG_DIR, LOG_RELEASE_MODE)\r
+ \r
+ # コントローラー部分\r
+ # セッション管理\r
+ session["info"] = ""\r
+ session["error"] = ""\r
+ if session["login"] != "true"\r
+ # ログイン情報を確認\r
+ LOGININFO.each {|h|\r
+ if (cgi["loginid"] == h[:id] && cgi["password"] == h[:password])\r
+ session["login"] = "true"\r
+ session["name"] = h[:name]\r
+ \r
+ # ログを記録\r
+ logger.info "ログインユーザ:#{h[:id]}, IPアドレス:#{cgi.remote_addr}"\r
+ \r
+ # ワークフォルダの中をクリーンアップします\r
+ filelist = Dir::entries("./work")\r
+ # 削除条件 : 最終変更日時から1日(60*60*24sec)かつ、ファイルタイプがファイルの場合\r
+ filelist.each do |file|\r
+ File.delete("./work/#{file}") if Time.now - File.ctime("./work/#{file}") > 86400 && File.ftype("./work/#{file}") == "file"\r
+ end\r
+ break\r
+ end\r
+ }\r
+ \r
+ # ログイン失敗ユーザを記録\r
+ if (session["login"] != "true" and (cgi["loginid"] != "" or cgi["password"] != ""))\r
+ session["error"] = "ログインに失敗しました。ユーザIDまたはパスワードを確認して下さい。"\r
+ logger.info "次のアクセスがログインに失敗しました。ログインID:#{cgi["loginid"]}, IPアドレス:#{cgi.remote_addr}"\r
+ end\r
+ end\r
+\r
+ # ログアウト処理\r
+ if params["mode"] == "logout"\r
+ session["login"] = nil\r
+ session["logini"] = nil\r
+ session["password"] = nil\r
+ session.delete\r
+ end\r
+\r
+ \r
+ begin\r
+ # セッションが有効な場合のみコントローラを実行します\r
+ if session["login"] == "true"\r
+ db = PStore.new("./work/#{session.session_id}_file.dat")\r
+ # コントローラ部分\r
+ Controller.MultiForm(cgi, session, params, db)\r
+ end\r
+\r
+ # ビュー部分\r
+ if session["login"] != "true"\r
+ # セッションが存在しない場合は強制的にエラーページに遷移\r
+ htmlwriter = HtmlWriter.new("./erbtemp/login.html.erb", binding)\r
+ else\r
+ htmlwriter = HtmlWriter.new("./erbtemp/filemanager.html.erb", binding)\r
+ end\r
+\r
+ # 実際にHTMLを出力します\r
+ cgi.out{htmlwriter.to_code}\r
+ rescue => exception\r
+ # ログに記録を実施します\r
+ logger.error(exception.to_s)\r
+ logger.error(exception.backtrace.join "\n")\r
+ \r
+ # エラーが発生した場合、それを画面に表示します\r
+ htmlwriter = HtmlWriter.new("./erbtemp/exception.html.erb", binding)\r
+ cgi.out{ htmlwriter.to_code }\r
+ end\r
+end\r
+\r
+begin\r
+ main\r
+rescue => evar\r
+ # エラーが発生した場合、それを画面に表示します\r
+ detail = ("%s: %s (%s)\n" %\r
+ [evar.backtrace[0], evar.message, evar.send('class')]) +\r
+ evar.backtrace[1..-1].join("\n")\r
+ puts "content-type: text/html\n\n<plaintext>\n" + detail\r
+end\r
--- /dev/null
+/*!\r
+ * jQuery JavaScript Library v1.6.1\r
+ * http://jquery.com/\r
+ *\r
+ * Copyright 2011, John Resig\r
+ * Dual licensed under the MIT or GPL Version 2 licenses.\r
+ * http://jquery.org/license\r
+ *\r
+ * Includes Sizzle.js\r
+ * http://sizzlejs.com/\r
+ * Copyright 2011, The Dojo Foundation\r
+ * Released under the MIT, BSD, and GPL Licenses.\r
+ *\r
+ * Date: Thu May 12 15:04:36 2011 -0400\r
+ */\r
+(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cv(a){if(!cj[a]){var b=f("<"+a+">").appendTo("body"),d=b.css("display");b.remove();if(d==="none"||d===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),c.body.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write("<!doctype><html><body></body></html>");b=cl.createElement(a),cl.body.appendChild(b),d=f.css(b,"display"),c.body.removeChild(ck)}cj[a]=d}return cj[a]}function cu(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function ct(){cq=b}function cs(){setTimeout(ct,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bF.test(a)?d(a,e):b_(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bU,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=b$(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=b$(a,c,d,e,"*",g));return l}function bZ(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bQ),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bD(a,b,c){var d=b==="width"?bx:by,e=b==="width"?a.offsetWidth:a.offsetHeight;if(c==="border")return e;f.each(d,function(){c||(e-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?e+=parseFloat(f.css(a,"margin"+this))||0:e-=parseFloat(f.css(a,"border"+this+"Width"))||0});return e}function bn(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bm(a){f.nodeName(a,"input")?bl(a):a.getElementsByTagName&&f.grep(a.getElementsByTagName("input"),bl)}function bl(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bk(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bj(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bi(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bh(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function X(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(S.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function W(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function O(a,b){return(a&&a!=="*"?a+".":"")+b.replace(A,"`").replace(B,"&")}function N(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(y,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function L(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function F(){return!0}function E(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function H(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(H,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=d.userAgent,x,y,z,A=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.push,D=Array.prototype.slice,E=String.prototype.trim,F=Array.prototype.indexOf,G={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.1",length:0,size:function(){return this.length},toArray:function(){return D.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?C.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),y.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(D.apply(this,arguments),"slice",D.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:C,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;y.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!y){y=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",z,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",z),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&H()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):G[A.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!B.call(a,"constructor")&&!B.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||B.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:E?function(a){return a==null?"":E.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?C.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(F)return F.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=D.call(arguments,2),g=function(){return a.apply(c,f.concat(D.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){G["[object "+b+"]"]=b.toLowerCase()}),x=e.uaMatch(w),x.browser&&(e.browser[x.browser]=!0,e.browser.version=x.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?z=function(){c.removeEventListener("DOMContentLoaded",z,!1),e.ready()}:c.attachEvent&&(z=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",z),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g](h)}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};f=c.createElement("select"),g=f.appendChild(c.createElement("option")),h=a.getElementsByTagName("input")[0],j={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:h.value==="on",optSelected:g.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},h.checked=!0,j.noCloneChecked=h.cloneNode(!0).checked,f.disabled=!0,j.optDisabled=!g.disabled;try{delete a.test}catch(s){j.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function b(){j.noCloneEvent=!1,a.detachEvent("onclick",b)}),a.cloneNode(!0).fireEvent("onclick")),h=c.createElement("input"),h.value="t",h.setAttribute("type","radio"),j.radioValue=h.value==="t",h.setAttribute("checked","checked"),a.appendChild(h),k=c.createDocumentFragment(),k.appendChild(a.firstChild),j.checkClone=k.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",l=c.createElement("body"),m={visibility:"hidden",width:0,height:0,border:0,margin:0,background:"none"};for(q in m)l.style[q]=m[q];l.appendChild(a),b.insertBefore(l,b.firstChild),j.appendChecked=h.checked,j.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,j.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",j.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",n=a.getElementsByTagName("td"),r=n[0].offsetHeight===0,n[0].style.display="",n[1].style.display="none",j.reliableHiddenOffsets=r&&n[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(i=c.createElement("div"),i.style.width="0",i.style.marginRight="0",a.appendChild(i),j.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(i,null)||{marginRight:0}).marginRight,10)||0)===0),l.innerHTML="",b.removeChild(l);if(a.attachEvent)for(q in{submit:1,change:1,focusin:1})p="on"+q,r=p in a,r||(a.setAttribute(p,"return;"),r=typeof a[p]=="function"),j[q+"Bubbles"]=r;return j}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u=/\:/,v,w;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.addClass(a.call(this,b,c.attr("class")||""))});if(a&&typeof a=="string"){var b=(a||"").split(o);for(var c=0,d=this.length;c<d;c++){var e=this[c];if(e.nodeType===1)if(!e.className)e.className=a;else{var g=" "+e.className+" ",h=e.className;for(var i=0,j=b.length;i<j;i++)g.indexOf(" "+b[i]+" ")<0&&(h+=" "+b[i]);e.className=f.trim(h)}}}return this},removeClass:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.removeClass(a.call(this,b,c.attr("class")))});if(a&&typeof a=="string"||a===b){var c=(a||"").split(o);for(var d=0,e=this.length;d<e;d++){var g=this[d];if(g.nodeType===1&&g.className)if(a){var h=(" "+g.className+" ").replace(n," ");for(var i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){var d=f(this);d.toggleClass(a.call(this,c,d.attr("class"),b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;return(e.value||"").replace(p,"")}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);c=j&&f.attrFix[c]||c,i=f.attrHooks[c],i||(!t.test(c)||typeof d!="boolean"&&d!==b&&d.toLowerCase()!==c.toLowerCase()?v&&(f.nodeName(a,"form")||u.test(c))&&(i=v):i=w);if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j)return i.get(a,c);h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);c=i&&f.propFix[c]||c,h=f.propHooks[c];return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return a[f.propFix[c]||c]?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=b),a.setAttribute(c,c.toLowerCase()));return c}},f.attrHooks.value={get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return a.value},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=Object.prototype.hasOwnProperty,y=/\.(.*)$/,z=/^(?:textarea|input|select)$/i,A=/\./g,B=/ /g,C=/[^\w\s.|`]/g,D=function(a){return a.replace(C,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=E;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=E);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),D).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem\r
+)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,O(a.origType,a.selector),f.extend({},a,{handler:N,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,O(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?F:E):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=F;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=F;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=F,this.stopPropagation()},isDefaultPrevented:E,isPropagationStopped:E,isImmediatePropagationStopped:E};var G=function(a){var b=a.relatedTarget;a.type=a.data;try{if(b&&b!==c&&!b.parentNode)return;while(b&&b!==this)b=b.parentNode;b!==this&&f.event.handle.apply(this,arguments)}catch(d){}},H=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?H:G,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?H:G)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&f(b).closest("form").length&&L("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&L("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var I,J=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},K=function(c){var d=c.target,e,g;if(!!z.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=J(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:K,beforedeactivate:K,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&K.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&K.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",J(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in I)f.event.add(this,c+".specialChange",I[c]);return z.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return z.test(this.nodeName)}},I=f.event.special.change.filters,I.focus=I.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var M={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||E,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=y.exec(h),k="",j&&(k=j[0],h=h.replace(y,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,M[h]?(a.push(M[h]+k),h=h+k):h=(M[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+O(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+O(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var P=/Until$/,Q=/^(?:parents|prevUntil|prevAll)/,R=/,/,S=/^.[^:#\[\.,]*$/,T=Array.prototype.slice,U=f.expr.match.POS,V={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(X(this,a,!1),"not",a)},filter:function(a){return this.pushStack(X(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=U.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=U.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(W(c[0])||W(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=T.call(arguments);P.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!V[a]?f.unique(e):e,(this.length>1||R.test(d))&&Q.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var Y=/ jQuery\d+="(?:\d+|null)"/g,Z=/^\s+/,$=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,_=/<([\w:]+)/,ba=/<tbody/i,bb=/<|&#?\w+;/,bc=/<(?:script|object|embed|option|style)/i,bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Y,""):null;if(typeof a=="string"&&!bc.test(a)&&(f.support.leadingWhitespace||!Z.test(a))&&!bg[(_.exec(a)||["",""])[1].toLowerCase()]){a=a.replace($,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bh(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bn)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i=b&&b[0]?b[0].ownerDocument||b[0]:c;a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!bc.test(a[0])&&(f.support.checkClone||!bd.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bj(a,d),e=bk(a),g=bk(d);for(h=0;e[h];++h)bj(e[h],g[h])}if(b){bi(a,d);if(c){e=bk(a),g=bk(d);for(h=0;e[h];++h)bi(e[h],g[h])}}return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||\r
+b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!bb.test(k))k=b.createTextNode(k);else{k=k.replace($,"<$1></$2>");var l=(_.exec(k)||["",""])[1].toLowerCase(),m=bg[l]||bg._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=ba.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Z.test(k)&&o.insertBefore(b.createTextNode(Z.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bm(k[i]);else bm(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||be.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bo=/alpha\([^)]*\)/i,bp=/opacity=([^)]*)/,bq=/-([a-z])/ig,br=/([A-Z]|^ms)/g,bs=/^-?\d+(?:px)?$/i,bt=/^-?\d/,bu=/^[+\-]=/,bv=/[^+\-\.\de]+/g,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Left","Right"],by=["Top","Bottom"],bz,bA,bB,bC=function(a,b){return b.toUpperCase()};f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bz(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{zIndex:!0,fontWeight:!0,opacity:!0,zoom:!0,lineHeight:!0,widows:!0,orphans:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d;if(h==="number"&&isNaN(d)||d==null)return;h==="string"&&bu.test(d)&&(d=+d.replace(bv,"")+parseFloat(f.css(a,c))),h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bz)return bz(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]},camelCase:function(a){return a.replace(bq,bC)}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){a.offsetWidth!==0?e=bD(a,b,d):f.swap(a,bw,function(){e=bD(a,b,d)});if(e<=0){e=bz(a,b,b),e==="0px"&&bB&&(e=bB(a,b,b));if(e!=null)return e===""||e==="auto"?"0px":e}if(e<0||e==null){e=a.style[b];return e===""||e==="auto"?"0px":e}return typeof e=="string"?e:e+"px"}},set:function(a,b){if(!bs.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bp.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bo.test(g)?g.replace(bo,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bz(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(bA=function(a,c){var d,e,g;c=c.replace(br,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bB=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bs.test(d)&&bt.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bz=bA||bB,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bE=/%20/g,bF=/\[\]$/,bG=/\r?\n/g,bH=/#.*$/,bI=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bJ=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bK=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bL=/^(?:GET|HEAD)$/,bM=/^\/\//,bN=/\?/,bO=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bP=/^(?:select|textarea)/i,bQ=/\s+/,bR=/([?&])_=[^&]*/,bS=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bT=f.fn.load,bU={},bV={},bW,bX;try{bW=e.href}catch(bY){bW=c.createElement("a"),bW.href="",bW=bW.href}bX=bS.exec(bW.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bT)return bT.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bO,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bP.test(this.nodeName)||bJ.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bG,"\r\n")}}):{name:b.name,value:c.replace(bG,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bW,isLocal:bK.test(bX[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bZ(bU),ajaxTransport:bZ(bV),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?ca(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=cb(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bI.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bH,"").replace(bM,bX[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bQ),d.crossDomain==null&&(r=bS.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bX[1]&&r[2]==bX[2]&&(r[3]||(r[1]==="http:"?80:443))==(bX[3]||(bX[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),b$(bU,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bL.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bN.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bR,"$1_="+x);d.url=y+(y===d.url?(bN.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=b$(bV,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bE,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq,cr=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cu("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cv(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cu("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cu("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cv(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cm.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=cn.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cu("show",1),slideUp:cu("hide",1),slideToggle:cu("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this),f.isFunction(d.old)&&d.old.call(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function h(a){return d.step(a)}var d=this,e=f.fx,g;this.startTime=cq||cs(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,h.elem=this.elem,h()&&f.timers.push(h)&&!co&&(cr?(co=1,g=function(){co&&(cr(g),e.tick())},cr(g)):co=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cq||cs(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cy(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!cw.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cy(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cy(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){return this[0]?parseFloat(f.css(this[0],d,"padding")):null},f.fn["outer"+c]=function(a){return this[0]?parseFloat(f.css(this[0],d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window);
\ No newline at end of file
--- /dev/null
+#!/usr/local/bin/ruby
+# -*- coding: utf-8 -*-
+
+THUMBS_SIZE = 150
+
+class ResizeManager
+ def self.create_thumbs(fname)
+ $LOAD_PATH.push("/home/lunardial/local/lib")
+ $LOAD_PATH.push("/home/lunardial/local/lib/ruby/gem/gems/rmagick-2.13.1/lib")
+
+ require 'rubygems'
+ require 'RMagick'
+
+ img = Magick::Image.read(fname).first
+
+ img.resize_to_fit!(THUMBS_SIZE, THUMBS_SIZE)
+ thumbs_name = fname.gsub(/#{File.extname(fname)}\Z/, "") + "_thumbs" + File.extname(fname)
+ img.write(thumbs_name)
+ end
+end