Skip to content

Instantly share code, notes, and snippets.

@whiteleaf7
Created December 18, 2012 04:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whiteleaf7/4325096 to your computer and use it in GitHub Desktop.
Save whiteleaf7/4325096 to your computer and use it in GitHub Desktop.
Limechat Quake Notifier 去年の震災直後に作った 、P2P地震情報をLimechatと連携させるソフト。お蔵入りにしてたけれどもったいないので保存
//
// Simple Ini file controller
//
// [ ] で囲まれたものはセクションとして扱われ、それ以降のデータはセクションに所属する
// セクションが登場するまでのデータは global というセクションに割り当てられる
//
// var ini = new Ini("setting.ini");
// value1 = ini.data.global.key;
// value2 = ini.data.section.key;
//
var Ini = Class.create({
delimiter: "=",
global_section: "global",
initialize: function(filename) {
this.filename = filename;
},
clear: function() {
this.data = { global: {} };
},
load: function() {
this.clear();
var file = openFile(this.filename);
if (file) {
var section = this.global_section;
var line;
while ((line = file.readLine()) != null) {
if (line.trim() == 0) continue;
if (/^\[(.+?)\]/.test(line)) {
section = RegExp.$1.trim();
if (!this.data[section]) {
this.data[section] = {};
}
continue;
}
var res = line.split(this.delimiter);
if (res.length != 2) continue;
var key = res[0].trim(), value = res[1].trim();
this.data[section][key] = value;
}
file.close();
return true;
}
return false;
},
save: function() {
var file = openFile(this.filename, false);
if (file) {
for (var section in this.data) {
if (section != this.global_section) {
file.writeLine("[" + section + "]");
}
for (var key in this.data[section]) {
file.writeLine(key + this.delimiter + this.data[section][key]);
}
}
file.truncate();
file.close();
return true;
}
return false;
}
});
String.prototype.trim = function() {
return this.replace(/(^\s+)|(\s+$)/g, "");
};
/* Prototype JavaScript framework, version 1.7
* (c) 2005-2010 Sam Stephenson
*
* Prototype is freely distributable under the terms of an MIT-style license.
* For details, see the Prototype web site: http://www.prototypejs.org/
*
*--------------------------------------------------------------------------*/
var document={getElementsByTagName:function(){return[{src:''}];},
createElement:function(){return{appendChild:function(){}};},
createTextNode:function(){},createEvent:function(){return{__proto__:{}};},
getElementById:function(){return{};},write:function(){},domain:'localhost'};
var window={document:document,attachEvent:function(){},setTimeout:function(a,b){setTimeout(a,b);}};
var navigator={userAgent:'LimeChat'};var location={protocol:'http:',port:''};
var Prototype = {
Version: '1.7',
Browser: (function(){
var ua = navigator.userAgent;
var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]';
return {
IE: !!window.attachEvent && !isOpera,
Opera: isOpera,
WebKit: ua.indexOf('AppleWebKit/') > -1,
Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
MobileSafari: /Apple.*Mobile/.test(ua)
}
})(),
BrowserFeatures: {
XPath: !!document.evaluate,
SelectorsAPI: !!document.querySelector,
ElementExtensions: (function() {
var constructor = window.Element || window.HTMLElement;
return !!(constructor && constructor.prototype);
})(),
SpecificElementExtensions: (function() {
if (typeof window.HTMLDivElement !== 'undefined')
return true;
var div = document.createElement('div'),
form = document.createElement('form'),
isSupported = false;
if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
isSupported = true;
}
div = form = null;
return isSupported;
})()
},
ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
emptyFunction: function() { },
K: function(x) { return x }
};
if (Prototype.Browser.MobileSafari)
Prototype.BrowserFeatures.SpecificElementExtensions = false;
var Abstract = { };
var Try = {
these: function() {
var returnValue;
for (var i = 0, length = arguments.length; i < length; i++) {
var lambda = arguments[i];
try {
returnValue = lambda();
break;
} catch (e) { }
}
return returnValue;
}
};
/* Based on Alex Arnell's inheritance implementation. */
var Class = (function() {
var IS_DONTENUM_BUGGY = (function(){
for (var p in { toString: 1 }) {
if (p === 'toString') return false;
}
return true;
})();
function subclass() {};
function create() {
var parent = null, properties = $A(arguments);
if (Object.isFunction(properties[0]))
parent = properties.shift();
function klass() {
this.initialize.apply(this, arguments);
}
Object.extend(klass, Class.Methods);
klass.superclass = parent;
klass.subclasses = [];
if (parent) {
subclass.prototype = parent.prototype;
klass.prototype = new subclass;
parent.subclasses.push(klass);
}
for (var i = 0, length = properties.length; i < length; i++)
klass.addMethods(properties[i]);
if (!klass.prototype.initialize)
klass.prototype.initialize = Prototype.emptyFunction;
klass.prototype.constructor = klass;
return klass;
}
function addMethods(source) {
var ancestor = this.superclass && this.superclass.prototype,
properties = Object.keys(source);
if (IS_DONTENUM_BUGGY) {
if (source.toString != Object.prototype.toString)
properties.push("toString");
if (source.valueOf != Object.prototype.valueOf)
properties.push("valueOf");
}
for (var i = 0, length = properties.length; i < length; i++) {
var property = properties[i], value = source[property];
if (ancestor && Object.isFunction(value) &&
value.argumentNames()[0] == "$super") {
var method = value;
value = (function(m) {
return function() { return ancestor[m].apply(this, arguments); };
})(property).wrap(method);
value.valueOf = method.valueOf.bind(method);
value.toString = method.toString.bind(method);
}
this.prototype[property] = value;
}
return this;
}
return {
create: create,
Methods: {
addMethods: addMethods
}
};
})();
(function() {
var _toString = Object.prototype.toString,
NULL_TYPE = 'Null',
UNDEFINED_TYPE = 'Undefined',
BOOLEAN_TYPE = 'Boolean',
NUMBER_TYPE = 'Number',
STRING_TYPE = 'String',
OBJECT_TYPE = 'Object',
FUNCTION_CLASS = '[object Function]',
BOOLEAN_CLASS = '[object Boolean]',
NUMBER_CLASS = '[object Number]',
STRING_CLASS = '[object String]',
ARRAY_CLASS = '[object Array]',
DATE_CLASS = '[object Date]',
NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
typeof JSON.stringify === 'function' &&
JSON.stringify(0) === '0' &&
typeof JSON.stringify(Prototype.K) === 'undefined';
function Type(o) {
switch(o) {
case null: return NULL_TYPE;
case (void 0): return UNDEFINED_TYPE;
}
var type = typeof o;
switch(type) {
case 'boolean': return BOOLEAN_TYPE;
case 'number': return NUMBER_TYPE;
case 'string': return STRING_TYPE;
}
return OBJECT_TYPE;
}
function extend(destination, source) {
for (var property in source)
destination[property] = source[property];
return destination;
}
function inspect(object) {
try {
if (isUndefined(object)) return 'undefined';
if (object === null) return 'null';
return object.inspect ? object.inspect() : String(object);
} catch (e) {
if (e instanceof RangeError) return '...';
throw e;
}
}
function toJSON(value) {
return Str('', { '': value }, []);
}
function Str(key, holder, stack) {
var value = holder[key],
type = typeof value;
if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
value = value.toJSON(key);
}
var _class = _toString.call(value);
switch (_class) {
case NUMBER_CLASS:
case BOOLEAN_CLASS:
case STRING_CLASS:
value = value.valueOf();
}
switch (value) {
case null: return 'null';
case true: return 'true';
case false: return 'false';
}
type = typeof value;
switch (type) {
case 'string':
return value.inspect(true);
case 'number':
return isFinite(value) ? String(value) : 'null';
case 'object':
for (var i = 0, length = stack.length; i < length; i++) {
if (stack[i] === value) { throw new TypeError(); }
}
stack.push(value);
var partial = [];
if (_class === ARRAY_CLASS) {
for (var i = 0, length = value.length; i < length; i++) {
var str = Str(i, value, stack);
partial.push(typeof str === 'undefined' ? 'null' : str);
}
partial = '[' + partial.join(',') + ']';
} else {
var keys = Object.keys(value);
for (var i = 0, length = keys.length; i < length; i++) {
var key = keys[i], str = Str(key, value, stack);
if (typeof str !== "undefined") {
partial.push(key.inspect(true)+ ':' + str);
}
}
partial = '{' + partial.join(',') + '}';
}
stack.pop();
return partial;
}
}
function stringify(object) {
return JSON.stringify(object);
}
function toQueryString(object) {
return $H(object).toQueryString();
}
function toHTML(object) {
return object && object.toHTML ? object.toHTML() : String.interpret(object);
}
function keys(object) {
if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
var results = [];
for (var property in object) {
if (object.hasOwnProperty(property)) {
results.push(property);
}
}
return results;
}
function values(object) {
var results = [];
for (var property in object)
results.push(object[property]);
return results;
}
function clone(object) {
return extend({ }, object);
}
function isElement(object) {
return !!(object && object.nodeType == 1);
}
function isArray(object) {
return _toString.call(object) === ARRAY_CLASS;
}
var hasNativeIsArray = (typeof Array.isArray == 'function')
&& Array.isArray([]) && !Array.isArray({});
if (hasNativeIsArray) {
isArray = Array.isArray;
}
function isHash(object) {
return object instanceof Hash;
}
function isFunction(object) {
return _toString.call(object) === FUNCTION_CLASS;
}
function isString(object) {
return _toString.call(object) === STRING_CLASS;
}
function isNumber(object) {
return _toString.call(object) === NUMBER_CLASS;
}
function isDate(object) {
return _toString.call(object) === DATE_CLASS;
}
function isUndefined(object) {
return typeof object === "undefined";
}
extend(Object, {
extend: extend,
inspect: inspect,
toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
toQueryString: toQueryString,
toHTML: toHTML,
keys: Object.keys || keys,
values: values,
clone: clone,
isElement: isElement,
isArray: isArray,
isHash: isHash,
isFunction: isFunction,
isString: isString,
isNumber: isNumber,
isDate: isDate,
isUndefined: isUndefined
});
})();
Object.extend(Function.prototype, (function() {
var slice = Array.prototype.slice;
function update(array, args) {
var arrayLength = array.length, length = args.length;
while (length--) array[arrayLength + length] = args[length];
return array;
}
function merge(array, args) {
array = slice.call(array, 0);
return update(array, args);
}
function argumentNames() {
var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1]
.replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '')
.replace(/\s+/g, '').split(',');
return names.length == 1 && !names[0] ? [] : names;
}
function bind(context) {
if (arguments.length < 2 && Object.isUndefined(arguments[0])) return this;
var __method = this, args = slice.call(arguments, 1);
return function() {
var a = merge(args, arguments);
return __method.apply(context, a);
}
}
function bindAsEventListener(context) {
var __method = this, args = slice.call(arguments, 1);
return function(event) {
var a = update([event || window.event], args);
return __method.apply(context, a);
}
}
function curry() {
if (!arguments.length) return this;
var __method = this, args = slice.call(arguments, 0);
return function() {
var a = merge(args, arguments);
return __method.apply(this, a);
}
}
function delay(timeout) {
var __method = this, args = slice.call(arguments, 1);
timeout = timeout * 1000;
return window.setTimeout(function() {
return __method.apply(__method, args);
}, timeout);
}
function defer() {
var args = update([0.01], arguments);
return this.delay.apply(this, args);
}
function wrap(wrapper) {
var __method = this;
return function() {
var a = update([__method.bind(this)], arguments);
return wrapper.apply(this, a);
}
}
function methodize() {
if (this._methodized) return this._methodized;
var __method = this;
return this._methodized = function() {
var a = update([this], arguments);
return __method.apply(null, a);
};
}
return {
argumentNames: argumentNames,
bind: bind,
bindAsEventListener: bindAsEventListener,
curry: curry,
delay: delay,
defer: defer,
wrap: wrap,
methodize: methodize
}
})());
(function(proto) {
function toISOString() {
return this.getUTCFullYear() + '-' +
(this.getUTCMonth() + 1).toPaddedString(2) + '-' +
this.getUTCDate().toPaddedString(2) + 'T' +
this.getUTCHours().toPaddedString(2) + ':' +
this.getUTCMinutes().toPaddedString(2) + ':' +
this.getUTCSeconds().toPaddedString(2) + 'Z';
}
function toJSON() {
return this.toISOString();
}
if (!proto.toISOString) proto.toISOString = toISOString;
if (!proto.toJSON) proto.toJSON = toJSON;
})(Date.prototype);
RegExp.prototype.match = RegExp.prototype.test;
RegExp.escape = function(str) {
return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};
var PeriodicalExecuter = Class.create({
initialize: function(callback, frequency) {
this.callback = callback;
this.frequency = frequency;
this.currentlyExecuting = false;
this.registerCallback();
},
registerCallback: function() {
this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
},
execute: function() {
this.callback(this);
},
stop: function() {
if (!this.timer) return;
clearInterval(this.timer);
this.timer = null;
},
onTimerEvent: function() {
if (!this.currentlyExecuting) {
try {
this.currentlyExecuting = true;
this.execute();
this.currentlyExecuting = false;
} catch(e) {
this.currentlyExecuting = false;
throw e;
}
}
}
});
Object.extend(String, {
interpret: function(value) {
return value == null ? '' : String(value);
},
specialChar: {
'\b': '\\b',
'\t': '\\t',
'\n': '\\n',
'\f': '\\f',
'\r': '\\r',
'\\': '\\\\'
}
});
Object.extend(String.prototype, (function() {
var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
typeof JSON.parse === 'function' &&
JSON.parse('{"test": true}').test;
function prepareReplacement(replacement) {
if (Object.isFunction(replacement)) return replacement;
var template = new Template(replacement);
return function(match) { return template.evaluate(match) };
}
function gsub(pattern, replacement) {
var result = '', source = this, match;
replacement = prepareReplacement(replacement);
if (Object.isString(pattern))
pattern = RegExp.escape(pattern);
if (!(pattern.length || pattern.source)) {
replacement = replacement('');
return replacement + source.split('').join(replacement) + replacement;
}
while (source.length > 0) {
if (match = source.match(pattern)) {
result += source.slice(0, match.index);
result += String.interpret(replacement(match));
source = source.slice(match.index + match[0].length);
} else {
result += source, source = '';
}
}
return result;
}
function sub(pattern, replacement, count) {
replacement = prepareReplacement(replacement);
count = Object.isUndefined(count) ? 1 : count;
return this.gsub(pattern, function(match) {
if (--count < 0) return match[0];
return replacement(match);
});
}
function scan(pattern, iterator) {
this.gsub(pattern, iterator);
return String(this);
}
function truncate(length, truncation) {
length = length || 30;
truncation = Object.isUndefined(truncation) ? '...' : truncation;
return this.length > length ?
this.slice(0, length - truncation.length) + truncation : String(this);
}
function strip() {
return this.replace(/^\s+/, '').replace(/\s+$/, '');
}
function stripTags() {
return this.replace(/<\w+(\s+("[^"]*"|'[^']*'|[^>])+)?>|<\/\w+>/gi, '');
}
function stripScripts() {
return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
}
function extractScripts() {
var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
matchOne = new RegExp(Prototype.ScriptFragment, 'im');
return (this.match(matchAll) || []).map(function(scriptTag) {
return (scriptTag.match(matchOne) || ['', ''])[1];
});
}
function evalScripts() {
return this.extractScripts().map(function(script) { return eval(script) });
}
function escapeHTML() {
return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}
function unescapeHTML() {
return this.stripTags().replace(/&lt;/g,'<').replace(/&gt;/g,'>').replace(/&amp;/g,'&');
}
function toQueryParams(separator) {
var match = this.strip().match(/([^?#]*)(#.*)?$/);
if (!match) return { };
return match[1].split(separator || '&').inject({ }, function(hash, pair) {
if ((pair = pair.split('='))[0]) {
var key = decodeURIComponent(pair.shift()),
value = pair.length > 1 ? pair.join('=') : pair[0];
if (value != undefined) value = decodeURIComponent(value);
if (key in hash) {
if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
hash[key].push(value);
}
else hash[key] = value;
}
return hash;
});
}
function toArray() {
return this.split('');
}
function succ() {
return this.slice(0, this.length - 1) +
String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
}
function times(count) {
return count < 1 ? '' : new Array(count + 1).join(this);
}
function camelize() {
return this.replace(/-+(.)?/g, function(match, chr) {
return chr ? chr.toUpperCase() : '';
});
}
function capitalize() {
return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
}
function underscore() {
return this.replace(/::/g, '/')
.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2')
.replace(/([a-z\d])([A-Z])/g, '$1_$2')
.replace(/-/g, '_')
.toLowerCase();
}
function dasherize() {
return this.replace(/_/g, '-');
}
function inspect(useDoubleQuotes) {
var escapedString = this.replace(/[\x00-\x1f\\]/g, function(character) {
if (character in String.specialChar) {
return String.specialChar[character];
}
return '\\u00' + character.charCodeAt().toPaddedString(2, 16);
});
if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
return "'" + escapedString.replace(/'/g, '\\\'') + "'";
}
function unfilterJSON(filter) {
return this.replace(filter || Prototype.JSONFilter, '$1');
}
function isJSON() {
var str = this;
if (str.blank()) return false;
str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
return (/^[\],:{}\s]*$/).test(str);
}
function evalJSON(sanitize) {
var json = this.unfilterJSON(),
cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
if (cx.test(json)) {
json = json.replace(cx, function (a) {
return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
});
}
try {
if (!sanitize || json.isJSON()) return eval('(' + json + ')');
} catch (e) { }
throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
}
function parseJSON() {
var json = this.unfilterJSON();
return JSON.parse(json);
}
function include(pattern) {
return this.indexOf(pattern) > -1;
}
function startsWith(pattern) {
return this.lastIndexOf(pattern, 0) === 0;
}
function endsWith(pattern) {
var d = this.length - pattern.length;
return d >= 0 && this.indexOf(pattern, d) === d;
}
function empty() {
return this == '';
}
function blank() {
return /^\s*$/.test(this);
}
function interpolate(object, pattern) {
return new Template(this, pattern).evaluate(object);
}
return {
gsub: gsub,
sub: sub,
scan: scan,
truncate: truncate,
strip: String.prototype.trim || strip,
stripTags: stripTags,
stripScripts: stripScripts,
extractScripts: extractScripts,
evalScripts: evalScripts,
escapeHTML: escapeHTML,
unescapeHTML: unescapeHTML,
toQueryParams: toQueryParams,
parseQuery: toQueryParams,
toArray: toArray,
succ: succ,
times: times,
camelize: camelize,
capitalize: capitalize,
underscore: underscore,
dasherize: dasherize,
inspect: inspect,
unfilterJSON: unfilterJSON,
isJSON: isJSON,
evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
include: include,
startsWith: startsWith,
endsWith: endsWith,
empty: empty,
blank: blank,
interpolate: interpolate
};
})());
var Template = Class.create({
initialize: function(template, pattern) {
this.template = template.toString();
this.pattern = pattern || Template.Pattern;
},
evaluate: function(object) {
if (object && Object.isFunction(object.toTemplateReplacements))
object = object.toTemplateReplacements();
return this.template.gsub(this.pattern, function(match) {
if (object == null) return (match[1] + '');
var before = match[1] || '';
if (before == '\\') return match[2];
var ctx = object, expr = match[3],
pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
match = pattern.exec(expr);
if (match == null) return before;
while (match != null) {
var comp = match[1].startsWith('[') ? match[2].replace(/\\\\]/g, ']') : match[1];
ctx = ctx[comp];
if (null == ctx || '' == match[3]) break;
expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
match = pattern.exec(expr);
}
return before + String.interpret(ctx);
});
}
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
var $break = { };
var Enumerable = (function() {
function each(iterator, context) {
var index = 0;
try {
this._each(function(value) {
iterator.call(context, value, index++);
});
} catch (e) {
if (e != $break) throw e;
}
return this;
}
function eachSlice(number, iterator, context) {
var index = -number, slices = [], array = this.toArray();
if (number < 1) return array;
while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
return slices.collect(iterator, context);
}
function all(iterator, context) {
iterator = iterator || Prototype.K;
var result = true;
this.each(function(value, index) {
result = result && !!iterator.call(context, value, index);
if (!result) throw $break;
});
return result;
}
function any(iterator, context) {
iterator = iterator || Prototype.K;
var result = false;
this.each(function(value, index) {
if (result = !!iterator.call(context, value, index))
throw $break;
});
return result;
}
function collect(iterator, context) {
iterator = iterator || Prototype.K;
var results = [];
this.each(function(value, index) {
results.push(iterator.call(context, value, index));
});
return results;
}
function detect(iterator, context) {
var result;
this.each(function(value, index) {
if (iterator.call(context, value, index)) {
result = value;
throw $break;
}
});
return result;
}
function findAll(iterator, context) {
var results = [];
this.each(function(value, index) {
if (iterator.call(context, value, index))
results.push(value);
});
return results;
}
function grep(filter, iterator, context) {
iterator = iterator || Prototype.K;
var results = [];
if (Object.isString(filter))
filter = new RegExp(RegExp.escape(filter));
this.each(function(value, index) {
if (filter.match(value))
results.push(iterator.call(context, value, index));
});
return results;
}
function include(object) {
if (Object.isFunction(this.indexOf))
if (this.indexOf(object) != -1) return true;
var found = false;
this.each(function(value) {
if (value == object) {
found = true;
throw $break;
}
});
return found;
}
function inGroupsOf(number, fillWith) {
fillWith = Object.isUndefined(fillWith) ? null : fillWith;
return this.eachSlice(number, function(slice) {
while(slice.length < number) slice.push(fillWith);
return slice;
});
}
function inject(memo, iterator, context) {
this.each(function(value, index) {
memo = iterator.call(context, memo, value, index);
});
return memo;
}
function invoke(method) {
var args = $A(arguments).slice(1);
return this.map(function(value) {
return value[method].apply(value, args);
});
}
function max(iterator, context) {
iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
value = iterator.call(context, value, index);
if (result == null || value >= result)
result = value;
});
return result;
}
function min(iterator, context) {
iterator = iterator || Prototype.K;
var result;
this.each(function(value, index) {
value = iterator.call(context, value, index);
if (result == null || value < result)
result = value;
});
return result;
}
function partition(iterator, context) {
iterator = iterator || Prototype.K;
var trues = [], falses = [];
this.each(function(value, index) {
(iterator.call(context, value, index) ?
trues : falses).push(value);
});
return [trues, falses];
}
function pluck(property) {
var results = [];
this.each(function(value) {
results.push(value[property]);
});
return results;
}
function reject(iterator, context) {
var results = [];
this.each(function(value, index) {
if (!iterator.call(context, value, index))
results.push(value);
});
return results;
}
function sortBy(iterator, context) {
return this.map(function(value, index) {
return {
value: value,
criteria: iterator.call(context, value, index)
};
}).sort(function(left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
}).pluck('value');
}
function toArray() {
return this.map();
}
function zip() {
var iterator = Prototype.K, args = $A(arguments);
if (Object.isFunction(args.last()))
iterator = args.pop();
var collections = [this].concat(args).map($A);
return this.map(function(value, index) {
return iterator(collections.pluck(index));
});
}
function size() {
return this.toArray().length;
}
function inspect() {
return '#<Enumerable:' + this.toArray().inspect() + '>';
}
return {
each: each,
eachSlice: eachSlice,
all: all,
every: all,
any: any,
some: any,
collect: collect,
map: collect,
detect: detect,
findAll: findAll,
select: findAll,
filter: findAll,
grep: grep,
include: include,
member: include,
inGroupsOf: inGroupsOf,
inject: inject,
invoke: invoke,
max: max,
min: min,
partition: partition,
pluck: pluck,
reject: reject,
sortBy: sortBy,
toArray: toArray,
entries: toArray,
zip: zip,
size: size,
inspect: inspect,
find: detect
};
})();
function $A(iterable) {
if (!iterable) return [];
if ('toArray' in Object(iterable)) return iterable.toArray();
var length = iterable.length || 0, results = new Array(length);
while (length--) results[length] = iterable[length];
return results;
}
function $w(string) {
if (!Object.isString(string)) return [];
string = string.strip();
return string ? string.split(/\s+/) : [];
}
Array.from = $A;
(function() {
var arrayProto = Array.prototype,
slice = arrayProto.slice,
_each = arrayProto.forEach; // use native browser JS 1.6 implementation if available
function each(iterator, context) {
for (var i = 0, length = this.length >>> 0; i < length; i++) {
if (i in this) iterator.call(context, this[i], i, this);
}
}
if (!_each) _each = each;
function clear() {
this.length = 0;
return this;
}
function first() {
return this[0];
}
function last() {
return this[this.length - 1];
}
function compact() {
return this.select(function(value) {
return value != null;
});
}
function flatten() {
return this.inject([], function(array, value) {
if (Object.isArray(value))
return array.concat(value.flatten());
array.push(value);
return array;
});
}
function without() {
var values = slice.call(arguments, 0);
return this.select(function(value) {
return !values.include(value);
});
}
function reverse(inline) {
return (inline === false ? this.toArray() : this)._reverse();
}
function uniq(sorted) {
return this.inject([], function(array, value, index) {
if (0 == index || (sorted ? array.last() != value : !array.include(value)))
array.push(value);
return array;
});
}
function intersect(array) {
return this.uniq().findAll(function(item) {
return array.detect(function(value) { return item === value });
});
}
function clone() {
return slice.call(this, 0);
}
function size() {
return this.length;
}
function inspect() {
return '[' + this.map(Object.inspect).join(', ') + ']';
}
function indexOf(item, i) {
i || (i = 0);
var length = this.length;
if (i < 0) i = length + i;
for (; i < length; i++)
if (this[i] === item) return i;
return -1;
}
function lastIndexOf(item, i) {
i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
var n = this.slice(0, i).reverse().indexOf(item);
return (n < 0) ? n : i - n - 1;
}
function concat() {
var array = slice.call(this, 0), item;
for (var i = 0, length = arguments.length; i < length; i++) {
item = arguments[i];
if (Object.isArray(item) && !('callee' in item)) {
for (var j = 0, arrayLength = item.length; j < arrayLength; j++)
array.push(item[j]);
} else {
array.push(item);
}
}
return array;
}
Object.extend(arrayProto, Enumerable);
if (!arrayProto._reverse)
arrayProto._reverse = arrayProto.reverse;
Object.extend(arrayProto, {
_each: _each,
clear: clear,
first: first,
last: last,
compact: compact,
flatten: flatten,
without: without,
reverse: reverse,
uniq: uniq,
intersect: intersect,
clone: clone,
toArray: clone,
size: size,
inspect: inspect
});
var CONCAT_ARGUMENTS_BUGGY = (function() {
return [].concat(arguments)[0][0] !== 1;
})(1,2)
if (CONCAT_ARGUMENTS_BUGGY) arrayProto.concat = concat;
if (!arrayProto.indexOf) arrayProto.indexOf = indexOf;
if (!arrayProto.lastIndexOf) arrayProto.lastIndexOf = lastIndexOf;
})();
function $H(object) {
return new Hash(object);
};
var Hash = Class.create(Enumerable, (function() {
function initialize(object) {
this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
}
function _each(iterator) {
for (var key in this._object) {
var value = this._object[key], pair = [key, value];
pair.key = key;
pair.value = value;
iterator(pair);
}
}
function set(key, value) {
return this._object[key] = value;
}
function get(key) {
if (this._object[key] !== Object.prototype[key])
return this._object[key];
}
function unset(key) {
var value = this._object[key];
delete this._object[key];
return value;
}
function toObject() {
return Object.clone(this._object);
}
function keys() {
return this.pluck('key');
}
function values() {
return this.pluck('value');
}
function index(value) {
var match = this.detect(function(pair) {
return pair.value === value;
});
return match && match.key;
}
function merge(object) {
return this.clone().update(object);
}
function update(object) {
return new Hash(object).inject(this, function(result, pair) {
result.set(pair.key, pair.value);
return result;
});
}
function toQueryPair(key, value) {
if (Object.isUndefined(value)) return key;
return key + '=' + encodeURIComponent(String.interpret(value));
}
function toQueryString() {
return this.inject([], function(results, pair) {
var key = encodeURIComponent(pair.key), values = pair.value;
if (values && typeof values == 'object') {
if (Object.isArray(values)) {
var queryValues = [];
for (var i = 0, len = values.length, value; i < len; i++) {
value = values[i];
queryValues.push(toQueryPair(key, value));
}
return results.concat(queryValues);
}
} else results.push(toQueryPair(key, values));
return results;
}).join('&');
}
function inspect() {
return '#<Hash:{' + this.map(function(pair) {
return pair.map(Object.inspect).join(': ');
}).join(', ') + '}>';
}
function clone() {
return new Hash(this);
}
return {
initialize: initialize,
_each: _each,
set: set,
get: get,
unset: unset,
toObject: toObject,
toTemplateReplacements: toObject,
keys: keys,
values: values,
index: index,
merge: merge,
update: update,
toQueryString: toQueryString,
inspect: inspect,
toJSON: toObject,
clone: clone
};
})());
Hash.from = $H;
Object.extend(Number.prototype, (function() {
function toColorPart() {
return this.toPaddedString(2, 16);
}
function succ() {
return this + 1;
}
function times(iterator, context) {
$R(0, this, true).each(iterator, context);
return this;
}
function toPaddedString(length, radix) {
var string = this.toString(radix || 10);
return '0'.times(length - string.length) + string;
}
function abs() {
return Math.abs(this);
}
function round() {
return Math.round(this);
}
function ceil() {
return Math.ceil(this);
}
function floor() {
return Math.floor(this);
}
return {
toColorPart: toColorPart,
succ: succ,
times: times,
toPaddedString: toPaddedString,
abs: abs,
round: round,
ceil: ceil,
floor: floor
};
})());
function $R(start, end, exclusive) {
return new ObjectRange(start, end, exclusive);
}
var ObjectRange = Class.create(Enumerable, (function() {
function initialize(start, end, exclusive) {
this.start = start;
this.end = end;
this.exclusive = exclusive;
}
function _each(iterator) {
var value = this.start;
while (this.include(value)) {
iterator(value);
value = value.succ();
}
}
function include(value) {
if (value < this.start)
return false;
if (this.exclusive)
return value < this.end;
return value <= this.end;
}
return {
initialize: initialize,
_each: _each,
include: include
};
})());
var Ajax = {
getTransport: function() {
return Try.these(
function() {return new XMLHttpRequest()},
function() {return new ActiveXObject('Msxml2.XMLHTTP')},
function() {return new ActiveXObject('Microsoft.XMLHTTP')}
) || false;
},
activeRequestCount: 0
};
Ajax.Responders = {
responders: [],
_each: function(iterator) {
this.responders._each(iterator);
},
register: function(responder) {
if (!this.include(responder))
this.responders.push(responder);
},
unregister: function(responder) {
this.responders = this.responders.without(responder);
},
dispatch: function(callback, request, transport, json) {
this.each(function(responder) {
if (Object.isFunction(responder[callback])) {
try {
responder[callback].apply(responder, [request, transport, json]);
} catch (e) { }
}
});
}
};
Object.extend(Ajax.Responders, Enumerable);
Ajax.Responders.register({
onCreate: function() { Ajax.activeRequestCount++ },
onComplete: function() { Ajax.activeRequestCount-- }
});
Ajax.Base = Class.create({
initialize: function(options) {
this.options = {
method: 'post',
asynchronous: true,
contentType: 'application/x-www-form-urlencoded',
encoding: 'UTF-8',
parameters: '',
evalJSON: true,
evalJS: true
};
Object.extend(this.options, options || { });
this.options.method = this.options.method.toLowerCase();
if (Object.isHash(this.options.parameters))
this.options.parameters = this.options.parameters.toObject();
}
});
Ajax.Request = Class.create(Ajax.Base, {
_complete: false,
initialize: function($super, url, options) {
$super(options);
this.transport = Ajax.getTransport();
this.request(url);
},
request: function(url) {
this.url = url;
this.method = this.options.method;
var params = Object.isString(this.options.parameters) ?
this.options.parameters :
Object.toQueryString(this.options.parameters);
if (!['get', 'post'].include(this.method)) {
params += (params ? '&' : '') + "_method=" + this.method;
this.method = 'post';
}
if (params && this.method === 'get') {
this.url += (this.url.include('?') ? '&' : '?') + params;
}
this.parameters = params.toQueryParams();
// try {
var response = new Ajax.Response(this);
if (this.options.onCreate) this.options.onCreate(response);
Ajax.Responders.dispatch('onCreate', this, response);
this.transport.open(this.method.toUpperCase(), this.url,
this.options.asynchronous);
if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);
this.transport.onreadystatechange = this.onStateChange.bind(this);
this.setRequestHeaders();
this.body = this.method == 'post' ? (this.options.postBody || params) : null;
this.transport.send(this.body);
/* Force Firefox to handle ready state 4 for synchronous requests */
if (!this.options.asynchronous && this.transport.overrideMimeType)
this.onStateChange();
/* }
catch (e) {
this.dispatchException(e);
}*/
},
onStateChange: function() {
var readyState = this.transport.readyState;
if (readyState > 1 && !((readyState == 4) && this._complete))
this.respondToReadyState(this.transport.readyState);
},
setRequestHeaders: function() {
var headers = {
'X-Requested-With': 'XMLHttpRequest',
'X-Prototype-Version': Prototype.Version,
'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
};
if (this.method == 'post') {
headers['Content-type'] = this.options.contentType +
(this.options.encoding ? '; charset=' + this.options.encoding : '');
/* Force "Connection: close" for older Mozilla browsers to work
* around a bug where XMLHttpRequest sends an incorrect
* Content-length header. See Mozilla Bugzilla #246651.
*/
if (this.transport.overrideMimeType &&
(navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
headers['Connection'] = 'close';
}
if (typeof this.options.requestHeaders == 'object') {
var extras = this.options.requestHeaders;
if (Object.isFunction(extras.push))
for (var i = 0, length = extras.length; i < length; i += 2)
headers[extras[i]] = extras[i+1];
else
$H(extras).each(function(pair) { headers[pair.key] = pair.value });
}
for (var name in headers)
this.transport.setRequestHeader(name, headers[name]);
},
success: function() {
var status = this.getStatus();
return !status || (status >= 200 && status < 300) || status == 304;
},
getStatus: function() {
//try {
if (this.transport.status === 1223) return 204;
return this.transport.status || 0;
//} catch (e) { return 0 }
},
respondToReadyState: function(readyState) {
var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);
if (state == 'Complete') {
//try {
this._complete = true;
(this.options['on' + response.status]
|| this.options['on' + (this.success() ? 'Success' : 'Failure')]
|| Prototype.emptyFunction)(response, response.headerJSON);
/*} catch (e) {
this.dispatchException(e);
}*/
var contentType = response.getHeader('Content-type');
if (this.options.evalJS == 'force'
|| (this.options.evalJS && this.isSameOrigin() && contentType
&& contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
this.evalResponse();
}
//try {
(this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
/*} catch (e) {
this.dispatchException(e);
}*/
if (state == 'Complete') {
this.transport.onreadystatechange = Prototype.emptyFunction;
}
},
isSameOrigin: function() {
var m = this.url.match(/^\s*https?:\/\/[^\/]*/);
return !m || (m[0] == '#{protocol}//#{domain}#{port}'.interpolate({
protocol: location.protocol,
domain: document.domain,
port: location.port ? ':' + location.port : ''
}));
},
getHeader: function(name) {
try {
return this.transport.getResponseHeader(name) || null;
} catch (e) { return null; }
},
evalResponse: function() {
try {
return eval((this.transport.responseText || '').unfilterJSON());
} catch (e) {
this.dispatchException(e);
}
},
dispatchException: function(exception) {
(this.options.onException || Prototype.emptyFunction)(this, exception);
Ajax.Responders.dispatch('onException', this, exception);
}
});
Ajax.Request.Events =
['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
Ajax.Response = Class.create({
initialize: function(request){
this.request = request;
var transport = this.transport = request.transport,
readyState = this.readyState = transport.readyState;
if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
this.status = this.getStatus();
this.statusText = this.getStatusText();
this.responseText = String.interpret(transport.responseText);
this.headerJSON = this._getHeaderJSON();
}
if (readyState == 4) {
var xml = transport.responseXML;
this.responseXML = Object.isUndefined(xml) ? null : xml;
this.responseJSON = this._getResponseJSON();
}
},
status: 0,
statusText: '',
getStatus: Ajax.Request.prototype.getStatus,
getStatusText: function() {
try {
return this.transport.statusText || '';
} catch (e) { return '' }
},
getHeader: Ajax.Request.prototype.getHeader,
getAllHeaders: function() {
try {
return this.getAllResponseHeaders();
} catch (e) { return null }
},
getResponseHeader: function(name) {
return this.transport.getResponseHeader(name);
},
getAllResponseHeaders: function() {
return this.transport.getAllResponseHeaders();
},
_getHeaderJSON: function() {
var json = this.getHeader('X-JSON');
if (!json) return null;
json = decodeURIComponent(escape(json));
try {
return json.evalJSON(this.request.options.sanitizeJSON ||
!this.request.isSameOrigin());
} catch (e) {
this.request.dispatchException(e);
}
},
_getResponseJSON: function() {
var options = this.request.options;
if (!options.evalJSON || (options.evalJSON != 'force' &&
!(this.getHeader('Content-type') || '').include('application/json')) ||
this.responseText.blank())
return null;
try {
return this.responseText.evalJSON(options.sanitizeJSON ||
!this.request.isSameOrigin());
} catch (e) {
this.request.dispatchException(e);
}
}
});
Ajax.Updater = Class.create(Ajax.Request, {
initialize: function($super, container, url, options) {
this.container = {
success: (container.success || container),
failure: (container.failure || (container.success ? null : container))
};
options = Object.clone(options);
var onComplete = options.onComplete;
options.onComplete = (function(response, json) {
this.updateContent(response.responseText);
if (Object.isFunction(onComplete)) onComplete(response, json);
}).bind(this);
$super(url, options);
},
updateContent: function(responseText) {
var receiver = this.container[this.success() ? 'success' : 'failure'],
options = this.options;
if (!options.evalScripts) responseText = responseText.stripScripts();
if (receiver = $(receiver)) {
if (options.insertion) {
if (Object.isString(options.insertion)) {
var insertion = { }; insertion[options.insertion] = responseText;
receiver.insert(insertion);
}
else options.insertion(receiver, responseText);
}
else receiver.update(responseText);
}
}
});
Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
initialize: function($super, container, url, options) {
$super(options);
this.onComplete = this.options.onComplete;
this.frequency = (this.options.frequency || 2);
this.decay = (this.options.decay || 1);
this.updater = { };
this.container = container;
this.url = url;
this.start();
},
start: function() {
this.options.onComplete = this.updateComplete.bind(this);
this.onTimerEvent();
},
stop: function() {
this.updater.options.onComplete = undefined;
clearTimeout(this.timer);
(this.onComplete || Prototype.emptyFunction).apply(this, arguments);
},
updateComplete: function(response) {
if (this.options.decay) {
this.decay = (response.responseText == this.lastText ?
this.decay * this.options.decay : 1);
this.lastText = response.responseText;
}
this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
},
onTimerEvent: function() {
this.updater = new Ajax.Updater(this.container, this.url, this.options);
}
});
//
// Limechat Quake Notifier by whiteleaf
//
// 2011/03/28 Ver.1.0
//
LimeExt.Require("library/prototype4lime.js");
LimeExt.Require("library/socket.js");
LimeExt.Require("library/ini.js");
var debug = false;
var Quake = {
default_min_shindo: 3, // これ以上の震度だけ表示する(デフォ値、チャンネルごとに設定可能)
arguments_order_prefix: "quake", // コマンド名
arguments_spliter: ">", // コマンドの区切り文字
setting_filename: "quake_setting_" + escape_filename(name) + ".ini" // 設定ファイル名(プロファイル別管理)
};
Quake.version = "1.1";
var P2PQuakePlugin = Class.create(Socket, {
port: (debug ? 7777 : 6918),
retry_limit: 10,
retry_interval: 2000,
initialize: function($super, options) {
$super();
this.connected = false;
this.retry_count = 0;
this.quited = false;
this.data_buffer = "";
this.options = {
name: "P2PQuake Plugin for Limechat",
onReceive: function() {}
};
Object.extend(this.options, options || {});
this.reconnect(30 * 1000 + Math.floor(Math.random() * 10 * 1000));
},
connectToP2PQuakeCliant: function() {
if (!this.connected) {
this.connect("localhost", this.port);
if (this.retry_count-- > 0) {
setTimeout(this.connectToP2PQuakeCliant.bind(this), this.retry_interval);
}
else {
log("[LQH] Error: P2P地震情報クライアントに接続出来ませんでした。" +
"再接続には quake>reconnect を使用してください");
}
}
},
reconnect: function(interval) {
if (!interval) {
interval = this.retry_interval
}
if (this.connected || this.retry_count > 0) return;
this.retry_count = this.retry_limit;
setTimeout(this.connectToP2PQuakeCliant.bind(this), interval);
},
onConnect: function() {
this.connected = true;
this.retry_count = 0;
this.send("JOIN", this.options.name);
},
onClose: function() {
this.connected = false;
log("[LQN] Error: P2P地震情報クライアントとの接続が切れました");
},
onError: function($super) {
$super();
this.connected = false;
},
onDataArrival: function(total) {
this.data_buffer = this.getData();
var operation = this.data_buffer.substring(0, 4);
var data = (this.data_buffer.length > 5 ? this.data_buffer.substring(5).replace(/[\r\n]/g, "") : "");
this.options.onReceive.apply(this, [operation, data]);
this.data_buffer = "";
},
quit: function() {
if (!this.quited) {
this.close();
this.quited = true;
}
},
send: function(operation, data) {
this.sendData(operation.toUpperCase() + " " + data + "\r\n");
}
});
Quake.Notifier = Class.create(P2PQuakePlugin, {
initialize: function($super) {
$super({
name: "Limechat Quake Notifier (Version " + Quake.version+ ")",
onReceive: this.receive
});
this.load_setting();
log(this.options.name);
},
test: function() {
this.receive("SVER", "P2P地震情報 for Peer(Beta 3/Revision 1012)");
//this.receive("QUAK", "28日14時38分,3,0,4,秋田県内陸南部,20km,4.1,0,N39.6,E140.5,気象庁:-秋田県,+3,*大仙市,*仙北市,+1,*秋田市,*由利本荘市,*大館市,*北秋田市,*秋田美郷町,-岩手県,+1,*矢巾町");
this.receive("QUAK", "28日20時08分,3,0,4,茨城県北部,20km,4.1,0,N36.7,E140.6,気象庁:-茨城県,+3,*常陸太田市,+2,*日立市,*高萩市,*大子町,*常陸大宮市,+1,*水戸市,*北茨城市,*笠間市,*ひたちなか市,*那珂市,*城里町,*小美玉市,*土浦市,*石岡市,*つくば市,*茨城鹿嶋市,*坂東市,*筑西市,*かすみがうら市,*桜川市,*鉾田市,*常総市,-福島県,+2,*矢祭町,*平田村,*楢葉町,+1,*白河市,*二本松市,*鏡石町,*天栄村,*棚倉町,*玉川村,*浅川町,*古殿町,*小野町,*田村,*福島伊達市,*いわき市,*飯舘村,-宮城県,+1,*岩沼市,-栃木県,+1,*宇都宮市,*栃木市,*鹿沼市,*芳賀町,*那須烏山市,*栃木那珂川町,-埼玉県,+1,*宮代町");
//this.receive("QUAK", "28日23時32分,2,0,4,新潟県中越地方,10km,1.9,0,N37.0,E138.6,気象庁:-長野県,+2,*栄村");
this.receive("OPTI");
this.receive("EEW1", "1");
this.receive("EEW1", "0");
},
commandline: function(prefix, channel, text) {
new Quake.Command(prefix, channel, text, this);
},
receive: function(operation, data) {
switch (operation) {
case "SVER":
log("[LQN] connected to " + data);
break;
case "QUAK":
this.notify_quak(data);
break;
case "EEW1":
if (data == "0") {
this.channels.each(function(ch) {
send(ch, "<bold><color red>!!!緊急地震速報!!!<stop>");
});
}
break;
case "OPTI":
log(this.options.name);
log("操作方法に関しては " + Quake.arguments_order_prefix +
Quake.arguments_spliter + "help を参照して下さい");
break;
default:
break;
}
},
cache_summary: {},
cache_detail: "",
latest_summary: "",
latest_detail: "",
notify_quak: function(data) {
var split_data = data.split(":");
var summary = split_data[0], detail = split_data[1];
if (detail.length == 0) {
return;
}
var result = this.get_quak_summary(summary);
if (result.elements.seismic_intensity == 0 || this.cache_summary[result.elements.date]) {
return;
}
if (result.elements.eq_position == "--") {
// 「地震速報」では震源・規模情報が配信されずに、速報震度と各地震度情報しか配信されない。
// 第二報以降の「地震情報」「震源情報」で詳細が発表されるため、第一報の各地震度のみ保存して
// 第二報以降の震度概要と統合する
this.cache_detail = detail;
return;
}
if (this.cache_detail != "") {
detail = this.cache_detail;
this.latest_detail = detail;
this.cache_detail = "";
}
this.cache_summary[result.elements.date] = true;
var summary_message = result.message;
this.latest_summary = summary_message;
this.channels.each(function(ch) {
var min = (this.min_shindo[ch] ? this.min_shindo[ch] : Quake.default_min_shindo);
var detail_messages = this.get_quak_detail(detail, min);
if (detail_messages.length > 0) {
send(ch, summary_message);
detail_messages.each(function(msg) {
send(ch, msg);
});
}
}, this);
},
get_quak_summary: function(summary) {
var split_data = summary.split(",");
var elements = {
date: split_data[0],
seismic_intensity: split_data[1],
eq_position: split_data[4],
eq_deep: split_data[5],
magnitude: split_data[6],
eq_pos_n: split_data[8],
eq_pos_e: split_data[9],
vender: split_data[10]
};
if (elements.eq_position == "") {
elements.eq_position = "--";
}
if (elements.magnitude == "-1.0") {
elements.magnitude = "--";
}
var template = new Template(
"<bold>地震情報<stop> #{date} (最大震度#{seismic_intensity}) [震源]#{eq_position} [規模]M#{magnitude}");
return {
elements: elements,
message: template.evaluate(elements)
};
},
get_quak_detail: function(detail, min_shindo) {
var result = {};
var prefecture = "", seismic_intensity = 0;
detail.split(",").each(function(value) {
var op = value.substring(0, 1);
var info = value.substring(1);
switch (op) {
case "-":
prefecture = info;
if (!result[prefecture]) {
result[prefecture] = {};
}
break;
case "+":
seismic_intensity = info;
result[prefecture][seismic_intensity] = [];
break;
case "*":
result[prefecture][seismic_intensity].push(info);
break;
default:
break;
}
}, this);
var messages = [];
for (prefecture in result) {
if (prefecture.length > 0) {
var cities = [];
for (seismic_intensity in result[prefecture]) {
if (seismic_intensity >= min_shindo) {
cities.push("震度" + seismic_intensity + ":" +
result[prefecture][seismic_intensity].join(" "));
}
}
if (cities.length > 0) {
messages.push("[" + prefecture + "]" + cities.join(" "));
}
}
}
return messages;
},
load_setting: function() {
this.channels = [];
this.min_shindo = {};
this.setting = new Ini(Quake.setting_filename);
if (!this.setting.load()) {
return;
}
if (this.setting.data.global.channels != "") {
this.channels = this.setting.data.global.channels.split(",");
}
for (var ch in this.setting.data.min_shindo) {
if (/^[1-7]$/.test(this.setting.data.min_shindo[ch])) {
this.min_shindo[ch] = this.setting.data.min_shindo[ch];
}
else {
this.min_shindo[ch] = Quake.default_min_shindo;
}
}
},
save_setting: function() {
this.setting.data.global.channels = this.channels.join(",");
this.setting.data.min_shindo = this.min_shindo;
this.setting.save();
}
});
Quake.Console = Class.create({
initialize: function(channel) {
this.channel = channel;
},
send: function(message) {
send(this.channel, message);
},
action: function(message) {
action(this.channel, message);
},
privmsg: function(message) {
sendRaw("privmsg " + this.channel + " " + message);
},
information: function(message) {
this.send("[LQN] " + message);
}
});
Quake.Command = Class.create({
commands: {
min: ["[1-7](表示震度の閾値)"], latest: [], boot: [], kill: [], reconnect: []/*, test: []*/
},
initialize: function(prefix, channel, text, notifier) {
var args = text.toLowerCase().split(Quake.arguments_spliter);
if (args.shift() != Quake.arguments_order_prefix) {
return;
}
this.notifier = notifier;
this.channel = channel;
this.owner = (prefix.nick == myNick);
this.is_boot = this.is_valid_channel(channel);
this.console = new Quake.Console(channel);
var order = args.shift();
if (!order) {
this.help();
return;
}
if (order == "help") {
this.help();
return;
}
if (this.commands[order]) {
if (args.length < this.commands[order].length) {
this.console.information("コマンドの引数が足りません。 " + Quake.arguments_order_prefix +
Quake.arguments_spliter + "help を参照して下さい");
return;
}
this[order](args);
return;
}
if (!this.is_boot && !this.owner) return;
this.console.information("コマンドが間違っています。 " + Quake.arguments_order_prefix +
Quake.arguments_spliter + "help を参照して下さい");
},
is_valid_channel: function(channel) {
return this.notifier.channels.include(channel);
},
test: function() {
this.notifier.test();
},
// quake>boot
// for owner
boot: function() {
if (!this.owner) return;
if (!this.is_boot) {
this.notifier.channels.push(this.channel);
this.console.information("このチャンネルで QuakeNotifier を有効にしました");
this.notifier.save_setting();
}
else {
this.console.information("すでに有効済みです");
}
},
// quake>kill
// for owner
kill: function() {
if (!this.owner) return;
if (!this.is_boot) {
this.help();
return;
}
var index = this.notifier.channels.indexOf(this.channel);
if (index >= 0) {
this.notifier.channels.splice(index, 1);
this.console.information("このチャンネルで QuakeNotifier を無効にしました");
this.notifier.save_setting();
}
},
// quake>min>[1-7]
// for owner
min: function(args) {
if (!this.owner) return;
if (!this.is_boot) {
this.help();
return;
}
if (/^[1-7]$/.test(args[0])) {
this.notifier.min_shindo[this.channel] = args[0];
this.console.information("このチャンネルでの閾値を " + args[0] + " 以上にしました");
this.notifier.save_setting();
}
else {
this.console.information("震度の閾値は 1~7 の間で入力して下さい");
}
},
// quake>latest>&option shindo
latest: function(args) {
var min;
if (args.length == 1 && /^[1-7]$/.test(args[0])) {
min = args[0];
}
else {
min = (this.notifier.min_shindo[this.channel] ? this.notifier.min_shindo[this.channel] : Quake.default_min_shindo);
}
if (this.notifier.latest_summary != "" && this.notifier.latest_detail != "") {
var detail_messages = this.notifier.get_quak_detail(this.notifier.latest_detail, min);
if (detail_messages.length > 0) {
this.console.information(this.notifier.latest_summary)
detail_messages.each(function(msg) {
this.console.information(msg);
}, this);
}
}
},
// quake>reconnect
// for owner
reconnect: function() {
if (!this.owner) return;
if (!this.is_boot) {
this.help();
return;
}
if (!this.notifier.connected) {
this.console.information("P2P地震情報クライアントに再接続を試みます");
this.notifier.reconnect();
}
else {
this.console.information("接続済みです");
}
},
// quake>help
help: function() {
if (!this.owner) return;
if (!this.is_boot) {
this.console.information("このチャンネルで有効にするには " + Quake.arguments_order_prefix +
Quake.arguments_spliter + "boot を実行して下さい");
return;
}
var messages = [];
for (var order in this.commands) {
msg = Quake.arguments_order_prefix + Quake.arguments_spliter + order;
if (this.commands[order].length > 0) {
msg += Quake.arguments_spliter + this.commands[order].join(Quake.arguments_spliter);
}
messages.push(msg);
}
this.console.send(messages.join(" | ") + " " + (this.notifier.connected ? "接続中" : "未接続"));
}
});
var quake = null;
function event::onLoad() {
quake = new Quake.Notifier;
//quake = new Quake.NotifierTest;
}
function event::onUnload() {
if (quake) {
quake.quit();
}
}
function event::onChannelText(prefix, channel, text) {
quake.commandline(prefix, channel, text);
}
//
// ファイル名に使えない文字等をエスケープ
//
function escape_filename(filename) {
var pattern = [[":", "colon"], ["?", "question"], ["/", "slash"]];
for (var i in pattern) {
filename = filename.replace(pattern[i][0], pattern[i][1]);
}
return encodeURI(filename);
}
//
// Socket library
// require: OSWINSOCK.dll
// http://www.ostrosoft.com/oswinsck.asp
//
var Socket = Class.create({
STATE: {
CLOSED: 0, OPEN: 1, LISTENING: 2, CONNECTION_PENDING: 3, RESOLVING_HOST: 4,
HOST_RESOLVED: 5, CONNECTING: 6, CONNECTED: 7, CLOSING: 8, ERROR: 9
},
initialize: function() {
this.regist_event();
this.winsock = new ActiveXObject("OSWINSCK.Winsock");
LimeExt.ConnectObject(this.winsock, this);
},
connect: function(host, port) {
return this.winsock.Connect(host, port);
},
close: function() {
this.winsock.CloseWinsock();
},
accept: function(request_id) {
return this.winsock.Accept(request_id);
},
bind: function(local_port, local_ip) {
if (!local_port) local_port = LimeExt.Empty;
if (!local_ip) local_ip = LimeExt.Empty;
return this.winsock.Bind(local_port, local_ip);
},
getData: function() {
return this.winsock.GetDataBuffer();
},
getDataBuffer: function() { // alias getData
return this.getData();
},
listen: function() {
return this.winsock.Listen();
},
sendData: function(data) {
this.winsock.SendData(data);
},
// event handlers
onClose: function() {},
onConnect: function() {},
onConnectionRequest: function(request_id) {},
onDataArrival: function(bytes_total) {},
onError: function(number, description, scode, source, help_file, help_context, cancel_display) {
log("SocketError(" + number + ") : " + description);
},
onSendComplete: function() {},
onSendProgress: function(bytes_sent, bytes_remaining) {},
onStatusChanged: function(status) {},
events: ["Close", "Connect", "ConnectionRequest", "DataArrival", "Error", "SendComplete",
"SendProgress", "StatusChanged"],
regist_event: function() {
this.events.each(function(event_name) {
this["On" + event_name] = function() {
this["on" + event_name].apply(this, arguments);
}.bind(this);
}.bind(this));
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment